[Pkg-cli-apps-commits] [SCM] smuxi branch, master, updated. debian/0.8-8-9-g7373915

Mirco Bauer meebey at meebey.net
Tue Jan 3 08:29:26 UTC 2012


The following commit has been merged in the master branch:
commit 0d666d8cd4743edbbda01900249d735859399da0
Author: Mirco Bauer <meebey at meebey.net>
Date:   Tue Jan 3 09:02:05 2012 +0100

    Imported Upstream version 0.8.9

diff --git a/Makefile.am b/Makefile.am
index db70768..a2d1da3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -43,6 +43,9 @@ SUBDIRS = 	lib \
 		src \
 		$(PODIRS)
 
+# forcely disable parallel builds
+export MAKEFLAGS=-j1
+
 update-po:
 	for PODIR in $(PODIRS); do \
 		echo $$PODIR; \
@@ -52,20 +55,25 @@ update-po:
 update-pot:
 	for PODIR in $(PODIRS); do \
 		echo $$PODIR; \
-		$(MAKE) -C $$PODIR check; \
+		$(MAKE) -C $$PODIR clean; \
+		$(MAKE) -C $$PODIR check 2>&1 | grep -v 'mismatched quotes at line' 2>&1; \
 	done
 
+update-transifex:
+	tx pull -l ca,da,de,en_GB,es,fi,fr,ru,sk,sv,tr,ur,zh_CN
+
 mail-po: update-po
 	for PODIR in $(PODIRS); do \
 		echo $$PODIR; \
 		podebconf-report-po \
-			--deadline=+7days \
+			--deadline=+14days \
 			--notdebconf \
 			--package="Smuxi ($$PODIR)" \
 			--utf8 \
 			--from="Mirco Bauer <meebey at meebey.net>" \
 			--smtp=booster.qnetp.net \
-			--podir=$$PODIR; \
+			--podir=$$PODIR \
+			--langs=cs,it,pt; \
 	done
 
 call-po: update-po
@@ -83,9 +91,16 @@ call-po: update-po
 	done
 	
 LIB_DIR = $(top_builddir)/lib
-WIN32_LIB_DIR = $(LIB_DIR)/win32
 BUILD_DIR = $(top_builddir)/bin/$(PROFILE)
+WIN32_LIB_DIR = $(LIB_DIR)/win32
 WIN32_BUILD_DIR = $(top_builddir)/bin-win32
+OSX_LIB_DIR = $(LIB_DIR)/osx
+OSX_BUILD_DIR = $(top_builddir)/bin-osx
+OSX_APP_DIR = $(OSX_BUILD_DIR)/Smuxi.app
+OSX_CONTENTS_DIR = $(OSX_APP_DIR)/Contents
+OSX_RESOURCES_DIR = $(OSX_CONTENTS_DIR)/Resources
+OSX_BINARIES_DIR = $(OSX_CONTENTS_DIR)/MacOS
+LINUX_STATIC_BUILD_DIR = $(top_builddir)/bin-linux-static
 
 WIN32_EXE_FILES = \
 	$(BUILD_DIR)/smuxi-frontend-gnome.exe \
@@ -104,24 +119,92 @@ WIN32_FILES = \
 	$(BUILD_DIR)/smuxi-engine.dll \
 	$(BUILD_DIR)/smuxi-engine-irc.dll \
 	$(BUILD_DIR)/smuxi-engine-twitter.dll \
+	$(BUILD_DIR)/smuxi-engine-xmpp.dll \
 	$(BUILD_DIR)/smuxi-frontend-gnome-irc.dll \
 	$(BUILD_DIR)/smuxi-frontend.dll \
 	$(BUILD_DIR)/Meebey.SmartIrc4net.dll \
-	$(BUILD_DIR)/Twitterizer.Framework.dll \
+	$(BUILD_DIR)/Twitterizer2.dll \
+	$(BUILD_DIR)/Newtonsoft.Json.dll \
+	$(BUILD_DIR)/jabber-net.dll \
+	$(BUILD_DIR)/Db4objects.Db4o.dll \
 	$(WIN32_LIB_DIR)/smuxi-frontend-gnome.exe.config \
 	$(WIN32_LIB_DIR)/smuxi-server.exe.config
+
+OSX_FILES = \
+	$(LIB_DIR)/Nini.dll \
+	$(LIB_DIR)/log4net.dll \
+	$(BUILD_DIR)/smuxi-frontend-gnome.exe \
+	$(BUILD_DIR)/smuxi-frontend-gnome-irc.dll \
+	$(BUILD_DIR)/smuxi-server.exe \
+	$(BUILD_DIR)/smuxi-common.dll \
+	$(BUILD_DIR)/smuxi-engine.dll \
+	$(BUILD_DIR)/smuxi-engine-irc.dll \
+	$(BUILD_DIR)/smuxi-engine-twitter.dll \
+	$(BUILD_DIR)/smuxi-engine-xmpp.dll \
+	$(BUILD_DIR)/smuxi-frontend.dll \
+	$(BUILD_DIR)/Meebey.SmartIrc4net.dll \
+	$(BUILD_DIR)/Twitterizer2.dll \
+	$(BUILD_DIR)/Newtonsoft.Json.dll \
+	$(BUILD_DIR)/jabber-net.dll \
+	$(BUILD_DIR)/Db4objects.Db4o.dll
+
+LINUX_STATIC_FILES = \
+	$(LIB_DIR)/Mono.Posix.dll \
+	$(LIB_DIR)/Nini.dll \
+	$(LIB_DIR)/log4net.dll \
+	$(BUILD_DIR)/smuxi-common.dll \
+	$(BUILD_DIR)/smuxi-engine.dll \
+	$(BUILD_DIR)/smuxi-engine-irc.dll \
+	$(BUILD_DIR)/smuxi-engine-twitter.dll \
+	$(BUILD_DIR)/Meebey.SmartIrc4net.dll \
+	$(BUILD_DIR)/Twitterizer2.dll \
+	$(BUILD_DIR)/Newtonsoft.Json.dll
 		
 dist-win32:
-	./autogen.sh --without-indicate --without-notify
+	./autogen.sh --without-indicate --without-notify --without-dbus
 	$(MAKE)
 	mkdir -p $(WIN32_BUILD_DIR)
 	for FILE in $(WIN32_FILES); do \
 		cp $$FILE $(WIN32_BUILD_DIR); \
 	done
-	for FILE in $(WIN32_EXE_FILES); do \
-		wine ../releases/win32/build-env/CorFlags.exe /nologo /32BIT+ $(WIN32_BUILD_DIR)/$$(basename $$FILE); \
-	done
 	for PODIR in $(PODIRS); do \
 		$(MAKE) -C $$PODIR install itlocaledir=$(abs_top_builddir)/$(WIN32_BUILD_DIR)/locale; \
 	done
 	makensis $(top_srcdir)/src/smuxi-win32.nsis
+
+dist-osx:
+	./autogen.sh --without-indicate --without-notify --without-dbus
+	$(MAKE)
+	mkdir -p $(OSX_BINARIES_DIR) $(OSX_RESOURCES_DIR)
+	cp $(OSX_LIB_DIR)/Info.plist $(OSX_CONTENTS_DIR)
+	cp $(OSX_LIB_DIR)/smuxi $(OSX_BINARIES_DIR)
+	cp $(OSX_LIB_DIR)/smuxi.icns $(OSX_RESOURCES_DIR)
+	for FILE in $(OSX_FILES); do \
+		cp $$FILE $(OSX_BINARIES_DIR); \
+	done
+	-rm smuxi-osx.zip
+	cd $(OSX_BUILD_DIR) && zip -r ../smuxi-osx.zip Smuxi.app
+
+dist-linux-x86-static:
+	$(MAKE)
+	mkdir -p $(LINUX_STATIC_BUILD_DIR)
+	mkbundle --static -o $(LINUX_STATIC_BUILD_DIR)/smuxi-server $(BUILD_DIR)/smuxi-server.exe
+	for FILE in $(LINUX_STATIC_FILES); do \
+		cp $$FILE $(LINUX_STATIC_BUILD_DIR); \
+	done
+	tar -czf smuxi-server-$(VERSION)-linux-x86-static.tar.gz $(LINUX_STATIC_BUILD_DIR)
+ 
+run: run-gnome
+run-gnome: all
+	cd $(BUILD_DIR) && \
+		mono --debug ./smuxi-frontend-gnome.exe -d
+
+run-stfl: all
+	cd $(BUILD_DIR) && \
+		mono ./smuxi-frontend-stfl.exe -d 2> smuxi-frontend-stfl.err
+
+run-server: all
+	cd $(BUILD_DIR) && \
+		mono --debug ./smuxi-server.exe -d
+
+.NOTPARALLEL:
diff --git a/Makefile.in b/Makefile.in
index fcce489..73add4f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -35,19 +35,22 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = .
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
-	$(srcdir)/Makefile.in $(top_srcdir)/configure TODO \
-	config.guess config.rpath config.sub install-sh ltmain.sh \
-	missing
+	$(srcdir)/Makefile.in $(top_srcdir)/configure \
+	$(top_srcdir)/lib/osx/Info.plist.in TODO config.guess \
+	config.rpath config.sub install-sh ltmain.sh missing
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
  configure.lineno config.status.lineno
 mkinstalldirs = $(install_sh) -d
-CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_FILES = lib/osx/Info.plist
 CONFIG_CLEAN_VPATH_FILES =
 SOURCES =
 DIST_SOURCES =
@@ -106,6 +109,7 @@ distcleancheck_listfiles = find . -type f -print
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -119,13 +123,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -166,13 +183,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -180,6 +199,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -190,13 +210,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -210,13 +239,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -224,7 +259,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -239,10 +276,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -308,9 +348,16 @@ SUBDIRS = lib \
 		$(PODIRS)
 
 LIB_DIR = $(top_builddir)/lib
-WIN32_LIB_DIR = $(LIB_DIR)/win32
 BUILD_DIR = $(top_builddir)/bin/$(PROFILE)
+WIN32_LIB_DIR = $(LIB_DIR)/win32
 WIN32_BUILD_DIR = $(top_builddir)/bin-win32
+OSX_LIB_DIR = $(LIB_DIR)/osx
+OSX_BUILD_DIR = $(top_builddir)/bin-osx
+OSX_APP_DIR = $(OSX_BUILD_DIR)/Smuxi.app
+OSX_CONTENTS_DIR = $(OSX_APP_DIR)/Contents
+OSX_RESOURCES_DIR = $(OSX_CONTENTS_DIR)/Resources
+OSX_BINARIES_DIR = $(OSX_CONTENTS_DIR)/MacOS
+LINUX_STATIC_BUILD_DIR = $(top_builddir)/bin-linux-static
 WIN32_EXE_FILES = \
 	$(BUILD_DIR)/smuxi-frontend-gnome.exe \
 	$(BUILD_DIR)/smuxi-server.exe
@@ -328,13 +375,47 @@ WIN32_FILES = \
 	$(BUILD_DIR)/smuxi-engine.dll \
 	$(BUILD_DIR)/smuxi-engine-irc.dll \
 	$(BUILD_DIR)/smuxi-engine-twitter.dll \
+	$(BUILD_DIR)/smuxi-engine-xmpp.dll \
 	$(BUILD_DIR)/smuxi-frontend-gnome-irc.dll \
 	$(BUILD_DIR)/smuxi-frontend.dll \
 	$(BUILD_DIR)/Meebey.SmartIrc4net.dll \
-	$(BUILD_DIR)/Twitterizer.Framework.dll \
+	$(BUILD_DIR)/Twitterizer2.dll \
+	$(BUILD_DIR)/Newtonsoft.Json.dll \
+	$(BUILD_DIR)/jabber-net.dll \
+	$(BUILD_DIR)/Db4objects.Db4o.dll \
 	$(WIN32_LIB_DIR)/smuxi-frontend-gnome.exe.config \
 	$(WIN32_LIB_DIR)/smuxi-server.exe.config
 
+OSX_FILES = \
+	$(LIB_DIR)/Nini.dll \
+	$(LIB_DIR)/log4net.dll \
+	$(BUILD_DIR)/smuxi-frontend-gnome.exe \
+	$(BUILD_DIR)/smuxi-frontend-gnome-irc.dll \
+	$(BUILD_DIR)/smuxi-server.exe \
+	$(BUILD_DIR)/smuxi-common.dll \
+	$(BUILD_DIR)/smuxi-engine.dll \
+	$(BUILD_DIR)/smuxi-engine-irc.dll \
+	$(BUILD_DIR)/smuxi-engine-twitter.dll \
+	$(BUILD_DIR)/smuxi-engine-xmpp.dll \
+	$(BUILD_DIR)/smuxi-frontend.dll \
+	$(BUILD_DIR)/Meebey.SmartIrc4net.dll \
+	$(BUILD_DIR)/Twitterizer2.dll \
+	$(BUILD_DIR)/Newtonsoft.Json.dll \
+	$(BUILD_DIR)/jabber-net.dll \
+	$(BUILD_DIR)/Db4objects.Db4o.dll
+
+LINUX_STATIC_FILES = \
+	$(LIB_DIR)/Mono.Posix.dll \
+	$(LIB_DIR)/Nini.dll \
+	$(LIB_DIR)/log4net.dll \
+	$(BUILD_DIR)/smuxi-common.dll \
+	$(BUILD_DIR)/smuxi-engine.dll \
+	$(BUILD_DIR)/smuxi-engine-irc.dll \
+	$(BUILD_DIR)/smuxi-engine-twitter.dll \
+	$(BUILD_DIR)/Meebey.SmartIrc4net.dll \
+	$(BUILD_DIR)/Twitterizer2.dll \
+	$(BUILD_DIR)/Newtonsoft.Json.dll
+
 all: all-recursive
 
 .SUFFIXES:
@@ -372,6 +453,17 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
 $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
 	$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
 $(am__aclocal_m4_deps):
+lib/osx/Info.plist: $(top_builddir)/config.status $(top_srcdir)/lib/osx/Info.plist.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool config.lt
 
 # This directory's subdirectories are mostly independent; you can cd
 # into them and run `make' without going through this Makefile.
@@ -715,12 +807,13 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-recursive
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-recursive
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
 	-rm -f Makefile
-distclean-am: clean-am distclean-generic distclean-tags
+distclean-am: clean-am distclean-generic distclean-libtool \
+	distclean-tags
 
 dvi: dvi-recursive
 
@@ -770,7 +863,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-recursive
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-recursive
 
@@ -787,19 +880,23 @@ uninstall-am:
 
 .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
 	all all-am am--refresh check check-am clean clean-generic \
-	ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \
-	dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \
-	distclean distclean-generic distclean-tags distcleancheck \
-	distdir distuninstallcheck dvi dvi-am html html-am info \
-	info-am install install-am install-data install-data-am \
-	install-dvi install-dvi-am install-exec install-exec-am \
-	install-html install-html-am install-info install-info-am \
-	install-man install-pdf install-pdf-am install-ps \
-	install-ps-am install-strip installcheck installcheck-am \
-	installdirs installdirs-am maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
-	pdf-am ps ps-am tags tags-recursive uninstall uninstall-am
-
+	clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \
+	dist-gzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \
+	distcheck distclean distclean-generic distclean-libtool \
+	distclean-tags distcleancheck distdir distuninstallcheck dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs installdirs-am \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-recursive uninstall uninstall-am
+
+
+# forcely disable parallel builds
+export MAKEFLAGS=-j1
 
 update-po:
 	for PODIR in $(PODIRS); do \
@@ -810,20 +907,25 @@ update-po:
 update-pot:
 	for PODIR in $(PODIRS); do \
 		echo $$PODIR; \
-		$(MAKE) -C $$PODIR check; \
+		$(MAKE) -C $$PODIR clean; \
+		$(MAKE) -C $$PODIR check 2>&1 | grep -v 'mismatched quotes at line' 2>&1; \
 	done
 
+update-transifex:
+	tx pull -l ca,da,de,en_GB,es,fi,fr,ru,sk,sv,tr,ur,zh_CN
+
 mail-po: update-po
 	for PODIR in $(PODIRS); do \
 		echo $$PODIR; \
 		podebconf-report-po \
-			--deadline=+7days \
+			--deadline=+14days \
 			--notdebconf \
 			--package="Smuxi ($$PODIR)" \
 			--utf8 \
 			--from="Mirco Bauer <meebey at meebey.net>" \
 			--smtp=booster.qnetp.net \
-			--podir=$$PODIR; \
+			--podir=$$PODIR \
+			--langs=cs,it,pt; \
 	done
 
 call-po: update-po
@@ -841,20 +943,54 @@ call-po: update-po
 	done
 
 dist-win32:
-	./autogen.sh --without-indicate --without-notify
+	./autogen.sh --without-indicate --without-notify --without-dbus
 	$(MAKE)
 	mkdir -p $(WIN32_BUILD_DIR)
 	for FILE in $(WIN32_FILES); do \
 		cp $$FILE $(WIN32_BUILD_DIR); \
 	done
-	for FILE in $(WIN32_EXE_FILES); do \
-		wine ../releases/win32/build-env/CorFlags.exe /nologo /32BIT+ $(WIN32_BUILD_DIR)/$$(basename $$FILE); \
-	done
 	for PODIR in $(PODIRS); do \
 		$(MAKE) -C $$PODIR install itlocaledir=$(abs_top_builddir)/$(WIN32_BUILD_DIR)/locale; \
 	done
 	makensis $(top_srcdir)/src/smuxi-win32.nsis
 
+dist-osx:
+	./autogen.sh --without-indicate --without-notify --without-dbus
+	$(MAKE)
+	mkdir -p $(OSX_BINARIES_DIR) $(OSX_RESOURCES_DIR)
+	cp $(OSX_LIB_DIR)/Info.plist $(OSX_CONTENTS_DIR)
+	cp $(OSX_LIB_DIR)/smuxi $(OSX_BINARIES_DIR)
+	cp $(OSX_LIB_DIR)/smuxi.icns $(OSX_RESOURCES_DIR)
+	for FILE in $(OSX_FILES); do \
+		cp $$FILE $(OSX_BINARIES_DIR); \
+	done
+	-rm smuxi-osx.zip
+	cd $(OSX_BUILD_DIR) && zip -r ../smuxi-osx.zip Smuxi.app
+
+dist-linux-x86-static:
+	$(MAKE)
+	mkdir -p $(LINUX_STATIC_BUILD_DIR)
+	mkbundle --static -o $(LINUX_STATIC_BUILD_DIR)/smuxi-server $(BUILD_DIR)/smuxi-server.exe
+	for FILE in $(LINUX_STATIC_FILES); do \
+		cp $$FILE $(LINUX_STATIC_BUILD_DIR); \
+	done
+	tar -czf smuxi-server-$(VERSION)-linux-x86-static.tar.gz $(LINUX_STATIC_BUILD_DIR)
+
+run: run-gnome
+run-gnome: all
+	cd $(BUILD_DIR) && \
+		mono --debug ./smuxi-frontend-gnome.exe -d
+
+run-stfl: all
+	cd $(BUILD_DIR) && \
+		mono ./smuxi-frontend-stfl.exe -d 2> smuxi-frontend-stfl.err
+
+run-server: all
+	cd $(BUILD_DIR) && \
+		mono --debug ./smuxi-server.exe -d
+
+.NOTPARALLEL:
+
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
diff --git a/Makefile.include b/Makefile.include
index 912feaa..d34f660 100644
--- a/Makefile.include
+++ b/Makefile.include
@@ -34,7 +34,7 @@ build_references_ref += $(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
 
 EXTRA_DIST += $(build_sources) $(build_resx_files) $(build_others_files) $(ASSEMBLY_WRAPPER_IN) $(EXTRAS) $(DATA_FILES) $(build_culture_res_files)
 CLEANFILES += $(ASSEMBLY) $(ASSEMBLY).mdb $(BINARIES) $(build_resx_resources) $(build_satellite_assembly_list)
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
diff --git a/README b/README
index c7e10ba..b1fdc5d 100644
--- a/README
+++ b/README
@@ -1,47 +1,33 @@
-/**
- * $Id$
- * $URL$
- * $Rev$
- * $Author$
- * $Date$
- */
-
-In order to run smuxi you need the following software
-
-Linux Installation (Gtk#/Gnome#)
-------------------
-On Linux smuxi can use the Gnome# or the Gtk# GUI library, Gnome# is 
-prefered, as configuration backend an INI file is used.
-
-you need:
-- Mono >= 1.2.6 [0]
-- Gtk# >= 2.8.0 [1]
-
-[0] http://www.mono-project.com/Downloads
-[1] http://www.mono-project.com/Downloads
-
-If you use Debian Sid/Unstable and build smuxi from source you can do:
-apt-get install mono-runtime libmono-system-remoting2.0-cil
-apt-get install libgnome2.0-cil (if you want to use Gnome#)
-or
-apt-get install libgtk2.0-cil (if you want to use Gtk#)
-
-Or using the official Debian packages just do:
-apt-get install smuxi-frontend-gnome-irc
-
-Windows Installation
---------------------
-On Windows smuxi has to use Gtk#, as configuration backend an simple 
-INI file is used.
-
-you need:
-- Microsoft .NET 2.0 Framework Runtime [0]
-- Nini >= 0.7.1 (bundled with binary installer) [1]
-- Gtk# >= 2.8.0 for MS .NET [2]
-or
-- Mono >= 1.2.6 + Gtk# >= 2.8.0 for Mono [3]
-
-[0] http://downloads.microsoft.com
-[1] http://sourceforge.net/project/showfiles.php?group_id=110719
-[2] http://forge.novell.com/modules/xfmod/project/showfiles.php?group_id=1430&release_id=1637#selected
-[3] http://forge.novell.com/modules/xfmod/project/showfiles.php?group_id=1395&release_id=1945#selected
+Software Requirements
+---------------------
+First you will need to install a few libraries to compile the source
+
+Libraries:
+* Mono SDK (>= 1.9.1)
+* Nini (>= 1.1)
+* log4net
+* GTK# (>= 2.10)
+* Notify# (optional)
+* Indicate#  (optional)
+* DBus# / NDesk.DBus (optional)
+
+Depending on your operating system and favorite distribution the installation of the listed applications varies. For Debian based distributions it's just a matter of the following commands:
+
+    apt-get install mono-devel mono-xbuild libnini-cil-dev liblog4net-cil-dev libgtk2.0-cil-dev libglade2.0-cil-dev libnotify-cil-dev libindicate0.1-cil-dev libndesk-dbus-glib1.0-cil-dev libndesk-dbus1.0-cil-dev lsb-release
+
+Compiling Source
+----------------
+
+    ./configure
+    make
+
+Installing
+----------
+
+    make install
+
+Running
+-------
+
+Now you can start Smuxi from the GNOME or KDE menu.
+
diff --git a/aclocal.m4 b/aclocal.m4
index 4602edb..b7ebc4f 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -13,8 +13,8 @@
 
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],,
-[m4_warning([this file was generated for autoconf 2.65.
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],,
+[m4_warning([this file was generated for autoconf 2.68.
 You have another version of autoconf.  It may work, but is not guaranteed to.
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically `autoreconf'.])])
@@ -1842,7 +1842,8 @@ AC_DEFUN([AM_NLS],
 # ----------------------------------
 AC_DEFUN([PKG_PROG_PKG_CONFIG],
 [m4_pattern_forbid([^_?PKG_[A-Z_]+$])
-m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
+m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
+m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
 AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
 AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
 AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
@@ -1888,7 +1889,8 @@ m4_define([_PKG_CONFIG],
     pkg_cv_[]$1="$$1"
  elif test -n "$PKG_CONFIG"; then
     PKG_CHECK_EXISTS([$3],
-                     [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
+                     [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes ],
 		     [pkg_failed=yes])
  else
     pkg_failed=untried
@@ -1936,9 +1938,9 @@ if test $pkg_failed = yes; then
    	AC_MSG_RESULT([no])
         _PKG_SHORT_ERRORS_SUPPORTED
         if test $_pkg_short_errors_supported = yes; then
-	        $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1`
+	        $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
         else 
-	        $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1`
+	        $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
@@ -1951,7 +1953,7 @@ $$1_PKG_ERRORS
 Consider adjusting the PKG_CONFIG_PATH environment variable if you
 installed software in a non-standard prefix.
 
-_PKG_TEXT])dnl
+_PKG_TEXT])[]dnl
         ])
 elif test $pkg_failed = untried; then
      	AC_MSG_RESULT([no])
@@ -1962,7 +1964,7 @@ path to pkg-config.
 
 _PKG_TEXT
 
-To get pkg-config, see <http://pkg-config.freedesktop.org/>.])dnl
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
         ])
 else
 	$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
@@ -3504,5 +3506,10 @@ AC_SUBST([am__untar])
 
 m4_include([expansions.m4])
 m4_include([intltool.m4])
+m4_include([libtool.m4])
+m4_include([ltoptions.m4])
+m4_include([ltsugar.m4])
+m4_include([ltversion.m4])
+m4_include([lt~obsolete.m4])
 m4_include([mono.m4])
 m4_include([programs.m4])
diff --git a/config.guess b/config.guess
index f32079a..40eaed4 100755
--- a/config.guess
+++ b/config.guess
@@ -1,10 +1,10 @@
 #! /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
-#   Free Software Foundation, Inc.
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011 Free Software Foundation, Inc.
 
-timestamp='2008-01-23'
+timestamp='2011-05-11'
 
 # 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
@@ -27,16 +27,16 @@ timestamp='2008-01-23'
 # the same distribution terms that you use for the rest of that program.
 
 
-# Originally written by Per Bothner <per at bothner.com>.
-# Please send patches to <config-patches at gnu.org>.  Submit a context
-# diff and a properly formatted ChangeLog entry.
+# Originally written by Per Bothner.  Please send patches (context
+# diff format) to <config-patches at gnu.org> and include a 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.
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
 
 me=`echo "$0" | sed -e 's,.*/,,'`
 
@@ -56,8 +56,9 @@ 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.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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."
@@ -170,7 +171,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
 		eval $set_cc_for_build
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
-			| grep __ELF__ >/dev/null
+			| grep -q __ELF__
 		then
 		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
 		    # Return netbsd for either.  FIX?
@@ -180,7 +181,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 		fi
 		;;
 	    *)
-	        os=netbsd
+		os=netbsd
 		;;
 	esac
 	# The OS release
@@ -223,7 +224,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
 		;;
 	*5.*)
-	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
 		;;
 	esac
 	# According to Compaq, /usr/sbin/psrinfo has been available on
@@ -269,7 +270,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	# 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 ;;
+	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+	exitcode=$?
+	trap '' 0
+	exit $exitcode ;;
     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
@@ -295,7 +299,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	echo s390-ibm-zvmoe
 	exit ;;
     *:OS400:*:*)
-        echo powerpc-ibm-os400
+	echo powerpc-ibm-os400
 	exit ;;
     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
 	echo arm-acorn-riscix${UNAME_RELEASE}
@@ -324,14 +328,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	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:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
     i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
-	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	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
@@ -375,23 +398,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     # 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}
+	echo m68k-atari-mint${UNAME_RELEASE}
 	exit ;;
     atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
 	echo m68k-atari-mint${UNAME_RELEASE}
-        exit ;;
+	exit ;;
     *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
-        echo m68k-atari-mint${UNAME_RELEASE}
+	echo m68k-atari-mint${UNAME_RELEASE}
 	exit ;;
     milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
-        echo m68k-milan-mint${UNAME_RELEASE}
-        exit ;;
+	echo m68k-milan-mint${UNAME_RELEASE}
+	exit ;;
     hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
-        echo m68k-hades-mint${UNAME_RELEASE}
-        exit ;;
+	echo m68k-hades-mint${UNAME_RELEASE}
+	exit ;;
     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
-        echo m68k-unknown-mint${UNAME_RELEASE}
-        exit ;;
+	echo m68k-unknown-mint${UNAME_RELEASE}
+	exit ;;
     m68k:machten:*:*)
 	echo m68k-apple-machten${UNAME_RELEASE}
 	exit ;;
@@ -461,8 +484,8 @@ EOF
 	echo m88k-motorola-sysv3
 	exit ;;
     AViiON:dgux:*:*)
-        # DG/UX returns AViiON for all architectures
-        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	# 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 ] || \
@@ -475,7 +498,7 @@ EOF
 	else
 	    echo i586-dg-dgux${UNAME_RELEASE}
 	fi
- 	exit ;;
+	exit ;;
     M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
 	echo m88k-dolphin-sysv3
 	exit ;;
@@ -532,7 +555,7 @@ EOF
 		echo rs6000-ibm-aix3.2
 	fi
 	exit ;;
-    *:AIX:*:[456])
+    *:AIX:*:[4567])
 	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
@@ -575,52 +598,52 @@ EOF
 	    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" ;;
+		    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
+			esac ;;
+		    esac
 		fi
 		if [ "${HP_ARCH}" = "" ]; then
 		    eval $set_cc_for_build
-		    sed 's/^              //' << EOF >$dummy.c
+		    sed 's/^		//' << EOF >$dummy.c
 
-              #define _HPUX_SOURCE
-              #include <stdlib.h>
-              #include <unistd.h>
+		#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);
+		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);
-              }
+		    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
@@ -640,7 +663,7 @@ EOF
 	    # => hppa64-hp-hpux11.23
 
 	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
-		grep __LP64__ >/dev/null
+		grep -q __LP64__
 	    then
 		HP_ARCH="hppa2.0w"
 	    else
@@ -711,22 +734,22 @@ EOF
 	exit ;;
     C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
 	echo c1-convex-bsd
-        exit ;;
+	exit ;;
     C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
 	if getsysinfo -f scalar_acc
 	then echo c32-convex-bsd
 	else echo c2-convex-bsd
 	fi
-        exit ;;
+	exit ;;
     C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
 	echo c34-convex-bsd
-        exit ;;
+	exit ;;
     C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
 	echo c38-convex-bsd
-        exit ;;
+	exit ;;
     C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
 	echo c4-convex-bsd
-        exit ;;
+	exit ;;
     CRAY*Y-MP:*:*:*)
 	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
 	exit ;;
@@ -750,14 +773,14 @@ EOF
 	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 ;;
+	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}"
+	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}
@@ -785,18 +808,18 @@ EOF
 	echo ${UNAME_MACHINE}-pc-mingw32
 	exit ;;
     i*:windows32*:*)
-    	# uname -m includes "-pc" on this system.
-    	echo ${UNAME_MACHINE}-mingw32
+	# 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
+    *:Interix*:*)
+	case ${UNAME_MACHINE} in
 	    x86)
 		echo i586-pc-interix${UNAME_RELEASE}
 		exit ;;
-	    EM64T | authenticamd)
+	    authenticamd | genuineintel | EM64T)
 		echo x86_64-unknown-interix${UNAME_RELEASE}
 		exit ;;
 	    IA64)
@@ -806,6 +829,9 @@ EOF
     [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
@@ -835,6 +861,20 @@ EOF
     i*86:Minix:*:*)
 	echo ${UNAME_MACHINE}-pc-minix
 	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 ;;
     arm*:Linux:*:*)
 	eval $set_cc_for_build
 	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
@@ -842,7 +882,13 @@ EOF
 	then
 	    echo ${UNAME_MACHINE}-unknown-linux-gnu
 	else
-	    echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+		| grep -q __ARM_PCS_VFP
+	    then
+		echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+	    else
+		echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+	    fi
 	fi
 	exit ;;
     avr32*:Linux:*:*)
@@ -855,7 +901,18 @@ EOF
 	echo crisv32-axis-linux-gnu
 	exit ;;
     frv:Linux:*:*)
-    	echo frv-unknown-linux-gnu
+	echo frv-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	LIBC=gnu
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+	echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
 	exit ;;
     ia64:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
@@ -866,74 +923,33 @@ EOF
     m68*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
 	exit ;;
-    mips:Linux:*:*)
-	eval $set_cc_for_build
-	sed 's/^	//' << EOF >$dummy.c
-	#undef CPU
-	#undef mips
-	#undef mipsel
-	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-	CPU=mipsel
-	#else
-	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-	CPU=mips
-	#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; }
-	;;
-    mips64:Linux:*:*)
+    mips:Linux:*:* | mips64:Linux:*:*)
 	eval $set_cc_for_build
 	sed 's/^	//' << EOF >$dummy.c
 	#undef CPU
-	#undef mips64
-	#undef mips64el
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
 	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-	CPU=mips64el
+	CPU=${UNAME_MACHINE}el
 	#else
 	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-	CPU=mips64
+	CPU=${UNAME_MACHINE}
 	#else
 	CPU=
 	#endif
 	#endif
 EOF
-	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
-	    /^CPU/{
-		s: ::g
-		p
-	    }'`"
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
 	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
+    padre:Linux:*:*)
+	echo sparc-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 ld.so.1 >/dev/null
-	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
-	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
 	exit ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
 	# Look for CPU level
@@ -943,14 +959,17 @@ EOF
 	  *)    echo hppa-unknown-linux-gnu ;;
 	esac
 	exit ;;
-    parisc64:Linux:*:* | hppa64:Linux:*:*)
-	echo hppa64-unknown-linux-gnu
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
 	exit ;;
     s390:Linux:*:* | s390x:Linux:*:*)
 	echo ${UNAME_MACHINE}-ibm-linux
 	exit ;;
     sh64*:Linux:*:*)
-    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
 	exit ;;
     sh*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
@@ -958,6 +977,9 @@ EOF
     sparc:Linux:*:* | sparc64:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
 	exit ;;
+    tile*:Linux:*:*)
+	echo ${UNAME_MACHINE}-tilera-linux-gnu
+	exit ;;
     vax:Linux:*:*)
 	echo ${UNAME_MACHINE}-dec-linux-gnu
 	exit ;;
@@ -965,71 +987,8 @@ EOF
 	echo x86_64-unknown-linux-gnu
 	exit ;;
     xtensa*:Linux:*:*)
-    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	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"
-		;;
-	  a.out-i386-linux)
-		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
-		exit ;;
-	  coff-i386)
-		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
-		exit ;;
-	  "")
-		# Either a pre-BFD a.out linker (linux-gnuoldld) or
-		# one that does not give us useful --help.
-		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
-		exit ;;
-	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
@@ -1037,11 +996,11 @@ EOF
 	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,
+	# 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.
+	# Use sysv4.2uw... so that sysv4* matches it.
 	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
 	exit ;;
     i*86:OS/2:*:*)
@@ -1058,7 +1017,7 @@ EOF
     i*86:syllable:*:*)
 	echo ${UNAME_MACHINE}-pc-syllable
 	exit ;;
-    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
 	echo i386-unknown-lynxos${UNAME_RELEASE}
 	exit ;;
     i*86:*DOS:*:*)
@@ -1073,7 +1032,7 @@ EOF
 	fi
 	exit ;;
     i*86:*:5:[678]*)
-    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	# UnixWare 7.x, OpenUNIX and OpenServer 6.
 	case `/bin/uname -X | grep "^Machine"` in
 	    *486*)	     UNAME_MACHINE=i486 ;;
 	    *Pentium)	     UNAME_MACHINE=i586 ;;
@@ -1101,10 +1060,13 @@ EOF
 	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 i386.
-	echo i386-pc-msdosdjgpp
-        exit ;;
+	# 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 ;;
@@ -1139,8 +1101,18 @@ EOF
 	/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; } ;;
+	/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 ;;
@@ -1153,7 +1125,7 @@ EOF
     rs6000:LynxOS:2.*:*)
 	echo rs6000-unknown-lynxos${UNAME_RELEASE}
 	exit ;;
-    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
 	echo powerpc-unknown-lynxos${UNAME_RELEASE}
 	exit ;;
     SM[BE]S:UNIX_SV:*:*)
@@ -1173,10 +1145,10 @@ EOF
 		echo ns32k-sni-sysv
 	fi
 	exit ;;
-    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
-                      # says <Richard.M.Bartel at ccMail.Census.GOV>
-        echo i586-unisys-sysv4
-        exit ;;
+    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+			# says <Richard.M.Bartel at ccMail.Census.GOV>
+	echo i586-unisys-sysv4
+	exit ;;
     *:UNIX_System_V:4*:FTX*)
 	# From Gerald Hewes <hewes at openmarket.com>.
 	# How about differentiating between stratus architectures? -djm
@@ -1202,11 +1174,11 @@ EOF
 	exit ;;
     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
 	if [ -d /usr/nec ]; then
-	        echo mips-nec-sysv${UNAME_RELEASE}
+		echo mips-nec-sysv${UNAME_RELEASE}
 	else
-	        echo mips-unknown-sysv${UNAME_RELEASE}
+		echo mips-unknown-sysv${UNAME_RELEASE}
 	fi
-        exit ;;
+	exit ;;
     BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
 	echo powerpc-be-beos
 	exit ;;
@@ -1216,6 +1188,9 @@ EOF
     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 ;;
@@ -1243,6 +1218,16 @@ EOF
     *:Darwin:*:*)
 	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
 	case $UNAME_PROCESSOR in
+	    i386)
+		eval $set_cc_for_build
+		if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+		  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		      grep IS_64BIT_ARCH >/dev/null
+		  then
+		      UNAME_PROCESSOR="x86_64"
+		  fi
+		fi ;;
 	    unknown) UNAME_PROCESSOR=powerpc ;;
 	esac
 	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
@@ -1258,6 +1243,9 @@ EOF
     *:QNX:*:4*)
 	echo i386-pc-qnx
 	exit ;;
+    NEO-?:NONSTOP_KERNEL:*:*)
+	echo neo-tandem-nsk${UNAME_RELEASE}
+	exit ;;
     NSE-?:NONSTOP_KERNEL:*:*)
 	echo nse-tandem-nsk${UNAME_RELEASE}
 	exit ;;
@@ -1303,13 +1291,13 @@ EOF
 	echo pdp10-unknown-its
 	exit ;;
     SEI:*:*:SEIUX)
-        echo mips-sei-seiux${UNAME_RELEASE}
+	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`
+	UNAME_MACHINE=`(uname -p) 2>/dev/null`
 	case "${UNAME_MACHINE}" in
 	    A*) echo alpha-dec-vms ; exit ;;
 	    I*) echo ia64-dec-vms ; exit ;;
@@ -1324,6 +1312,9 @@ EOF
     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
@@ -1346,11 +1337,11 @@ main ()
 #include <sys/param.h>
   printf ("m68k-sony-newsos%s\n",
 #ifdef NEWSOS4
-          "4"
+	"4"
 #else
-	  ""
+	""
 #endif
-         ); exit (0);
+	); exit (0);
 #endif
 #endif
 
diff --git a/config.sub b/config.sub
index 6759825..30fdca8 100755
--- a/config.sub
+++ b/config.sub
@@ -1,10 +1,10 @@
 #! /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
-#   Free Software Foundation, Inc.
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011 Free Software Foundation, Inc.
 
-timestamp='2008-01-16'
+timestamp='2011-03-23'
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -32,13 +32,16 @@ timestamp='2008-01-16'
 
 
 # Please send patches to <config-patches at gnu.org>.  Submit a context
-# diff and a properly formatted ChangeLog entry.
+# diff and a properly formatted GNU 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.
 
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
 # 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.
@@ -72,8 +75,9 @@ Report bugs and patches to <config-patches at 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.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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."
@@ -120,8 +124,10 @@ esac
 # 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* | \
+  nto-qnx* | linux-gnu* | linux-android* | 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/'`
@@ -148,10 +154,13 @@ case $os in
 	-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)
+	-apple | -axis | -knuth | -cray | -microblaze)
 		os=
 		basic_machine=$1
 		;;
+	-bluegene*)
+		os=-cnk
+		;;
 	-sim | -cisco | -oki | -wec | -winbond)
 		os=
 		basic_machine=$1
@@ -166,10 +175,10 @@ case $os in
 		os=-chorusos
 		basic_machine=$1
 		;;
- 	-chorusrdb)
- 		os=-chorusrdb
+	-chorusrdb)
+		os=-chorusrdb
 		basic_machine=$1
- 		;;
+		;;
 	-hiux*)
 		os=-hiuxwe2
 		;;
@@ -249,13 +258,16 @@ case $basic_machine in
 	| 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 \
+	| maxq | mb | microblaze | mcore | mep | metag \
 	| mips | mipsbe | mipseb | mipsel | mipsle \
 	| mips16 \
 	| mips64 | mips64el \
-	| mips64vr | mips64vrel \
+	| mips64octeon | mips64octeonel \
 	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
 	| mips64vr4100 | mips64vr4100el \
 	| mips64vr4300 | mips64vr4300el \
 	| mips64vr5000 | mips64vr5000el \
@@ -268,28 +280,42 @@ case $basic_machine in
 	| mipsisa64sr71k | mipsisa64sr71kel \
 	| mipstx39 | mipstx39el \
 	| mn10200 | mn10300 \
+	| moxie \
 	| mt \
 	| msp430 \
+	| nds32 | nds32le | nds32be \
 	| nios | nios2 \
 	| ns16k | ns32k \
+	| open8 \
 	| or32 \
 	| pdp10 | pdp11 | pj | pjl \
-	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| powerpc | powerpc64 | powerpc64le | powerpcle \
 	| pyramid \
+	| rx \
 	| score \
-	| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| 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 \
+	| spu \
+	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+	| ubicom32 \
 	| v850 | v850e \
 	| we32k \
-	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
-	| z8k)
+	| x86 | xc16x | xstormy16 | xtensa \
+	| z8k | z80)
 		basic_machine=$basic_machine-unknown
 		;;
-	m6811 | m68hc11 | m6812 | m68hc12)
+	c54x)
+		basic_machine=tic54x-unknown
+		;;
+	c55x)
+		basic_machine=tic55x-unknown
+		;;
+	c6x)
+		basic_machine=tic6x-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
 		# Motorola 68HC11/12.
 		basic_machine=$basic_machine-unknown
 		os=-none
@@ -300,6 +326,18 @@ case $basic_machine in
 		basic_machine=mt-unknown
 		;;
 
+	strongarm | thumb | xscale)
+		basic_machine=arm-unknown
+		;;
+
+	xscaleeb)
+		basic_machine=armeb-unknown
+		;;
+
+	xscaleel)
+		basic_machine=armel-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.
@@ -320,7 +358,7 @@ case $basic_machine in
 	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
 	| avr-* | avr32-* \
 	| bfin-* | bs2000-* \
-	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* \
 	| clipper-* | craynv-* | cydra-* \
 	| d10v-* | d30v-* | dlx-* \
 	| elxsi-* \
@@ -329,14 +367,17 @@ case $basic_machine in
 	| 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-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
 	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
 	| mips16-* \
 	| mips64-* | mips64el-* \
-	| mips64vr-* | mips64vrel-* \
+	| mips64octeon-* | mips64octeonel-* \
 	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
 	| mips64vr4100-* | mips64vr4100el-* \
 	| mips64vr4300-* | mips64vr4300el-* \
 	| mips64vr5000-* | mips64vr5000el-* \
@@ -351,27 +392,31 @@ case $basic_machine in
 	| mmix-* \
 	| mt-* \
 	| msp430-* \
+	| nds32-* | nds32le-* | nds32be-* \
 	| nios-* | nios2-* \
 	| none-* | np1-* | ns16k-* | ns32k-* \
+	| open8-* \
 	| orion-* \
 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
 	| pyramid-* \
-	| romp-* | rs6000-* \
-	| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| romp-* | rs6000-* | rx-* \
+	| 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-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+	| tahoe-* \
 	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tile-* | tilegx-* \
 	| tron-* \
+	| ubicom32-* \
 	| v850-* | v850e-* | vax-* \
 	| we32k-* \
-	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* \
 	| xstormy16-* | xtensa*-* \
 	| ymp-* \
-	| z8k-*)
+	| z8k-* | z80-*)
 		;;
 	# Recognize the basic CPU types without company name, with glob match.
 	xtensa*)
@@ -393,7 +438,7 @@ case $basic_machine in
 		basic_machine=a29k-amd
 		os=-udi
 		;;
-    	abacus)
+	abacus)
 		basic_machine=abacus-unknown
 		;;
 	adobe68k)
@@ -439,6 +484,10 @@ case $basic_machine in
 		basic_machine=m68k-apollo
 		os=-bsd
 		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
 	aux)
 		basic_machine=m68k-apple
 		os=-aux
@@ -455,10 +504,27 @@ case $basic_machine in
 		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
 		os=-linux
 		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c54x-*)
+		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c55x-*)
+		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c6x-*)
+		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
 	c90)
 		basic_machine=c90-cray
 		os=-unicos
 		;;
+	cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
 	convex-c1)
 		basic_machine=c1-convex
 		os=-bsd
@@ -487,7 +553,7 @@ case $basic_machine in
 		basic_machine=craynv-cray
 		os=-unicosmp
 		;;
-	cr16)
+	cr16 | cr16-*)
 		basic_machine=cr16-unknown
 		os=-elf
 		;;
@@ -526,6 +592,10 @@ case $basic_machine in
 		basic_machine=m88k-motorola
 		os=-sysv3
 		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
 	djgpp)
 		basic_machine=i586-pc
 		os=-msdosdjgpp
@@ -699,6 +769,9 @@ case $basic_machine in
 		basic_machine=ns32k-utek
 		os=-sysv
 		;;
+	microblaze)
+		basic_machine=microblaze-xilinx
+		;;
 	mingw32)
 		basic_machine=i386-pc
 		os=-mingw32
@@ -803,6 +876,12 @@ case $basic_machine in
 	np1)
 		basic_machine=np1-gould
 		;;
+	neo-tandem)
+		basic_machine=neo-tandem
+		;;
+	nse-tandem)
+		basic_machine=nse-tandem
+		;;
 	nsr-tandem)
 		basic_machine=nsr-tandem
 		;;
@@ -885,9 +964,10 @@ case $basic_machine in
 		;;
 	power)	basic_machine=power-ibm
 		;;
-	ppc)	basic_machine=powerpc-unknown
+	ppc | ppcbe)	basic_machine=powerpc-unknown
 		;;
-	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+	ppc-* | ppcbe-*)
+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
 	ppcle | powerpclittle | ppc-le | powerpc-little)
 		basic_machine=powerpcle-unknown
@@ -981,6 +1061,9 @@ case $basic_machine in
 		basic_machine=i860-stratus
 		os=-sysv4
 		;;
+	strongarm-* | thumb-*)
+		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
 	sun2)
 		basic_machine=m68000-sun
 		;;
@@ -1037,17 +1120,10 @@ case $basic_machine in
 		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
+	# This must be matched before tile*.
+	tilegx*)
+		basic_machine=tilegx-unknown
+		os=-linux-gnu
 		;;
 	tile*)
 		basic_machine=tile-unknown
@@ -1120,6 +1196,9 @@ case $basic_machine in
 	xps | xps100)
 		basic_machine=xps100-honeywell
 		;;
+	xscale-* | xscalee[bl]-*)
+		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+		;;
 	ymp)
 		basic_machine=ymp-cray
 		os=-unicos
@@ -1128,6 +1207,10 @@ case $basic_machine in
 		basic_machine=z8k-unknown
 		os=-sim
 		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
 	none)
 		basic_machine=none-none
 		os=-none
@@ -1166,7 +1249,7 @@ case $basic_machine in
 	we32k)
 		basic_machine=we32k-att
 		;;
-	sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+	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)
@@ -1213,9 +1296,12 @@ esac
 if [ x"$os" != x"" ]
 then
 case $os in
-        # First match some system type aliases
-        # that might get confused with valid system types.
+	# First match some system type aliases
+	# that might get confused with valid system types.
 	# -solaris* is a basic system type, with this one exception.
+	-auroraux)
+		os=-auroraux
+		;;
 	-solaris1 | -solaris1.*)
 		os=`echo $os | sed -e 's|solaris1|sunos4|'`
 		;;
@@ -1236,10 +1322,11 @@ case $os in
 	# 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* | -sunos | -sunos[34]*\
-	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* \
 	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-	      | -aos* \
+	      | -aos* | -aros* \
 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
 	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
@@ -1248,9 +1335,10 @@ case $os in
 	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-	      | -chorusos* | -chorusrdb* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
 	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -mingw32* | -linux-gnu* | -linux-android* \
+	      | -linux-newlib* | -linux-uclibc* \
 	      | -uxpv* | -beos* | -mpeix* | -udk* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@@ -1258,7 +1346,7 @@ case $os in
 	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
@@ -1297,7 +1385,7 @@ case $os in
 	-opened*)
 		os=-openedition
 		;;
-        -os400*)
+	-os400*)
 		os=-os400
 		;;
 	-wince*)
@@ -1346,7 +1434,7 @@ case $os in
 	-sinix*)
 		os=-sysv4
 		;;
-        -tpf*)
+	-tpf*)
 		os=-tpf
 		;;
 	-triton*)
@@ -1388,6 +1476,11 @@ case $os in
 	-zvmoe)
 		os=-zvmoe
 		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-nacl*)
+		;;
 	-none)
 		;;
 	*)
@@ -1410,10 +1503,10 @@ else
 # system, and we'll never get to this point.
 
 case $basic_machine in
-        score-*)
+	score-*)
 		os=-elf
 		;;
-        spu-*)
+	spu-*)
 		os=-elf
 		;;
 	*-acorn)
@@ -1425,8 +1518,17 @@ case $basic_machine in
 	arm*-semi)
 		os=-aout
 		;;
-        c4x-* | tic4x-*)
-        	os=-coff
+	c4x-* | tic4x-*)
+		os=-coff
+		;;
+	tic54x-*)
+		os=-coff
+		;;
+	tic55x-*)
+		os=-coff
+		;;
+	tic6x-*)
+		os=-coff
 		;;
 	# This must come before the *-dec entry.
 	pdp10-*)
@@ -1453,7 +1555,7 @@ case $basic_machine in
 	m68*-cisco)
 		os=-aout
 		;;
-        mep-*)
+	mep-*)
 		os=-elf
 		;;
 	mips*-cisco)
@@ -1480,7 +1582,7 @@ case $basic_machine in
 	*-ibm)
 		os=-aix
 		;;
-    	*-knuth)
+	*-knuth)
 		os=-mmixware
 		;;
 	*-wec)
@@ -1585,7 +1687,7 @@ case $basic_machine in
 			-sunos*)
 				vendor=sun
 				;;
-			-aix*)
+			-cnk*|-aix*)
 				vendor=ibm
 				;;
 			-beos*)
diff --git a/configure b/configure
index 3898cde..231abec 100755
--- a/configure
+++ b/configure
@@ -1,13 +1,13 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.65 for smuxi 0.8.
+# Generated by GNU Autoconf 2.68 for smuxi 0.8.9.
 #
 # Report bugs to <http://www.smuxi.org/issues/new>.
 #
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+# Foundation, Inc.
 #
 #
 # This configure script is free software; the Free Software Foundation
@@ -91,6 +91,7 @@ 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
@@ -173,6 +174,14 @@ test x\$exitcode = x0 || exit 1"
   as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
   eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
   test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+
+  test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1
 test \$(( 1 + 1 )) = 2 || exit 1"
   if (eval "$as_required") 2>/dev/null; then :
   as_have_required=yes
@@ -216,11 +225,18 @@ 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
-	exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+	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+"$@"}
 fi
 
     if test x$as_have_required = xno; then :
@@ -319,7 +335,7 @@ $as_echo X"$as_dir" |
       test -d "$as_dir" && break
     done
     test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
 
 
 } # as_fn_mkdir_p
@@ -359,19 +375,19 @@ else
 fi # as_fn_arith
 
 
-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
 # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
 # provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
+# script with STATUS, using 1 if that was 0.
 as_fn_error ()
 {
-  as_status=$?; test $as_status -eq 0 && as_status=1
-  if test "$3"; then
-    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $1" >&2
+  $as_echo "$as_me: error: $2" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
@@ -528,12 +544,14 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
 # Sed expression to map a string onto a valid variable name.
 as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
+SHELL=${CONFIG_SHELL-/bin/sh}
+
 
 test -n "$DJDIR" || exec 7<&0 </dev/null
 exec 6>&1
 
 # Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
 # so uname gets run too.
 ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
 
@@ -552,11 +570,47 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='smuxi'
 PACKAGE_TARNAME='smuxi'
-PACKAGE_VERSION='0.8'
-PACKAGE_STRING='smuxi 0.8'
+PACKAGE_VERSION='0.8.9'
+PACKAGE_STRING='smuxi 0.8.9'
 PACKAGE_BUGREPORT='http://www.smuxi.org/issues/new'
 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"
+
 gt_needs=
 enable_option_checking=no
 ac_subst_vars='am__EXEEXT_FALSE
@@ -573,6 +627,10 @@ ENABLE_FRONTEND_CURSES_FALSE
 ENABLE_FRONTEND_CURSES_TRUE
 ENABLE_FRONTEND_STFL_FALSE
 ENABLE_FRONTEND_STFL_TRUE
+ENABLE_STATIC_STFL_FALSE
+ENABLE_STATIC_STFL_TRUE
+STFL_LIBS
+STFL_CFLAGS
 ENABLE_FRONTEND_GNOME_XMPP_FALSE
 ENABLE_FRONTEND_GNOME_XMPP_TRUE
 ENABLE_FRONTEND_GNOME_IRC_FALSE
@@ -586,18 +644,16 @@ GTK_SHARP_20_LIBS
 GTK_SHARP_20_CFLAGS
 GLIB_SHARP_20_LIBS
 GLIB_SHARP_20_CFLAGS
+SERVER_COMPILER_FLAGS
 twitter_api_key
 ENABLE_ENGINE_TWITTER_FALSE
 ENABLE_ENGINE_TWITTER_TRUE
-XBUILD
 ENABLE_ENGINE_MSNP_FALSE
 ENABLE_ENGINE_MSNP_TRUE
 MSNPSHARP_LIBS
 MSNPSHARP_CFLAGS
 ENABLE_ENGINE_XMPP_FALSE
 ENABLE_ENGINE_XMPP_TRUE
-JABBER_NET_LIBS
-JABBER_NET_CFLAGS
 ENABLE_ENGINE_OSCAR_FALSE
 ENABLE_ENGINE_OSCAR_TRUE
 OSCARLIB_LIBS
@@ -606,16 +662,32 @@ ENABLE_ENGINE_IRC_FALSE
 ENABLE_ENGINE_IRC_TRUE
 SMARTIRC4NET_FILES
 subdirs
+NDESK_DBUS_GLIB_LIBS
+NDESK_DBUS_GLIB_CFLAGS
+NDESK_DBUS_LIBS
+NDESK_DBUS_CFLAGS
+DBUS_LIBS
+DBUS_SHARP_GLIB_LIBS
+DBUS_SHARP_GLIB_CFLAGS
+DBUS_SHARP_LIBS
+DBUS_SHARP_CFLAGS
 NOTIFY_SHARP_LIBS
 NOTIFY_SHARP_CFLAGS
 INDICATE_SHARP_LIBS
 INDICATE_SHARP_CFLAGS
+DB4O_FILES
+XBUILD
+BUNDLE_DB4O_FALSE
+BUNDLE_DB4O_TRUE
+DB4O_LIBS
+DB4O_CFLAGS
 NINI_LIBS
 NINI_CFLAGS
 BUNDLE_NINI_FALSE
 BUNDLE_NINI_TRUE
 LOG4NET_LIBS
 LOG4NET_CFLAGS
+XBUILD_FLAGS
 CSC_FLAGS
 CSC
 PROFILE
@@ -630,23 +702,16 @@ MONO_MODULE_CFLAGS
 PKG_CONFIG_LIBDIR
 PKG_CONFIG_PATH
 expanded_libdir
+dist_version
+DEV_VERSION_SUFFIX
+git_commit_hash
+git_branch
 LTLIBINTL
 LIBINTL
 INTLLIBS
 LTLIBICONV
 LIBICONV
 INTL_MACOSX_LIBS
-EGREP
-GREP
-CPP
-host_os
-host_vendor
-host_cpu
-host
-build_os
-build_vendor
-build_cpu
-build
 XGETTEXT_EXTRA_OPTIONS
 XGETTEXT_015
 GMSGFMT_015
@@ -670,22 +735,6 @@ GETTEXT_PACKAGE_ENGINE
 GETTEXT_PACKAGE
 POSUB
 DATADIRNAME
-am__fastdepCC_FALSE
-am__fastdepCC_TRUE
-CCDEPMODE
-AMDEPBACKSLASH
-AMDEP_FALSE
-AMDEP_TRUE
-am__quote
-am__include
-DEPDIR
-OBJEXT
-EXEEXT
-ac_ct_CC
-CPPFLAGS
-LDFLAGS
-CFLAGS
-CC
 ALL_LINGUAS
 INTLTOOL_PERL
 GMSGFMT
@@ -715,6 +764,52 @@ INTLTOOL_EXTRACT
 INTLTOOL_MERGE
 INTLTOOL_UPDATE
 USE_NLS
+CPP
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+ac_ct_AR
+AR
+DLLTOOL
+OBJDUMP
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LIBTOOL
 PKG_CONFIG
 MAINT
 MAINTAINER_MODE_FALSE
@@ -784,16 +879,25 @@ ac_subst_files=''
 ac_user_opts='
 enable_option_checking
 enable_maintainer_mode
-enable_nls
+enable_static
+enable_shared
+with_pic
+enable_fast_install
 enable_dependency_tracking
 with_gnu_ld
+with_sysroot
+enable_libtool_lock
+enable_nls
 enable_rpath
 with_libiconv_prefix
 with_libintl_prefix
+with_vendor_package_version
 enable_release
 enable_debug
+with_db4o
 with_indicate
 with_notify
+with_dbus
 enable_engine_irc
 enable_engine_oscar
 enable_engine_xmpp
@@ -825,14 +929,22 @@ LOG4NET_CFLAGS
 LOG4NET_LIBS
 NINI_CFLAGS
 NINI_LIBS
+DB4O_CFLAGS
+DB4O_LIBS
 INDICATE_SHARP_CFLAGS
 INDICATE_SHARP_LIBS
 NOTIFY_SHARP_CFLAGS
 NOTIFY_SHARP_LIBS
+DBUS_SHARP_CFLAGS
+DBUS_SHARP_LIBS
+DBUS_SHARP_GLIB_CFLAGS
+DBUS_SHARP_GLIB_LIBS
+NDESK_DBUS_CFLAGS
+NDESK_DBUS_LIBS
+NDESK_DBUS_GLIB_CFLAGS
+NDESK_DBUS_GLIB_LIBS
 OSCARLIB_CFLAGS
 OSCARLIB_LIBS
-JABBER_NET_CFLAGS
-JABBER_NET_LIBS
 MSNPSHARP_CFLAGS
 MSNPSHARP_LIBS
 GLIB_SHARP_20_CFLAGS
@@ -840,7 +952,9 @@ GLIB_SHARP_20_LIBS
 GTK_SHARP_20_CFLAGS
 GTK_SHARP_20_LIBS
 GLADE_SHARP_20_CFLAGS
-GLADE_SHARP_20_LIBS'
+GLADE_SHARP_20_LIBS
+STFL_CFLAGS
+STFL_LIBS'
 ac_subdirs_all='lib/SmartIrc4net'
 
 # Initialize some variables set by options.
@@ -903,8 +1017,9 @@ do
   fi
 
   case $ac_option in
-  *=*)	ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
-  *)	ac_optarg=yes ;;
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
   esac
 
   # Accept the important Cygnus configure options, so we can diagnose typos.
@@ -949,7 +1064,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -975,7 +1090,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -1179,7 +1294,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -1195,7 +1310,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -1225,8 +1340,8 @@ do
   | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
     x_libraries=$ac_optarg ;;
 
-  -*) as_fn_error "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information."
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
     ;;
 
   *=*)
@@ -1234,7 +1349,7 @@ Try \`$0 --help' for more information."
     # Reject names that are not valid shell variable names.
     case $ac_envvar in #(
       '' | [0-9]* | *[!_$as_cr_alnum]* )
-      as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
     esac
     eval $ac_envvar=\$ac_optarg
     export $ac_envvar ;;
@@ -1244,7 +1359,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
@@ -1252,13 +1367,13 @@ done
 
 if test -n "$ac_prev"; then
   ac_option=--`echo $ac_prev | sed 's/_/-/g'`
-  as_fn_error "missing argument to $ac_option"
+  as_fn_error $? "missing argument to $ac_option"
 fi
 
 if test -n "$ac_unrecognized_opts"; then
   case $enable_option_checking in
     no) ;;
-    fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
     *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
   esac
 fi
@@ -1281,7 +1396,7 @@ do
     [\\/$]* | ?:[\\/]* )  continue;;
     NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
   esac
-  as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
 done
 
 # There might be people who depend on the old broken behavior: `$host'
@@ -1295,8 +1410,8 @@ target=$target_alias
 if test "x$host_alias" != x; then
   if test "x$build_alias" = x; then
     cross_compiling=maybe
-    $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
-    If a cross compiler is detected then cross compile mode will be used." >&2
+    $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used" >&2
   elif test "x$build_alias" != "x$host_alias"; then
     cross_compiling=yes
   fi
@@ -1311,9 +1426,9 @@ test "$silent" = yes && exec 6>/dev/null
 ac_pwd=`pwd` && test -n "$ac_pwd" &&
 ac_ls_di=`ls -di .` &&
 ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
-  as_fn_error "working directory cannot be determined"
+  as_fn_error $? "working directory cannot be determined"
 test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
-  as_fn_error "pwd does not report name of working directory"
+  as_fn_error $? "pwd does not report name of working directory"
 
 
 # Find the source files, if location was not specified.
@@ -1352,11 +1467,11 @@ else
 fi
 if test ! -r "$srcdir/$ac_unique_file"; then
   test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
-  as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
 fi
 ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
 ac_abs_confdir=`(
-	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
 	pwd)`
 # When building in place, set srcdir=.
 if test "$ac_abs_confdir" = "$ac_pwd"; then
@@ -1382,7 +1497,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 smuxi 0.8 to adapt to many kinds of systems.
+\`configure' configures smuxi 0.8.9 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1396,7 +1511,7 @@ Configuration:
       --help=short        display options specific to this package
       --help=recursive    display the short help of all the included packages
   -V, --version           display version information and exit
-  -q, --quiet, --silent   do not print \`checking...' messages
+  -q, --quiet, --silent   do not print \`checking ...' messages
       --cache-file=FILE   cache test results in FILE [disabled]
   -C, --config-cache      alias for \`--cache-file=config.cache'
   -n, --no-create         do not create output files
@@ -1452,7 +1567,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of smuxi 0.8:";;
+     short | recursive ) echo "Configuration of smuxi 0.8.9:";;
    esac
   cat <<\_ACEOF
 
@@ -1462,15 +1577,20 @@ Optional Features:
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
   --enable-maintainer-mode  enable make rules and dependencies not useful
 			  (and sometimes confusing) to the casual installer
-  --disable-nls           do not use Native Language Support
+  --enable-static[=PKGS]  build static libraries [default=no]
+  --enable-shared[=PKGS]  build shared libraries [default=yes]
+  --enable-fast-install[=PKGS]
+                          optimize for fast installation [default=yes]
   --disable-dependency-tracking  speeds up one-time build
   --enable-dependency-tracking   do not reject slow dependency extractors
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+  --disable-nls           do not use Native Language Support
   --disable-rpath         do not hardcode runtime library paths
   --enable-release        Use 'RELEASE' Configuration [default=NO]
   --enable-debug          Use 'DEBUG' Configuration [default=YES]
   --enable-engine-irc     Enable IRC protocol support (default yes)
   --enable-engine-oscar   Enable OSCAR (AIM/ICQ) protocol support (default no)
-  --enable-engine-xmpp    Enable XMPP (Jabber) protocol support (default no)
+  --enable-engine-xmpp    Enable XMPP (Jabber) protocol support (default yes)
   --enable-engine-msnp    Enable MSNP protocol support (default no)
   --enable-engine-twitter Enable Twitter support (default yes)
   --enable-frontend-gnome Enable GNOME frontend (default yes)
@@ -1485,13 +1605,24 @@ Optional Features:
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-sysroot=DIR Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).
   --with-gnu-ld           assume the C compiler uses GNU ld default=no
   --with-libiconv-prefix[=DIR]  search for libiconv in DIR/include and DIR/lib
   --without-libiconv-prefix     don't search for libiconv in includedir and libdir
   --with-libintl-prefix[=DIR]  search for libintl in DIR/include and DIR/lib
   --without-libintl-prefix     don't search for libintl in includedir and libdir
+  --with-vendor-package-version="DISTRO_NAME PACKAGE_VERSION"
+                          Set the distro name and package version, e.g.
+                          "Debian 0.8-1"
+  --with-db4o=auto|system|included
+                          Use system or included db4o [default=auto]
   --with-indicate         Support Messaging Menu [default=auto]
   --with-notify           Support Desktop Notifications [default=auto]
+  --with-dbus             Support D-Bus [default=auto]
   --with-twitter-api-key  Specify custom Twitter API key
 
 Some influential environment variables:
@@ -1518,6 +1649,8 @@ Some influential environment variables:
               linker flags for LOG4NET, overriding pkg-config
   NINI_CFLAGS C compiler flags for NINI, overriding pkg-config
   NINI_LIBS   linker flags for NINI, overriding pkg-config
+  DB4O_CFLAGS C compiler flags for DB4O, overriding pkg-config
+  DB4O_LIBS   linker flags for DB4O, overriding pkg-config
   INDICATE_SHARP_CFLAGS
               C compiler flags for INDICATE_SHARP, overriding pkg-config
   INDICATE_SHARP_LIBS
@@ -1526,14 +1659,26 @@ Some influential environment variables:
               C compiler flags for NOTIFY_SHARP, overriding pkg-config
   NOTIFY_SHARP_LIBS
               linker flags for NOTIFY_SHARP, overriding pkg-config
+  DBUS_SHARP_CFLAGS
+              C compiler flags for DBUS_SHARP, overriding pkg-config
+  DBUS_SHARP_LIBS
+              linker flags for DBUS_SHARP, overriding pkg-config
+  DBUS_SHARP_GLIB_CFLAGS
+              C compiler flags for DBUS_SHARP_GLIB, overriding pkg-config
+  DBUS_SHARP_GLIB_LIBS
+              linker flags for DBUS_SHARP_GLIB, overriding pkg-config
+  NDESK_DBUS_CFLAGS
+              C compiler flags for NDESK_DBUS, overriding pkg-config
+  NDESK_DBUS_LIBS
+              linker flags for NDESK_DBUS, overriding pkg-config
+  NDESK_DBUS_GLIB_CFLAGS
+              C compiler flags for NDESK_DBUS_GLIB, overriding pkg-config
+  NDESK_DBUS_GLIB_LIBS
+              linker flags for NDESK_DBUS_GLIB, overriding pkg-config
   OSCARLIB_CFLAGS
               C compiler flags for OSCARLIB, overriding pkg-config
   OSCARLIB_LIBS
               linker flags for OSCARLIB, overriding pkg-config
-  JABBER_NET_CFLAGS
-              C compiler flags for JABBER_NET, overriding pkg-config
-  JABBER_NET_LIBS
-              linker flags for JABBER_NET, overriding pkg-config
   MSNPSHARP_CFLAGS
               C compiler flags for MSNPSHARP, overriding pkg-config
   MSNPSHARP_LIBS
@@ -1550,6 +1695,8 @@ Some influential environment variables:
               C compiler flags for GLADE_SHARP_20, overriding pkg-config
   GLADE_SHARP_20_LIBS
               linker flags for GLADE_SHARP_20, overriding pkg-config
+  STFL_CFLAGS C compiler flags for STFL, overriding pkg-config
+  STFL_LIBS   linker flags for STFL, overriding pkg-config
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
@@ -1617,10 +1764,10 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-smuxi configure 0.8
-generated by GNU Autoconf 2.65
+smuxi configure 0.8.9
+generated by GNU Autoconf 2.68
 
-Copyright (C) 2009 Free Software Foundation, Inc.
+Copyright (C) 2010 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 _ACEOF
@@ -1664,7 +1811,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 	ac_retval=1
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_compile
@@ -1710,77 +1857,41 @@ fi
   # 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; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_link
 
-# ac_fn_c_check_func LINENO FUNC VAR
-# ----------------------------------
-# Tests whether FUNC exists, setting the cache variable VAR accordingly
-ac_fn_c_check_func ()
+# 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 { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define $2 innocuous_$2
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $2 (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $2
-
-/* 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 $2 ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub_$2 || defined __stub___$2
-choke me
-#endif
-
-int
-main ()
-{
-return $2 ();
-  ;
-  return 0;
-}
+$4
+#include <$2>
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+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_exeext conftest.$ac_ext
+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; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
-} # ac_fn_c_check_func
+} # ac_fn_c_check_header_compile
 
 # ac_fn_c_try_cpp LINENO
 # ----------------------
@@ -1803,7 +1914,7 @@ $as_echo "$ac_try_echo"; } >&5
     mv -f conftest.er1 conftest.err
   fi
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } >/dev/null && {
+  test $ac_status = 0; } > conftest.i && {
 	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
 	 test ! -s conftest.err
        }; then :
@@ -1814,7 +1925,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
     ac_retval=1
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_cpp
@@ -1856,16 +1967,83 @@ sed 's/^/| /' conftest.$ac_ext >&5
        ac_retval=$ac_status
 fi
   rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  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_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  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.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* 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 $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext 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_func
 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 smuxi $as_me 0.8, which was
-generated by GNU Autoconf 2.65.  Invocation command line was
+It was created by smuxi $as_me 0.8.9, which was
+generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
 
@@ -1975,11 +2153,9 @@ trap 'exit_status=$?
   {
     echo
 
-    cat <<\_ASBOX
-## ---------------- ##
+    $as_echo "## ---------------- ##
 ## Cache variables. ##
-## ---------------- ##
-_ASBOX
+## ---------------- ##"
     echo
     # The following way of writing the cache mishandles newlines in values,
 (
@@ -2013,11 +2189,9 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
 )
     echo
 
-    cat <<\_ASBOX
-## ----------------- ##
+    $as_echo "## ----------------- ##
 ## Output variables. ##
-## ----------------- ##
-_ASBOX
+## ----------------- ##"
     echo
     for ac_var in $ac_subst_vars
     do
@@ -2030,11 +2204,9 @@ _ASBOX
     echo
 
     if test -n "$ac_subst_files"; then
-      cat <<\_ASBOX
-## ------------------- ##
+      $as_echo "## ------------------- ##
 ## File substitutions. ##
-## ------------------- ##
-_ASBOX
+## ------------------- ##"
       echo
       for ac_var in $ac_subst_files
       do
@@ -2048,11 +2220,9 @@ _ASBOX
     fi
 
     if test -s confdefs.h; then
-      cat <<\_ASBOX
-## ----------- ##
+      $as_echo "## ----------- ##
 ## confdefs.h. ##
-## ----------- ##
-_ASBOX
+## ----------- ##"
       echo
       cat confdefs.h
       echo
@@ -2107,7 +2277,12 @@ _ACEOF
 ac_site_file1=NONE
 ac_site_file2=NONE
 if test -n "$CONFIG_SITE"; then
-  ac_site_file1=$CONFIG_SITE
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
 elif test "x$prefix" != xNONE; then
   ac_site_file1=$prefix/share/config.site
   ac_site_file2=$prefix/etc/config.site
@@ -2122,7 +2297,11 @@ do
     { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
 $as_echo "$as_me: loading site script $ac_site_file" >&6;}
     sed 's/^/| /' "$ac_site_file" >&5
-    . "$ac_site_file"
+    . "$ac_site_file" \
+      || { { $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; }
   fi
 done
 
@@ -2199,7 +2378,7 @@ if $ac_cache_corrupted; then
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
   { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
 fi
 ## -------------------- ##
 ## Main body of script. ##
@@ -2218,16 +2397,22 @@ am__api_version='1.11'
 
 ac_aux_dir=
 for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
-  for ac_t in install-sh install.sh shtool; do
-    if test -f "$ac_dir/$ac_t"; then
-      ac_aux_dir=$ac_dir
-      ac_install_sh="$ac_aux_dir/$ac_t -c"
-      break 2
-    fi
-  done
+  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
+  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,
@@ -2256,7 +2441,7 @@ ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
 { $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 :
+if ${ac_cv_path_install+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -2343,11 +2528,11 @@ am_lf='
 '
 case `pwd` in
   *[\\\"\#\$\&\'\`$am_lf]*)
-    as_fn_error "unsafe absolute working directory name" "$LINENO" 5;;
+    as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
 esac
 case $srcdir in
   *[\\\"\#\$\&\'\`$am_lf\ \	]*)
-    as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+    as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
 esac
 
 # Do `set' in a subshell so we don't clobber the current shell's
@@ -2369,7 +2554,7 @@ if (
       # if, for instance, CONFIG_SHELL is bash and it inherits a
       # broken ls alias from the environment.  This has actually
       # happened.  Such a system could not be considered "sane".
-      as_fn_error "ls -t appears to fail.  Make sure there is not a broken
+      as_fn_error $? "ls -t appears to fail.  Make sure there is not a broken
 alias in your environment" "$LINENO" 5
    fi
 
@@ -2379,7 +2564,7 @@ then
    # Ok.
    :
 else
-   as_fn_error "newly created file is older than distributed files!
+   as_fn_error $? "newly created file is older than distributed files!
 Check your system clock" "$LINENO" 5
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
@@ -2433,7 +2618,7 @@ if test "$cross_compiling" != no; then
 set dummy ${ac_tool_prefix}strip; 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_STRIP+set}" = set; then :
+if ${ac_cv_prog_STRIP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$STRIP"; then
@@ -2473,7 +2658,7 @@ if test -z "$ac_cv_prog_STRIP"; then
 set dummy strip; 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_ac_ct_STRIP+set}" = set; then :
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_STRIP"; then
@@ -2526,7 +2711,7 @@ INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
 if test -z "$MKDIR_P"; then
-  if test "${ac_cv_path_mkdir+set}" = set; then :
+  if ${ac_cv_path_mkdir+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -2577,7 +2762,7 @@ do
 set dummy $ac_prog; 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_AWK+set}" = set; then :
+if ${ac_cv_prog_AWK+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$AWK"; then
@@ -2617,7 +2802,7 @@ done
 $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 { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat >conftest.make <<\_ACEOF
@@ -2625,7 +2810,7 @@ SHELL = /bin/sh
 all:
 	@echo '@@@%%%=$(MAKE)=@@@%%%'
 _ACEOF
-# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+# 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;;
@@ -2659,7 +2844,7 @@ if test "`cd $srcdir && pwd`" != "`pwd`"; then
   am__isrc=' -I$(srcdir)'
   # test to see if srcdir already configured
   if test -f $srcdir/config.status; then
-    as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+    as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
   fi
 fi
 
@@ -2675,7 +2860,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='smuxi'
- VERSION='0.8'
+ VERSION='0.8.9'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -2783,7 +2968,7 @@ do
 done
 rm -rf conftest.dir
 
-if test "${am_cv_prog_tar_ustar+set}" = set; then :
+if ${am_cv_prog_tar_ustar+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   am_cv_prog_tar_ustar=$_am_tool
@@ -2824,7 +3009,7 @@ fi
 set dummy pkg-config; 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_PKG_CONFIG+set}" = set; then :
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $PKG_CONFIG in
@@ -2862,71 +3047,252 @@ fi
 
 
 if test "x$PKG_CONFIG" = "xno"; then
-	as_fn_error "You need to install pkg-config" "$LINENO" 5
+	as_fn_error $? "You need to install pkg-config" "$LINENO" 5
 fi
 
 
 
-# I18N
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5
-$as_echo_n "checking whether NLS is requested... " >&6; }
-    # Check whether --enable-nls was given.
-if test "${enable_nls+set}" = set; then :
-  enableval=$enable_nls; USE_NLS=$enableval
+# Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+  enableval=$enable_static; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
 else
-  USE_NLS=yes
+  enable_static=no
 fi
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5
-$as_echo "$USE_NLS" >&6; }
 
 
-DEPDIR="${am__leading_dot}deps"
 
-ac_config_commands="$ac_config_commands depfiles"
 
 
-am_make=${MAKE-make}
-cat > confinc << 'END'
-am__doit:
-	@echo this is the am__doit target
-.PHONY: am__doit
-END
-# If we don't find an include directive, just comment out the code.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
-$as_echo_n "checking for style of include used by $am_make... " >&6; }
-am__include="#"
-am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
-  am__include=include
-  am__quote=
-  _am_result=GNU
-  ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
-   echo '.include "confinc"' > confmf
-   case `$am_make -s -f confmf 2> /dev/null` in #(
-   *the\ am__doit\ target*)
-     am__include=.include
-     am__quote="\""
-     _am_result=BSD
-     ;;
-   esac
-fi
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
-$as_echo "$_am_result" >&6; }
-rm -f confinc confmf
 
-# Check whether --enable-dependency-tracking was given.
+case `pwd` in
+  *\ * | *\	*)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# 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
+
+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_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+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
+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
+
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO ""
+}
+
+case "$ECHO" in
+  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
 if test "${enable_dependency_tracking+set}" = set; then :
   enableval=$enable_dependency_tracking;
 fi
@@ -2954,7 +3320,7 @@ if test -n "$ac_tool_prefix"; then
 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 test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
@@ -2994,7 +3360,7 @@ if test -z "$ac_cv_prog_CC"; then
 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 test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_CC"; then
@@ -3047,7 +3413,7 @@ if test -z "$CC"; then
 set dummy ${ac_tool_prefix}cc; 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_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
@@ -3087,7 +3453,7 @@ if test -z "$CC"; then
 set dummy cc; 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_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
@@ -3146,7 +3512,7 @@ if test -z "$CC"; then
 set dummy $ac_tool_prefix$ac_prog; 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_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
@@ -3190,7 +3556,7 @@ do
 set dummy $ac_prog; 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_ac_ct_CC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_CC"; then
@@ -3244,8 +3610,8 @@ 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; }
+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
@@ -3359,9 +3725,8 @@ 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_set_status 77
-as_fn_error "C compiler cannot create executables
-See \`config.log' for more details." "$LINENO" 5; }; }
+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; }
@@ -3403,8 +3768,8 @@ 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; }
+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
@@ -3461,9 +3826,9 @@ $as_echo "$ac_try_echo"; } >&5
     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.
+as_fn_error $? "cannot run C compiled programs.
 If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5; }
     fi
   fi
 fi
@@ -3474,7 +3839,7 @@ 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 test "${ac_cv_objext+set}" = set; then :
+if ${ac_cv_objext+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -3514,8 +3879,8 @@ 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; }
+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
@@ -3525,7 +3890,7 @@ 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 test "${ac_cv_c_compiler_gnu+set}" = set; then :
+if ${ac_cv_c_compiler_gnu+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -3562,7 +3927,7 @@ 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 test "${ac_cv_prog_cc_g+set}" = set; then :
+if ${ac_cv_prog_cc_g+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_save_c_werror_flag=$ac_c_werror_flag
@@ -3640,7 +4005,7 @@ else
 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 test "${ac_cv_prog_cc_c89+set}" = set; then :
+if ${ac_cv_prog_cc_c89+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_cv_prog_cc_c89=no
@@ -3739,7 +4104,7 @@ depcc="$CC"   am_compiler_list=
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
 $as_echo_n "checking dependency style of $depcc... " >&6; }
-if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then :
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
@@ -3862,187 +4227,286 @@ else
 fi
 
 
-
-
-
-case "$am__api_version" in
-    1.01234)
-	as_fn_error "Automake 1.5 or newer is required to use intltool" "$LINENO" 5
-    ;;
-    *)
-    ;;
-esac
-
-if test -n "0.25"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for intltool >= 0.25" >&5
-$as_echo_n "checking for intltool >= 0.25... " >&6; }
-
-    INTLTOOL_REQUIRED_VERSION_AS_INT=`echo 0.25 | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'`
-    INTLTOOL_APPLIED_VERSION=`intltool-update --version | head -1 | cut -d" " -f3`
-    INTLTOOL_APPLIED_VERSION_AS_INT=`echo $INTLTOOL_APPLIED_VERSION | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'`
-
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_APPLIED_VERSION found" >&5
-$as_echo "$INTLTOOL_APPLIED_VERSION found" >&6; }
-    test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT" ||
-	as_fn_error "Your intltool is too old.  You need intltool 0.25 or later." "$LINENO" 5
-fi
-
-# Extract the first word of "intltool-update", so it can be a program name with args.
-set dummy intltool-update; 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_INTLTOOL_UPDATE+set}" = set; then :
+{ $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 ${ac_cv_path_SED+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  case $INTLTOOL_UPDATE in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_INTLTOOL_UPDATE="$INTLTOOL_UPDATE" # Let the user override the test with a path.
-  ;;
-  *)
+            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_path_INTLTOOL_UPDATE="$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
+      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
-IFS=$as_save_IFS
-
-  ;;
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
 esac
-fi
-INTLTOOL_UPDATE=$ac_cv_path_INTLTOOL_UPDATE
-if test -n "$INTLTOOL_UPDATE"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_UPDATE" >&5
-$as_echo "$INTLTOOL_UPDATE" >&6; }
+
+      $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
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  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
 
-# Extract the first word of "intltool-merge", so it can be a program name with args.
-set dummy intltool-merge; 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_INTLTOOL_MERGE+set}" = set; then :
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $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
 else
-  case $INTLTOOL_MERGE in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_INTLTOOL_MERGE="$INTLTOOL_MERGE" # Let the user override the test with a path.
-  ;;
-  *)
+  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
+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
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_path_INTLTOOL_MERGE="$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
+      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
-IFS=$as_save_IFS
-
-  ;;
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
 esac
-fi
-INTLTOOL_MERGE=$ac_cv_path_INTLTOOL_MERGE
-if test -n "$INTLTOOL_MERGE"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_MERGE" >&5
-$as_echo "$INTLTOOL_MERGE" >&6; }
+
+      $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
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  ac_cv_path_GREP=$GREP
+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"
 
 
-# Extract the first word of "intltool-extract", so it can be a program name with args.
-set dummy intltool-extract; 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_INTLTOOL_EXTRACT+set}" = set; then :
+{ $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
-  case $INTLTOOL_EXTRACT in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_INTLTOOL_EXTRACT="$INTLTOOL_EXTRACT" # Let the user override the test with a path.
-  ;;
-  *)
+  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
+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
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_path_INTLTOOL_EXTRACT="$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
+      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
-IFS=$as_save_IFS
-
-  ;;
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
 esac
-fi
-INTLTOOL_EXTRACT=$ac_cv_path_INTLTOOL_EXTRACT
-if test -n "$INTLTOOL_EXTRACT"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_EXTRACT" >&5
-$as_echo "$INTLTOOL_EXTRACT" >&6; }
+
+      $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
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  ac_cv_path_EGREP=$EGREP
 fi
 
-
-if test -z "$INTLTOOL_UPDATE" -o -z "$INTLTOOL_MERGE" -o -z "$INTLTOOL_EXTRACT"; then
-    as_fn_error "The intltool scripts were not found. Please install intltool." "$LINENO" 5
+   fi
 fi
-
-  INTLTOOL_DESKTOP_RULE='%.desktop:   %.desktop.in   $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-     INTLTOOL_KEYS_RULE='%.keys:      %.keys.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-     INTLTOOL_PROP_RULE='%.prop:      %.prop.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-      INTLTOOL_OAF_RULE='%.oaf:       %.oaf.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -p $(top_srcdir)/po $< $@'
-     INTLTOOL_PONG_RULE='%.pong:      %.pong.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-   INTLTOOL_SERVER_RULE='%.server:    %.server.in    $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-    INTLTOOL_SHEET_RULE='%.sheet:     %.sheet.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-       INTLTOOL_UI_RULE='%.ui:        %.ui.in        $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-      INTLTOOL_XML_RULE='%.xml:       %.xml.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-      INTLTOOL_XML_NOMERGE_RULE='%.xml:       %.xml.in       $(INTLTOOL_MERGE) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< $@'
-      INTLTOOL_XAM_RULE='%.xam:       %.xml.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-      INTLTOOL_KBD_RULE='%.kbd:       %.kbd.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-    INTLTOOL_CAVES_RULE='%.caves:     %.caves.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-  INTLTOOL_SCHEMAS_RULE='%.schemas:   %.schemas.in   $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-    INTLTOOL_THEME_RULE='%.theme:     %.theme.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-    INTLTOOL_SERVICE_RULE='%.service: %.service.in   $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-   INTLTOOL_POLICY_RULE='%.policy:    %.policy.in    $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
-
-
-
-
-
-
-
+{ $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 fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+   then ac_cv_path_FGREP="$GREP -F"
+   else
+     if test -z "$FGREP"; then
+  ac_path_FGREP_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 fgrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+  # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_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 'FGREP' >> "conftest.nl"
+    "$ac_path_FGREP" FGREP < "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_FGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_FGREP="$ac_path_FGREP"
+      ac_path_FGREP_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_FGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_FGREP"; then
+    as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_FGREP=$FGREP
+fi
 
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
 
 
+test -z "$GREP" && GREP=grep
 
 
 
@@ -4062,39 +4526,524 @@ INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcar
 
 
 
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in dumpbin "link -dump"
+  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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DUMPBIN"; then
+  ac_cv_prog_DUMPBIN="$DUMPBIN" # 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_DUMPBIN="$ac_tool_prefix$ac_prog"
+    $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
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$DUMPBIN" && break
+  done
+fi
+if test -z "$DUMPBIN"; then
+  ac_ct_DUMPBIN=$DUMPBIN
+  for ac_prog in dumpbin "link -dump"
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; 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_DUMPBIN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DUMPBIN"; then
+  ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # 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_ac_ct_DUMPBIN="$ac_prog"
+    $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
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_DUMPBIN" && break
+done
+
+  if test "x$ac_ct_DUMPBIN" = x; then
+    DUMPBIN=":"
+  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
+    DUMPBIN=$ac_ct_DUMPBIN
+  fi
+fi
+
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
+
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+
+
 
 
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+  cat conftest.out >&5
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
 
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+    i=0
+  teststring="ABCD"
 
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
 
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
 
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
 
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
 
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
 
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
 
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
 
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
 
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[	 ]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
 
+fi
 
+if test -n $lt_cv_sys_max_cmd_len ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
 
 
 
 
 
 
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
 
 
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
 
 
 
 
 
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
 
 
 
@@ -4104,20 +5053,109 @@ INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcar
 
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
 
+fi
 
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
 
 
 
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
 
+fi
 
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
 
 
 
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
 
 
 
@@ -4127,27 +5165,25 @@ INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcar
 
 
 
-# Check the gettext tools to make sure they are GNU
-# Extract the first word of "xgettext", so it can be a program name with args.
-set dummy xgettext; ac_word=$2
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; 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_XGETTEXT+set}" = set; then :
+if ${ac_cv_prog_OBJDUMP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  case $XGETTEXT in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # 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_path_XGETTEXT="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -4155,39 +5191,39 @@ done
   done
 IFS=$as_save_IFS
 
-  ;;
-esac
 fi
-XGETTEXT=$ac_cv_path_XGETTEXT
-if test -n "$XGETTEXT"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5
-$as_echo "$XGETTEXT" >&6; }
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
 
 
-# Extract the first word of "msgmerge", so it can be a program name with args.
-set dummy msgmerge; ac_word=$2
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+  ac_ct_OBJDUMP=$OBJDUMP
+  # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; 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_MSGMERGE+set}" = set; then :
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  case $MSGMERGE in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+  if test -n "$ac_ct_OBJDUMP"; then
+  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # 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_path_MSGMERGE="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_prog_ac_ct_OBJDUMP="objdump"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -4195,39 +5231,305 @@ done
   done
 IFS=$as_save_IFS
 
-  ;;
-esac
 fi
-MSGMERGE=$ac_cv_path_MSGMERGE
-if test -n "$MSGMERGE"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5
-$as_echo "$MSGMERGE" >&6; }
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
 
+  if test "x$ac_ct_OBJDUMP" = x; then
+    OBJDUMP="false"
+  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
+    OBJDUMP=$ac_ct_OBJDUMP
+  fi
+else
+  OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
 
-# Extract the first word of "msgfmt", so it can be a program name with args.
-set dummy msgfmt; 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_MSGFMT+set}" = set; then :
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  case $MSGFMT in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[45]*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc*)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
   ;;
+
+haiku*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
   *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[3-9]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd* | netbsdelf*-gnu)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; 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_DLLTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DLLTOOL"; then
+  ac_cv_prog_DLLTOOL="$DLLTOOL" # 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_path_MSGFMT="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -4235,39 +5537,39 @@ done
   done
 IFS=$as_save_IFS
 
-  ;;
-esac
 fi
-MSGFMT=$ac_cv_path_MSGFMT
-if test -n "$MSGFMT"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5
-$as_echo "$MSGFMT" >&6; }
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
 
 
-# Extract the first word of "gmsgfmt", so it can be a program name with args.
-set dummy gmsgfmt; ac_word=$2
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+  ac_ct_DLLTOOL=$DLLTOOL
+  # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; 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_GMSGFMT+set}" = set; then :
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  case $GMSGFMT in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+  if test -n "$ac_ct_DLLTOOL"; then
+  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # 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_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -4275,50 +5577,103 @@ done
   done
 IFS=$as_save_IFS
 
-  test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
-  ;;
-esac
 fi
-GMSGFMT=$ac_cv_path_GMSGFMT
-if test -n "$GMSGFMT"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5
-$as_echo "$GMSGFMT" >&6; }
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
 
-
-if test -z "$XGETTEXT" -o -z "$MSGMERGE" -o -z "$MSGFMT"; then
-    as_fn_error "GNU gettext tools not found; required for intltool" "$LINENO" 5
+  if test "x$ac_ct_DLLTOOL" = x; then
+    DLLTOOL="false"
+  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
+    DLLTOOL=$ac_ct_DLLTOOL
+  fi
+else
+  DLLTOOL="$ac_cv_prog_DLLTOOL"
 fi
-xgversion="`$XGETTEXT --version|grep '(GNU ' 2> /dev/null`"
-mmversion="`$MSGMERGE --version|grep '(GNU ' 2> /dev/null`"
-mfversion="`$MSGFMT --version|grep '(GNU ' 2> /dev/null`"
-if test -z "$xgversion" -o -z "$mmversion" -o -z "$mfversion"; then
-    as_fn_error "GNU gettext tools not found; required for intltool" "$LINENO" 5
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
 
-# Extract the first word of "perl", so it can be a program name with args.
-set dummy perl; ac_word=$2
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar
+  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
 { $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_INTLTOOL_PERL+set}" = set; then :
+if ${ac_cv_prog_AR+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  case $INTLTOOL_PERL in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_INTLTOOL_PERL="$INTLTOOL_PERL" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # 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_path_INTLTOOL_PERL="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -4326,81 +5681,141 @@ done
   done
 IFS=$as_save_IFS
 
-  ;;
-esac
 fi
-INTLTOOL_PERL=$ac_cv_path_INTLTOOL_PERL
-if test -n "$INTLTOOL_PERL"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_PERL" >&5
-$as_echo "$INTLTOOL_PERL" >&6; }
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
 
 
-if test -z "$INTLTOOL_PERL"; then
-   as_fn_error "perl not found" "$LINENO" 5
+    test -n "$AR" && break
+  done
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for perl >= 5.8.1" >&5
-$as_echo_n "checking for perl >= 5.8.1... " >&6; }
-$INTLTOOL_PERL -e "use 5.8.1;" > /dev/null 2>&1
-if test $? -ne 0; then
-   as_fn_error "perl 5.8.1 is required for intltool" "$LINENO" 5
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; 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_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-   IT_PERL_VERSION="`$INTLTOOL_PERL -e \"printf '%vd', $^V\"`"
-   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IT_PERL_VERSION" >&5
-$as_echo "$IT_PERL_VERSION" >&6; }
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # 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_ac_ct_AR="$ac_prog"
+    $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
+
 fi
-if test "x" != "xno-xml"; then
-   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML::Parser" >&5
-$as_echo_n "checking for XML::Parser... " >&6; }
-   if `$INTLTOOL_PERL -e "require XML::Parser" 2>/dev/null`; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
-$as_echo "ok" >&6; }
-   else
-       as_fn_error "XML::Parser perl module is required for intltool" "$LINENO" 5
-   fi
 fi
-
-# Substitute ALL_LINGUAS so we can use it in po/Makefile
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
 
-# Set DATADIRNAME correctly if it is not set yet
-# (copied from glib-gettext.m4)
-if test -z "$DATADIRNAME"; then
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+  test -n "$ac_ct_AR" && break
+done
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  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
+    AR=$ac_ct_AR
+  fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ar_at_file=no
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
 main ()
 {
-extern int _nl_msg_cat_cntr;
-                       return _nl_msg_cat_cntr
+
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  DATADIRNAME=share
-else
-  case $host in
-    *-*-solaris*)
-                        ac_fn_c_check_func "$LINENO" "bind_textdomain_codeset" "ac_cv_func_bind_textdomain_codeset"
-if test "x$ac_cv_func_bind_textdomain_codeset" = x""yes; then :
-  DATADIRNAME=share
-else
-  DATADIRNAME=lib
+if ac_fn_c_try_compile "$LINENO"; then :
+  echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+
 fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
-    ;;
-    *)
-    DATADIRNAME=lib
-    ;;
-    esac
 fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
 fi
 
 
@@ -4408,997 +5823,1374 @@ fi
 
 
 
-POSUB="
-	po
-	po-Engine
-	po-Engine-IRC
-	po-Engine-XMPP
-	po-Engine-OSCAR
-	po-Engine-MSNP
-	po-Server
-	po-Frontend
-	po-Frontend-GNOME
-	po-Frontend-GNOME-IRC
-	po-Frontend-GNOME-XMPP
-	po-Frontend-SWF
-"
 
-GETTEXT_PACKAGE=smuxi
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; 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_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # 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_STRIP="${ac_tool_prefix}strip"
+    $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
 
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
-GETTEXT_PACKAGE_ENGINE=smuxi-engine
 
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; 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_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # 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_ac_ct_STRIP="strip"
+    $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 >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_ENGINE "$GETTEXT_PACKAGE_ENGINE"
-_ACEOF
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  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
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
 
-GETTEXT_PACKAGE_ENGINE_IRC=smuxi-engine-irc
+test -z "$STRIP" && STRIP=:
 
 
-cat >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_ENGINE_IRC "$GETTEXT_PACKAGE_ENGINE_IRC"
-_ACEOF
 
 
-GETTEXT_PACKAGE_ENGINE_XMPP=smuxi-engine-xmpp
 
 
-cat >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_ENGINE_XMPP "$GETTEXT_PACKAGE_ENGINE_XMPP"
-_ACEOF
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; 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_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # 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_RANLIB="${ac_tool_prefix}ranlib"
+    $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
 
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
-GETTEXT_PACKAGE_ENGINE_OSCAR=smuxi-engine-oscar
 
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; 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_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # 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_ac_ct_RANLIB="ranlib"
+    $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 >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_ENGINE_OSCAR "$GETTEXT_PACKAGE_ENGINE_OSCAR"
-_ACEOF
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  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
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
 
-GETTEXT_PACKAGE_ENGINE_MSNP=smuxi-engine-msnp
+test -z "$RANLIB" && RANLIB=:
 
 
-cat >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_ENGINE_MSNP "$GETTEXT_PACKAGE_ENGINE_MSNP"
-_ACEOF
 
 
-GETTEXT_PACKAGE_ENGINE_TWITTER=smuxi-engine-twitter
 
 
-cat >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_ENGINE_TWITTER "$GETTEXT_PACKAGE_ENGINE_TWITTER"
-_ACEOF
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
 
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
 
-GETTEXT_PACKAGE_SERVER=smuxi-server
-
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
 
-cat >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_SERVER "$GETTEXT_PACKAGE_SERVER"
-_ACEOF
 
 
-GETTEXT_PACKAGE_FRONTEND=smuxi-frontend
 
 
-cat >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_FRONTEND "$GETTEXT_PACKAGE_FRONTEND"
-_ACEOF
 
 
-GETTEXT_PACKAGE_FRONTEND_GNOME=smuxi-frontend-gnome
 
 
-cat >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_FRONTEND_GNOME "$GETTEXT_PACKAGE_FRONTEND_GNOME"
-_ACEOF
 
 
-GETTEXT_PACKAGE_FRONTEND_GNOME_IRC=smuxi-frontend-gnome-irc
 
 
-cat >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_FRONTEND_GNOME_IRC "$GETTEXT_PACKAGE_FRONTEND_GNOME_IRC"
-_ACEOF
 
 
-GETTEXT_PACKAGE_FRONTEND_GNOME_XMPP=smuxi-frontend-gnome-xmpp
 
 
-cat >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_FRONTEND_GNOME_XMPP "$GETTEXT_PACKAGE_FRONTEND_GNOME_XMPP"
-_ACEOF
 
 
-GETTEXT_PACKAGE_FRONTEND_STFL=smuxi-frontend-stfl
 
 
-cat >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_FRONTEND_STFL "$GETTEXT_PACKAGE_FRONTEND_STFL"
-_ACEOF
 
 
-GETTEXT_PACKAGE_FRONTEND_CURSES=smuxi-frontend-curses
 
 
-cat >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_FRONTEND_CURSES "$GETTEXT_PACKAGE_FRONTEND_CURSES"
-_ACEOF
 
 
-GETTEXT_PACKAGE_FRONTEND_SWF=smuxi-frontend-swf
 
 
-cat >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_FRONTEND_SWF "$GETTEXT_PACKAGE_FRONTEND_SWF"
-_ACEOF
 
 
-GETTEXT_PACKAGE_FRONTEND_WPF=smuxi-frontend-wpf
 
 
-cat >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_FRONTEND_WPF "$GETTEXT_PACKAGE_FRONTEND_WPF"
-_ACEOF
 
 
 
 
-      GETTEXT_MACRO_VERSION=0.18
 
 
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
 
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
 
-# Prepare PATH_SEPARATOR.
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
+# Allow CC to be a program name with arguments.
+compiler=$CC
 
-# Find out how to test for executable files. Don't use a zero-byte file,
-# as systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
-  ac_executable_p="test -x"
-else
-  ac_executable_p="test -f"
-fi
-rm -f conf$$.file
 
-# Extract the first word of "msgfmt", so it can be a program name with args.
-set dummy msgfmt; 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_MSGFMT+set}" = set; then :
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  case "$MSGFMT" in
-  [\\/]* | ?:[\\/]*)
-    ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
-    ;;
-  *)
-    ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
-    for ac_dir in $PATH; do
-      IFS="$ac_save_IFS"
-      test -z "$ac_dir" && ac_dir=.
-      for ac_exec_ext in '' $ac_executable_extensions; do
-        if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
-          echo "$as_me: trying $ac_dir/$ac_word..." >&5
-          if $ac_dir/$ac_word --statistics /dev/null >&5 2>&1 &&
-     (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then
-            ac_cv_path_MSGFMT="$ac_dir/$ac_word$ac_exec_ext"
-            break 2
-          fi
-        fi
-      done
-    done
-    IFS="$ac_save_IFS"
-  test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":"
-    ;;
-esac
-fi
-MSGFMT="$ac_cv_path_MSGFMT"
-if test "$MSGFMT" != ":"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5
-$as_echo "$MSGFMT" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
 
-  # Extract the first word of "gmsgfmt", so it can be a program name with args.
-set dummy gmsgfmt; 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_GMSGFMT+set}" = set; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $GMSGFMT in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[BCDT]'
   ;;
-  *)
-  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_GMSGFMT="$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
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[ABCDEGRST]'
   fi
-done
-  done
-IFS=$as_save_IFS
+  ;;
+irix* | nonstopux*)
+  symcode='[BCDEGRST]'
+  ;;
+osf*)
+  symcode='[BCDEGQRST]'
+  ;;
+solaris*)
+  symcode='[BDRT]'
+  ;;
+sco3.2v5*)
+  symcode='[DT]'
+  ;;
+sysv4.2uw2*)
+  symcode='[DT]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[ABDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
 
-  test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
   ;;
 esac
-fi
-GMSGFMT=$ac_cv_path_GMSGFMT
-if test -n "$GMSGFMT"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5
-$as_echo "$GMSGFMT" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
 
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK '"\
+"     {last_section=section; section=\$ 3};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
 
+  # Check to see that the pipe works correctly.
+  pipe_works=no
 
-    case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
-    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;;
-    *) MSGFMT_015=$MSGFMT ;;
-  esac
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
 
-  case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
-    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;;
-    *) GMSGFMT_015=$GMSGFMT ;;
-  esac
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
 
-# Prepare PATH_SEPARATOR.
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+LT_DLSYM_CONST struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_globsym_save_LIBS=$LIBS
+	  lt_globsym_save_CFLAGS=$CFLAGS
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS=$lt_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_save_CFLAGS
+	else
+	  echo "cannot find nm_test_func in $nlist" >&5
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
   else
-    PATH_SEPARATOR=:
+    echo "$progname: failed program was:" >&5
+    cat conftest.$ac_ext >&5
   fi
-  rm -f conf$$.sh
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+
 fi
 
-# Find out how to test for executable files. Don't use a zero-byte file,
-# as systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
-  ac_executable_p="test -x"
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
 else
-  ac_executable_p="test -f"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
 fi
-rm -f conf$$.file
 
-# Extract the first word of "xgettext", so it can be a program name with args.
-set dummy xgettext; 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_XGETTEXT+set}" = set; then :
-  $as_echo_n "(cached) " >&6
-else
-  case "$XGETTEXT" in
-  [\\/]* | ?:[\\/]*)
-    ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
-    ;;
-  *)
-    ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
-    for ac_dir in $PATH; do
-      IFS="$ac_save_IFS"
-      test -z "$ac_dir" && ac_dir=.
-      for ac_exec_ext in '' $ac_executable_extensions; do
-        if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
-          echo "$as_me: trying $ac_dir/$ac_word..." >&5
-          if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&5 2>&1 &&
-     (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then
-            ac_cv_path_XGETTEXT="$ac_dir/$ac_word$ac_exec_ext"
-            break 2
-          fi
-        fi
-      done
-    done
-    IFS="$ac_save_IFS"
-  test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
-    ;;
-esac
-fi
-XGETTEXT="$ac_cv_path_XGETTEXT"
-if test "$XGETTEXT" != ":"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5
-$as_echo "$XGETTEXT" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+  nm_file_list_spec='@'
 fi
 
-    rm -f messages.po
 
-    case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
-    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;;
-    *) XGETTEXT_015=$XGETTEXT ;;
-  esac
 
 
 
-# Prepare PATH_SEPARATOR.
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
 
-# Find out how to test for executable files. Don't use a zero-byte file,
-# as systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
-  ac_executable_p="test -x"
-else
-  ac_executable_p="test -f"
-fi
-rm -f conf$$.file
 
-# Extract the first word of "msgmerge", so it can be a program name with args.
-set dummy msgmerge; 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_MSGMERGE+set}" = set; then :
-  $as_echo_n "(cached) " >&6
-else
-  case "$MSGMERGE" in
-  [\\/]* | ?:[\\/]*)
-    ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path.
-    ;;
-  *)
-    ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
-    for ac_dir in $PATH; do
-      IFS="$ac_save_IFS"
-      test -z "$ac_dir" && ac_dir=.
-      for ac_exec_ext in '' $ac_executable_extensions; do
-        if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
-          echo "$as_me: trying $ac_dir/$ac_word..." >&5
-          if $ac_dir/$ac_word --update -q /dev/null /dev/null >&5 2>&1; then
-            ac_cv_path_MSGMERGE="$ac_dir/$ac_word$ac_exec_ext"
-            break 2
-          fi
-        fi
-      done
-    done
-    IFS="$ac_save_IFS"
-  test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":"
-    ;;
-esac
-fi
-MSGMERGE="$ac_cv_path_MSGMERGE"
-if test "$MSGMERGE" != ":"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5
-$as_echo "$MSGMERGE" >&6; }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+  withval=$with_sysroot;
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  with_sysroot=no
 fi
 
 
-        test -n "$localedir" || localedir='${datadir}/locale'
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+   as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+   ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
 
 
-    test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS=
 
 
-  ac_config_commands="$ac_config_commands po-directories"
 
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+  enableval=$enable_libtool_lock;
+fi
 
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
 
-      if test "X$prefix" = "XNONE"; then
-    acl_final_prefix="$ac_default_prefix"
-  else
-    acl_final_prefix="$prefix"
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE="32"
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE="64"
+	;;
+    esac
   fi
-  if test "X$exec_prefix" = "XNONE"; then
-    acl_final_exec_prefix='${prefix}'
-  else
-    acl_final_exec_prefix="$exec_prefix"
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
   fi
-  acl_save_prefix="$prefix"
-  prefix="$acl_final_prefix"
-  eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
-  prefix="$acl_save_prefix"
+  rm -rf conftest*
+  ;;
 
-# 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
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_i386"
+	    ;;
+	  ppc64-*linux*|powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  ppc*-*linux*|powerpc*-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
-$as_echo_n "checking build system type... " >&6; }
-if test "${ac_cv_build+set}" = set; then :
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} 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
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
+int
+main ()
+{
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
-$as_echo_n "checking host system type... " >&6; }
-if test "${ac_cv_host+set}" = set; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "x$host_alias" = x; then
-  ac_cv_host=$ac_cv_build
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_cc_needs_belf=yes
 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
+  lt_cv_cc_needs_belf=no
 fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+     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_host" >&5
-$as_echo "$ac_cv_host" >&6; }
-case $ac_cv_host in
-*-*-*) ;;
-*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
 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
-
 
+need_locks="$enable_libtool_lock"
 
-# Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then :
-  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; 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_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  with_gnu_ld=no
-fi
-
-# Prepare PATH_SEPARATOR.
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
+  if test -n "$MANIFEST_TOOL"; then
+  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # 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_MANIFEST_TOOL="${ac_tool_prefix}mt"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
   fi
-  rm -f conf$$.sh
+done
+  done
+IFS=$as_save_IFS
+
 fi
-ac_prog=ld
-if test "$GCC" = yes; then
-  # Check if gcc -print-prog-name=ld gives a path.
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5
-$as_echo_n "checking for ld used by GCC... " >&6; }
-  case $host in
-  *-*-mingw*)
-    # gcc leaves a trailing carriage return which upsets mingw
-    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
-  *)
-    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
-  esac
-  case $ac_prog in
-    # Accept absolute paths.
-    [\\/]* | [A-Za-z]:[\\/]*)
-      re_direlt='/[^/][^/]*/\.\./'
-      # Canonicalize the path of ld
-      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
-      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
-        ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
-      done
-      test -z "$LD" && LD="$ac_prog"
-      ;;
-  "")
-    # If it fails, then pretend we aren't using GCC.
-    ac_prog=ld
-    ;;
-  *)
-    # If it is relative, then search for the first ld in PATH.
-    with_gnu_ld=unknown
-    ;;
-  esac
-elif test "$with_gnu_ld" = yes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
-$as_echo_n "checking for GNU ld... " >&6; }
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
-$as_echo_n "checking for non-GNU ld... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
 fi
-if test "${acl_cv_path_LD+set}" = set; then :
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+  # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; 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_MANIFEST_TOOL+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  if test -z "$LD"; then
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
-  for ac_dir in $PATH; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      acl_cv_path_LD="$ac_dir/$ac_prog"
-      # Check to see if the program is GNU ld.  I'd rather use --version,
-      # but apparently some GNU ld's only accept -v.
-      # Break only if it was the GNU/non-GNU ld that we prefer.
-      case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
-      *GNU* | *'with BFD'*)
-        test "$with_gnu_ld" != no && break ;;
-      *)
-        test "$with_gnu_ld" != yes && break ;;
-      esac
-    fi
-  done
-  IFS="$ac_save_ifs"
+  if test -n "$ac_ct_MANIFEST_TOOL"; then
+  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
 else
-  acl_cv_path_LD="$LD" # 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_MANIFEST_TOOL="mt"
+    $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
+
 fi
 fi
-
-LD="$acl_cv_path_LD"
-if test -n "$LD"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
-$as_echo "$LD" >&6; }
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
-test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
-$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
-if test "${acl_cv_prog_gnu_ld+set}" = set; then :
+
+  if test "x$ac_ct_MANIFEST_TOOL" = x; then
+    MANIFEST_TOOL=":"
+  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
+    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+  fi
+else
+  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
-  acl_cv_prog_gnu_ld=yes ;;
-*)
-  acl_cv_prog_gnu_ld=no ;;
-esac
+  lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&5
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_prog_gnu_ld" >&5
-$as_echo "$acl_cv_prog_gnu_ld" >&6; }
-with_gnu_ld=$acl_cv_prog_gnu_ld
 
 
 
 
-                                                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5
-$as_echo_n "checking for shared library run path origin... " >&6; }
-if test "${acl_cv_rpath+set}" = set; then :
+
+
+  case $host_os in
+    rhapsody* | darwin*)
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; 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_DSYMUTIL+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-
-    CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
-    ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
-    . ./conftest.sh
-    rm -f ./conftest.sh
-    acl_cv_rpath=done
+  if test -n "$DSYMUTIL"; then
+  ac_cv_prog_DSYMUTIL="$DSYMUTIL" # 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_DSYMUTIL="${ac_tool_prefix}dsymutil"
+    $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
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5
-$as_echo "$acl_cv_rpath" >&6; }
-  wl="$acl_cv_wl"
-  acl_libext="$acl_cv_libext"
-  acl_shlibext="$acl_cv_shlibext"
-  acl_libname_spec="$acl_cv_libname_spec"
-  acl_library_names_spec="$acl_cv_library_names_spec"
-  acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
-  acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
-  acl_hardcode_direct="$acl_cv_hardcode_direct"
-  acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
-    # Check whether --enable-rpath was given.
-if test "${enable_rpath+set}" = set; then :
-  enableval=$enable_rpath; :
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
 else
-  enable_rpath=yes
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 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 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 test "${ac_cv_prog_CPP+set}" = set; then :
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+  ac_ct_DSYMUTIL=$DSYMUTIL
+  # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; 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_DSYMUTIL+:} false; then :
   $as_echo_n "(cached) " >&6
 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
+  if test -n "$ac_ct_DSYMUTIL"; then
+  ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
 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 :
+  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_DSYMUTIL="dsymutil"
+    $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
 
-else
-  # Broken: fails on valid input.
-continue
 fi
-rm -f conftest.err 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
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
 else
-  # Passes both tests.
-ac_preproc_ok=:
-break
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
-rm -f conftest.err conftest.$ac_ext
 
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-  break
+  if test "x$ac_ct_DSYMUTIL" = x; then
+    DSYMUTIL=":"
+  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
+    DSYMUTIL=$ac_ct_DSYMUTIL
+  fi
+else
+  DSYMUTIL="$ac_cv_prog_DSYMUTIL"
 fi
 
-    done
-    ac_cv_prog_CPP=$CPP
-
-fi
-  CPP=$ac_cv_prog_CPP
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; 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_NMEDIT+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  ac_cv_prog_CPP=$CPP
-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
+  if test -n "$NMEDIT"; then
+  ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
 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 :
+  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_NMEDIT="${ac_tool_prefix}nmedit"
+    $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
 
-else
-  # Broken: fails on valid input.
-continue
 fi
-rm -f conftest.err 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
-else
-  # Passes both tests.
-ac_preproc_ok=:
-break
 fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
 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; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 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 for grep that handles long lines and -e" >&5
-$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then :
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+  ac_ct_NMEDIT=$NMEDIT
+  # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; 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_NMEDIT+:} false; then :
   $as_echo_n "(cached) " >&6
 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
+  if test -n "$ac_ct_NMEDIT"; then
+  ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # 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_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
+  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_NMEDIT="nmedit"
+    $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
-  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
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
 else
-  ac_cv_path_GREP=$GREP
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
+  if test "x$ac_ct_NMEDIT" = x; then
+    NMEDIT=":"
+  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
+    NMEDIT=$ac_ct_NMEDIT
+  fi
+else
+  NMEDIT="$ac_cv_prog_NMEDIT"
 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 test "${ac_cv_path_EGREP+set}" = set; then :
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; 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_LIPO+:} 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
+  if test -n "$LIPO"; then
+  ac_cv_prog_LIPO="$LIPO" # 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_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;;
-esac
-
-      $ac_path_EGREP_found && break 3
-    done
-  done
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+    $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
-  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
-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"
-
-
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
 
-  acl_libdirstem=lib
-  acl_libdirstem2=
-  case "$host_os" in
-    solaris*)
-                                    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit host" >&5
-$as_echo_n "checking for 64-bit host... " >&6; }
-if test "${gl_cv_solaris_64bit+set}" = set; then :
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+  ac_ct_LIPO=$LIPO
+  # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; 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_LIPO+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-#ifdef _LP64
-sixtyfour bits
-#endif
+  if test -n "$ac_ct_LIPO"; then
+  ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # 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_ac_ct_LIPO="lipo"
+    $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
 
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "sixtyfour bits" >/dev/null 2>&1; then :
-  gl_cv_solaris_64bit=yes
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
 else
-  gl_cv_solaris_64bit=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
-rm -f conftest*
 
+  if test "x$ac_ct_LIPO" = x; then
+    LIPO=":"
+  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
+    LIPO=$ac_ct_LIPO
+  fi
+else
+  LIPO="$ac_cv_prog_LIPO"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; 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_OTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL"; then
+  ac_cv_prog_OTOOL="$OTOOL" # 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_OTOOL="${ac_tool_prefix}otool"
+    $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
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+  ac_ct_OTOOL=$OTOOL
+  # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; 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_OTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL"; then
+  ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # 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_ac_ct_OTOOL="otool"
+    $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
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL" = x; then
+    OTOOL=":"
+  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
+    OTOOL=$ac_ct_OTOOL
+  fi
+else
+  OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; 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_OTOOL64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL64"; then
+  ac_cv_prog_OTOOL64="$OTOOL64" # 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_OTOOL64="${ac_tool_prefix}otool64"
+    $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
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_solaris_64bit" >&5
-$as_echo "$gl_cv_solaris_64bit" >&6; }
-      if test $gl_cv_solaris_64bit = yes; then
-        acl_libdirstem=lib/64
-        case "$host_cpu" in
-          sparc*)        acl_libdirstem2=lib/sparcv9 ;;
-          i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
-        esac
-      fi
-      ;;
-    *)
-      searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
-      if test -n "$searchpath"; then
-        acl_save_IFS="${IFS= 	}"; IFS=":"
-        for searchdir in $searchpath; do
-          if test -d "$searchdir"; then
-            case "$searchdir" in
-              */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
-              */../ | */.. )
-                # Better ignore directories of this form. They are misleading.
-                ;;
-              *) searchdir=`cd "$searchdir" && pwd`
-                 case "$searchdir" in
-                   */lib64 ) acl_libdirstem=lib64 ;;
-                 esac ;;
-            esac
-          fi
-        done
-        IFS="$acl_save_IFS"
-      fi
-      ;;
-  esac
-  test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
-
 
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+  ac_ct_OTOOL64=$OTOOL64
+  # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; 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_OTOOL64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL64"; then
+  ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # 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_ac_ct_OTOOL64="otool64"
+    $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
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
+  if test "x$ac_ct_OTOOL64" = x; then
+    OTOOL64=":"
+  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
+    OTOOL64=$ac_ct_OTOOL64
+  fi
+else
+  OTOOL64="$ac_cv_prog_OTOOL64"
+fi
 
 
 
@@ -5408,60 +7200,6564 @@ $as_echo "$gl_cv_solaris_64bit" >&6; }
 
 
 
-    use_additional=yes
 
-  acl_save_prefix="$prefix"
-  prefix="$acl_final_prefix"
-  acl_save_exec_prefix="$exec_prefix"
-  exec_prefix="$acl_final_exec_prefix"
 
-    eval additional_includedir=\"$includedir\"
-    eval additional_libdir=\"$libdir\"
 
-  exec_prefix="$acl_save_exec_prefix"
-  prefix="$acl_save_prefix"
 
 
-# Check whether --with-libiconv-prefix was given.
-if test "${with_libiconv_prefix+set}" = set; then :
-  withval=$with_libiconv_prefix;
-    if test "X$withval" = "Xno"; then
-      use_additional=no
-    else
-      if test "X$withval" = "X"; then
 
-  acl_save_prefix="$prefix"
-  prefix="$acl_final_prefix"
-  acl_save_exec_prefix="$exec_prefix"
-  exec_prefix="$acl_final_exec_prefix"
 
-          eval additional_includedir=\"$includedir\"
-          eval additional_libdir=\"$libdir\"
 
-  exec_prefix="$acl_save_exec_prefix"
-  prefix="$acl_save_prefix"
 
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	# If there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&5
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&5
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_ld_exported_symbols_list=yes
+else
+  lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+      echo "$AR cru libconftest.a conftest.o" >&5
+      $AR cru libconftest.a conftest.o 2>&5
+      echo "$RANLIB libconftest.a" >&5
+      $RANLIB libconftest.a 2>&5
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&5
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+	lt_cv_ld_force_load=yes
       else
-        additional_includedir="$withval/include"
-        additional_libdir="$withval/$acl_libdirstem"
-        if test "$acl_libdirstem2" != "$acl_libdirstem" \
-           && ! test -d "$withval/$acl_libdirstem"; then
-          additional_libdir="$withval/$acl_libdirstem2"
-        fi
+	cat conftest.err >&5
       fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+    case $host_os in
+    rhapsody* | darwin1.[012])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[012]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
     fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
 
+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
+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 :
+
+else
+  # Broken: fails on valid input.
+continue
+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
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+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
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+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 :
+
+else
+  # Broken: fails on valid input.
+continue
+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
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+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 :
+
+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; }
+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 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>
+
+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 :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+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 :
+
+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 :
+  :
+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
+
+#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 :
+
+else
+  ac_cv_header_stdc=no
+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
+
+
+for ac_header in dlfcn.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+  enable_win32_dll=no
+
+
+            # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+  enableval=$enable_shared; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+  withval=$with_pic; lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+	IFS="$lt_save_ifs"
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+  # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+  enableval=$enable_fast_install; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool at gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool at gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+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
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  case $cc_basename in
+  nvcc*)
+    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+  *)
+    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+  esac
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+
+
+
+
+
+  lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl='-Wl,'
+    lt_prog_compiler_static='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static=
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+    esac
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      lt_prog_compiler_wl='-Xlinker '
+      if test -n "$lt_prog_compiler_pic"; then
+        lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+      fi
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      else
+	lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-KPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='--shared'
+	lt_prog_compiler_static='--static'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	lt_prog_compiler_wl='-Wl,-Wl,,'
+	lt_prog_compiler_pic='-PIC'
+	lt_prog_compiler_static='-Bstatic'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fpic'
+	lt_prog_compiler_static='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static='-non_shared'
+        ;;
+      xl* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-qpic'
+	lt_prog_compiler_static='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+        *Intel*\ [CF]*Compiler*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fPIC'
+	  lt_prog_compiler_static='-static'
+	  ;;
+	*Portland\ Group*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fpic'
+	  lt_prog_compiler_static='-Bstatic'
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    rdos*)
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+	lt_prog_compiler_wl='-Qoption ld ';;
+      *)
+	lt_prog_compiler_wl='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl='-Qoption ld '
+      lt_prog_compiler_pic='-PIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_prog_compiler_pic='-Kconform_pic'
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_can_build_shared=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic='-pic'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared=no
+      ;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic=
+    ;;
+  *)
+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+    ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+    case $lt_prog_compiler_pic in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+     esac
+else
+    lt_prog_compiler_pic=
+     lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+    :
+else
+    lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  runpath_var=
+  allow_undefined_flag=
+  always_export_symbols=no
+  archive_cmds=
+  archive_expsym_cmds=
+  compiler_needs_object=no
+  enable_shared_with_static_runtimes=no
+  export_dynamic_flag_spec=
+  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  hardcode_automatic=no
+  hardcode_direct=no
+  hardcode_direct_absolute=no
+  hardcode_libdir_flag_spec=
+  hardcode_libdir_separator=
+  hardcode_minus_L=no
+  hardcode_shlibpath_var=unsupported
+  inherit_rpath=no
+  link_all_deplibs=unknown
+  module_cmds=
+  module_expsym_cmds=
+  old_archive_from_new_cmds=
+  old_archive_from_expsyms_cmds=
+  thread_safe_flag_spec=
+  whole_archive_flag_spec=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    link_all_deplibs=no
+    ;;
+  esac
+
+  ld_shlibs=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+	  *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      whole_archive_flag_spec=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[3-9]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag=unsupported
+	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      export_dynamic_flag_spec='${wl}--export-all-symbols'
+      allow_undefined_flag=unsupported
+      always_export_symbols=no
+      enable_shared_with_static_runtimes=yes
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    haiku*)
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      link_all_deplibs=yes
+      ;;
+
+    interix[3-9]*)
+      hardcode_direct=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=' $pic_flag'
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  whole_archive_flag_spec=
+	  tmp_sharedflag='--shared' ;;
+	xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf* | bgf* | bgxlf* | mpixlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+	  hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    ld_shlibs=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs" = no; then
+      runpath_var=
+      hardcode_libdir_flag_spec=
+      export_dynamic_flag_spec=
+      whole_archive_flag_spec=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag=unsupported
+      always_export_symbols=yes
+      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct=unsupported
+      fi
+      ;;
+
+    aix[4-9]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds=''
+      hardcode_direct=yes
+      hardcode_direct_absolute=yes
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      file_list_spec='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[012]|aix4.[012].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  hardcode_direct=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  hardcode_minus_L=yes
+	  hardcode_libdir_flag_spec='-L$libdir'
+	  hardcode_libdir_separator=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+	link_all_deplibs=no
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      export_dynamic_flag_spec='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+fi
+
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag="-z nodefs"
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+fi
+
+	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag=' ${wl}-bernotok'
+	  allow_undefined_flag=' ${wl}-berok'
+	  if test "$with_gnu_ld" = yes; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    whole_archive_flag_spec='$convenience'
+	  fi
+	  archive_cmds_need_lc=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	always_export_symbols=yes
+	file_list_spec='@'
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+	enable_shared_with_static_runtimes=yes
+	exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	old_postinstall_cmds='chmod 644 $oldlib'
+	postlink_cmds='lt_outputfile="@OUTPUT@"~
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+	# The linker will automatically build a .lib file if we build a DLL.
+	old_archive_from_new_cmds='true'
+	# FIXME: Should let the user specify the lib program.
+	old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+	enable_shared_with_static_runtimes=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec=''
+  fi
+  link_all_deplibs=yes
+  allow_undefined_flag="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=func_echo_all
+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+  else
+  ld_shlibs=no
+  fi
+
+      ;;
+
+    dgux*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2.*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      export_dynamic_flag_spec='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator=:
+	hardcode_direct=yes
+	hardcode_direct_absolute=yes
+	export_dynamic_flag_spec='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler__b=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS -b"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler__b=yes
+       fi
+     else
+       lt_cv_prog_compiler__b=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+    archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+    archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  hardcode_direct=no
+	  hardcode_shlibpath_var=no
+	  ;;
+	*)
+	  hardcode_direct=yes
+	  hardcode_direct_absolute=yes
+	  export_dynamic_flag_spec='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+	# This should be the same for all languages, so no per-tag cache variable.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_irix_exported_symbol=yes
+else
+  lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+           LDFLAGS="$save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+	fi
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      inherit_rpath=yes
+      link_all_deplibs=yes
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    newsos6)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_shlibpath_var=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	hardcode_direct=yes
+	hardcode_shlibpath_var=no
+	hardcode_direct_absolute=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	  export_dynamic_flag_spec='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	     archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     hardcode_libdir_flag_spec='-R$libdir'
+	     ;;
+	   *)
+	     archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_separator=:
+      ;;
+
+    solaris*)
+      no_undefined_flag=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_shlibpath_var=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      link_all_deplibs=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds='$CC -r -o $output$reload_objs'
+	  hardcode_direct=no
+        ;;
+	motorola)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag='${wl}-z,text'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag='${wl}-z,text'
+      allow_undefined_flag='${wl}-z,nodefs'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-R,$libdir'
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      export_dynamic_flag_spec='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      ld_shlibs=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	export_dynamic_flag_spec='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$lt_prog_compiler_wl
+	  pic_flag=$lt_prog_compiler_pic
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$allow_undefined_flag
+	  allow_undefined_flag=
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	  then
+	    lt_cv_archive_cmds_need_lc=no
+	  else
+	    lt_cv_archive_cmds_need_lc=yes
+	  fi
+	  allow_undefined_flag=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[lt_foo]++; }
+  if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2.*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux # correct to gnu/linux during the next big refactor
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux # correct to gnu/linux during the next big refactor
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+   test -n "$runpath_var" ||
+   test "X$hardcode_automatic" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+   test "$inherit_rpath" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+  if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $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 dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=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_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+    ;;
+
+  *)
+    ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+  lt_cv_dlopen="shl_load"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $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 shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_shl_load=yes
+else
+  ac_cv_lib_dld_shl_load=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_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+  ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $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 dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=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_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $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 dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_svld_dlopen=yes
+else
+  ac_cv_lib_svld_dlopen=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_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $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 dld_link ();
+int
+main ()
+{
+return dld_link ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_dld_link=yes
+else
+  ac_cv_lib_dld_dld_link=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_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&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: no" >&5
+$as_echo "no" >&6; }
+    ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+  # Report which library types will actually be built
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[4-9]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+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
+
+CC="$lt_save_CC"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+        ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+#LT_INIT([disable-static])
+
+# I18N
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5
+$as_echo_n "checking whether NLS is requested... " >&6; }
+    # Check whether --enable-nls was given.
+if test "${enable_nls+set}" = set; then :
+  enableval=$enable_nls; USE_NLS=$enableval
+else
+  USE_NLS=yes
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5
+$as_echo "$USE_NLS" >&6; }
+
+
+
+
+case "$am__api_version" in
+    1.01234)
+	as_fn_error $? "Automake 1.5 or newer is required to use intltool" "$LINENO" 5
+    ;;
+    *)
+    ;;
+esac
+
+if test -n "0.25"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for intltool >= 0.25" >&5
+$as_echo_n "checking for intltool >= 0.25... " >&6; }
+
+    INTLTOOL_REQUIRED_VERSION_AS_INT=`echo 0.25 | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'`
+    INTLTOOL_APPLIED_VERSION=`intltool-update --version | head -1 | cut -d" " -f3`
+    INTLTOOL_APPLIED_VERSION_AS_INT=`echo $INTLTOOL_APPLIED_VERSION | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'`
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_APPLIED_VERSION found" >&5
+$as_echo "$INTLTOOL_APPLIED_VERSION found" >&6; }
+    test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT" ||
+	as_fn_error $? "Your intltool is too old.  You need intltool 0.25 or later." "$LINENO" 5
+fi
+
+# Extract the first word of "intltool-update", so it can be a program name with args.
+set dummy intltool-update; 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_INTLTOOL_UPDATE+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $INTLTOOL_UPDATE in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_INTLTOOL_UPDATE="$INTLTOOL_UPDATE" # 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_INTLTOOL_UPDATE="$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
+INTLTOOL_UPDATE=$ac_cv_path_INTLTOOL_UPDATE
+if test -n "$INTLTOOL_UPDATE"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_UPDATE" >&5
+$as_echo "$INTLTOOL_UPDATE" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "intltool-merge", so it can be a program name with args.
+set dummy intltool-merge; 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_INTLTOOL_MERGE+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $INTLTOOL_MERGE in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_INTLTOOL_MERGE="$INTLTOOL_MERGE" # 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_INTLTOOL_MERGE="$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
+INTLTOOL_MERGE=$ac_cv_path_INTLTOOL_MERGE
+if test -n "$INTLTOOL_MERGE"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_MERGE" >&5
+$as_echo "$INTLTOOL_MERGE" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "intltool-extract", so it can be a program name with args.
+set dummy intltool-extract; 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_INTLTOOL_EXTRACT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $INTLTOOL_EXTRACT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_INTLTOOL_EXTRACT="$INTLTOOL_EXTRACT" # 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_INTLTOOL_EXTRACT="$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
+INTLTOOL_EXTRACT=$ac_cv_path_INTLTOOL_EXTRACT
+if test -n "$INTLTOOL_EXTRACT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_EXTRACT" >&5
+$as_echo "$INTLTOOL_EXTRACT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test -z "$INTLTOOL_UPDATE" -o -z "$INTLTOOL_MERGE" -o -z "$INTLTOOL_EXTRACT"; then
+    as_fn_error $? "The intltool scripts were not found. Please install intltool." "$LINENO" 5
+fi
+
+  INTLTOOL_DESKTOP_RULE='%.desktop:   %.desktop.in   $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+     INTLTOOL_KEYS_RULE='%.keys:      %.keys.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+     INTLTOOL_PROP_RULE='%.prop:      %.prop.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+      INTLTOOL_OAF_RULE='%.oaf:       %.oaf.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -p $(top_srcdir)/po $< $@'
+     INTLTOOL_PONG_RULE='%.pong:      %.pong.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+   INTLTOOL_SERVER_RULE='%.server:    %.server.in    $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+    INTLTOOL_SHEET_RULE='%.sheet:     %.sheet.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+       INTLTOOL_UI_RULE='%.ui:        %.ui.in        $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+      INTLTOOL_XML_RULE='%.xml:       %.xml.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+      INTLTOOL_XML_NOMERGE_RULE='%.xml:       %.xml.in       $(INTLTOOL_MERGE) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< $@'
+      INTLTOOL_XAM_RULE='%.xam:       %.xml.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+      INTLTOOL_KBD_RULE='%.kbd:       %.kbd.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+    INTLTOOL_CAVES_RULE='%.caves:     %.caves.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+  INTLTOOL_SCHEMAS_RULE='%.schemas:   %.schemas.in   $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+    INTLTOOL_THEME_RULE='%.theme:     %.theme.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+    INTLTOOL_SERVICE_RULE='%.service: %.service.in   $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+   INTLTOOL_POLICY_RULE='%.policy:    %.policy.in    $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check the gettext tools to make sure they are GNU
+# Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; 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_XGETTEXT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $XGETTEXT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_XGETTEXT="$XGETTEXT" # 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_XGETTEXT="$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
+XGETTEXT=$ac_cv_path_XGETTEXT
+if test -n "$XGETTEXT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5
+$as_echo "$XGETTEXT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "msgmerge", so it can be a program name with args.
+set dummy msgmerge; 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_MSGMERGE+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MSGMERGE in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_MSGMERGE="$MSGMERGE" # 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_MSGMERGE="$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
+MSGMERGE=$ac_cv_path_MSGMERGE
+if test -n "$MSGMERGE"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5
+$as_echo "$MSGMERGE" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; 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_MSGFMT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MSGFMT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_MSGFMT="$MSGFMT" # 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_MSGFMT="$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
+MSGFMT=$ac_cv_path_MSGFMT
+if test -n "$MSGFMT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5
+$as_echo "$MSGFMT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; 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_GMSGFMT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $GMSGFMT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GMSGFMT="$GMSGFMT" # 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_GMSGFMT="$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
+
+  test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+  ;;
+esac
+fi
+GMSGFMT=$ac_cv_path_GMSGFMT
+if test -n "$GMSGFMT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5
+$as_echo "$GMSGFMT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test -z "$XGETTEXT" -o -z "$MSGMERGE" -o -z "$MSGFMT"; then
+    as_fn_error $? "GNU gettext tools not found; required for intltool" "$LINENO" 5
+fi
+xgversion="`$XGETTEXT --version|grep '(GNU ' 2> /dev/null`"
+mmversion="`$MSGMERGE --version|grep '(GNU ' 2> /dev/null`"
+mfversion="`$MSGFMT --version|grep '(GNU ' 2> /dev/null`"
+if test -z "$xgversion" -o -z "$mmversion" -o -z "$mfversion"; then
+    as_fn_error $? "GNU gettext tools not found; required for intltool" "$LINENO" 5
+fi
+
+# Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; 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_INTLTOOL_PERL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $INTLTOOL_PERL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_INTLTOOL_PERL="$INTLTOOL_PERL" # 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_INTLTOOL_PERL="$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
+INTLTOOL_PERL=$ac_cv_path_INTLTOOL_PERL
+if test -n "$INTLTOOL_PERL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_PERL" >&5
+$as_echo "$INTLTOOL_PERL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test -z "$INTLTOOL_PERL"; then
+   as_fn_error $? "perl not found" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for perl >= 5.8.1" >&5
+$as_echo_n "checking for perl >= 5.8.1... " >&6; }
+$INTLTOOL_PERL -e "use 5.8.1;" > /dev/null 2>&1
+if test $? -ne 0; then
+   as_fn_error $? "perl 5.8.1 is required for intltool" "$LINENO" 5
+else
+   IT_PERL_VERSION="`$INTLTOOL_PERL -e \"printf '%vd', $^V\"`"
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IT_PERL_VERSION" >&5
+$as_echo "$IT_PERL_VERSION" >&6; }
+fi
+if test "x" != "xno-xml"; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML::Parser" >&5
+$as_echo_n "checking for XML::Parser... " >&6; }
+   if `$INTLTOOL_PERL -e "require XML::Parser" 2>/dev/null`; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+   else
+       as_fn_error $? "XML::Parser perl module is required for intltool" "$LINENO" 5
+   fi
+fi
+
+# Substitute ALL_LINGUAS so we can use it in po/Makefile
+
+
+# Set DATADIRNAME correctly if it is not set yet
+# (copied from glib-gettext.m4)
+if test -z "$DATADIRNAME"; then
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+extern int _nl_msg_cat_cntr;
+                       return _nl_msg_cat_cntr
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  DATADIRNAME=share
+else
+  case $host in
+    *-*-solaris*)
+                        ac_fn_c_check_func "$LINENO" "bind_textdomain_codeset" "ac_cv_func_bind_textdomain_codeset"
+if test "x$ac_cv_func_bind_textdomain_codeset" = xyes; then :
+  DATADIRNAME=share
+else
+  DATADIRNAME=lib
+fi
+
+    ;;
+    *)
+    DATADIRNAME=lib
+    ;;
+    esac
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+
+
+
+
+POSUB="
+	po
+	po-Engine
+	po-Engine-IRC
+	po-Engine-XMPP
+	po-Engine-OSCAR
+	po-Engine-MSNP
+	po-Server
+	po-Frontend
+	po-Frontend-GNOME
+	po-Frontend-GNOME-IRC
+	po-Frontend-GNOME-XMPP
+	po-Frontend-SWF
+"
+
+GETTEXT_PACKAGE=smuxi
+
+
+GETTEXT_PACKAGE_ENGINE=smuxi-engine
+
+
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE_ENGINE "$GETTEXT_PACKAGE_ENGINE"
+_ACEOF
+
+
+GETTEXT_PACKAGE_ENGINE_IRC=smuxi-engine-irc
+
+
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE_ENGINE_IRC "$GETTEXT_PACKAGE_ENGINE_IRC"
+_ACEOF
+
+
+GETTEXT_PACKAGE_ENGINE_XMPP=smuxi-engine-xmpp
+
+
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE_ENGINE_XMPP "$GETTEXT_PACKAGE_ENGINE_XMPP"
+_ACEOF
+
+
+GETTEXT_PACKAGE_ENGINE_OSCAR=smuxi-engine-oscar
+
+
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE_ENGINE_OSCAR "$GETTEXT_PACKAGE_ENGINE_OSCAR"
+_ACEOF
+
+
+GETTEXT_PACKAGE_ENGINE_MSNP=smuxi-engine-msnp
+
+
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE_ENGINE_MSNP "$GETTEXT_PACKAGE_ENGINE_MSNP"
+_ACEOF
+
+
+GETTEXT_PACKAGE_ENGINE_TWITTER=smuxi-engine-twitter
+
+
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE_ENGINE_TWITTER "$GETTEXT_PACKAGE_ENGINE_TWITTER"
+_ACEOF
+
+
+GETTEXT_PACKAGE_SERVER=smuxi-server
+
+
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE_SERVER "$GETTEXT_PACKAGE_SERVER"
+_ACEOF
+
+
+GETTEXT_PACKAGE_FRONTEND=smuxi-frontend
+
+
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE_FRONTEND "$GETTEXT_PACKAGE_FRONTEND"
+_ACEOF
+
+
+GETTEXT_PACKAGE_FRONTEND_GNOME=smuxi-frontend-gnome
+
+
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE_FRONTEND_GNOME "$GETTEXT_PACKAGE_FRONTEND_GNOME"
+_ACEOF
+
+
+GETTEXT_PACKAGE_FRONTEND_GNOME_IRC=smuxi-frontend-gnome-irc
+
+
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE_FRONTEND_GNOME_IRC "$GETTEXT_PACKAGE_FRONTEND_GNOME_IRC"
+_ACEOF
+
+
+GETTEXT_PACKAGE_FRONTEND_GNOME_XMPP=smuxi-frontend-gnome-xmpp
+
+
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE_FRONTEND_GNOME_XMPP "$GETTEXT_PACKAGE_FRONTEND_GNOME_XMPP"
+_ACEOF
+
+
+GETTEXT_PACKAGE_FRONTEND_STFL=smuxi-frontend-stfl
+
+
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE_FRONTEND_STFL "$GETTEXT_PACKAGE_FRONTEND_STFL"
+_ACEOF
+
+
+GETTEXT_PACKAGE_FRONTEND_CURSES=smuxi-frontend-curses
+
+
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE_FRONTEND_CURSES "$GETTEXT_PACKAGE_FRONTEND_CURSES"
+_ACEOF
+
+
+GETTEXT_PACKAGE_FRONTEND_SWF=smuxi-frontend-swf
+
+
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE_FRONTEND_SWF "$GETTEXT_PACKAGE_FRONTEND_SWF"
+_ACEOF
+
+
+GETTEXT_PACKAGE_FRONTEND_WPF=smuxi-frontend-wpf
+
+
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE_FRONTEND_WPF "$GETTEXT_PACKAGE_FRONTEND_WPF"
+_ACEOF
+
+
+
+
+      GETTEXT_MACRO_VERSION=0.18
+
+
+
+
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+# Find out how to test for executable files. Don't use a zero-byte file,
+# as systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+  ac_executable_p="test -x"
+else
+  ac_executable_p="test -f"
+fi
+rm -f conf$$.file
+
+# Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; 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_MSGFMT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case "$MSGFMT" in
+  [\\/]* | ?:[\\/]*)
+    ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+    ;;
+  *)
+    ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH; do
+      IFS="$ac_save_IFS"
+      test -z "$ac_dir" && ac_dir=.
+      for ac_exec_ext in '' $ac_executable_extensions; do
+        if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
+          echo "$as_me: trying $ac_dir/$ac_word..." >&5
+          if $ac_dir/$ac_word --statistics /dev/null >&5 2>&1 &&
+     (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then
+            ac_cv_path_MSGFMT="$ac_dir/$ac_word$ac_exec_ext"
+            break 2
+          fi
+        fi
+      done
+    done
+    IFS="$ac_save_IFS"
+  test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":"
+    ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test "$MSGFMT" != ":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5
+$as_echo "$MSGFMT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; 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_GMSGFMT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $GMSGFMT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GMSGFMT="$GMSGFMT" # 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_GMSGFMT="$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
+
+  test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+  ;;
+esac
+fi
+GMSGFMT=$ac_cv_path_GMSGFMT
+if test -n "$GMSGFMT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5
+$as_echo "$GMSGFMT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+    case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;;
+    *) MSGFMT_015=$MSGFMT ;;
+  esac
+
+  case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;;
+    *) GMSGFMT_015=$GMSGFMT ;;
+  esac
+
+
+
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+# Find out how to test for executable files. Don't use a zero-byte file,
+# as systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+  ac_executable_p="test -x"
+else
+  ac_executable_p="test -f"
+fi
+rm -f conf$$.file
+
+# Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; 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_XGETTEXT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case "$XGETTEXT" in
+  [\\/]* | ?:[\\/]*)
+    ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+    ;;
+  *)
+    ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH; do
+      IFS="$ac_save_IFS"
+      test -z "$ac_dir" && ac_dir=.
+      for ac_exec_ext in '' $ac_executable_extensions; do
+        if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
+          echo "$as_me: trying $ac_dir/$ac_word..." >&5
+          if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&5 2>&1 &&
+     (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then
+            ac_cv_path_XGETTEXT="$ac_dir/$ac_word$ac_exec_ext"
+            break 2
+          fi
+        fi
+      done
+    done
+    IFS="$ac_save_IFS"
+  test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+    ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test "$XGETTEXT" != ":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5
+$as_echo "$XGETTEXT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+    rm -f messages.po
+
+    case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;;
+    *) XGETTEXT_015=$XGETTEXT ;;
+  esac
+
+
+
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+# Find out how to test for executable files. Don't use a zero-byte file,
+# as systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+  ac_executable_p="test -x"
+else
+  ac_executable_p="test -f"
+fi
+rm -f conf$$.file
+
+# Extract the first word of "msgmerge", so it can be a program name with args.
+set dummy msgmerge; 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_MSGMERGE+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case "$MSGMERGE" in
+  [\\/]* | ?:[\\/]*)
+    ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path.
+    ;;
+  *)
+    ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH; do
+      IFS="$ac_save_IFS"
+      test -z "$ac_dir" && ac_dir=.
+      for ac_exec_ext in '' $ac_executable_extensions; do
+        if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
+          echo "$as_me: trying $ac_dir/$ac_word..." >&5
+          if $ac_dir/$ac_word --update -q /dev/null /dev/null >&5 2>&1; then
+            ac_cv_path_MSGMERGE="$ac_dir/$ac_word$ac_exec_ext"
+            break 2
+          fi
+        fi
+      done
+    done
+    IFS="$ac_save_IFS"
+  test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":"
+    ;;
+esac
+fi
+MSGMERGE="$ac_cv_path_MSGMERGE"
+if test "$MSGMERGE" != ":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5
+$as_echo "$MSGMERGE" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+        test -n "$localedir" || localedir='${datadir}/locale'
+
+
+    test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS=
+
+
+  ac_config_commands="$ac_config_commands po-directories"
+
+
+
+      if test "X$prefix" = "XNONE"; then
+    acl_final_prefix="$ac_default_prefix"
+  else
+    acl_final_prefix="$prefix"
+  fi
+  if test "X$exec_prefix" = "XNONE"; then
+    acl_final_exec_prefix='${prefix}'
+  else
+    acl_final_exec_prefix="$exec_prefix"
+  fi
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
+  prefix="$acl_save_prefix"
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5
+$as_echo_n "checking for ld used by GCC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+        ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${acl_cv_path_LD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      acl_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
+      *GNU* | *'with BFD'*)
+        test "$with_gnu_ld" != no && break ;;
+      *)
+        test "$with_gnu_ld" != yes && break ;;
+      esac
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  acl_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$acl_cv_path_LD"
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${acl_cv_prog_gnu_ld+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  acl_cv_prog_gnu_ld=yes ;;
+*)
+  acl_cv_prog_gnu_ld=no ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_prog_gnu_ld" >&5
+$as_echo "$acl_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$acl_cv_prog_gnu_ld
+
+
+
+
+                                                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5
+$as_echo_n "checking for shared library run path origin... " >&6; }
+if ${acl_cv_rpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
+    ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
+    . ./conftest.sh
+    rm -f ./conftest.sh
+    acl_cv_rpath=done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5
+$as_echo "$acl_cv_rpath" >&6; }
+  wl="$acl_cv_wl"
+  acl_libext="$acl_cv_libext"
+  acl_shlibext="$acl_cv_shlibext"
+  acl_libname_spec="$acl_cv_libname_spec"
+  acl_library_names_spec="$acl_cv_library_names_spec"
+  acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
+  acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
+  acl_hardcode_direct="$acl_cv_hardcode_direct"
+  acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
+    # Check whether --enable-rpath was given.
+if test "${enable_rpath+set}" = set; then :
+  enableval=$enable_rpath; :
+else
+  enable_rpath=yes
+fi
+
+
+
+
+  acl_libdirstem=lib
+  acl_libdirstem2=
+  case "$host_os" in
+    solaris*)
+                                    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit host" >&5
+$as_echo_n "checking for 64-bit host... " >&6; }
+if ${gl_cv_solaris_64bit+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef _LP64
+sixtyfour bits
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "sixtyfour bits" >/dev/null 2>&1; then :
+  gl_cv_solaris_64bit=yes
+else
+  gl_cv_solaris_64bit=no
+fi
+rm -f conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_solaris_64bit" >&5
+$as_echo "$gl_cv_solaris_64bit" >&6; }
+      if test $gl_cv_solaris_64bit = yes; then
+        acl_libdirstem=lib/64
+        case "$host_cpu" in
+          sparc*)        acl_libdirstem2=lib/sparcv9 ;;
+          i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
+        esac
+      fi
+      ;;
+    *)
+      searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
+      if test -n "$searchpath"; then
+        acl_save_IFS="${IFS= 	}"; IFS=":"
+        for searchdir in $searchpath; do
+          if test -d "$searchdir"; then
+            case "$searchdir" in
+              */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
+              */../ | */.. )
+                # Better ignore directories of this form. They are misleading.
+                ;;
+              *) searchdir=`cd "$searchdir" && pwd`
+                 case "$searchdir" in
+                   */lib64 ) acl_libdirstem=lib64 ;;
+                 esac ;;
+            esac
+          fi
+        done
+        IFS="$acl_save_IFS"
+      fi
+      ;;
+  esac
+  test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
+
+
+
+
+
+
+
+
+
+
+
+
+    use_additional=yes
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+
+    eval additional_includedir=\"$includedir\"
+    eval additional_libdir=\"$libdir\"
+
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+
+# Check whether --with-libiconv-prefix was given.
+if test "${with_libiconv_prefix+set}" = set; then :
+  withval=$with_libiconv_prefix;
+    if test "X$withval" = "Xno"; then
+      use_additional=no
+    else
+      if test "X$withval" = "X"; then
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+
+          eval additional_includedir=\"$includedir\"
+          eval additional_libdir=\"$libdir\"
+
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+      else
+        additional_includedir="$withval/include"
+        additional_libdir="$withval/$acl_libdirstem"
+        if test "$acl_libdirstem2" != "$acl_libdirstem" \
+           && ! test -d "$withval/$acl_libdirstem"; then
+          additional_libdir="$withval/$acl_libdirstem2"
+        fi
+      fi
+    fi
+
+fi
+
+      LIBICONV=
+  LTLIBICONV=
+  INCICONV=
+  LIBICONV_PREFIX=
+      HAVE_LIBICONV=
+  rpathdirs=
+  ltrpathdirs=
+  names_already_handled=
+  names_next_round='iconv '
+  while test -n "$names_next_round"; do
+    names_this_round="$names_next_round"
+    names_next_round=
+    for name in $names_this_round; do
+      already_handled=
+      for n in $names_already_handled; do
+        if test "$n" = "$name"; then
+          already_handled=yes
+          break
+        fi
+      done
+      if test -z "$already_handled"; then
+        names_already_handled="$names_already_handled $name"
+                        uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
+        eval value=\"\$HAVE_LIB$uppername\"
+        if test -n "$value"; then
+          if test "$value" = yes; then
+            eval value=\"\$LIB$uppername\"
+            test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value"
+            eval value=\"\$LTLIB$uppername\"
+            test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value"
+          else
+                                    :
+          fi
+        else
+                              found_dir=
+          found_la=
+          found_so=
+          found_a=
+          eval libname=\"$acl_libname_spec\"    # typically: libname=lib$name
+          if test -n "$acl_shlibext"; then
+            shrext=".$acl_shlibext"             # typically: shrext=.so
+          else
+            shrext=
+          fi
+          if test $use_additional = yes; then
+            dir="$additional_libdir"
+                                    if test -n "$acl_shlibext"; then
+              if test -f "$dir/$libname$shrext"; then
+                found_dir="$dir"
+                found_so="$dir/$libname$shrext"
+              else
+                if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+                  ver=`(cd "$dir" && \
+                        for f in "$libname$shrext".*; do echo "$f"; done \
+                        | sed -e "s,^$libname$shrext\\\\.,," \
+                        | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+                        | sed 1q ) 2>/dev/null`
+                  if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+                    found_dir="$dir"
+                    found_so="$dir/$libname$shrext.$ver"
+                  fi
+                else
+                  eval library_names=\"$acl_library_names_spec\"
+                  for f in $library_names; do
+                    if test -f "$dir/$f"; then
+                      found_dir="$dir"
+                      found_so="$dir/$f"
+                      break
+                    fi
+                  done
+                fi
+              fi
+            fi
+                        if test "X$found_dir" = "X"; then
+              if test -f "$dir/$libname.$acl_libext"; then
+                found_dir="$dir"
+                found_a="$dir/$libname.$acl_libext"
+              fi
+            fi
+            if test "X$found_dir" != "X"; then
+              if test -f "$dir/$libname.la"; then
+                found_la="$dir/$libname.la"
+              fi
+            fi
+          fi
+          if test "X$found_dir" = "X"; then
+            for x in $LDFLAGS $LTLIBICONV; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+              case "$x" in
+                -L*)
+                  dir=`echo "X$x" | sed -e 's/^X-L//'`
+                                    if test -n "$acl_shlibext"; then
+                    if test -f "$dir/$libname$shrext"; then
+                      found_dir="$dir"
+                      found_so="$dir/$libname$shrext"
+                    else
+                      if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+                        ver=`(cd "$dir" && \
+                              for f in "$libname$shrext".*; do echo "$f"; done \
+                              | sed -e "s,^$libname$shrext\\\\.,," \
+                              | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+                              | sed 1q ) 2>/dev/null`
+                        if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+                          found_dir="$dir"
+                          found_so="$dir/$libname$shrext.$ver"
+                        fi
+                      else
+                        eval library_names=\"$acl_library_names_spec\"
+                        for f in $library_names; do
+                          if test -f "$dir/$f"; then
+                            found_dir="$dir"
+                            found_so="$dir/$f"
+                            break
+                          fi
+                        done
+                      fi
+                    fi
+                  fi
+                                    if test "X$found_dir" = "X"; then
+                    if test -f "$dir/$libname.$acl_libext"; then
+                      found_dir="$dir"
+                      found_a="$dir/$libname.$acl_libext"
+                    fi
+                  fi
+                  if test "X$found_dir" != "X"; then
+                    if test -f "$dir/$libname.la"; then
+                      found_la="$dir/$libname.la"
+                    fi
+                  fi
+                  ;;
+              esac
+              if test "X$found_dir" != "X"; then
+                break
+              fi
+            done
+          fi
+          if test "X$found_dir" != "X"; then
+                        LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name"
+            if test "X$found_so" != "X"; then
+                                                        if test "$enable_rpath" = no \
+                 || test "X$found_dir" = "X/usr/$acl_libdirstem" \
+                 || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
+                                LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
+              else
+                                                                                haveit=
+                for x in $ltrpathdirs; do
+                  if test "X$x" = "X$found_dir"; then
+                    haveit=yes
+                    break
+                  fi
+                done
+                if test -z "$haveit"; then
+                  ltrpathdirs="$ltrpathdirs $found_dir"
+                fi
+                                if test "$acl_hardcode_direct" = yes; then
+                                                      LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
+                else
+                  if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
+                                                            LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
+                                                            haveit=
+                    for x in $rpathdirs; do
+                      if test "X$x" = "X$found_dir"; then
+                        haveit=yes
+                        break
+                      fi
+                    done
+                    if test -z "$haveit"; then
+                      rpathdirs="$rpathdirs $found_dir"
+                    fi
+                  else
+                                                                                haveit=
+                    for x in $LDFLAGS $LIBICONV; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+                      if test "X$x" = "X-L$found_dir"; then
+                        haveit=yes
+                        break
+                      fi
+                    done
+                    if test -z "$haveit"; then
+                      LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir"
+                    fi
+                    if test "$acl_hardcode_minus_L" != no; then
+                                                                                        LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
+                    else
+                                                                                                                                                                                LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name"
+                    fi
+                  fi
+                fi
+              fi
+            else
+              if test "X$found_a" != "X"; then
+                                LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a"
+              else
+                                                LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name"
+              fi
+            fi
+                        additional_includedir=
+            case "$found_dir" in
+              */$acl_libdirstem | */$acl_libdirstem/)
+                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
+                if test "$name" = 'iconv'; then
+                  LIBICONV_PREFIX="$basedir"
+                fi
+                additional_includedir="$basedir/include"
+                ;;
+              */$acl_libdirstem2 | */$acl_libdirstem2/)
+                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
+                if test "$name" = 'iconv'; then
+                  LIBICONV_PREFIX="$basedir"
+                fi
+                additional_includedir="$basedir/include"
+                ;;
+            esac
+            if test "X$additional_includedir" != "X"; then
+                                                                                                                if test "X$additional_includedir" != "X/usr/include"; then
+                haveit=
+                if test "X$additional_includedir" = "X/usr/local/include"; then
+                  if test -n "$GCC"; then
+                    case $host_os in
+                      linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+                    esac
+                  fi
+                fi
+                if test -z "$haveit"; then
+                  for x in $CPPFLAGS $INCICONV; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+                    if test "X$x" = "X-I$additional_includedir"; then
+                      haveit=yes
+                      break
+                    fi
+                  done
+                  if test -z "$haveit"; then
+                    if test -d "$additional_includedir"; then
+                                            INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir"
+                    fi
+                  fi
+                fi
+              fi
+            fi
+                        if test -n "$found_la"; then
+                                                        save_libdir="$libdir"
+              case "$found_la" in
+                */* | *\\*) . "$found_la" ;;
+                *) . "./$found_la" ;;
+              esac
+              libdir="$save_libdir"
+                            for dep in $dependency_libs; do
+                case "$dep" in
+                  -L*)
+                    additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
+                                                                                                                                                                if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \
+                       && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
+                      haveit=
+                      if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
+                         || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then
+                        if test -n "$GCC"; then
+                          case $host_os in
+                            linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+                          esac
+                        fi
+                      fi
+                      if test -z "$haveit"; then
+                        haveit=
+                        for x in $LDFLAGS $LIBICONV; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+                          if test "X$x" = "X-L$additional_libdir"; then
+                            haveit=yes
+                            break
+                          fi
+                        done
+                        if test -z "$haveit"; then
+                          if test -d "$additional_libdir"; then
+                                                        LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir"
+                          fi
+                        fi
+                        haveit=
+                        for x in $LDFLAGS $LTLIBICONV; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+                          if test "X$x" = "X-L$additional_libdir"; then
+                            haveit=yes
+                            break
+                          fi
+                        done
+                        if test -z "$haveit"; then
+                          if test -d "$additional_libdir"; then
+                                                        LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir"
+                          fi
+                        fi
+                      fi
+                    fi
+                    ;;
+                  -R*)
+                    dir=`echo "X$dep" | sed -e 's/^X-R//'`
+                    if test "$enable_rpath" != no; then
+                                                                  haveit=
+                      for x in $rpathdirs; do
+                        if test "X$x" = "X$dir"; then
+                          haveit=yes
+                          break
+                        fi
+                      done
+                      if test -z "$haveit"; then
+                        rpathdirs="$rpathdirs $dir"
+                      fi
+                                                                  haveit=
+                      for x in $ltrpathdirs; do
+                        if test "X$x" = "X$dir"; then
+                          haveit=yes
+                          break
+                        fi
+                      done
+                      if test -z "$haveit"; then
+                        ltrpathdirs="$ltrpathdirs $dir"
+                      fi
+                    fi
+                    ;;
+                  -l*)
+                                        names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
+                    ;;
+                  *.la)
+                                                                                names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
+                    ;;
+                  *)
+                                        LIBICONV="${LIBICONV}${LIBICONV:+ }$dep"
+                    LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep"
+                    ;;
+                esac
+              done
+            fi
+          else
+                                                            LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name"
+            LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name"
+          fi
+        fi
+      fi
+    done
+  done
+  if test "X$rpathdirs" != "X"; then
+    if test -n "$acl_hardcode_libdir_separator"; then
+                        alldirs=
+      for found_dir in $rpathdirs; do
+        alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
+      done
+            acl_save_libdir="$libdir"
+      libdir="$alldirs"
+      eval flag=\"$acl_hardcode_libdir_flag_spec\"
+      libdir="$acl_save_libdir"
+      LIBICONV="${LIBICONV}${LIBICONV:+ }$flag"
+    else
+            for found_dir in $rpathdirs; do
+        acl_save_libdir="$libdir"
+        libdir="$found_dir"
+        eval flag=\"$acl_hardcode_libdir_flag_spec\"
+        libdir="$acl_save_libdir"
+        LIBICONV="${LIBICONV}${LIBICONV:+ }$flag"
+      done
+    fi
+  fi
+  if test "X$ltrpathdirs" != "X"; then
+            for found_dir in $ltrpathdirs; do
+      LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir"
+    done
+  fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFPreferencesCopyAppValue" >&5
+$as_echo_n "checking for CFPreferencesCopyAppValue... " >&6; }
+if ${gt_cv_func_CFPreferencesCopyAppValue+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gt_save_LIBS="$LIBS"
+     LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <CoreFoundation/CFPreferences.h>
+int
+main ()
+{
+CFPreferencesCopyAppValue(NULL, NULL)
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  gt_cv_func_CFPreferencesCopyAppValue=yes
+else
+  gt_cv_func_CFPreferencesCopyAppValue=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+     LIBS="$gt_save_LIBS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5
+$as_echo "$gt_cv_func_CFPreferencesCopyAppValue" >&6; }
+  if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then
+
+$as_echo "#define HAVE_CFPREFERENCESCOPYAPPVALUE 1" >>confdefs.h
+
+  fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFLocaleCopyCurrent" >&5
+$as_echo_n "checking for CFLocaleCopyCurrent... " >&6; }
+if ${gt_cv_func_CFLocaleCopyCurrent+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gt_save_LIBS="$LIBS"
+     LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <CoreFoundation/CFLocale.h>
+int
+main ()
+{
+CFLocaleCopyCurrent();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  gt_cv_func_CFLocaleCopyCurrent=yes
+else
+  gt_cv_func_CFLocaleCopyCurrent=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+     LIBS="$gt_save_LIBS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFLocaleCopyCurrent" >&5
+$as_echo "$gt_cv_func_CFLocaleCopyCurrent" >&6; }
+  if test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+
+$as_echo "#define HAVE_CFLOCALECOPYCURRENT 1" >>confdefs.h
+
+  fi
+  INTL_MACOSX_LIBS=
+  if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+    INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation"
+  fi
+
+
+
+
+
+
+  LIBINTL=
+  LTLIBINTL=
+  POSUB=
+
+    case " $gt_needs " in
+    *" need-formatstring-macros "*) gt_api_version=3 ;;
+    *" need-ngettext "*) gt_api_version=2 ;;
+    *) gt_api_version=1 ;;
+  esac
+  gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc"
+  gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl"
+
+    if test "$USE_NLS" = "yes"; then
+    gt_use_preinstalled_gnugettext=no
+
+
+        if test $gt_api_version -ge 3; then
+          gt_revision_test_code='
+#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
+#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
+#endif
+typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
+'
+        else
+          gt_revision_test_code=
+        fi
+        if test $gt_api_version -ge 2; then
+          gt_expression_test_code=' + * ngettext ("", "", 0)'
+        else
+          gt_expression_test_code=
+        fi
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libc" >&5
+$as_echo_n "checking for GNU gettext in libc... " >&6; }
+if eval \${$gt_func_gnugettext_libc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern int *_nl_domain_bindings;
+int
+main ()
+{
+bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$gt_func_gnugettext_libc=yes"
+else
+  eval "$gt_func_gnugettext_libc=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$gt_func_gnugettext_libc
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+        if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
+
+
+
+
+
+          am_save_CPPFLAGS="$CPPFLAGS"
+
+  for element in $INCICONV; do
+    haveit=
+    for x in $CPPFLAGS; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+      if test "X$x" = "X$element"; then
+        haveit=yes
+        break
+      fi
+    done
+    if test -z "$haveit"; then
+      CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element"
+    fi
+  done
+
+
+  { $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 :
+  $as_echo_n "(cached) " >&6
+else
+
+    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 $LIBICONV"
+      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
+
+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 "$as_me:${as_lineno-$LINENO}: checking for working iconv" >&5
+$as_echo_n "checking for working iconv... " >&6; }
+if ${am_cv_func_iconv_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+            am_save_LIBS="$LIBS"
+      if test $am_cv_lib_iconv = yes; then
+        LIBS="$LIBS $LIBICONV"
+      fi
+      if test "$cross_compiling" = yes; then :
+  case "$host_os" in
+           aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
+           *)            am_cv_func_iconv_works="guessing yes" ;;
+         esac
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <iconv.h>
+#include <string.h>
+int main ()
+{
+  /* Test against AIX 5.1 bug: Failures are not distinguishable from successful
+     returns.  */
+  {
+    iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
+    if (cd_utf8_to_88591 != (iconv_t)(-1))
+      {
+        static const char input[] = "\342\202\254"; /* EURO SIGN */
+        char buf[10];
+        const char *inptr = input;
+        size_t inbytesleft = strlen (input);
+        char *outptr = buf;
+        size_t outbytesleft = sizeof (buf);
+        size_t res = iconv (cd_utf8_to_88591,
+                            (char **) &inptr, &inbytesleft,
+                            &outptr, &outbytesleft);
+        if (res == 0)
+          return 1;
+      }
+  }
+  /* Test against Solaris 10 bug: Failures are not distinguishable from
+     successful returns.  */
+  {
+    iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
+    if (cd_ascii_to_88591 != (iconv_t)(-1))
+      {
+        static const char input[] = "\263";
+        char buf[10];
+        const char *inptr = input;
+        size_t inbytesleft = strlen (input);
+        char *outptr = buf;
+        size_t outbytesleft = sizeof (buf);
+        size_t res = iconv (cd_ascii_to_88591,
+                            (char **) &inptr, &inbytesleft,
+                            &outptr, &outbytesleft);
+        if (res == 0)
+          return 1;
+      }
+  }
+#if 0 /* This bug could be worked around by the caller.  */
+  /* Test against HP-UX 11.11 bug: Positive return value instead of 0.  */
+  {
+    iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
+    if (cd_88591_to_utf8 != (iconv_t)(-1))
+      {
+        static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+        char buf[50];
+        const char *inptr = input;
+        size_t inbytesleft = strlen (input);
+        char *outptr = buf;
+        size_t outbytesleft = sizeof (buf);
+        size_t res = iconv (cd_88591_to_utf8,
+                            (char **) &inptr, &inbytesleft,
+                            &outptr, &outbytesleft);
+        if ((int)res > 0)
+          return 1;
+      }
+  }
+#endif
+  /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
+     provided.  */
+  if (/* Try standardized names.  */
+      iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
+      /* Try IRIX, OSF/1 names.  */
+      && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
+      /* Try AIX names.  */
+      && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
+      /* Try HP-UX names.  */
+      && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
+    return 1;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  am_cv_func_iconv_works=yes
+else
+  am_cv_func_iconv_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 
-      LIBICONV=
-  LTLIBICONV=
-  INCICONV=
-  LIBICONV_PREFIX=
-      HAVE_LIBICONV=
+      LIBS="$am_save_LIBS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv_works" >&5
+$as_echo "$am_cv_func_iconv_works" >&6; }
+    case "$am_cv_func_iconv_works" in
+      *no) am_func_iconv=no am_cv_lib_iconv=no ;;
+      *)   am_func_iconv=yes ;;
+    esac
+  else
+    am_func_iconv=no am_cv_lib_iconv=no
+  fi
+  if test "$am_func_iconv" = yes; then
+
+$as_echo "#define HAVE_ICONV 1" >>confdefs.h
+
+  fi
+  if test "$am_cv_lib_iconv" = yes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5
+$as_echo_n "checking how to link with libiconv... " >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5
+$as_echo "$LIBICONV" >&6; }
+  else
+            CPPFLAGS="$am_save_CPPFLAGS"
+    LIBICONV=
+    LTLIBICONV=
+  fi
+
+
+
+
+
+
+
+
+
+
+
+    use_additional=yes
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+
+    eval additional_includedir=\"$includedir\"
+    eval additional_libdir=\"$libdir\"
+
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+
+# Check whether --with-libintl-prefix was given.
+if test "${with_libintl_prefix+set}" = set; then :
+  withval=$with_libintl_prefix;
+    if test "X$withval" = "Xno"; then
+      use_additional=no
+    else
+      if test "X$withval" = "X"; then
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+
+          eval additional_includedir=\"$includedir\"
+          eval additional_libdir=\"$libdir\"
+
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+      else
+        additional_includedir="$withval/include"
+        additional_libdir="$withval/$acl_libdirstem"
+        if test "$acl_libdirstem2" != "$acl_libdirstem" \
+           && ! test -d "$withval/$acl_libdirstem"; then
+          additional_libdir="$withval/$acl_libdirstem2"
+        fi
+      fi
+    fi
+
+fi
+
+      LIBINTL=
+  LTLIBINTL=
+  INCINTL=
+  LIBINTL_PREFIX=
+      HAVE_LIBINTL=
   rpathdirs=
   ltrpathdirs=
   names_already_handled=
-  names_next_round='iconv '
+  names_next_round='intl '
   while test -n "$names_next_round"; do
     names_this_round="$names_next_round"
     names_next_round=
@@ -5480,9 +13776,9 @@ fi
         if test -n "$value"; then
           if test "$value" = yes; then
             eval value=\"\$LIB$uppername\"
-            test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value"
+            test -z "$value" || LIBINTL="${LIBINTL}${LIBINTL:+ }$value"
             eval value=\"\$LTLIB$uppername\"
-            test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value"
+            test -z "$value" || LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$value"
           else
                                     :
           fi
@@ -5539,7 +13835,7 @@ fi
             fi
           fi
           if test "X$found_dir" = "X"; then
-            for x in $LDFLAGS $LTLIBICONV; do
+            for x in $LDFLAGS $LTLIBINTL; do
 
   acl_save_prefix="$prefix"
   prefix="$acl_final_prefix"
@@ -5598,12 +13894,12 @@ fi
             done
           fi
           if test "X$found_dir" != "X"; then
-                        LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name"
+                        LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$found_dir -l$name"
             if test "X$found_so" != "X"; then
                                                         if test "$enable_rpath" = no \
                  || test "X$found_dir" = "X/usr/$acl_libdirstem" \
                  || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
-                                LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
+                                LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so"
               else
                                                                                 haveit=
                 for x in $ltrpathdirs; do
@@ -5616,10 +13912,10 @@ fi
                   ltrpathdirs="$ltrpathdirs $found_dir"
                 fi
                                 if test "$acl_hardcode_direct" = yes; then
-                                                      LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
+                                                      LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so"
                 else
                   if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
-                                                            LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
+                                                            LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so"
                                                             haveit=
                     for x in $rpathdirs; do
                       if test "X$x" = "X$found_dir"; then
@@ -5632,7 +13928,7 @@ fi
                     fi
                   else
                                                                                 haveit=
-                    for x in $LDFLAGS $LIBICONV; do
+                    for x in $LDFLAGS $LIBINTL; do
 
   acl_save_prefix="$prefix"
   prefix="$acl_final_prefix"
@@ -5648,36 +13944,36 @@ fi
                       fi
                     done
                     if test -z "$haveit"; then
-                      LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir"
+                      LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir"
                     fi
                     if test "$acl_hardcode_minus_L" != no; then
-                                                                                        LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
+                                                                                        LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so"
                     else
-                                                                                                                                                                                LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name"
+                                                                                                                                                                                LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name"
                     fi
                   fi
                 fi
               fi
             else
               if test "X$found_a" != "X"; then
-                                LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a"
+                                LIBINTL="${LIBINTL}${LIBINTL:+ }$found_a"
               else
-                                                LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name"
+                                                LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir -l$name"
               fi
             fi
                         additional_includedir=
             case "$found_dir" in
               */$acl_libdirstem | */$acl_libdirstem/)
                 basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
-                if test "$name" = 'iconv'; then
-                  LIBICONV_PREFIX="$basedir"
+                if test "$name" = 'intl'; then
+                  LIBINTL_PREFIX="$basedir"
                 fi
                 additional_includedir="$basedir/include"
                 ;;
               */$acl_libdirstem2 | */$acl_libdirstem2/)
                 basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
-                if test "$name" = 'iconv'; then
-                  LIBICONV_PREFIX="$basedir"
+                if test "$name" = 'intl'; then
+                  LIBINTL_PREFIX="$basedir"
                 fi
                 additional_includedir="$basedir/include"
                 ;;
@@ -5693,7 +13989,7 @@ fi
                   fi
                 fi
                 if test -z "$haveit"; then
-                  for x in $CPPFLAGS $INCICONV; do
+                  for x in $CPPFLAGS $INCINTL; do
 
   acl_save_prefix="$prefix"
   prefix="$acl_final_prefix"
@@ -5710,7 +14006,7 @@ fi
                   done
                   if test -z "$haveit"; then
                     if test -d "$additional_includedir"; then
-                                            INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir"
+                                            INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir"
                     fi
                   fi
                 fi
@@ -5740,7 +14036,7 @@ fi
                       fi
                       if test -z "$haveit"; then
                         haveit=
-                        for x in $LDFLAGS $LIBICONV; do
+                        for x in $LDFLAGS $LIBINTL; do
 
   acl_save_prefix="$prefix"
   prefix="$acl_final_prefix"
@@ -5757,11 +14053,11 @@ fi
                         done
                         if test -z "$haveit"; then
                           if test -d "$additional_libdir"; then
-                                                        LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir"
+                                                        LIBINTL="${LIBINTL}${LIBINTL:+ }-L$additional_libdir"
                           fi
                         fi
                         haveit=
-                        for x in $LDFLAGS $LTLIBICONV; do
+                        for x in $LDFLAGS $LTLIBINTL; do
 
   acl_save_prefix="$prefix"
   prefix="$acl_final_prefix"
@@ -5778,7 +14074,7 @@ fi
                         done
                         if test -z "$haveit"; then
                           if test -d "$additional_libdir"; then
-                                                        LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir"
+                                                        LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$additional_libdir"
                           fi
                         fi
                       fi
@@ -5816,15 +14112,15 @@ fi
                                                                                 names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
                     ;;
                   *)
-                                        LIBICONV="${LIBICONV}${LIBICONV:+ }$dep"
-                    LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep"
+                                        LIBINTL="${LIBINTL}${LIBINTL:+ }$dep"
+                    LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$dep"
                     ;;
                 esac
               done
             fi
           else
-                                                            LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name"
-            LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name"
+                                                            LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name"
+            LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-l$name"
           fi
         fi
       fi
@@ -5832,1233 +14128,1055 @@ fi
   done
   if test "X$rpathdirs" != "X"; then
     if test -n "$acl_hardcode_libdir_separator"; then
-                        alldirs=
-      for found_dir in $rpathdirs; do
-        alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
-      done
-            acl_save_libdir="$libdir"
-      libdir="$alldirs"
-      eval flag=\"$acl_hardcode_libdir_flag_spec\"
-      libdir="$acl_save_libdir"
-      LIBICONV="${LIBICONV}${LIBICONV:+ }$flag"
-    else
-            for found_dir in $rpathdirs; do
-        acl_save_libdir="$libdir"
-        libdir="$found_dir"
-        eval flag=\"$acl_hardcode_libdir_flag_spec\"
-        libdir="$acl_save_libdir"
-        LIBICONV="${LIBICONV}${LIBICONV:+ }$flag"
-      done
-    fi
-  fi
-  if test "X$ltrpathdirs" != "X"; then
-            for found_dir in $ltrpathdirs; do
-      LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir"
-    done
-  fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+                        alldirs=
+      for found_dir in $rpathdirs; do
+        alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
+      done
+            acl_save_libdir="$libdir"
+      libdir="$alldirs"
+      eval flag=\"$acl_hardcode_libdir_flag_spec\"
+      libdir="$acl_save_libdir"
+      LIBINTL="${LIBINTL}${LIBINTL:+ }$flag"
+    else
+            for found_dir in $rpathdirs; do
+        acl_save_libdir="$libdir"
+        libdir="$found_dir"
+        eval flag=\"$acl_hardcode_libdir_flag_spec\"
+        libdir="$acl_save_libdir"
+        LIBINTL="${LIBINTL}${LIBINTL:+ }$flag"
+      done
+    fi
+  fi
+  if test "X$ltrpathdirs" != "X"; then
+            for found_dir in $ltrpathdirs; do
+      LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-R$found_dir"
+    done
+  fi
 
 
 
 
 
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFPreferencesCopyAppValue" >&5
-$as_echo_n "checking for CFPreferencesCopyAppValue... " >&6; }
-if test "${gt_cv_func_CFPreferencesCopyAppValue+set}" = set; then :
+          { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libintl" >&5
+$as_echo_n "checking for GNU gettext in libintl... " >&6; }
+if eval \${$gt_func_gnugettext_libintl+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  gt_save_LIBS="$LIBS"
-     LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
-     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+  gt_save_CPPFLAGS="$CPPFLAGS"
+            CPPFLAGS="$CPPFLAGS $INCINTL"
+            gt_save_LIBS="$LIBS"
+            LIBS="$LIBS $LIBINTL"
+                        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <CoreFoundation/CFPreferences.h>
+#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);
 int
 main ()
 {
-CFPreferencesCopyAppValue(NULL, NULL)
+bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
   ;
   return 0;
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  gt_cv_func_CFPreferencesCopyAppValue=yes
+  eval "$gt_func_gnugettext_libintl=yes"
 else
-  gt_cv_func_CFPreferencesCopyAppValue=no
+  eval "$gt_func_gnugettext_libintl=no"
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-     LIBS="$gt_save_LIBS"
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5
-$as_echo "$gt_cv_func_CFPreferencesCopyAppValue" >&6; }
-  if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then
-
-$as_echo "#define HAVE_CFPREFERENCESCOPYAPPVALUE 1" >>confdefs.h
-
-  fi
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFLocaleCopyCurrent" >&5
-$as_echo_n "checking for CFLocaleCopyCurrent... " >&6; }
-if test "${gt_cv_func_CFLocaleCopyCurrent+set}" = set; then :
-  $as_echo_n "(cached) " >&6
-else
-  gt_save_LIBS="$LIBS"
-     LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
-     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+                        if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then
+              LIBS="$LIBS $LIBICONV"
+              cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <CoreFoundation/CFLocale.h>
+#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);
 int
 main ()
 {
-CFLocaleCopyCurrent();
+bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
   ;
   return 0;
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  gt_cv_func_CFLocaleCopyCurrent=yes
-else
-  gt_cv_func_CFLocaleCopyCurrent=no
+  LIBINTL="$LIBINTL $LIBICONV"
+                LTLIBINTL="$LTLIBINTL $LTLIBICONV"
+                eval "$gt_func_gnugettext_libintl=yes"
+
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-     LIBS="$gt_save_LIBS"
+            fi
+            CPPFLAGS="$gt_save_CPPFLAGS"
+            LIBS="$gt_save_LIBS"
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFLocaleCopyCurrent" >&5
-$as_echo "$gt_cv_func_CFLocaleCopyCurrent" >&6; }
-  if test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+eval ac_res=\$$gt_func_gnugettext_libintl
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+        fi
 
-$as_echo "#define HAVE_CFLOCALECOPYCURRENT 1" >>confdefs.h
+                                        if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \
+           || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \
+                && test "$PACKAGE" != gettext-runtime \
+                && test "$PACKAGE" != gettext-tools; }; then
+          gt_use_preinstalled_gnugettext=yes
+        else
+                    LIBINTL=
+          LTLIBINTL=
+          INCINTL=
+        fi
+
+
+
+    if test -n "$INTL_MACOSX_LIBS"; then
+      if test "$gt_use_preinstalled_gnugettext" = "yes" \
+         || test "$nls_cv_use_gnu_gettext" = "yes"; then
+                LIBINTL="$LIBINTL $INTL_MACOSX_LIBS"
+        LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS"
+      fi
+    fi
+
+    if test "$gt_use_preinstalled_gnugettext" = "yes" \
+       || test "$nls_cv_use_gnu_gettext" = "yes"; then
+
+$as_echo "#define ENABLE_NLS 1" >>confdefs.h
+
+    else
+      USE_NLS=no
+    fi
+  fi
 
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use NLS" >&5
+$as_echo_n "checking whether to use NLS... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5
+$as_echo "$USE_NLS" >&6; }
+  if test "$USE_NLS" = "yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking where the gettext function comes from" >&5
+$as_echo_n "checking where the gettext function comes from... " >&6; }
+    if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+      if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
+        gt_source="external libintl"
+      else
+        gt_source="libc"
+      fi
+    else
+      gt_source="included intl directory"
+    fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_source" >&5
+$as_echo "$gt_source" >&6; }
   fi
-  INTL_MACOSX_LIBS=
-  if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then
-    INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation"
+
+  if test "$USE_NLS" = "yes"; then
+
+    if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+      if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libintl" >&5
+$as_echo_n "checking how to link with libintl... " >&6; }
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBINTL" >&5
+$as_echo "$LIBINTL" >&6; }
+
+  for element in $INCINTL; do
+    haveit=
+    for x in $CPPFLAGS; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+      if test "X$x" = "X$element"; then
+        haveit=yes
+        break
+      fi
+    done
+    if test -z "$haveit"; then
+      CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element"
+    fi
+  done
+
+      fi
+
+
+$as_echo "#define HAVE_GETTEXT 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_DCGETTEXT 1" >>confdefs.h
+
+    fi
+
+        POSUB=po
   fi
 
 
 
+    INTLLIBS="$LIBINTL"
 
 
 
-  LIBINTL=
-  LTLIBINTL=
-  POSUB=
 
-    case " $gt_needs " in
-    *" need-formatstring-macros "*) gt_api_version=3 ;;
-    *" need-ngettext "*) gt_api_version=2 ;;
-    *) gt_api_version=1 ;;
-  esac
-  gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc"
-  gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl"
 
-    if test "$USE_NLS" = "yes"; then
-    gt_use_preinstalled_gnugettext=no
 
 
-        if test $gt_api_version -ge 3; then
-          gt_revision_test_code='
-#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
-#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
-#endif
-typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
-'
-        else
-          gt_revision_test_code=
-        fi
-        if test $gt_api_version -ge 2; then
-          gt_expression_test_code=' + * ngettext ("", "", 0)'
-        else
-          gt_expression_test_code=
-        fi
+# doesn't support multiple po directories :(
+#AM_GLIB_GNU_GETTEXT
 
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libc" >&5
-$as_echo_n "checking for GNU gettext in libc... " >&6; }
-if { as_var=$gt_func_gnugettext_libc; eval "test \"\${$as_var+set}\" = set"; }; then :
-  $as_echo_n "(cached) " >&6
+
+# Check whether --with-vendor-package-version was given.
+if test "${with_vendor_package_version+set}" = set; then :
+  withval=$with_vendor_package_version;
 else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <libintl.h>
-$gt_revision_test_code
-extern int _nl_msg_cat_cntr;
-extern int *_nl_domain_bindings;
-int
-main ()
-{
-bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  eval "$gt_func_gnugettext_libc=yes"
+  with_vendor_package_version=
+
+fi
+
+WITH_VENDOR_PACKAGE_VERSION=$with_vendor_package_version
+if test "x$WITH_VENDOR_PACKAGE_VERSION" = "x"; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for git version" >&5
+$as_echo_n "checking for git version... " >&6; }
+	if git log --oneline 295b37c8ac4939829a3c7f9150943dba8fff07f0 > /dev/null 2>&1; then
+		GIT_BRANCH=$(git branch | grep '^\*' | cut -d ' ' -f 2)
+		GIT_COMMIT_HASH=$(git log --no-color --first-parent -n1 --pretty=format:%h)
+		DIST_VERSION=$GIT_BRANCH/$GIT_COMMIT_HASH
+		DEV_VERSION_SUFFIX="-dev"
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	else
+		DIST_VERSION=tarball
+		DEV_VERSION_SUFFIX=
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	fi
 else
-  eval "$gt_func_gnugettext_libc=no"
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
+	DIST_VERSION=$WITH_VENDOR_PACKAGE_VERSION
 fi
-eval ac_res=\$$gt_func_gnugettext_libc
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
+git_branch="$GIT_BRANCH"
 
-        if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
+git_commit_hash="$GIT_COMMIT_HASH"
 
 
+dist_version="$DIST_VERSION"
 
 
 
-          am_save_CPPFLAGS="$CPPFLAGS"
+	expanded_libdir=`(
+		case $prefix in
+			NONE) prefix=$ac_default_prefix ;;
+			*) ;;
+		esac
+		case $exec_prefix in
+			NONE) exec_prefix=$prefix ;;
+			*) ;;
+		esac
+		eval echo $libdir
+	)`
 
-  for element in $INCICONV; do
-    haveit=
-    for x in $CPPFLAGS; do
 
-  acl_save_prefix="$prefix"
-  prefix="$acl_final_prefix"
-  acl_save_exec_prefix="$exec_prefix"
-  exec_prefix="$acl_final_exec_prefix"
-  eval x=\"$x\"
-  exec_prefix="$acl_save_exec_prefix"
-  prefix="$acl_save_prefix"
 
-      if test "X$x" = "X$element"; then
-        haveit=yes
-        break
-      fi
-    done
-    if test -z "$haveit"; then
-      CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element"
-    fi
-  done
 
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5
-$as_echo_n "checking for iconv... " >&6; }
-if test "${am_cv_func_iconv+set}" = set; then :
-  $as_echo_n "(cached) " >&6
-else
 
-    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 $LIBICONV"
-      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
 
-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 "$as_me:${as_lineno-$LINENO}: checking for working iconv" >&5
-$as_echo_n "checking for working iconv... " >&6; }
-if test "${am_cv_func_iconv_works+set}" = set; then :
-  $as_echo_n "(cached) " >&6
-else
 
-            am_save_LIBS="$LIBS"
-      if test $am_cv_lib_iconv = yes; then
-        LIBS="$LIBS $LIBICONV"
-      fi
-      if test "$cross_compiling" = yes; then :
-  case "$host_os" in
-           aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
-           *)            am_cv_func_iconv_works="guessing yes" ;;
-         esac
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
 
-#include <iconv.h>
-#include <string.h>
-int main ()
-{
-  /* Test against AIX 5.1 bug: Failures are not distinguishable from successful
-     returns.  */
-  {
-    iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
-    if (cd_utf8_to_88591 != (iconv_t)(-1))
-      {
-        static const char input[] = "\342\202\254"; /* EURO SIGN */
-        char buf[10];
-        const char *inptr = input;
-        size_t inbytesleft = strlen (input);
-        char *outptr = buf;
-        size_t outbytesleft = sizeof (buf);
-        size_t res = iconv (cd_utf8_to_88591,
-                            (char **) &inptr, &inbytesleft,
-                            &outptr, &outbytesleft);
-        if (res == 0)
-          return 1;
-      }
-  }
-  /* Test against Solaris 10 bug: Failures are not distinguishable from
-     successful returns.  */
-  {
-    iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
-    if (cd_ascii_to_88591 != (iconv_t)(-1))
-      {
-        static const char input[] = "\263";
-        char buf[10];
-        const char *inptr = input;
-        size_t inbytesleft = strlen (input);
-        char *outptr = buf;
-        size_t outbytesleft = sizeof (buf);
-        size_t res = iconv (cd_ascii_to_88591,
-                            (char **) &inptr, &inbytesleft,
-                            &outptr, &outbytesleft);
-        if (res == 0)
-          return 1;
-      }
-  }
-#if 0 /* This bug could be worked around by the caller.  */
-  /* Test against HP-UX 11.11 bug: Positive return value instead of 0.  */
-  {
-    iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
-    if (cd_88591_to_utf8 != (iconv_t)(-1))
-      {
-        static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
-        char buf[50];
-        const char *inptr = input;
-        size_t inbytesleft = strlen (input);
-        char *outptr = buf;
-        size_t outbytesleft = sizeof (buf);
-        size_t res = iconv (cd_88591_to_utf8,
-                            (char **) &inptr, &inbytesleft,
-                            &outptr, &outbytesleft);
-        if ((int)res > 0)
-          return 1;
-      }
-  }
-#endif
-  /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
-     provided.  */
-  if (/* Try standardized names.  */
-      iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
-      /* Try IRIX, OSF/1 names.  */
-      && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
-      /* Try AIX names.  */
-      && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
-      /* Try HP-UX names.  */
-      && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
-    return 1;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-  am_cv_func_iconv_works=yes
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; 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_PKG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  am_cv_func_iconv_works=no
+  case $PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # 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_PKG_CONFIG="$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
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
-      LIBS="$am_save_LIBS"
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv_works" >&5
-$as_echo "$am_cv_func_iconv_works" >&6; }
-    case "$am_cv_func_iconv_works" in
-      *no) am_func_iconv=no am_cv_lib_iconv=no ;;
-      *)   am_func_iconv=yes ;;
-    esac
-  else
-    am_func_iconv=no am_cv_lib_iconv=no
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+  ac_pt_PKG_CONFIG=$PKG_CONFIG
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; 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_PKG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # 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_PKG_CONFIG="$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
-  if test "$am_func_iconv" = yes; then
+done
+  done
+IFS=$as_save_IFS
 
-$as_echo "#define HAVE_ICONV 1" >>confdefs.h
+  ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
-  fi
-  if test "$am_cv_lib_iconv" = yes; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5
-$as_echo_n "checking how to link with libiconv... " >&6; }
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5
-$as_echo "$LIBICONV" >&6; }
+  if test "x$ac_pt_PKG_CONFIG" = x; then
+    PKG_CONFIG=""
   else
-            CPPFLAGS="$am_save_CPPFLAGS"
-    LIBICONV=
-    LTLIBICONV=
+    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
+    PKG_CONFIG=$ac_pt_PKG_CONFIG
   fi
+else
+  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
 
+fi
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=0.9.0
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		PKG_CONFIG=""
+	fi
+fi
 
 
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for MONO_MODULE" >&5
+$as_echo_n "checking for MONO_MODULE... " >&6; }
 
+if test -n "$MONO_MODULE_CFLAGS"; then
+    pkg_cv_MONO_MODULE_CFLAGS="$MONO_MODULE_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"mono >= 1.9.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "mono >= 1.9.1") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_MONO_MODULE_CFLAGS=`$PKG_CONFIG --cflags "mono >= 1.9.1" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$MONO_MODULE_LIBS"; then
+    pkg_cv_MONO_MODULE_LIBS="$MONO_MODULE_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"mono >= 1.9.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "mono >= 1.9.1") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_MONO_MODULE_LIBS=`$PKG_CONFIG --libs "mono >= 1.9.1" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
 
 
 
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        MONO_MODULE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "mono >= 1.9.1" 2>&1`
+        else
+	        MONO_MODULE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "mono >= 1.9.1" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$MONO_MODULE_PKG_ERRORS" >&5
 
+	as_fn_error $? "Package requirements (mono >= 1.9.1) were not met:
 
+$MONO_MODULE_PKG_ERRORS
 
-    use_additional=yes
-
-  acl_save_prefix="$prefix"
-  prefix="$acl_final_prefix"
-  acl_save_exec_prefix="$exec_prefix"
-  exec_prefix="$acl_final_exec_prefix"
-
-    eval additional_includedir=\"$includedir\"
-    eval additional_libdir=\"$libdir\"
-
-  exec_prefix="$acl_save_exec_prefix"
-  prefix="$acl_save_prefix"
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
 
+Alternatively, you may set the environment variables MONO_MODULE_CFLAGS
+and MONO_MODULE_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&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 $? "The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
 
-# Check whether --with-libintl-prefix was given.
-if test "${with_libintl_prefix+set}" = set; then :
-  withval=$with_libintl_prefix;
-    if test "X$withval" = "Xno"; then
-      use_additional=no
-    else
-      if test "X$withval" = "X"; then
+Alternatively, you may set the environment variables MONO_MODULE_CFLAGS
+and MONO_MODULE_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
 
-  acl_save_prefix="$prefix"
-  prefix="$acl_final_prefix"
-  acl_save_exec_prefix="$exec_prefix"
-  exec_prefix="$acl_final_exec_prefix"
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+	MONO_MODULE_CFLAGS=$pkg_cv_MONO_MODULE_CFLAGS
+	MONO_MODULE_LIBS=$pkg_cv_MONO_MODULE_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 
-          eval additional_includedir=\"$includedir\"
-          eval additional_libdir=\"$libdir\"
+fi
 
-  exec_prefix="$acl_save_exec_prefix"
-  prefix="$acl_save_prefix"
 
-      else
-        additional_includedir="$withval/include"
-        additional_libdir="$withval/$acl_libdirstem"
-        if test "$acl_libdirstem2" != "$acl_libdirstem" \
-           && ! test -d "$withval/$acl_libdirstem"; then
-          additional_libdir="$withval/$acl_libdirstem2"
-        fi
-      fi
-    fi
 
-fi
 
-      LIBINTL=
-  LTLIBINTL=
-  INCINTL=
-  LIBINTL_PREFIX=
-      HAVE_LIBINTL=
-  rpathdirs=
-  ltrpathdirs=
-  names_already_handled=
-  names_next_round='intl '
-  while test -n "$names_next_round"; do
-    names_this_round="$names_next_round"
-    names_next_round=
-    for name in $names_this_round; do
-      already_handled=
-      for n in $names_already_handled; do
-        if test "$n" = "$name"; then
-          already_handled=yes
-          break
-        fi
-      done
-      if test -z "$already_handled"; then
-        names_already_handled="$names_already_handled $name"
-                        uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
-        eval value=\"\$HAVE_LIB$uppername\"
-        if test -n "$value"; then
-          if test "$value" = yes; then
-            eval value=\"\$LIB$uppername\"
-            test -z "$value" || LIBINTL="${LIBINTL}${LIBINTL:+ }$value"
-            eval value=\"\$LTLIB$uppername\"
-            test -z "$value" || LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$value"
-          else
-                                    :
-          fi
-        else
-                              found_dir=
-          found_la=
-          found_so=
-          found_a=
-          eval libname=\"$acl_libname_spec\"    # typically: libname=lib$name
-          if test -n "$acl_shlibext"; then
-            shrext=".$acl_shlibext"             # typically: shrext=.so
-          else
-            shrext=
-          fi
-          if test $use_additional = yes; then
-            dir="$additional_libdir"
-                                    if test -n "$acl_shlibext"; then
-              if test -f "$dir/$libname$shrext"; then
-                found_dir="$dir"
-                found_so="$dir/$libname$shrext"
-              else
-                if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
-                  ver=`(cd "$dir" && \
-                        for f in "$libname$shrext".*; do echo "$f"; done \
-                        | sed -e "s,^$libname$shrext\\\\.,," \
-                        | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
-                        | sed 1q ) 2>/dev/null`
-                  if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
-                    found_dir="$dir"
-                    found_so="$dir/$libname$shrext.$ver"
-                  fi
-                else
-                  eval library_names=\"$acl_library_names_spec\"
-                  for f in $library_names; do
-                    if test -f "$dir/$f"; then
-                      found_dir="$dir"
-                      found_so="$dir/$f"
-                      break
-                    fi
-                  done
-                fi
-              fi
-            fi
-                        if test "X$found_dir" = "X"; then
-              if test -f "$dir/$libname.$acl_libext"; then
-                found_dir="$dir"
-                found_a="$dir/$libname.$acl_libext"
-              fi
-            fi
-            if test "X$found_dir" != "X"; then
-              if test -f "$dir/$libname.la"; then
-                found_la="$dir/$libname.la"
-              fi
-            fi
-          fi
-          if test "X$found_dir" = "X"; then
-            for x in $LDFLAGS $LTLIBINTL; do
+	# Extract the first word of "mono", so it can be a program name with args.
+set dummy mono; 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_MONO+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MONO in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_MONO="$MONO" # 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_MONO="$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
 
-  acl_save_prefix="$prefix"
-  prefix="$acl_final_prefix"
-  acl_save_exec_prefix="$exec_prefix"
-  exec_prefix="$acl_final_exec_prefix"
-  eval x=\"$x\"
-  exec_prefix="$acl_save_exec_prefix"
-  prefix="$acl_save_prefix"
+  test -z "$ac_cv_path_MONO" && ac_cv_path_MONO="no"
+  ;;
+esac
+fi
+MONO=$ac_cv_path_MONO
+if test -n "$MONO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MONO" >&5
+$as_echo "$MONO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
-              case "$x" in
-                -L*)
-                  dir=`echo "X$x" | sed -e 's/^X-L//'`
-                                    if test -n "$acl_shlibext"; then
-                    if test -f "$dir/$libname$shrext"; then
-                      found_dir="$dir"
-                      found_so="$dir/$libname$shrext"
-                    else
-                      if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
-                        ver=`(cd "$dir" && \
-                              for f in "$libname$shrext".*; do echo "$f"; done \
-                              | sed -e "s,^$libname$shrext\\\\.,," \
-                              | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
-                              | sed 1q ) 2>/dev/null`
-                        if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
-                          found_dir="$dir"
-                          found_so="$dir/$libname$shrext.$ver"
-                        fi
-                      else
-                        eval library_names=\"$acl_library_names_spec\"
-                        for f in $library_names; do
-                          if test -f "$dir/$f"; then
-                            found_dir="$dir"
-                            found_so="$dir/$f"
-                            break
-                          fi
-                        done
-                      fi
-                    fi
-                  fi
-                                    if test "X$found_dir" = "X"; then
-                    if test -f "$dir/$libname.$acl_libext"; then
-                      found_dir="$dir"
-                      found_a="$dir/$libname.$acl_libext"
-                    fi
-                  fi
-                  if test "X$found_dir" != "X"; then
-                    if test -f "$dir/$libname.la"; then
-                      found_la="$dir/$libname.la"
-                    fi
-                  fi
-                  ;;
-              esac
-              if test "X$found_dir" != "X"; then
-                break
-              fi
-            done
-          fi
-          if test "X$found_dir" != "X"; then
-                        LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$found_dir -l$name"
-            if test "X$found_so" != "X"; then
-                                                        if test "$enable_rpath" = no \
-                 || test "X$found_dir" = "X/usr/$acl_libdirstem" \
-                 || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
-                                LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so"
-              else
-                                                                                haveit=
-                for x in $ltrpathdirs; do
-                  if test "X$x" = "X$found_dir"; then
-                    haveit=yes
-                    break
-                  fi
-                done
-                if test -z "$haveit"; then
-                  ltrpathdirs="$ltrpathdirs $found_dir"
-                fi
-                                if test "$acl_hardcode_direct" = yes; then
-                                                      LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so"
-                else
-                  if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
-                                                            LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so"
-                                                            haveit=
-                    for x in $rpathdirs; do
-                      if test "X$x" = "X$found_dir"; then
-                        haveit=yes
-                        break
-                      fi
-                    done
-                    if test -z "$haveit"; then
-                      rpathdirs="$rpathdirs $found_dir"
-                    fi
-                  else
-                                                                                haveit=
-                    for x in $LDFLAGS $LIBINTL; do
 
-  acl_save_prefix="$prefix"
-  prefix="$acl_final_prefix"
-  acl_save_exec_prefix="$exec_prefix"
-  exec_prefix="$acl_final_exec_prefix"
-  eval x=\"$x\"
-  exec_prefix="$acl_save_exec_prefix"
-  prefix="$acl_save_prefix"
 
-                      if test "X$x" = "X-L$found_dir"; then
-                        haveit=yes
-                        break
-                      fi
-                    done
-                    if test -z "$haveit"; then
-                      LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir"
-                    fi
-                    if test "$acl_hardcode_minus_L" != no; then
-                                                                                        LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so"
-                    else
-                                                                                                                                                                                LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name"
-                    fi
-                  fi
-                fi
-              fi
-            else
-              if test "X$found_a" != "X"; then
-                                LIBINTL="${LIBINTL}${LIBINTL:+ }$found_a"
-              else
-                                                LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir -l$name"
-              fi
-            fi
-                        additional_includedir=
-            case "$found_dir" in
-              */$acl_libdirstem | */$acl_libdirstem/)
-                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
-                if test "$name" = 'intl'; then
-                  LIBINTL_PREFIX="$basedir"
-                fi
-                additional_includedir="$basedir/include"
-                ;;
-              */$acl_libdirstem2 | */$acl_libdirstem2/)
-                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
-                if test "$name" = 'intl'; then
-                  LIBINTL_PREFIX="$basedir"
-                fi
-                additional_includedir="$basedir/include"
-                ;;
-            esac
-            if test "X$additional_includedir" != "X"; then
-                                                                                                                if test "X$additional_includedir" != "X/usr/include"; then
-                haveit=
-                if test "X$additional_includedir" = "X/usr/local/include"; then
-                  if test -n "$GCC"; then
-                    case $host_os in
-                      linux* | gnu* | k*bsd*-gnu) haveit=yes;;
-                    esac
-                  fi
-                fi
-                if test -z "$haveit"; then
-                  for x in $CPPFLAGS $INCINTL; do
 
-  acl_save_prefix="$prefix"
-  prefix="$acl_final_prefix"
-  acl_save_exec_prefix="$exec_prefix"
-  exec_prefix="$acl_final_exec_prefix"
-  eval x=\"$x\"
-  exec_prefix="$acl_save_exec_prefix"
-  prefix="$acl_save_prefix"
+	if test "x$MONO" = "xno"; then
+		as_fn_error $? "You need to install 'mono'" "$LINENO" 5
+	fi
+
+
+
+
+
+	# Extract the first word of "gmcs", so it can be a program name with args.
+set dummy gmcs; 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_MCS+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MCS in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_MCS="$MCS" # 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_MCS="$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
+
+  test -z "$ac_cv_path_MCS" && ac_cv_path_MCS="no"
+  ;;
+esac
+fi
+MCS=$ac_cv_path_MCS
+if test -n "$MCS"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MCS" >&5
+$as_echo "$MCS" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+	if test "x$MCS" = "xno"; then
+		as_fn_error $? "You need to install 'gmcs'" "$LINENO" 5
+	fi
+
+
+
+
+	for asm in $(echo "2.0,System
+	System.Core
+	System.Xml
+	System.Runtime.Remoting
+	Mono.Posix
+" | cut -d, -f2- | sed 's/\,/ /g')
+	do
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Mono 2.0 GAC for $asm.dll" >&5
+$as_echo_n "checking for Mono 2.0 GAC for $asm.dll... " >&6; }
+		if test \
+			-e "$($PKG_CONFIG --variable=libdir mono)/mono/2.0/$asm.dll" -o \
+			-e "$($PKG_CONFIG --variable=prefix mono)/lib/mono/2.0/$asm.dll"; \
+			then \
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
+$as_echo "found" >&6; }
+		else
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+			as_fn_error $? "missing reqired Mono 2.0 assembly: $asm.dll" "$LINENO" 5
+		fi
+	done
 
-                    if test "X$x" = "X-I$additional_includedir"; then
-                      haveit=yes
-                      break
-                    fi
-                  done
-                  if test -z "$haveit"; then
-                    if test -d "$additional_includedir"; then
-                                            INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir"
-                    fi
-                  fi
-                fi
-              fi
-            fi
-                        if test -n "$found_la"; then
-                                                        save_libdir="$libdir"
-              case "$found_la" in
-                */* | *\\*) . "$found_la" ;;
-                *) . "./$found_la" ;;
-              esac
-              libdir="$save_libdir"
-                            for dep in $dependency_libs; do
-                case "$dep" in
-                  -L*)
-                    additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
-                                                                                                                                                                if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \
-                       && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
-                      haveit=
-                      if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
-                         || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then
-                        if test -n "$GCC"; then
-                          case $host_os in
-                            linux* | gnu* | k*bsd*-gnu) haveit=yes;;
-                          esac
-                        fi
-                      fi
-                      if test -z "$haveit"; then
-                        haveit=
-                        for x in $LDFLAGS $LIBINTL; do
 
-  acl_save_prefix="$prefix"
-  prefix="$acl_final_prefix"
-  acl_save_exec_prefix="$exec_prefix"
-  exec_prefix="$acl_final_exec_prefix"
-  eval x=\"$x\"
-  exec_prefix="$acl_save_exec_prefix"
-  prefix="$acl_save_prefix"
 
-                          if test "X$x" = "X-L$additional_libdir"; then
-                            haveit=yes
-                            break
-                          fi
-                        done
-                        if test -z "$haveit"; then
-                          if test -d "$additional_libdir"; then
-                                                        LIBINTL="${LIBINTL}${LIBINTL:+ }-L$additional_libdir"
-                          fi
-                        fi
-                        haveit=
-                        for x in $LDFLAGS $LTLIBINTL; do
+PROFILE=debug
+# Check whether --enable-release was given.
+if test "${enable_release+set}" = set; then :
+  enableval=$enable_release; enable_release=yes
+else
+  enable_release=no
+fi
 
-  acl_save_prefix="$prefix"
-  prefix="$acl_final_prefix"
-  acl_save_exec_prefix="$exec_prefix"
-  exec_prefix="$acl_final_exec_prefix"
-  eval x=\"$x\"
-  exec_prefix="$acl_save_exec_prefix"
-  prefix="$acl_save_prefix"
+ if test x$enable_release = xyes; then
+  ENABLE_RELEASE_TRUE=
+  ENABLE_RELEASE_FALSE='#'
+else
+  ENABLE_RELEASE_TRUE='#'
+  ENABLE_RELEASE_FALSE=
+fi
 
-                          if test "X$x" = "X-L$additional_libdir"; then
-                            haveit=yes
-                            break
-                          fi
-                        done
-                        if test -z "$haveit"; then
-                          if test -d "$additional_libdir"; then
-                                                        LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$additional_libdir"
-                          fi
-                        fi
-                      fi
-                    fi
-                    ;;
-                  -R*)
-                    dir=`echo "X$dep" | sed -e 's/^X-R//'`
-                    if test "$enable_rpath" != no; then
-                                                                  haveit=
-                      for x in $rpathdirs; do
-                        if test "X$x" = "X$dir"; then
-                          haveit=yes
-                          break
-                        fi
-                      done
-                      if test -z "$haveit"; then
-                        rpathdirs="$rpathdirs $dir"
-                      fi
-                                                                  haveit=
-                      for x in $ltrpathdirs; do
-                        if test "X$x" = "X$dir"; then
-                          haveit=yes
-                          break
-                        fi
-                      done
-                      if test -z "$haveit"; then
-                        ltrpathdirs="$ltrpathdirs $dir"
-                      fi
-                    fi
-                    ;;
-                  -l*)
-                                        names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
-                    ;;
-                  *.la)
-                                                                                names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
-                    ;;
-                  *)
-                                        LIBINTL="${LIBINTL}${LIBINTL:+ }$dep"
-                    LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$dep"
-                    ;;
-                esac
-              done
-            fi
-          else
-                                                            LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name"
-            LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-l$name"
-          fi
-        fi
-      fi
-    done
-  done
-  if test "X$rpathdirs" != "X"; then
-    if test -n "$acl_hardcode_libdir_separator"; then
-                        alldirs=
-      for found_dir in $rpathdirs; do
-        alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
-      done
-            acl_save_libdir="$libdir"
-      libdir="$alldirs"
-      eval flag=\"$acl_hardcode_libdir_flag_spec\"
-      libdir="$acl_save_libdir"
-      LIBINTL="${LIBINTL}${LIBINTL:+ }$flag"
-    else
-            for found_dir in $rpathdirs; do
-        acl_save_libdir="$libdir"
-        libdir="$found_dir"
-        eval flag=\"$acl_hardcode_libdir_flag_spec\"
-        libdir="$acl_save_libdir"
-        LIBINTL="${LIBINTL}${LIBINTL:+ }$flag"
-      done
-    fi
-  fi
-  if test "X$ltrpathdirs" != "X"; then
-            for found_dir in $ltrpathdirs; do
-      LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-R$found_dir"
-    done
-  fi
+if test "x$enable_release" = "xyes" ; then
+	PROFILE=release
+fi
+# Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then :
+  enableval=$enable_debug; enable_debug=yes
+else
+  enable_debug=no
+fi
 
+ if test x$enable_debug = xyes; then
+  ENABLE_DEBUG_TRUE=
+  ENABLE_DEBUG_FALSE='#'
+else
+  ENABLE_DEBUG_TRUE='#'
+  ENABLE_DEBUG_FALSE=
+fi
 
+if test "x$enable_debug" = "xyes" ; then
+	PROFILE=debug
+fi
 
 
+CSC="$MCS"
 
+CSC_FLAGS=
+if test "x$PROFILE" = "xdebug"; then
+	 if true; then
+  ENABLE_DEBUG_TRUE=
+  ENABLE_DEBUG_FALSE='#'
+else
+  ENABLE_DEBUG_TRUE='#'
+  ENABLE_DEBUG_FALSE=
+fi
 
-          { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libintl" >&5
-$as_echo_n "checking for GNU gettext in libintl... " >&6; }
-if { as_var=$gt_func_gnugettext_libintl; eval "test \"\${$as_var+set}\" = set"; }; then :
-  $as_echo_n "(cached) " >&6
+	CSC_FLAGS+=-define:DEBUG,TRACE,LOG4NET
 else
-  gt_save_CPPFLAGS="$CPPFLAGS"
-            CPPFLAGS="$CPPFLAGS $INCINTL"
-            gt_save_LIBS="$LIBS"
-            LIBS="$LIBS $LIBINTL"
-                        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <libintl.h>
-$gt_revision_test_code
-extern int _nl_msg_cat_cntr;
-extern
-#ifdef __cplusplus
-"C"
-#endif
-const char *_nl_expand_alias (const char *);
-int
-main ()
-{
-bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  eval "$gt_func_gnugettext_libintl=yes"
+	 if true; then
+  ENABLE_RELEASE_TRUE=
+  ENABLE_RELEASE_FALSE='#'
 else
-  eval "$gt_func_gnugettext_libintl=no"
+  ENABLE_RELEASE_TRUE='#'
+  ENABLE_RELEASE_FALSE=
 fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-                        if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then
-              LIBS="$LIBS $LIBICONV"
-              cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <libintl.h>
-$gt_revision_test_code
-extern int _nl_msg_cat_cntr;
-extern
-#ifdef __cplusplus
-"C"
-#endif
-const char *_nl_expand_alias (const char *);
-int
-main ()
-{
-bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  LIBINTL="$LIBINTL $LIBICONV"
-                LTLIBINTL="$LTLIBINTL $LTLIBICONV"
-                eval "$gt_func_gnugettext_libintl=yes"
 
 fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-            fi
-            CPPFLAGS="$gt_save_CPPFLAGS"
-            LIBS="$gt_save_LIBS"
+
+
+MCS_BASENAME=$(basename $MCS)
+CLI_RUNTIME=
+if test "$MCS_BASENAME" = "gmcs"; then
+	CLI_RUNTIME=2.0
+fi
+if test "$MCS_BASENAME" = "dmcs"; then
+	CLI_RUNTIME=4.0
+fi
+if test "$CLI_RUNTIME" = "2.0"; then
+	XBUILD_FLAGS="/toolsversion:3.5 /p:TargetFrameworkVersion=v3.5"
+fi
+if test "$CLI_RUNTIME" = "4.0"; then
+	XBUILD_FLAGS="/toolsversion:4.0 /p:TargetFrameworkVersion=v4.0"
 fi
-eval ac_res=\$$gt_func_gnugettext_libintl
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-        fi
 
-                                        if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \
-           || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \
-                && test "$PACKAGE" != gettext-runtime \
-                && test "$PACKAGE" != gettext-tools; }; then
-          gt_use_preinstalled_gnugettext=yes
-        else
-                    LIBINTL=
-          LTLIBINTL=
-          INCINTL=
-        fi
 
+# Required Libraries
 
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LOG4NET" >&5
+$as_echo_n "checking for LOG4NET... " >&6; }
 
-    if test -n "$INTL_MACOSX_LIBS"; then
-      if test "$gt_use_preinstalled_gnugettext" = "yes" \
-         || test "$nls_cv_use_gnu_gettext" = "yes"; then
-                LIBINTL="$LIBINTL $INTL_MACOSX_LIBS"
-        LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS"
-      fi
-    fi
+if test -n "$LOG4NET_CFLAGS"; then
+    pkg_cv_LOG4NET_CFLAGS="$LOG4NET_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"log4net\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "log4net") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LOG4NET_CFLAGS=`$PKG_CONFIG --cflags "log4net" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$LOG4NET_LIBS"; then
+    pkg_cv_LOG4NET_LIBS="$LOG4NET_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"log4net\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "log4net") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LOG4NET_LIBS=`$PKG_CONFIG --libs "log4net" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
 
-    if test "$gt_use_preinstalled_gnugettext" = "yes" \
-       || test "$nls_cv_use_gnu_gettext" = "yes"; then
 
-$as_echo "#define ENABLE_NLS 1" >>confdefs.h
 
-    else
-      USE_NLS=no
-    fi
-  fi
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use NLS" >&5
-$as_echo_n "checking whether to use NLS... " >&6; }
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5
-$as_echo "$USE_NLS" >&6; }
-  if test "$USE_NLS" = "yes"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking where the gettext function comes from" >&5
-$as_echo_n "checking where the gettext function comes from... " >&6; }
-    if test "$gt_use_preinstalled_gnugettext" = "yes"; then
-      if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
-        gt_source="external libintl"
-      else
-        gt_source="libc"
-      fi
-    else
-      gt_source="included intl directory"
-    fi
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_source" >&5
-$as_echo "$gt_source" >&6; }
-  fi
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        LOG4NET_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "log4net" 2>&1`
+        else
+	        LOG4NET_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "log4net" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$LOG4NET_PKG_ERRORS" >&5
 
-  if test "$USE_NLS" = "yes"; then
+	as_fn_error $? "Package requirements (log4net) were not met:
 
-    if test "$gt_use_preinstalled_gnugettext" = "yes"; then
-      if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libintl" >&5
-$as_echo_n "checking how to link with libintl... " >&6; }
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBINTL" >&5
-$as_echo "$LIBINTL" >&6; }
+$LOG4NET_PKG_ERRORS
 
-  for element in $INCINTL; do
-    haveit=
-    for x in $CPPFLAGS; do
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
 
-  acl_save_prefix="$prefix"
-  prefix="$acl_final_prefix"
-  acl_save_exec_prefix="$exec_prefix"
-  exec_prefix="$acl_final_exec_prefix"
-  eval x=\"$x\"
-  exec_prefix="$acl_save_exec_prefix"
-  prefix="$acl_save_prefix"
+Alternatively, you may set the environment variables LOG4NET_CFLAGS
+and LOG4NET_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&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 $? "The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
 
-      if test "X$x" = "X$element"; then
-        haveit=yes
-        break
-      fi
-    done
-    if test -z "$haveit"; then
-      CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element"
-    fi
-  done
+Alternatively, you may set the environment variables LOG4NET_CFLAGS
+and LOG4NET_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
 
-      fi
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+	LOG4NET_CFLAGS=$pkg_cv_LOG4NET_CFLAGS
+	LOG4NET_LIBS=$pkg_cv_LOG4NET_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 
+fi
 
-$as_echo "#define HAVE_GETTEXT 1" >>confdefs.h
+if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"nini-1.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "nini-1.1") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  FOUND_NINI=yes
+else
+  FOUND_NINI=no
+fi
+if test "x$FOUND_NINI" = "xyes"; then
+	nini_files=`pkg-config --variable=Libraries nini-1.1`
+	 if test -n "$nini_files"; then
+  BUNDLE_NINI_TRUE=
+  BUNDLE_NINI_FALSE='#'
+else
+  BUNDLE_NINI_TRUE='#'
+  BUNDLE_NINI_FALSE=
+fi
 
+	if test -z "$nini_files" ; then
+		# Debian-based distros place Nini into the GAC
 
-$as_echo "#define HAVE_DCGETTEXT 1" >>confdefs.h
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NINI" >&5
+$as_echo_n "checking for NINI... " >&6; }
 
-    fi
+if test -n "$NINI_CFLAGS"; then
+    pkg_cv_NINI_CFLAGS="$NINI_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"nini-1.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "nini-1.1") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_NINI_CFLAGS=`$PKG_CONFIG --cflags "nini-1.1" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$NINI_LIBS"; then
+    pkg_cv_NINI_LIBS="$NINI_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"nini-1.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "nini-1.1") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_NINI_LIBS=`$PKG_CONFIG --libs "nini-1.1" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
 
-        POSUB=po
-  fi
 
 
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 
-    INTLLIBS="$LIBINTL"
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        NINI_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "nini-1.1" 2>&1`
+        else
+	        NINI_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "nini-1.1" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$NINI_PKG_ERRORS" >&5
+
+	as_fn_error $? "Package requirements (nini-1.1) were not met:
 
+$NINI_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables NINI_CFLAGS
+and NINI_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&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 $? "The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
 
+Alternatively, you may set the environment variables NINI_CFLAGS
+and NINI_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
 
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+	NINI_CFLAGS=$pkg_cv_NINI_CFLAGS
+	NINI_LIBS=$pkg_cv_NINI_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 
+fi
+	else
+		# openSUSE has Nini as a private assembly; need to copy it.
+		NINI_LIBS="$nini_files"
 
+	fi
+else
 
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NINI" >&5
+$as_echo_n "checking for NINI... " >&6; }
 
-# doesn't support multiple po directories :(
-#AM_GLIB_GNU_GETTEXT
+if test -n "$NINI_CFLAGS"; then
+    pkg_cv_NINI_CFLAGS="$NINI_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"nini >= 1.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "nini >= 1.1") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_NINI_CFLAGS=`$PKG_CONFIG --cflags "nini >= 1.1" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$NINI_LIBS"; then
+    pkg_cv_NINI_LIBS="$NINI_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"nini >= 1.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "nini >= 1.1") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_NINI_LIBS=`$PKG_CONFIG --libs "nini >= 1.1" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
 
 
-	expanded_libdir=`(
-		case $prefix in
-			NONE) prefix=$ac_default_prefix ;;
-			*) ;;
-		esac
-		case $exec_prefix in
-			NONE) exec_prefix=$prefix ;;
-			*) ;;
-		esac
-		eval echo $libdir
-	)`
 
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        NINI_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "nini >= 1.1" 2>&1`
+        else
+	        NINI_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "nini >= 1.1" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$NINI_PKG_ERRORS" >&5
 
+	as_fn_error $? "Package requirements (nini >= 1.1) were not met:
 
+$NINI_PKG_ERRORS
 
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
 
+Alternatively, you may set the environment variables NINI_CFLAGS
+and NINI_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&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 $? "The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
 
+Alternatively, you may set the environment variables NINI_CFLAGS
+and NINI_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
 
-if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
-	if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
-set dummy ${ac_tool_prefix}pkg-config; 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_PKG_CONFIG+set}" = set; then :
-  $as_echo_n "(cached) " >&6
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
 else
-  case $PKG_CONFIG in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # 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_PKG_CONFIG="$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
+	NINI_CFLAGS=$pkg_cv_NINI_CFLAGS
+	NINI_LIBS=$pkg_cv_NINI_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 
-  ;;
-esac
 fi
-PKG_CONFIG=$ac_cv_path_PKG_CONFIG
-if test -n "$PKG_CONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
-$as_echo "$PKG_CONFIG" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
 fi
 
 
-fi
-if test -z "$ac_cv_path_PKG_CONFIG"; then
-  ac_pt_PKG_CONFIG=$PKG_CONFIG
-  # Extract the first word of "pkg-config", so it can be a program name with args.
-set dummy pkg-config; 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_PKG_CONFIG+set}" = set; then :
-  $as_echo_n "(cached) " >&6
+# Check whether --with-db4o was given.
+if test "${with_db4o+set}" = set; then :
+  withval=$with_db4o;
 else
-  case $ac_pt_PKG_CONFIG in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # 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_PKG_CONFIG="$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
+  with_db4o=auto
 
-  ;;
-esac
-fi
-ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
-if test -n "$ac_pt_PKG_CONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
-$as_echo "$ac_pt_PKG_CONFIG" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
 fi
 
-  if test "x$ac_pt_PKG_CONFIG" = x; then
-    PKG_CONFIG=""
-  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
-    PKG_CONFIG=$ac_pt_PKG_CONFIG
-  fi
+WITH_DB4O=$with_db4o
+if test "x$WITH_DB4O" = "xauto"; then
+	if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"db4o >= 8.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "db4o >= 8.0") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  FOUND_DB4O=yes
 else
-  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
-fi
-
+  FOUND_DB4O=no
 fi
-if test -n "$PKG_CONFIG"; then
-	_pkg_min_version=0.9.0
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
-$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
-	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+	if test "x$FOUND_DB4O" = "xyes"; then
+		WITH_DB4O=system
 	else
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-		PKG_CONFIG=""
+		WITH_DB4O=included
 	fi
 fi
-
+if test "x$WITH_DB4O" = "xsystem"; then
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for MONO_MODULE" >&5
-$as_echo_n "checking for MONO_MODULE... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DB4O" >&5
+$as_echo_n "checking for DB4O... " >&6; }
 
-if test -n "$MONO_MODULE_CFLAGS"; then
-    pkg_cv_MONO_MODULE_CFLAGS="$MONO_MODULE_CFLAGS"
+if test -n "$DB4O_CFLAGS"; then
+    pkg_cv_DB4O_CFLAGS="$DB4O_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"mono >= 1.9.1\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "mono >= 1.9.1") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"db4o >= 8.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "db4o >= 8.0") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_MONO_MODULE_CFLAGS=`$PKG_CONFIG --cflags "mono >= 1.9.1" 2>/dev/null`
+  pkg_cv_DB4O_CFLAGS=`$PKG_CONFIG --cflags "db4o >= 8.0" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
  else
     pkg_failed=untried
 fi
-if test -n "$MONO_MODULE_LIBS"; then
-    pkg_cv_MONO_MODULE_LIBS="$MONO_MODULE_LIBS"
+if test -n "$DB4O_LIBS"; then
+    pkg_cv_DB4O_LIBS="$DB4O_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"mono >= 1.9.1\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "mono >= 1.9.1") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"db4o >= 8.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "db4o >= 8.0") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_MONO_MODULE_LIBS=`$PKG_CONFIG --libs "mono >= 1.9.1" 2>/dev/null`
+  pkg_cv_DB4O_LIBS=`$PKG_CONFIG --libs "db4o >= 8.0" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -7078,110 +15196,69 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        MONO_MODULE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "mono >= 1.9.1" 2>&1`
+	        DB4O_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "db4o >= 8.0" 2>&1`
         else
-	        MONO_MODULE_PKG_ERRORS=`$PKG_CONFIG --print-errors "mono >= 1.9.1" 2>&1`
+	        DB4O_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "db4o >= 8.0" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
-	echo "$MONO_MODULE_PKG_ERRORS" >&5
+	echo "$DB4O_PKG_ERRORS" >&5
 
-	as_fn_error "Package requirements (mono >= 1.9.1) were not met:
+	as_fn_error $? "Package requirements (db4o >= 8.0) were not met:
 
-$MONO_MODULE_PKG_ERRORS
+$DB4O_PKG_ERRORS
 
 Consider adjusting the PKG_CONFIG_PATH environment variable if you
 installed software in a non-standard prefix.
 
-Alternatively, you may set the environment variables MONO_MODULE_CFLAGS
-and MONO_MODULE_LIBS to avoid the need to call pkg-config.
+Alternatively, you may set the environment variables DB4O_CFLAGS
+and DB4O_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details." "$LINENO" 5
 elif test $pkg_failed = untried; then
      	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&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 "The pkg-config script could not be found or is too old.  Make sure it
+as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
 is in your PATH or set the PKG_CONFIG environment variable to the full
 path to pkg-config.
 
-Alternatively, you may set the environment variables MONO_MODULE_CFLAGS
-and MONO_MODULE_LIBS to avoid the need to call pkg-config.
+Alternatively, you may set the environment variables DB4O_CFLAGS
+and DB4O_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details.
 
 To get pkg-config, see <http://pkg-config.freedesktop.org/>.
-See \`config.log' for more details." "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5; }
 else
-	MONO_MODULE_CFLAGS=$pkg_cv_MONO_MODULE_CFLAGS
-	MONO_MODULE_LIBS=$pkg_cv_MONO_MODULE_LIBS
+	DB4O_CFLAGS=$pkg_cv_DB4O_CFLAGS
+	DB4O_LIBS=$pkg_cv_DB4O_LIBS
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
 
 fi
-
-
-
-
-	# Extract the first word of "mono", so it can be a program name with args.
-set dummy mono; 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_MONO+set}" = set; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $MONO in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_MONO="$MONO" # 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_MONO="$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
-
-  test -z "$ac_cv_path_MONO" && ac_cv_path_MONO="no"
-  ;;
-esac
-fi
-MONO=$ac_cv_path_MONO
-if test -n "$MONO"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MONO" >&5
-$as_echo "$MONO" >&6; }
+	 if false; then
+  BUNDLE_DB4O_TRUE=
+  BUNDLE_DB4O_FALSE='#'
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  BUNDLE_DB4O_TRUE='#'
+  BUNDLE_DB4O_FALSE=
 fi
 
-
-
-
-	if test "xMONO" = "xno"; then
-		as_fn_error "You need to install 'mono'" "$LINENO" 5
+fi
+if test "x$WITH_DB4O" = "xincluded"; then
+	if test ! -d "$srcdir/lib/db4o-net/Db4objects.Db4o"; then
+		as_fn_error $? "lib/db4o-net is empty!" "$LINENO" 5
 	fi
 
-
-
-
-
-	# Extract the first word of "gmcs", so it can be a program name with args.
-set dummy gmcs; ac_word=$2
+	# Extract the first word of "xbuild", so it can be a program name with args.
+set dummy xbuild; 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_MCS+set}" = set; then :
+if ${ac_cv_path_XBUILD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  case $MCS in
+  case $XBUILD in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_MCS="$MCS" # Let the user override the test with a path.
+  ac_cv_path_XBUILD="$XBUILD" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -7191,7 +15268,7 @@ do
   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_MCS="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_path_XBUILD="$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
@@ -7199,148 +15276,212 @@ done
   done
 IFS=$as_save_IFS
 
-  test -z "$ac_cv_path_MCS" && ac_cv_path_MCS="no"
+  test -z "$ac_cv_path_XBUILD" && ac_cv_path_XBUILD="no"
   ;;
 esac
 fi
-MCS=$ac_cv_path_MCS
-if test -n "$MCS"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MCS" >&5
-$as_echo "$MCS" >&6; }
+XBUILD=$ac_cv_path_XBUILD
+if test -n "$XBUILD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XBUILD" >&5
+$as_echo "$XBUILD" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
 
 
-
-
-	if test "xMCS" = "xno"; then
-		as_fn_error "You need to install 'gmcs'" "$LINENO" 5
+	if test "x$XBUILD" = "xno"; then
+		as_fn_error $? "You need to install xbuild" "$LINENO" 5
 	fi
 
+	 if true; then
+  BUNDLE_DB4O_TRUE=
+  BUNDLE_DB4O_FALSE='#'
+else
+  BUNDLE_DB4O_TRUE='#'
+  BUNDLE_DB4O_FALSE=
+fi
 
+	#AC_SUBST([DB4O_FILES], "Db4objects.Db4o.dll Db4objects.Db4o.Instrumentation.dll Db4objects.Db4o.NativeQueries.dll")
+	DB4O_FILES="Db4objects.Db4o.dll"
 
+fi
 
-	for asm in $(echo "2.0,System
-	System.Core
-	System.Runtime.Remoting
-	Mono.Posix
-" | cut -d, -f2- | sed 's/\,/ /g')
-	do
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Mono 2.0 GAC for $asm.dll" >&5
-$as_echo_n "checking for Mono 2.0 GAC for $asm.dll... " >&6; }
-		if test \
-			-e "$($PKG_CONFIG --variable=libdir mono)/mono/2.0/$asm.dll" -o \
-			-e "$($PKG_CONFIG --variable=prefix mono)/lib/mono/2.0/$asm.dll"; \
-			then \
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
-$as_echo "found" >&6; }
-		else
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-			as_fn_error "missing reqired Mono 2.0 assembly: $asm.dll" "$LINENO" 5
-		fi
-	done
+# Optional Libraries
 
+# Check whether --with-indicate was given.
+if test "${with_indicate+set}" = set; then :
+  withval=$with_indicate;
+else
+  with_indicate=auto
 
+fi
 
-PROFILE=debug
-# Check whether --enable-release was given.
-if test "${enable_release+set}" = set; then :
-  enableval=$enable_release; enable_release=yes
+WITH_INDICATE=$with_indicate
+if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"indicate-sharp-0.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "indicate-sharp-0.1") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  INDICATE_SHARP_SUPPORT=yes
 else
-  enable_release=no
+  INDICATE_SHARP_SUPPORT=no
+fi
+if test "x$WITH_INDICATE" = "xauto"; then
+	WITH_INDICATE=$INDICATE_SHARP_SUPPORT
 fi
+if test "x$WITH_INDICATE" = "xyes"; then
 
- if test x$enable_release = xyes; then
-  ENABLE_RELEASE_TRUE=
-  ENABLE_RELEASE_FALSE='#'
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for INDICATE_SHARP" >&5
+$as_echo_n "checking for INDICATE_SHARP... " >&6; }
+
+if test -n "$INDICATE_SHARP_CFLAGS"; then
+    pkg_cv_INDICATE_SHARP_CFLAGS="$INDICATE_SHARP_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"indicate-sharp-0.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "indicate-sharp-0.1") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_INDICATE_SHARP_CFLAGS=`$PKG_CONFIG --cflags "indicate-sharp-0.1" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
-  ENABLE_RELEASE_TRUE='#'
-  ENABLE_RELEASE_FALSE=
+  pkg_failed=yes
 fi
-
-if test "x$enable_release" = "xyes" ; then
-	PROFILE=release
+ else
+    pkg_failed=untried
 fi
-# Check whether --enable-debug was given.
-if test "${enable_debug+set}" = set; then :
-  enableval=$enable_debug; enable_debug=yes
+if test -n "$INDICATE_SHARP_LIBS"; then
+    pkg_cv_INDICATE_SHARP_LIBS="$INDICATE_SHARP_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"indicate-sharp-0.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "indicate-sharp-0.1") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_INDICATE_SHARP_LIBS=`$PKG_CONFIG --libs "indicate-sharp-0.1" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
-  enable_debug=no
+  pkg_failed=yes
 fi
-
- if test x$enable_debug = xyes; then
-  ENABLE_DEBUG_TRUE=
-  ENABLE_DEBUG_FALSE='#'
-else
-  ENABLE_DEBUG_TRUE='#'
-  ENABLE_DEBUG_FALSE=
+ else
+    pkg_failed=untried
 fi
 
-if test "x$enable_debug" = "xyes" ; then
-	PROFILE=debug
-fi
 
 
-CSC_FLAGS=
-if test "x$PROFILE" = "xdebug"; then
-	 if true; then
-  ENABLE_DEBUG_TRUE=
-  ENABLE_DEBUG_FALSE='#'
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
 else
-  ENABLE_DEBUG_TRUE='#'
-  ENABLE_DEBUG_FALSE=
+        _pkg_short_errors_supported=no
 fi
+        if test $_pkg_short_errors_supported = yes; then
+	        INDICATE_SHARP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "indicate-sharp-0.1" 2>&1`
+        else
+	        INDICATE_SHARP_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "indicate-sharp-0.1" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$INDICATE_SHARP_PKG_ERRORS" >&5
 
-	CSC_FLAGS+=-define:DEBUG,TRACE,LOG4NET
-else
-	 if true; then
-  ENABLE_RELEASE_TRUE=
-  ENABLE_RELEASE_FALSE='#'
+	as_fn_error $? "Package requirements (indicate-sharp-0.1) were not met:
+
+$INDICATE_SHARP_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables INDICATE_SHARP_CFLAGS
+and INDICATE_SHARP_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&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 $? "The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables INDICATE_SHARP_CFLAGS
+and INDICATE_SHARP_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
 else
-  ENABLE_RELEASE_TRUE='#'
-  ENABLE_RELEASE_FALSE=
-fi
+	INDICATE_SHARP_CFLAGS=$pkg_cv_INDICATE_SHARP_CFLAGS
+	INDICATE_SHARP_LIBS=$pkg_cv_INDICATE_SHARP_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 
 fi
-CSC="$MCS"
+fi
 
 
+# Check whether --with-notify was given.
+if test "${with_notify+set}" = set; then :
+  withval=$with_notify;
+else
+  with_notify=auto
 
-# Required Libraries
+fi
+
+WITH_NOTIFY=$with_notify
+if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"notify-sharp\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "notify-sharp") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  NOTIFY_SHARP_SUPPORT=yes
+else
+  NOTIFY_SHARP_SUPPORT=no
+fi
+if test "x$WITH_NOTIFY" = "xauto"; then
+	WITH_NOTIFY=$NOTIFY_SHARP_SUPPORT
+fi
+if test "x$WITH_NOTIFY" = "xyes"; then
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LOG4NET" >&5
-$as_echo_n "checking for LOG4NET... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NOTIFY_SHARP" >&5
+$as_echo_n "checking for NOTIFY_SHARP... " >&6; }
 
-if test -n "$LOG4NET_CFLAGS"; then
-    pkg_cv_LOG4NET_CFLAGS="$LOG4NET_CFLAGS"
+if test -n "$NOTIFY_SHARP_CFLAGS"; then
+    pkg_cv_NOTIFY_SHARP_CFLAGS="$NOTIFY_SHARP_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"log4net\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "log4net") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"notify-sharp\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "notify-sharp") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_LOG4NET_CFLAGS=`$PKG_CONFIG --cflags "log4net" 2>/dev/null`
+  pkg_cv_NOTIFY_SHARP_CFLAGS=`$PKG_CONFIG --cflags "notify-sharp" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
  else
     pkg_failed=untried
 fi
-if test -n "$LOG4NET_LIBS"; then
-    pkg_cv_LOG4NET_LIBS="$LOG4NET_LIBS"
+if test -n "$NOTIFY_SHARP_LIBS"; then
+    pkg_cv_NOTIFY_SHARP_LIBS="$NOTIFY_SHARP_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"log4net\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "log4net") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"notify-sharp\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "notify-sharp") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_LOG4NET_LIBS=`$PKG_CONFIG --libs "log4net" 2>/dev/null`
+  pkg_cv_NOTIFY_SHARP_LIBS=`$PKG_CONFIG --libs "notify-sharp" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -7360,99 +15501,119 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        LOG4NET_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "log4net" 2>&1`
+	        NOTIFY_SHARP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "notify-sharp" 2>&1`
         else
-	        LOG4NET_PKG_ERRORS=`$PKG_CONFIG --print-errors "log4net" 2>&1`
+	        NOTIFY_SHARP_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "notify-sharp" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
-	echo "$LOG4NET_PKG_ERRORS" >&5
+	echo "$NOTIFY_SHARP_PKG_ERRORS" >&5
 
-	as_fn_error "Package requirements (log4net) were not met:
+	as_fn_error $? "Package requirements (notify-sharp) were not met:
 
-$LOG4NET_PKG_ERRORS
+$NOTIFY_SHARP_PKG_ERRORS
 
 Consider adjusting the PKG_CONFIG_PATH environment variable if you
 installed software in a non-standard prefix.
 
-Alternatively, you may set the environment variables LOG4NET_CFLAGS
-and LOG4NET_LIBS to avoid the need to call pkg-config.
+Alternatively, you may set the environment variables NOTIFY_SHARP_CFLAGS
+and NOTIFY_SHARP_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details." "$LINENO" 5
 elif test $pkg_failed = untried; then
      	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&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 "The pkg-config script could not be found or is too old.  Make sure it
+as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
 is in your PATH or set the PKG_CONFIG environment variable to the full
 path to pkg-config.
 
-Alternatively, you may set the environment variables LOG4NET_CFLAGS
-and LOG4NET_LIBS to avoid the need to call pkg-config.
+Alternatively, you may set the environment variables NOTIFY_SHARP_CFLAGS
+and NOTIFY_SHARP_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details.
 
 To get pkg-config, see <http://pkg-config.freedesktop.org/>.
-See \`config.log' for more details." "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5; }
 else
-	LOG4NET_CFLAGS=$pkg_cv_LOG4NET_CFLAGS
-	LOG4NET_LIBS=$pkg_cv_LOG4NET_LIBS
+	NOTIFY_SHARP_CFLAGS=$pkg_cv_NOTIFY_SHARP_CFLAGS
+	NOTIFY_SHARP_LIBS=$pkg_cv_NOTIFY_SHARP_LIBS
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
 
 fi
+fi
+
+
+# Check whether --with-dbus was given.
+if test "${with_dbus+set}" = set; then :
+  withval=$with_dbus;
+else
+  with_dbus=auto
+
+fi
 
+WITH_DBUS=$with_dbus
 if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"nini-1.1\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "nini-1.1") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-sharp-1.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "dbus-sharp-1.0") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  FOUND_NINI=yes
+  DBUS_SHARP_SUPPORT=yes
 else
-  FOUND_NINI=no
+  DBUS_SHARP_SUPPORT=no
 fi
-if test "x$FOUND_NINI" = "xyes"; then
-	nini_files=`pkg-config --variable=Libraries nini-1.1`
-	 if test -n "$nini_files"; then
-  BUNDLE_NINI_TRUE=
-  BUNDLE_NINI_FALSE='#'
+if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ndesk-dbus-1.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "ndesk-dbus-1.0") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  NDESK_DBUS_SUPPORT=yes
 else
-  BUNDLE_NINI_TRUE='#'
-  BUNDLE_NINI_FALSE=
+  NDESK_DBUS_SUPPORT=no
 fi
-
-	if test -z "$nini_files" ; then
-		# Debian-based distros place Nini into the GAC
+if test "x$WITH_DBUS" = "xauto"; then
+	if test "x$DBUS_SHARP_SUPPORT" = "xyes"; then
+		WITH_DBUS=$DBUS_SHARP_SUPPORT
+	else
+		WITH_DBUS=$NDESK_DBUS_SUPPORT
+	fi
+fi
+if test "x$WITH_DBUS" = "xyes"; then
+	if test "x$DBUS_SHARP_SUPPORT" = "xyes"; then
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NINI" >&5
-$as_echo_n "checking for NINI... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DBUS_SHARP" >&5
+$as_echo_n "checking for DBUS_SHARP... " >&6; }
 
-if test -n "$NINI_CFLAGS"; then
-    pkg_cv_NINI_CFLAGS="$NINI_CFLAGS"
+if test -n "$DBUS_SHARP_CFLAGS"; then
+    pkg_cv_DBUS_SHARP_CFLAGS="$DBUS_SHARP_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"nini-1.1\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "nini-1.1") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-sharp-1.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "dbus-sharp-1.0") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_NINI_CFLAGS=`$PKG_CONFIG --cflags "nini-1.1" 2>/dev/null`
+  pkg_cv_DBUS_SHARP_CFLAGS=`$PKG_CONFIG --cflags "dbus-sharp-1.0" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
  else
     pkg_failed=untried
 fi
-if test -n "$NINI_LIBS"; then
-    pkg_cv_NINI_LIBS="$NINI_LIBS"
+if test -n "$DBUS_SHARP_LIBS"; then
+    pkg_cv_DBUS_SHARP_LIBS="$DBUS_SHARP_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"nini-1.1\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "nini-1.1") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-sharp-1.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "dbus-sharp-1.0") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_NINI_LIBS=`$PKG_CONFIG --libs "nini-1.1" 2>/dev/null`
+  pkg_cv_DBUS_SHARP_LIBS=`$PKG_CONFIG --libs "dbus-sharp-1.0" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -7472,82 +15633,78 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        NINI_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "nini-1.1" 2>&1`
+	        DBUS_SHARP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "dbus-sharp-1.0" 2>&1`
         else
-	        NINI_PKG_ERRORS=`$PKG_CONFIG --print-errors "nini-1.1" 2>&1`
+	        DBUS_SHARP_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "dbus-sharp-1.0" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
-	echo "$NINI_PKG_ERRORS" >&5
+	echo "$DBUS_SHARP_PKG_ERRORS" >&5
 
-	as_fn_error "Package requirements (nini-1.1) were not met:
+	as_fn_error $? "Package requirements (dbus-sharp-1.0) were not met:
 
-$NINI_PKG_ERRORS
+$DBUS_SHARP_PKG_ERRORS
 
 Consider adjusting the PKG_CONFIG_PATH environment variable if you
 installed software in a non-standard prefix.
 
-Alternatively, you may set the environment variables NINI_CFLAGS
-and NINI_LIBS to avoid the need to call pkg-config.
+Alternatively, you may set the environment variables DBUS_SHARP_CFLAGS
+and DBUS_SHARP_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details." "$LINENO" 5
 elif test $pkg_failed = untried; then
      	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&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 "The pkg-config script could not be found or is too old.  Make sure it
+as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
 is in your PATH or set the PKG_CONFIG environment variable to the full
 path to pkg-config.
 
-Alternatively, you may set the environment variables NINI_CFLAGS
-and NINI_LIBS to avoid the need to call pkg-config.
+Alternatively, you may set the environment variables DBUS_SHARP_CFLAGS
+and DBUS_SHARP_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details.
 
 To get pkg-config, see <http://pkg-config.freedesktop.org/>.
-See \`config.log' for more details." "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5; }
 else
-	NINI_CFLAGS=$pkg_cv_NINI_CFLAGS
-	NINI_LIBS=$pkg_cv_NINI_LIBS
+	DBUS_SHARP_CFLAGS=$pkg_cv_DBUS_SHARP_CFLAGS
+	DBUS_SHARP_LIBS=$pkg_cv_DBUS_SHARP_LIBS
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
 
 fi
-	else
-		# openSUSE has Nini as a private assembly; need to copy it.
-		NINI_LIBS="$nini_files"
-
-	fi
-else
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NINI" >&5
-$as_echo_n "checking for NINI... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DBUS_SHARP_GLIB" >&5
+$as_echo_n "checking for DBUS_SHARP_GLIB... " >&6; }
 
-if test -n "$NINI_CFLAGS"; then
-    pkg_cv_NINI_CFLAGS="$NINI_CFLAGS"
+if test -n "$DBUS_SHARP_GLIB_CFLAGS"; then
+    pkg_cv_DBUS_SHARP_GLIB_CFLAGS="$DBUS_SHARP_GLIB_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"nini >= 1.1\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "nini >= 1.1") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-sharp-glib-1.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "dbus-sharp-glib-1.0") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_NINI_CFLAGS=`$PKG_CONFIG --cflags "nini >= 1.1" 2>/dev/null`
+  pkg_cv_DBUS_SHARP_GLIB_CFLAGS=`$PKG_CONFIG --cflags "dbus-sharp-glib-1.0" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
  else
     pkg_failed=untried
 fi
-if test -n "$NINI_LIBS"; then
-    pkg_cv_NINI_LIBS="$NINI_LIBS"
+if test -n "$DBUS_SHARP_GLIB_LIBS"; then
+    pkg_cv_DBUS_SHARP_GLIB_LIBS="$DBUS_SHARP_GLIB_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"nini >= 1.1\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "nini >= 1.1") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-sharp-glib-1.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "dbus-sharp-glib-1.0") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_NINI_LIBS=`$PKG_CONFIG --libs "nini >= 1.1" 2>/dev/null`
+  pkg_cv_DBUS_SHARP_GLIB_LIBS=`$PKG_CONFIG --libs "dbus-sharp-glib-1.0" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -7567,103 +15724,83 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        NINI_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "nini >= 1.1" 2>&1`
+	        DBUS_SHARP_GLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "dbus-sharp-glib-1.0" 2>&1`
         else
-	        NINI_PKG_ERRORS=`$PKG_CONFIG --print-errors "nini >= 1.1" 2>&1`
+	        DBUS_SHARP_GLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "dbus-sharp-glib-1.0" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
-	echo "$NINI_PKG_ERRORS" >&5
+	echo "$DBUS_SHARP_GLIB_PKG_ERRORS" >&5
 
-	as_fn_error "Package requirements (nini >= 1.1) were not met:
+	as_fn_error $? "Package requirements (dbus-sharp-glib-1.0) were not met:
 
-$NINI_PKG_ERRORS
+$DBUS_SHARP_GLIB_PKG_ERRORS
 
 Consider adjusting the PKG_CONFIG_PATH environment variable if you
 installed software in a non-standard prefix.
 
-Alternatively, you may set the environment variables NINI_CFLAGS
-and NINI_LIBS to avoid the need to call pkg-config.
+Alternatively, you may set the environment variables DBUS_SHARP_GLIB_CFLAGS
+and DBUS_SHARP_GLIB_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details." "$LINENO" 5
 elif test $pkg_failed = untried; then
      	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&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 "The pkg-config script could not be found or is too old.  Make sure it
+as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
 is in your PATH or set the PKG_CONFIG environment variable to the full
 path to pkg-config.
 
-Alternatively, you may set the environment variables NINI_CFLAGS
-and NINI_LIBS to avoid the need to call pkg-config.
+Alternatively, you may set the environment variables DBUS_SHARP_GLIB_CFLAGS
+and DBUS_SHARP_GLIB_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details.
 
 To get pkg-config, see <http://pkg-config.freedesktop.org/>.
-See \`config.log' for more details." "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5; }
 else
-	NINI_CFLAGS=$pkg_cv_NINI_CFLAGS
-	NINI_LIBS=$pkg_cv_NINI_LIBS
+	DBUS_SHARP_GLIB_CFLAGS=$pkg_cv_DBUS_SHARP_GLIB_CFLAGS
+	DBUS_SHARP_GLIB_LIBS=$pkg_cv_DBUS_SHARP_GLIB_LIBS
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
 
 fi
-fi
-
-# Optional Libraries
-
-# Check whether --with-indicate was given.
-if test "${with_indicate+set}" = set; then :
-  withval=$with_indicate;
-else
-  with_indicate=auto
-
-fi
+		DBUS_LIBS="$DBUS_SHARP_LIBS $DBUS_SHARP_GLIB_LIBS"
 
-WITH_INDICATE=$with_indicate
-if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"indicate-sharp-0.1\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "indicate-sharp-0.1") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then
-  INDICATE_SHARP_SUPPORT=yes
-else
-  INDICATE_SHARP_SUPPORT=no
-fi
-if test "x$WITH_INDICATE" = "xauto"; then
-	WITH_INDICATE=$INDICATE_SHARP_SUPPORT
-fi
-if test "x$WITH_INDICATE" = "xyes"; then
+		CSC_FLAGS+=" -define:IPC_DBUS -define:DBUS_SHARP"
+	else
+		# fallback to ndesk-dbus
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for INDICATE_SHARP" >&5
-$as_echo_n "checking for INDICATE_SHARP... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NDESK_DBUS" >&5
+$as_echo_n "checking for NDESK_DBUS... " >&6; }
 
-if test -n "$INDICATE_SHARP_CFLAGS"; then
-    pkg_cv_INDICATE_SHARP_CFLAGS="$INDICATE_SHARP_CFLAGS"
+if test -n "$NDESK_DBUS_CFLAGS"; then
+    pkg_cv_NDESK_DBUS_CFLAGS="$NDESK_DBUS_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"indicate-sharp-0.1\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "indicate-sharp-0.1") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ndesk-dbus-1.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "ndesk-dbus-1.0") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_INDICATE_SHARP_CFLAGS=`$PKG_CONFIG --cflags "indicate-sharp-0.1" 2>/dev/null`
+  pkg_cv_NDESK_DBUS_CFLAGS=`$PKG_CONFIG --cflags "ndesk-dbus-1.0" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
  else
     pkg_failed=untried
 fi
-if test -n "$INDICATE_SHARP_LIBS"; then
-    pkg_cv_INDICATE_SHARP_LIBS="$INDICATE_SHARP_LIBS"
+if test -n "$NDESK_DBUS_LIBS"; then
+    pkg_cv_NDESK_DBUS_LIBS="$NDESK_DBUS_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"indicate-sharp-0.1\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "indicate-sharp-0.1") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ndesk-dbus-1.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "ndesk-dbus-1.0") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_INDICATE_SHARP_LIBS=`$PKG_CONFIG --libs "indicate-sharp-0.1" 2>/dev/null`
+  pkg_cv_NDESK_DBUS_LIBS=`$PKG_CONFIG --libs "ndesk-dbus-1.0" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -7683,102 +15820,78 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        INDICATE_SHARP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "indicate-sharp-0.1" 2>&1`
+	        NDESK_DBUS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ndesk-dbus-1.0" 2>&1`
         else
-	        INDICATE_SHARP_PKG_ERRORS=`$PKG_CONFIG --print-errors "indicate-sharp-0.1" 2>&1`
+	        NDESK_DBUS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ndesk-dbus-1.0" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
-	echo "$INDICATE_SHARP_PKG_ERRORS" >&5
+	echo "$NDESK_DBUS_PKG_ERRORS" >&5
 
-	as_fn_error "Package requirements (indicate-sharp-0.1) were not met:
+	as_fn_error $? "Package requirements (ndesk-dbus-1.0) were not met:
 
-$INDICATE_SHARP_PKG_ERRORS
+$NDESK_DBUS_PKG_ERRORS
 
 Consider adjusting the PKG_CONFIG_PATH environment variable if you
 installed software in a non-standard prefix.
 
-Alternatively, you may set the environment variables INDICATE_SHARP_CFLAGS
-and INDICATE_SHARP_LIBS to avoid the need to call pkg-config.
+Alternatively, you may set the environment variables NDESK_DBUS_CFLAGS
+and NDESK_DBUS_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details." "$LINENO" 5
 elif test $pkg_failed = untried; then
      	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&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 "The pkg-config script could not be found or is too old.  Make sure it
+as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
 is in your PATH or set the PKG_CONFIG environment variable to the full
 path to pkg-config.
 
-Alternatively, you may set the environment variables INDICATE_SHARP_CFLAGS
-and INDICATE_SHARP_LIBS to avoid the need to call pkg-config.
+Alternatively, you may set the environment variables NDESK_DBUS_CFLAGS
+and NDESK_DBUS_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details.
 
 To get pkg-config, see <http://pkg-config.freedesktop.org/>.
-See \`config.log' for more details." "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5; }
 else
-	INDICATE_SHARP_CFLAGS=$pkg_cv_INDICATE_SHARP_CFLAGS
-	INDICATE_SHARP_LIBS=$pkg_cv_INDICATE_SHARP_LIBS
+	NDESK_DBUS_CFLAGS=$pkg_cv_NDESK_DBUS_CFLAGS
+	NDESK_DBUS_LIBS=$pkg_cv_NDESK_DBUS_LIBS
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
 
 fi
-fi
-
-
-# Check whether --with-notify was given.
-if test "${with_notify+set}" = set; then :
-  withval=$with_notify;
-else
-  with_notify=auto
-
-fi
-
-WITH_NOTIFY=$with_notify
-if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"notify-sharp\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "notify-sharp") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then
-  NOTIFY_SHARP_SUPPORT=yes
-else
-  NOTIFY_SHARP_SUPPORT=no
-fi
-if test "x$WITH_NOTIFY" = "xauto"; then
-	WITH_NOTIFY=$NOTIFY_SHARP_SUPPORT
-fi
-if test "x$WITH_NOTIFY" = "xyes"; then
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NOTIFY_SHARP" >&5
-$as_echo_n "checking for NOTIFY_SHARP... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NDESK_DBUS_GLIB" >&5
+$as_echo_n "checking for NDESK_DBUS_GLIB... " >&6; }
 
-if test -n "$NOTIFY_SHARP_CFLAGS"; then
-    pkg_cv_NOTIFY_SHARP_CFLAGS="$NOTIFY_SHARP_CFLAGS"
+if test -n "$NDESK_DBUS_GLIB_CFLAGS"; then
+    pkg_cv_NDESK_DBUS_GLIB_CFLAGS="$NDESK_DBUS_GLIB_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"notify-sharp\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "notify-sharp") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ndesk-dbus-glib-1.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "ndesk-dbus-glib-1.0") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_NOTIFY_SHARP_CFLAGS=`$PKG_CONFIG --cflags "notify-sharp" 2>/dev/null`
+  pkg_cv_NDESK_DBUS_GLIB_CFLAGS=`$PKG_CONFIG --cflags "ndesk-dbus-glib-1.0" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
  else
     pkg_failed=untried
 fi
-if test -n "$NOTIFY_SHARP_LIBS"; then
-    pkg_cv_NOTIFY_SHARP_LIBS="$NOTIFY_SHARP_LIBS"
+if test -n "$NDESK_DBUS_GLIB_LIBS"; then
+    pkg_cv_NDESK_DBUS_GLIB_LIBS="$NDESK_DBUS_GLIB_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"notify-sharp\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "notify-sharp") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ndesk-dbus-glib-1.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "ndesk-dbus-glib-1.0") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_NOTIFY_SHARP_LIBS=`$PKG_CONFIG --libs "notify-sharp" 2>/dev/null`
+  pkg_cv_NDESK_DBUS_GLIB_LIBS=`$PKG_CONFIG --libs "ndesk-dbus-glib-1.0" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -7798,45 +15911,49 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        NOTIFY_SHARP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "notify-sharp" 2>&1`
+	        NDESK_DBUS_GLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ndesk-dbus-glib-1.0" 2>&1`
         else
-	        NOTIFY_SHARP_PKG_ERRORS=`$PKG_CONFIG --print-errors "notify-sharp" 2>&1`
+	        NDESK_DBUS_GLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ndesk-dbus-glib-1.0" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
-	echo "$NOTIFY_SHARP_PKG_ERRORS" >&5
+	echo "$NDESK_DBUS_GLIB_PKG_ERRORS" >&5
 
-	as_fn_error "Package requirements (notify-sharp) were not met:
+	as_fn_error $? "Package requirements (ndesk-dbus-glib-1.0) were not met:
 
-$NOTIFY_SHARP_PKG_ERRORS
+$NDESK_DBUS_GLIB_PKG_ERRORS
 
 Consider adjusting the PKG_CONFIG_PATH environment variable if you
 installed software in a non-standard prefix.
 
-Alternatively, you may set the environment variables NOTIFY_SHARP_CFLAGS
-and NOTIFY_SHARP_LIBS to avoid the need to call pkg-config.
+Alternatively, you may set the environment variables NDESK_DBUS_GLIB_CFLAGS
+and NDESK_DBUS_GLIB_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details." "$LINENO" 5
 elif test $pkg_failed = untried; then
      	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&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 "The pkg-config script could not be found or is too old.  Make sure it
+as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
 is in your PATH or set the PKG_CONFIG environment variable to the full
 path to pkg-config.
 
-Alternatively, you may set the environment variables NOTIFY_SHARP_CFLAGS
-and NOTIFY_SHARP_LIBS to avoid the need to call pkg-config.
+Alternatively, you may set the environment variables NDESK_DBUS_GLIB_CFLAGS
+and NDESK_DBUS_GLIB_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details.
 
 To get pkg-config, see <http://pkg-config.freedesktop.org/>.
-See \`config.log' for more details." "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5; }
 else
-	NOTIFY_SHARP_CFLAGS=$pkg_cv_NOTIFY_SHARP_CFLAGS
-	NOTIFY_SHARP_LIBS=$pkg_cv_NOTIFY_SHARP_LIBS
+	NDESK_DBUS_GLIB_CFLAGS=$pkg_cv_NDESK_DBUS_GLIB_CFLAGS
+	NDESK_DBUS_GLIB_LIBS=$pkg_cv_NDESK_DBUS_GLIB_LIBS
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
 
 fi
+		DBUS_LIBS="$NDESK_DBUS_LIBS $NDESK_DBUS_GLIB_LIBS"
+
+		CSC_FLAGS+=" -define:IPC_DBUS -define:NDESK_DBUS"
+	fi
 fi
 
 # Engines
@@ -7850,7 +15967,7 @@ fi
 
 if test "x$ENABLE_ENGINE_IRC" != "xno"; then
 	if test ! -f "$srcdir/lib/SmartIrc4net/configure.ac"; then
-		as_fn_error "lib/SmartIrc4net not found" "$LINENO" 5
+		as_fn_error $? "lib/SmartIrc4net is empty!" "$LINENO" 5
 	fi
 	ac_configure_args="$ac_configure_args --disable-pkg-config --disable-pkg-lib --disable-pkg-gac"
 
@@ -7893,6 +16010,7 @@ if test -n "$OSCARLIB_CFLAGS"; then
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_OSCARLIB_CFLAGS=`$PKG_CONFIG --cflags "oscarlib" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -7909,6 +16027,7 @@ if test -n "$OSCARLIB_LIBS"; then
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_OSCARLIB_LIBS=`$PKG_CONFIG --libs "oscarlib" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -7928,9 +16047,9 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        OSCARLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "oscarlib" 2>&1`
+	        OSCARLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "oscarlib" 2>&1`
         else
-	        OSCARLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors "oscarlib" 2>&1`
+	        OSCARLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "oscarlib" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$OSCARLIB_PKG_ERRORS" >&5
@@ -7949,7 +16068,7 @@ $as_echo "yes" >&6; }
 fi
 
 	if test "x$ENABLE_ENGINE_OSCAR" = "xyes" -a "x$OSCAR_ENGINE_SUPPORT" != "xyes"; then
-		as_fn_error "OscarLib not found" "$LINENO" 5
+		as_fn_error $? "OscarLib not found" "$LINENO" 5
 	else
 		ENABLE_ENGINE_OSCARC=$OSCAR_SUPPORT
 	fi
@@ -7967,86 +16086,82 @@ fi
 if test "${enable_engine_xmpp+set}" = set; then :
   enableval=$enable_engine_xmpp; ENABLE_ENGINE_XMPP=$enableval
 else
-  ENABLE_ENGINE_XMPP=no
+  ENABLE_ENGINE_XMPP=yes
 
 fi
 
 if test "x$ENABLE_ENGINE_XMPP" != "xno"; then
-
-pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for JABBER_NET" >&5
-$as_echo_n "checking for JABBER_NET... " >&6; }
-
-if test -n "$JABBER_NET_CFLAGS"; then
-    pkg_cv_JABBER_NET_CFLAGS="$JABBER_NET_CFLAGS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"jabber-net\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "jabber-net") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then
-  pkg_cv_JABBER_NET_CFLAGS=`$PKG_CONFIG --cflags "jabber-net" 2>/dev/null`
+	# Extract the first word of "xbuild", so it can be a program name with args.
+set dummy xbuild; 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_XBUILD+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  pkg_failed=yes
-fi
- else
-    pkg_failed=untried
+  case $XBUILD in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_XBUILD="$XBUILD" # 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_XBUILD="$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
+
+  test -z "$ac_cv_path_XBUILD" && ac_cv_path_XBUILD="no"
+  ;;
+esac
 fi
-if test -n "$JABBER_NET_LIBS"; then
-    pkg_cv_JABBER_NET_LIBS="$JABBER_NET_LIBS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"jabber-net\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "jabber-net") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then
-  pkg_cv_JABBER_NET_LIBS=`$PKG_CONFIG --libs "jabber-net" 2>/dev/null`
+XBUILD=$ac_cv_path_XBUILD
+if test -n "$XBUILD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XBUILD" >&5
+$as_echo "$XBUILD" >&6; }
 else
-  pkg_failed=yes
-fi
- else
-    pkg_failed=untried
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
 
+	if test "x$XBUILD" = "xno"; then
+		as_fn_error $? "You need to install xbuild for XMPP support" "$LINENO" 5
+	fi
 
-if test $pkg_failed = yes; then
-   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+	if test ! -f "$srcdir/lib/jabber-net/2005-jabber-net.csproj"; then
+		as_fn_error $? "lib/jabber-net is empty!" "$LINENO" 5
+	fi
 
-if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
-        _pkg_short_errors_supported=yes
-else
-        _pkg_short_errors_supported=no
-fi
-        if test $_pkg_short_errors_supported = yes; then
-	        JABBER_NET_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "jabber-net" 2>&1`
-        else
-	        JABBER_NET_PKG_ERRORS=`$PKG_CONFIG --print-errors "jabber-net" 2>&1`
-        fi
-	# Put the nasty error message in config.log where it belongs
-	echo "$JABBER_NET_PKG_ERRORS" >&5
 
-	XMPP_SUPPORT=no
-elif test $pkg_failed = untried; then
-     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-	XMPP_SUPPORT=no
-else
-	JABBER_NET_CFLAGS=$pkg_cv_JABBER_NET_CFLAGS
-	JABBER_NET_LIBS=$pkg_cv_JABBER_NET_LIBS
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-	XMPP_SUPPORT=yes
-fi
+	for asm in $(echo "2.0,System
+		System.Drawing
+		System.Xml
+	" | cut -d, -f2- | sed 's/\,/ /g')
+	do
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Mono 2.0 GAC for $asm.dll" >&5
+$as_echo_n "checking for Mono 2.0 GAC for $asm.dll... " >&6; }
+		if test \
+			-e "$($PKG_CONFIG --variable=libdir mono)/mono/2.0/$asm.dll" -o \
+			-e "$($PKG_CONFIG --variable=prefix mono)/lib/mono/2.0/$asm.dll"; \
+			then \
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
+$as_echo "found" >&6; }
+		else
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+			as_fn_error $? "missing reqired Mono 2.0 assembly: $asm.dll" "$LINENO" 5
+		fi
+	done
+
 
-	if test "x$ENABLE_ENGINE_XMPP" = "xyes" -a "x$XMPP_SUPPORT" != "xyes"; then
-		as_fn_error "jabber-net not found" "$LINENO" 5
-	else
-		ENABLE_ENGINE_XMPP=$XMPP_SUPPORT
-	fi
 fi
  if test "x$ENABLE_ENGINE_XMPP" = "xyes"; then
   ENABLE_ENGINE_XMPP_TRUE=
@@ -8081,6 +16196,7 @@ if test -n "$MSNPSHARP_CFLAGS"; then
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_MSNPSHARP_CFLAGS=`$PKG_CONFIG --cflags "msnp-sharp" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -8097,6 +16213,7 @@ if test -n "$MSNPSHARP_LIBS"; then
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_MSNPSHARP_LIBS=`$PKG_CONFIG --libs "msnp-sharp" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -8116,9 +16233,9 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        MSNPSHARP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "msnp-sharp" 2>&1`
+	        MSNPSHARP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "msnp-sharp" 2>&1`
         else
-	        MSNPSHARP_PKG_ERRORS=`$PKG_CONFIG --print-errors "msnp-sharp" 2>&1`
+	        MSNPSHARP_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "msnp-sharp" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$MSNPSHARP_PKG_ERRORS" >&5
@@ -8137,7 +16254,7 @@ $as_echo "yes" >&6; }
 fi
 
 	if test "x$ENABLE_ENGINE_MSNP" = "xyes" -a "x$MSNP_SUPPORT" != "xyes"; then
-		as_fn_error "MSNPSharp not found" "$LINENO" 5
+		as_fn_error $? "MSNPSharp not found" "$LINENO" 5
 	else
 		ENABLE_ENGINE_MSNP=$MSNP_SUPPORT
 	fi
@@ -8164,7 +16281,7 @@ if test "x$ENABLE_ENGINE_TWITTER" != "xno"; then
 set dummy xbuild; 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_XBUILD+set}" = set; then :
+if ${ac_cv_path_XBUILD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $XBUILD in
@@ -8202,7 +16319,7 @@ fi
 
 
 	if test "x$XBUILD" = "xno"; then
-		as_fn_error "You need to install xbuild for Twitter support" "$LINENO" 5
+		as_fn_error $? "You need to install xbuild for Twitter support" "$LINENO" 5
 	fi
 
 	# compiling Json.NET with the C# compiler of Mono 2.4 will result in
@@ -8215,11 +16332,11 @@ $as_echo "yes" >&6; }
 	else
 		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-		as_fn_error "You need Mono 2.6 or later for Twitter support" "$LINENO" 5
+		as_fn_error $? "You need Mono 2.6 or later for Twitter support" "$LINENO" 5
 	fi
 
 	if test ! -f "$srcdir/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Newtonsoft.Json.csproj"; then
-		as_fn_error "lib/Newtonsoft.Json is empty! Used git submodule init; git submodule update?" "$LINENO" 5
+		as_fn_error $? "lib/Newtonsoft.Json is empty!" "$LINENO" 5
 	fi
 
 
@@ -8243,14 +16360,14 @@ $as_echo "found" >&6; }
 		else
 			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
 $as_echo "not found" >&6; }
-			as_fn_error "missing reqired Mono 2.0 assembly: $asm.dll" "$LINENO" 5
+			as_fn_error $? "missing reqired Mono 2.0 assembly: $asm.dll" "$LINENO" 5
 		fi
 	done
 
 
 
 	if test ! -f "$srcdir/lib/Twitterizer/Twitterizer2/Twitterizer2.csproj"; then
-		as_fn_error "lib/Twitterizer is empty! Used git submodule init; git submodule update?" "$LINENO" 5
+		as_fn_error $? "lib/Twitterizer is empty!" "$LINENO" 5
 	fi
 
 
@@ -8276,7 +16393,7 @@ $as_echo "found" >&6; }
 		else
 			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
 $as_echo "not found" >&6; }
-			as_fn_error "missing reqired Mono 2.0 assembly: $asm.dll" "$LINENO" 5
+			as_fn_error $? "missing reqired Mono 2.0 assembly: $asm.dll" "$LINENO" 5
 		fi
 	done
 
@@ -8295,13 +16412,19 @@ fi
 if test "${with_twitter_api_key+set}" = set; then :
   withval=$with_twitter_api_key;
 else
-  with_twitter_api_key="G0fxRfJqvcMPAuNat15YQ|j77MQDIuZJFa0CXehYzGPBZidF8DT3OXAi6sb5ucE"
+  with_twitter_api_key="60QV2qQx9cS7y1BJDbgAA|2VgD6qQKddsF5HYQ0TrRgs3tFTnCwDONBmRlTmG658"
 
 fi
 
 twitter_api_key=$with_twitter_api_key
 
 
+# Server
+if $PKG_CONFIG 'mono >= 2.6'; then
+	SERVER_COMPILER_FLAGS+=" -platform:x86"
+fi
+
+
 # Frontends
 # Check whether --enable-frontend-gnome was given.
 if test "${enable_frontend_gnome+set}" = set; then :
@@ -8327,6 +16450,7 @@ if test -n "$GLIB_SHARP_20_CFLAGS"; then
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_GLIB_SHARP_20_CFLAGS=`$PKG_CONFIG --cflags "glib-sharp-2.0 >= 2.8" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -8343,6 +16467,7 @@ if test -n "$GLIB_SHARP_20_LIBS"; then
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_GLIB_SHARP_20_LIBS=`$PKG_CONFIG --libs "glib-sharp-2.0 >= 2.8" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -8362,14 +16487,14 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        GLIB_SHARP_20_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "glib-sharp-2.0 >= 2.8" 2>&1`
+	        GLIB_SHARP_20_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "glib-sharp-2.0 >= 2.8" 2>&1`
         else
-	        GLIB_SHARP_20_PKG_ERRORS=`$PKG_CONFIG --print-errors "glib-sharp-2.0 >= 2.8" 2>&1`
+	        GLIB_SHARP_20_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "glib-sharp-2.0 >= 2.8" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$GLIB_SHARP_20_PKG_ERRORS" >&5
 
-	as_fn_error "Package requirements (glib-sharp-2.0 >= 2.8) were not met:
+	as_fn_error $? "Package requirements (glib-sharp-2.0 >= 2.8) were not met:
 
 $GLIB_SHARP_20_PKG_ERRORS
 
@@ -8384,7 +16509,7 @@ elif test $pkg_failed = untried; then
 $as_echo "no" >&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 "The pkg-config script could not be found or is too old.  Make sure it
+as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
 is in your PATH or set the PKG_CONFIG environment variable to the full
 path to pkg-config.
 
@@ -8393,7 +16518,7 @@ and GLIB_SHARP_20_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details.
 
 To get pkg-config, see <http://pkg-config.freedesktop.org/>.
-See \`config.log' for more details." "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5; }
 else
 	GLIB_SHARP_20_CFLAGS=$pkg_cv_GLIB_SHARP_20_CFLAGS
 	GLIB_SHARP_20_LIBS=$pkg_cv_GLIB_SHARP_20_LIBS
@@ -8416,6 +16541,7 @@ if test -n "$GTK_SHARP_20_CFLAGS"; then
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_GTK_SHARP_20_CFLAGS=`$PKG_CONFIG --cflags "gtk-sharp-2.0 >= 2.8" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -8432,6 +16558,7 @@ if test -n "$GTK_SHARP_20_LIBS"; then
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_GTK_SHARP_20_LIBS=`$PKG_CONFIG --libs "gtk-sharp-2.0 >= 2.8" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -8451,14 +16578,14 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        GTK_SHARP_20_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "gtk-sharp-2.0 >= 2.8" 2>&1`
+	        GTK_SHARP_20_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk-sharp-2.0 >= 2.8" 2>&1`
         else
-	        GTK_SHARP_20_PKG_ERRORS=`$PKG_CONFIG --print-errors "gtk-sharp-2.0 >= 2.8" 2>&1`
+	        GTK_SHARP_20_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk-sharp-2.0 >= 2.8" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$GTK_SHARP_20_PKG_ERRORS" >&5
 
-	as_fn_error "Package requirements (gtk-sharp-2.0 >= 2.8) were not met:
+	as_fn_error $? "Package requirements (gtk-sharp-2.0 >= 2.8) were not met:
 
 $GTK_SHARP_20_PKG_ERRORS
 
@@ -8473,7 +16600,7 @@ elif test $pkg_failed = untried; then
 $as_echo "no" >&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 "The pkg-config script could not be found or is too old.  Make sure it
+as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
 is in your PATH or set the PKG_CONFIG environment variable to the full
 path to pkg-config.
 
@@ -8482,7 +16609,7 @@ and GTK_SHARP_20_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details.
 
 To get pkg-config, see <http://pkg-config.freedesktop.org/>.
-See \`config.log' for more details." "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5; }
 else
 	GTK_SHARP_20_CFLAGS=$pkg_cv_GTK_SHARP_20_CFLAGS
 	GTK_SHARP_20_LIBS=$pkg_cv_GTK_SHARP_20_LIBS
@@ -8505,6 +16632,7 @@ if test -n "$GLADE_SHARP_20_CFLAGS"; then
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_GLADE_SHARP_20_CFLAGS=`$PKG_CONFIG --cflags "glade-sharp-2.0 >= 2.8" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -8521,6 +16649,7 @@ if test -n "$GLADE_SHARP_20_LIBS"; then
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_GLADE_SHARP_20_LIBS=`$PKG_CONFIG --libs "glade-sharp-2.0 >= 2.8" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -8540,14 +16669,14 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        GLADE_SHARP_20_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "glade-sharp-2.0 >= 2.8" 2>&1`
+	        GLADE_SHARP_20_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "glade-sharp-2.0 >= 2.8" 2>&1`
         else
-	        GLADE_SHARP_20_PKG_ERRORS=`$PKG_CONFIG --print-errors "glade-sharp-2.0 >= 2.8" 2>&1`
+	        GLADE_SHARP_20_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "glade-sharp-2.0 >= 2.8" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$GLADE_SHARP_20_PKG_ERRORS" >&5
 
-	as_fn_error "Package requirements (glade-sharp-2.0 >= 2.8) were not met:
+	as_fn_error $? "Package requirements (glade-sharp-2.0 >= 2.8) were not met:
 
 $GLADE_SHARP_20_PKG_ERRORS
 
@@ -8562,7 +16691,7 @@ elif test $pkg_failed = untried; then
 $as_echo "no" >&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 "The pkg-config script could not be found or is too old.  Make sure it
+as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
 is in your PATH or set the PKG_CONFIG environment variable to the full
 path to pkg-config.
 
@@ -8571,7 +16700,7 @@ and GLADE_SHARP_20_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details.
 
 To get pkg-config, see <http://pkg-config.freedesktop.org/>.
-See \`config.log' for more details." "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5; }
 else
 	GLADE_SHARP_20_CFLAGS=$pkg_cv_GLADE_SHARP_20_CFLAGS
 	GLADE_SHARP_20_LIBS=$pkg_cv_GLADE_SHARP_20_LIBS
@@ -8610,7 +16739,7 @@ $as_echo "found" >&6; }
 		else
 			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
 $as_echo "not found" >&6; }
-			as_fn_error "missing reqired Mono 2.0 assembly: $asm.dll" "$LINENO" 5
+			as_fn_error $? "missing reqired Mono 2.0 assembly: $asm.dll" "$LINENO" 5
 		fi
 	done
 
@@ -8622,9 +16751,11 @@ $as_echo "not found" >&6; }
 	if test "x$WITH_NOTIFY" = "xyes"; then
 		FRONTEND_GNOME_COMPILER_FLAGS+=" -define:NOTIFY_SHARP"
 	fi
+	if $PKG_CONFIG 'mono >= 2.6'; then
+		FRONTEND_GNOME_COMPILER_FLAGS+=" -platform:x86"
+	fi
 
 
-
 	ENABLE_FRONTEND_GNOME_IRC=$ENABLE_ENGINE_IRC;
 	ENABLE_FRONTEND_GNOME_XMPP=$ENABLE_ENGINE_XMPP;
 fi
@@ -8662,9 +16793,106 @@ else
 fi
 
 if test "x$ENABLE_FRONTEND_STFL" != "xno"; then
-	# TODO: check deps
-	as_fn_error "STFL frontend not supported (yet)" "$LINENO" 5
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for STFL" >&5
+$as_echo_n "checking for STFL... " >&6; }
+
+if test -n "$STFL_CFLAGS"; then
+    pkg_cv_STFL_CFLAGS="$STFL_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"stfl >= 0.21\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "stfl >= 0.21") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_STFL_CFLAGS=`$PKG_CONFIG --cflags "stfl >= 0.21" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$STFL_LIBS"; then
+    pkg_cv_STFL_LIBS="$STFL_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"stfl >= 0.21\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "stfl >= 0.21") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_STFL_LIBS=`$PKG_CONFIG --libs "stfl >= 0.21" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        STFL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "stfl >= 0.21" 2>&1`
+        else
+	        STFL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "stfl >= 0.21" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$STFL_PKG_ERRORS" >&5
+
+	as_fn_error $? "Package requirements (stfl >= 0.21) were not met:
+
+$STFL_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables STFL_CFLAGS
+and STFL_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&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 $? "The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables STFL_CFLAGS
+and STFL_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+	STFL_CFLAGS=$pkg_cv_STFL_CFLAGS
+	STFL_LIBS=$pkg_cv_STFL_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+fi
+ if false; then
+  ENABLE_STATIC_STFL_TRUE=
+  ENABLE_STATIC_STFL_FALSE='#'
+else
+  ENABLE_STATIC_STFL_TRUE='#'
+  ENABLE_STATIC_STFL_FALSE=
 fi
+
  if test "x$ENABLE_FRONTEND_STFL" = "xyes"; then
   ENABLE_FRONTEND_STFL_TRUE=
   ENABLE_FRONTEND_STFL_FALSE='#'
@@ -8684,7 +16912,7 @@ fi
 
 if test "x$ENABLE_FRONTEND_CURSES" != "xno"; then
 	# TODO: check deps
-	as_fn_error "Ncurses frontend not supported (yet)" "$LINENO" 5
+	as_fn_error $? "Ncurses frontend not supported (yet)" "$LINENO" 5
 fi
  if test "x$ENABLE_FRONTEND_CURSES" = "xyes"; then
   ENABLE_FRONTEND_CURSES_TRUE=
@@ -8720,7 +16948,7 @@ $as_echo "found" >&6; }
 		else
 			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
 $as_echo "not found" >&6; }
-			as_fn_error "missing reqired Mono 2.0 assembly: $asm.dll" "$LINENO" 5
+			as_fn_error $? "missing reqired Mono 2.0 assembly: $asm.dll" "$LINENO" 5
 		fi
 	done
 
@@ -8745,7 +16973,7 @@ fi
 
 if test "x$ENABLE_FRONTEND_WPF" != "xno"; then
 	# TODO: check deps
-	as_fn_error "WPF frontend not supported (yet)" "$LINENO" 5
+	as_fn_error $? "WPF frontend not supported (yet)" "$LINENO" 5
 fi
  if test "x$ENABLE_FRONTEND_WPF" = "xyes"; then
   ENABLE_FRONTEND_WPF_TRUE=
@@ -8773,7 +17001,7 @@ else
 fi
 
 
-ac_config_files="$ac_config_files Makefile src/Makefile src/AssemblyVersion.cs src/smuxi-win32.nsis src/Common/Makefile src/Common/Defines.cs src/Common/smuxi-common.pc src/Engine/Makefile src/Engine/smuxi-engine.pc src/Engine-IRC/Makefile src/Engine-IRC/smuxi-engine-irc.pc src/Engine-MSNP/Makefile src/Engine-MSNP/smuxi-engine-msnp.pc src/Engine-OSCAR/Makefile src/Engine-OSCAR/smuxi-engine-oscar.pc src/Engine-Twitter/Makefile src/Engine-XMPP/Makefile src/Engine-XMPP/smuxi-engine-xmpp.pc src/Server/Makefile src/Server/smuxi-server src/Frontend/Makefile src/Frontend/smuxi-frontend.pc src/Frontend-GNOME/Makefile src/Frontend-GNOME/smuxi-frontend-gnome src/Frontend-GNOME-IRC/Makefile src/Frontend-GNOME-XMPP/Makefile src/Frontend-Curses/Makefile src/Frontend-Curses/smuxi-frontend-curses src/Frontend-STFL/Makefile src/Frontend-STFL/smuxi-frontend-stfl src/Frontend-SWF/Makefile src/Frontend-SWF/smuxi-frontend-swf src/Frontend-Test/Makefile src/Frontend-Test/smuxi-frontend-test lib/Makefile po/Makefile.in po-Engine/Makefile.in po-Engine-IRC/Makefile.in po-Engine-Twitter/Makefile.in po-Server/Makefile.in po-Frontend/Makefile.in po-Frontend-GNOME/Makefile.in po-Frontend-GNOME-IRC/Makefile.in"
+ac_config_files="$ac_config_files Makefile src/Makefile src/AssemblyVersion.cs src/smuxi-win32.nsis src/Common/Makefile src/Common/Defines.cs src/Common/smuxi-common.pc src/Engine/Makefile src/Engine/smuxi-engine.pc src/Engine-IRC/Makefile src/Engine-IRC/smuxi-engine-irc.pc src/Engine-MSNP/Makefile src/Engine-MSNP/smuxi-engine-msnp.pc src/Engine-OSCAR/Makefile src/Engine-OSCAR/smuxi-engine-oscar.pc src/Engine-Twitter/Makefile src/Engine-XMPP/Makefile src/Engine-XMPP/smuxi-engine-xmpp.pc src/Server/Makefile src/Server/smuxi-server src/Frontend/Makefile src/Frontend/smuxi-frontend.pc src/Frontend-GNOME/Makefile src/Frontend-GNOME/smuxi-frontend-gnome src/Frontend-GNOME-IRC/Makefile src/Frontend-GNOME-XMPP/Makefile src/Frontend-Curses/Makefile src/Frontend-Curses/smuxi-frontend-curses src/Frontend-STFL/Makefile src/Frontend-STFL/smuxi-frontend-stfl src/Frontend-STFL/STFL/Makefile src/Frontend-SWF/Makefile src/Frontend-SWF/smuxi-frontend-swf src/Frontend-Test/Makefile src/Frontend-Test/smuxi-frontend-test lib/Makefile lib/osx/Info.plist po/Makefile.in po-Engine/Makefile.in po-Engine-IRC/Makefile.in po-Engine-Twitter/Makefile.in po-Server/Makefile.in po-Frontend/Makefile.in po-Frontend-GNOME/Makefile.in po-Frontend-GNOME-IRC/Makefile.in"
 
 
 cat >confcache <<\_ACEOF
@@ -8840,10 +17068,21 @@ $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
-    test "x$cache_file" != "x/dev/null" &&
+    if test "x$cache_file" != "x/dev/null"; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
 $as_echo "$as_me: updating cache $cache_file" >&6;}
-    cat confcache >$cache_file
+      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
   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;}
@@ -8895,6 +17134,7 @@ DEFS=`sed -n "$ac_script" confdefs.h`
 
 ac_libobjs=
 ac_ltlibobjs=
+U=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
   ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
@@ -8918,15 +17158,15 @@ else
 fi
 
 if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
-  as_fn_error "conditional \"MAINTAINER_MODE\" was never defined.
+  as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
-  as_fn_error "conditional \"AMDEP\" was never defined.
+  as_fn_error $? "conditional \"AMDEP\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
-  as_fn_error "conditional \"am__fastdepCC\" was never defined.
+  as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 
@@ -8934,79 +17174,91 @@ fi
 
 
 if test -z "${ENABLE_RELEASE_TRUE}" && test -z "${ENABLE_RELEASE_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_RELEASE\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_RELEASE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_DEBUG_TRUE}" && test -z "${ENABLE_DEBUG_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_DEBUG\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_DEBUG\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_DEBUG_TRUE}" && test -z "${ENABLE_DEBUG_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_DEBUG\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_DEBUG\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_RELEASE_TRUE}" && test -z "${ENABLE_RELEASE_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_RELEASE\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_RELEASE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${BUNDLE_NINI_TRUE}" && test -z "${BUNDLE_NINI_FALSE}"; then
-  as_fn_error "conditional \"BUNDLE_NINI\" was never defined.
+  as_fn_error $? "conditional \"BUNDLE_NINI\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${BUNDLE_DB4O_TRUE}" && test -z "${BUNDLE_DB4O_FALSE}"; then
+  as_fn_error $? "conditional \"BUNDLE_DB4O\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${BUNDLE_DB4O_TRUE}" && test -z "${BUNDLE_DB4O_FALSE}"; then
+  as_fn_error $? "conditional \"BUNDLE_DB4O\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_ENGINE_IRC_TRUE}" && test -z "${ENABLE_ENGINE_IRC_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_ENGINE_IRC\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_ENGINE_IRC\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_ENGINE_OSCAR_TRUE}" && test -z "${ENABLE_ENGINE_OSCAR_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_ENGINE_OSCAR\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_ENGINE_OSCAR\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_ENGINE_XMPP_TRUE}" && test -z "${ENABLE_ENGINE_XMPP_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_ENGINE_XMPP\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_ENGINE_XMPP\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_ENGINE_MSNP_TRUE}" && test -z "${ENABLE_ENGINE_MSNP_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_ENGINE_MSNP\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_ENGINE_MSNP\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_ENGINE_TWITTER_TRUE}" && test -z "${ENABLE_ENGINE_TWITTER_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_ENGINE_TWITTER\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_ENGINE_TWITTER\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_FRONTEND_GNOME_TRUE}" && test -z "${ENABLE_FRONTEND_GNOME_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_FRONTEND_GNOME\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_FRONTEND_GNOME\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_FRONTEND_GNOME_IRC_TRUE}" && test -z "${ENABLE_FRONTEND_GNOME_IRC_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_FRONTEND_GNOME_IRC\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_FRONTEND_GNOME_IRC\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_FRONTEND_GNOME_XMPP_TRUE}" && test -z "${ENABLE_FRONTEND_GNOME_XMPP_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_FRONTEND_GNOME_XMPP\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_FRONTEND_GNOME_XMPP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_STATIC_STFL_TRUE}" && test -z "${ENABLE_STATIC_STFL_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_STATIC_STFL\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_FRONTEND_STFL_TRUE}" && test -z "${ENABLE_FRONTEND_STFL_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_FRONTEND_STFL\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_FRONTEND_STFL\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_FRONTEND_CURSES_TRUE}" && test -z "${ENABLE_FRONTEND_CURSES_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_FRONTEND_CURSES\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_FRONTEND_CURSES\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_FRONTEND_SWF_TRUE}" && test -z "${ENABLE_FRONTEND_SWF_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_FRONTEND_SWF\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_FRONTEND_SWF\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_FRONTEND_WPF_TRUE}" && test -z "${ENABLE_FRONTEND_WPF_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_FRONTEND_WPF\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_FRONTEND_WPF\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_FRONTEND_TEST_TRUE}" && test -z "${ENABLE_FRONTEND_TEST_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_FRONTEND_TEST\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_FRONTEND_TEST\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 
-: ${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"
@@ -9107,6 +17359,7 @@ 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
@@ -9152,19 +17405,19 @@ export LANGUAGE
 (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
 
-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
 # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
 # provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
+# script with STATUS, using 1 if that was 0.
 as_fn_error ()
 {
-  as_status=$?; test $as_status -eq 0 && as_status=1
-  if test "$3"; then
-    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $1" >&2
+  $as_echo "$as_me: error: $2" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
@@ -9360,7 +17613,7 @@ $as_echo X"$as_dir" |
       test -d "$as_dir" && break
     done
     test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
 
 
 } # as_fn_mkdir_p
@@ -9413,8 +17666,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 smuxi $as_me 0.8, which was
-generated by GNU Autoconf 2.65.  Invocation command line was
+This file was extended by smuxi $as_me 0.8.9, which was
+generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -9470,11 +17723,11 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-smuxi config.status 0.8
-configured by $0, generated by GNU Autoconf 2.65,
+smuxi config.status 0.8.9
+configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
-Copyright (C) 2009 Free Software Foundation, Inc.
+Copyright (C) 2010 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
@@ -9492,11 +17745,16 @@ ac_need_defaults=:
 while test $# != 0
 do
   case $1 in
-  --*=*)
+  --*=?*)
     ac_option=`expr "X$1" : 'X\([^=]*\)='`
     ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
     ac_shift=:
     ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
   *)
     ac_option=$1
     ac_optarg=$2
@@ -9518,6 +17776,7 @@ do
     $ac_shift
     case $ac_optarg in
     *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
     esac
     as_fn_append CONFIG_FILES " '$ac_optarg'"
     ac_need_defaults=false;;
@@ -9528,7 +17787,7 @@ do
     ac_cs_silent=: ;;
 
   # This is an error.
-  -*) as_fn_error "unrecognized option: \`$1'
+  -*) as_fn_error $? "unrecognized option: \`$1'
 Try \`$0 --help' for more information." ;;
 
   *) as_fn_append ac_config_targets " $1"
@@ -9573,6 +17832,283 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 # INIT-COMMANDS
 #
 AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'
+
+
+
 # Capture the value of obsolete ALL_LINGUAS because we need it to compute
     # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it
     # from automake < 1.5.
@@ -9590,6 +18126,7 @@ for ac_config_target in $ac_config_targets
 do
   case $ac_config_target in
     "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
     "po-directories") CONFIG_COMMANDS="$CONFIG_COMMANDS po-directories" ;;
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
     "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
@@ -9621,11 +18158,13 @@ do
     "src/Frontend-Curses/smuxi-frontend-curses") CONFIG_FILES="$CONFIG_FILES src/Frontend-Curses/smuxi-frontend-curses" ;;
     "src/Frontend-STFL/Makefile") CONFIG_FILES="$CONFIG_FILES src/Frontend-STFL/Makefile" ;;
     "src/Frontend-STFL/smuxi-frontend-stfl") CONFIG_FILES="$CONFIG_FILES src/Frontend-STFL/smuxi-frontend-stfl" ;;
+    "src/Frontend-STFL/STFL/Makefile") CONFIG_FILES="$CONFIG_FILES src/Frontend-STFL/STFL/Makefile" ;;
     "src/Frontend-SWF/Makefile") CONFIG_FILES="$CONFIG_FILES src/Frontend-SWF/Makefile" ;;
     "src/Frontend-SWF/smuxi-frontend-swf") CONFIG_FILES="$CONFIG_FILES src/Frontend-SWF/smuxi-frontend-swf" ;;
     "src/Frontend-Test/Makefile") CONFIG_FILES="$CONFIG_FILES src/Frontend-Test/Makefile" ;;
     "src/Frontend-Test/smuxi-frontend-test") CONFIG_FILES="$CONFIG_FILES src/Frontend-Test/smuxi-frontend-test" ;;
     "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;;
+    "lib/osx/Info.plist") CONFIG_FILES="$CONFIG_FILES lib/osx/Info.plist" ;;
     "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;;
     "po-Engine/Makefile.in") CONFIG_FILES="$CONFIG_FILES po-Engine/Makefile.in" ;;
     "po-Engine-IRC/Makefile.in") CONFIG_FILES="$CONFIG_FILES po-Engine-IRC/Makefile.in" ;;
@@ -9636,7 +18175,7 @@ do
     "po-Frontend-GNOME-IRC/Makefile.in") CONFIG_FILES="$CONFIG_FILES po-Frontend-GNOME-IRC/Makefile.in" ;;
     "po/stamp-it") CONFIG_COMMANDS="$CONFIG_COMMANDS po/stamp-it" ;;
 
-  *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
 done
 
@@ -9658,9 +18197,10 @@ fi
 # after its creation but before its name has been assigned to `$tmp'.
 $debug ||
 {
-  tmp=
+  tmp= ac_tmp=
   trap 'exit_status=$?
-  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
 ' 0
   trap 'as_fn_exit 1' 1 2 13 15
 }
@@ -9668,12 +18208,13 @@ $debug ||
 
 {
   tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
-  test -n "$tmp" && test -d "$tmp"
+  test -d "$tmp"
 }  ||
 {
   tmp=./conf$$-$RANDOM
   (umask 077 && mkdir "$tmp")
-} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+} || 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.
@@ -9690,12 +18231,12 @@ if test "x$ac_cr" = x; then
 fi
 ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
 if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
-  ac_cs_awk_cr='\r'
+  ac_cs_awk_cr='\\r'
 else
   ac_cs_awk_cr=$ac_cr
 fi
 
-echo 'BEGIN {' >"$tmp/subs1.awk" &&
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
 _ACEOF
 
 
@@ -9704,18 +18245,18 @@ _ACEOF
   echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
   echo "_ACEOF"
 } >conf$$subs.sh ||
-  as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
-ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
   . ./conf$$subs.sh ||
-    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
 
   ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
   if test $ac_delim_n = $ac_delim_num; then
     break
   elif $ac_last_try; then
-    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
   else
     ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
   fi
@@ -9723,7 +18264,7 @@ done
 rm -f conf$$subs.sh
 
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
 _ACEOF
 sed -n '
 h
@@ -9771,7 +18312,7 @@ t delim
 rm -f conf$$subs.awk
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 _ACAWK
-cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
   for (key in S) S_is_set[key] = 1
   FS = ""
 
@@ -9803,21 +18344,29 @@ 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 < "$tmp/subs1.awk" > "$tmp/subs.awk" \
-  || as_fn_error "could not setup config files machinery" "$LINENO" 5
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
 _ACEOF
 
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
 # trailing colons and then remove the whole line if VPATH becomes empty
 # (actually we leave an empty line to preserve line numbers).
 if test "x$srcdir" = x.; then
-  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[	 ]*\):*/\1/
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
 s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
 s/^[^=]*=[	 ]*$//
 }'
 fi
@@ -9835,7 +18384,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
@@ -9854,7 +18403,7 @@ do
     for ac_f
     do
       case $ac_f in
-      -) ac_f="$tmp/stdin";;
+      -) ac_f="$ac_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 `:'.
@@ -9863,7 +18412,7 @@ do
 	   [\\/$]*) false;;
 	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
 	   esac ||
-	   as_fn_error "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'"
@@ -9889,8 +18438,8 @@ $as_echo "$as_me: creating $ac_file" >&6;}
     esac
 
     case $ac_tag in
-    *:-:* | *:-) cat >"$tmp/stdin" \
-      || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
     esac
     ;;
   esac
@@ -10026,23 +18575,24 @@ s&@INSTALL@&$ac_INSTALL&;t t
 s&@MKDIR_P@&$ac_MKDIR_P&;t t
 $ac_datarootdir_hack
 "
-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
+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
 
 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
-  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
-  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { 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"; } &&
   { $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
+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;}
+which seems to be undefined.  Please make sure it is defined" >&2;}
 
-  rm -f "$tmp/stdin"
+  rm -f "$ac_tmp/stdin"
   case $ac_file in
-  -) cat "$tmp/out" && rm -f "$tmp/out";;
-  *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
   esac \
-  || as_fn_error "could not create $ac_file" "$LINENO" 5
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
  ;;
 
 
@@ -10148,6 +18698,636 @@ $as_echo X"$file" |
   done
 }
  ;;
+    "libtool":C)
+
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=""
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  if test x"$xsi_shell" = xyes; then
+  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\    # positional parameters, so assign one to ordinary parameter first.\
+\    func_stripname_result=${3}\
+\    func_stripname_result=${func_stripname_result#"${1}"}\
+\    func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\    func_split_long_opt_name=${1%%=*}\
+\    func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\    func_split_short_opt_arg=${1#??}\
+\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\    case ${1} in\
+\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\      *)    func_lo2o_result=${1} ;;\
+\    esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+    func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+    func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+    func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+    eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\    func_quote_for_eval "${2}"\
+\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+ ;;
     "po-directories":C)
     for ac_file in $CONFIG_FILES; do
       # Support "outfile[:infile[:infile...]]"
@@ -10263,7 +19443,7 @@ $as_echo X"$file" |
     done ;;
     "po/stamp-it":C)
     if  ! grep "^# INTLTOOL_MAKEFILE$" "po/Makefile.in" > /dev/null ; then
-       as_fn_error "po/Makefile.in.in was not created by intltoolize." "$LINENO" 5
+       as_fn_error $? "po/Makefile.in.in was not created by intltoolize." "$LINENO" 5
     fi
     rm -f "po/stamp-it" "po/stamp-it.tmp" "po/POTFILES" "po/Makefile.tmp"
     >"po/stamp-it.tmp"
@@ -10291,7 +19471,7 @@ _ACEOF
 ac_clean_files=$ac_clean_files_save
 
 test $ac_write_fail = 0 ||
-  as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
 
 
 # configure is writing to config.log, and then calls config.status.
@@ -10312,7 +19492,7 @@ if test "$no_create" != yes; then
   exec 5>>config.log
   # Use ||, not &&, to avoid exiting from the if with $? = 1, which
   # would make configure fail if this is the last instruction.
-  $ac_cs_success || as_fn_exit $?
+  $ac_cs_success || as_fn_exit 1
 fi
 
 #
@@ -10453,7 +19633,7 @@ $as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cach
       # The eval makes quoting arguments work.
       eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \
 	   --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" ||
-	as_fn_error "$ac_sub_configure failed for $ac_dir" "$LINENO" 5
+	as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5
     fi
 
     cd "$ac_popdir"
@@ -10465,14 +19645,21 @@ $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
 fi
 
 
+if test "x$CLI_RUNTIME" = "x"; then
+	CLI_RUNTIME=default
+fi
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: result:
-	Configuration summary for $PACKAGE_NAME ($VERSION)
+	Configuration summary for $PACKAGE_NAME $VERSION ($DIST_VERSION)
 
 	* Installation prefix: $prefix
 	* Build profile:       $PROFILE
+	* Compiler:            $CSC
+	* Target CLI runtime:  $CLI_RUNTIME
 
 	* Engines
 	  -------
+	  Core:                (db4o: $WITH_DB4O)
 	  IRC:                 $ENABLE_ENGINE_IRC
 	  XMPP:                $ENABLE_ENGINE_XMPP
 	  OSCAR:               $ENABLE_ENGINE_OSCAR
@@ -10484,6 +19671,7 @@ fi
 	  GNOME:               $ENABLE_FRONTEND_GNOME (IRC: $ENABLE_FRONTEND_GNOME_IRC XMPP: $ENABLE_FRONTEND_GNOME_XMPP)
 	  + Messaging Menu:    $WITH_INDICATE
 	  + Notifications:     $WITH_NOTIFY
+	  + D-Bus:             $WITH_DBUS
 	  Ncurses:             $ENABLE_FRONTEND_CURSES
 	  STFL:                $ENABLE_FRONTEND_STFL
 	  SWF (WinForms):      $ENABLE_FRONTEND_SWF
@@ -10491,13 +19679,16 @@ fi
 	  Test:                $ENABLE_FRONTEND_TEST
 " >&5
 $as_echo "
-	Configuration summary for $PACKAGE_NAME ($VERSION)
+	Configuration summary for $PACKAGE_NAME $VERSION ($DIST_VERSION)
 
 	* Installation prefix: $prefix
 	* Build profile:       $PROFILE
+	* Compiler:            $CSC
+	* Target CLI runtime:  $CLI_RUNTIME
 
 	* Engines
 	  -------
+	  Core:                (db4o: $WITH_DB4O)
 	  IRC:                 $ENABLE_ENGINE_IRC
 	  XMPP:                $ENABLE_ENGINE_XMPP
 	  OSCAR:               $ENABLE_ENGINE_OSCAR
@@ -10509,6 +19700,7 @@ $as_echo "
 	  GNOME:               $ENABLE_FRONTEND_GNOME (IRC: $ENABLE_FRONTEND_GNOME_IRC XMPP: $ENABLE_FRONTEND_GNOME_XMPP)
 	  + Messaging Menu:    $WITH_INDICATE
 	  + Notifications:     $WITH_NOTIFY
+	  + D-Bus:             $WITH_DBUS
 	  Ncurses:             $ENABLE_FRONTEND_CURSES
 	  STFL:                $ENABLE_FRONTEND_STFL
 	  SWF (WinForms):      $ENABLE_FRONTEND_SWF
diff --git a/configure.ac b/configure.ac
index b1b76a7..d1da1be 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
 AC_PREREQ([2.54])
-AC_INIT([smuxi], [0.8], [http://www.smuxi.org/issues/new])
+AC_INIT([smuxi], [0.8.9], [http://www.smuxi.org/issues/new])
 # using the --foreign option makes automake less strict about GNU policy 
 AC_CONFIG_MACRO_DIR([.])
 AM_INIT_AUTOMAKE([foreign tar-ustar])
@@ -12,6 +12,10 @@ fi
 
 AC_PROG_INSTALL
 
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+#LT_INIT([disable-static])
+
 # I18N
 IT_PROG_INTLTOOL([0.25])
 
@@ -98,6 +102,34 @@ AM_GNU_GETTEXT_VERSION([0.17])
 # doesn't support multiple po directories :(
 #AM_GLIB_GNU_GETTEXT
 
+AC_ARG_WITH([vendor-package-version],
+	AC_HELP_STRING([--with-vendor-package-version="DISTRO_NAME PACKAGE_VERSION"],
+		[Set the distro name and package version, e.g. "Debian 0.8-1"]),
+	[],
+	with_vendor_package_version=
+)
+WITH_VENDOR_PACKAGE_VERSION=$with_vendor_package_version
+if test "x$WITH_VENDOR_PACKAGE_VERSION" = "x"; then
+	AC_MSG_CHECKING([for git version])
+	if git log --oneline 295b37c8ac4939829a3c7f9150943dba8fff07f0 > /dev/null 2>&1; then
+		GIT_BRANCH=$(git branch | grep '^\*' | cut -d ' ' -f 2)
+		GIT_COMMIT_HASH=$(git log --no-color --first-parent -n1 --pretty=format:%h)
+		DIST_VERSION=$GIT_BRANCH/$GIT_COMMIT_HASH
+		DEV_VERSION_SUFFIX="-dev"
+		AC_MSG_RESULT(yes)
+	else
+		DIST_VERSION=tarball
+		DEV_VERSION_SUFFIX=
+		AC_MSG_RESULT(no)
+	fi
+else
+	DIST_VERSION=$WITH_VENDOR_PACKAGE_VERSION
+fi
+AC_SUBST([git_branch], "$GIT_BRANCH")
+AC_SUBST([git_commit_hash], "$GIT_COMMIT_HASH")
+AC_SUBST([DEV_VERSION_SUFFIX])
+AC_SUBST([dist_version], "$DIST_VERSION")
+
 SHAMROCK_EXPAND_LIBDIR
 SHAMROCK_CHECK_MONO_MODULE(1.9.1)
 SHAMROCK_FIND_MONO_RUNTIME
@@ -105,6 +137,7 @@ SHAMROCK_FIND_MONO_2_0_COMPILER
 SHAMROCK_CHECK_MONO_2_0_GAC_ASSEMBLIES([
 	System
 	System.Core
+	System.Xml
 	System.Runtime.Remoting
 	Mono.Posix
 ])
@@ -128,6 +161,7 @@ if test "x$enable_debug" = "xyes" ; then
 fi
 AC_SUBST(PROFILE)
 
+AC_SUBST(CSC, "$MCS")
 CSC_FLAGS=
 if test "x$PROFILE" = "xdebug"; then
 	AM_CONDITIONAL(ENABLE_DEBUG, true)
@@ -135,9 +169,24 @@ if test "x$PROFILE" = "xdebug"; then
 else
 	AM_CONDITIONAL(ENABLE_RELEASE, true)
 fi
-AC_SUBST(CSC, "$MCS")
 AC_SUBST(CSC_FLAGS)
 
+MCS_BASENAME=$(basename $MCS)
+CLI_RUNTIME=
+if test "$MCS_BASENAME" = "gmcs"; then
+	CLI_RUNTIME=2.0
+fi
+if test "$MCS_BASENAME" = "dmcs"; then
+	CLI_RUNTIME=4.0
+fi
+if test "$CLI_RUNTIME" = "2.0"; then
+	XBUILD_FLAGS="/toolsversion:3.5 /p:TargetFrameworkVersion=v3.5"
+fi
+if test "$CLI_RUNTIME" = "4.0"; then
+	XBUILD_FLAGS="/toolsversion:4.0 /p:TargetFrameworkVersion=v4.0"
+fi
+AC_SUBST(XBUILD_FLAGS)
+
 # Required Libraries	
 PKG_CHECK_MODULES([LOG4NET], [log4net])
 
@@ -156,6 +205,39 @@ else
 	PKG_CHECK_MODULES([NINI], [nini >= 1.1])
 fi
 
+AC_ARG_WITH([db4o],
+	AC_HELP_STRING([--with-db4o=auto|system|included], [Use system or included db4o @<:@default=auto@:>@]),
+	[],
+	with_db4o=auto
+)
+WITH_DB4O=$with_db4o
+if test "x$WITH_DB4O" = "xauto"; then
+	PKG_CHECK_EXISTS([db4o >= 8.0], FOUND_DB4O=yes, FOUND_DB4O=no)
+	if test "x$FOUND_DB4O" = "xyes"; then
+		WITH_DB4O=system
+	else
+		WITH_DB4O=included
+	fi
+fi
+if test "x$WITH_DB4O" = "xsystem"; then
+	PKG_CHECK_MODULES([DB4O], [db4o >= 8.0])
+	AM_CONDITIONAL([BUNDLE_DB4O], false)
+fi
+if test "x$WITH_DB4O" = "xincluded"; then
+	if test ! -d "$srcdir/lib/db4o-net/Db4objects.Db4o"; then
+		AC_MSG_ERROR([lib/db4o-net is empty!])
+	fi
+
+	AC_PATH_PROG(XBUILD, xbuild, no)
+	if test "x$XBUILD" = "xno"; then
+		AC_MSG_ERROR([You need to install xbuild])
+	fi
+
+	AM_CONDITIONAL([BUNDLE_DB4O], true)
+	#AC_SUBST([DB4O_FILES], "Db4objects.Db4o.dll Db4objects.Db4o.Instrumentation.dll Db4objects.Db4o.NativeQueries.dll")
+	AC_SUBST([DB4O_FILES], "Db4objects.Db4o.dll")
+fi
+
 # Optional Libraries
 AC_ARG_WITH([indicate],
 	AC_HELP_STRING([--with-indicate], [Support Messaging Menu @<:@default=auto@:>@]),
@@ -185,6 +267,36 @@ if test "x$WITH_NOTIFY" = "xyes"; then
 	PKG_CHECK_MODULES([NOTIFY_SHARP], [notify-sharp])
 fi
 
+AC_ARG_WITH([dbus],
+	AC_HELP_STRING([--with-dbus], [Support D-Bus @<:@default=auto@:>@]),
+	[],
+	with_dbus=auto
+)
+WITH_DBUS=$with_dbus
+PKG_CHECK_EXISTS([dbus-sharp-1.0], DBUS_SHARP_SUPPORT=yes, DBUS_SHARP_SUPPORT=no)
+PKG_CHECK_EXISTS([ndesk-dbus-1.0], NDESK_DBUS_SUPPORT=yes, NDESK_DBUS_SUPPORT=no)
+if test "x$WITH_DBUS" = "xauto"; then
+	if test "x$DBUS_SHARP_SUPPORT" = "xyes"; then
+		WITH_DBUS=$DBUS_SHARP_SUPPORT
+	else
+		WITH_DBUS=$NDESK_DBUS_SUPPORT
+	fi
+fi
+if test "x$WITH_DBUS" = "xyes"; then
+	if test "x$DBUS_SHARP_SUPPORT" = "xyes"; then
+		PKG_CHECK_MODULES([DBUS_SHARP], [dbus-sharp-1.0])
+		PKG_CHECK_MODULES([DBUS_SHARP_GLIB], [dbus-sharp-glib-1.0])
+		AC_SUBST([DBUS_LIBS], "$DBUS_SHARP_LIBS $DBUS_SHARP_GLIB_LIBS")
+		CSC_FLAGS+=" -define:IPC_DBUS -define:DBUS_SHARP"
+	else
+		# fallback to ndesk-dbus
+		PKG_CHECK_MODULES([NDESK_DBUS], [ndesk-dbus-1.0])
+		PKG_CHECK_MODULES([NDESK_DBUS_GLIB], [ndesk-dbus-glib-1.0])
+		AC_SUBST([DBUS_LIBS], "$NDESK_DBUS_LIBS $NDESK_DBUS_GLIB_LIBS")
+		CSC_FLAGS+=" -define:IPC_DBUS -define:NDESK_DBUS"
+	fi
+fi
+
 # Engines
 AC_ARG_ENABLE([engine-irc],
 	AC_HELP_STRING([--enable-engine-irc], [Enable IRC protocol support (default yes)]),
@@ -193,7 +305,7 @@ AC_ARG_ENABLE([engine-irc],
 )
 if test "x$ENABLE_ENGINE_IRC" != "xno"; then
 	if test ! -f "$srcdir/lib/SmartIrc4net/configure.ac"; then
-		AC_MSG_ERROR([lib/SmartIrc4net not found])
+		AC_MSG_ERROR([lib/SmartIrc4net is empty!])
 	fi
 	ac_configure_args="$ac_configure_args --disable-pkg-config --disable-pkg-lib --disable-pkg-gac"
 	AC_CONFIG_SUBDIRS([lib/SmartIrc4net])
@@ -218,18 +330,24 @@ fi
 AM_CONDITIONAL(ENABLE_ENGINE_OSCAR, test "x$ENABLE_ENGINE_OSCAR" = "xyes")
 
 AC_ARG_ENABLE([engine-xmpp],
-	AC_HELP_STRING([--enable-engine-xmpp], [Enable XMPP (Jabber) protocol support (default no)]),
+	AC_HELP_STRING([--enable-engine-xmpp], [Enable XMPP (Jabber) protocol support (default yes)]),
 	ENABLE_ENGINE_XMPP=$enableval,
-	ENABLE_ENGINE_XMPP=no
+	ENABLE_ENGINE_XMPP=yes
 )
 if test "x$ENABLE_ENGINE_XMPP" != "xno"; then
-	PKG_CHECK_MODULES([JABBER_NET], [jabber-net], XMPP_SUPPORT=yes, XMPP_SUPPORT=no)
-	AC_SUBST(JABBER_NET_LIBS)
-	if test "x$ENABLE_ENGINE_XMPP" = "xyes" -a "x$XMPP_SUPPORT" != "xyes"; then
-		AC_MSG_ERROR([jabber-net not found])
-	else
-		ENABLE_ENGINE_XMPP=$XMPP_SUPPORT
+	AC_PATH_PROG(XBUILD, xbuild, no)
+	if test "x$XBUILD" = "xno"; then
+		AC_MSG_ERROR([You need to install xbuild for XMPP support])
 	fi
+
+	if test ! -f "$srcdir/lib/jabber-net/2005-jabber-net.csproj"; then
+		AC_MSG_ERROR([lib/jabber-net is empty!])
+	fi
+	SHAMROCK_CHECK_MONO_2_0_GAC_ASSEMBLIES([
+		System
+		System.Drawing
+		System.Xml
+	])
 fi
 AM_CONDITIONAL(ENABLE_ENGINE_XMPP, test "x$ENABLE_ENGINE_XMPP" = "xyes")
 
@@ -271,7 +389,7 @@ if test "x$ENABLE_ENGINE_TWITTER" != "xno"; then
 	fi
 
 	if test ! -f "$srcdir/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Newtonsoft.Json.csproj"; then
-		AC_MSG_ERROR([lib/Newtonsoft.Json is empty! Used git submodule init; git submodule update?])
+		AC_MSG_ERROR([lib/Newtonsoft.Json is empty!])
 	fi
 	SHAMROCK_CHECK_MONO_2_0_GAC_ASSEMBLIES([
 		System
@@ -284,7 +402,7 @@ if test "x$ENABLE_ENGINE_TWITTER" != "xno"; then
 	])
 
 	if test ! -f "$srcdir/lib/Twitterizer/Twitterizer2/Twitterizer2.csproj"; then
-		AC_MSG_ERROR([lib/Twitterizer is empty! Used git submodule init; git submodule update?])
+		AC_MSG_ERROR([lib/Twitterizer is empty!])
 	fi
 	SHAMROCK_CHECK_MONO_2_0_GAC_ASSEMBLIES([
 		System
@@ -302,10 +420,16 @@ AM_CONDITIONAL(ENABLE_ENGINE_TWITTER, test "x$ENABLE_ENGINE_TWITTER" = "xyes")
 AC_ARG_WITH([twitter-api-key],
 	AC_HELP_STRING([--with-twitter-api-key], [Specify custom Twitter API key]),
 	[],
-	with_twitter_api_key="G0fxRfJqvcMPAuNat15YQ|j77MQDIuZJFa0CXehYzGPBZidF8DT3OXAi6sb5ucE"
+	with_twitter_api_key="60QV2qQx9cS7y1BJDbgAA|2VgD6qQKddsF5HYQ0TrRgs3tFTnCwDONBmRlTmG658"
 )
 AC_SUBST([twitter_api_key], $with_twitter_api_key)
 
+# Server
+if $PKG_CONFIG 'mono >= 2.6'; then
+	SERVER_COMPILER_FLAGS+=" -platform:x86"
+fi
+AC_SUBST(SERVER_COMPILER_FLAGS)
+
 # Frontends
 AC_ARG_ENABLE([frontend-gnome],
 	AC_HELP_STRING([--enable-frontend-gnome], [Enable GNOME frontend (default yes)]),
@@ -336,7 +460,9 @@ if test "x$ENABLE_FRONTEND_GNOME" != "xno"; then
 	if test "x$WITH_NOTIFY" = "xyes"; then
 		FRONTEND_GNOME_COMPILER_FLAGS+=" -define:NOTIFY_SHARP"
 	fi
-	
+	if $PKG_CONFIG 'mono >= 2.6'; then
+		FRONTEND_GNOME_COMPILER_FLAGS+=" -platform:x86"
+	fi
 	AC_SUBST(FRONTEND_GNOME_COMPILER_FLAGS)
 	
 	ENABLE_FRONTEND_GNOME_IRC=$ENABLE_ENGINE_IRC;
@@ -352,9 +478,9 @@ AC_ARG_ENABLE([frontend-stfl],
 	ENABLE_FRONTEND_STFL=no
 )
 if test "x$ENABLE_FRONTEND_STFL" != "xno"; then
-	# TODO: check deps
-	AC_MSG_ERROR([STFL frontend not supported (yet)])
+	PKG_CHECK_MODULES([STFL], [stfl >= 0.21])
 fi
+AM_CONDITIONAL(ENABLE_STATIC_STFL, false)
 AM_CONDITIONAL(ENABLE_FRONTEND_STFL, test "x$ENABLE_FRONTEND_STFL" = "xyes")
 
 AC_ARG_ENABLE([frontend-curses],
@@ -429,11 +555,13 @@ AC_CONFIG_FILES([
 	src/Frontend-Curses/smuxi-frontend-curses
 	src/Frontend-STFL/Makefile
 	src/Frontend-STFL/smuxi-frontend-stfl
+	src/Frontend-STFL/STFL/Makefile
 	src/Frontend-SWF/Makefile
 	src/Frontend-SWF/smuxi-frontend-swf
 	src/Frontend-Test/Makefile
 	src/Frontend-Test/smuxi-frontend-test
 	lib/Makefile
+	lib/osx/Info.plist
 	po/Makefile.in
 	po-Engine/Makefile.in
 	po-Engine-IRC/Makefile.in
@@ -446,14 +574,21 @@ AC_CONFIG_FILES([
 
 AC_OUTPUT
 
+if test "x$CLI_RUNTIME" = "x"; then
+	CLI_RUNTIME=default
+fi
+
 AC_MSG_RESULT([
-	Configuration summary for $PACKAGE_NAME ($VERSION)
+	Configuration summary for $PACKAGE_NAME $VERSION ($DIST_VERSION)
 	
 	* Installation prefix: $prefix
 	* Build profile:       $PROFILE
+	* Compiler:            $CSC
+	* Target CLI runtime:  $CLI_RUNTIME
 
 	* Engines
 	  -------
+	  Core:                (db4o: $WITH_DB4O)
 	  IRC:                 $ENABLE_ENGINE_IRC
 	  XMPP:                $ENABLE_ENGINE_XMPP
 	  OSCAR:               $ENABLE_ENGINE_OSCAR
@@ -465,6 +600,7 @@ AC_MSG_RESULT([
 	  GNOME:               $ENABLE_FRONTEND_GNOME (IRC: $ENABLE_FRONTEND_GNOME_IRC XMPP: $ENABLE_FRONTEND_GNOME_XMPP)
 	  + Messaging Menu:    $WITH_INDICATE
 	  + Notifications:     $WITH_NOTIFY
+	  + D-Bus:             $WITH_DBUS
 	  Ncurses:             $ENABLE_FRONTEND_CURSES
 	  STFL:                $ENABLE_FRONTEND_STFL
 	  SWF (WinForms):      $ENABLE_FRONTEND_SWF
diff --git a/glade/smuxi-frontend-gnome.glade b/glade/smuxi-frontend-gnome.glade
index 1b68554..7444b0e 100644
--- a/glade/smuxi-frontend-gnome.glade
+++ b/glade/smuxi-frontend-gnome.glade
@@ -4,7 +4,7 @@
   <!-- interface-naming-policy toplevel-contextual -->
   <widget class="GtkDialog" id="PreferencesDialog">
     <property name="visible">True</property>
-    <property name="title" translatable="yes">Smuxi - Preferences</property>
+    <property name="title" translatable="yes">Smuxi Preferences</property>
     <property name="default_width">700</property>
     <property name="default_height">600</property>
     <property name="type_hint">dialog</property>
@@ -508,8 +508,7 @@
                                         <property name="shadow_type">in</property>
                                         <child>
                                           <widget class="GtkTextView" id="OnConnectCommandsTextView">
-                                            <property name="width_request">152</property>
-                                            <property name="height_request">168</property>
+                                            <property name="height_request">100</property>
                                             <property name="visible">True</property>
                                             <property name="can_focus">True</property>
                                             <property name="wrap_mode">word</property>
@@ -568,8 +567,7 @@
                                         <property name="shadow_type">in</property>
                                         <child>
                                           <widget class="GtkTextView" id="OnStartupCommandsTextView">
-                                            <property name="width_request">152</property>
-                                            <property name="height_request">168</property>
+                                            <property name="height_request">100</property>
                                             <property name="visible">True</property>
                                             <property name="can_focus">True</property>
                                             <property name="wrap_mode">word</property>
@@ -626,145 +624,158 @@
                     <child>
                       <widget class="GtkVBox" id="vbox10">
                         <property name="visible">True</property>
+                        <property name="border_width">5</property>
                         <property name="orientation">vertical</property>
+                        <property name="spacing">5</property>
                         <child>
-                          <widget class="GtkTable" id="table5">
+                          <widget class="GtkFrame" id="frame14">
                             <property name="visible">True</property>
-                            <property name="border_width">5</property>
-                            <property name="n_rows">3</property>
-                            <property name="n_columns">2</property>
-                            <property name="column_spacing">5</property>
-                            <property name="row_spacing">5</property>
-                            <child>
-                              <widget class="GtkHBox" id="hbox7">
-                                <property name="visible">True</property>
-                                <child>
-                                  <widget class="GtkLabel" id="label33">
-                                    <property name="visible">True</property>
-                                    <property name="label" translatable="yes">Timestamp Format:</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <widget class="GtkFixed" id="fixed25">
-                                    <property name="visible">True</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                              </widget>
-                              <packing>
-                                <property name="x_options">GTK_FILL</property>
-                                <property name="y_options">GTK_FILL</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkHBox" id="hbox8">
-                                <property name="visible">True</property>
-                                <child>
-                                  <widget class="GtkLabel" id="label39">
-                                    <property name="visible">True</property>
-                                    <property name="label" translatable="yes">Buffer Lines:</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <widget class="GtkFixed" id="fixed26">
-                                    <property name="visible">True</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                              </widget>
-                              <packing>
-                                <property name="top_attach">1</property>
-                                <property name="bottom_attach">2</property>
-                                <property name="x_options">GTK_FILL</property>
-                                <property name="y_options">GTK_FILL</property>
-                              </packing>
-                            </child>
+                            <property name="label_xalign">0</property>
+                            <property name="shadow_type">none</property>
                             <child>
-                              <widget class="GtkHBox" id="hbox9">
+                              <widget class="GtkAlignment" id="alignment19">
                                 <property name="visible">True</property>
+                                <property name="left_padding">12</property>
                                 <child>
-                                  <widget class="GtkLabel" id="label40">
-                                    <property name="visible">True</property>
-                                    <property name="label" translatable="yes">Engine Buffer Lines:</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <widget class="GtkFixed" id="fixed27">
+                                  <widget class="GtkTable" id="table5">
                                     <property name="visible">True</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                              </widget>
-                              <packing>
-                                <property name="top_attach">2</property>
-                                <property name="bottom_attach">3</property>
-                                <property name="x_options">GTK_FILL</property>
-                                <property name="y_options">GTK_FILL</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkSpinButton" id="BufferLinesSpinButton">
-                                <property name="width_request">60</property>
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="adjustment">200 1 9999 1 10 10</property>
-                                <property name="climb_rate">1</property>
-                                <property name="numeric">True</property>
-                                <signal name="changed" handler="_OnChanged"/>
-                              </widget>
-                              <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
-                                <property name="top_attach">1</property>
-                                <property name="bottom_attach">2</property>
-                                <property name="y_options"></property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkSpinButton" id="EngineBufferLinesSpinButton">
-                                <property name="width_request">60</property>
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="adjustment">200 0 9999 1 10 10</property>
-                                <property name="climb_rate">1</property>
-                                <property name="numeric">True</property>
-                                <signal name="changed" handler="_OnChanged"/>
-                              </widget>
-                              <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
-                                <property name="top_attach">2</property>
-                                <property name="bottom_attach">3</property>
-                                <property name="y_options"></property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkEntry" id="TimestampFormatEntry">
-                                <property name="width_request">60</property>
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="tooltip" translatable="yes">ss = seconds
+                                    <property name="border_width">5</property>
+                                    <property name="n_rows">6</property>
+                                    <property name="n_columns">2</property>
+                                    <property name="column_spacing">5</property>
+                                    <property name="row_spacing">5</property>
+                                    <child>
+                                      <widget class="GtkHBox" id="hbox7">
+                                        <property name="visible">True</property>
+                                        <child>
+                                          <widget class="GtkLabel" id="label33">
+                                            <property name="visible">True</property>
+                                            <property name="label" translatable="yes">Timestamp Format:</property>
+                                          </widget>
+                                          <packing>
+                                            <property name="expand">False</property>
+                                            <property name="fill">False</property>
+                                            <property name="position">0</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <widget class="GtkFixed" id="fixed25">
+                                            <property name="visible">True</property>
+                                          </widget>
+                                          <packing>
+                                            <property name="position">1</property>
+                                          </packing>
+                                        </child>
+                                      </widget>
+                                      <packing>
+                                        <property name="x_options">GTK_FILL</property>
+                                        <property name="y_options">GTK_FILL</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkHBox" id="hbox8">
+                                        <property name="visible">True</property>
+                                        <child>
+                                          <widget class="GtkLabel" id="label39">
+                                            <property name="visible">True</property>
+                                            <property name="label" translatable="yes">Buffer Lines:</property>
+                                          </widget>
+                                          <packing>
+                                            <property name="expand">False</property>
+                                            <property name="fill">False</property>
+                                            <property name="position">0</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <widget class="GtkFixed" id="fixed26">
+                                            <property name="visible">True</property>
+                                          </widget>
+                                          <packing>
+                                            <property name="position">1</property>
+                                          </packing>
+                                        </child>
+                                      </widget>
+                                      <packing>
+                                        <property name="top_attach">1</property>
+                                        <property name="bottom_attach">2</property>
+                                        <property name="x_options">GTK_FILL</property>
+                                        <property name="y_options">GTK_FILL</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkHBox" id="hbox9">
+                                        <property name="visible">True</property>
+                                        <child>
+                                          <widget class="GtkLabel" id="label40">
+                                            <property name="visible">True</property>
+                                            <property name="label" translatable="yes">Engine Buffer Lines:</property>
+                                          </widget>
+                                          <packing>
+                                            <property name="expand">False</property>
+                                            <property name="fill">False</property>
+                                            <property name="position">0</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <widget class="GtkFixed" id="fixed27">
+                                            <property name="visible">True</property>
+                                          </widget>
+                                          <packing>
+                                            <property name="position">1</property>
+                                          </packing>
+                                        </child>
+                                      </widget>
+                                      <packing>
+                                        <property name="top_attach">2</property>
+                                        <property name="bottom_attach">3</property>
+                                        <property name="x_options">GTK_FILL</property>
+                                        <property name="y_options">GTK_FILL</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkSpinButton" id="BufferLinesSpinButton">
+                                        <property name="width_request">60</property>
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="invisible_char">&#x25CF;</property>
+                                        <property name="adjustment">200 1 9999 1 10 10</property>
+                                        <property name="climb_rate">1</property>
+                                        <property name="numeric">True</property>
+                                        <signal name="changed" handler="_OnChanged"/>
+                                      </widget>
+                                      <packing>
+                                        <property name="left_attach">1</property>
+                                        <property name="right_attach">2</property>
+                                        <property name="top_attach">1</property>
+                                        <property name="bottom_attach">2</property>
+                                        <property name="y_options"></property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkSpinButton" id="EngineBufferLinesSpinButton">
+                                        <property name="width_request">60</property>
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="invisible_char">&#x25CF;</property>
+                                        <property name="adjustment">200 0 9999 1 10 10</property>
+                                        <property name="climb_rate">1</property>
+                                        <property name="numeric">True</property>
+                                        <signal name="changed" handler="_OnChanged"/>
+                                      </widget>
+                                      <packing>
+                                        <property name="left_attach">1</property>
+                                        <property name="right_attach">2</property>
+                                        <property name="top_attach">2</property>
+                                        <property name="bottom_attach">3</property>
+                                        <property name="y_options"></property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkEntry" id="TimestampFormatEntry">
+                                        <property name="width_request">60</property>
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="tooltip" translatable="yes">ss = seconds
 mm = minutes
 hh = hours (01 - 12)
 HH = hours (00 - 23)
@@ -773,92 +784,173 @@ tt = AM/PM
 dd = day
 MM = month
 yy/yyyy = year</property>
-                                <property name="text">HH:mm</property>
-                                <signal name="changed" handler="_OnChanged"/>
-                              </widget>
-                              <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
-                                <property name="y_options"></property>
-                              </packing>
-                            </child>
-                          </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="position">0</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <widget class="GtkCheckButton" id="StripColorsCheckButton">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">False</property>
-                            <property name="draw_indicator">True</property>
-                            <signal name="toggled" handler="_OnChanged"/>
-                            <child>
-                              <widget class="GtkAlignment" id="alignment16">
-                                <property name="visible">True</property>
-                                <property name="xscale">0</property>
-                                <property name="yscale">0</property>
-                                <child>
-                                  <widget class="GtkHBox" id="hbox17">
-                                    <property name="visible">True</property>
-                                    <property name="spacing">2</property>
+                                        <property name="invisible_char">&#x25CF;</property>
+                                        <property name="text">HH:mm</property>
+                                        <signal name="changed" handler="_OnChanged"/>
+                                      </widget>
+                                      <packing>
+                                        <property name="left_attach">1</property>
+                                        <property name="right_attach">2</property>
+                                        <property name="y_options"></property>
+                                      </packing>
+                                    </child>
                                     <child>
-                                      <widget class="GtkImage" id="image2">
+                                      <widget class="GtkComboBox" id="PersistencyTypeComboBox">
                                         <property name="visible">True</property>
-                                        <property name="stock">gtk-cut</property>
                                       </widget>
                                       <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">False</property>
-                                        <property name="position">0</property>
+                                        <property name="left_attach">1</property>
+                                        <property name="right_attach">2</property>
+                                        <property name="top_attach">3</property>
+                                        <property name="bottom_attach">4</property>
                                       </packing>
                                     </child>
                                     <child>
-                                      <widget class="GtkLabel" id="label47">
+                                      <widget class="GtkLabel" id="label58">
                                         <property name="visible">True</property>
-                                        <property name="label" translatable="yes">Strip Colors</property>
-                                        <property name="use_underline">True</property>
+                                        <property name="xalign">0</property>
+                                        <property name="label" translatable="yes">Persistency Type:</property>
                                       </widget>
                                       <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">False</property>
-                                        <property name="position">1</property>
+                                        <property name="top_attach">3</property>
+                                        <property name="bottom_attach">4</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkLabel" id="label64">
+                                        <property name="visible">True</property>
+                                        <property name="xalign">0</property>
+                                        <property name="label" translatable="yes">Volatile Buffer Lines:</property>
+                                      </widget>
+                                      <packing>
+                                        <property name="top_attach">4</property>
+                                        <property name="bottom_attach">5</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkLabel" id="label65">
+                                        <property name="visible">True</property>
+                                        <property name="xalign">0</property>
+                                        <property name="label" translatable="yes">Persistent Buffer Lines:</property>
+                                      </widget>
+                                      <packing>
+                                        <property name="top_attach">5</property>
+                                        <property name="bottom_attach">6</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkSpinButton" id="VolatileMaxCapacitySpinButton">
+                                        <property name="width_request">60</property>
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="invisible_char">&#x25CF;</property>
+                                        <property name="adjustment">200 0 10000 100 1000 10</property>
+                                        <property name="climb_rate">1</property>
+                                        <property name="numeric">True</property>
+                                      </widget>
+                                      <packing>
+                                        <property name="left_attach">1</property>
+                                        <property name="right_attach">2</property>
+                                        <property name="top_attach">4</property>
+                                        <property name="bottom_attach">5</property>
+                                        <property name="y_options"></property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkSpinButton" id="PersistentMaxCapacitySpinButton">
+                                        <property name="width_request">60</property>
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="invisible_char">&#x25CF;</property>
+                                        <property name="adjustment">50000 0 1000000000 100 1000 10</property>
+                                        <property name="climb_rate">1</property>
+                                        <property name="numeric">True</property>
+                                      </widget>
+                                      <packing>
+                                        <property name="left_attach">1</property>
+                                        <property name="right_attach">2</property>
+                                        <property name="top_attach">5</property>
+                                        <property name="bottom_attach">6</property>
+                                        <property name="y_options"></property>
                                       </packing>
                                     </child>
                                   </widget>
                                 </child>
                               </widget>
                             </child>
+                            <child>
+                              <widget class="GtkLabel" id="label8">
+                                <property name="visible">True</property>
+                                <property name="label" translatable="yes"><b>Message Buffer</b></property>
+                                <property name="use_markup">True</property>
+                              </widget>
+                              <packing>
+                                <property name="type">label_item</property>
+                              </packing>
+                            </child>
                           </widget>
                           <packing>
                             <property name="expand">False</property>
                             <property name="fill">False</property>
-                            <property name="position">1</property>
+                            <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkCheckButton" id="StripFormattingsCheckButton">
+                          <widget class="GtkFrame" id="frame15">
                             <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">False</property>
-                            <property name="draw_indicator">True</property>
-                            <signal name="toggled" handler="_OnChanged"/>
+                            <property name="label_xalign">0</property>
+                            <property name="shadow_type">none</property>
                             <child>
-                              <widget class="GtkAlignment" id="alignment15">
+                              <widget class="GtkAlignment" id="alignment28">
                                 <property name="visible">True</property>
-                                <property name="xscale">0</property>
-                                <property name="yscale">0</property>
+                                <property name="left_padding">12</property>
                                 <child>
-                                  <widget class="GtkHBox" id="hbox16">
+                                  <widget class="GtkVBox" id="vbox14">
                                     <property name="visible">True</property>
-                                    <property name="spacing">2</property>
+                                    <property name="orientation">vertical</property>
                                     <child>
-                                      <widget class="GtkImage" id="image1">
+                                      <widget class="GtkCheckButton" id="StripColorsCheckButton">
                                         <property name="visible">True</property>
-                                        <property name="stock">gtk-cut</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">False</property>
+                                        <property name="draw_indicator">True</property>
+                                        <signal name="toggled" handler="_OnChanged"/>
+                                        <child>
+                                          <widget class="GtkAlignment" id="alignment16">
+                                            <property name="visible">True</property>
+                                            <property name="xscale">0</property>
+                                            <property name="yscale">0</property>
+                                            <child>
+                                              <widget class="GtkHBox" id="hbox17">
+                                                <property name="visible">True</property>
+                                                <property name="spacing">2</property>
+                                                <child>
+                                                  <widget class="GtkImage" id="image2">
+                                                    <property name="visible">True</property>
+                                                    <property name="stock">gtk-cut</property>
+                                                  </widget>
+                                                  <packing>
+                                                    <property name="expand">False</property>
+                                                    <property name="fill">False</property>
+                                                    <property name="position">0</property>
+                                                  </packing>
+                                                </child>
+                                                <child>
+                                                  <widget class="GtkLabel" id="label47">
+                                                    <property name="visible">True</property>
+                                                    <property name="label" translatable="yes">Strip Colors</property>
+                                                    <property name="use_underline">True</property>
+                                                  </widget>
+                                                  <packing>
+                                                    <property name="expand">False</property>
+                                                    <property name="fill">False</property>
+                                                    <property name="position">1</property>
+                                                  </packing>
+                                                </child>
+                                              </widget>
+                                            </child>
+                                          </widget>
+                                        </child>
                                       </widget>
                                       <packing>
                                         <property name="expand">False</property>
@@ -867,10 +959,48 @@ yy/yyyy = year</property>
                                       </packing>
                                     </child>
                                     <child>
-                                      <widget class="GtkLabel" id="label46">
+                                      <widget class="GtkCheckButton" id="StripFormattingsCheckButton">
                                         <property name="visible">True</property>
-                                        <property name="label" translatable="yes">Strip Formattings</property>
-                                        <property name="use_underline">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">False</property>
+                                        <property name="draw_indicator">True</property>
+                                        <signal name="toggled" handler="_OnChanged"/>
+                                        <child>
+                                          <widget class="GtkAlignment" id="alignment15">
+                                            <property name="visible">True</property>
+                                            <property name="xscale">0</property>
+                                            <property name="yscale">0</property>
+                                            <child>
+                                              <widget class="GtkHBox" id="hbox16">
+                                                <property name="visible">True</property>
+                                                <property name="spacing">2</property>
+                                                <child>
+                                                  <widget class="GtkImage" id="image1">
+                                                    <property name="visible">True</property>
+                                                    <property name="stock">gtk-cut</property>
+                                                  </widget>
+                                                  <packing>
+                                                    <property name="expand">False</property>
+                                                    <property name="fill">False</property>
+                                                    <property name="position">0</property>
+                                                  </packing>
+                                                </child>
+                                                <child>
+                                                  <widget class="GtkLabel" id="label46">
+                                                    <property name="visible">True</property>
+                                                    <property name="label" translatable="yes">Strip Formattings</property>
+                                                    <property name="use_underline">True</property>
+                                                  </widget>
+                                                  <packing>
+                                                    <property name="expand">False</property>
+                                                    <property name="fill">False</property>
+                                                    <property name="position">1</property>
+                                                  </packing>
+                                                </child>
+                                              </widget>
+                                            </child>
+                                          </widget>
+                                        </child>
                                       </widget>
                                       <packing>
                                         <property name="expand">False</property>
@@ -878,105 +1008,115 @@ yy/yyyy = year</property>
                                         <property name="position">1</property>
                                       </packing>
                                     </child>
-                                  </widget>
-                                </child>
-                              </widget>
-                            </child>
-                          </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="position">2</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <widget class="GtkCheckButton" id="StripUtf8CheckButton">
-                            <property name="visible">True</property>
-                            <property name="sensitive">False</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">False</property>
-                            <property name="draw_indicator">True</property>
-                            <signal name="toggled" handler="_OnChanged"/>
-                            <child>
-                              <widget class="GtkAlignment" id="alignment26">
-                                <property name="visible">True</property>
-                                <property name="xscale">0</property>
-                                <property name="yscale">0</property>
-                                <child>
-                                  <widget class="GtkHBox" id="hbox28">
-                                    <property name="visible">True</property>
-                                    <property name="spacing">2</property>
                                     <child>
-                                      <widget class="GtkImage" id="image12">
+                                      <widget class="GtkCheckButton" id="StripUtf8CheckButton">
                                         <property name="visible">True</property>
-                                        <property name="stock">gtk-cut</property>
+                                        <property name="sensitive">False</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">False</property>
+                                        <property name="draw_indicator">True</property>
+                                        <signal name="toggled" handler="_OnChanged"/>
+                                        <child>
+                                          <widget class="GtkAlignment" id="alignment26">
+                                            <property name="visible">True</property>
+                                            <property name="xscale">0</property>
+                                            <property name="yscale">0</property>
+                                            <child>
+                                              <widget class="GtkHBox" id="hbox28">
+                                                <property name="visible">True</property>
+                                                <property name="spacing">2</property>
+                                                <child>
+                                                  <widget class="GtkImage" id="image12">
+                                                    <property name="visible">True</property>
+                                                    <property name="stock">gtk-cut</property>
+                                                  </widget>
+                                                  <packing>
+                                                    <property name="expand">False</property>
+                                                    <property name="fill">False</property>
+                                                    <property name="position">0</property>
+                                                  </packing>
+                                                </child>
+                                                <child>
+                                                  <widget class="GtkLabel" id="label60">
+                                                    <property name="visible">True</property>
+                                                    <property name="label" translatable="yes">Strip UTF-8</property>
+                                                    <property name="use_underline">True</property>
+                                                  </widget>
+                                                  <packing>
+                                                    <property name="expand">False</property>
+                                                    <property name="fill">False</property>
+                                                    <property name="position">1</property>
+                                                  </packing>
+                                                </child>
+                                              </widget>
+                                            </child>
+                                          </widget>
+                                        </child>
                                       </widget>
                                       <packing>
                                         <property name="expand">False</property>
                                         <property name="fill">False</property>
-                                        <property name="position">0</property>
+                                        <property name="position">2</property>
                                       </packing>
                                     </child>
                                     <child>
-                                      <widget class="GtkLabel" id="label60">
+                                      <widget class="GtkCheckButton" id="ShowAdvancedSettingsCheckButton">
                                         <property name="visible">True</property>
-                                        <property name="label" translatable="yes">Strip UTF-8</property>
-                                        <property name="use_underline">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">False</property>
+                                        <property name="xalign">1</property>
+                                        <property name="draw_indicator">True</property>
+                                        <signal name="toggled" handler="_OnChanged"/>
+                                        <child>
+                                          <widget class="GtkHBox" id="hbox31">
+                                            <property name="visible">True</property>
+                                            <property name="spacing">2</property>
+                                            <child>
+                                              <widget class="GtkImage" id="image5">
+                                                <property name="visible">True</property>
+                                                <property name="stock">gtk-execute</property>
+                                              </widget>
+                                              <packing>
+                                                <property name="position">0</property>
+                                              </packing>
+                                            </child>
+                                            <child>
+                                              <widget class="GtkLabel" id="label34">
+                                                <property name="visible">True</property>
+                                                <property name="label" translatable="yes">Show Advanced Settings</property>
+                                              </widget>
+                                              <packing>
+                                                <property name="position">1</property>
+                                              </packing>
+                                            </child>
+                                          </widget>
+                                        </child>
                                       </widget>
                                       <packing>
                                         <property name="expand">False</property>
                                         <property name="fill">False</property>
-                                        <property name="position">1</property>
+                                        <property name="position">3</property>
                                       </packing>
                                     </child>
                                   </widget>
                                 </child>
                               </widget>
                             </child>
-                          </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="position">3</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <widget class="GtkCheckButton" id="ShowAdvancedSettingsCheckButton">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">False</property>
-                            <property name="xalign">1</property>
-                            <property name="draw_indicator">True</property>
-                            <signal name="toggled" handler="_OnChanged"/>
                             <child>
-                              <widget class="GtkHBox" id="hbox31">
+                              <widget class="GtkLabel" id="label50">
                                 <property name="visible">True</property>
-                                <property name="spacing">2</property>
-                                <child>
-                                  <widget class="GtkImage" id="image5">
-                                    <property name="visible">True</property>
-                                    <property name="stock">gtk-execute</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <widget class="GtkLabel" id="label34">
-                                    <property name="visible">True</property>
-                                    <property name="label" translatable="yes">Show Advanced Settings</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
+                                <property name="label" translatable="yes"><b>Advanced</b></property>
+                                <property name="use_markup">True</property>
                               </widget>
+                              <packing>
+                                <property name="type">label_item</property>
+                              </packing>
                             </child>
                           </widget>
                           <packing>
                             <property name="expand">False</property>
                             <property name="fill">False</property>
-                            <property name="position">4</property>
+                            <property name="position">1</property>
                           </packing>
                         </child>
                       </widget>
@@ -996,6 +1136,7 @@ yy/yyyy = year</property>
                       <widget class="GtkVBox" id="vbox5">
                         <property name="visible">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="border_width">5</property>
                         <property name="orientation">vertical</property>
                         <property name="spacing">5</property>
                         <child>
@@ -1418,6 +1559,7 @@ yy/yyyy = year</property>
                     <child>
                       <widget class="GtkFrame" id="frame3">
                         <property name="visible">True</property>
+                        <property name="border_width">5</property>
                         <property name="label_xalign">0</property>
                         <child>
                           <widget class="GtkAlignment" id="alignment7">
@@ -1632,6 +1774,7 @@ yy/yyyy = year</property>
                       <widget class="GtkVBox" id="vbox8">
                         <property name="visible">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="border_width">5</property>
                         <property name="orientation">vertical</property>
                         <child>
                           <widget class="GtkFrame" id="frame2">
@@ -2306,6 +2449,7 @@ yy/yyyy = year</property>
                     <child>
                       <widget class="GtkVBox" id="vbox9">
                         <property name="visible">True</property>
+                        <property name="border_width">5</property>
                         <property name="orientation">vertical</property>
                         <property name="spacing">5</property>
                         <child>
diff --git a/images/128/smuxi-frontend-gnome.png b/images/128/smuxi-frontend-gnome.png
new file mode 100644
index 0000000..4d45c6e
Binary files /dev/null and b/images/128/smuxi-frontend-gnome.png differ
diff --git a/images/16/smuxi-frontend-gnome.png b/images/16/smuxi-frontend-gnome.png
new file mode 100644
index 0000000..b4ef91b
Binary files /dev/null and b/images/16/smuxi-frontend-gnome.png differ
diff --git a/images/22/smuxi-frontend-gnome.png b/images/22/smuxi-frontend-gnome.png
new file mode 100644
index 0000000..eb5c5a3
Binary files /dev/null and b/images/22/smuxi-frontend-gnome.png differ
diff --git a/images/24/smuxi-frontend-gnome.png b/images/24/smuxi-frontend-gnome.png
new file mode 100644
index 0000000..03dae63
Binary files /dev/null and b/images/24/smuxi-frontend-gnome.png differ
diff --git a/images/256/smuxi-frontend-gnome.png b/images/256/smuxi-frontend-gnome.png
new file mode 100644
index 0000000..3b10038
Binary files /dev/null and b/images/256/smuxi-frontend-gnome.png differ
diff --git a/images/32/smuxi-frontend-gnome.png b/images/32/smuxi-frontend-gnome.png
new file mode 100644
index 0000000..d2fafd6
Binary files /dev/null and b/images/32/smuxi-frontend-gnome.png differ
diff --git a/images/48/smuxi-frontend-gnome.png b/images/48/smuxi-frontend-gnome.png
new file mode 100644
index 0000000..fcbaf0e
Binary files /dev/null and b/images/48/smuxi-frontend-gnome.png differ
diff --git a/images/connect-button.svg b/images/connect-button.svg
deleted file mode 100644
index 8b37ee3..0000000
--- a/images/connect-button.svg
+++ /dev/null
@@ -1,1015 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   inkscape:export-ydpi="90.000000"
-   inkscape:export-xdpi="90.000000"
-   inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
-   width="48px"
-   height="48px"
-   id="svg11300"
-   sodipodi:version="0.32"
-   inkscape:version="0.45"
-   sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/categories"
-   sodipodi:docname="applications-internet.svg"
-   inkscape:output_extension="org.inkscape.output.svg.inkscape">
-  <defs
-     id="defs3">
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient4873">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop4875" />
-      <stop
-         style="stop-color:#ffffff;stop-opacity:0;"
-         offset="1"
-         id="stop4877" />
-    </linearGradient>
-    <radialGradient
-       r="10.625"
-       fy="4.625"
-       fx="62.625"
-       cy="4.625"
-       cx="62.625"
-       gradientTransform="matrix(1,0,0,0.341176,1.298961e-14,3.047059)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9169"
-       xlink:href="#linearGradient8838"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient8838"
-       inkscape:collect="always">
-      <stop
-         id="stop8840"
-         offset="0"
-         style="stop-color:#000000;stop-opacity:1;" />
-      <stop
-         id="stop8842"
-         offset="1"
-         style="stop-color:#000000;stop-opacity:0;" />
-    </linearGradient>
-    <radialGradient
-       r="9.7552835"
-       fy="-8.7256308"
-       fx="62.200352"
-       cy="-8.7256308"
-       cx="62.200352"
-       gradientTransform="matrix(1.122354,-2.185101e-15,2.185149e-15,1.122379,-7.610472,1.067717)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9171"
-       xlink:href="#linearGradient8647"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient8647">
-      <stop
-         id="stop8649"
-         offset="0"
-         style="stop-color:#8fb1dc;stop-opacity:1;" />
-      <stop
-         id="stop8651"
-         offset="1"
-         style="stop-color:#3465a4;stop-opacity:1;" />
-    </linearGradient>
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8748"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient8740"
-       inkscape:collect="always">
-      <stop
-         id="stop8742"
-         offset="0"
-         style="stop-color:#ffffff;stop-opacity:1;" />
-      <stop
-         id="stop8744"
-         offset="1"
-         style="stop-color:#ffffff;stop-opacity:0;" />
-    </linearGradient>
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8750"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-1.618775e-13,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8752"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-6.799488e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9173"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8756"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8758"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-1.906811e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8760"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-1.960516e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9175"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8764"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-1.965096e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8766"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-2.68581e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9177"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8770"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8772"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-1.618775e-13,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8774"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-6.799488e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9179"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8778"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8780"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-2.257223e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8782"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-2.79498e-14,0.79739)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9181"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8786"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-8.035238e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8788"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-4.638683e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9183"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8792"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8794"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8796"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8798"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8800"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8802"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8804"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8806"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8808"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,1.662905e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8810"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="8.61745"
-       fy="18.944481"
-       fx="24.652485"
-       cy="18.94449"
-       cx="24.652573"
-       gradientTransform="matrix(7.657394e-2,2.760516,-1.969551,5.463895e-2,60.09901,-55.47179)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9185"
-       xlink:href="#linearGradient8924"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient8924">
-      <stop
-         style="stop-color:#cee14b"
-         offset="0"
-         id="stop8926" />
-      <stop
-         style="stop-color:#9db029"
-         offset="1"
-         id="stop8928" />
-    </linearGradient>
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-4.23828e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8812"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="8.61745"
-       fy="18.944481"
-       fx="24.652485"
-       cy="18.94449"
-       cx="24.652573"
-       gradientTransform="matrix(6.822876e-2,2.459669,-1.754905,4.868429e-2,55.12882,-46.82188)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9187"
-       xlink:href="#linearGradient8924"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(0.891018,0,0,0.828854,1.579517,2.39052)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9189"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="4.13475"
-       fy="14.542329"
-       fx="25.135332"
-       cy="14.542349"
-       cx="25.135374"
-       gradientTransform="matrix(0.159592,5.753335,-0.8072,2.23703e-2,32.87305,-131.6974)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9191"
-       xlink:href="#linearGradient8930"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient8930">
-      <stop
-         style="stop-color:#cee14b"
-         offset="0"
-         id="stop8932" />
-      <stop
-         style="stop-color:#9db029"
-         offset="1"
-         id="stop8934" />
-    </linearGradient>
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-5.087595e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8816"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="4.13475"
-       fy="14.542329"
-       fx="25.135332"
-       cy="14.542349"
-       cx="25.135374"
-       gradientTransform="matrix(0.159592,5.753335,-0.8072,2.23703e-2,32.87305,-130.867)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9193"
-       xlink:href="#linearGradient8930"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-3.093343e-14,0.589884)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9195"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="2.97195"
-       fy="17.573889"
-       fx="24.478539"
-       cy="17.573915"
-       cx="24.478569"
-       gradientTransform="matrix(0.222034,8.004376,-0.597156,1.656095e-2,29.5454,-182.3268)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9197"
-       xlink:href="#linearGradient8912"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient8912">
-      <stop
-         id="stop8914"
-         offset="0"
-         style="stop-color:#cee14b" />
-      <stop
-         id="stop8916"
-         offset="1"
-         style="stop-color:#9db029" />
-    </linearGradient>
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-1.223188e-13,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8820"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="2.97195"
-       fy="17.573889"
-       fx="24.478539"
-       cy="17.573915"
-       cx="24.478569"
-       gradientTransform="matrix(0.222034,8.004376,-0.597156,1.656095e-2,29.85665,-181.6002)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9199"
-       xlink:href="#linearGradient8912"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,0.311259,0.486131)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9201"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="9.82225"
-       fy="17.257843"
-       fx="25.968998"
-       cy="17.257854"
-       cx="25.969097"
-       gradientTransform="matrix(6.718136e-2,2.42191,-1.629357,4.51789e-2,52.36869,-50.34012)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9203"
-       xlink:href="#linearGradient8918"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient8918">
-      <stop
-         style="stop-color:#cee14b"
-         offset="0"
-         id="stop8920" />
-      <stop
-         style="stop-color:#9db029"
-         offset="1"
-         id="stop8922" />
-    </linearGradient>
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(1,0,0,0.930233,-3.15581e-14,-0.240141)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient8824"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <radialGradient
-       r="9.82225"
-       fy="17.257843"
-       fx="25.968998"
-       cy="17.257854"
-       cx="25.969097"
-       gradientTransform="matrix(6.168149e-2,2.223638,-1.495968,4.148028e-2,50.51125,-44.50839)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9205"
-       xlink:href="#linearGradient8918"
-       inkscape:collect="always" />
-    <radialGradient
-       r="10.081216"
-       fy="-3.4420195"
-       fx="62.225393"
-       cy="-3.4420195"
-       cx="62.225393"
-       gradientTransform="matrix(0.918134,0,0,0.854079,2.429764,1.490099)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient9207"
-       xlink:href="#linearGradient8740"
-       inkscape:collect="always" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4873"
-       id="linearGradient4879"
-       x1="63.397362"
-       y1="-9.3832779"
-       x2="68.910904"
-       y2="16.839214"
-       gradientUnits="userSpaceOnUse" />
-  </defs>
-  <sodipodi:namedview
-     stroke="#555753"
-     fill="#eeeeec"
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="0.25490196"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="2"
-     inkscape:cx="16.217641"
-     inkscape:cy="22.472776"
-     inkscape:current-layer="layer1"
-     showgrid="false"
-     inkscape:grid-bbox="true"
-     inkscape:document-units="px"
-     inkscape:showpageshadow="false"
-     inkscape:window-width="822"
-     inkscape:window-height="549"
-     inkscape:window-x="234"
-     inkscape:window-y="201" />
-  <metadata
-     id="metadata4">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:creator>
-          <cc:Agent>
-            <dc:title>Jakub Steiner</dc:title>
-          </cc:Agent>
-        </dc:creator>
-        <dc:source>http://jimmac.musichall.cz</dc:source>
-        <cc:license
-           rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
-        <dc:title>Web Browser</dc:title>
-      </cc:Work>
-      <cc:License
-         rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
-        <cc:permits
-           rdf:resource="http://web.resource.org/cc/Reproduction" />
-        <cc:permits
-           rdf:resource="http://web.resource.org/cc/Distribution" />
-        <cc:requires
-           rdf:resource="http://web.resource.org/cc/Notice" />
-        <cc:permits
-           rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
-        <cc:requires
-           rdf:resource="http://web.resource.org/cc/ShareAlike" />
-        <cc:requires
-           rdf:resource="http://web.resource.org/cc/SourceCode" />
-      </cc:License>
-    </rdf:RDF>
-  </metadata>
-  <g
-     id="layer1"
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer">
-    <g
-       inkscape:label="Layer 1"
-       id="g3020"
-       transform="matrix(1.673435,0,0,1.673435,-3.189256,-2.668541)">
-      <g
-         transform="matrix(1.284706,0,0,1.284706,-63.89629,19.96894)"
-         id="g8936"
-         style="display:inline">
-        <path
-           sodipodi:type="arc"
-           style="opacity:0.56043958;color:#000000;fill:url(#radialGradient9169);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
-           id="path8836"
-           sodipodi:cx="62.625"
-           sodipodi:cy="4.625"
-           sodipodi:rx="10.625"
-           sodipodi:ry="3.625"
-           d="M 73.25 4.625 A 10.625 3.625 0 1 1  52,4.625 A 10.625 3.625 0 1 1  73.25 4.625 z"
-           transform="matrix(1,0,0,1.192473,-0.590821,-2.378705)" />
-        <path
-           style="fill:url(#radialGradient9171);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:0.46514398;stroke-miterlimit:4;stroke-dasharray:none"
-           d="M 71.455637,-3.5111605 C 71.455637,1.6006722 67.3116,5.7446615 62.20047,5.7446615 C 57.088872,5.7446615 52.94507,1.6006253 52.94507,-3.5111605 C 52.94507,-8.6227588 57.088872,-12.766327 62.20047,-12.766327 C 67.3116,-12.766327 71.455637,-8.6227588 71.455637,-3.5111605 L 71.455637,-3.5111605 z "
-           id="path6495" />
-        <path
-           id="path8655"
-           d="M 70.945908,-3.5111451 C 70.945908,1.3191267 67.030126,5.234864 62.200518,5.234864 C 57.370468,5.234864 53.454907,1.3190823 53.454907,-3.5111451 C 53.454907,-8.3411954 57.370468,-12.256535 62.200518,-12.256535 C 67.030126,-12.256535 70.945908,-8.3411954 70.945908,-3.5111451 L 70.945908,-3.5111451 z "
-           style="opacity:0.52747253;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4879);stroke-width:0.46514425;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
-        <image
-           style="opacity:0.75;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8748);stroke-miterlimit:4"
-           width="10.784556"
-           height="16.411282"
-           href="62169F0D.png"
-           id="image6522"
-           x="61.522053"
-           y="-11.413214" />
-        <image
-           style="opacity:0.75;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8750);stroke-miterlimit:4"
-           width="2.3444688"
-           height="2.3444688"
-           href="62169F0E.png"
-           id="image6530"
-           x="61.990948"
-           y="-10.94432" />
-        <g
-           transform="matrix(0.468894,0,0,0.468894,50.39042,-14.57365)"
-           style="fill:#9db029;fill-rule:nonzero;stroke:url(#radialGradient8752);stroke-miterlimit:4"
-           id="g6532">
-          <path
-             d="M 26.0703,9.2363 L 25.9971,9.7295 L 26.5069,10.0586 L 27.378,9.4829 L 26.9425,8.9892 L 26.3605,9.3188 L 26.0705,9.2363"
-             id="path6534"
-             style="fill:#9db029;stroke:url(#radialGradient9173)" />
-        </g>
-        <image
-           style="opacity:0.75;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8756);stroke-miterlimit:4"
-           width="5.6267252"
-           height="4.6889377"
-           href="62169F0F.png"
-           id="image6538"
-           x="58.708691"
-           y="-12.819895" />
-        <image
-           style="opacity:0.75;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8758);stroke-miterlimit:4"
-           width="2.3444688"
-           height="2.3444688"
-           href="62169F10.png"
-           id="image6546"
-           x="62.928734"
-           y="-9.5376387" />
-        <g
-           transform="matrix(0.468894,0,0,0.468894,49.7717,-14.57365)"
-           style="fill:#9db029;fill-rule:nonzero;stroke:url(#radialGradient8760);stroke-miterlimit:4"
-           id="g6548">
-          <path
-             d="M 28.833,12.7749 L 28.542,12.0337 L 28.0322,12.1987 L 28.1787,13.103 L 28.833,12.7749"
-             id="path6550"
-             style="fill:#9db029;stroke:url(#radialGradient9175)" />
-        </g>
-        <image
-           style="opacity:0.75;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8764);stroke-miterlimit:4"
-           width="2.3444688"
-           height="3.2822564"
-           href="62169F11.png"
-           id="image6554"
-           x="63.397629"
-           y="-10.006532" />
-        <g
-           transform="matrix(0.468894,0,0,0.468894,49.94848,-14.57365)"
-           style="fill:#9db029;fill-rule:nonzero;stroke:url(#radialGradient8766);stroke-miterlimit:4"
-           id="g6556">
-          <path
-             d="M 29.123,12.6089 L 28.9775,13.5972 L 29.7773,13.4322 L 30.3584,12.857 L 29.8496,12.3629 C 29.6787,11.9078 29.4824,11.483 29.2685,11.0465 L 28.833,11.0465 L 28.833,11.5397 L 29.123,11.8688 L 29.123,12.609"
-             id="path6558"
-             style="fill:#9db029;stroke:url(#radialGradient9177)" />
-        </g>
-        <image
-           style="opacity:0.75;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8770);stroke-miterlimit:4"
-           width="9.8467684"
-           height="17.34907"
-           href="62169F12.png"
-           id="image6562"
-           x="52.144176"
-           y="-11.413214" />
-        <image
-           style="opacity:0.75;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8772);stroke-miterlimit:4"
-           width="2.3444688"
-           height="2.3444688"
-           href="62169F13.png"
-           id="image6570"
-           x="57.770901"
-           y="-10.94432" />
-        <g
-           transform="matrix(0.468894,0,0,0.468894,50.39042,-14.57365)"
-           style="fill:#9db029;fill-rule:nonzero;stroke:url(#radialGradient8774);stroke-miterlimit:4"
-           id="g6572">
-          <path
-             d="M 16.7656,9.5649 L 17.4922,10.0586 L 18.0742,10.0586 L 18.0742,9.4829 L 17.3476,9.1538 L 16.7656,9.5649"
-             id="path6574"
-             style="fill:#9db029;stroke:url(#radialGradient9179)" />
-        </g>
-        <image
-           style="opacity:0.75;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8778);stroke-miterlimit:4"
-           width="4.2200437"
-           height="3.2822564"
-           href="62169F14.png"
-           id="image6578"
-           x="56.36422"
-           y="-11.882107" />
-        <image
-           style="opacity:0.75;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8780);stroke-miterlimit:4"
-           width="3.7511499"
-           height="2.8133626"
-           href="2D44FCEC.png"
-           id="image6606"
-           x="57.30201"
-           y="-12.819895" />
-        <g
-           transform="matrix(0.468894,0,0,0.468894,50.96494,-14.52946)"
-           style="fill:#9db029;fill-rule:nonzero;stroke:url(#radialGradient8782);stroke-miterlimit:4"
-           id="g6608">
-          <path
-             d="M 17.4922,7.887132 L 17.856,7.558532 L 18.5831,7.393932 C 19.0811,7.151732 19.5811,6.988632 20.1095,6.817732 L 19.8195,6.324032 L 18.881,6.458832 L 18.4376,6.900732 L 17.7066,7.006732 L 17.0567,7.311932 L 16.7408,7.464732 L 16.5479,7.723032 L 17.4922,7.887132"
-             id="path6610"
-             style="fill:#9db029;stroke:url(#radialGradient9181)" />
-        </g>
-        <image
-           style="opacity:0.75;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8786);stroke-miterlimit:4"
-           width="2.3444688"
-           height="2.3444688"
-           href="2D44FCED.png"
-           id="image6614"
-           x="58.239796"
-           y="-8.5998507" />
-        <g
-           transform="matrix(0.468894,0,0,0.468894,50.56718,-14.30851)"
-           style="fill:#9db029;fill-rule:nonzero;stroke:url(#radialGradient8788);stroke-miterlimit:4"
-           id="g6616">
-          <path
-             d="M 18.7285,14.6665 L 19.165,14.0083 L 18.5102,13.5151 L 18.7285,14.6665"
-             id="path6618"
-             style="fill:#9db029;stroke:url(#radialGradient9183)" />
-        </g>
-        <image
-           style="opacity:0.15750002;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8792);stroke-miterlimit:4"
-           width="10.784556"
-           height="16.411282"
-           href="2D44FCEE.png"
-           id="image6624"
-           x="61.522053"
-           y="-11.413214" />
-        <image
-           style="opacity:0.15750002;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8794);stroke-miterlimit:4"
-           width="2.3444688"
-           height="2.3444688"
-           href="2D44FCEF.png"
-           id="image6632"
-           x="61.990948"
-           y="-10.94432" />
-        <image
-           style="opacity:0.15750002;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8796);stroke-miterlimit:4"
-           width="5.6267252"
-           height="4.6889377"
-           href="2D44FCF0.png"
-           id="image6640"
-           x="58.708691"
-           y="-12.819895" />
-        <image
-           style="opacity:0.15750002;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8798);stroke-miterlimit:4"
-           width="2.3444688"
-           height="2.3444688"
-           href="2D44FCF1.png"
-           id="image6648"
-           x="62.928734"
-           y="-9.5376387" />
-        <image
-           style="opacity:0.15750002;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8800);stroke-miterlimit:4"
-           width="2.3444688"
-           height="3.2822564"
-           href="2D44FCF2.png"
-           id="image6656"
-           x="63.397629"
-           y="-10.006532" />
-        <image
-           style="opacity:0.15750002;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8802);stroke-miterlimit:4"
-           width="9.8467684"
-           height="17.34907"
-           href="2D44FCF3.png"
-           id="image6664"
-           x="52.144176"
-           y="-11.413214" />
-        <image
-           style="opacity:0.15750002;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8804);stroke-miterlimit:4"
-           width="2.3444688"
-           height="2.3444688"
-           href="2D44FCF4.png"
-           id="image6672"
-           x="57.770901"
-           y="-10.94432" />
-        <image
-           style="opacity:0.15750002;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8806);stroke-miterlimit:4"
-           width="4.2200437"
-           height="3.2822564"
-           href="2D44FCF5.png"
-           id="image6680"
-           x="56.36422"
-           y="-11.882107" />
-        <image
-           style="opacity:0.15750002;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8808);stroke-miterlimit:4"
-           width="3.7511499"
-           height="2.8133626"
-           href="2D44FD11.png"
-           id="image6708"
-           x="57.30201"
-           y="-12.819895" />
-        <image
-           style="opacity:0.15750002;fill:#ffffff;fill-rule:nonzero;stroke:url(#radialGradient8810);stroke-miterlimit:4"
-           width="2.3444688"
-           height="2.3444688"
-           href="2D44FD12.png"
-           id="image6716"
-           x="58.239796"
-           y="-8.5998507" />
-        <g
-           transform="matrix(0.468894,0,0,0.468894,50.74397,-14.61784)"
-           style="fill:url(#radialGradient9185);fill-opacity:1;fill-rule:nonzero;stroke:url(#radialGradient8812);stroke-miterlimit:4"
-           id="g6564">
-          <path
-             d="M 17.943241,27.768799 L 17.424668,26.742079 L 16.453191,26.522353 L 15.935064,25.130138 L 14.639881,25.276354 L 13.539117,24.470606 L 12.372685,25.496524 L 12.372685,25.658333 C 12.019842,25.55649 11.586095,25.54259 11.271922,25.349417 L 11.012635,24.616733 L 11.012635,23.810095 L 10.235579,23.883158 C 10.300445,23.369754 10.364776,22.85724 10.430088,22.343925 L 9.9762924,22.343925 L 9.523388,22.930393 L 9.0695925,23.149672 L 8.4217333,22.784177 L 8.3568672,21.977538 L 8.4865103,21.097836 L 9.4584328,20.365152 L 10.23549,20.365152 L 10.364687,19.9249 L 11.336164,20.144179 L 12.0488,21.024772 L 12.178443,19.557711 L 13.409207,18.531793 L 13.862557,17.431921 L 14.769256,17.065623 L 15.287383,16.332939 L 16.452924,16.111966 L 17.036363,15.233155 C 16.45337,15.233155 15.870376,15.233155 15.287383,15.233155 L 16.388503,14.719751 L 17.165115,14.719751 L 18.26668,14.352562 L 18.396323,13.914003 L 18.007394,13.546815 L 17.554044,13.399797 L 17.683687,12.960347 L 17.35998,12.300815 L 16.582478,12.593158 L 16.712121,12.007136 L 15.805421,11.493731 L 15.093231,12.739285 L 15.157651,13.179537 L 14.445461,13.473662 L 13.991665,14.426428 L 13.797601,13.546726 L 12.566838,13.033321 L 12.372329,12.37379 L 13.991665,11.420133 L 14.704301,10.760601 L 14.769167,9.9544084 L 14.380684,9.7342382 L 13.862557,9.6607292 L 13.53885,10.467367 C 13.53885,10.467367 12.9972,10.573488 12.857934,10.607881 C 11.079373,12.246819 7.4857189,15.784785 6.650835,22.463945 C 6.6838918,22.618804 7.2560145,23.516772 7.2560145,23.516772 L 8.6160643,24.322519 L 9.9761142,24.689708 L 10.559553,25.423194 L 11.465807,26.082725 L 11.983934,26.009662 L 12.372418,26.184569 L 12.372418,26.302896 L 11.854647,27.695557 L 11.465718,28.282025 L 11.595361,28.57615 L 11.271654,29.674241 L 12.437641,31.800833 L 13.603181,32.827553 L 14.121754,33.560237 L 14.056531,35.100362 L 14.445461,35.979173 L 14.056531,37.665514 C 14.056531,37.665514 14.026058,37.655089 14.075688,37.823848 C 14.125763,37.992695 16.150958,39.116893 16.27971,39.021198 C 16.408017,38.92372 16.517701,38.83845 16.517701,38.83845 L 16.388503,38.472954 L 16.906274,37.95955 L 17.100783,37.446145 L 17.943063,37.15202 L 18.590476,35.538832 L 18.396413,35.100273 L 18.848871,34.440741 L 19.820794,34.219769 L 20.339366,33.046833 L 20.209723,31.581554 L 20.98678,30.481681 L 21.116423,29.381808 C 20.053082,28.854504 18.998473,28.311518 17.943063,27.76862"
-             id="path6566"
-             style="fill:url(#radialGradient9187);fill-opacity:1;stroke:url(#radialGradient9189)" />
-        </g>
-        <g
-           transform="matrix(0.468894,0,0,0.468894,50.523,-14.44107)"
-           style="fill:url(#radialGradient9191);fill-opacity:1;fill-rule:nonzero;stroke:url(#radialGradient8816);stroke-miterlimit:4"
-           id="g6540">
-          <path
-             d="M 26.8701,6.6933256 L 24.9795,5.9526256 L 22.7998,6.1992256 L 20.1094,6.9394256 L 19.6006,7.4335256 L 21.2725,8.5849256 L 21.2725,9.2431256 L 20.6182,9.9013256 L 21.4912,11.630324 L 22.0713,11.300224 L 22.7998,10.148825 C 23.9228,9.8016256 24.9297,9.4081256 25.9971,8.9144256 L 26.8701,6.6932256"
-             id="path6542"
-             style="fill:url(#radialGradient9193);fill-opacity:1;stroke:url(#radialGradient9195)" />
-        </g>
-        <g
-           transform="matrix(0.468894,0,0,0.468894,50.83236,-14.75043)"
-           style="fill:url(#radialGradient9197);fill-opacity:1;fill-rule:nonzero;stroke:url(#radialGradient8820);stroke-miterlimit:4"
-           id="g6580">
-          <path
-             d="M 15.187259,9.6334723 L 14.823459,10.538271 L 15.550559,10.538271 L 15.914359,9.7154723 C 16.227859,9.4937723 16.539859,9.2706723 16.859159,9.0572723 L 17.586259,9.3043723 C 18.070659,9.6334723 18.555059,9.9625723 19.039859,10.291172 L 19.767359,9.6334723 L 18.967059,9.3043723 L 18.603259,8.5636723 L 17.222359,8.3990723 L 17.149559,7.9874723 L 16.495259,8.1524723 L 16.204859,8.7282723 L 15.841059,7.9875723 L 15.696059,8.3166723 L 15.768859,9.1394723 L 15.187259,9.6334723"
-             id="path6582"
-             style="fill:url(#radialGradient9199);fill-opacity:1;stroke:url(#radialGradient9201)" />
-        </g>
-        <g
-           transform="matrix(0.468894,0,0,0.468894,50.12526,-14.48526)"
-           style="fill:url(#radialGradient9203);fill-opacity:1;fill-rule:nonzero;stroke:url(#radialGradient8824);stroke-miterlimit:4"
-           id="g6626">
-          <path
-             d="M 42.893123,20.729176 C 42.893123,20.97037 42.893123,20.729176 42.893123,20.729176 L 42.392832,21.295848 C 42.086175,20.934471 41.741875,20.630568 41.392249,20.313169 L 40.624781,20.4261 L 39.923602,19.633475 L 39.923602,20.614409 L 40.524337,21.068977 L 40.924185,21.521801 L 41.458539,20.917485 C 41.593045,21.169421 41.725716,21.421357 41.859304,21.673293 L 41.859304,22.428275 L 41.257651,23.107877 L 40.156625,23.863685 L 39.322775,24.69579 L 38.788421,24.089638 L 39.055598,23.410035 L 38.522071,22.80572 L 37.621014,20.87975 L 36.853546,20.011838 L 36.652658,20.237791 L 36.953898,21.333492 L 37.52057,21.975451 C 37.844212,22.909744 38.164366,23.802721 38.58937,24.69579 C 39.248406,24.69579 39.869708,24.625828 40.524245,24.54338 L 40.524245,25.072409 L 39.723541,27.036481 L 38.989217,27.86675 L 38.388482,29.152504 C 38.388482,29.857264 38.388482,30.562024 38.388482,31.266692 L 38.58937,32.098797 L 38.255812,32.475415 L 37.52057,32.929065 L 36.753102,33.571024 L 37.3879,34.288362 L 36.519988,35.045089 L 36.686721,35.534638 L 35.384807,37.008702 L 34.517813,37.008702 L 33.783489,37.462352 L 33.315425,37.462352 L 33.315425,36.858036 L 33.116373,35.647568 C 32.858102,34.889006 32.589181,34.13586 32.315668,33.382715 C 32.315668,32.826785 32.348813,32.276272 32.382049,31.720433 L 32.716526,30.965452 L 32.248461,30.05806 L 32.282524,28.811785 L 31.647726,28.094447 L 31.965125,27.056129 L 31.448674,26.470176 L 30.5467,26.470176 L 30.246378,26.130375 L 29.345321,26.697506 L 28.978619,26.28104 L 28.143851,26.998746 C 27.577179,26.356327 27.009588,25.714368 26.44209,25.072409 L 25.774974,23.485414 L 26.375709,22.579859 L 26.042151,22.202414 L 26.775556,20.463835 C 27.378127,19.714271 28.007508,18.995188 28.644142,18.273443 L 29.779231,17.971285 L 31.047083,17.820619 L 31.914995,18.04749 L 33.14961,19.292847 L 33.583611,18.80238 L 34.183428,18.727093 L 35.318517,19.104538 L 36.18643,19.104538 L 36.787165,18.575509 L 37.054342,18.198064 L 36.452688,17.820619 L 35.451188,17.745332 C 35.173269,17.359808 34.914998,16.954543 34.58502,16.611988 L 34.250544,16.762653 L 34.116955,17.745332 L 33.51622,17.065729 L 33.38355,16.309003 L 32.716434,15.781811 L 32.448339,15.781811 L 33.116281,16.536792 L 32.849104,17.216395 L 32.315577,17.367061 L 32.649135,16.687458 L 32.047481,16.386218 L 31.514872,15.781903 L 30.512453,16.007855 L 30.379783,16.309095 L 29.779048,16.687458 L 29.44549,17.518645 L 28.61164,17.933733 L 28.24402,17.518645 L 27.844172,17.518645 L 27.844172,16.158521 L 28.712084,15.704871 L 29.3792,15.704871 L 29.244694,15.176761 L 28.712084,14.647732 L 29.612315,14.458504 L 30.112606,13.89275 L 30.512453,13.212229 L 31.247695,13.212229 L 31.046807,12.684119 L 31.514872,12.381961 L 31.514872,12.986276 L 32.515454,13.212229 L 33.516037,12.381961 L 33.583244,12.003598 L 34.450238,11.399741 C 34.13642,11.438762 33.822602,11.467407 33.515945,11.550866 L 33.515945,10.870437 L 33.849503,10.114996 L 33.515945,10.114996 L 32.782907,10.794599 L 32.582019,11.172503 L 32.782907,11.701991 L 32.448431,12.607546 L 31.914903,12.305388 L 31.448674,11.777278 L 30.713433,12.305388 L 30.446256,11.097216 L 31.714107,10.266488 L 31.714107,9.8128376 L 32.515638,9.284268 L 33.783489,8.981651 L 34.651401,9.284268 L 36.252719,9.5864259 L 35.852871,10.03925 L 34.984959,10.03925 L 35.852871,10.945724 L 36.519988,10.190742 L 36.72262,9.8585606 C 36.72262,9.8585606 39.281551,12.15206 40.743955,14.660861 C 42.206359,17.170489 42.893123,20.128441 42.893123,20.729176 z "
-             id="path6628"
-             style="fill:url(#radialGradient9205);fill-opacity:1;stroke:url(#radialGradient9207)" />
-        </g>
-      </g>
-    </g>
-  </g>
-</svg>
diff --git a/images/group-chat.svg b/images/group-chat.svg
deleted file mode 100644
index bcc5140..0000000
--- a/images/group-chat.svg
+++ /dev/null
@@ -1,753 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="16"
-   height="16"
-   id="svg2108"
-   sodipodi:version="0.32"
-   inkscape:version="0.47 r22583"
-   sodipodi:docname="group-chat.svg"
-   inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-icon-theme/48x48/stock/generic/stock_person.png"
-   inkscape:export-xdpi="90"
-   inkscape:export-ydpi="90"
-   inkscape:output_extension="org.inkscape.output.svg.inkscape"
-   version="1.1">
-  <defs
-     id="defs3">
-    <inkscape:perspective
-       sodipodi:type="inkscape:persp3d"
-       inkscape:vp_x="0 : 24 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_z="48 : 24 : 1"
-       inkscape:persp3d-origin="24 : 16 : 1"
-       id="perspective75" />
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient5060">
-      <stop
-         style="stop-color:black;stop-opacity:1;"
-         offset="0"
-         id="stop5062" />
-      <stop
-         style="stop-color:black;stop-opacity:0;"
-         offset="1"
-         id="stop5064" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient5048">
-      <stop
-         style="stop-color:black;stop-opacity:0;"
-         offset="0"
-         id="stop5050" />
-      <stop
-         id="stop5056"
-         offset="0.5"
-         style="stop-color:black;stop-opacity:1;" />
-      <stop
-         style="stop-color:black;stop-opacity:0;"
-         offset="1"
-         id="stop5052" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient4562">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop4564" />
-      <stop
-         style="stop-color:#d6d6d2;stop-opacity:1;"
-         offset="1"
-         id="stop4566" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient4356">
-      <stop
-         style="stop-color:#000000;stop-opacity:1;"
-         offset="0"
-         id="stop4358" />
-      <stop
-         style="stop-color:#000000;stop-opacity:0;"
-         offset="1"
-         id="stop4360" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3824">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop3826" />
-      <stop
-         style="stop-color:#c9c9c9;stop-opacity:1.0000000;"
-         offset="1.0000000"
-         id="stop3828" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient3816">
-      <stop
-         style="stop-color:#000000;stop-opacity:1;"
-         offset="0"
-         id="stop3818" />
-      <stop
-         style="stop-color:#000000;stop-opacity:0;"
-         offset="1"
-         id="stop3820" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3824"
-       id="linearGradient5482"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.33835,0,0,1.33835,-36.66116,-20.70004)"
-       x1="30.935921"
-       y1="29.553486"
-       x2="30.935921"
-       y2="35.803486" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4356"
-       id="linearGradient5484"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(-1.308485,0.281154,0.281154,1.308485,35.90908,-26.21225)"
-       x1="22.686766"
-       y1="36.3904"
-       x2="21.408455"
-       y2="35.739632" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient5048"
-       id="linearGradient5486"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
-       x1="302.85715"
-       y1="366.64789"
-       x2="302.85715"
-       y2="609.50507" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient5060"
-       id="radialGradient5488"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
-       cx="605.71429"
-       cy="486.64789"
-       fx="605.71429"
-       fy="486.64789"
-       r="117.14286" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient5060"
-       id="radialGradient5490"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
-       cx="605.71429"
-       cy="486.64789"
-       fx="605.71429"
-       fy="486.64789"
-       r="117.14286" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4562"
-       id="radialGradient5492"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.046177,0,-2.580083e-8,1.017815,-9.084376,-6.268494)"
-       cx="24.753788"
-       cy="26.814409"
-       fx="24.753788"
-       fy="26.814409"
-       r="17.986025" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4356"
-       id="linearGradient5494"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(-0.999008,0.214863,0.214657,0.999968,41.63405,-13.05229)"
-       x1="22.686766"
-       y1="36.3904"
-       x2="21.408455"
-       y2="35.739632" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4356"
-       id="linearGradient5496"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.004822,0.185726,-0.185548,1.005788,-9.182192,-11.89716)"
-       x1="20.661695"
-       y1="35.817974"
-       x2="22.626925"
-       y2="36.217758" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3816"
-       id="radialGradient5498"
-       gradientUnits="userSpaceOnUse"
-       cx="31.112698"
-       cy="19.008621"
-       fx="31.112698"
-       fy="19.008621"
-       r="8.6620579" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4562"
-       id="radialGradient5500"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.558489,0,-1.377346e-8,0.563387,14.87134,4.364123)"
-       cx="29.922075"
-       cy="17.727694"
-       fx="29.922075"
-       fy="17.727694"
-       r="17.986025" />
-    <filter
-       color-interpolation-filters="sRGB"
-       id="filter5655"
-       height="1.5668966"
-       y="-0.28344828"
-       width="1.1522222"
-       x="-0.076111108"
-       inkscape:collect="always">
-      <feGaussianBlur
-         id="feGaussianBlur5657"
-         stdDeviation="1.4531044"
-         inkscape:collect="always" />
-    </filter>
-    <radialGradient
-       r="17.986025"
-       fy="17.727694"
-       fx="29.922075"
-       cy="17.727694"
-       cx="29.922075"
-       gradientTransform="matrix(0.558489,0,-1.377346e-8,0.563387,14.87134,4.364123)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient3816"
-       xlink:href="#linearGradient4562-0"
-       inkscape:collect="always" />
-    <radialGradient
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.442517,0,0,0.44639751,-3.058883,29.105609)"
-       r="17.986025"
-       fy="26.814409"
-       fx="24.753788"
-       cy="26.814409"
-       cx="24.753788"
-       id="radialGradient4568"
-       xlink:href="#linearGradient4562-0"
-       inkscape:collect="always" />
-    <linearGradient
-       y2="35.803486"
-       x2="30.935921"
-       y1="29.553486"
-       x1="30.935921"
-       gradientTransform="matrix(0.43723529,0,0,0.43723529,-11.073329,25.567913)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient1372"
-       xlink:href="#linearGradient3824-5"
-       inkscape:collect="always" />
-    <linearGradient
-       y2="35.739632"
-       x2="21.408455"
-       y1="36.3904"
-       x1="22.686766"
-       gradientTransform="matrix(-0.42747849,0.09185225,0.09185225,0.42747849,12.635172,23.767089)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient1366"
-       xlink:href="#linearGradient4356-8"
-       inkscape:collect="always" />
-    <linearGradient
-       gradientTransform="matrix(-0.42747849,0.09185225,0.09185225,0.42747849,17.134219,25.374901)"
-       y2="35.739632"
-       x2="21.408455"
-       y1="36.3904"
-       x1="22.686766"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient4366"
-       xlink:href="#linearGradient4356-8"
-       inkscape:collect="always" />
-    <linearGradient
-       gradientTransform="matrix(0.4299663,0.07939659,-0.07939659,0.4299663,-1.828453,25.567853)"
-       gradientUnits="userSpaceOnUse"
-       y2="36.217758"
-       x2="22.626925"
-       y1="35.817974"
-       x1="20.661695"
-       id="linearGradient4362"
-       xlink:href="#linearGradient4356-8"
-       inkscape:collect="always" />
-    <radialGradient
-       gradientUnits="userSpaceOnUse"
-       r="8.6620579"
-       fy="19.008621"
-       fx="31.112698"
-       cy="19.008621"
-       cx="31.112698"
-       id="radialGradient3822"
-       xlink:href="#linearGradient3816-2"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient3816-2"
-       inkscape:collect="always">
-      <stop
-         id="stop3818-5"
-         offset="0"
-         style="stop-color:#000000;stop-opacity:1;" />
-      <stop
-         id="stop3820-7"
-         offset="1"
-         style="stop-color:#000000;stop-opacity:0;" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3824-5">
-      <stop
-         id="stop3826-4"
-         offset="0"
-         style="stop-color:#ffffff;stop-opacity:1;" />
-      <stop
-         id="stop3828-9"
-         offset="1.0000000"
-         style="stop-color:#c9c9c9;stop-opacity:1.0000000;" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient4356-8"
-       inkscape:collect="always">
-      <stop
-         id="stop4358-9"
-         offset="0"
-         style="stop-color:#000000;stop-opacity:1;" />
-      <stop
-         id="stop4360-1"
-         offset="1"
-         style="stop-color:#000000;stop-opacity:0;" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient4562-0">
-      <stop
-         id="stop4564-1"
-         offset="0"
-         style="stop-color:#ffffff;stop-opacity:1;" />
-      <stop
-         id="stop4566-7"
-         offset="1"
-         style="stop-color:#d6d6d2;stop-opacity:1;" />
-    </linearGradient>
-    <inkscape:perspective
-       id="perspective39"
-       inkscape:persp3d-origin="24 : 16 : 1"
-       inkscape:vp_z="48 : 24 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_x="0 : 24 : 1"
-       sodipodi:type="inkscape:persp3d" />
-    <inkscape:perspective
-       id="perspective3735"
-       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
-       inkscape:vp_z="1 : 0.5 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_x="0 : 0.5 : 1"
-       sodipodi:type="inkscape:persp3d" />
-    <linearGradient
-       y2="35.803486"
-       x2="30.935921"
-       y1="29.553486"
-       x1="30.935921"
-       gradientTransform="matrix(0.43723529,0,0,0.43723529,-11.073329,25.567913)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient1372-6"
-       xlink:href="#linearGradient3824-5-3"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient3824-5-3">
-      <stop
-         id="stop3826-4-0"
-         offset="0"
-         style="stop-color:#ffffff;stop-opacity:1;" />
-      <stop
-         id="stop3828-9-2"
-         offset="1.0000000"
-         style="stop-color:#c9c9c9;stop-opacity:1.0000000;" />
-    </linearGradient>
-    <linearGradient
-       y2="35.739632"
-       x2="21.408455"
-       y1="36.3904"
-       x1="22.686766"
-       gradientTransform="matrix(-0.42747849,0.09185225,0.09185225,0.42747849,12.635172,23.767089)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient1366-1"
-       xlink:href="#linearGradient4356-8-5"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient4356-8-5"
-       inkscape:collect="always">
-      <stop
-         id="stop4358-9-6"
-         offset="0"
-         style="stop-color:#000000;stop-opacity:1;" />
-      <stop
-         id="stop4360-1-5"
-         offset="1"
-         style="stop-color:#000000;stop-opacity:0;" />
-    </linearGradient>
-    <filter
-       color-interpolation-filters="sRGB"
-       id="filter5655-0"
-       height="1.5668966"
-       y="-0.28344828"
-       width="1.1522222"
-       x="-0.076111108"
-       inkscape:collect="always">
-      <feGaussianBlur
-         id="feGaussianBlur5657-0"
-         stdDeviation="1.4531044"
-         inkscape:collect="always" />
-    </filter>
-    <radialGradient
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.442517,0,0,0.44639751,-3.058883,29.105609)"
-       r="17.986025"
-       fy="26.814409"
-       fx="24.753788"
-       cy="26.814409"
-       cx="24.753788"
-       id="radialGradient4568-3"
-       xlink:href="#linearGradient4562-0-4"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient4562-0-4">
-      <stop
-         id="stop4564-1-6"
-         offset="0"
-         style="stop-color:#ffffff;stop-opacity:1;" />
-      <stop
-         id="stop4566-7-6"
-         offset="1"
-         style="stop-color:#d6d6d2;stop-opacity:1;" />
-    </linearGradient>
-    <linearGradient
-       gradientTransform="matrix(-0.42747849,0.09185225,0.09185225,0.42747849,17.134219,25.374901)"
-       y2="35.739632"
-       x2="21.408455"
-       y1="36.3904"
-       x1="22.686766"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient4366-0"
-       xlink:href="#linearGradient4356-8-5"
-       inkscape:collect="always" />
-    <linearGradient
-       gradientTransform="matrix(0.4299663,0.07939659,-0.07939659,0.4299663,-1.828453,25.567853)"
-       gradientUnits="userSpaceOnUse"
-       y2="36.217758"
-       x2="22.626925"
-       y1="35.817974"
-       x1="20.661695"
-       id="linearGradient4362-2"
-       xlink:href="#linearGradient4356-8-5"
-       inkscape:collect="always" />
-    <radialGradient
-       gradientUnits="userSpaceOnUse"
-       r="8.6620579"
-       fy="19.008621"
-       fx="31.112698"
-       cy="19.008621"
-       cx="31.112698"
-       id="radialGradient3822-5"
-       xlink:href="#linearGradient3816-2-8"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient3816-2-8"
-       inkscape:collect="always">
-      <stop
-         id="stop3818-5-9"
-         offset="0"
-         style="stop-color:#000000;stop-opacity:1;" />
-      <stop
-         id="stop3820-7-5"
-         offset="1"
-         style="stop-color:#000000;stop-opacity:0;" />
-    </linearGradient>
-    <radialGradient
-       r="17.986025"
-       fy="17.727694"
-       fx="29.922075"
-       cy="17.727694"
-       cx="29.922075"
-       gradientTransform="matrix(0.558489,0,-1.377346e-8,0.563387,14.87134,4.364123)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient3816-0"
-       xlink:href="#linearGradient4562-0-4"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient3772">
-      <stop
-         id="stop3774"
-         offset="0"
-         style="stop-color:#ffffff;stop-opacity:1;" />
-      <stop
-         id="stop3776"
-         offset="1"
-         style="stop-color:#d6d6d2;stop-opacity:1;" />
-    </linearGradient>
-  </defs>
-  <sodipodi:namedview
-     inkscape:showpageshadow="false"
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="0.16862745"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="32"
-     inkscape:cx="12.068842"
-     inkscape:cy="8.52489"
-     inkscape:current-layer="layer2"
-     showgrid="true"
-     inkscape:grid-bbox="true"
-     inkscape:document-units="px"
-     fill="#9db029"
-     stroke="#727e0a"
-     inkscape:window-width="1680"
-     inkscape:window-height="1026"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="1" />
-  <metadata
-     id="metadata4">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title>Person</dc:title>
-        <dc:creator>
-          <cc:Agent>
-            <dc:title>Jakub Steiner</dc:title>
-          </cc:Agent>
-        </dc:creator>
-        <dc:source>http://jimmac.musichall.cz</dc:source>
-        <dc:subject>
-          <rdf:Bag>
-            <rdf:li>user</rdf:li>
-            <rdf:li>person</rdf:li>
-          </rdf:Bag>
-        </dc:subject>
-        <cc:license
-           rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
-      </cc:Work>
-      <cc:License
-         rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
-        <cc:permits
-           rdf:resource="http://web.resource.org/cc/Reproduction" />
-        <cc:permits
-           rdf:resource="http://web.resource.org/cc/Distribution" />
-        <cc:requires
-           rdf:resource="http://web.resource.org/cc/Notice" />
-        <cc:permits
-           rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
-        <cc:requires
-           rdf:resource="http://web.resource.org/cc/ShareAlike" />
-        <cc:requires
-           rdf:resource="http://web.resource.org/cc/SourceCode" />
-      </cc:License>
-    </rdf:RDF>
-  </metadata>
-  <g
-     id="layer1"
-     inkscape:label="cipek"
-     inkscape:groupmode="layer"
-     style="display:inline"
-     transform="translate(-3.5100292,-28.525131)" />
-  <g
-     inkscape:groupmode="layer"
-     id="layer2"
-     inkscape:label="dalsi cipek"
-     style="display:inline"
-     transform="translate(-3.5100292,-28.525131)">
-    <g
-       style="display:inline;opacity:0.7873267"
-       id="g2941-6"
-       transform="matrix(0.78967949,0,0,0.78967949,2.9173754,29.106241)">
-      <g
-         transform="translate(0,-32)"
-         style="display:inline"
-         inkscape:label="cipek"
-         id="layer1-9-0">
-        <path
-           id="path4173-4-8"
-           d="m 4.2306913,40.449062 1.8550322,0 -1.0821017,-1.00481 -0.2318793,0.309172 -0.2318793,-0.231878 -0.3091719,0.927516 z"
-           style="color:#000000;fill:url(#linearGradient1372-6);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible" />
-        <path
-           style="opacity:0.22784807000000001;color:#000000;fill:url(#linearGradient1366-1);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible"
-           d="M 6.3599261,42.94513 C 6.8982722,42.691107 7.148864,42.069645 7.148864,42.069645 6.7295031,40.30191 5.4103517,39.077722 5.4103517,39.077722 c 0,0 1.0776072,2.77321 0.9495744,3.867408 z"
-           id="path4370-5-3"
-           sodipodi:nodetypes="cccc" />
-      </g>
-      <g
-         transform="translate(0,-32)"
-         style="display:inline"
-         inkscape:label="dalsi cipek"
-         id="layer2-9-7">
-        <rect
-           transform="matrix(0.30552246,0,0,0.30552246,0.38079273,33.07423)"
-           ry="5.126524"
-           rx="5.126524"
-           y="35.448853"
-           x="5.3033009"
-           height="10.253048"
-           width="38.183765"
-           id="rect4608-8"
-           style="opacity:0.34857142000000002;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.30000000999999998;marker:none;visibility:visible;display:block;overflow:visible;filter:url(#filter5655-0);enable-background:accumulate" />
-        <path
-           sodipodi:nodetypes="cczcczc"
-           id="path4308-3-2"
-           d="m 5.7182874,46.547445 4.6375806,0 c 1.313982,0 2.61488,-0.481802 3.09172,-1.855032 0.452818,-1.304043 0.0773,-3.787357 -2.859841,-5.796975 l -5.4878038,0 c -2.9371344,1.855033 -3.3041833,4.391955 -2.6279623,5.874269 0.6889059,1.510119 1.8550321,1.777738 3.2463065,1.777738 z"
-           style="color:#000000;fill:url(#radialGradient4568-3);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1.26633656000000006;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
-        <path
-           inkscape:r_cy="true"
-           inkscape:r_cx="true"
-           style="opacity:0.29120878000000000;color:#000000;fill:url(#linearGradient4366-0);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible"
-           d="m 10.858975,44.552945 c 0.538346,-0.254024 0.788939,-0.875486 0.788939,-0.875486 -0.419361,-1.767736 -1.7385137,-2.991924 -1.7385137,-2.991924 0,0 1.0776067,2.77321 0.9495747,3.86741 z"
-           id="path4364-5-1"
-           sodipodi:nodetypes="cccc" />
-        <path
-           inkscape:r_cy="true"
-           inkscape:r_cx="true"
-           sodipodi:nodetypes="cccc"
-           id="path4354-7-0"
-           d="M 5.0011939,44.555528 C 4.4556961,44.317247 4.2115492,43.743022 4.2115492,43.743022 c 0.367838,-1.77917 1.626483,-3.080854 1.626483,-3.080854 0,0 -0.9965998,2.803341 -0.8368383,3.89336 z"
-           style="opacity:0.54945056000000003;color:#000000;fill:url(#linearGradient4362-2);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible" />
-        <path
-           style="opacity:0.64285714999999999;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.26633656000000006;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
-           d="m 5.9435927,45.300708 3.9247143,-0.0083 c 0.987298,0 2.433726,-0.209204 2.512673,-1.296943 0.07895,-1.087739 -0.939399,-3.059034 -2.372589,-4.15582 L 5.697963,39.7488 c -1.954314,1.679673 -2.5391851,3.307174 -2.1344116,4.372489 0.4047735,1.065316 1.2272263,1.171182 2.3800413,1.179446 l 0,-2.7e-5 z"
-           id="path4314-0-5"
-           sodipodi:nodetypes="cczcczcc" />
-        <path
-           transform="matrix(0.43723529,0,0,0.43723529,-5.6984391,29.873025)"
-           sodipodi:type="arc"
-           style="color:#000000;fill:url(#radialGradient3822-5);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible"
-           id="path4318-8-8"
-           sodipodi:cx="31.112698"
-           sodipodi:cy="19.008621"
-           sodipodi:rx="8.6620579"
-           sodipodi:ry="8.6620579"
-           d="m 39.774755,19.008621 c 0,4.783923 -3.878135,8.662058 -8.662057,8.662058 -4.783923,0 -8.662058,-3.878135 -8.662058,-8.662058 0,-4.783922 3.878135,-8.662058 8.662058,-8.662058 4.783922,0 8.662057,3.878136 8.662057,8.662058 z" />
-        <path
-           transform="matrix(0.43723529,0,0,0.43723529,-5.6437858,28.342699)"
-           d="m 39.774755,19.008621 c 0,4.783923 -3.878135,8.662058 -8.662057,8.662058 -4.783923,0 -8.662058,-3.878135 -8.662058,-8.662058 0,-4.783922 3.878135,-8.662058 8.662058,-8.662058 4.783922,0 8.662057,3.878136 8.662057,8.662058 z"
-           sodipodi:ry="8.6620579"
-           sodipodi:rx="8.6620579"
-           sodipodi:cy="19.008621"
-           sodipodi:cx="31.112698"
-           id="path4320-1-5"
-           style="color:#000000;fill:url(#radialGradient3816-0);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:2.89623593999999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
-           sodipodi:type="arc" />
-        <path
-           transform="matrix(0.34658216,0,0,0.34658216,-2.8233135,30.065895)"
-           sodipodi:type="arc"
-           style="opacity:0.19620254000000001;color:#000000;fill:none;stroke:#ffffff;stroke-width:3.65378450999999993;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
-           id="path4322-9-5"
-           sodipodi:cx="31.112698"
-           sodipodi:cy="19.008621"
-           sodipodi:rx="7.2737665"
-           sodipodi:ry="7.321795"
-           d="m 38.386464,19.008621 c 0,4.043716 -3.256576,7.321795 -7.273766,7.321795 -4.017191,0 -7.273767,-3.278079 -7.273767,-7.321795 0,-4.043715 3.256576,-7.321795 7.273767,-7.321795 4.01719,0 7.273766,3.27808 7.273766,7.321795 z" />
-      </g>
-    </g>
-    <g
-       id="g2941"
-       transform="matrix(0.78967949,0,0,0.78967949,6.9352308,31.211348)">
-      <g
-         transform="translate(0,-32)"
-         style="display:inline"
-         inkscape:label="cipek"
-         id="layer1-9">
-        <path
-           id="path4173-4"
-           d="m 4.2306913,40.449062 1.8550322,0 -1.0821017,-1.00481 -0.2318793,0.309172 -0.2318793,-0.231878 -0.3091719,0.927516 z"
-           style="color:#000000;fill:url(#linearGradient1372);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible" />
-        <path
-           style="opacity:0.22784807;color:#000000;fill:url(#linearGradient1366);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible"
-           d="M 6.3599261,42.94513 C 6.8982722,42.691107 7.148864,42.069645 7.148864,42.069645 6.7295031,40.30191 5.4103517,39.077722 5.4103517,39.077722 c 0,0 1.0776072,2.77321 0.9495744,3.867408 z"
-           id="path4370-5"
-           sodipodi:nodetypes="cccc" />
-      </g>
-      <g
-         transform="translate(0,-32)"
-         style="display:inline"
-         inkscape:label="dalsi cipek"
-         id="layer2-9">
-        <rect
-           transform="matrix(0.30552246,0,0,0.30552246,0.38079273,33.07423)"
-           ry="5.126524"
-           rx="5.126524"
-           y="35.448853"
-           x="5.3033009"
-           height="10.253048"
-           width="38.183765"
-           id="rect4608"
-           style="opacity:0.34857142;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.30000001;marker:none;visibility:visible;display:block;overflow:visible;filter:url(#filter5655);enable-background:accumulate" />
-        <path
-           sodipodi:nodetypes="cczcczc"
-           id="path4308-3"
-           d="m 5.7182874,46.547445 4.6375806,0 c 1.313982,0 2.61488,-0.481802 3.09172,-1.855032 0.452818,-1.304043 0.0773,-3.787357 -2.859841,-5.796975 l -5.4878038,0 c -2.9371344,1.855033 -3.3041833,4.391955 -2.6279623,5.874269 0.6889059,1.510119 1.8550321,1.777738 3.2463065,1.777738 z"
-           style="color:#000000;fill:url(#radialGradient4568);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1.26633655;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
-        <path
-           inkscape:r_cy="true"
-           inkscape:r_cx="true"
-           style="opacity:0.29120878;color:#000000;fill:url(#linearGradient4366);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible"
-           d="m 10.858975,44.552945 c 0.538346,-0.254024 0.788939,-0.875486 0.788939,-0.875486 -0.419361,-1.767736 -1.7385137,-2.991924 -1.7385137,-2.991924 0,0 1.0776067,2.77321 0.9495747,3.86741 z"
-           id="path4364-5"
-           sodipodi:nodetypes="cccc" />
-        <path
-           inkscape:r_cy="true"
-           inkscape:r_cx="true"
-           sodipodi:nodetypes="cccc"
-           id="path4354-7"
-           d="M 5.0011939,44.555528 C 4.4556961,44.317247 4.2115492,43.743022 4.2115492,43.743022 c 0.367838,-1.77917 1.626483,-3.080854 1.626483,-3.080854 0,0 -0.9965998,2.803341 -0.8368383,3.89336 z"
-           style="opacity:0.54945056;color:#000000;fill:url(#linearGradient4362);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible" />
-        <path
-           style="opacity:0.64285714999999999;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.26633655;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
-           d="m 5.9435927,45.300708 3.9247143,-0.0083 c 0.987298,0 2.433726,-0.209204 2.512673,-1.296943 0.07895,-1.087739 -0.939399,-3.059034 -2.372589,-4.15582 L 5.697963,39.7488 c -1.954314,1.679673 -2.5391851,3.307174 -2.1344116,4.372489 0.4047735,1.065316 1.2272263,1.171182 2.3800413,1.179446 l 0,-2.7e-5 z"
-           id="path4314-0"
-           sodipodi:nodetypes="cczcczcc" />
-        <path
-           transform="matrix(0.43723529,0,0,0.43723529,-5.6984391,29.873025)"
-           sodipodi:type="arc"
-           style="color:#000000;fill:url(#radialGradient3822);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible"
-           id="path4318-8"
-           sodipodi:cx="31.112698"
-           sodipodi:cy="19.008621"
-           sodipodi:rx="8.6620579"
-           sodipodi:ry="8.6620579"
-           d="m 39.774755,19.008621 c 0,4.783923 -3.878135,8.662058 -8.662057,8.662058 -4.783923,0 -8.662058,-3.878135 -8.662058,-8.662058 0,-4.783922 3.878135,-8.662058 8.662058,-8.662058 4.783922,0 8.662057,3.878136 8.662057,8.662058 z" />
-        <path
-           transform="matrix(0.43723529,0,0,0.43723529,-5.6437858,28.342699)"
-           d="m 39.774755,19.008621 c 0,4.783923 -3.878135,8.662058 -8.662057,8.662058 -4.783923,0 -8.662058,-3.878135 -8.662058,-8.662058 0,-4.783922 3.878135,-8.662058 8.662058,-8.662058 4.783922,0 8.662057,3.878136 8.662057,8.662058 z"
-           sodipodi:ry="8.6620579"
-           sodipodi:rx="8.6620579"
-           sodipodi:cy="19.008621"
-           sodipodi:cx="31.112698"
-           id="path4320-1"
-           style="color:#000000;fill:url(#radialGradient3816);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:2.89623591;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
-           sodipodi:type="arc" />
-        <path
-           transform="matrix(0.34658216,0,0,0.34658216,-2.8233135,30.065895)"
-           sodipodi:type="arc"
-           style="opacity:0.19620254;color:#000000;fill:none;stroke:#ffffff;stroke-width:3.65378451;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
-           id="path4322-9"
-           sodipodi:cx="31.112698"
-           sodipodi:cy="19.008621"
-           sodipodi:rx="7.2737665"
-           sodipodi:ry="7.321795"
-           d="m 38.386464,19.008621 c 0,4.043716 -3.256576,7.321795 -7.273766,7.321795 -4.017191,0 -7.273767,-3.278079 -7.273767,-7.321795 0,-4.043715 3.256576,-7.321795 7.273767,-7.321795 4.01719,0 7.273766,3.27808 7.273766,7.321795 z" />
-      </g>
-    </g>
-  </g>
-</svg>
diff --git a/images/group-chat_256x256.png b/images/group-chat_256x256.png
new file mode 100644
index 0000000..361b6d1
Binary files /dev/null and b/images/group-chat_256x256.png differ
diff --git a/images/icon.ico b/images/icon.ico
new file mode 100644
index 0000000..ec8e7d5
Binary files /dev/null and b/images/icon.ico differ
diff --git a/images/icon_256x256.png b/images/icon_256x256.png
new file mode 100644
index 0000000..3b10038
Binary files /dev/null and b/images/icon_256x256.png differ
diff --git a/images/person-chat.svg b/images/person-chat.svg
deleted file mode 100644
index 7eb6d25..0000000
--- a/images/person-chat.svg
+++ /dev/null
@@ -1,317 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="16"
-   height="16"
-   id="svg2108"
-   sodipodi:version="0.32"
-   inkscape:version="0.47 r22583"
-   sodipodi:docname="person-chat.svg"
-   inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-icon-theme/48x48/stock/generic/stock_person.png"
-   inkscape:export-xdpi="90"
-   inkscape:export-ydpi="90"
-   inkscape:output_extension="org.inkscape.output.svg.inkscape"
-   version="1.1">
-  <defs
-     id="defs3">
-    <inkscape:perspective
-       sodipodi:type="inkscape:persp3d"
-       inkscape:vp_x="0 : 24 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_z="48 : 24 : 1"
-       inkscape:persp3d-origin="24 : 16 : 1"
-       id="perspective39" />
-    <linearGradient
-       id="linearGradient4562">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop4564" />
-      <stop
-         style="stop-color:#d6d6d2;stop-opacity:1;"
-         offset="1"
-         id="stop4566" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient4356">
-      <stop
-         style="stop-color:#000000;stop-opacity:1;"
-         offset="0"
-         id="stop4358" />
-      <stop
-         style="stop-color:#000000;stop-opacity:0;"
-         offset="1"
-         id="stop4360" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3824">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop3826" />
-      <stop
-         style="stop-color:#c9c9c9;stop-opacity:1.0000000;"
-         offset="1.0000000"
-         id="stop3828" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient3816">
-      <stop
-         style="stop-color:#000000;stop-opacity:1;"
-         offset="0"
-         id="stop3818" />
-      <stop
-         style="stop-color:#000000;stop-opacity:0;"
-         offset="1"
-         id="stop3820" />
-    </linearGradient>
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3816"
-       id="radialGradient3822"
-       cx="31.112698"
-       cy="19.008621"
-       fx="31.112698"
-       fy="19.008621"
-       r="8.6620579"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4356"
-       id="linearGradient4362"
-       x1="20.661695"
-       y1="35.817974"
-       x2="22.626925"
-       y2="36.217758"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.4299663,0.07939659,-0.07939659,0.4299663,-2.2241832,25.844864)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4356"
-       id="linearGradient4366"
-       gradientUnits="userSpaceOnUse"
-       x1="22.686766"
-       y1="36.3904"
-       x2="21.408455"
-       y2="35.739632"
-       gradientTransform="matrix(-0.42747849,0.09185225,0.09185225,0.42747849,17.589309,25.651912)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4356"
-       id="linearGradient1366"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(-0.42747849,0.09185225,0.09185225,0.42747849,12.635172,23.767089)"
-       x1="22.686766"
-       y1="36.3904"
-       x2="21.408455"
-       y2="35.739632" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3824"
-       id="linearGradient1372"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.43723529,0,0,0.43723529,-11.073329,25.567913)"
-       x1="30.935921"
-       y1="29.553486"
-       x2="30.935921"
-       y2="35.803486" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4562"
-       id="radialGradient4568"
-       cx="24.753788"
-       cy="26.814409"
-       fx="24.753788"
-       fy="26.814409"
-       r="17.986025"
-       gradientTransform="matrix(0.442517,0,0,0.44639751,-3.058883,29.105609)"
-       gradientUnits="userSpaceOnUse" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4562"
-       id="radialGradient3816"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.558489,0,-1.377346e-8,0.563387,14.87134,4.364123)"
-       cx="29.922075"
-       cy="17.727694"
-       fx="29.922075"
-       fy="17.727694"
-       r="17.986025" />
-    <filter
-       inkscape:collect="always"
-       x="-0.076111108"
-       width="1.1522222"
-       y="-0.28344828"
-       height="1.5668966"
-       id="filter5655"
-       color-interpolation-filters="sRGB">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.4531044"
-         id="feGaussianBlur5657" />
-    </filter>
-  </defs>
-  <sodipodi:namedview
-     inkscape:showpageshadow="false"
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="0.16862745"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="5.6568542"
-     inkscape:cx="-4.8071576"
-     inkscape:cy="26.717119"
-     inkscape:current-layer="layer2"
-     showgrid="false"
-     inkscape:grid-bbox="true"
-     inkscape:document-units="px"
-     fill="#9db029"
-     stroke="#727e0a"
-     inkscape:window-width="1680"
-     inkscape:window-height="1026"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     showguides="true"
-     inkscape:guide-bbox="true"
-     inkscape:window-maximized="1" />
-  <metadata
-     id="metadata4">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title>Person</dc:title>
-        <dc:creator>
-          <cc:Agent>
-            <dc:title>Jakub Steiner</dc:title>
-          </cc:Agent>
-        </dc:creator>
-        <dc:source>http://jimmac.musichall.cz</dc:source>
-        <dc:subject>
-          <rdf:Bag>
-            <rdf:li>user</rdf:li>
-            <rdf:li>person</rdf:li>
-          </rdf:Bag>
-        </dc:subject>
-        <cc:license
-           rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
-      </cc:Work>
-      <cc:License
-         rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
-        <cc:permits
-           rdf:resource="http://web.resource.org/cc/Reproduction" />
-        <cc:permits
-           rdf:resource="http://web.resource.org/cc/Distribution" />
-        <cc:requires
-           rdf:resource="http://web.resource.org/cc/Notice" />
-        <cc:permits
-           rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
-        <cc:requires
-           rdf:resource="http://web.resource.org/cc/ShareAlike" />
-        <cc:requires
-           rdf:resource="http://web.resource.org/cc/SourceCode" />
-      </cc:License>
-    </rdf:RDF>
-  </metadata>
-  <g
-     id="layer1"
-     inkscape:label="cipek"
-     inkscape:groupmode="layer"
-     style="display:inline"
-     transform="translate(0,-32)">
-    <path
-       style="color:#000000;fill:url(#linearGradient1372);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible"
-       d="m 4.2306913,40.449062 1.8550322,0 -1.0821017,-1.00481 -0.2318793,0.309172 -0.2318793,-0.231878 -0.3091719,0.927516 z"
-       id="path4173" />
-    <path
-       sodipodi:nodetypes="cccc"
-       id="path4370"
-       d="M 6.3599261,42.94513 C 6.8982722,42.691107 7.148864,42.069645 7.148864,42.069645 6.7295031,40.30191 5.4103517,39.077722 5.4103517,39.077722 c 0,0 1.0776072,2.77321 0.9495744,3.867408 z"
-       style="opacity:0.22784807;color:#000000;fill:url(#linearGradient1366);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible" />
-  </g>
-  <g
-     inkscape:groupmode="layer"
-     id="layer2"
-     inkscape:label="dalsi cipek"
-     style="display:inline"
-     transform="translate(0,-32)">
-    <rect
-       style="opacity:0.34857142;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.30000001;marker:none;visibility:visible;display:block;overflow:visible;filter:url(#filter5655);enable-background:accumulate"
-       id="rect4608"
-       width="38.183765"
-       height="10.253048"
-       x="5.3033009"
-       y="35.448853"
-       rx="5.126524"
-       ry="5.126524"
-       transform="matrix(0.30552246,0,0,0.30552246,0.38079273,33.07423)" />
-    <path
-       style="color:#000000;fill:url(#radialGradient4568);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
-       d="m 5.7182874,46.547445 4.6375806,0 c 1.313982,0 2.61488,-0.481802 3.09172,-1.855032 0.452818,-1.304043 0.0773,-3.787357 -2.859841,-5.796975 l -5.4878038,0 c -2.9371344,1.855033 -3.3041833,4.391955 -2.6279623,5.874269 0.6889059,1.510119 1.8550321,1.777738 3.2463065,1.777738 z"
-       id="path4308"
-       sodipodi:nodetypes="cczcczc" />
-    <path
-       sodipodi:nodetypes="cccc"
-       id="path4364"
-       d="m 11.314065,44.829956 c 0.538346,-0.254024 0.788939,-0.875486 0.788939,-0.875486 -0.419361,-1.767736 -1.738514,-2.991924 -1.738514,-2.991924 0,0 1.077607,2.77321 0.949575,3.86741 z"
-       style="opacity:0.29120878;color:#000000;fill:url(#linearGradient4366);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible"
-       inkscape:r_cx="true"
-       inkscape:r_cy="true" />
-    <path
-       style="opacity:0.54945056;color:#000000;fill:url(#linearGradient4362);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible"
-       d="M 4.6054637,44.832539 C 4.0599659,44.594258 3.815819,44.020033 3.815819,44.020033 c 0.367838,-1.77917 1.626483,-3.080854 1.626483,-3.080854 0,0 -0.9965998,2.803341 -0.8368383,3.89336 z"
-       id="path4354"
-       sodipodi:nodetypes="cccc"
-       inkscape:r_cx="true"
-       inkscape:r_cy="true" />
-    <path
-       sodipodi:nodetypes="cczcczcc"
-       id="path4314"
-       d="m 6.0029522,45.597506 3.9247143,-0.0083 c 0.9872985,0 2.3272495,-0.127275 2.6511785,-1.237584 0.323929,-1.110312 -0.424886,-3.492639 -2.570454,-4.511977 L 5.697963,39.7488 c -2.2467578,1.314118 -2.8685733,3.424728 -2.3520632,4.629714 0.5165101,1.204986 1.5042374,1.210755 2.6570524,1.219019 l 0,-2.7e-5 z"
-       style="opacity:0.64285715;color:#000000;fill:none;stroke:#ffffff;stroke-width:0.90813291;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
-    <path
-       d="m 39.774755,19.008621 a 8.6620579,8.6620579 0 1 1 -17.324115,0 8.6620579,8.6620579 0 1 1 17.324115,0 z"
-       sodipodi:ry="8.6620579"
-       sodipodi:rx="8.6620579"
-       sodipodi:cy="19.008621"
-       sodipodi:cx="31.112698"
-       id="path4318"
-       style="color:#000000;fill:url(#radialGradient3822);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible"
-       sodipodi:type="arc"
-       transform="matrix(0.43723529,0,0,0.43723529,-5.6984391,29.873025)" />
-    <path
-       sodipodi:type="arc"
-       style="color:#000000;fill:url(#radialGradient3816);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:2.2870981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
-       id="path4320"
-       sodipodi:cx="31.112698"
-       sodipodi:cy="19.008621"
-       sodipodi:rx="8.6620579"
-       sodipodi:ry="8.6620579"
-       d="m 39.774755,19.008621 a 8.6620579,8.6620579 0 1 1 -17.324115,0 8.6620579,8.6620579 0 1 1 17.324115,0 z"
-       transform="matrix(0.43723529,0,0,0.43723529,-5.6437858,28.342699)" />
-    <path
-       d="m 39.414091,19.008621 a 8.3013935,8.1210604 0 1 1 -16.602787,0 8.3013935,8.1210604 0 1 1 16.602787,0 z"
-       sodipodi:ry="8.1210604"
-       sodipodi:rx="8.3013935"
-       sodipodi:cy="19.008621"
-       sodipodi:cx="31.112698"
-       id="path4322"
-       style="opacity:0.19620254;color:#000000;fill:none;stroke:#ffffff;stroke-width:2.5190351;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
-       sodipodi:type="arc"
-       transform="matrix(0.34658216,0,0,0.34658216,-2.8233135,30.065895)" />
-  </g>
-</svg>
diff --git a/images/person-chat_256x256.png b/images/person-chat_256x256.png
new file mode 100644
index 0000000..8614388
Binary files /dev/null and b/images/person-chat_256x256.png differ
diff --git a/images/protocol-chat.svg b/images/protocol-chat.svg
deleted file mode 100644
index a9ff302..0000000
--- a/images/protocol-chat.svg
+++ /dev/null
@@ -1,1056 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="16"
-   height="16"
-   id="svg2108"
-   sodipodi:version="0.32"
-   inkscape:version="0.47 r22583"
-   sodipodi:docname="protocol-chat.svg"
-   inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-icon-theme/48x48/stock/generic/stock_person.png"
-   inkscape:export-xdpi="90"
-   inkscape:export-ydpi="90"
-   inkscape:output_extension="org.inkscape.output.svg.inkscape"
-   version="1.1">
-  <title
-     id="title3774">Server</title>
-  <defs
-     id="defs3">
-    <inkscape:perspective
-       sodipodi:type="inkscape:persp3d"
-       inkscape:vp_x="0 : 24 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_z="48 : 24 : 1"
-       inkscape:persp3d-origin="24 : 16 : 1"
-       id="perspective39" />
-    <linearGradient
-       id="linearGradient4562">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop4564" />
-      <stop
-         style="stop-color:#d6d6d2;stop-opacity:1;"
-         offset="1"
-         id="stop4566" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3824">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop3826" />
-      <stop
-         style="stop-color:#c9c9c9;stop-opacity:1.0000000;"
-         offset="1.0000000"
-         id="stop3828" />
-    </linearGradient>
-    <linearGradient
-       gradientTransform="translate(-14.93152,-1.331719)"
-       y2="37.256325"
-       x2="53.5625"
-       y1="4.4916701"
-       x1="53.5625"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient2319"
-       xlink:href="#linearGradient3942"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient2809">
-      <stop
-         style="stop-color:#d3d7cf;stop-opacity:1;"
-         offset="0"
-         id="stop2811" />
-      <stop
-         style="stop-color:#eeeeec;stop-opacity:0;"
-         offset="1"
-         id="stop2813" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3942">
-      <stop
-         id="stop3944"
-         offset="0"
-         style="stop-color:#888a85;stop-opacity:1" />
-      <stop
-         id="stop3946"
-         offset="1"
-         style="stop-color:#eeeeec;stop-opacity:1" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3859">
-      <stop
-         id="stop3861"
-         offset="0"
-         style="stop-color:#d3d7cf;stop-opacity:1" />
-      <stop
-         id="stop3037"
-         offset="0.30973485"
-         style="stop-color:#eeeeec;stop-opacity:1;" />
-      <stop
-         style="stop-color:white;stop-opacity:1;"
-         offset="0.88648254"
-         id="stop3039" />
-      <stop
-         id="stop3863"
-         offset="1"
-         style="stop-color:#d3d7cf;stop-opacity:1" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient5048">
-      <stop
-         id="stop5050"
-         offset="0"
-         style="stop-color:black;stop-opacity:0;" />
-      <stop
-         style="stop-color:black;stop-opacity:1;"
-         offset="0.5"
-         id="stop5056" />
-      <stop
-         id="stop5052"
-         offset="1"
-         style="stop-color:black;stop-opacity:0;" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient2833">
-      <stop
-         style="stop-color:#959595;stop-opacity:1;"
-         offset="0"
-         id="stop2835" />
-      <stop
-         style="stop-color:white;stop-opacity:0.85576922;"
-         offset="1"
-         id="stop2837" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient4227">
-      <stop
-         style="stop-color:#d7d7d7;stop-opacity:1;"
-         offset="0"
-         id="stop4229" />
-      <stop
-         style="stop-color:#eeeeec;stop-opacity:1"
-         offset="1"
-         id="stop4231" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient4233">
-      <stop
-         style="stop-color:#d7d7d7;stop-opacity:1;"
-         offset="0"
-         id="stop4235" />
-      <stop
-         style="stop-color:#eeeeec;stop-opacity:1"
-         offset="1"
-         id="stop4237" />
-    </linearGradient>
-    <inkscape:perspective
-       id="perspective2932"
-       inkscape:persp3d-origin="24 : 16 : 1"
-       inkscape:vp_z="48 : 24 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_x="0 : 24 : 1"
-       sodipodi:type="inkscape:persp3d" />
-    <linearGradient
-       id="linearGradient3859-8">
-      <stop
-         style="stop-color:#d3d7cf;stop-opacity:1"
-         offset="0"
-         id="stop3861-2" />
-      <stop
-         style="stop-color:#eeeeec;stop-opacity:1;"
-         offset="0.30973485"
-         id="stop3037-8" />
-      <stop
-         id="stop3039-2"
-         offset="0.88648254"
-         style="stop-color:white;stop-opacity:1;" />
-      <stop
-         style="stop-color:#d3d7cf;stop-opacity:1"
-         offset="1"
-         id="stop3863-7" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3942-6">
-      <stop
-         style="stop-color:#888a85;stop-opacity:1"
-         offset="0"
-         id="stop3944-9" />
-      <stop
-         style="stop-color:#eeeeec;stop-opacity:1"
-         offset="1"
-         id="stop3946-4" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient2809-9">
-      <stop
-         id="stop2811-1"
-         offset="0"
-         style="stop-color:#d3d7cf;stop-opacity:1;" />
-      <stop
-         id="stop2813-2"
-         offset="1"
-         style="stop-color:#eeeeec;stop-opacity:0;" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient2287">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop2289" />
-      <stop
-         style="stop-color:#ffffff;stop-opacity:0;"
-         offset="1"
-         id="stop2291" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient2271">
-      <stop
-         style="stop-color:#6e6e71;stop-opacity:1;"
-         offset="0"
-         id="stop2273" />
-      <stop
-         style="stop-color:#babdb6"
-         offset="1"
-         id="stop2275" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient2240">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop2242" />
-      <stop
-         style="stop-color:#babdb6"
-         offset="1"
-         id="stop2244" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient2232">
-      <stop
-         style="stop-color:#888a85"
-         offset="0"
-         id="stop2234" />
-      <stop
-         style="stop-color:#babdb6"
-         offset="1"
-         id="stop2236" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient4039">
-      <stop
-         style="stop-color:#729fcf"
-         offset="0"
-         id="stop4041" />
-      <stop
-         style="stop-color:#3465a4"
-         offset="1"
-         id="stop4043" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient5048-6">
-      <stop
-         id="stop5050-6"
-         offset="0"
-         style="stop-color:black;stop-opacity:0;" />
-      <stop
-         style="stop-color:black;stop-opacity:1;"
-         offset="0.5"
-         id="stop5056-0" />
-      <stop
-         id="stop5052-0"
-         offset="1"
-         style="stop-color:black;stop-opacity:0;" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient2833-5">
-      <stop
-         style="stop-color:#959595;stop-opacity:1;"
-         offset="0"
-         id="stop2835-7" />
-      <stop
-         style="stop-color:white;stop-opacity:0.85576922;"
-         offset="1"
-         id="stop2837-5" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient2823">
-      <stop
-         id="stop2825"
-         offset="0"
-         style="stop-color:#d7d7d7;stop-opacity:1;" />
-      <stop
-         id="stop2827"
-         offset="1"
-         style="stop-color:#f6f6f6;stop-opacity:1;" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient4091"
-       inkscape:collect="always">
-      <stop
-         id="stop4093"
-         offset="0"
-         style="stop-color:black;stop-opacity:1;" />
-      <stop
-         id="stop4095"
-         offset="1"
-         style="stop-color:black;stop-opacity:0;" />
-    </linearGradient>
-    <inkscape:perspective
-       id="perspective4104"
-       inkscape:persp3d-origin="24 : 16 : 1"
-       inkscape:vp_z="48 : 24 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_x="0 : 24 : 1"
-       sodipodi:type="inkscape:persp3d" />
-    <inkscape:perspective
-       id="perspective4389"
-       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
-       inkscape:vp_z="1 : 0.5 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_x="0 : 0.5 : 1"
-       sodipodi:type="inkscape:persp3d" />
-    <radialGradient
-       r="0.75"
-       fy="40.5"
-       fx="26"
-       cy="40.5"
-       cx="26"
-       gradientTransform="matrix(2,0,0,2,-5.5,-40.5)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient4128-9"
-       xlink:href="#linearGradient4091-5"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient4091-5"
-       inkscape:collect="always">
-      <stop
-         id="stop4093-4"
-         offset="0"
-         style="stop-color:black;stop-opacity:1;" />
-      <stop
-         id="stop4095-6"
-         offset="1"
-         style="stop-color:black;stop-opacity:0;" />
-    </linearGradient>
-    <radialGradient
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(2,0,0,2,-79.5,-121.5)"
-       r="0.75"
-       fy="40.5"
-       fx="26"
-       cy="40.5"
-       cx="26"
-       id="radialGradient4097-2"
-       xlink:href="#linearGradient4091-5"
-       inkscape:collect="always" />
-    <radialGradient
-       r="0.75"
-       fy="40.5"
-       fx="26"
-       cy="40.5"
-       cx="26"
-       gradientTransform="matrix(2,0,0,2,-5.5,-40.5)"
-       gradientUnits="userSpaceOnUse"
-       id="radialGradient4101-7"
-       xlink:href="#linearGradient4091-5"
-       inkscape:collect="always" />
-    <linearGradient
-       gradientUnits="userSpaceOnUse"
-       y2="38.999298"
-       x2="36.4375"
-       y1="42"
-       x1="36.4375"
-       id="linearGradient4111-6"
-       xlink:href="#linearGradient5048-6-7"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient5048-6-7">
-      <stop
-         id="stop5050-6-1"
-         offset="0"
-         style="stop-color:black;stop-opacity:0;" />
-      <stop
-         style="stop-color:black;stop-opacity:1;"
-         offset="0.5"
-         id="stop5056-0-7" />
-      <stop
-         id="stop5052-0-1"
-         offset="1"
-         style="stop-color:black;stop-opacity:0;" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2232-6"
-       id="linearGradient2238-8"
-       x1="6.5625"
-       y1="15.53534"
-       x2="15.005585"
-       y2="15.53534"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient2232-6">
-      <stop
-         style="stop-color:#888a85"
-         offset="0"
-         id="stop2234-8" />
-      <stop
-         style="stop-color:#babdb6"
-         offset="1"
-         id="stop2236-0" />
-    </linearGradient>
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4039-8"
-       id="radialGradient1509-7"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.600917,0,1.491591e-5,0.376288,-116.8045,-9.8179392)"
-       cx="213.01555"
-       cy="56.564655"
-       fx="213.01555"
-       fy="56.564655"
-       r="21.006207" />
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient4039-8">
-      <stop
-         style="stop-color:#729fcf"
-         offset="0"
-         id="stop4041-6" />
-      <stop
-         style="stop-color:#3465a4"
-         offset="1"
-         id="stop4043-6" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2271-6"
-       id="linearGradient2277-9"
-       x1="0.4375"
-       y1="20.375"
-       x2="0.4375"
-       y2="6.559052"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(0.05375011,1.5623773)" />
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient2271-6">
-      <stop
-         style="stop-color:#6e6e71;stop-opacity:1;"
-         offset="0"
-         id="stop2273-1" />
-      <stop
-         style="stop-color:#babdb6"
-         offset="1"
-         id="stop2275-8" />
-    </linearGradient>
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2240-9"
-       id="radialGradient1357-5"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.0951267,0,0,0.21042699,-0.9978401,15.869857)"
-       cx="11"
-       cy="18.5"
-       fx="11"
-       fy="18.5"
-       r="7.0007591" />
-    <linearGradient
-       id="linearGradient2240-9">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop2242-6" />
-      <stop
-         style="stop-color:#babdb6"
-         offset="1"
-         id="stop2244-6" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2287-7"
-       id="linearGradient2293-1"
-       x1="9.0554562"
-       y1="2.0277281"
-       x2="1.6302037"
-       y2="10"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(0.21500044,0.53875079)" />
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient2287-7">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop2289-5" />
-      <stop
-         style="stop-color:#ffffff;stop-opacity:0;"
-         offset="1"
-         id="stop2291-5" />
-    </linearGradient>
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4091"
-       id="radialGradient4631"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(2,0,0,2,-5.5,-40.5)"
-       cx="26"
-       cy="40.5"
-       fx="26"
-       fy="40.5"
-       r="0.75" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4091"
-       id="radialGradient4633"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(2,0,0,2,-79.5,-121.5)"
-       cx="26"
-       cy="40.5"
-       fx="26"
-       fy="40.5"
-       r="0.75" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4091"
-       id="radialGradient4635"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(2,0,0,2,-5.5,-40.5)"
-       cx="26"
-       cy="40.5"
-       fx="26"
-       fy="40.5"
-       r="0.75" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient5048-6"
-       id="linearGradient4637"
-       gradientUnits="userSpaceOnUse"
-       x1="36.4375"
-       y1="42"
-       x2="36.4375"
-       y2="38.999298" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2232"
-       id="linearGradient4639"
-       gradientUnits="userSpaceOnUse"
-       x1="6.5625"
-       y1="15.53534"
-       x2="15.005585"
-       y2="15.53534" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4039"
-       id="radialGradient4641"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.600917,0,1.491591e-5,0.376288,-116.8045,-9.8179392)"
-       cx="213.01555"
-       cy="56.564655"
-       fx="213.01555"
-       fy="56.564655"
-       r="21.006207" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2271"
-       id="linearGradient4643"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(0.05375011,1.5623773)"
-       x1="0.4375"
-       y1="20.375"
-       x2="0.4375"
-       y2="6.559052" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2240"
-       id="radialGradient4645"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.0951267,0,0,0.21042699,-0.9978401,15.869857)"
-       cx="11"
-       cy="18.5"
-       fx="11"
-       fy="18.5"
-       r="7.0007591" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2287"
-       id="linearGradient4647"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(0.21500044,0.53875079)"
-       x1="9.0554562"
-       y1="2.0277281"
-       x2="1.6302037"
-       y2="10" />
-  </defs>
-  <sodipodi:namedview
-     inkscape:showpageshadow="false"
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="0.16862745"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="32"
-     inkscape:cx="14.132226"
-     inkscape:cy="7.7824326"
-     inkscape:current-layer="layer2"
-     showgrid="false"
-     inkscape:grid-bbox="true"
-     inkscape:document-units="px"
-     fill="#9db029"
-     stroke="#727e0a"
-     inkscape:window-width="1299"
-     inkscape:window-height="793"
-     inkscape:window-x="332"
-     inkscape:window-y="137"
-     showguides="true"
-     inkscape:guide-bbox="true"
-     inkscape:window-maximized="0" />
-  <metadata
-     id="metadata4">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title>Server</dc:title>
-        <dc:creator>
-          <cc:Agent>
-            <dc:title>Ahmed Abdellah</dc:title>
-          </cc:Agent>
-        </dc:creator>
-        <dc:source>http://www.gnome.org</dc:source>
-        <dc:subject>
-          <rdf:Bag>
-            <rdf:li>network</rdf:li>
-            <rdf:li>workgroup</rdf:li>
-          </rdf:Bag>
-        </dc:subject>
-        <cc:license
-           rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
-        <dc:contributor>
-          <cc:Agent>
-            <dc:title>Jakub Steiner
-Andreas Nilsson
-Lapo Calamandrei</dc:title>
-          </cc:Agent>
-        </dc:contributor>
-      </cc:Work>
-      <cc:License
-         rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
-        <cc:permits
-           rdf:resource="http://web.resource.org/cc/Reproduction" />
-        <cc:permits
-           rdf:resource="http://web.resource.org/cc/Distribution" />
-        <cc:requires
-           rdf:resource="http://web.resource.org/cc/Notice" />
-        <cc:permits
-           rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
-        <cc:requires
-           rdf:resource="http://web.resource.org/cc/ShareAlike" />
-        <cc:requires
-           rdf:resource="http://web.resource.org/cc/SourceCode" />
-      </cc:License>
-    </rdf:RDF>
-  </metadata>
-  <g
-     id="layer1"
-     inkscape:label="cipek"
-     inkscape:groupmode="layer"
-     style="display:inline"
-     transform="translate(0,-32)" />
-  <g
-     inkscape:groupmode="layer"
-     id="layer2"
-     inkscape:label="dalsi cipek"
-     style="display:inline"
-     transform="translate(0,-32)">
-    <g
-       transform="translate(-3.6812071,-5.1750768)"
-       style="display:inline"
-       id="g4342-6">
-      <g
-         transform="matrix(0.41015415,0,0,0.41015415,-5.7332016,29.660011)"
-         id="layer1-0-3"
-         inkscape:label="Layer 1">
-        <g
-           id="g4132-0"
-           style="opacity:0.4">
-          <g
-             transform="translate(-7,-11)"
-             id="g4118-2">
-            <rect
-               style="color:#000000;fill:url(#radialGradient4128-9);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
-               id="rect4122-5"
-               width="1.5"
-               height="3"
-               x="46.5"
-               y="39" />
-          </g>
-          <g
-             id="g4113-9">
-            <rect
-               style="color:#000000;fill:url(#radialGradient4097-2);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
-               id="rect4081-8"
-               width="1.5"
-               height="3"
-               x="-27.5"
-               y="-42"
-               transform="scale(-1,-1)" />
-            <rect
-               style="color:#000000;fill:url(#radialGradient4101-7);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
-               id="rect4099-2"
-               width="1.5"
-               height="3"
-               x="46.5"
-               y="39" />
-            <rect
-               style="color:#000000;fill:url(#linearGradient4111-6);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
-               id="rect4103-3"
-               width="19"
-               height="3"
-               x="27.5"
-               y="39" />
-          </g>
-        </g>
-        <g
-           id="g4784-8"
-           transform="translate(19,9)">
-          <g
-             inkscape:label="Shadow"
-             id="g4786-6" />
-          <g
-             style="display:inline"
-             inkscape:label="Lavoro"
-             id="g4788-1">
-            <g
-               transform="translate(0,15.06603)"
-               inkscape:label="Shadow"
-               id="g4790-6" />
-            <g
-               transform="translate(0,15.06603)"
-               style="display:inline"
-               inkscape:label="Lavoro"
-               id="g4792-6" />
-            <g
-               id="g4804-1" />
-            <g
-               transform="translate(-306.25,-49)"
-               inkscape:label="Shadow"
-               id="g4812-3" />
-            <g
-               transform="translate(-306.25,-49)"
-               style="display:inline"
-               inkscape:label="finiture"
-               id="g4814-4" />
-          </g>
-          <g
-             style="display:inline"
-             inkscape:label="finiture"
-             id="g4820-0" />
-        </g>
-        <g
-           id="g4763-9"
-           transform="matrix(1.002325,0,0,1,25.94886,20)">
-          <g
-             inkscape:label="Shadow"
-             id="g4765-6" />
-          <g
-             style="display:inline"
-             inkscape:label="Lavoro"
-             id="layer2-9-8">
-            <g
-               transform="translate(0,15.06603)"
-               inkscape:label="Shadow"
-               id="g2611-2" />
-            <g
-               transform="translate(0,15.06603)"
-               style="display:inline"
-               inkscape:label="Lavoro"
-               id="g2613-6" />
-            <rect
-               y="13.570681"
-               x="7.4910188"
-               height="3.9293196"
-               width="7.0145669"
-               id="rect1428-4"
-               style="color:#000000;fill:url(#linearGradient2238-8);fill-opacity:1;fill-rule:nonzero;stroke:#868883;stroke-width:2.43527842;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
-            <rect
-               ry="0"
-               rx="0"
-               y="0.5"
-               x="1.3479717"
-               height="14.114286"
-               width="20.064199"
-               id="rect1432-2"
-               style="color:#000000;fill:#e4e4e1;fill-opacity:1;fill-rule:nonzero;stroke:#808083;stroke-width:2.43527841999999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
-            <rect
-               ry="0"
-               rx="0"
-               y="2.6313767"
-               x="3.3600018"
-               height="9.6833715"
-               width="15.817497"
-               id="rect1434-3"
-               style="color:#000000;fill:none;stroke:#ffffff;stroke-width:2.43527841999999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
-            <rect
-               y="3.0387506"
-               x="3.6872342"
-               height="9"
-               width="15.027766"
-               id="rect1436-0"
-               style="color:#000000;fill:url(#radialGradient1509-7);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:0.99883962000000004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
-            <g
-               id="g2228-5">
-              <path
-                 sodipodi:nodetypes="cccccc"
-                 id="path2622-0"
-                 d="m 1.5537501,18.062377 19.0000009,0 0.763237,4.52391 -21.02928736,0.0094 1.26604946,-4.533336 0,2.6e-5 z"
-                 style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2277-9);stroke-width:2.43527841999999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
-              <path
-                 sodipodi:nodetypes="ccccc"
-                 id="path2626-7"
-                 d="m 2.8671752,18.781151 16.4268998,0 0.547564,1.963204 -17.5220272,0 0.5475634,-1.963204 z"
-                 style="color:#000000;fill:#bfc5ba;fill-opacity:1;fill-rule:nonzero;stroke:#b5b8b1;stroke-width:1.0356096;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
-            </g>
-            <path
-               id="path2414-2"
-               d="m 4.9226886,18.29035 c -0.017818,0.0033 -0.051307,0.0259 -0.068445,0.03068 -0.025155,0.0082 -0.079397,0.01934 -0.1026686,0.03068 -0.075268,0.041 -0.1595883,0.116587 -0.2053362,0.184049 -0.012649,0.02086 -0.025002,0.06948 -0.034223,0.09202 -0.00799,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00186,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00186,0.04486 0,0.06135 0.00416,0.02436 0.026217,0.06898 0.034223,0.09202 0.0092,0.02254 0.021574,0.07116 0.034223,0.09202 0.045743,0.06746 0.1300715,0.143045 0.2053362,0.184051 0.023272,0.01134 0.077513,0.02241 0.1026686,0.03068 0.025714,0.0071 0.075487,0.02695 0.1026685,0.03068 0.018398,0.0017 0.049554,0 0.068445,0 0.018891,0 0.050048,0.0017 0.068445,0 0.027181,-0.0038 0.076955,-0.0235 0.1026685,-0.03068 0.025155,-0.0082 0.079397,-0.01934 0.1026685,-0.03068 0.075268,-0.041 0.1595885,-0.116588 0.2053363,-0.184051 0.012649,-0.02086 0.025002,-0.06948 0.034223,-0.09202 0.00799,-0.02305 0.030061,-0.06766 0.034223,-0.09202 0.00186,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.00186,-0.04486 0,-0.06135 -0.00416,-0.02436 -0.026217,-0.06898 -0.034223,-0.09202 -0.0092,-0.02254 -0.021574,-0.07116 -0.034223,-0.09202 -0.045743,-0.06746 -0.1300715,-0.143044 -0.2053363,-0.184049 -0.023271,-0.01134 -0.077512,-0.02241 -0.1026685,-0.03068 -0.025714,-0.0071 -0.075487,-0.02695 -0.1026685,-0.03068 -0.018399,-0.0017 -0.049554,0 -0.068445,0 -0.018891,0 -0.050048,-0.0017 -0.068445,0 -0.00909,0.0013 -0.025319,-0.0017 -0.034223,0 z m 2.1902533,0 c -0.017818,0.0033 -0.051307,0.0259 -0.068445,0.03068 -0.025155,0.0082 -0.079397,0.01934 -0.1026685,0.03068 -0.075268,0.041 -0.1595884,0.116587 -0.2053363,0.184049 -0.012649,0.02086 -0.025002,0.06948 -0.034222,0.09202 -0.00799,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00186,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00186,0.04486 0,0.06135 0.00416,0.02436 0.026217,0.06898 0.034223,0.09202 0.0092,0.02254 0.021574,0.07116 0.034222,0.09202 0.045743,0.06746 0.1300715,0.143045 0.2053363,0.184051 0.023272,0.01134 0.077513,0.02241 0.1026685,0.03068 0.025714,0.0071 0.075488,0.02695 0.1026686,0.03068 0.018398,0.0017 0.049554,0 0.068445,0 0.018891,0 0.050048,0.0017 0.068445,0 0.027181,-0.0038 0.076955,-0.0235 0.1026685,-0.03068 0.025155,-0.0082 0.079397,-0.01934 0.1026685,-0.03068 0.075268,-0.041 0.1595885,-0.116588 0.2053362,-0.184051 0.012649,-0.02086 0.025002,-0.06948 0.034223,-0.09202 0.00799,-0.02305 0.030061,-0.06766 0.034223,-0.09202 0.00186,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.00186,-0.04486 0,-0.06135 -0.00416,-0.02436 -0.026217,-0.06898 -0.034223,-0.09202 -0.0092,-0.02254 -0.021574,-0.07116 -0.034223,-0.09202 C 7.6489857,18.468299 7.5646573,18.392715 7.4893925,18.35171 7.4661215,18.34037 7.4118795,18.3293 7.386724,18.32103 7.36101,18.31393 7.311237,18.29408 7.2840555,18.29035 c -0.018398,-0.0017 -0.049554,0 -0.068445,0 -0.018891,0 -0.050048,-0.0017 -0.068445,0 -0.00909,0.0013 -0.025319,-0.0017 -0.034223,0 z m 2.1902534,0 c -0.017818,0.0033 -0.051307,0.0259 -0.068445,0.03068 -0.025155,0.0082 -0.079397,0.01934 -0.1026685,0.03068 -0.075268,0.041 -0.1595884,0.116587 -0.2053363,0.184049 -0.012649,0.02086 -0.025002,0.06948 -0.034222,0.09202 -0.00799,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00186,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00186,0.04486 0,0.06135 0.00416,0.02436 0.026217,0.06898 0.034223,0.09202 0.0092,0.02254 0.021574,0.07116 0.034222,0.09202 0.045743,0.06746 0.1300715,0.143045 0.2053363,0.184051 0.023272,0.01134 0.077514,0.02241 0.1026685,0.03068 0.025714,0.0071 0.075487,0.02695 0.1026686,0.03068 0.018398,0.0017 0.049554,0 0.068445,0 0.018891,0 0.050048,0.0017 0.068445,0 0.027181,-0.0038 0.076955,-0.0235 0.1026685,-0.03068 0.025155,-0.0082 0.079397,-0.01934 0.1026685,-0.03068 0.075272,-0.041 0.1595879,-0.116588 0.205336,-0.184051 0.012653,-0.02086 0.025004,-0.06948 0.034223,-0.09202 0.00801,-0.02305 0.030061,-0.06766 0.034223,-0.09202 0.00187,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.00187,-0.04486 0,-0.06135 -0.00416,-0.02436 -0.026222,-0.06898 -0.034223,-0.09202 -0.00916,-0.02254 -0.02157,-0.07116 -0.034223,-0.09202 -0.045742,-0.06746 -0.130071,-0.143044 -0.205336,-0.184049 -0.023266,-0.01134 -0.077509,-0.02241 -0.1026685,-0.03068 -0.025714,-0.0071 -0.075487,-0.02695 -0.1026685,-0.03068 -0.018398,-0.0017 -0.049554,0 -0.068445,0 -0.018891,0 -0.050048,-0.0017 -0.068445,0 -0.00909,0.0013 -0.025319,-0.0017 -0.034223,0 z m 2.1902527,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02515,0.0082 -0.07939,0.01934 -0.10267,0.03068 -0.07527,0.041 -0.159589,0.116587 -0.205337,0.184049 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130072,0.143045 0.205337,0.184051 0.02327,0.01134 0.07751,0.02241 0.10267,0.03068 0.02571,0.0071 0.07549,0.02695 0.102669,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.10267,-0.03068 0.02515,-0.0082 0.07939,-0.01934 0.102669,-0.03068 0.07527,-0.041 0.159589,-0.116588 0.205337,-0.184051 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130072,-0.143044 -0.205337,-0.184049 -0.02327,-0.01134 -0.07751,-0.02241 -0.102669,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.10267,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.02531,-0.0017 -0.03422,0 z m 2.190254,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02516,0.0082 -0.07939,0.01934 -0.102669,0.03068 -0.07527,0.041 -0.159588,0.116587 -0.205336,0.184049 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130072,0.143045 0.205336,0.184051 0.02328,0.01134 0.07751,0.02241 0.102669,0.03068 0.02571,0.0071 0.07549,0.02695 0.10267,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.102669,-0.03068 0.02516,-0.0082 0.07939,-0.01934 0.10267,-0.03068 0.07527,-0.041 0.159589,-0.116588 0.205336,-0.184051 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130071,-0.143044 -0.205336,-0.184049 -0.02327,-0.01134 -0.07751,-0.02241 -0.10267,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.102669,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.01889,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.02531,-0.0017 -0.03422,0 z m 2.190253,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02515,0.0082 -0.07939,0.01934 -0.10267,0.03068 -0.07527,0.041 -0.159588,0.116587 -0.205336,0.184049 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130071,0.143045 0.205336,0.184051 0.02327,0.01134 0.07751,0.02241 0.10267,0.03068 0.02571,0.0071 0.07549,0.02695 0.102669,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.10267,-0.03068 0.02515,-0.0082 0.07939,-0.01934 0.102669,-0.03068 0.07527,-0.041 0.159589,-0.116588 0.205336,-0.184051 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130071,-0.143044 -0.205336,-0.184049 -0.02328,-0.01134 -0.07751,-0.02241 -0.102669,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.10267,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.0253,-0.0017 -0.03422,0 z m 2.190254,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02515,0.0082 -0.07939,0.01934 -0.102669,0.03068 -0.07527,0.041 -0.159589,0.116587 -0.205336,0.184049 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130071,0.143045 0.205336,0.184051 0.02328,0.01134 0.07751,0.02241 0.102669,0.03068 0.02571,0.0071 0.07549,0.02695 0.10267,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.102669,-0.03068 0.02515,-0.0082 0.07939,-0.01934 0.10267,-0.03068 0.07527,-0.041 0.159588,-0.116588 0.205336,-0.184051 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130072,-0.143044 -0.205336,-0.184049 -0.02327,-0.01134 -0.07751,-0.02241 -0.10267,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.102669,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.02532,-0.0017 -0.03422,0 z M 3.8275619,19.271952 c -0.017818,0.0033 -0.051307,0.0259 -0.068445,0.03068 -0.025155,0.0082 -0.079397,0.01934 -0.1026686,0.03068 -0.075268,0.041 -0.1595884,0.116587 -0.2053363,0.184049 -0.012649,0.02086 -0.025002,0.06948 -0.034223,0.09202 -0.00799,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00186,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00186,0.04486 0,0.06135 0.00416,0.02436 0.026217,0.06898 0.034223,0.09202 0.0092,0.02254 0.021574,0.07116 0.034223,0.09202 0.045743,0.06746 0.1300716,0.143044 0.2053363,0.18405 0.023272,0.01134 0.077513,0.0224 0.1026686,0.03068 0.025714,0.0071 0.075487,0.02695 0.1026685,0.03068 0.018398,0.0017 0.049554,0 0.068445,0 0.018891,0 0.050048,0.0017 0.068445,0 0.027181,-0.0038 0.076955,-0.0235 0.1026685,-0.03068 0.025155,-0.0082 0.079397,-0.01934 0.1026685,-0.03068 0.075268,-0.041 0.1595885,-0.116588 0.2053363,-0.18405 0.012649,-0.02086 0.025002,-0.06948 0.034223,-0.09202 0.00799,-0.02305 0.030061,-0.06766 0.034223,-0.09202 0.00186,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.00186,-0.04486 0,-0.06135 -0.00416,-0.02436 -0.026217,-0.06898 -0.034223,-0.09202 -0.0092,-0.02254 -0.021574,-0.07116 -0.034223,-0.09202 -0.045743,-0.06746 -0.1300715,-0.143044 -0.2053363,-0.184049 -0.023271,-0.01134 -0.077513,-0.0224 -0.1026685,-0.03068 -0.025714,-0.0071 -0.075487,-0.02695 -0.1026685,-0.03068 -0.018398,-0.0017 -0.049554,0 -0.068445,0 -0.018891,0 -0.050048,-0.0017 -0.068445,0 -0.00909,0.0013 -0.025319,-0.0017 -0.034223,0 z m 2.1902533,0 c -0.017818,0.0033 -0.051307,0.0259 -0.068445,0.03068 -0.025155,0.0082 -0.079397,0.01934 -0.1026685,0.03068 -0.075268,0.041 -0.1595884,0.116587 -0.2053362,0.184049 -0.012649,0.02086 -0.025002,0.06948 -0.034223,0.09202 -0.00799,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00186,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00186,0.04486 0,0.06135 0.00416,0.02436 0.026217,0.06898 0.034223,0.09202 0.0092,0.02254 0.021574,0.07116 0.034223,0.09202 0.045743,0.06746 0.1300714,0.143044 0.2053362,0.18405 0.023272,0.01134 0.077513,0.0224 0.1026685,0.03068 0.025714,0.0071 0.075488,0.02695 0.1026686,0.03068 0.018398,0.0017 0.049554,0 0.068445,0 0.018891,0 0.050048,0.0017 0.068445,0 0.027181,-0.0038 0.076955,-0.0235 0.1026685,-0.03068 0.025155,-0.0082 0.079397,-0.01934 0.1026685,-0.03068 0.075268,-0.041 0.1595885,-0.116588 0.2053363,-0.18405 0.012649,-0.02086 0.025002,-0.06948 0.034223,-0.09202 0.00799,-0.02305 0.030061,-0.06766 0.034223,-0.09202 0.00186,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.00186,-0.04486 0,-0.06135 -0.00416,-0.02436 -0.026217,-0.06898 -0.034223,-0.09202 -0.0092,-0.02254 -0.021574,-0.07116 -0.034223,-0.09202 -0.045743,-0.06746 -0.1300715,-0.143044 -0.2053363,-0.184049 -0.023271,-0.01134 -0.077513,-0.0224 -0.1026685,-0.03068 -0.025714,-0.0071 -0.075487,-0.02695 -0.1026685,-0.03068 -0.018398,-0.0017 -0.049554,0 -0.068445,0 -0.018891,0 -0.050048,-0.0017 -0.068445,0 -0.00909,0.0013 -0.025319,-0.0017 -0.034223,0 z m 2.1902534,0 c -0.017818,0.0033 -0.051307,0.0259 -0.068445,0.03068 -0.025155,0.0082 -0.079397,0.01934 -0.1026685,0.03068 -0.075268,0.041 -0.1595884,0.116587 -0.2053363,0.184049 -0.012649,0.02086 -0.025002,0.06948 -0.034223,0.09202 -0.00799,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00186,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00186,0.04486 0,0.06135 0.00416,0.02436 0.026217,0.06898 0.034223,0.09202 0.0092,0.02254 0.021574,0.07116 0.034223,0.09202 0.045743,0.06746 0.1300715,0.143044 0.2053363,0.18405 0.023272,0.01134 0.077513,0.0224 0.1026685,0.03068 0.025714,0.0071 0.075487,0.02695 0.1026686,0.03068 0.018399,0.0017 0.049554,0 0.068445,0 0.018891,0 0.050048,0.0017 0.068445,0 0.027181,-0.0038 0.076955,-0.0235 0.1026685,-0.03068 0.025155,-0.0082 0.079397,-0.01934 0.1026685,-0.03068 0.075268,-0.041 0.1595884,-0.116588 0.2053362,-0.18405 0.012649,-0.02086 0.025002,-0.06948 0.034223,-0.09202 0.00799,-0.02305 0.030061,-0.06766 0.034222,-0.09202 0.00186,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.00186,-0.04486 0,-0.06135 -0.00416,-0.02436 -0.026217,-0.06898 -0.034222,-0.09202 -0.0092,-0.02254 -0.021574,-0.07116 -0.034223,-0.09202 -0.045743,-0.06746 -0.1300714,-0.143044 -0.2053362,-0.184049 -0.023271,-0.01134 -0.077512,-0.0224 -0.1026685,-0.03068 -0.025714,-0.0071 -0.075487,-0.02695 -0.1026685,-0.03068 -0.018398,-0.0017 -0.049554,0 -0.068445,0 -0.018891,0 -0.050048,-0.0017 -0.068445,0 -0.00909,0.0013 -0.025319,-0.0017 -0.034222,0 z m 2.1902534,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02516,0.0082 -0.07939,0.01934 -0.102669,0.03068 -0.07527,0.041 -0.159588,0.116587 -0.205336,0.184049 -0.01265,0.02086 -0.025004,0.06948 -0.034223,0.09202 -0.00801,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00187,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00187,0.04486 0,0.06135 0.00416,0.02436 0.026222,0.06898 0.034223,0.09202 0.00916,0.02254 0.02157,0.07116 0.034223,0.09202 0.04574,0.06746 0.130072,0.143044 0.205336,0.18405 0.02328,0.01134 0.07751,0.0224 0.102669,0.03068 0.02571,0.0071 0.07549,0.02695 0.10267,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.102669,-0.03068 0.02516,-0.0082 0.07939,-0.01934 0.10267,-0.03068 0.07527,-0.041 0.159589,-0.116588 0.205336,-0.18405 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130071,-0.143044 -0.205336,-0.184049 -0.02328,-0.01134 -0.07751,-0.0224 -0.10267,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.102669,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.02531,-0.0017 -0.03422,0 z m 2.190253,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02515,0.0082 -0.07939,0.01934 -0.10267,0.03068 -0.07527,0.041 -0.159587,0.116587 -0.205336,0.184049 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130071,0.143044 0.205336,0.18405 0.02328,0.01134 0.07751,0.0224 0.10267,0.03068 0.02571,0.0071 0.07549,0.02695 0.10267,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.10267,-0.03068 0.02515,-0.0082 0.07939,-0.01934 0.102669,-0.03068 0.07527,-0.041 0.159588,-0.116588 0.205336,-0.18405 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130071,-0.143044 -0.205336,-0.184049 -0.02327,-0.01134 -0.07751,-0.0224 -0.102669,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.10267,-0.03068 -0.0184,-0.0017 -0.04956,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.02531,-0.0017 -0.03422,0 z m 2.190254,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02516,0.0082 -0.07939,0.01934 -0.10267,0.03068 -0.07527,0.041 -0.159589,0.116587 -0.205336,0.184049 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130071,0.143044 0.205336,0.18405 0.02327,0.01134 0.07751,0.0224 0.10267,0.03068 0.02571,0.0071 0.07549,0.02695 0.102669,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.102669,-0.03068 0.02516,-0.0082 0.07939,-0.01934 0.10267,-0.03068 0.07527,-0.041 0.159588,-0.116588 0.205336,-0.18405 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130072,-0.143044 -0.205336,-0.184049 -0.02328,-0.01134 -0.07751,-0.0224 -0.10267,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.102669,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.02531,-0.0017 -0.03422,0 z m 2.190253,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02515,0.0082 -0.07939,0.01934 -0.102669,0.03068 -0.07527,0.041 -0.159589,0.116587 -0.205337,0.184049 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130072,0.143044 0.205337,0.18405 0.02328,0.01134 0.07751,0.0224 0.102669,0.03068 0.02571,0.0071 0.07549,0.02695 0.10267,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.10267,-0.03068 0.02515,-0.0082 0.07939,-0.01934 0.10267,-0.03068 0.07527,-0.041 0.159588,-0.116588 0.205337,-0.18405 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130072,-0.143044 -0.205337,-0.184049 -0.02328,-0.01134 -0.07751,-0.0224 -0.10267,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.10267,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.02532,-0.0017 -0.03422,0 z M 4.9226886,20.253554 c -0.017818,0.0033 -0.051307,0.0259 -0.068445,0.03068 -0.025155,0.0082 -0.079397,0.01934 -0.1026686,0.03068 -0.075268,0.041 -0.1595883,0.116588 -0.2053362,0.184051 -0.012649,0.02086 -0.025002,0.06948 -0.034223,0.09202 -0.00799,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00186,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00186,0.04486 0,0.06135 0.00416,0.02436 0.026217,0.06898 0.034223,0.09202 0.0092,0.02254 0.021574,0.07116 0.034223,0.09202 0.045743,0.06746 0.1300715,0.143044 0.2053362,0.184049 0.023272,0.01134 0.077513,0.02241 0.1026686,0.03068 0.025714,0.0071 0.075487,0.02695 0.1026685,0.03068 0.018398,0.0017 0.049554,0 0.068445,0 0.018891,0 0.050048,0.0017 0.068445,0 0.027181,-0.0038 0.076955,-0.0235 0.1026685,-0.03068 0.025155,-0.0082 0.079397,-0.01934 0.1026685,-0.03068 0.075268,-0.041 0.1595885,-0.116587 0.2053363,-0.184049 0.012649,-0.02086 0.025002,-0.06948 0.034223,-0.09202 0.00799,-0.02305 0.030061,-0.06766 0.034223,-0.09202 0.00186,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.00186,-0.04486 0,-0.06135 -0.00416,-0.02436 -0.026217,-0.06898 -0.034223,-0.09202 -0.0092,-0.02254 -0.021574,-0.07116 -0.034223,-0.09202 -0.045743,-0.06746 -0.1300715,-0.143045 -0.2053363,-0.184051 -0.023271,-0.01134 -0.077512,-0.02241 -0.1026685,-0.03068 -0.025714,-0.0071 -0.075487,-0.02695 -0.1026685,-0.03068 -0.018399,-0.0017 -0.049554,0 -0.068445,0 -0.018891,0 -0.050048,-0.0017 -0.068445,0 -0.00909,0.0013 -0.025319,-0.0017 -0.034223,0 z m 2.1902533,0 c -0.017818,0.0033 -0.051307,0.0259 -0.068445,0.03068 -0.025155,0.0082 -0.079397,0.01934 -0.1026685,0.03068 -0.075268,0.041 -0.1595884,0.116588 -0.2053363,0.184051 -0.012649,0.02086 -0.025002,0.06948 -0.034222,0.09202 -0.00799,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00186,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00186,0.04486 0,0.06135 0.00416,0.02436 0.026217,0.06898 0.034223,0.09202 0.0092,0.02254 0.021574,0.07116 0.034222,0.09202 0.045743,0.06746 0.1300715,0.143044 0.2053363,0.184049 0.023272,0.01134 0.077513,0.02241 0.1026685,0.03068 0.025714,0.0071 0.075488,0.02695 0.1026686,0.03068 0.018398,0.0017 0.049554,0 0.068445,0 0.018891,0 0.050048,0.0017 0.068445,0 0.027181,-0.0038 0.076955,-0.0235 0.1026685,-0.03068 0.025155,-0.0082 0.079397,-0.01934 0.1026685,-0.03068 0.075268,-0.041 0.1595885,-0.116587 0.2053362,-0.184049 0.012649,-0.02086 0.025002,-0.06948 0.034223,-0.09202 0.00799,-0.02305 0.030061,-0.06766 0.034223,-0.09202 0.00186,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.00186,-0.04486 0,-0.06135 -0.00416,-0.02436 -0.026217,-0.06898 -0.034223,-0.09202 -0.0092,-0.02254 -0.021574,-0.07116 -0.034223,-0.09202 -0.045743,-0.06746 -0.1300714,-0.143045 -0.2053362,-0.184051 -0.023271,-0.01134 -0.077513,-0.02241 -0.1026685,-0.03068 -0.025714,-0.0071 -0.075487,-0.02695 -0.1026685,-0.03068 -0.018398,-0.0017 -0.049554,0 -0.068445,0 -0.018891,0 -0.050048,-0.0017 -0.068445,0 -0.00909,0.0013 -0.025319,-0.0017 -0.034223,0 z m 8.7610131,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02515,0.0082 -0.07939,0.01934 -0.10267,0.03068 -0.07527,0.041 -0.159588,0.116588 -0.205336,0.184051 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130071,0.143044 0.205336,0.184049 0.02327,0.01134 0.07751,0.02241 0.10267,0.03068 0.02571,0.0071 0.07549,0.02695 0.102669,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.10267,-0.03068 0.02515,-0.0082 0.07939,-0.01934 0.102669,-0.03068 0.07527,-0.041 0.159589,-0.116587 0.205336,-0.184049 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130071,-0.143045 -0.205336,-0.184051 -0.02328,-0.01134 -0.07751,-0.02241 -0.102669,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.10267,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.0253,-0.0017 -0.03422,0 z m 2.190254,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02515,0.0082 -0.07939,0.01934 -0.102669,0.03068 -0.07527,0.041 -0.159589,0.116588 -0.205336,0.184051 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130071,0.143044 0.205336,0.184049 0.02328,0.01134 0.07751,0.02241 0.102669,0.03068 0.02571,0.0071 0.07549,0.02695 0.10267,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.102669,-0.03068 0.02515,-0.0082 0.07939,-0.01934 0.10267,-0.03068 0.07527,-0.041 0.159588,-0.116587 0.205336,-0.184049 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130072,-0.143045 -0.205336,-0.184051 -0.02327,-0.01134 -0.07751,-0.02241 -0.10267,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.102669,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.02532,-0.0017 -0.03422,0 z"
-               style="fill:url(#radialGradient1357-5);fill-opacity:1;stroke:none" />
-            <g
-               transform="translate(-306.25,-49)"
-               inkscape:label="Shadow"
-               id="g1598-8" />
-            <g
-               transform="translate(-306.25,-49)"
-               style="display:inline"
-               inkscape:label="finiture"
-               id="g1618-0" />
-            <path
-               id="path2258-2"
-               d="m 1.6362852,21.212052 c 11.4030458,0 12.6666658,0 18.9999988,0"
-               style="fill:none;stroke:#ffffff;stroke-width:0.99883962;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-               sodipodi:nodetypes="cc" />
-            <path
-               sodipodi:nodetypes="ccccc"
-               id="rect2260-3"
-               d="m 4.2150004,3.5387508 13.9999996,0 0,3 c -7.0625,0.0625 -7,4.0000002 -13.9999996,4.0000002 l 0,-7.0000002 z"
-               style="opacity:0.30196078;color:#000000;fill:url(#linearGradient2293-1);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" />
-          </g>
-          <g
-             style="display:inline"
-             inkscape:label="finiture"
-             id="layer3-5" />
-        </g>
-        <g
-           id="g2235-4"
-           transform="matrix(0.0088651,0,0,0.01858481,16.88494,34.80067)"
-           style="display:inline" />
-        <g
-           id="g2734-3"
-           transform="matrix(1,0,0,0.714894,-1,9.15079)"
-           style="opacity:0.7" />
-      </g>
-    </g>
-    <g
-       id="g4342"
-       transform="translate(0.53033009,0.08838835)">
-      <g
-         transform="matrix(0.41015415,0,0,0.41015415,-5.7332016,29.660011)"
-         id="layer1-0"
-         inkscape:label="Layer 1">
-        <g
-           id="g4132"
-           style="opacity:0.4">
-          <g
-             transform="translate(-7,-11)"
-             id="g4118">
-            <rect
-               style="color:#000000;fill:url(#radialGradient4631);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
-               id="rect4122"
-               width="1.5"
-               height="3"
-               x="46.5"
-               y="39" />
-          </g>
-          <g
-             id="g4113">
-            <rect
-               style="color:#000000;fill:url(#radialGradient4633);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
-               id="rect4081"
-               width="1.5"
-               height="3"
-               x="-27.5"
-               y="-42"
-               transform="scale(-1,-1)" />
-            <rect
-               style="color:#000000;fill:url(#radialGradient4635);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
-               id="rect4099"
-               width="1.5"
-               height="3"
-               x="46.5"
-               y="39" />
-            <rect
-               style="color:#000000;fill:url(#linearGradient4637);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
-               id="rect4103"
-               width="19"
-               height="3"
-               x="27.5"
-               y="39" />
-          </g>
-        </g>
-        <g
-           id="g4784"
-           transform="translate(19,9)">
-          <g
-             inkscape:label="Shadow"
-             id="g4786" />
-          <g
-             style="display:inline"
-             inkscape:label="Lavoro"
-             id="g4788">
-            <g
-               transform="translate(0,15.06603)"
-               inkscape:label="Shadow"
-               id="g4790" />
-            <g
-               transform="translate(0,15.06603)"
-               style="display:inline"
-               inkscape:label="Lavoro"
-               id="g4792" />
-            <g
-               id="g4804" />
-            <g
-               transform="translate(-306.25,-49)"
-               inkscape:label="Shadow"
-               id="g4812" />
-            <g
-               transform="translate(-306.25,-49)"
-               style="display:inline"
-               inkscape:label="finiture"
-               id="g4814" />
-          </g>
-          <g
-             style="display:inline"
-             inkscape:label="finiture"
-             id="g4820" />
-        </g>
-        <g
-           id="g4763"
-           transform="matrix(1.002325,0,0,1,25.94886,20)">
-          <g
-             inkscape:label="Shadow"
-             id="g4765" />
-          <g
-             style="display:inline"
-             inkscape:label="Lavoro"
-             id="layer2-9">
-            <g
-               transform="translate(0,15.06603)"
-               inkscape:label="Shadow"
-               id="g2611" />
-            <g
-               transform="translate(0,15.06603)"
-               style="display:inline"
-               inkscape:label="Lavoro"
-               id="g2613" />
-            <rect
-               y="13.570681"
-               x="7.4910188"
-               height="3.9293196"
-               width="7.0145669"
-               id="rect1428"
-               style="color:#000000;fill:url(#linearGradient4639);fill-opacity:1;fill-rule:nonzero;stroke:#868883;stroke-width:2.43527842;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
-            <rect
-               ry="0"
-               rx="0"
-               y="0.5"
-               x="1.3099647"
-               height="13.923809"
-               width="19.912169"
-               id="rect1432"
-               style="color:#000000;fill:#e4e4e1;fill-opacity:1;fill-rule:nonzero;stroke:#808083;stroke-width:2.43527842;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
-            <rect
-               ry="0"
-               rx="0"
-               y="2.6313767"
-               x="3.3600018"
-               height="9.6833715"
-               width="15.817497"
-               id="rect1434"
-               style="color:#000000;fill:none;stroke:#ffffff;stroke-width:2.43527841999999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
-            <rect
-               y="3.0387506"
-               x="3.6872342"
-               height="9"
-               width="15.027766"
-               id="rect1436"
-               style="color:#000000;fill:url(#radialGradient4641);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:0.99883962000000004;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
-            <g
-               id="g2228">
-              <path
-                 sodipodi:nodetypes="ccccc"
-                 id="path2622"
-                 d="m 1.5537501,18.062377 19.0000009,0 1.029286,3.990574 -21.02928689,0.0094 0.99999999,-4 z"
-                 style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4643);stroke-width:2.43527841999999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
-              <path
-                 sodipodi:nodetypes="ccccc"
-                 id="path2626"
-                 d="m 2.8671752,18.781151 16.4268998,0 0.547564,1.963204 -17.5220272,0 0.5475634,-1.963204 z"
-                 style="color:#000000;fill:#bfc5ba;fill-opacity:1;fill-rule:nonzero;stroke:#b5b8b1;stroke-width:1.0356096;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
-            </g>
-            <path
-               id="path2414"
-               d="m 4.9226886,18.29035 c -0.017818,0.0033 -0.051307,0.0259 -0.068445,0.03068 -0.025155,0.0082 -0.079397,0.01934 -0.1026686,0.03068 -0.075268,0.041 -0.1595883,0.116587 -0.2053362,0.184049 -0.012649,0.02086 -0.025002,0.06948 -0.034223,0.09202 -0.00799,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00186,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00186,0.04486 0,0.06135 0.00416,0.02436 0.026217,0.06898 0.034223,0.09202 0.0092,0.02254 0.021574,0.07116 0.034223,0.09202 0.045743,0.06746 0.1300715,0.143045 0.2053362,0.184051 0.023272,0.01134 0.077513,0.02241 0.1026686,0.03068 0.025714,0.0071 0.075487,0.02695 0.1026685,0.03068 0.018398,0.0017 0.049554,0 0.068445,0 0.018891,0 0.050048,0.0017 0.068445,0 0.027181,-0.0038 0.076955,-0.0235 0.1026685,-0.03068 0.025155,-0.0082 0.079397,-0.01934 0.1026685,-0.03068 0.075268,-0.041 0.1595885,-0.116588 0.2053363,-0.184051 0.012649,-0.02086 0.025002,-0.06948 0.034223,-0.09202 0.00799,-0.02305 0.030061,-0.06766 0.034223,-0.09202 0.00186,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.00186,-0.04486 0,-0.06135 -0.00416,-0.02436 -0.026217,-0.06898 -0.034223,-0.09202 -0.0092,-0.02254 -0.021574,-0.07116 -0.034223,-0.09202 -0.045743,-0.06746 -0.1300715,-0.143044 -0.2053363,-0.184049 -0.023271,-0.01134 -0.077512,-0.02241 -0.1026685,-0.03068 -0.025714,-0.0071 -0.075487,-0.02695 -0.1026685,-0.03068 -0.018399,-0.0017 -0.049554,0 -0.068445,0 -0.018891,0 -0.050048,-0.0017 -0.068445,0 -0.00909,0.0013 -0.025319,-0.0017 -0.034223,0 z m 2.1902533,0 c -0.017818,0.0033 -0.051307,0.0259 -0.068445,0.03068 -0.025155,0.0082 -0.079397,0.01934 -0.1026685,0.03068 -0.075268,0.041 -0.1595884,0.116587 -0.2053363,0.184049 -0.012649,0.02086 -0.025002,0.06948 -0.034222,0.09202 -0.00799,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00186,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00186,0.04486 0,0.06135 0.00416,0.02436 0.026217,0.06898 0.034223,0.09202 0.0092,0.02254 0.021574,0.07116 0.034222,0.09202 0.045743,0.06746 0.1300715,0.143045 0.2053363,0.184051 0.023272,0.01134 0.077513,0.02241 0.1026685,0.03068 0.025714,0.0071 0.075488,0.02695 0.1026686,0.03068 0.018398,0.0017 0.049554,0 0.068445,0 0.018891,0 0.050048,0.0017 0.068445,0 0.027181,-0.0038 0.076955,-0.0235 0.1026685,-0.03068 0.025155,-0.0082 0.079397,-0.01934 0.1026685,-0.03068 0.075268,-0.041 0.1595885,-0.116588 0.2053362,-0.184051 0.012649,-0.02086 0.025002,-0.06948 0.034223,-0.09202 0.00799,-0.02305 0.030061,-0.06766 0.034223,-0.09202 0.00186,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.00186,-0.04486 0,-0.06135 -0.00416,-0.02436 -0.026217,-0.06898 -0.034223,-0.09202 -0.0092,-0.02254 -0.021574,-0.07116 -0.034223,-0.09202 C 7.6489857,18.468299 7.5646573,18.392715 7.4893925,18.35171 7.4661215,18.34037 7.4118795,18.3293 7.386724,18.32103 7.36101,18.31393 7.311237,18.29408 7.2840555,18.29035 c -0.018398,-0.0017 -0.049554,0 -0.068445,0 -0.018891,0 -0.050048,-0.0017 -0.068445,0 -0.00909,0.0013 -0.025319,-0.0017 -0.034223,0 z m 2.1902534,0 c -0.017818,0.0033 -0.051307,0.0259 -0.068445,0.03068 -0.025155,0.0082 -0.079397,0.01934 -0.1026685,0.03068 -0.075268,0.041 -0.1595884,0.116587 -0.2053363,0.184049 -0.012649,0.02086 -0.025002,0.06948 -0.034222,0.09202 -0.00799,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00186,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00186,0.04486 0,0.06135 0.00416,0.02436 0.026217,0.06898 0.034223,0.09202 0.0092,0.02254 0.021574,0.07116 0.034222,0.09202 0.045743,0.06746 0.1300715,0.143045 0.2053363,0.184051 0.023272,0.01134 0.077514,0.02241 0.1026685,0.03068 0.025714,0.0071 0.075487,0.02695 0.1026686,0.03068 0.018398,0.0017 0.049554,0 0.068445,0 0.018891,0 0.050048,0.0017 0.068445,0 0.027181,-0.0038 0.076955,-0.0235 0.1026685,-0.03068 0.025155,-0.0082 0.079397,-0.01934 0.1026685,-0.03068 0.075272,-0.041 0.1595879,-0.116588 0.205336,-0.184051 0.012653,-0.02086 0.025004,-0.06948 0.034223,-0.09202 0.00801,-0.02305 0.030061,-0.06766 0.034223,-0.09202 0.00187,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.00187,-0.04486 0,-0.06135 -0.00416,-0.02436 -0.026222,-0.06898 -0.034223,-0.09202 -0.00916,-0.02254 -0.02157,-0.07116 -0.034223,-0.09202 -0.045742,-0.06746 -0.130071,-0.143044 -0.205336,-0.184049 -0.023266,-0.01134 -0.077509,-0.02241 -0.1026685,-0.03068 -0.025714,-0.0071 -0.075487,-0.02695 -0.1026685,-0.03068 -0.018398,-0.0017 -0.049554,0 -0.068445,0 -0.018891,0 -0.050048,-0.0017 -0.068445,0 -0.00909,0.0013 -0.025319,-0.0017 -0.034223,0 z m 2.1902527,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02515,0.0082 -0.07939,0.01934 -0.10267,0.03068 -0.07527,0.041 -0.159589,0.116587 -0.205337,0.184049 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130072,0.143045 0.205337,0.184051 0.02327,0.01134 0.07751,0.02241 0.10267,0.03068 0.02571,0.0071 0.07549,0.02695 0.102669,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.10267,-0.03068 0.02515,-0.0082 0.07939,-0.01934 0.102669,-0.03068 0.07527,-0.041 0.159589,-0.116588 0.205337,-0.184051 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130072,-0.143044 -0.205337,-0.184049 -0.02327,-0.01134 -0.07751,-0.02241 -0.102669,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.10267,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.02531,-0.0017 -0.03422,0 z m 2.190254,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02516,0.0082 -0.07939,0.01934 -0.102669,0.03068 -0.07527,0.041 -0.159588,0.116587 -0.205336,0.184049 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130072,0.143045 0.205336,0.184051 0.02328,0.01134 0.07751,0.02241 0.102669,0.03068 0.02571,0.0071 0.07549,0.02695 0.10267,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.102669,-0.03068 0.02516,-0.0082 0.07939,-0.01934 0.10267,-0.03068 0.07527,-0.041 0.159589,-0.116588 0.205336,-0.184051 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130071,-0.143044 -0.205336,-0.184049 -0.02327,-0.01134 -0.07751,-0.02241 -0.10267,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.102669,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.01889,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.02531,-0.0017 -0.03422,0 z m 2.190253,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02515,0.0082 -0.07939,0.01934 -0.10267,0.03068 -0.07527,0.041 -0.159588,0.116587 -0.205336,0.184049 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130071,0.143045 0.205336,0.184051 0.02327,0.01134 0.07751,0.02241 0.10267,0.03068 0.02571,0.0071 0.07549,0.02695 0.102669,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.10267,-0.03068 0.02515,-0.0082 0.07939,-0.01934 0.102669,-0.03068 0.07527,-0.041 0.159589,-0.116588 0.205336,-0.184051 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130071,-0.143044 -0.205336,-0.184049 -0.02328,-0.01134 -0.07751,-0.02241 -0.102669,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.10267,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.0253,-0.0017 -0.03422,0 z m 2.190254,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02515,0.0082 -0.07939,0.01934 -0.102669,0.03068 -0.07527,0.041 -0.159589,0.116587 -0.205336,0.184049 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130071,0.143045 0.205336,0.184051 0.02328,0.01134 0.07751,0.02241 0.102669,0.03068 0.02571,0.0071 0.07549,0.02695 0.10267,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.102669,-0.03068 0.02515,-0.0082 0.07939,-0.01934 0.10267,-0.03068 0.07527,-0.041 0.159588,-0.116588 0.205336,-0.184051 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130072,-0.143044 -0.205336,-0.184049 -0.02327,-0.01134 -0.07751,-0.02241 -0.10267,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.102669,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.02532,-0.0017 -0.03422,0 z M 3.8275619,19.271952 c -0.017818,0.0033 -0.051307,0.0259 -0.068445,0.03068 -0.025155,0.0082 -0.079397,0.01934 -0.1026686,0.03068 -0.075268,0.041 -0.1595884,0.116587 -0.2053363,0.184049 -0.012649,0.02086 -0.025002,0.06948 -0.034223,0.09202 -0.00799,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00186,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00186,0.04486 0,0.06135 0.00416,0.02436 0.026217,0.06898 0.034223,0.09202 0.0092,0.02254 0.021574,0.07116 0.034223,0.09202 0.045743,0.06746 0.1300716,0.143044 0.2053363,0.18405 0.023272,0.01134 0.077513,0.0224 0.1026686,0.03068 0.025714,0.0071 0.075487,0.02695 0.1026685,0.03068 0.018398,0.0017 0.049554,0 0.068445,0 0.018891,0 0.050048,0.0017 0.068445,0 0.027181,-0.0038 0.076955,-0.0235 0.1026685,-0.03068 0.025155,-0.0082 0.079397,-0.01934 0.1026685,-0.03068 0.075268,-0.041 0.1595885,-0.116588 0.2053363,-0.18405 0.012649,-0.02086 0.025002,-0.06948 0.034223,-0.09202 0.00799,-0.02305 0.030061,-0.06766 0.034223,-0.09202 0.00186,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.00186,-0.04486 0,-0.06135 -0.00416,-0.02436 -0.026217,-0.06898 -0.034223,-0.09202 -0.0092,-0.02254 -0.021574,-0.07116 -0.034223,-0.09202 -0.045743,-0.06746 -0.1300715,-0.143044 -0.2053363,-0.184049 -0.023271,-0.01134 -0.077513,-0.0224 -0.1026685,-0.03068 -0.025714,-0.0071 -0.075487,-0.02695 -0.1026685,-0.03068 -0.018398,-0.0017 -0.049554,0 -0.068445,0 -0.018891,0 -0.050048,-0.0017 -0.068445,0 -0.00909,0.0013 -0.025319,-0.0017 -0.034223,0 z m 2.1902533,0 c -0.017818,0.0033 -0.051307,0.0259 -0.068445,0.03068 -0.025155,0.0082 -0.079397,0.01934 -0.1026685,0.03068 -0.075268,0.041 -0.1595884,0.116587 -0.2053362,0.184049 -0.012649,0.02086 -0.025002,0.06948 -0.034223,0.09202 -0.00799,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00186,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00186,0.04486 0,0.06135 0.00416,0.02436 0.026217,0.06898 0.034223,0.09202 0.0092,0.02254 0.021574,0.07116 0.034223,0.09202 0.045743,0.06746 0.1300714,0.143044 0.2053362,0.18405 0.023272,0.01134 0.077513,0.0224 0.1026685,0.03068 0.025714,0.0071 0.075488,0.02695 0.1026686,0.03068 0.018398,0.0017 0.049554,0 0.068445,0 0.018891,0 0.050048,0.0017 0.068445,0 0.027181,-0.0038 0.076955,-0.0235 0.1026685,-0.03068 0.025155,-0.0082 0.079397,-0.01934 0.1026685,-0.03068 0.075268,-0.041 0.1595885,-0.116588 0.2053363,-0.18405 0.012649,-0.02086 0.025002,-0.06948 0.034223,-0.09202 0.00799,-0.02305 0.030061,-0.06766 0.034223,-0.09202 0.00186,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.00186,-0.04486 0,-0.06135 -0.00416,-0.02436 -0.026217,-0.06898 -0.034223,-0.09202 -0.0092,-0.02254 -0.021574,-0.07116 -0.034223,-0.09202 -0.045743,-0.06746 -0.1300715,-0.143044 -0.2053363,-0.184049 -0.023271,-0.01134 -0.077513,-0.0224 -0.1026685,-0.03068 -0.025714,-0.0071 -0.075487,-0.02695 -0.1026685,-0.03068 -0.018398,-0.0017 -0.049554,0 -0.068445,0 -0.018891,0 -0.050048,-0.0017 -0.068445,0 -0.00909,0.0013 -0.025319,-0.0017 -0.034223,0 z m 2.1902534,0 c -0.017818,0.0033 -0.051307,0.0259 -0.068445,0.03068 -0.025155,0.0082 -0.079397,0.01934 -0.1026685,0.03068 -0.075268,0.041 -0.1595884,0.116587 -0.2053363,0.184049 -0.012649,0.02086 -0.025002,0.06948 -0.034223,0.09202 -0.00799,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00186,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00186,0.04486 0,0.06135 0.00416,0.02436 0.026217,0.06898 0.034223,0.09202 0.0092,0.02254 0.021574,0.07116 0.034223,0.09202 0.045743,0.06746 0.1300715,0.143044 0.2053363,0.18405 0.023272,0.01134 0.077513,0.0224 0.1026685,0.03068 0.025714,0.0071 0.075487,0.02695 0.1026686,0.03068 0.018399,0.0017 0.049554,0 0.068445,0 0.018891,0 0.050048,0.0017 0.068445,0 0.027181,-0.0038 0.076955,-0.0235 0.1026685,-0.03068 0.025155,-0.0082 0.079397,-0.01934 0.1026685,-0.03068 0.075268,-0.041 0.1595884,-0.116588 0.2053362,-0.18405 0.012649,-0.02086 0.025002,-0.06948 0.034223,-0.09202 0.00799,-0.02305 0.030061,-0.06766 0.034222,-0.09202 0.00186,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.00186,-0.04486 0,-0.06135 -0.00416,-0.02436 -0.026217,-0.06898 -0.034222,-0.09202 -0.0092,-0.02254 -0.021574,-0.07116 -0.034223,-0.09202 -0.045743,-0.06746 -0.1300714,-0.143044 -0.2053362,-0.184049 -0.023271,-0.01134 -0.077512,-0.0224 -0.1026685,-0.03068 -0.025714,-0.0071 -0.075487,-0.02695 -0.1026685,-0.03068 -0.018398,-0.0017 -0.049554,0 -0.068445,0 -0.018891,0 -0.050048,-0.0017 -0.068445,0 -0.00909,0.0013 -0.025319,-0.0017 -0.034222,0 z m 2.1902534,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02516,0.0082 -0.07939,0.01934 -0.102669,0.03068 -0.07527,0.041 -0.159588,0.116587 -0.205336,0.184049 -0.01265,0.02086 -0.025004,0.06948 -0.034223,0.09202 -0.00801,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00187,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00187,0.04486 0,0.06135 0.00416,0.02436 0.026222,0.06898 0.034223,0.09202 0.00916,0.02254 0.02157,0.07116 0.034223,0.09202 0.04574,0.06746 0.130072,0.143044 0.205336,0.18405 0.02328,0.01134 0.07751,0.0224 0.102669,0.03068 0.02571,0.0071 0.07549,0.02695 0.10267,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.102669,-0.03068 0.02516,-0.0082 0.07939,-0.01934 0.10267,-0.03068 0.07527,-0.041 0.159589,-0.116588 0.205336,-0.18405 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130071,-0.143044 -0.205336,-0.184049 -0.02328,-0.01134 -0.07751,-0.0224 -0.10267,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.102669,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.02531,-0.0017 -0.03422,0 z m 2.190253,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02515,0.0082 -0.07939,0.01934 -0.10267,0.03068 -0.07527,0.041 -0.159587,0.116587 -0.205336,0.184049 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130071,0.143044 0.205336,0.18405 0.02328,0.01134 0.07751,0.0224 0.10267,0.03068 0.02571,0.0071 0.07549,0.02695 0.10267,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.10267,-0.03068 0.02515,-0.0082 0.07939,-0.01934 0.102669,-0.03068 0.07527,-0.041 0.159588,-0.116588 0.205336,-0.18405 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130071,-0.143044 -0.205336,-0.184049 -0.02327,-0.01134 -0.07751,-0.0224 -0.102669,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.10267,-0.03068 -0.0184,-0.0017 -0.04956,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.02531,-0.0017 -0.03422,0 z m 2.190254,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02516,0.0082 -0.07939,0.01934 -0.10267,0.03068 -0.07527,0.041 -0.159589,0.116587 -0.205336,0.184049 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130071,0.143044 0.205336,0.18405 0.02327,0.01134 0.07751,0.0224 0.10267,0.03068 0.02571,0.0071 0.07549,0.02695 0.102669,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.102669,-0.03068 0.02516,-0.0082 0.07939,-0.01934 0.10267,-0.03068 0.07527,-0.041 0.159588,-0.116588 0.205336,-0.18405 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130072,-0.143044 -0.205336,-0.184049 -0.02328,-0.01134 -0.07751,-0.0224 -0.10267,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.102669,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.02531,-0.0017 -0.03422,0 z m 2.190253,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02515,0.0082 -0.07939,0.01934 -0.102669,0.03068 -0.07527,0.041 -0.159589,0.116587 -0.205337,0.184049 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130072,0.143044 0.205337,0.18405 0.02328,0.01134 0.07751,0.0224 0.102669,0.03068 0.02571,0.0071 0.07549,0.02695 0.10267,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.10267,-0.03068 0.02515,-0.0082 0.07939,-0.01934 0.10267,-0.03068 0.07527,-0.041 0.159588,-0.116588 0.205337,-0.18405 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130072,-0.143044 -0.205337,-0.184049 -0.02328,-0.01134 -0.07751,-0.0224 -0.10267,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.10267,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.02532,-0.0017 -0.03422,0 z M 4.9226886,20.253554 c -0.017818,0.0033 -0.051307,0.0259 -0.068445,0.03068 -0.025155,0.0082 -0.079397,0.01934 -0.1026686,0.03068 -0.075268,0.041 -0.1595883,0.116588 -0.2053362,0.184051 -0.012649,0.02086 -0.025002,0.06948 -0.034223,0.09202 -0.00799,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00186,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00186,0.04486 0,0.06135 0.00416,0.02436 0.026217,0.06898 0.034223,0.09202 0.0092,0.02254 0.021574,0.07116 0.034223,0.09202 0.045743,0.06746 0.1300715,0.143044 0.2053362,0.184049 0.023272,0.01134 0.077513,0.02241 0.1026686,0.03068 0.025714,0.0071 0.075487,0.02695 0.1026685,0.03068 0.018398,0.0017 0.049554,0 0.068445,0 0.018891,0 0.050048,0.0017 0.068445,0 0.027181,-0.0038 0.076955,-0.0235 0.1026685,-0.03068 0.025155,-0.0082 0.079397,-0.01934 0.1026685,-0.03068 0.075268,-0.041 0.1595885,-0.116587 0.2053363,-0.184049 0.012649,-0.02086 0.025002,-0.06948 0.034223,-0.09202 0.00799,-0.02305 0.030061,-0.06766 0.034223,-0.09202 0.00186,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.00186,-0.04486 0,-0.06135 -0.00416,-0.02436 -0.026217,-0.06898 -0.034223,-0.09202 -0.0092,-0.02254 -0.021574,-0.07116 -0.034223,-0.09202 -0.045743,-0.06746 -0.1300715,-0.143045 -0.2053363,-0.184051 -0.023271,-0.01134 -0.077512,-0.02241 -0.1026685,-0.03068 -0.025714,-0.0071 -0.075487,-0.02695 -0.1026685,-0.03068 -0.018399,-0.0017 -0.049554,0 -0.068445,0 -0.018891,0 -0.050048,-0.0017 -0.068445,0 -0.00909,0.0013 -0.025319,-0.0017 -0.034223,0 z m 2.1902533,0 c -0.017818,0.0033 -0.051307,0.0259 -0.068445,0.03068 -0.025155,0.0082 -0.079397,0.01934 -0.1026685,0.03068 -0.075268,0.041 -0.1595884,0.116588 -0.2053363,0.184051 -0.012649,0.02086 -0.025002,0.06948 -0.034222,0.09202 -0.00799,0.02305 -0.030061,0.06766 -0.034223,0.09202 -0.00186,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.00186,0.04486 0,0.06135 0.00416,0.02436 0.026217,0.06898 0.034223,0.09202 0.0092,0.02254 0.021574,0.07116 0.034222,0.09202 0.045743,0.06746 0.1300715,0.143044 0.2053363,0.184049 0.023272,0.01134 0.077513,0.02241 0.1026685,0.03068 0.025714,0.0071 0.075488,0.02695 0.1026686,0.03068 0.018398,0.0017 0.049554,0 0.068445,0 0.018891,0 0.050048,0.0017 0.068445,0 0.027181,-0.0038 0.076955,-0.0235 0.1026685,-0.03068 0.025155,-0.0082 0.079397,-0.01934 0.1026685,-0.03068 0.075268,-0.041 0.1595885,-0.116587 0.2053362,-0.184049 0.012649,-0.02086 0.025002,-0.06948 0.034223,-0.09202 0.00799,-0.02305 0.030061,-0.06766 0.034223,-0.09202 0.00186,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.00186,-0.04486 0,-0.06135 -0.00416,-0.02436 -0.026217,-0.06898 -0.034223,-0.09202 -0.0092,-0.02254 -0.021574,-0.07116 -0.034223,-0.09202 -0.045743,-0.06746 -0.1300714,-0.143045 -0.2053362,-0.184051 -0.023271,-0.01134 -0.077513,-0.02241 -0.1026685,-0.03068 -0.025714,-0.0071 -0.075487,-0.02695 -0.1026685,-0.03068 -0.018398,-0.0017 -0.049554,0 -0.068445,0 -0.018891,0 -0.050048,-0.0017 -0.068445,0 -0.00909,0.0013 -0.025319,-0.0017 -0.034223,0 z m 8.7610131,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02515,0.0082 -0.07939,0.01934 -0.10267,0.03068 -0.07527,0.041 -0.159588,0.116588 -0.205336,0.184051 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130071,0.143044 0.205336,0.184049 0.02327,0.01134 0.07751,0.02241 0.10267,0.03068 0.02571,0.0071 0.07549,0.02695 0.102669,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.10267,-0.03068 0.02515,-0.0082 0.07939,-0.01934 0.102669,-0.03068 0.07527,-0.041 0.159589,-0.116587 0.205336,-0.184049 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130071,-0.143045 -0.205336,-0.184051 -0.02328,-0.01134 -0.07751,-0.02241 -0.102669,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.10267,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.0253,-0.0017 -0.03422,0 z m 2.190254,0 c -0.01781,0.0033 -0.05131,0.0259 -0.06845,0.03068 -0.02515,0.0082 -0.07939,0.01934 -0.102669,0.03068 -0.07527,0.041 -0.159589,0.116588 -0.205336,0.184051 -0.01265,0.02086 -0.025,0.06948 -0.03422,0.09202 -0.008,0.02305 -0.03006,0.06766 -0.03422,0.09202 -0.0019,0.01649 0,0.04442 0,0.06135 0,0.01693 -0.0019,0.04486 0,0.06135 0.0042,0.02436 0.02622,0.06898 0.03422,0.09202 0.0092,0.02254 0.02157,0.07116 0.03422,0.09202 0.04574,0.06746 0.130071,0.143044 0.205336,0.184049 0.02328,0.01134 0.07751,0.02241 0.102669,0.03068 0.02571,0.0071 0.07549,0.02695 0.10267,0.03068 0.0184,0.0017 0.04955,0 0.06845,0 0.0189,0 0.05005,0.0017 0.06845,0 0.02718,-0.0038 0.07696,-0.0235 0.102669,-0.03068 0.02515,-0.0082 0.07939,-0.01934 0.10267,-0.03068 0.07527,-0.041 0.159588,-0.116587 0.205336,-0.184049 0.01265,-0.02086 0.025,-0.06948 0.03422,-0.09202 0.008,-0.02305 0.03006,-0.06766 0.03422,-0.09202 0.0019,-0.01649 0,-0.04442 0,-0.06135 0,-0.01693 0.0019,-0.04486 0,-0.06135 -0.0042,-0.02436 -0.02622,-0.06898 -0.03422,-0.09202 -0.0092,-0.02254 -0.02157,-0.07116 -0.03422,-0.09202 -0.04574,-0.06746 -0.130072,-0.143045 -0.205336,-0.184051 -0.02327,-0.01134 -0.07751,-0.02241 -0.10267,-0.03068 -0.02571,-0.0071 -0.07549,-0.02695 -0.102669,-0.03068 -0.0184,-0.0017 -0.04955,0 -0.06845,0 -0.0189,0 -0.05005,-0.0017 -0.06845,0 -0.0091,0.0013 -0.02532,-0.0017 -0.03422,0 z"
-               style="fill:url(#radialGradient4645);fill-opacity:1;stroke:none" />
-            <g
-               transform="translate(-306.25,-49)"
-               inkscape:label="Shadow"
-               id="g1598" />
-            <g
-               transform="translate(-306.25,-49)"
-               style="display:inline"
-               inkscape:label="finiture"
-               id="g1618" />
-            <path
-               id="path2258"
-               d="m 1.5629721,20.846877 18.9999999,0"
-               style="fill:none;stroke:#ffffff;stroke-width:0.99846411;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
-            <path
-               sodipodi:nodetypes="ccccc"
-               id="rect2260"
-               d="m 4.2150004,3.5387508 13.9999996,0 0,3 c -7.0625,0.0625 -7,4.0000002 -13.9999996,4.0000002 l 0,-7.0000002 z"
-               style="opacity:0.30196078;color:#000000;fill:url(#linearGradient4647);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" />
-          </g>
-          <g
-             style="display:inline"
-             inkscape:label="finiture"
-             id="layer3" />
-        </g>
-        <g
-           id="g2235"
-           transform="matrix(0.0088651,0,0,0.01858481,16.88494,34.80067)"
-           style="display:inline" />
-        <g
-           id="g2734"
-           transform="matrix(1,0,0,0.714894,-1,9.15079)"
-           style="opacity:0.7" />
-      </g>
-    </g>
-  </g>
-</svg>
diff --git a/images/protocol-chat_256x256.png b/images/protocol-chat_256x256.png
new file mode 100644
index 0000000..bf466d5
Binary files /dev/null and b/images/protocol-chat_256x256.png differ
diff --git a/images/session-chat.svg b/images/session-chat.svg
deleted file mode 100644
index 9a503c1..0000000
--- a/images/session-chat.svg
+++ /dev/null
@@ -1,260 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="16"
-   height="16"
-   id="svg1328"
-   sodipodi:version="0.32"
-   inkscape:version="0.47 r22583"
-   sodipodi:docname="session-chat.svg"
-   inkscape:output_extension="org.inkscape.output.svg.inkscape"
-   version="1.1">
-  <sodipodi:namedview
-     inkscape:cy="9.8974181"
-     inkscape:cx="8.7592106"
-     inkscape:zoom="32"
-     inkscape:window-height="1026"
-     inkscape:window-width="1680"
-     inkscape:pageshadow="2"
-     inkscape:pageopacity="0.0"
-     guidetolerance="10.0"
-     gridtolerance="10.0"
-     objecttolerance="10.0"
-     borderopacity="0.31764706"
-     bordercolor="#666"
-     pagecolor="#ffffff"
-     id="base"
-     inkscape:showpageshadow="false"
-     showgrid="false"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:current-layer="layer1"
-     inkscape:window-maximized="1" />
-  <defs
-     id="defs1330">
-    <inkscape:perspective
-       sodipodi:type="inkscape:persp3d"
-       inkscape:vp_x="0 : 24 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_z="48 : 24 : 1"
-       inkscape:persp3d-origin="24 : 16 : 1"
-       id="perspective32" />
-    <linearGradient
-       id="linearGradient2804">
-      <stop
-         style="stop-color:black;stop-opacity:0;"
-         offset="0"
-         id="stop2806" />
-      <stop
-         id="stop2812"
-         offset="0.5"
-         style="stop-color:black;stop-opacity:1;" />
-      <stop
-         style="stop-color:black;stop-opacity:0;"
-         offset="1"
-         id="stop2808" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient2781">
-      <stop
-         style="stop-color:black;stop-opacity:1;"
-         offset="0"
-         id="stop2783" />
-      <stop
-         style="stop-color:black;stop-opacity:0;"
-         offset="1"
-         id="stop2785" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient2782">
-      <stop
-         style="stop-color:white;stop-opacity:1;"
-         offset="0"
-         id="stop2784" />
-      <stop
-         style="stop-color:white;stop-opacity:0;"
-         offset="1"
-         id="stop2786" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient5106">
-      <stop
-         style="stop-color:#729fcf;stop-opacity:1;"
-         offset="0"
-         id="stop5108" />
-      <stop
-         style="stop-color:#386ea6;stop-opacity:1;"
-         offset="1"
-         id="stop5110" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient5106"
-       id="linearGradient2780"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.89976686,0,0,0.91323462,0.770616,31.810865)"
-       x1="8.1771841"
-       y1="5.8576875"
-       x2="8.1771841"
-       y2="15.676654" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2782"
-       id="linearGradient2788"
-       x1="26.0625"
-       y1="23.265625"
-       x2="29.03125"
-       y2="55.265625"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.28680891,0,0,0.28680891,1.2712629,33.483916)" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2781"
-       id="radialGradient2827"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(2,0,0,0.8,-13,-79.2)"
-       cx="1"
-       cy="44"
-       fx="1"
-       fy="44"
-       r="5" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2781"
-       id="radialGradient2829"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(2,0,0,0.8,36,8.8)"
-       cx="1"
-       cy="44"
-       fx="1"
-       fy="44"
-       r="5" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2804"
-       id="linearGradient2831"
-       gradientUnits="userSpaceOnUse"
-       x1="21.875"
-       y1="48.000977"
-       x2="21.875"
-       y2="40" />
-  </defs>
-  <sodipodi:namedview
-     id="namedview21"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="9.8994949"
-     inkscape:cx="24"
-     inkscape:cy="24"
-     inkscape:current-layer="layer1"
-     showgrid="true"
-     inkscape:grid-bbox="true"
-     inkscape:document-units="px"
-     inkscape:window-width="736"
-     inkscape:window-height="851"
-     inkscape:window-x="214"
-     inkscape:window-y="28" />
-  <metadata
-     id="metadata1333">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title>Go Home</dc:title>
-        <dc:subject>
-          <rdf:Bag>
-            <rdf:li>go</rdf:li>
-            <rdf:li>seek</rdf:li>
-            <rdf:li>home</rdf:li>
-          </rdf:Bag>
-        </dc:subject>
-        <dc:creator>
-          <cc:Agent>
-            <dc:title>Rodney Dawes</dc:title>
-          </cc:Agent>
-        </dc:creator>
-        <dc:contributor>
-          <cc:Agent>
-            <dc:title>Jakub Steiner</dc:title>
-          </cc:Agent>
-        </dc:contributor>
-        <cc:license
-           rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
-      </cc:Work>
-      <cc:License
-         rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
-        <cc:permits
-           rdf:resource="http://web.resource.org/cc/Reproduction" />
-        <cc:permits
-           rdf:resource="http://web.resource.org/cc/Distribution" />
-        <cc:requires
-           rdf:resource="http://web.resource.org/cc/Notice" />
-        <cc:permits
-           rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
-        <cc:requires
-           rdf:resource="http://web.resource.org/cc/ShareAlike" />
-        <cc:requires
-           rdf:resource="http://web.resource.org/cc/SourceCode" />
-      </cc:License>
-    </rdf:RDF>
-  </metadata>
-  <g
-     id="layer1"
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     transform="translate(0,-32)">
-    <g
-       id="g2822"
-       style="opacity:0.3"
-       transform="matrix(0.28680892,0,0,0.29753472,1.2314267,32.732228)">
-      <rect
-         transform="scale(-1,-1)"
-         y="-48"
-         x="-11"
-         height="8"
-         width="10"
-         id="rect1892"
-         style="color:#000000;fill:url(#radialGradient2827);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" />
-      <rect
-         y="40"
-         x="38"
-         height="8"
-         width="10"
-         id="rect2789"
-         style="color:#000000;fill:url(#radialGradient2829);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" />
-      <rect
-         y="40"
-         x="11"
-         height="8"
-         width="27"
-         id="rect2793"
-         style="color:#000000;fill:url(#linearGradient2831);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" />
-    </g>
-    <path
-       style="color:#000000;fill:url(#linearGradient2780);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:0.90138447;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
-       d="m 8.1281758,33.637334 -6.5474193,6.903034 1.5109807,0 0.017925,5.443556 10.3244838,-0.01793 -0.04226,-5.456153 1.283708,0.0126 -2.677203,-2.818949 0.0026,-3.485229 -2.0202173,-0.0025 0.00907,1.33751 -1.8616665,-1.915822 z"
-       id="rect5117"
-       sodipodi:nodetypes="cccccccccccc" />
-    <path
-       style="opacity:0.41237111;color:#000000;fill:none;stroke:url(#linearGradient2788);stroke-width:0.90138441;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
-       d="m 8.1437186,34.946098 -4.4653091,4.673388 0.064577,0 c 0.068393,-1.92e-4 0.1340407,0.0269 0.1824021,0.07526 0.048361,0.04837 0.075445,0.114008 0.075256,0.1824 l 0.015156,5.18642 8.5158814,-0.01516 -0.03908,-4.900355 c -1.9e-4,-0.0684 0.0058,-0.306571 0.05414,-0.354933 0.04837,-0.04837 0.0119,-0.04375 0.08029,-0.04356 l 0.0696,-0.0082 -1.548282,-1.58661 c -0.04383,-0.04746 -0.0682,-0.10969 -0.06823,-0.174298 l 0.01753,-2.894408 -0.201452,0.005 0.01753,2.056608 c 4.61e-4,0.104355 -0.06227,0.198621 -0.158698,0.238523 -0.09642,0.03991 -0.207415,0.01751 -0.280836,-0.05665 l -2.3304935,-2.383362 3.74e-5,0 -2.98e-5,5e-6 -9e-7,2.5e-5 9e-7,-3.9e-5 z"
-       id="path2778"
-       sodipodi:nodetypes="cccsccccscccccccscccccc" />
-  </g>
-</svg>
diff --git a/images/session-chat_256x256.png b/images/session-chat_256x256.png
new file mode 100644
index 0000000..42c1bb3
Binary files /dev/null and b/images/session-chat_256x256.png differ
diff --git a/lib/Makefile.am b/lib/Makefile.am
index a171e18..54b3067 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -2,12 +2,13 @@ SUBDIRS =	SmartIrc4net
 
 OUTPUT_DIR = $(top_builddir)/bin/$(PROFILE)
 OBJECT_DIR = $(OUTPUT_DIR)/obj
-SOURCE_PATTERNS = *.cs */*.cs */*/*.cs */*/*/*.cs
-XBUILD_FLAGS = /p:Configuration=Debug /p:WarningLevel=0 /p:OutputPath=$(abspath $(OUTPUT_DIR)) /p:BaseIntermediateOutputPath=$(abspath $(OBJECT_DIR))/ /p:DocumentationFile=
+SOURCE_PATTERNS = *.cs */*.cs */*/*.cs */*/*/*.cs */*/*/*/*.cs */*/*/*/*/*.cs
+XBUILD_FLAGS += /p:Configuration=Debug /p:SignAssembly=false /p:WarningLevel=0 /p:OutputPath=$(abspath $(OUTPUT_DIR)) /p:BaseIntermediateOutputPath=$(abspath $(OBJECT_DIR))/ /p:IntermediateOutputPath=$(abspath $(OBJECT_DIR))/ /p:DocumentationFile=
 
 JSON_SUBDIR = Newtonsoft.Json
 JSON_SRCDIR = $(srcdir)/$(JSON_SUBDIR)/Src/Newtonsoft.Json
 JSON_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(JSON_SRCDIR)/$(pattern)))
+JSON_CLEAN_FILES = $(OBJECT_DIR)/Newtonsoft.Json.Dynamic.snk
 JSON_ASSEMBLY_NAME = Newtonsoft.Json.dll
 JSON_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(JSON_ASSEMBLY_NAME)
 JSON_BUILD_FILE = $(JSON_SRCDIR)/Newtonsoft.Json.csproj
@@ -15,24 +16,80 @@ JSON_XBUILD_FLAGS = $(XBUILD_FLAGS)
 
 TWITTERIZER_SUBDIR = Twitterizer
 TWITTERIZER_SRCDIR = $(srcdir)/$(TWITTERIZER_SUBDIR)/Twitterizer2
-TWITTERIZER_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(TWITTERIZER_SRCDIR)/$(pattern)))
+TWITTERIZER_SOURCE_FILES = $(foreach pattern, ../*.cs $(SOURCE_PATTERNS), $(wildcard $(TWITTERIZER_SRCDIR)/$(pattern)))
+TWITTERIZER_EXTRA_FILES = $(TWITTERIZER_SRCDIR)/Twitterizer2.snk $(TWITTERIZER_SRCDIR)/../GettingStarted.txt $(TWITTERIZER_SRCDIR)/../Json.NET.license.txt $(TWITTERIZER_SRCDIR)/../Twitterizer2.license.txt
+TWITTERIZER_CLEAN_FILES = \
+	$(OUTPUT_DIR)/.license.txt \
+	$(OUTPUT_DIR)/Twitterizer2.license.txt \
+	$(OUTPUT_DIR)/Json.NET.license.txt \
+	$(OUTPUT_DIR)/GettingStarted.txt
 TWITTERIZER_ASSEMBLY_NAME = Twitterizer2.dll
 TWITTERIZER_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(TWITTERIZER_ASSEMBLY_NAME)
 TWITTERIZER_BUILD_FILE = $(TWITTERIZER_SRCDIR)/Twitterizer2.csproj
 TWITTERIZER_XBUILD_FLAGS = $(XBUILD_FLAGS) /p:PostBuildEvent=
 
+JABBER_NET_SUBDIR = jabber-net
+JABBER_NET_SRCDIR = $(srcdir)/$(JABBER_NET_SUBDIR)
+JABBER_NET_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(JABBER_NET_SRCDIR)/$(pattern)))
+JABBER_NET_EXTRA_FILES = $(wildcard $(JABBER_NET_SRCDIR)/jabber/*/*.bmp) $(wildcard $(JABBER_NET_SRCDIR)/jabber/*/*.resx)
+JABBER_NET_CLEAN_FILES = $(wildcard $(OBJECT_DIR)/*.bmp)
+JABBER_NET_ASSEMBLY_NAME = jabber-net.dll
+JABBER_NET_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(JABBER_NET_ASSEMBLY_NAME)
+JABBER_NET_BUILD_FILE = $(JABBER_NET_SRCDIR)/2005-jabber-net.csproj
+JABBER_NET_XBUILD_FLAGS = $(XBUILD_FLAGS)
+
+DB4O_SUBDIR = db4o-net
+DB4O_SRCDIR = $(srcdir)/$(DB4O_SUBDIR)/Db4objects.Db4o
+DB4O_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(DB4O_SRCDIR)/$(pattern)))
+DB4O_ASSEMBLY_NAME = Db4objects.Db4o.dll
+DB4O_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(DB4O_ASSEMBLY_NAME)
+DB4O_BUILD_FILE = $(DB4O_SRCDIR)/Db4objects.Db4o-2008.csproj
+DB4O_XBUILD_FLAGS = $(XBUILD_FLAGS) /property:DefineConstants="NET_3_5,MONO,EMBEDDED"
+
+DB4O_INSTR_SRCDIR = $(srcdir)/$(DB4O_SUBDIR)/Db4objects.Db4o.Instrumentation
+DB4O_INSTR_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(DB4O_INSTR_SRCDIR)/$(pattern)))
+DB4O_INSTR_ASSEMBLY_NAME = Db4objects.Db4o.Instrumentation.dll
+DB4O_INSTR_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(DB4O_INSTR_ASSEMBLY_NAME)
+DB4O_INSTR_BUILD_FILE = $(DB4O_INSTR_SRCDIR)/Db4objects.Db4o.Instrumentation-2008.csproj
+DB4O_INSTR_XBUILD_FLAGS = $(DB4O_XBUILD_FLAGS)
+
+DB4O_NQ_SRCDIR = $(srcdir)/$(DB4O_SUBDIR)/Db4objects.Db4o.NativeQueries
+DB4O_NQ_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(DB4O_NQ_SRCDIR)/$(pattern)))
+DB4O_NQ_ASSEMBLY_NAME = Db4objects.Db4o.NativeQueries.dll
+DB4O_NQ_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(DB4O_NQ_ASSEMBLY_NAME)
+DB4O_NQ_BUILD_FILE = $(DB4O_NQ_SRCDIR)/Db4objects.Db4o.NativeQueries-2008.csproj
+DB4O_NQ_XBUILD_FLAGS = $(DB4O_XBUILD_FLAGS)
+
 # magic automake variables
 if ENABLE_ENGINE_TWITTER
-pkglib_DATA = \
+EXTRA_TWITTER_LIBS = \
 	$(JSON_ASSEMBLY_TARGET) $(JSON_ASSEMBLY_TARGET).mdb \
 	$(TWITTERIZER_ASSEMBLY_TARGET) $(TWITTERIZER_ASSEMBLY_TARGET).mdb
 endif
+if ENABLE_ENGINE_XMPP
+EXTRA_XMPP_LIBS = \
+	$(JABBER_NET_ASSEMBLY_TARGET) $(JABBER_NET_ASSEMBLY_TARGET).mdb
+endif
+if BUNDLE_DB4O
+EXTRA_DB4O_LIBS = \
+	$(DB4O_ASSEMBLY_TARGET) $(DB4O_ASSEMBLY_TARGET).mdb
+#	$(DB4O_INSTR_ASSEMBLY_TARGET) $(DB4O_INSTR_ASSEMBLY_TARGET).mdb \
+#	$(DB4O_NQ_ASSEMBLY_TARGET) $(DB4O_NQ_ASSEMBLY_TARGET).mdb
+endif
+pkglib_DATA = $(EXTRA_TWITTER_LIBS) $(EXTRA_XMPP_LIBS) $(EXTRA_DB4O_LIBS)
 
 EXTRA_DIST = \
 	 $(JSON_SOURCE_FILES) $(JSON_BUILD_FILE) $(JSON_SRCDIR)/Dynamic.snk \
-	 $(TWITTERIZER_SOURCE_FILES) $(TWITTERIZER_BUILD_FILE) $(TWITTERIZER_SRCDIR)/Twitterizer2.snk
+	 $(TWITTERIZER_SOURCE_FILES) $(TWITTERIZER_EXTRA_FILES) $(TWITTERIZER_BUILD_FILE) \
+	 $(JABBER_NET_SOURCE_FILES) $(JABBER_NET_EXTRA_FILES) $(JABBER_NET_BUILD_FILE) \
+	 $(DB4O_SOURCE_FILES) $(DB4O_BUILD_FILE) \
+	 $(DB4O_INSTR_SOURCE_FILES) $(DB4O_INSTR_BUILD_FILE) \
+	 $(DB4O_NQ_SOURCE_FILES) $(DB4O_NQ_BUILD_FILE)
 
-CLEANFILES = $(OBJECT_DIR)/Debug/Newtonsoft.Json.Dynamic.snk
+CLEANFILES = \
+	$(JSON_CLEAN_FILES) \
+	$(JABBER_NET_CLEAN_FILES) \
+	$(TWITTERIZER_CLEAN_FILES)
 # end of magic
 
 $(JSON_ASSEMBLY_TARGET) $(JSON_ASSEMBLY_TARGET).mdb: $(JSON_BUILD_FILE) $(JSON_SOURCE_FILES)
@@ -41,8 +98,28 @@ $(JSON_ASSEMBLY_TARGET) $(JSON_ASSEMBLY_TARGET).mdb: $(JSON_BUILD_FILE) $(JSON_S
 $(TWITTERIZER_ASSEMBLY_TARGET) $(TWITTERIZER_ASSEMBLY_TARGET).mdb: $(TWITTERIZER_BUILD_FILE) $(TWITTERIZER_SOURCE_FILES)
 	$(XBUILD) $(TWITTERIZER_XBUILD_FLAGS) $(TWITTERIZER_BUILD_FILE)
 
-if ENABLE_ENGINE_TWITTER
+$(JABBER_NET_ASSEMBLY_TARGET) $(JABBER_NET_ASSEMBLY_TARGET).mdb: $(JABBER_NET_BUILD_FILE) $(JABBER_NET_SOURCE_FILES)
+	$(XBUILD) $(JABBER_NET_XBUILD_FLAGS) $(JABBER_NET_BUILD_FILE)
+
+$(DB4O_ASSEMBLY_TARGET) $(DB4O_ASSEMBLY_TARGET).mdb: $(DB4O_BUILD_FILE) $(DB4O_SOURCE_FILES)
+	$(XBUILD) $(DB4O_XBUILD_FLAGS) $(DB4O_BUILD_FILE)
+
+$(DB4O_INSTR_ASSEMBLY_TARGET) $(DB4O_INSTR_ASSEMBLY_TARGET).mdb: $(DB4O_INSTR_BUILD_FILE) $(DB4O_INSTR_SOURCE_FILES)
+	$(XBUILD) $(DB4O_INSTR_XBUILD_FLAGS) $(DB4O_INSTR_BUILD_FILE)
+
+$(DB4O_NQ_ASSEMBLY_TARGET) $(DB4O_NQ_ASSEMBLY_TARGET).mdb: $(DB4O_NQ_BUILD_FILE) $(DB4O_NQ_SOURCE_FILES)
+	$(XBUILD) $(DB4O_NQ_XBUILD_FLAGS) $(DB4O_NQ_BUILD_FILE)
+
 clean-local:
+if ENABLE_ENGINE_TWITTER
 	$(XBUILD) $(JSON_XBUILD_FLAGS) /t:Clean $(JSON_BUILD_FILE)
 	$(XBUILD) $(TWITTERIZER_XBUILD_FLAGS) /t:Clean $(TWITTERIZER_BUILD_FILE)
 endif
+if ENABLE_ENGINE_XMPP
+	$(XBUILD) $(JABBER_NET_XBUILD_FLAGS) /t:Clean $(JABBER_NET_BUILD_FILE)
+endif
+if BUNDLE_DB4O
+	$(XBUILD) $(DB4O_XBUILD_FLAGS) /t:Clean $(DB4O_BUILD_FILE)
+#	$(XBUILD) $(DB4O_INSTR_XBUILD_FLAGS) /t:Clean $(DB4O_INSTR_BUILD_FILE)
+#	$(XBUILD) $(DB4O_NQ_XBUILD_FLAGS) /t:Clean $(DB4O_NQ_BUILD_FILE)
+endif
diff --git a/lib/Makefile.in b/lib/Makefile.in
index a404c4d..940c62b 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -38,8 +38,11 @@ subdir = lib
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -114,6 +117,7 @@ am__relativize = \
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -127,13 +131,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -174,13 +191,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -188,6 +207,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -198,13 +218,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -218,13 +247,24 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@ /p:Configuration=Debug \
+	/p:SignAssembly=false /p:WarningLevel=0 \
+	/p:OutputPath=$(abspath $(OUTPUT_DIR)) \
+	/p:BaseIntermediateOutputPath=$(abspath $(OBJECT_DIR))/ \
+	/p:IntermediateOutputPath=$(abspath $(OBJECT_DIR))/ \
+	/p:DocumentationFile=
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -232,7 +272,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -247,10 +289,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -284,33 +329,85 @@ twitter_api_key = @twitter_api_key@
 SUBDIRS = SmartIrc4net
 OUTPUT_DIR = $(top_builddir)/bin/$(PROFILE)
 OBJECT_DIR = $(OUTPUT_DIR)/obj
-SOURCE_PATTERNS = *.cs */*.cs */*/*.cs */*/*/*.cs
-XBUILD_FLAGS = /p:Configuration=Debug /p:WarningLevel=0 /p:OutputPath=$(abspath $(OUTPUT_DIR)) /p:BaseIntermediateOutputPath=$(abspath $(OBJECT_DIR))/ /p:DocumentationFile=
+SOURCE_PATTERNS = *.cs */*.cs */*/*.cs */*/*/*.cs */*/*/*/*.cs */*/*/*/*/*.cs
 JSON_SUBDIR = Newtonsoft.Json
 JSON_SRCDIR = $(srcdir)/$(JSON_SUBDIR)/Src/Newtonsoft.Json
 JSON_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(JSON_SRCDIR)/$(pattern)))
+JSON_CLEAN_FILES = $(OBJECT_DIR)/Newtonsoft.Json.Dynamic.snk
 JSON_ASSEMBLY_NAME = Newtonsoft.Json.dll
 JSON_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(JSON_ASSEMBLY_NAME)
 JSON_BUILD_FILE = $(JSON_SRCDIR)/Newtonsoft.Json.csproj
 JSON_XBUILD_FLAGS = $(XBUILD_FLAGS)
 TWITTERIZER_SUBDIR = Twitterizer
 TWITTERIZER_SRCDIR = $(srcdir)/$(TWITTERIZER_SUBDIR)/Twitterizer2
-TWITTERIZER_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(TWITTERIZER_SRCDIR)/$(pattern)))
+TWITTERIZER_SOURCE_FILES = $(foreach pattern, ../*.cs $(SOURCE_PATTERNS), $(wildcard $(TWITTERIZER_SRCDIR)/$(pattern)))
+TWITTERIZER_EXTRA_FILES = $(TWITTERIZER_SRCDIR)/Twitterizer2.snk $(TWITTERIZER_SRCDIR)/../GettingStarted.txt $(TWITTERIZER_SRCDIR)/../Json.NET.license.txt $(TWITTERIZER_SRCDIR)/../Twitterizer2.license.txt
+TWITTERIZER_CLEAN_FILES = \
+	$(OUTPUT_DIR)/.license.txt \
+	$(OUTPUT_DIR)/Twitterizer2.license.txt \
+	$(OUTPUT_DIR)/Json.NET.license.txt \
+	$(OUTPUT_DIR)/GettingStarted.txt
+
 TWITTERIZER_ASSEMBLY_NAME = Twitterizer2.dll
 TWITTERIZER_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(TWITTERIZER_ASSEMBLY_NAME)
 TWITTERIZER_BUILD_FILE = $(TWITTERIZER_SRCDIR)/Twitterizer2.csproj
 TWITTERIZER_XBUILD_FLAGS = $(XBUILD_FLAGS) /p:PostBuildEvent=
+JABBER_NET_SUBDIR = jabber-net
+JABBER_NET_SRCDIR = $(srcdir)/$(JABBER_NET_SUBDIR)
+JABBER_NET_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(JABBER_NET_SRCDIR)/$(pattern)))
+JABBER_NET_EXTRA_FILES = $(wildcard $(JABBER_NET_SRCDIR)/jabber/*/*.bmp) $(wildcard $(JABBER_NET_SRCDIR)/jabber/*/*.resx)
+JABBER_NET_CLEAN_FILES = $(wildcard $(OBJECT_DIR)/*.bmp)
+JABBER_NET_ASSEMBLY_NAME = jabber-net.dll
+JABBER_NET_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(JABBER_NET_ASSEMBLY_NAME)
+JABBER_NET_BUILD_FILE = $(JABBER_NET_SRCDIR)/2005-jabber-net.csproj
+JABBER_NET_XBUILD_FLAGS = $(XBUILD_FLAGS)
+DB4O_SUBDIR = db4o-net
+DB4O_SRCDIR = $(srcdir)/$(DB4O_SUBDIR)/Db4objects.Db4o
+DB4O_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(DB4O_SRCDIR)/$(pattern)))
+DB4O_ASSEMBLY_NAME = Db4objects.Db4o.dll
+DB4O_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(DB4O_ASSEMBLY_NAME)
+DB4O_BUILD_FILE = $(DB4O_SRCDIR)/Db4objects.Db4o-2008.csproj
+DB4O_XBUILD_FLAGS = $(XBUILD_FLAGS) /property:DefineConstants="NET_3_5,MONO,EMBEDDED"
+DB4O_INSTR_SRCDIR = $(srcdir)/$(DB4O_SUBDIR)/Db4objects.Db4o.Instrumentation
+DB4O_INSTR_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(DB4O_INSTR_SRCDIR)/$(pattern)))
+DB4O_INSTR_ASSEMBLY_NAME = Db4objects.Db4o.Instrumentation.dll
+DB4O_INSTR_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(DB4O_INSTR_ASSEMBLY_NAME)
+DB4O_INSTR_BUILD_FILE = $(DB4O_INSTR_SRCDIR)/Db4objects.Db4o.Instrumentation-2008.csproj
+DB4O_INSTR_XBUILD_FLAGS = $(DB4O_XBUILD_FLAGS)
+DB4O_NQ_SRCDIR = $(srcdir)/$(DB4O_SUBDIR)/Db4objects.Db4o.NativeQueries
+DB4O_NQ_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(DB4O_NQ_SRCDIR)/$(pattern)))
+DB4O_NQ_ASSEMBLY_NAME = Db4objects.Db4o.NativeQueries.dll
+DB4O_NQ_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(DB4O_NQ_ASSEMBLY_NAME)
+DB4O_NQ_BUILD_FILE = $(DB4O_NQ_SRCDIR)/Db4objects.Db4o.NativeQueries-2008.csproj
+DB4O_NQ_XBUILD_FLAGS = $(DB4O_XBUILD_FLAGS)
 
 # magic automake variables
- at ENABLE_ENGINE_TWITTER_TRUE@pkglib_DATA = \
+ at ENABLE_ENGINE_TWITTER_TRUE@EXTRA_TWITTER_LIBS = \
 @ENABLE_ENGINE_TWITTER_TRUE@	$(JSON_ASSEMBLY_TARGET) $(JSON_ASSEMBLY_TARGET).mdb \
 @ENABLE_ENGINE_TWITTER_TRUE@	$(TWITTERIZER_ASSEMBLY_TARGET) $(TWITTERIZER_ASSEMBLY_TARGET).mdb
 
+ at ENABLE_ENGINE_XMPP_TRUE@EXTRA_XMPP_LIBS = \
+ at ENABLE_ENGINE_XMPP_TRUE@	$(JABBER_NET_ASSEMBLY_TARGET) $(JABBER_NET_ASSEMBLY_TARGET).mdb
+
+ at BUNDLE_DB4O_TRUE@EXTRA_DB4O_LIBS = \
+ at BUNDLE_DB4O_TRUE@	$(DB4O_ASSEMBLY_TARGET) $(DB4O_ASSEMBLY_TARGET).mdb
+
+#	$(DB4O_INSTR_ASSEMBLY_TARGET) $(DB4O_INSTR_ASSEMBLY_TARGET).mdb \
+#	$(DB4O_NQ_ASSEMBLY_TARGET) $(DB4O_NQ_ASSEMBLY_TARGET).mdb
+pkglib_DATA = $(EXTRA_TWITTER_LIBS) $(EXTRA_XMPP_LIBS) $(EXTRA_DB4O_LIBS)
 EXTRA_DIST = \
 	 $(JSON_SOURCE_FILES) $(JSON_BUILD_FILE) $(JSON_SRCDIR)/Dynamic.snk \
-	 $(TWITTERIZER_SOURCE_FILES) $(TWITTERIZER_BUILD_FILE) $(TWITTERIZER_SRCDIR)/Twitterizer2.snk
+	 $(TWITTERIZER_SOURCE_FILES) $(TWITTERIZER_EXTRA_FILES) $(TWITTERIZER_BUILD_FILE) \
+	 $(JABBER_NET_SOURCE_FILES) $(JABBER_NET_EXTRA_FILES) $(JABBER_NET_BUILD_FILE) \
+	 $(DB4O_SOURCE_FILES) $(DB4O_BUILD_FILE) \
+	 $(DB4O_INSTR_SOURCE_FILES) $(DB4O_INSTR_BUILD_FILE) \
+	 $(DB4O_NQ_SOURCE_FILES) $(DB4O_NQ_BUILD_FILE)
+
+CLEANFILES = \
+	$(JSON_CLEAN_FILES) \
+	$(JABBER_NET_CLEAN_FILES) \
+	$(TWITTERIZER_CLEAN_FILES)
 
-CLEANFILES = $(OBJECT_DIR)/Debug/Newtonsoft.Json.Dynamic.snk
 all: all-recursive
 
 .SUFFIXES:
@@ -344,6 +441,12 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
 $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-pkglibDATA: $(pkglib_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)"
@@ -592,10 +695,9 @@ distclean-generic:
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "it deletes files that may require special tools to rebuild."
- at ENABLE_ENGINE_TWITTER_FALSE@clean-local:
 clean: clean-recursive
 
-clean-am: clean-generic clean-local mostlyclean-am
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
 
 distclean: distclean-recursive
 	-rm -f Makefile
@@ -647,7 +749,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-recursive
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-recursive
 
@@ -663,17 +765,18 @@ uninstall-am: uninstall-pkglibDATA
 	install-am install-strip tags-recursive
 
 .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
-	all all-am check check-am clean clean-generic clean-local \
-	ctags ctags-recursive distclean distclean-generic \
-	distclean-tags distdir dvi dvi-am html html-am info info-am \
-	install install-am install-data install-data-am install-dvi \
-	install-dvi-am install-exec install-exec-am install-html \
-	install-html-am install-info install-info-am install-man \
-	install-pdf install-pdf-am install-pkglibDATA install-ps \
-	install-ps-am install-strip installcheck installcheck-am \
-	installdirs installdirs-am maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
-	pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+	all all-am check check-am clean clean-generic clean-libtool \
+	clean-local ctags ctags-recursive distclean distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-pkglibDATA install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs installdirs-am \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-recursive uninstall uninstall-am \
 	uninstall-pkglibDATA
 
 # end of magic
@@ -684,9 +787,25 @@ $(JSON_ASSEMBLY_TARGET) $(JSON_ASSEMBLY_TARGET).mdb: $(JSON_BUILD_FILE) $(JSON_S
 $(TWITTERIZER_ASSEMBLY_TARGET) $(TWITTERIZER_ASSEMBLY_TARGET).mdb: $(TWITTERIZER_BUILD_FILE) $(TWITTERIZER_SOURCE_FILES)
 	$(XBUILD) $(TWITTERIZER_XBUILD_FLAGS) $(TWITTERIZER_BUILD_FILE)
 
- at ENABLE_ENGINE_TWITTER_TRUE@clean-local:
+$(JABBER_NET_ASSEMBLY_TARGET) $(JABBER_NET_ASSEMBLY_TARGET).mdb: $(JABBER_NET_BUILD_FILE) $(JABBER_NET_SOURCE_FILES)
+	$(XBUILD) $(JABBER_NET_XBUILD_FLAGS) $(JABBER_NET_BUILD_FILE)
+
+$(DB4O_ASSEMBLY_TARGET) $(DB4O_ASSEMBLY_TARGET).mdb: $(DB4O_BUILD_FILE) $(DB4O_SOURCE_FILES)
+	$(XBUILD) $(DB4O_XBUILD_FLAGS) $(DB4O_BUILD_FILE)
+
+$(DB4O_INSTR_ASSEMBLY_TARGET) $(DB4O_INSTR_ASSEMBLY_TARGET).mdb: $(DB4O_INSTR_BUILD_FILE) $(DB4O_INSTR_SOURCE_FILES)
+	$(XBUILD) $(DB4O_INSTR_XBUILD_FLAGS) $(DB4O_INSTR_BUILD_FILE)
+
+$(DB4O_NQ_ASSEMBLY_TARGET) $(DB4O_NQ_ASSEMBLY_TARGET).mdb: $(DB4O_NQ_BUILD_FILE) $(DB4O_NQ_SOURCE_FILES)
+	$(XBUILD) $(DB4O_NQ_XBUILD_FLAGS) $(DB4O_NQ_BUILD_FILE)
+
+clean-local:
 @ENABLE_ENGINE_TWITTER_TRUE@	$(XBUILD) $(JSON_XBUILD_FLAGS) /t:Clean $(JSON_BUILD_FILE)
 @ENABLE_ENGINE_TWITTER_TRUE@	$(XBUILD) $(TWITTERIZER_XBUILD_FLAGS) /t:Clean $(TWITTERIZER_BUILD_FILE)
+ at ENABLE_ENGINE_XMPP_TRUE@	$(XBUILD) $(JABBER_NET_XBUILD_FLAGS) /t:Clean $(JABBER_NET_BUILD_FILE)
+ at BUNDLE_DB4O_TRUE@	$(XBUILD) $(DB4O_XBUILD_FLAGS) /t:Clean $(DB4O_BUILD_FILE)
+#	$(XBUILD) $(DB4O_INSTR_XBUILD_FLAGS) /t:Clean $(DB4O_INSTR_BUILD_FILE)
+#	$(XBUILD) $(DB4O_NQ_XBUILD_FLAGS) /t:Clean $(DB4O_NQ_BUILD_FILE)
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/lib/SmartIrc4net/SmartIrc4net.mds b/lib/SmartIrc4net/SmartIrc4net.mds
index ae9b1c8..496c09c 100644
--- a/lib/SmartIrc4net/SmartIrc4net.mds
+++ b/lib/SmartIrc4net/SmartIrc4net.mds
@@ -5,7 +5,8 @@
     </ChangeLogPolicy>
     <TextStylePolicy RemoveTrailingWhitespace="True" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" />
     <TextStylePolicy inheritsSet="null" scope="text/x-csharp" />
-    <CSharpFormattingPolicy inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
+    <CSharpFormattingPolicy IndentSwitchBody="True" AllowPropertyGetBlockInline="False" AllowPropertySetBlockInline="False" IfElseBraceForcement="AddBraces" ForBraceForcement="AddBraces" ForEachBraceForcement="AddBraces" WhileBraceForcement="AddBraces" UsingBraceForcement="AddBraces" FixedBraceForcement="AddBraces" BeforeMethodCallParentheses="False" BeforeMethodDeclarationParentheses="False" BeforeConstructorDeclarationParentheses="False" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
+    <StandardHeader Text=" SmartIrc4net - the IRC library for .NET/C# <http://smartirc4net.sf.net>&#xA;&#xA; Copyright (c) ${Year} ${CopyrightHolder}&#xA;&#xA; Full LGPL License: <http://www.gnu.org/licenses/lgpl.txt>&#xA;&#xA; This library is free software; you can redistribute it and/or modify&#xA; it under the terms of the GNU Lesser General Public License as&#xA; published by the Free Software Foundation; either version 2.1 of the&#xA; License, or (at your option) any later version.&#xA;&#xA; This library is distributed in the hope that it will be useful, but&#xA; WITHOUT ANY WARRANTY; without even the implied warranty of&#xA; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU&#xA; Lesser General Public License for more details.&#xA;&#xA; You should have received a copy of the GNU Lesser General Public&#xA; License along with this library; if not, write to the Free Software&#xA; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA" inheritsSet="Apache2License" />
   </Policies>
   <Configurations active="Debug">
     <Configuration name="Release" ctype="CombineConfiguration">
diff --git a/lib/SmartIrc4net/aclocal.m4 b/lib/SmartIrc4net/aclocal.m4
index d3b5b1a..d5d544a 100644
--- a/lib/SmartIrc4net/aclocal.m4
+++ b/lib/SmartIrc4net/aclocal.m4
@@ -13,8 +13,8 @@
 
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],,
-[m4_warning([this file was generated for autoconf 2.65.
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],,
+[m4_warning([this file was generated for autoconf 2.68.
 You have another version of autoconf.  It may work, but is not guaranteed to.
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically `autoreconf'.])])
@@ -47,7 +47,8 @@ To do so, use the procedure documented by the package, typically `autoreconf'.])
 # ----------------------------------
 AC_DEFUN([PKG_PROG_PKG_CONFIG],
 [m4_pattern_forbid([^_?PKG_[A-Z_]+$])
-m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
+m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
+m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
 AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
 AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
 AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
@@ -93,7 +94,8 @@ m4_define([_PKG_CONFIG],
     pkg_cv_[]$1="$$1"
  elif test -n "$PKG_CONFIG"; then
     PKG_CHECK_EXISTS([$3],
-                     [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
+                     [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes ],
 		     [pkg_failed=yes])
  else
     pkg_failed=untried
@@ -141,9 +143,9 @@ if test $pkg_failed = yes; then
    	AC_MSG_RESULT([no])
         _PKG_SHORT_ERRORS_SUPPORTED
         if test $_pkg_short_errors_supported = yes; then
-	        $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1`
+	        $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
         else 
-	        $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1`
+	        $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
@@ -156,7 +158,7 @@ $$1_PKG_ERRORS
 Consider adjusting the PKG_CONFIG_PATH environment variable if you
 installed software in a non-standard prefix.
 
-_PKG_TEXT])dnl
+_PKG_TEXT])[]dnl
         ])
 elif test $pkg_failed = untried; then
      	AC_MSG_RESULT([no])
@@ -167,7 +169,7 @@ path to pkg-config.
 
 _PKG_TEXT
 
-To get pkg-config, see <http://pkg-config.freedesktop.org/>.])dnl
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
         ])
 else
 	$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
diff --git a/lib/SmartIrc4net/configure b/lib/SmartIrc4net/configure
index c41d559..f9fa34a 100755
--- a/lib/SmartIrc4net/configure
+++ b/lib/SmartIrc4net/configure
@@ -1,11 +1,11 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.65 for smartirc4net 0.4.5.1.
+# Generated by GNU Autoconf 2.68 for smartirc4net 0.4.5.1.
 #
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+# Foundation, Inc.
 #
 #
 # This configure script is free software; the Free Software Foundation
@@ -89,6 +89,7 @@ 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
@@ -213,11 +214,18 @@ 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
-	exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+	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+"$@"}
 fi
 
     if test x$as_have_required = xno; then :
@@ -315,7 +323,7 @@ $as_echo X"$as_dir" |
       test -d "$as_dir" && break
     done
     test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
 
 
 } # as_fn_mkdir_p
@@ -355,19 +363,19 @@ else
 fi # as_fn_arith
 
 
-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
 # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
 # provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
+# script with STATUS, using 1 if that was 0.
 as_fn_error ()
 {
-  as_status=$?; test $as_status -eq 0 && as_status=1
-  if test "$3"; then
-    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $1" >&2
+  $as_echo "$as_me: error: $2" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
@@ -529,7 +537,7 @@ test -n "$DJDIR" || exec 7<&0 </dev/null
 exec 6>&1
 
 # Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
 # so uname gets run too.
 ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
 
@@ -720,8 +728,9 @@ do
   fi
 
   case $ac_option in
-  *=*)	ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
-  *)	ac_optarg=yes ;;
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
   esac
 
   # Accept the important Cygnus configure options, so we can diagnose typos.
@@ -766,7 +775,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -792,7 +801,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -996,7 +1005,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -1012,7 +1021,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -1042,8 +1051,8 @@ do
   | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
     x_libraries=$ac_optarg ;;
 
-  -*) as_fn_error "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information."
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
     ;;
 
   *=*)
@@ -1051,7 +1060,7 @@ Try \`$0 --help' for more information."
     # Reject names that are not valid shell variable names.
     case $ac_envvar in #(
       '' | [0-9]* | *[!_$as_cr_alnum]* )
-      as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
     esac
     eval $ac_envvar=\$ac_optarg
     export $ac_envvar ;;
@@ -1061,7 +1070,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
@@ -1069,13 +1078,13 @@ done
 
 if test -n "$ac_prev"; then
   ac_option=--`echo $ac_prev | sed 's/_/-/g'`
-  as_fn_error "missing argument to $ac_option"
+  as_fn_error $? "missing argument to $ac_option"
 fi
 
 if test -n "$ac_unrecognized_opts"; then
   case $enable_option_checking in
     no) ;;
-    fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
     *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
   esac
 fi
@@ -1098,7 +1107,7 @@ do
     [\\/$]* | ?:[\\/]* )  continue;;
     NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
   esac
-  as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
 done
 
 # There might be people who depend on the old broken behavior: `$host'
@@ -1112,8 +1121,8 @@ target=$target_alias
 if test "x$host_alias" != x; then
   if test "x$build_alias" = x; then
     cross_compiling=maybe
-    $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
-    If a cross compiler is detected then cross compile mode will be used." >&2
+    $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used" >&2
   elif test "x$build_alias" != "x$host_alias"; then
     cross_compiling=yes
   fi
@@ -1128,9 +1137,9 @@ test "$silent" = yes && exec 6>/dev/null
 ac_pwd=`pwd` && test -n "$ac_pwd" &&
 ac_ls_di=`ls -di .` &&
 ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
-  as_fn_error "working directory cannot be determined"
+  as_fn_error $? "working directory cannot be determined"
 test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
-  as_fn_error "pwd does not report name of working directory"
+  as_fn_error $? "pwd does not report name of working directory"
 
 
 # Find the source files, if location was not specified.
@@ -1169,11 +1178,11 @@ else
 fi
 if test ! -r "$srcdir/$ac_unique_file"; then
   test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
-  as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
 fi
 ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
 ac_abs_confdir=`(
-	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
 	pwd)`
 # When building in place, set srcdir=.
 if test "$ac_abs_confdir" = "$ac_pwd"; then
@@ -1213,7 +1222,7 @@ Configuration:
       --help=short        display options specific to this package
       --help=recursive    display the short help of all the included packages
   -V, --version           display version information and exit
-  -q, --quiet, --silent   do not print \`checking...' messages
+  -q, --quiet, --silent   do not print \`checking ...' messages
       --cache-file=FILE   cache test results in FILE [disabled]
   -C, --config-cache      alias for \`--cache-file=config.cache'
   -n, --no-create         do not create output files
@@ -1357,9 +1366,9 @@ test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
 smartirc4net configure 0.4.5.1
-generated by GNU Autoconf 2.65
+generated by GNU Autoconf 2.68
 
-Copyright (C) 2009 Free Software Foundation, Inc.
+Copyright (C) 2010 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 _ACEOF
@@ -1374,7 +1383,7 @@ This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
 It was created by smartirc4net $as_me 0.4.5.1, which was
-generated by GNU Autoconf 2.65.  Invocation command line was
+generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
 
@@ -1484,11 +1493,9 @@ trap 'exit_status=$?
   {
     echo
 
-    cat <<\_ASBOX
-## ---------------- ##
+    $as_echo "## ---------------- ##
 ## Cache variables. ##
-## ---------------- ##
-_ASBOX
+## ---------------- ##"
     echo
     # The following way of writing the cache mishandles newlines in values,
 (
@@ -1522,11 +1529,9 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
 )
     echo
 
-    cat <<\_ASBOX
-## ----------------- ##
+    $as_echo "## ----------------- ##
 ## Output variables. ##
-## ----------------- ##
-_ASBOX
+## ----------------- ##"
     echo
     for ac_var in $ac_subst_vars
     do
@@ -1539,11 +1544,9 @@ _ASBOX
     echo
 
     if test -n "$ac_subst_files"; then
-      cat <<\_ASBOX
-## ------------------- ##
+      $as_echo "## ------------------- ##
 ## File substitutions. ##
-## ------------------- ##
-_ASBOX
+## ------------------- ##"
       echo
       for ac_var in $ac_subst_files
       do
@@ -1557,11 +1560,9 @@ _ASBOX
     fi
 
     if test -s confdefs.h; then
-      cat <<\_ASBOX
-## ----------- ##
+      $as_echo "## ----------- ##
 ## confdefs.h. ##
-## ----------- ##
-_ASBOX
+## ----------- ##"
       echo
       cat confdefs.h
       echo
@@ -1616,7 +1617,12 @@ _ACEOF
 ac_site_file1=NONE
 ac_site_file2=NONE
 if test -n "$CONFIG_SITE"; then
-  ac_site_file1=$CONFIG_SITE
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
 elif test "x$prefix" != xNONE; then
   ac_site_file1=$prefix/share/config.site
   ac_site_file2=$prefix/etc/config.site
@@ -1631,7 +1637,11 @@ do
     { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
 $as_echo "$as_me: loading site script $ac_site_file" >&6;}
     sed 's/^/| /' "$ac_site_file" >&5
-    . "$ac_site_file"
+    . "$ac_site_file" \
+      || { { $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; }
   fi
 done
 
@@ -1707,7 +1717,7 @@ if $ac_cache_corrupted; then
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
   { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
 fi
 ## -------------------- ##
 ## Main body of script. ##
@@ -1724,16 +1734,22 @@ am__api_version='1.11'
 
 ac_aux_dir=
 for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
-  for ac_t in install-sh install.sh shtool; do
-    if test -f "$ac_dir/$ac_t"; then
-      ac_aux_dir=$ac_dir
-      ac_install_sh="$ac_aux_dir/$ac_t -c"
-      break 2
-    fi
-  done
+  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
+  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,
@@ -1762,7 +1778,7 @@ ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
 { $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 :
+if ${ac_cv_path_install+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -1849,11 +1865,11 @@ am_lf='
 '
 case `pwd` in
   *[\\\"\#\$\&\'\`$am_lf]*)
-    as_fn_error "unsafe absolute working directory name" "$LINENO" 5;;
+    as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
 esac
 case $srcdir in
   *[\\\"\#\$\&\'\`$am_lf\ \	]*)
-    as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+    as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
 esac
 
 # Do `set' in a subshell so we don't clobber the current shell's
@@ -1875,7 +1891,7 @@ if (
       # if, for instance, CONFIG_SHELL is bash and it inherits a
       # broken ls alias from the environment.  This has actually
       # happened.  Such a system could not be considered "sane".
-      as_fn_error "ls -t appears to fail.  Make sure there is not a broken
+      as_fn_error $? "ls -t appears to fail.  Make sure there is not a broken
 alias in your environment" "$LINENO" 5
    fi
 
@@ -1885,7 +1901,7 @@ then
    # Ok.
    :
 else
-   as_fn_error "newly created file is older than distributed files!
+   as_fn_error $? "newly created file is older than distributed files!
 Check your system clock" "$LINENO" 5
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
@@ -1939,7 +1955,7 @@ if test "$cross_compiling" != no; then
 set dummy ${ac_tool_prefix}strip; 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_STRIP+set}" = set; then :
+if ${ac_cv_prog_STRIP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$STRIP"; then
@@ -1979,7 +1995,7 @@ if test -z "$ac_cv_prog_STRIP"; then
 set dummy strip; 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_ac_ct_STRIP+set}" = set; then :
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_STRIP"; then
@@ -2032,7 +2048,7 @@ INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
 if test -z "$MKDIR_P"; then
-  if test "${ac_cv_path_mkdir+set}" = set; then :
+  if ${ac_cv_path_mkdir+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -2083,7 +2099,7 @@ do
 set dummy $ac_prog; 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_AWK+set}" = set; then :
+if ${ac_cv_prog_AWK+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$AWK"; then
@@ -2123,7 +2139,7 @@ done
 $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 { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat >conftest.make <<\_ACEOF
@@ -2131,7 +2147,7 @@ SHELL = /bin/sh
 all:
 	@echo '@@@%%%=$(MAKE)=@@@%%%'
 _ACEOF
-# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+# 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;;
@@ -2165,7 +2181,7 @@ if test "`cd $srcdir && pwd`" != "`pwd`"; then
   am__isrc=' -I$(srcdir)'
   # test to see if srcdir already configured
   if test -f $srcdir/config.status; then
-    as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+    as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
   fi
 fi
 
@@ -2276,13 +2292,14 @@ ASSEMBLY_VERSION="0.4.5.0"
 
 
 
+
 if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
 	if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
 set dummy ${ac_tool_prefix}pkg-config; 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_PKG_CONFIG+set}" = set; then :
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $PKG_CONFIG in
@@ -2325,7 +2342,7 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then
 set dummy pkg-config; 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_PKG_CONFIG+set}" = set; then :
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $ac_pt_PKG_CONFIG in
@@ -2405,6 +2422,7 @@ if test -n "$MONO_MODULE_CFLAGS"; then
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_MONO_MODULE_CFLAGS=`$PKG_CONFIG --cflags "mono >= 1.2.6" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -2421,6 +2439,7 @@ if test -n "$MONO_MODULE_LIBS"; then
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_MONO_MODULE_LIBS=`$PKG_CONFIG --libs "mono >= 1.2.6" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -2440,14 +2459,14 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        MONO_MODULE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "mono >= 1.2.6" 2>&1`
+	        MONO_MODULE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "mono >= 1.2.6" 2>&1`
         else
-	        MONO_MODULE_PKG_ERRORS=`$PKG_CONFIG --print-errors "mono >= 1.2.6" 2>&1`
+	        MONO_MODULE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "mono >= 1.2.6" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$MONO_MODULE_PKG_ERRORS" >&5
 
-	as_fn_error "Package requirements (mono >= 1.2.6) were not met:
+	as_fn_error $? "Package requirements (mono >= 1.2.6) were not met:
 
 $MONO_MODULE_PKG_ERRORS
 
@@ -2462,7 +2481,7 @@ elif test $pkg_failed = untried; then
 $as_echo "no" >&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 "The pkg-config script could not be found or is too old.  Make sure it
+as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
 is in your PATH or set the PKG_CONFIG environment variable to the full
 path to pkg-config.
 
@@ -2471,7 +2490,7 @@ and MONO_MODULE_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details.
 
 To get pkg-config, see <http://pkg-config.freedesktop.org/>.
-See \`config.log' for more details." "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5; }
 else
 	MONO_MODULE_CFLAGS=$pkg_cv_MONO_MODULE_CFLAGS
 	MONO_MODULE_LIBS=$pkg_cv_MONO_MODULE_LIBS
@@ -2487,7 +2506,7 @@ fi
 set dummy mono; 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_MONO+set}" = set; then :
+if ${ac_cv_path_MONO+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $MONO in
@@ -2527,7 +2546,7 @@ fi
 
 
 	if test "xMONO" = "xno"; then
-		as_fn_error "You need to install 'mono'" "$LINENO" 5
+		as_fn_error $? "You need to install 'mono'" "$LINENO" 5
 	fi
 
 
@@ -2540,7 +2559,7 @@ CLR=$MONO
 set dummy gmcs; 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_MCS+set}" = set; then :
+if ${ac_cv_path_MCS+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $MCS in
@@ -2580,13 +2599,13 @@ fi
 
 
 	if test "xMCS" = "xno"; then
-		as_fn_error "You need to install 'gmcs'" "$LINENO" 5
+		as_fn_error $? "You need to install 'gmcs'" "$LINENO" 5
 	fi
 
 
 CSC=$MCS
 
-CSC_FLAGS="-debug -define:TRACE,DEBUG"
+CSC_FLAGS="-debug -define:TRACE,DEBUG -nowarn:1591"
 
 
 
@@ -2604,7 +2623,7 @@ $as_echo "found" >&6; }
 		else
 			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
 $as_echo "not found" >&6; }
-			as_fn_error "missing reqired Mono 2.0 assembly: $asm.dll" "$LINENO" 5
+			as_fn_error $? "missing reqired Mono 2.0 assembly: $asm.dll" "$LINENO" 5
 		fi
 	done
 
@@ -2614,7 +2633,7 @@ $as_echo "not found" >&6; }
 set dummy gacutil; 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_GACUTIL+set}" = set; then :
+if ${ac_cv_path_GACUTIL+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $GACUTIL in
@@ -2651,7 +2670,7 @@ fi
 
 
 if test x$GACUTIL = x; then
-	as_fn_error "You need gacutil" "$LINENO" 5
+	as_fn_error $? "You need gacutil" "$LINENO" 5
 fi
 
 #PKG_CHECK_MODULES([LOG4NET], [log4net])
@@ -2777,10 +2796,21 @@ $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
-    test "x$cache_file" != "x/dev/null" &&
+    if test "x$cache_file" != "x/dev/null"; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
 $as_echo "$as_me: updating cache $cache_file" >&6;}
-    cat confcache >$cache_file
+      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
   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;}
@@ -2832,6 +2862,7 @@ DEFS=`sed -n "$ac_script" confdefs.h`
 
 ac_libobjs=
 ac_ltlibobjs=
+U=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
   ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
@@ -2848,23 +2879,23 @@ LTLIBOBJS=$ac_ltlibobjs
 
 
 if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
-  as_fn_error "conditional \"MAINTAINER_MODE\" was never defined.
+  as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${INSTALL_PKG_CONFIG_TRUE}" && test -z "${INSTALL_PKG_CONFIG_FALSE}"; then
-  as_fn_error "conditional \"INSTALL_PKG_CONFIG\" was never defined.
+  as_fn_error $? "conditional \"INSTALL_PKG_CONFIG\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${INSTALL_PKG_LIB_TRUE}" && test -z "${INSTALL_PKG_LIB_FALSE}"; then
-  as_fn_error "conditional \"INSTALL_PKG_LIB\" was never defined.
+  as_fn_error $? "conditional \"INSTALL_PKG_LIB\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${INSTALL_PKG_GAC_TRUE}" && test -z "${INSTALL_PKG_GAC_FALSE}"; then
-  as_fn_error "conditional \"INSTALL_PKG_GAC\" was never defined.
+  as_fn_error $? "conditional \"INSTALL_PKG_GAC\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 
-: ${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"
@@ -2965,6 +2996,7 @@ 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
@@ -3010,19 +3042,19 @@ export LANGUAGE
 (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
 
-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
 # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
 # provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
+# script with STATUS, using 1 if that was 0.
 as_fn_error ()
 {
-  as_status=$?; test $as_status -eq 0 && as_status=1
-  if test "$3"; then
-    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $1" >&2
+  $as_echo "$as_me: error: $2" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
@@ -3218,7 +3250,7 @@ $as_echo X"$as_dir" |
       test -d "$as_dir" && break
     done
     test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
 
 
 } # as_fn_mkdir_p
@@ -3272,7 +3304,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # values after options handling.
 ac_log="
 This file was extended by smartirc4net $as_me 0.4.5.1, which was
-generated by GNU Autoconf 2.65.  Invocation command line was
+generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -3325,10 +3357,10 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
 smartirc4net config.status 0.4.5.1
-configured by $0, generated by GNU Autoconf 2.65,
+configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
-Copyright (C) 2009 Free Software Foundation, Inc.
+Copyright (C) 2010 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
@@ -3346,11 +3378,16 @@ ac_need_defaults=:
 while test $# != 0
 do
   case $1 in
-  --*=*)
+  --*=?*)
     ac_option=`expr "X$1" : 'X\([^=]*\)='`
     ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
     ac_shift=:
     ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
   *)
     ac_option=$1
     ac_optarg=$2
@@ -3372,6 +3409,7 @@ do
     $ac_shift
     case $ac_optarg in
     *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
     esac
     as_fn_append CONFIG_FILES " '$ac_optarg'"
     ac_need_defaults=false;;
@@ -3382,7 +3420,7 @@ do
     ac_cs_silent=: ;;
 
   # This is an error.
-  -*) as_fn_error "unrecognized option: \`$1'
+  -*) as_fn_error $? "unrecognized option: \`$1'
 Try \`$0 --help' for more information." ;;
 
   *) as_fn_append ac_config_targets " $1"
@@ -3436,7 +3474,7 @@ do
     "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
     "src/AssemblyInfo.cs") CONFIG_FILES="$CONFIG_FILES src/AssemblyInfo.cs" ;;
 
-  *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
 done
 
@@ -3457,9 +3495,10 @@ fi
 # after its creation but before its name has been assigned to `$tmp'.
 $debug ||
 {
-  tmp=
+  tmp= ac_tmp=
   trap 'exit_status=$?
-  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
 ' 0
   trap 'as_fn_exit 1' 1 2 13 15
 }
@@ -3467,12 +3506,13 @@ $debug ||
 
 {
   tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
-  test -n "$tmp" && test -d "$tmp"
+  test -d "$tmp"
 }  ||
 {
   tmp=./conf$$-$RANDOM
   (umask 077 && mkdir "$tmp")
-} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+} || 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.
@@ -3489,12 +3529,12 @@ if test "x$ac_cr" = x; then
 fi
 ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
 if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
-  ac_cs_awk_cr='\r'
+  ac_cs_awk_cr='\\r'
 else
   ac_cs_awk_cr=$ac_cr
 fi
 
-echo 'BEGIN {' >"$tmp/subs1.awk" &&
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
 _ACEOF
 
 
@@ -3503,18 +3543,18 @@ _ACEOF
   echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
   echo "_ACEOF"
 } >conf$$subs.sh ||
-  as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
-ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
   . ./conf$$subs.sh ||
-    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
 
   ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
   if test $ac_delim_n = $ac_delim_num; then
     break
   elif $ac_last_try; then
-    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
   else
     ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
   fi
@@ -3522,7 +3562,7 @@ done
 rm -f conf$$subs.sh
 
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
 _ACEOF
 sed -n '
 h
@@ -3570,7 +3610,7 @@ t delim
 rm -f conf$$subs.awk
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 _ACAWK
-cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
   for (key in S) S_is_set[key] = 1
   FS = ""
 
@@ -3602,21 +3642,29 @@ 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 < "$tmp/subs1.awk" > "$tmp/subs.awk" \
-  || as_fn_error "could not setup config files machinery" "$LINENO" 5
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
 _ACEOF
 
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
 # trailing colons and then remove the whole line if VPATH becomes empty
 # (actually we leave an empty line to preserve line numbers).
 if test "x$srcdir" = x.; then
-  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[	 ]*\):*/\1/
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
 s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
 s/^[^=]*=[	 ]*$//
 }'
 fi
@@ -3634,7 +3682,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
@@ -3653,7 +3701,7 @@ do
     for ac_f
     do
       case $ac_f in
-      -) ac_f="$tmp/stdin";;
+      -) ac_f="$ac_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 `:'.
@@ -3662,7 +3710,7 @@ do
 	   [\\/$]*) false;;
 	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
 	   esac ||
-	   as_fn_error "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'"
@@ -3688,8 +3736,8 @@ $as_echo "$as_me: creating $ac_file" >&6;}
     esac
 
     case $ac_tag in
-    *:-:* | *:-) cat >"$tmp/stdin" \
-      || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
     esac
     ;;
   esac
@@ -3825,23 +3873,24 @@ s&@INSTALL@&$ac_INSTALL&;t t
 s&@MKDIR_P@&$ac_MKDIR_P&;t t
 $ac_datarootdir_hack
 "
-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
+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
 
 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
-  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
-  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { 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"; } &&
   { $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
+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;}
+which seems to be undefined.  Please make sure it is defined" >&2;}
 
-  rm -f "$tmp/stdin"
+  rm -f "$ac_tmp/stdin"
   case $ac_file in
-  -) cat "$tmp/out" && rm -f "$tmp/out";;
-  *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
   esac \
-  || as_fn_error "could not create $ac_file" "$LINENO" 5
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
  ;;
 
 
@@ -3856,7 +3905,7 @@ _ACEOF
 ac_clean_files=$ac_clean_files_save
 
 test $ac_write_fail = 0 ||
-  as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
 
 
 # configure is writing to config.log, and then calls config.status.
@@ -3877,7 +3926,7 @@ if test "$no_create" != yes; then
   exec 5>>config.log
   # Use ||, not &&, to avoid exiting from the if with $? = 1, which
   # would make configure fail if this is the last instruction.
-  $ac_cs_success || as_fn_exit $?
+  $ac_cs_success || as_fn_exit 1
 fi
 if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
diff --git a/lib/SmartIrc4net/configure.ac b/lib/SmartIrc4net/configure.ac
index af622bf..9cc8ec1 100644
--- a/lib/SmartIrc4net/configure.ac
+++ b/lib/SmartIrc4net/configure.ac
@@ -20,7 +20,7 @@ SHAMROCK_FIND_MONO_RUNTIME
 AC_SUBST(CLR, $MONO)
 SHAMROCK_FIND_MONO_2_0_COMPILER
 AC_SUBST(CSC, $MCS)
-CSC_FLAGS="-debug -define:TRACE,DEBUG"
+CSC_FLAGS="-debug -define:TRACE,DEBUG -nowarn:1591"
 AC_SUBST(CSC_FLAGS)
 SHAMROCK_CHECK_MONO_2_0_GAC_ASSEMBLIES([
 	System
diff --git a/lib/SmartIrc4net/src/IrcConnection/IrcConnection.cs b/lib/SmartIrc4net/src/IrcConnection/IrcConnection.cs
index a3385ed..c58756b 100644
--- a/lib/SmartIrc4net/src/IrcConnection/IrcConnection.cs
+++ b/lib/SmartIrc4net/src/IrcConnection/IrcConnection.cs
@@ -573,8 +573,6 @@ namespace Meebey.SmartIrc4net
                 OnConnecting(this, EventArgs.Empty);
             }
             try {
-                System.Net.IPAddress ip = System.Net.Dns.Resolve(Address).AddressList[0];
-
                 _TcpClient = new TcpClient();
                 _TcpClient.NoDelay = true;
                 _TcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1);
@@ -607,9 +605,9 @@ namespace Meebey.SmartIrc4net
                     
                     _TcpClient.Connect(_ProxyHost, _ProxyPort);
                     proxyClient.TcpClient = _TcpClient;
-                    proxyClient.CreateConnection(ip.ToString(), port);
+                    proxyClient.CreateConnection(Address, port);
                 } else {
-                    _TcpClient.Connect(ip, port);
+                    _TcpClient.Connect(Address, port);
                 }
                 
                 Stream stream = _TcpClient.GetStream();
@@ -768,6 +766,7 @@ namespace Meebey.SmartIrc4net
             Logger.Connection.Info("reconnecting...");
 #endif
             Disconnect();
+            Thread.Sleep(AutoRetryDelay * 1000);
             Connect(_AddressList, _Port);
         }
         
@@ -965,46 +964,48 @@ namespace Meebey.SmartIrc4net
         {
             string   rawline = args.Line;
             string[] rawlineex = rawline.Split(new char[] {' '});
-            string   messagecode = "";
+            string   line = null;
+            string   prefix = null;
+            string   command = null;
 
             if (rawline[0] == ':') {
-                messagecode = rawlineex[1];
-                
-                ReplyCode replycode = ReplyCode.Null;
-                try {
-                    replycode = (ReplyCode)int.Parse(messagecode);
-                } catch (FormatException) {
-                }
-                
-                if (replycode != ReplyCode.Null) {
-                    switch (replycode) {
-                        case ReplyCode.Welcome:
-                            _IsRegistered = true;
-#if LOG4NET
-                            Logger.Connection.Info("logged in");
-#endif
-                            break;
-                    }
-                } else {
-                    switch (rawlineex[1]) {
-                        case "PONG":
-                            DateTime now = DateTime.Now;
-                            _LastPongReceived = now;
-                            _Lag = now - _LastPingSent;
+                prefix = rawlineex[0].Substring(1);
+                line = rawline.Substring(prefix.Length + 2);
+            } else {
+                line = rawline;
+            }
+            string[] lineex = line.Split(new char[] {' '});
 
+            command = lineex[0];
+            ReplyCode replycode = ReplyCode.Null;
+            int intReplycode;
+            if (Int32.TryParse(command, out intReplycode)) {
+                replycode = (ReplyCode) intReplycode;
+            }
+            if (replycode != ReplyCode.Null) {
+                switch (replycode) {
+                    case ReplyCode.Welcome:
+                        _IsRegistered = true;
 #if LOG4NET
-                            Logger.Connection.Debug("PONG received, took: " + _Lag.TotalMilliseconds + " ms");
+                        Logger.Connection.Info("logged in");
 #endif
-                            break;
-                    }
+                        break;
                 }
             } else {
-                messagecode = rawlineex[0];
-                switch (messagecode) {
+                switch (command) {
                     case "ERROR":
                         // FIXME: handle server errors differently than connection errors!
                         //IsConnectionError = true;
                         break;
+                    case "PONG":
+                        DateTime now = DateTime.Now;
+                        _LastPongReceived = now;
+                        _Lag = now - _LastPingSent;
+
+#if LOG4NET
+                        Logger.Connection.Debug("PONG received, took: " + _Lag.TotalMilliseconds + " ms");
+#endif
+                        break;
                 }
             }
         }
diff --git a/lib/Twitterizer/CommonAssemblyInfo.cs b/lib/Twitterizer/CommonAssemblyInfo.cs
new file mode 100644
index 0000000..ee09c66
--- /dev/null
+++ b/lib/Twitterizer/CommonAssemblyInfo.cs
@@ -0,0 +1,66 @@
+//-----------------------------------------------------------------------
+// <copyright file="CommonAssemblyInfo.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+//-----------------------------------------------------------------------
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Security;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Twitterizer")]
+[assembly: AssemblyDescription("Twitter integration library")]
+
+#if DEBUG
+[assembly: AssemblyConfiguration("Debug")]
+#else
+[assembly: AssemblyConfiguration("Release")]
+#endif
+
+[assembly: AssemblyCompany("Twitterizer Group (www.twitterizer.net)")]
+[assembly: AssemblyProduct("Twitterizer")]
+[assembly: AssemblyCopyright("2010 Patrick 'Ricky' Smith (www.ricky-dev.com)")]
+[assembly: AssemblyTrademark("")]
+
+[assembly: AssemblyVersion("2.4.0.*")]
+[assembly: AssemblyFileVersion("2.4.0.0")]
+
+#if !SILVERLIGHT
+[assembly: AllowPartiallyTrustedCallers]
+#endif
+
+[assembly: CLSCompliant(true)]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/lib/Twitterizer/GettingStarted.txt b/lib/Twitterizer/GettingStarted.txt
new file mode 100644
index 0000000..d161149
--- /dev/null
+++ b/lib/Twitterizer/GettingStarted.txt
@@ -0,0 +1,46 @@
+		___        ___ ___  ___  __    __  ___  __    _ _ _   
+		 |  |  | |  |   |  |__  |__) |  / |__  |__)    | | 
+		 |  |/\| |  |   |  |___ |  \ | /_ |___ |  \   _|_|_
+
+Q) Which files do I need?
+A) More than likely, you only need Twitterizer2.dll and Newtonsoft.Json.dll
+
+Q) What exactly are all these files?
+A)
+	Twitterizer2.dll
+		This is the main binary which contains the core class library. This file is required for all addon 
+		libraries.
+
+	Twitterizer2.Data.dll
+		This is an additional library that provides data conversion functionality. 
+		For example, with it you can quickly generate DataTables from any Twitterizer2 collection.
+		This file is not necessary for most projects.
+
+	Newtonsoft.Json.dll
+		This is JSON.NET, developed by James Newton-King. You do not need to add a reference in your 
+		project to this library, but it must be placed in your project's bin folder along with Twitterizer2.dll.
+		More information can be found here: http://james.newtonking.com/pages/json-net.aspx
+
+	Twitterizer2.Async.dll
+		This is an addon library that allows developers to call Twitterizer2 methods asynchronously.
+		This file is not necessary for most projects.
+
+	Twitterizer2.Streaming.dll
+		This is an addon library that provides access to the Streaming API.
+		This file is not necessary for most projects.
+
+	Twitterizer.OAuth.dll
+		This is a standalone library that provides access to our OAuth request signing functionality without 
+		using Twitterizer2. _DO_NOT_ include this file in your project if you are using Twitterizer2.dll. 
+		All of the functionality found in this library is available within Twitterizer2.dll.
+		This file is not necessary for most projects.
+
+	Twitterizer2lite.dll
+		This is a slimmed down version of the Twitterizer2.dll file built with the client profile as the target framework.
+		It will lack some extra pieces of functionality, such as the built-in data caching and support for application 
+		configuration settings.
+		_DO_NOT_ include this file in your project if you are using Twitterizer2.dll. 
+		This file is not necessary for most projects.
+
+Q) What about the license files?
+A) The license files must accompany the dlls. That means that they must be distributed along with your application.
\ No newline at end of file
diff --git a/lib/Twitterizer/Json.NET.license.txt b/lib/Twitterizer/Json.NET.license.txt
new file mode 100644
index 0000000..8f532d5
--- /dev/null
+++ b/lib/Twitterizer/Json.NET.license.txt
@@ -0,0 +1,7 @@
+Copyright (c) 2007 James Newton-King
+
+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.
\ No newline at end of file
diff --git a/lib/Twitterizer/Twitterizer2.license.txt b/lib/Twitterizer/Twitterizer2.license.txt
new file mode 100644
index 0000000..86be395
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2.license.txt
@@ -0,0 +1,19 @@
+Copyright (c) 2010, Patrick "Ricky" Smith
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ 
+ - 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.
+   
+ - Neither the name Twitterizer 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 HOLDER 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.
\ No newline at end of file
diff --git a/lib/Twitterizer/Twitterizer2/Core/AccessLevel.cs b/lib/Twitterizer/Twitterizer2/Core/AccessLevel.cs
new file mode 100644
index 0000000..a464b7a
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Core/AccessLevel.cs
@@ -0,0 +1,67 @@
+//-----------------------------------------------------------------------
+// <copyright file="AccessLevel.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>David Golden</author>
+// <summary>The OAuth Token Access Level class. Provides information about the last request made.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer
+{
+    /// <summary>
+    /// Describes the access level of the OAuth Token
+    /// </summary>
+    public enum AccessLevel
+    {
+        /// <summary>
+        /// The request may not be authenticated or the Access Level header was missing from the response.
+        /// </summary>
+        Unknown,
+
+        /// <summary>
+        /// The OAuth token has read access levels only.
+        /// </summary>
+        Read,
+
+        /// <summary>
+        /// The OAuth token has read write access only.
+        /// </summary>
+        ReadWrite,
+
+        /// <summary>
+        /// The OAuth token has read write and direct messages access.
+        /// </summary>
+        ReadWriteDirectMessage,
+
+        /// <summary>
+        /// There was no OAuth token access level available for reading in the response headers.
+        /// </summary>
+        Unavailable
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Core/CommandPerformer.cs b/lib/Twitterizer/Twitterizer2/Core/CommandPerformer.cs
index 45b8fd1..5c4d786 100644
--- a/lib/Twitterizer/Twitterizer2/Core/CommandPerformer.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/CommandPerformer.cs
@@ -34,13 +34,7 @@
 
 namespace Twitterizer.Core
 {
-    /// <summary>
-    /// The Command Performer Class
-    /// </summary>
-    /// <typeparam name="T">The business object the performer should return.</typeparam>
-    /// <tocexclude />
-    internal static class CommandPerformer<T>
-        where T : ITwitterObject
+    internal static class CommandPerformer
     {
         /// <summary>
         /// Performs the action.
@@ -49,22 +43,12 @@ namespace Twitterizer.Core
         /// <returns>The parsed result of the action.</returns>
         /// <seealso cref="Twitterizer.Core.TwitterCommand{T}"/>
         /// <seealso cref="Twitterizer.Core.TwitterObject"/>
-        public static T PerformAction(ICommand<T> command)
+        public static TwitterResponse<T> PerformAction<T>(ICommand<T> command)
+            where T : ITwitterObject
         {
             command.Init();
 
-            T result = default(T);
-
-            try
-            {
-                result = command.ExecuteCommand();
-            }
-            catch (System.Exception)
-            {
-                throw;
-            }
-
-            return result;
+            return command.ExecuteCommand();
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Core/ConversionUtility.cs b/lib/Twitterizer/Twitterizer2/Core/ConversionUtility.cs
index cff5efc..61065ef 100644
--- a/lib/Twitterizer/Twitterizer2/Core/ConversionUtility.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/ConversionUtility.cs
@@ -34,7 +34,9 @@
 
 namespace Twitterizer
 {
+#if !SILVERLIGHT
     using System.Drawing;
+#endif
     using System.IO;
     using System.Text.RegularExpressions;
 
@@ -44,6 +46,7 @@ namespace Twitterizer
     /// <tocexclude />
     internal static class ConversionUtility
     {
+#if !SILVERLIGHT
         /// <summary>
         /// Converts the color string to a <see cref="System.Drawing.Color"/>
         /// </summary>
@@ -63,6 +66,7 @@ namespace Twitterizer
 
             return Color.FromName(value);
         }
+#endif
 
         /// <summary>
         /// Reads the stream into a byte array.
diff --git a/lib/Twitterizer/Twitterizer2/Core/CursorPagedCommand.cs b/lib/Twitterizer/Twitterizer2/Core/CursorPagedCommand.cs
deleted file mode 100644
index ce301ba..0000000
--- a/lib/Twitterizer/Twitterizer2/Core/CursorPagedCommand.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="CursorPagedCommand.cs" company="Patrick 'Ricky' Smith">
-//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
-// 
-//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
-//  All rights reserved.
-//  
-//  Redistribution and use in source and binary forms, with or without modification, are 
-//  permitted provided that the following conditions are met:
-// 
-//  - Redistributions of source code must retain the above copyright notice, this list 
-//    of conditions and the following disclaimer.
-//  - 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.
-//  - Neither the name of the Twitterizer 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.
-// </copyright>
-// <author>Ricky Smith</author>
-// <summary>The interface that indicates that the command results can be paged through using cursors.</summary>
-//-----------------------------------------------------------------------
-namespace Twitterizer.Core
-{
-    using System;
-
-    /// <summary>
-    /// The CursorCursorPagedCommand class.
-    /// </summary>
-    /// <typeparam name="T">The type of BaseObject that the command returns.</typeparam>
-    /// <tocexclude />
-    [Serializable]
-    internal abstract class CursorPagedCommand<T> : TwitterCommand<T>
-        where T : class, ITwitterObject, new()
-    {
-        #region Constructors
-        /// <summary>
-        /// Initializes a new instance of the <see cref="CursorPagedCommand<T>"/> class.
-        /// </summary>
-        /// <param name="method">The method.</param>
-        /// <param name="endPoint">The end point.</param>
-        /// <param name="tokens">The tokens.</param>
-        /// <param name="options">The options.</param>
-        protected CursorPagedCommand(HTTPVerb method, string endPoint, OAuthTokens tokens, OptionalProperties options)
-            : base(method, endPoint, tokens, options)
-        {
-        }
-        #endregion
-
-        /// <summary>
-        /// Gets or sets the cursor.
-        /// </summary>
-        /// <value>The cursor.</value>
-        /// <remarks>
-        /// Optional. 
-        /// Breaks the results into pages. 
-        /// A single page contains 100 users.
-        /// </remarks>
-        public long Cursor { get; set; }
-    }
-}
diff --git a/lib/Twitterizer/Twitterizer2/Core/ICommand.cs b/lib/Twitterizer/Twitterizer2/Core/ICommand.cs
index 3a3a919..fe70d34 100644
--- a/lib/Twitterizer/Twitterizer2/Core/ICommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/ICommand.cs
@@ -47,7 +47,7 @@ namespace Twitterizer.Core
         /// Gets the request parameters.
         /// </summary>
         /// <value>The request parameters.</value>
-        Dictionary<string, string> RequestParameters { get; }
+        Dictionary<string, object> RequestParameters { get; }
 
         /// <summary>
         /// Initializes the command.
@@ -59,6 +59,6 @@ namespace Twitterizer.Core
         /// </summary>
         /// <returns>The results of the command.</returns>
         /// <see cref="Twitterizer.Core.TwitterObject"/>
-        T ExecuteCommand();
+        TwitterResponse<T> ExecuteCommand();
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Core/ITwitterObject.cs b/lib/Twitterizer/Twitterizer2/Core/ITwitterObject.cs
index 864df0b..de92013 100644
--- a/lib/Twitterizer/Twitterizer2/Core/ITwitterObject.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/ITwitterObject.cs
@@ -41,27 +41,9 @@ namespace Twitterizer.Core
     public interface ITwitterObject
     {
         /// <summary>
-        /// Gets or sets information about the user's rate usage.
+        /// Annotations are additional pieces of data, supplied by Twitter clients, in a non-structured dictionary.
         /// </summary>
-        /// <value>The rate limiting object.</value>
-        RateLimiting RateLimiting { get; set; }
-
-        /// <summary>
-        /// Gets or sets the oauth tokens.
-        /// </summary>
-        /// <value>The oauth tokens.</value>
-        OAuthTokens Tokens { get; set; }
-
-        /// <summary>
-        /// Gets details about the request attempted.
-        /// </summary>
-        /// <value>The last request status.</value>
-        RequestStatus RequestStatus { get; set; }
-
-        /// <summary>
-        /// Gets or sets a value indicating whether this instance is empty.
-        /// </summary>
-        /// <value><c>true</c> if this instance is empty; otherwise, <c>false</c>.</value>
-        bool IsEmpty { get; set; }
+        /// <value>The annotations.</value>
+        System.Collections.Generic.Dictionary<string, string> Annotations { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Core/OptionalProperties.cs b/lib/Twitterizer/Twitterizer2/Core/OptionalProperties.cs
index 8248656..3cce16d 100644
--- a/lib/Twitterizer/Twitterizer2/Core/OptionalProperties.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/OptionalProperties.cs
@@ -39,7 +39,9 @@ namespace Twitterizer
     using System.Net;
 
     /// <include file='OptionalProperties.xml' path='OptionalProperties/OptionalProperties/*'/>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public class OptionalProperties
     {
         /// <summary>
@@ -49,11 +51,13 @@ namespace Twitterizer
         {
             // Set the default values for the properties
             this.UseSSL = false;
-            this.CacheOutput = false;
             this.APIBaseAddress = "http://api.twitter.com/1/";
-            this.CacheTimespan = new TimeSpan(0, 5, 0);
 
+#if !LITE && !SILVERLIGHT
+            this.CacheOutput = false;
+            this.CacheTimespan = new TimeSpan(0, 5, 0);
             this.ReadConfigurationSettings();
+#endif
         }
 
         /// <include file='OptionalProperties.xml' path='OptionalProperties/Property[@name="UseSSL"]/*'/>
@@ -65,20 +69,24 @@ namespace Twitterizer
         /// <include file='OptionalProperties.xml' path='OptionalProperties/Property[@name="APIBaseAddress"]/*'/>
         public string APIBaseAddress { get; set; }
 
+#if !SILVERLIGHT
         /// <include file='OptionalProperties.xml' path='OptionalProperties/Property[@name="Proxy"]/*'/>
         public WebProxy Proxy { get; set; }
+#endif
 
+#if !LITE && !SILVERLIGHT
         /// <include file='OptionalProperties.xml' path='OptionalProperties/Property[@name="CacheOutput"]/*'/>
         public bool CacheOutput { get; set; }
 
         /// <include file='OptionalProperties.xml' path='OptionalProperties/Property[@name="CacheTimespan"]/*'/>
-        public TimeSpan CacheTimespan { get; set; }
+		public TimeSpan CacheTimespan { get; set; }
 
-        /// <summary>
+		/// <summary>
         /// Reads the configuration settings.
         /// </summary>
         private void ReadConfigurationSettings()
         {
+
             System.Collections.Specialized.NameValueCollection appSettings = ConfigurationManager.AppSettings;
 
             // Get the enable caching configuration setting
@@ -105,5 +113,6 @@ namespace Twitterizer
                 this.UseSSL = true;
             }
         }
-    }
+#endif
+        }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Core/PagedCommand.cs b/lib/Twitterizer/Twitterizer2/Core/PagedCommand.cs
deleted file mode 100644
index f033e0f..0000000
--- a/lib/Twitterizer/Twitterizer2/Core/PagedCommand.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="PagedCommand.cs" company="Patrick 'Ricky' Smith">
-//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
-// 
-//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
-//  All rights reserved.
-//  
-//  Redistribution and use in source and binary forms, with or without modification, are 
-//  permitted provided that the following conditions are met:
-// 
-//  - Redistributions of source code must retain the above copyright notice, this list 
-//    of conditions and the following disclaimer.
-//  - 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.
-//  - Neither the name of the Twitterizer 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.
-// </copyright>
-// <author>Ricky Smith</author>
-// <summary>The interface that indicates that the command results can be paged through.</summary>
-//-----------------------------------------------------------------------
-namespace Twitterizer.Core
-{
-    using System;
-
-    /// <summary>
-    /// The IPagedCommand interface.
-    /// </summary>
-    /// <typeparam name="T">The type of BaseObject that the command returns.</typeparam>
-    [Serializable]
-    internal abstract class PagedCommand<T> : TwitterCommand<T>
-        where T : class, ITwitterObject, new()
-    {
-        /// <summary>
-        /// Initializes a new instance of the <see cref="PagedCommand<T>"/> class.
-        /// </summary>
-        /// <param name="httpMethod">The HTTP method.</param>
-        /// <param name="endPoint">The end point.</param>
-        /// <param name="tokens">The tokens.</param>
-        /// <param name="optionalProperties">The optional properties.</param>
-        protected PagedCommand(HTTPVerb httpMethod, string endPoint, OAuthTokens tokens, OptionalProperties optionalProperties)
-            : base(httpMethod, endPoint, tokens, optionalProperties)
-        {
-        }
-        
-        /// <summary>
-        /// Gets or sets the page number to obtain.
-        /// </summary>
-        /// <value>The page number.</value>
-        public int Page { get; set; }
-    }
-}
diff --git a/lib/Twitterizer/Twitterizer2/Core/RateLimit.cs b/lib/Twitterizer/Twitterizer2/Core/RateLimit.cs
index b0dd952..dc079ad 100644
--- a/lib/Twitterizer/Twitterizer2/Core/RateLimit.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/RateLimit.cs
@@ -38,7 +38,9 @@ namespace Twitterizer
     /// <summary>
     /// Provides data about the user's current rate limiting.
     /// </summary>
-    [Serializable]
+#if !SILVERLIGHT
+    [System.Serializable]
+#endif
     public class RateLimiting
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Core/RequestResult.cs b/lib/Twitterizer/Twitterizer2/Core/RequestResult.cs
index 7dad32b..2d375e8 100644
--- a/lib/Twitterizer/Twitterizer2/Core/RequestResult.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/RequestResult.cs
@@ -80,8 +80,18 @@ namespace Twitterizer
         TwitterIsOverloaded,
 
         /// <summary>
+        /// The request failed due to a connection issue or timeout.
+        /// </summary>
+        ConnectionFailure,
+
+        /// <summary>
         /// Something unexpected happened. See the error message for additional information.
         /// </summary>
-        Unknown
+        Unknown,
+
+        /// <summary>
+        /// Failed to authenticate with the proxy.
+        /// </summary>
+        ProxyAuthenticationRequired
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Core/RequestStatus.cs b/lib/Twitterizer/Twitterizer2/Core/RequestStatus.cs
deleted file mode 100644
index 11b59e3..0000000
--- a/lib/Twitterizer/Twitterizer2/Core/RequestStatus.cs
+++ /dev/null
@@ -1,254 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="RequestStatus.cs" company="Patrick 'Ricky' Smith">
-//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
-// 
-//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
-//  All rights reserved.
-//  
-//  Redistribution and use in source and binary forms, with or without modification, are 
-//  permitted provided that the following conditions are met:
-// 
-//  - Redistributions of source code must retain the above copyright notice, this list 
-//    of conditions and the following disclaimer.
-//  - 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.
-//  - Neither the name of the Twitterizer 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.
-// </copyright>
-// <author>Ricky Smith</author>
-// <summary>The twitter status class. Provides information about the last request made.</summary>
-//-----------------------------------------------------------------------
-
-namespace Twitterizer
-{
-    using System;
-    using System.Net;
-    using System.Text;
-    using System.Xml.Serialization;
-    using Twitterizer.Core;
-
-    /// <summary>
-    /// Describes the result status of a request
-    /// </summary>
-    public enum RequestResult
-    {
-        /// <summary>
-        /// The request was completed successfully
-        /// </summary>
-        Success,
-
-        /// <summary>
-        /// The URI requested is invalid or the resource requested, such as a user, does not exists.
-        /// </summary>
-        FileNotFound,
-
-        /// <summary>
-        /// The request was invalid.  An accompanying error message will explain why.
-        /// </summary>
-        BadRequest,
-
-        /// <summary>
-        /// Authentication credentials were missing or incorrect.
-        /// </summary>
-        Unauthorized,
-
-        /// <summary>
-        /// Returned by the Search API when an invalid format is specified in the request.
-        /// </summary>
-        NotAcceptable,
-
-        /// <summary>
-        /// The authorized user, or client IP address, is being rate limited.
-        /// </summary>
-        RateLimited,
-
-        /// <summary>
-        /// Twitter is currently down.
-        /// </summary>
-        TwitterIsDown,
-
-        /// <summary>
-        /// Twitter is online, but is overloaded. Try again later.
-        /// </summary>
-        TwitterIsOverloaded,
-
-        /// <summary>
-        /// Something unexpected happened. See the error message for additional information.
-        /// </summary>
-        Unknown
-    }
-
-    /// <summary>
-    /// The twitter status class. Provides thread-safe information about the last request made.
-    /// </summary>
-    [Serializable]
-    public sealed class RequestStatus
-    {
-        /// <summary>
-        /// A lock for the last status instance
-        /// </summary>
-        private static readonly object padlock = new object();
-
-        /// <summary>
-        /// The last request status
-        /// </summary>
-        private static RequestStatus lastRequestStatus;
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="RequestStatus"/> class.
-        /// </summary>
-        internal RequestStatus()
-        {
-            this.Status = RequestResult.Success;
-        }
-
-        /// <summary>
-        /// Gets the last request status.
-        /// </summary>
-        /// <value>The last request status.</value>
-        public static RequestStatus LastRequestStatus
-        {
-            get
-            {
-                lock (padlock)
-                {
-                    if (lastRequestStatus == null)
-                    {
-                        lastRequestStatus = new RequestStatus();
-                    }
-
-                    return lastRequestStatus;
-                }
-            }
-        }
-
-        /// <summary>
-        /// Gets the full path.
-        /// </summary>
-        /// <value>The full path.</value>
-        public string FullPath { get; internal set; }
-
-        /// <summary>
-        /// Gets the error details.
-        /// </summary>
-        /// <value>The error details.</value>
-        public TwitterErrorDetails ErrorDetails { get; internal set; }
-
-        /// <summary>
-        /// Gets the response body.
-        /// </summary>
-        /// <value>The response body.</value>
-        public string ResponseBody { get; internal set; }
-
-        /// <summary>
-        /// Gets the status.
-        /// </summary>
-        /// <value>The status.</value>
-        public RequestResult Status { get; internal set; }
-
-        /// <summary>
-        /// Updates the request status.
-        /// </summary>
-        /// <param name="responseData">The response data.</param>
-        /// <param name="absoluteUri">The absolute URI.</param>
-        /// <param name="statusCode">The status code.</param>
-        /// <param name="contentType">Type of the content.</param>
-        /// <returns>
-        /// 	<c>true</c> if the status was updated successfully, otherwise <c>false</c>
-        /// </returns>
-        internal static void UpdateRequestStatus(byte[] responseData, string absoluteUri, HttpStatusCode statusCode, string contentType, RateLimiting rateLimiting)
-        {
-            RequestStatus requestStatus = BuildRequestStatus(responseData, absoluteUri, statusCode, contentType, rateLimiting);
-
-            UpdateRequestStatus(requestStatus);
-        }
-
-        /// <summary>
-        /// Updates the request status.
-        /// </summary>
-        /// <param name="requestStatus">The request status.</param>
-        internal static void UpdateRequestStatus(RequestStatus requestStatus)
-        {
-            lock (padlock)
-            {
-                lastRequestStatus = requestStatus;
-            }
-        }
-
-        /// <summary>
-        /// Builds the request status.
-        /// </summary>
-        /// <param name="responseData">The response data.</param>
-        /// <param name="absoluteUri">The absolute URI.</param>
-        /// <param name="statusCode">The status code.</param>
-        /// <param name="contentType">Type of the content.</param>
-        /// <returns></returns>
-        internal static RequestStatus BuildRequestStatus(byte[] responseData, string absoluteUri, HttpStatusCode statusCode, string contentType, RateLimiting rateLimiting)
-        {
-            RequestStatus requestStatus = new RequestStatus();
-
-            requestStatus.ResponseBody = Encoding.UTF8.GetString(responseData);
-            requestStatus.FullPath = absoluteUri;
-
-            // Lookup the status code and set the status accordingly
-            switch (statusCode)
-            {
-                case HttpStatusCode.OK:
-                    requestStatus.Status = RequestResult.Success;
-                    break;
-
-                case HttpStatusCode.BadRequest:
-            		requestStatus.Status = rateLimiting.Remaining == 0 ? RequestResult.RateLimited : RequestResult.BadRequest;
-                    break;
-
-                case HttpStatusCode.Unauthorized:
-                    requestStatus.Status = RequestResult.Unauthorized;
-                    break;
-
-                case HttpStatusCode.NotFound:
-                    requestStatus.Status = RequestResult.FileNotFound;
-                    break;
-
-                default:
-                    requestStatus.Status = RequestResult.Unknown;
-                    break;
-            }
-
-            // Attempt to parse the error details returned by the API
-            try
-            {
-                if (responseData.Length > 0 && requestStatus.Status != RequestResult.Success)
-                {
-                    if (contentType.StartsWith("text/xml", StringComparison.OrdinalIgnoreCase))
-                    {
-                        XmlSerializer xmlSerializer = new XmlSerializer(typeof(TwitterErrorDetails));
-                        requestStatus.ErrorDetails = xmlSerializer.Deserialize(new System.IO.MemoryStream(responseData)) as TwitterErrorDetails;
-                    }
-
-                    if (contentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
-                    {
-                        requestStatus.ErrorDetails = SerializationHelper<TwitterErrorDetails>.Deserialize(responseData);
-                    }
-                }
-            }
-            catch (Exception)
-            {
-                // Do nothing.
-            }
-            return requestStatus;
-        }
-    }
-}
diff --git a/lib/Twitterizer/Twitterizer2/Core/SerializationHelper.cs b/lib/Twitterizer/Twitterizer2/Core/SerializationHelper.cs
index 1c43591..387d913 100644
--- a/lib/Twitterizer/Twitterizer2/Core/SerializationHelper.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/SerializationHelper.cs
@@ -34,7 +34,6 @@
 
 namespace Twitterizer.Core
 {
-    using System.Diagnostics;
     using System.Text;
     using Newtonsoft.Json;
     using Newtonsoft.Json.Linq;
@@ -65,20 +64,15 @@ namespace Twitterizer.Core
         public static T Deserialize(byte[] webResponseData, DeserializationHandler deserializationHandler)
         {
             T resultObject;
-#if DEBUG
-            Debug.WriteLine("----------- RESPONSE -----------");
-            Debug.WriteLine(Encoding.UTF8.GetString(webResponseData));
-            Debug.WriteLine("----------- END -----------");
-#endif
 
             // Deserialize the results.
             if (deserializationHandler == null)
             {
-                resultObject = JsonConvert.DeserializeObject<T>(Encoding.UTF8.GetString(webResponseData));
+                resultObject = JsonConvert.DeserializeObject<T>(Encoding.UTF8.GetString(webResponseData, 0, webResponseData.Length));
             }
             else
             {
-                resultObject = deserializationHandler((JObject)JsonConvert.DeserializeObject(Encoding.UTF8.GetString(webResponseData)));
+                resultObject = deserializationHandler((JObject)JsonConvert.DeserializeObject(Encoding.UTF8.GetString(webResponseData, 0, webResponseData.Length)));
             }
 
             return resultObject;
diff --git a/lib/Twitterizer/Twitterizer2/Core/TwitterCollection.cs b/lib/Twitterizer/Twitterizer2/Core/TwitterCollection.cs
index 4eb8fb2..bb404f2 100644
--- a/lib/Twitterizer/Twitterizer2/Core/TwitterCollection.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/TwitterCollection.cs
@@ -36,61 +36,24 @@ namespace Twitterizer.Core
 {
     using System;
     using System.Collections.ObjectModel;
-    using System.Xml.Serialization;
+    using System.Runtime.Serialization;
 
     /// <summary>
     /// The base class for object collections.
     /// </summary>
     /// <typeparam name="T">The type of object stored in the collection.</typeparam>
+#if !SILVERLIGHT
     [Serializable]
-    public abstract class TwitterCollection<T> : Collection<T>, ITwitterObject
-        where T : ITwitterObject
+#endif
+    [DataContract]
+    public abstract class TwitterCollection<T> : Collection<T>
+        where T : class, ITwitterObject
     {
         /// <summary>
-        /// The oauth tokens
+        /// Gets or sets the annotations.
         /// </summary>
-        private OAuthTokens tokens;
-
-        /// <summary>
-        /// Gets or sets information about the user's rate usage.
-        /// </summary>
-        /// <value>The rate limiting object.</value>
-        public RateLimiting RateLimiting { get; set; }
-
-        /// <summary>
-        /// Gets or sets the oauth tokens.
-        /// </summary>
-        /// <value>The oauth tokens.</value>
-        [XmlIgnore, SoapIgnore]
-        public OAuthTokens Tokens
-        {
-            get
-            {
-                return this.tokens;
-            }
-
-            set
-            {
-                this.tokens = value;
-
-                foreach (T item in this)
-                {
-                    item.Tokens = value;
-                }
-            }
-        }
-
-        /// <summary>
-        /// Gets details about the request attempted.
-        /// </summary>
-        /// <value>The last request status.</value>
-        [XmlIgnore, SoapIgnore]
-        public RequestStatus RequestStatus { get; set; }
-
-        /// <summary>
-        /// Gets or sets a value indicating whether this instance is empty.
-        /// </summary>
-        /// <value><c>true</c> if this instance is empty; otherwise, <c>false</c>.</value>
-        public new bool IsEmpty { get; set; }
+        /// <value>The annotations.</value>
+        [DataMember]
+        public System.Collections.Generic.Dictionary<string, string> Annotations { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Core/TwitterCommand.cs b/lib/Twitterizer/Twitterizer2/Core/TwitterCommand.cs
index 494ef3c..33f5e30 100644
--- a/lib/Twitterizer/Twitterizer2/Core/TwitterCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/TwitterCommand.cs
@@ -35,22 +35,27 @@ namespace Twitterizer.Core
 {
     using System;
     using System.Collections.Generic;
-    using System.Diagnostics;
     using System.Globalization;
-    using System.IO;
     using System.Net;
+    using System.Linq;
     using System.Text;
+#if !SILVERLIGHT
     using System.Web;
+#endif
+#if !LITE && !SILVERLIGHT
     using System.Web.Caching;
+#endif
     using Twitterizer;
 
     /// <summary>
     /// The base command class.
     /// </summary>
     /// <typeparam name="T">The business object the command should return.</typeparam>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal abstract class TwitterCommand<T> : ICommand<T>
-        where T : class, ITwitterObject, new()
+        where T : ITwitterObject
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="TwitterCommand<T>"/> class.
@@ -61,10 +66,10 @@ namespace Twitterizer.Core
         /// <param name="optionalProperties">The optional properties.</param>
         protected TwitterCommand(HTTPVerb method, string endPoint, OAuthTokens tokens, OptionalProperties optionalProperties)
         {
-            this.RequestParameters = new Dictionary<string, string>();
+			this.RequestParameters = new Dictionary<string, object>();
             this.Verb = method;
             this.Tokens = tokens;
-            this.OptionalProperties = optionalProperties == null ? new OptionalProperties() : optionalProperties;
+            this.OptionalProperties = optionalProperties ?? new OptionalProperties();
 
             this.SetCommandUri(endPoint);
         }
@@ -91,13 +96,7 @@ namespace Twitterizer.Core
         /// Gets or sets the request parameters.
         /// </summary>
         /// <value>The request parameters.</value>
-        public Dictionary<string, string> RequestParameters { get; set; }
-
-        /// <summary>
-        /// Gets or sets the image to upload.
-        /// </summary>
-        /// <value>The image to upload.</value>
-        public TwitterImage ImageToUpload { get; set; }
+        public Dictionary<string, object> RequestParameters { get; set; }
 
         /// <summary>
         /// Gets or sets the serialization delegate.
@@ -117,18 +116,24 @@ namespace Twitterizer.Core
         public abstract void Init();
 
         /// <summary>
+        /// Gets or sets a value indicating whether this <see cref="TwitterCommand<T>"/> is multipart.
+        /// </summary>
+        /// <value><c>true</c> if multipart; otherwise, <c>false</c>.</value>
+        public bool Multipart { get; set; }
+
+        /// <summary>
         /// Executes the command.
         /// </summary>
         /// <returns>The results of the command.</returns>
-        public T ExecuteCommand()
+        public TwitterResponse<T> ExecuteCommand()
         {
+            TwitterResponse<T> twitterResponse = new TwitterResponse<T>();
+
             if (this.OptionalProperties.UseSSL)
             {
                 this.Uri = new Uri(this.Uri.AbsoluteUri.Replace("http://", "https://"));
             }
 
-            Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Begin {0}", this.Uri.AbsoluteUri), "Twitterizer2");
-
             // Loop through all of the custom attributes assigned to the command class
             foreach (Attribute attribute in this.GetType().GetCustomAttributes(false))
             {
@@ -150,7 +155,7 @@ namespace Twitterizer.Core
                 else if (attribute.GetType() == typeof(RateLimitedAttribute))
                 {
                     // Get the rate limiting status
-                    if (TwitterRateLimitStatus.GetStatus(this.Tokens).RemainingHits == 0)
+                    if (TwitterRateLimitStatus.GetStatus(this.Tokens).ResponseObject.RemainingHits == 0)
                     {
                         throw new TwitterizerException("You are being rate limited.");
                     }
@@ -158,6 +163,7 @@ namespace Twitterizer.Core
 
             }
 
+#if !LITE && !SILVERLIGHT
             // Variables and objects needed for caching
             StringBuilder cacheKeyBuilder = new StringBuilder(this.Uri.AbsoluteUri);
             if (this.Tokens != null)
@@ -166,42 +172,48 @@ namespace Twitterizer.Core
             }
 
             Cache cache = HttpRuntime.Cache;
+#endif
 
             // Prepare the query parameters
-            Dictionary<string, string> queryParameters = new Dictionary<string, string>();
-            foreach (KeyValuePair<string, string> item in this.RequestParameters)
+			Dictionary<string, object> queryParameters = new Dictionary<string, object>();
+			foreach (KeyValuePair<string, object> item in this.RequestParameters)
             {
                 queryParameters.Add(item.Key, item.Value);
+#if !LITE && !SILVERLIGHT
                 cacheKeyBuilder.AppendFormat("|{0}={1}", item.Key, item.Value);
+#endif
             }
 
+#if !LITE && !SILVERLIGHT
             // Lookup the cached item and return it
             if (this.Verb == HTTPVerb.GET && this.OptionalProperties.CacheOutput && cache[cacheKeyBuilder.ToString()] != null)
             {
                 if (cache[cacheKeyBuilder.ToString()] is T)
                 {
-                    Debug.WriteLine("Found in cache", "Twitterizer2");
-                    Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "End {0}", this.Uri.AbsoluteUri), "Twitterizer2");
-                    return (T)cache[cacheKeyBuilder.ToString()];
+                    return new TwitterResponse<T>()
+                               {
+                                   ResponseObject = (T)cache[cacheKeyBuilder.ToString()],
+                                   ResponseCached = true
+                               };
                 }
             }
-
+            
+#endif
             // Declare the variable to be returned
-            T resultObject = default(T);
-            RequestStatus requestStatus = null;
-            RateLimiting rateLimiting = null;
-
-            // This must be set for all twitter request.
-            System.Net.ServicePointManager.Expect100Continue = false;
-
-            byte[] responseData = null;
+            twitterResponse.ResponseObject = default(T);
+            twitterResponse.RequestUrl = this.Uri.AbsoluteUri;
+            RateLimiting rateLimiting;
+            AccessLevel accessLevel;
+            byte[] responseData;
 
             try
             {
-                WebRequestBuilder requestBuilder = new WebRequestBuilder(this.Uri, this.Verb, this.Tokens);
+				WebRequestBuilder requestBuilder = new WebRequestBuilder(this.Uri, this.Verb, this.Tokens, "") { Multipart = this.Multipart };
 
+#if !SILVERLIGHT
                 if (this.OptionalProperties != null)
                     requestBuilder.Proxy = this.OptionalProperties.Proxy;
+#endif
 
                 foreach (var item in queryParameters)
                 {
@@ -211,80 +223,132 @@ namespace Twitterizer.Core
                 HttpWebResponse response = requestBuilder.ExecuteRequest();
 
                 responseData = ConversionUtility.ReadStream(response.GetResponseStream());
+                twitterResponse.Content = Encoding.UTF8.GetString(responseData, 0, responseData.Length);
+
+                twitterResponse.RequestUrl = requestBuilder.RequestUri.AbsoluteUri;
 
                 // Parse the rate limiting HTTP Headers
                 rateLimiting = ParseRateLimitHeaders(response.Headers);
 
-                // Build the request status (holds details about the last request) and update the singleton
-                requestStatus = RequestStatus.BuildRequestStatus(
-                    responseData,
-                    response.ResponseUri.AbsoluteUri,
-                    response.StatusCode,
-                    response.ContentType,
-                    rateLimiting);
+                // Parse Access Level
+                accessLevel = ParseAccessLevel(response.Headers);
+
+                // Lookup the status code and set the status accordingly
+                SetStatusCode(twitterResponse, response.StatusCode, rateLimiting);
 
-                RequestStatus.UpdateRequestStatus(requestStatus);
+                twitterResponse.RateLimiting = rateLimiting;
+                twitterResponse.AccessLevel = accessLevel;
             }
             catch (WebException wex)
             {
-                Trace.TraceError(wex.Message);
+                if (new[]
+                        {
+#if !SILVERLIGHT
+                            WebExceptionStatus.Timeout, 
+                            WebExceptionStatus.ConnectionClosed,
+#endif
+                            WebExceptionStatus.ConnectFailure
+                        }.Contains(wex.Status))
+                {
+                    twitterResponse.Result = RequestResult.ConnectionFailure;
+                    twitterResponse.ErrorMessage = wex.Message;
+                    return twitterResponse;
+                }
 
                 // The exception response should always be an HttpWebResponse, but we check for good measure.
                 HttpWebResponse exceptionResponse = wex.Response as HttpWebResponse;
 
-                if (wex.Response == null)
+                if (exceptionResponse == null)
                 {
                     throw;
                 }
 
                 responseData = ConversionUtility.ReadStream(exceptionResponse.GetResponseStream());
+                twitterResponse.Content = Encoding.UTF8.GetString(responseData, 0, responseData.Length);
 
                 rateLimiting = ParseRateLimitHeaders(exceptionResponse.Headers);
 
-                requestStatus = RequestStatus.BuildRequestStatus(
-                        responseData,
-                        exceptionResponse.ResponseUri.AbsoluteUri,
-                        exceptionResponse.StatusCode,
-                        exceptionResponse.ContentType,
-                        rateLimiting);
+                // Parse Access Level
+                accessLevel = ParseAccessLevel(exceptionResponse.Headers);
+
+                // Try to read the error message, if there is one.
+                try
+                {
+                    twitterResponse.ErrorMessage = SerializationHelper<TwitterErrorDetails>.Deserialize(responseData).ErrorMessage;
+                }
+                catch (Exception)
+                {
+                    // Occasionally, Twitter responds with XML error data even though we asked for json.
+                    // This is that scenario. We will deal with it by doing nothing. It's up to the developer to deal with it.
+                }
+
+                // Lookup the status code and set the status accordingly
+                SetStatusCode(twitterResponse, exceptionResponse.StatusCode, rateLimiting);
 
-                RequestStatus.UpdateRequestStatus(requestStatus);
+                twitterResponse.RateLimiting = rateLimiting;
+                twitterResponse.AccessLevel = accessLevel;
 
                 if (wex.Status == WebExceptionStatus.UnknownError)
                     throw;
 
-                return new T() { IsEmpty = true, RequestStatus = requestStatus, RateLimiting = rateLimiting };
+                return twitterResponse;
             }
-            finally
+
+            try
             {
-                // Set this back to the default so it doesn't affect other .net code.
-                System.Net.ServicePointManager.Expect100Continue = true;
+                twitterResponse.ResponseObject = SerializationHelper<T>.Deserialize(responseData, this.DeserializationHandler);
+            }
+            catch (Newtonsoft.Json.JsonReaderException)
+            {
+                twitterResponse.ErrorMessage = "Unable to parse JSON";
+                twitterResponse.Result = RequestResult.Unknown;
+                return twitterResponse;
             }
 
-            resultObject = SerializationHelper<T>.Deserialize(responseData, this.DeserializationHandler);
-
-            this.AddResultToCache(cacheKeyBuilder, cache, resultObject);
-
-            if (resultObject == null)
-                resultObject = new T();
+#if !LITE && !SILVERLIGHT
+            this.AddResultToCache(cacheKeyBuilder, cache, twitterResponse.ResponseObject);
+#endif
 
             // Pass the current oauth tokens into the new object, so method calls from there will keep the authentication.
-            resultObject.Tokens = this.Tokens;
-            resultObject.RequestStatus = requestStatus;
-            resultObject.RateLimiting = rateLimiting;
-
-            Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Finished {0}", this.Uri.AbsoluteUri), "Twitterizer2");
+            twitterResponse.Tokens = this.Tokens;
 
-            return resultObject;
+            return twitterResponse;
         }
 
         /// <summary>
-        /// Clones this instance.
+        /// Sets the status code.
         /// </summary>
-        /// <returns>A new instance of the <see cref="Twitterizer.Core.PagedCommand{T}"/> interface.</returns>
-        internal virtual TwitterCommand<T> Clone()
+        /// <param name="twitterResponse">The twitter response.</param>
+        /// <param name="statusCode">The status code.</param>
+        /// <param name="rateLimiting">The rate limiting.</param>
+        private static void SetStatusCode(TwitterResponse<T> twitterResponse, HttpStatusCode statusCode, RateLimiting rateLimiting)
         {
-            return default(TwitterCommand<T>);
+            switch (statusCode)
+            {
+                case HttpStatusCode.OK:
+                    twitterResponse.Result = RequestResult.Success;
+                    break;
+
+                case HttpStatusCode.BadRequest:
+                    twitterResponse.Result = rateLimiting.Remaining == 0 ? RequestResult.RateLimited : RequestResult.BadRequest;
+                    break;
+
+                case HttpStatusCode.Unauthorized:
+                    twitterResponse.Result = RequestResult.Unauthorized;
+                    break;
+
+                case HttpStatusCode.NotFound:
+                    twitterResponse.Result = RequestResult.FileNotFound;
+                    break;
+
+                case HttpStatusCode.ProxyAuthenticationRequired:
+                    twitterResponse.Result = RequestResult.ProxyAuthenticationRequired;
+                    break;
+
+                default:
+                    twitterResponse.Result = RequestResult.Unknown;
+                    break;
+            }
         }
 
         /// <summary>
@@ -293,6 +357,9 @@ namespace Twitterizer.Core
         /// <param name="endPoint">The end point.</param>
         protected void SetCommandUri(string endPoint)
         {
+            if (endPoint.StartsWith("/"))
+                throw new ArgumentException("The API endpoint cannot begin with a forward slash. This will result in 404 errors and headaches.", "endPoint");
+
             this.Uri = new Uri(string.Concat(this.OptionalProperties.APIBaseAddress, endPoint));
         }
 
@@ -305,25 +372,54 @@ namespace Twitterizer.Core
         {
             RateLimiting rateLimiting = new RateLimiting();
 
-            if (!string.IsNullOrEmpty(responseHeaders.Get("X-RateLimit-Limit")))
+            if (responseHeaders.AllKeys.Contains("X-RateLimit-Limit"))
             {
-                rateLimiting.Total = int.Parse(responseHeaders.Get("X-RateLimit-Limit"), CultureInfo.InvariantCulture);
+                rateLimiting.Total = int.Parse(responseHeaders["X-RateLimit-Limit"], CultureInfo.InvariantCulture);
             }
 
-            if (!string.IsNullOrEmpty(responseHeaders.Get("X-RateLimit-Remaining")))
+            if (responseHeaders.AllKeys.Contains("X-RateLimit-Remaining"))
             {
-                rateLimiting.Remaining = int.Parse(responseHeaders.Get("X-RateLimit-Remaining"), CultureInfo.InvariantCulture);
+                rateLimiting.Remaining = int.Parse(responseHeaders["X-RateLimit-Remaining"], CultureInfo.InvariantCulture);
             }
 
             if (!string.IsNullOrEmpty(responseHeaders["X-RateLimit-Reset"]))
             {
-                rateLimiting.ResetDate = TimeZone.CurrentTimeZone.ToLocalTime(DateTime.SpecifyKind(new DateTime(1970, 1, 1, 0, 0, 0, 0)
-                    .AddSeconds(double.Parse(responseHeaders.Get("X-RateLimit-Reset"), CultureInfo.InvariantCulture)), DateTimeKind.Utc));
+                rateLimiting.ResetDate = DateTime.SpecifyKind(new DateTime(1970, 1, 1, 0, 0, 0, 0)
+                    .AddSeconds(double.Parse(responseHeaders["X-RateLimit-Reset"], CultureInfo.InvariantCulture)), DateTimeKind.Utc);
             }
             return rateLimiting;
         }
 
         /// <summary>
+        /// Parses the access level headers.
+        /// </summary>
+        /// <param name="responseHeaders">The headers of the web response.</param>
+        /// <returns>An enum of the current access level of the OAuth Token being used.</returns>
+        private AccessLevel ParseAccessLevel(WebHeaderCollection responseHeaders)
+        {
+            if (responseHeaders.AllKeys.Contains("X-Access-Level"))
+            {
+                switch (responseHeaders["X-Access-Level"].ToLower())
+                {
+                    case "read":
+                        return AccessLevel.Read;
+                    case "read-write":
+                        return AccessLevel.ReadWrite;
+                    case "read-write-privatemessages":
+                    case "read-write-directmessages":
+                        return AccessLevel.ReadWriteDirectMessage;
+                    default:
+                        break;
+                }
+                return AccessLevel.Unknown;
+            }
+            else
+                return AccessLevel.Unavailable;
+        }
+
+
+#if !LITE && !SILVERLIGHT
+        /// <summary>
         /// Adds the result to cache.
         /// </summary>
         /// <param name="cacheKeyBuilder">The cache key builder.</param>
@@ -338,13 +434,12 @@ namespace Twitterizer.Core
                     cacheKeyBuilder.ToString(),
                     resultObject,
                     null,
-                    Cache.NoAbsoluteExpiration,
-                    this.OptionalProperties.CacheTimespan,
+                    DateTime.Now.Add(this.OptionalProperties.CacheTimespan),
+                    Cache.NoSlidingExpiration,
                     CacheItemPriority.Normal,
                     null);
-
-                Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Added results to cache", this.Uri.AbsoluteUri), "Twitterizer2");
             }
         }
-    }
+#endif
+        }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Core/TwitterCursorPagedIdCollection.cs b/lib/Twitterizer/Twitterizer2/Core/TwitterCursorPagedIdCollection.cs
new file mode 100644
index 0000000..599f792
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Core/TwitterCursorPagedIdCollection.cs
@@ -0,0 +1,83 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterCursorPagedIdCollection.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The twitter cursor paged id collection class.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer
+{
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using Newtonsoft.Json;
+    using Newtonsoft.Json.Linq;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// Holds a collection of ID values that are broken into multiple pages.
+    /// </summary>
+    public class TwitterCursorPagedIdCollection : Collection<decimal>, ITwitterObject
+    {
+        /// <summary>
+        /// Annotations are additional pieces of data, supplied by Twitter clients, in a non-structured dictionary.
+        /// </summary>
+        /// <value>The annotations.</value>
+        public Dictionary<string, string> Annotations { get; set; }
+
+        /// <summary>
+        /// Gets or sets the next cursor.
+        /// </summary>
+        /// <value>The next cursor.</value>
+        public long NextCursor { get; set; }
+
+        /// <summary>
+        /// Gets or sets the previous cursor.
+        /// </summary>
+        /// <value>The previous cursor.</value>
+        public long PreviousCursor { get; set; }
+
+        /// <summary>
+        /// Deserializes the specified value.
+        /// </summary>
+        /// <param name="value">The value.</param>
+        /// <returns></returns>
+        internal static TwitterCursorPagedIdCollection DeserializeWrapper(JObject value)
+        {
+            if (value == null || value.SelectToken("ids") == null)
+                return null;
+
+            TwitterCursorPagedIdCollection result = JsonConvert.DeserializeObject<TwitterCursorPagedIdCollection>(value.SelectToken("ids").ToString());
+            result.NextCursor = value.SelectToken("next_cursor").Value<long>();
+            result.PreviousCursor = value.SelectToken("previous_cursor").Value<long>();
+
+            return result;
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Core/TwitterEmptyObject.cs b/lib/Twitterizer/Twitterizer2/Core/TwitterEmptyObject.cs
deleted file mode 100644
index 8e18d8c..0000000
--- a/lib/Twitterizer/Twitterizer2/Core/TwitterEmptyObject.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-namespace Twitterizer
-{
-    using System;
-    using Twitterizer.Core;
-
-    /// <summary>
-    /// Represents an empty object.
-    /// </summary>
-    [Serializable]
-    public class TwitterEmptyObject : ITwitterObject
-    {
-        /// <summary>
-        /// Gets or sets a value indicating whether this instance is empty.
-        /// </summary>
-        /// <value><c>true</c> if this instance is empty; otherwise, <c>false</c>.</value>
-        public bool IsEmpty { get; set; }
-
-        /// <summary>
-        /// Gets or sets information about the user's rate usage.
-        /// </summary>
-        /// <value>The rate limiting object.</value>
-        public RateLimiting RateLimiting { get; set; }
-
-        /// <summary>
-        /// Gets or sets the oauth tokens.
-        /// </summary>
-        /// <value>The oauth tokens.</value>
-        public OAuthTokens Tokens { get; set; }
-
-        /// <summary>
-        /// Gets details about the request attempted.
-        /// </summary>
-        /// <value>The last request status.</value>
-        public RequestStatus RequestStatus { get; set; }
-    }
-}
diff --git a/lib/Twitterizer/Twitterizer2/Core/TwitterIdCollection.cs b/lib/Twitterizer/Twitterizer2/Core/TwitterIdCollection.cs
new file mode 100644
index 0000000..76795bd
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Core/TwitterIdCollection.cs
@@ -0,0 +1,108 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterIdCollection.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The twitter id collection class.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer
+{
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// Holds a collection of ID values
+    /// </summary>
+    public class TwitterIdCollection : Collection<decimal>, ITwitterObject
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="T:System.Object"/> class.
+        /// </summary>
+        /// <remarks></remarks>
+        public TwitterIdCollection() { }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TwitterIdCollection"/> class.
+        /// </summary>
+        /// <param name="items">The items.</param>
+        /// <remarks></remarks>
+        public TwitterIdCollection(List<decimal> items)
+        {
+            items.ForEach((a) => { this.Add(a); });
+        }
+
+        /// <summary>
+        /// Annotations are additional pieces of data, supplied by Twitter clients, in a non-structured dictionary.
+        /// </summary>
+        /// <value>The annotations.</value>
+        public Dictionary<string, string> Annotations { get; set; }
+
+        /// <summary>
+        /// Performs an explicit conversion from <see cref="System.Collections.Generic.List<System.Decimal>"/> to <see cref="Twitterizer.TwitterIdCollection"/>.
+        /// </summary>
+        /// <param name="collection">The collection.</param>
+        /// <returns>The result of the conversion.</returns>
+        /// <remarks></remarks>
+        public static explicit operator TwitterIdCollection (List<decimal> collection)
+        {
+            TwitterIdCollection newCollection = new TwitterIdCollection();
+            foreach (var item in collection)
+            {
+                newCollection.Add(item);
+            }
+
+            return newCollection;
+        }
+    }
+
+    /// <summary>
+    /// Holds extension methods related to the <see cref="Twitterizer.TwitterIdCollection"/> class.
+    /// </summary>
+    /// <remarks></remarks>
+    public static class TwitterIdCollectionExtensions
+    {
+        /// <summary>
+        /// Converts the collection to a <see cref="Twitterizer.TwitterIdCollection"/> class.
+        /// </summary>
+        /// <param name="old">The old.</param>
+        /// <returns></returns>
+        /// <remarks></remarks>
+        public static TwitterIdCollection ToIdCollection(this IEnumerable<decimal> old)
+        {
+            TwitterIdCollection newCollection = new TwitterIdCollection();
+            foreach (var item in old)
+            {
+                newCollection.Add(item);
+            }
+            return newCollection;
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Core/TwitterImage.cs b/lib/Twitterizer/Twitterizer2/Core/TwitterImage.cs
index 499fef6..1dbad35 100644
--- a/lib/Twitterizer/Twitterizer2/Core/TwitterImage.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/TwitterImage.cs
@@ -6,7 +6,9 @@
     /// <summary>
     /// The image type that is being uploaded.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public enum TwitterImageImageType
     {
         /// <summary>
@@ -28,7 +30,9 @@
     /// <summary>
     /// Represents an image for uploading. Used to upload new profile and background images.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public class TwitterImage
     {
         /// <summary>
@@ -99,7 +103,7 @@
                     newImage.ImageType = TwitterImageImageType.PNG;
                     break;
                 default:
-                    throw new ApplicationException("File is not a recognized type. Must be jpg, png, or gif.");
+                    throw new Exception("File is not a recognized type. Must be jpg, png, or gif.");
             }
 
             return newImage;
diff --git a/lib/Twitterizer/Twitterizer2/Core/TwitterObject.cs b/lib/Twitterizer/Twitterizer2/Core/TwitterObject.cs
index aa7f3c4..4cf82fa 100644
--- a/lib/Twitterizer/Twitterizer2/Core/TwitterObject.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/TwitterObject.cs
@@ -33,26 +33,26 @@
 //-----------------------------------------------------------------------
 namespace Twitterizer.Core
 {
-    using System.Xml.Serialization;
-    using Twitterizer;
+    using System.Collections.Generic;
+    using Newtonsoft.Json;
 
+    /// <summary>
+    /// Represents the callback signature for asynchronous methods.
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    /// <param name="result">The result.</param>
+    /// <remarks></remarks>
     public delegate void TwitterAsyncCallback<T>(T result)
-            where T : TwitterObject;
+            where T : ITwitterObject;
 
     /// <summary>
     /// The base object class
     /// </summary>
+#if !SILVERLIGHT
     [System.Serializable]
+#endif
     public class TwitterObject : ITwitterObject
     {
-        public static TwitterObject Empty = new TwitterObject() { IsEmpty = true };
-
-        /// <summary>
-        /// Gets or sets a value indicating whether this instance is empty.
-        /// </summary>
-        /// <value><c>true</c> if this instance is empty; otherwise, <c>false</c>.</value>
-        public new bool IsEmpty { get; set; }
-
         /// <summary>
         /// The format that all twitter dates are in.
         /// </summary>
@@ -64,59 +64,10 @@ namespace Twitterizer.Core
         protected const string SearchDateFormat = "ddd, dd MMM yyyy HH:mm:ss +zz00";
 
         /// <summary>
-        /// Gets or sets information about the user's rate usage.
-        /// </summary>
-        /// <value>The rate limiting object.</value>
-        public RateLimiting RateLimiting { get; set; }
-
-        /// <summary>
-        /// Gets or sets the oauth tokens.
-        /// </summary>
-        /// <value>The oauth tokens.</value>
-        [XmlIgnore, SoapIgnore]
-        public OAuthTokens Tokens { get; set; }
-
-        /// <summary>
-        /// Gets details about the request attempted.
-        /// </summary>
-        /// <value>The last request status.</value>
-        [XmlIgnore, SoapIgnore]
-        public RequestStatus RequestStatus { get; set; }
-
-        /// <summary>
-        /// Implements the operator ==.
-        /// </summary>
-        /// <param name="obj1">The obj1.</param>
-        /// <param name="obj2">The obj2.</param>
-        /// <returns>The result of the operator.</returns>
-        public static bool operator ==(TwitterObject obj1, TwitterObject obj2)
-        {
-			if (object.Equals(obj1, null) || object.Equals(obj2, null))
-			{
-				return object.Equals(obj1, null) && object.Equals(obj2, null);
-			}
-
-            if (object.ReferenceEquals(obj1, obj2))
-                return true;
-
-            if (obj1.IsEmpty && object.ReferenceEquals(obj2, TwitterObject.Empty))
-                return true;
-
-            if (obj2.IsEmpty && object.ReferenceEquals(obj1, TwitterObject.Empty))
-                return true;
-
-            return false;
-        }
-
-        /// <summary>
-        /// Implements the operator !=.
+        /// Annotations are additional pieces of data, supplied by Twitter clients, in a non-structured dictionary.
         /// </summary>
-        /// <param name="obj1">The obj1.</param>
-        /// <param name="obj2">The obj2.</param>
-        /// <returns>The result of the operator.</returns>
-        public static bool operator !=(TwitterObject obj1, TwitterObject obj2)
-        {
-            return !(obj1 == obj2);
-        }
+        /// <value>The annotations.</value>
+        [JsonProperty(PropertyName = "annotations")]
+        public Dictionary<string, string> Annotations { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Core/TwitterizerDateConverter.cs b/lib/Twitterizer/Twitterizer2/Core/TwitterizerDateConverter.cs
index a521a9b..dc8a475 100644
--- a/lib/Twitterizer/Twitterizer2/Core/TwitterizerDateConverter.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/TwitterizerDateConverter.cs
@@ -40,8 +40,9 @@ namespace Twitterizer
     /// <summary>
     /// Converts date strings returned by the Twitter API into <see cref="System.DateTime"/>
     /// </summary>
-    internal class TwitterizerDateConverter : Newtonsoft.Json.Converters.DateTimeConverterBase
+    public class TwitterizerDateConverter : Newtonsoft.Json.Converters.DateTimeConverterBase
     {
+        public TwitterizerDateConverter() { }
         /// <summary>
         /// The date pattern for most dates returned by the API
         /// </summary>
@@ -80,5 +81,19 @@ namespace Twitterizer
         {
             throw new NotImplementedException();
         }
+
+//#if SILVERLIGHT
+//        /// <summary>
+//        /// Determines whether this instance can convert the specified object type.
+//        /// </summary>
+//        /// <param name="objectType">Type of the object.</param>
+//        /// <returns>
+//        /// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
+//        /// </returns>
+//        public override bool CanConvert(Type objectType)
+//        {
+//            return objectType == typeof(DateTime);
+//        }
+//#endif
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Exceptions/CommandValidationException.cs b/lib/Twitterizer/Twitterizer2/Exceptions/CommandValidationException.cs
index 3684a12..0b0e5d2 100644
--- a/lib/Twitterizer/Twitterizer2/Exceptions/CommandValidationException.cs
+++ b/lib/Twitterizer/Twitterizer2/Exceptions/CommandValidationException.cs
@@ -44,8 +44,10 @@ namespace Twitterizer
     /// An exception class indicating that required parameters were missing from a command.
     /// </summary>
     /// <typeparam name="T">The command type, derived from ITwitterObject.</typeparam>
+#if !SILVERLIGHT 
     [Serializable]
-    public class CommandValidationException<T> : Exception, ISerializable
+#endif
+    public class CommandValidationException<T> : Exception
         where T : ITwitterObject
     {
         #region Constructors
diff --git a/lib/Twitterizer/Twitterizer2/Exceptions/TwitterErrorDetails.cs b/lib/Twitterizer/Twitterizer2/Exceptions/TwitterErrorDetails.cs
index 79fa02b..7ae90de 100644
--- a/lib/Twitterizer/Twitterizer2/Exceptions/TwitterErrorDetails.cs
+++ b/lib/Twitterizer/Twitterizer2/Exceptions/TwitterErrorDetails.cs
@@ -46,9 +46,11 @@ namespace Twitterizer
     /// <remarks>Often, twitter returns error details in the body of response. This class represents the data structure of the error for deserialization.</remarks>
     [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
     [XmlRoot("hash")]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     [DebuggerDisplay("@{ErrorMessage}")]
-    public class TwitterErrorDetails : ITwitterObject
+    public class TwitterErrorDetails : TwitterObject
     {
         /// <summary>
         /// Gets or sets the request path.
@@ -65,61 +67,5 @@ namespace Twitterizer
         [JsonProperty(PropertyName = "error")]
         [XmlElement("error")]
         public string ErrorMessage { get; set; }
-
-        #region ITwitterObject Members
-
-        /// <summary>
-        /// Gets or sets information about the user's rate usage.
-        /// </summary>
-        /// <value>The rate limiting object.</value>
-        public RateLimiting RateLimiting
-        {
-            get
-            {
-                throw new System.NotImplementedException();
-            }
-
-            set
-            {
-                throw new System.NotImplementedException();
-            }
-        }
-
-        /// <summary>
-        /// Gets or sets the oauth tokens.
-        /// </summary>
-        /// <value>The oauth tokens.</value>
-        public OAuthTokens Tokens
-        {
-            get
-            {
-                throw new System.NotImplementedException();
-            }
-
-            set
-            {
-                throw new System.NotImplementedException();
-            }
-        }
-
-        RequestStatus ITwitterObject.RequestStatus
-        {
-            get
-            {
-                throw new System.NotImplementedException();
-            }
-            set
-            {
-                throw new System.NotImplementedException();
-            }
-        }
-
-        #endregion
-
-        /// <summary>
-        /// Gets or sets a value indicating whether this instance is empty.
-        /// </summary>
-        /// <value><c>true</c> if this instance is empty; otherwise, <c>false</c>.</value>
-        public new bool IsEmpty { get { return false; } set { } }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Exceptions/TwitterizerException.cs b/lib/Twitterizer/Twitterizer2/Exceptions/TwitterizerException.cs
index 1db2485..3b4518b 100644
--- a/lib/Twitterizer/Twitterizer2/Exceptions/TwitterizerException.cs
+++ b/lib/Twitterizer/Twitterizer2/Exceptions/TwitterizerException.cs
@@ -35,18 +35,19 @@ namespace Twitterizer
     using System;
     using System.Globalization;
     using System.IO;
+    using System.Linq;
     using System.Net;
-    using System.Runtime.Serialization;
-    using System.Security.Permissions;
     using System.Text;
-    using Twitterizer.Core;
+    using Core;
 
     /// <summary>
     /// The Twitterizer Exception
     /// </summary>
     /// <seealso cref="System.Net.WebException"/>
+#if !SILVERLIGHT
     [Serializable]
-    public class TwitterizerException : WebException, ISerializable
+#endif
+    public class TwitterizerException : WebException
     {
         #region Constructors
         /// <summary>
@@ -86,19 +87,15 @@ namespace Twitterizer
 
                 byte[] responseData = ConversionUtility.ReadStream(responseStream);
 
-                this.ResponseBody = Encoding.UTF8.GetString(responseData);
+                this.ResponseBody = Encoding.UTF8.GetString(responseData, 0, responseData.Length);
 
-#if DEBUG
-                System.Diagnostics.Debug.WriteLine("----------- RESPONSE -----------");
-                System.Diagnostics.Debug.Write(this.ResponseBody);
-                System.Diagnostics.Debug.WriteLine("----------- END -----------");
-#endif
                 this.ParseRateLimitHeaders(response);
 
                 if (response.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
                 {
                     this.ErrorDetails = SerializationHelper<TwitterErrorDetails>.Deserialize(responseData, null);
                 }
+#if !SILVERLIGHT
                 else if (response.ContentType.StartsWith("text/xml", StringComparison.OrdinalIgnoreCase))
                 {
                     // Try to deserialize as XML (specifically OAuth requests)
@@ -107,20 +104,9 @@ namespace Twitterizer
 
                     this.ErrorDetails = ds.Deserialize(new MemoryStream(responseData)) as TwitterErrorDetails;
                 }
+#endif
             }
         }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="TwitterizerException"/> class.
-        /// </summary>
-        /// <param name="info">The object that holds the serialized object data.</param>
-        /// <param name="context">The contextual information about the source or destination.</param>
-        protected TwitterizerException(
-            SerializationInfo info,
-            StreamingContext context)
-            : base(info, context)
-        {
-        }
         #endregion
 
         /// <summary>
@@ -156,10 +142,7 @@ namespace Twitterizer
         {
             get
             {
-                if (this.InnerException == null)
-                    return null;
-
-                return ((WebException)this.InnerException).Response;
+                return InnerException == null ? null : ((WebException)this.InnerException).Response;
             }
         }
 
@@ -193,36 +176,13 @@ namespace Twitterizer
                     reportBuilder.AppendFormat(
                         "{0} = \"{1}\"",
                         this.Response.Headers.AllKeys[i],
-                        this.Response.Headers[i]);
+                        this.Response.Headers[this.Response.Headers.AllKeys[i]]);
                 }
 
                 return reportBuilder.ToString();
             }
         }
 
-        #region ISerializable Members
-        /// <summary>
-        /// When overridden in a derived class, sets the <see cref="T:System.Runtime.Serialization.SerializationInfo"/> with information about the exception.
-        /// </summary>
-        /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
-        /// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
-        /// <exception cref="T:System.ArgumentNullException">
-        /// The <paramref name="info"/> parameter is a null reference (Nothing in Visual Basic).
-        /// </exception>
-        /// <PermissionSet>
-        /// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Read="*AllFiles*" PathDiscovery="*AllFiles*"/>
-        /// <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="SerializationFormatter"/>
-        /// </PermissionSet>
-        //[SecurityPermissionAttribute(SecurityAction.LinkDemand, SerializationFormatter = true)]
-        public override void GetObjectData(SerializationInfo info, StreamingContext context)
-        {
-            if (info == null)
-                throw new ArgumentNullException("info");
-
-            base.GetObjectData(info, context);
-        }
-        #endregion
-
         /// <summary>
         /// Parses the rate limit headers.
         /// </summary>
@@ -231,20 +191,20 @@ namespace Twitterizer
         {
             this.RateLimiting = new RateLimiting();
 
-            if (!string.IsNullOrEmpty(response.Headers.Get("X-RateLimit-Limit")))
+            if (response.Headers.AllKeys.Contains("X-RateLimit-Limit") && !string.IsNullOrEmpty(response.Headers["X-RateLimit-Limit"]))
             {
-                this.RateLimiting.Total = int.Parse(response.Headers.Get("X-RateLimit-Limit"), CultureInfo.InvariantCulture);
+                this.RateLimiting.Total = int.Parse(response.Headers["X-RateLimit-Limit"], CultureInfo.InvariantCulture);
             }
 
-            if (!string.IsNullOrEmpty(response.Headers.Get("X-RateLimit-Remaining")))
+            if (response.Headers.AllKeys.Contains("X-RateLimit-Remaining") && !string.IsNullOrEmpty(response.Headers["X-RateLimit-Remaining"]))
             {
-                this.RateLimiting.Remaining = int.Parse(response.Headers.Get("X-RateLimit-Remaining"), CultureInfo.InvariantCulture);
+                this.RateLimiting.Remaining = int.Parse(response.Headers["X-RateLimit-Remaining"], CultureInfo.InvariantCulture);
             }
 
-            if (!string.IsNullOrEmpty(response.Headers["X-RateLimit-Reset"]))
+            if (!string.IsNullOrEmpty(response.Headers["X-RateLimit-Reset"]) && !string.IsNullOrEmpty(response.Headers["X-RateLimit-Reset"]))
             {
-                this.RateLimiting.ResetDate = (new DateTime(1970, 1, 1, 0, 0, 0, 0))
-                    .AddSeconds(double.Parse(response.Headers.Get("X-RateLimit-Reset"), CultureInfo.InvariantCulture));
+                this.RateLimiting.ResetDate = DateTime.SpecifyKind(new DateTime(1970, 1, 1, 0, 0, 0, 0)
+                    .AddSeconds(double.Parse(response.Headers["X-RateLimit-Reset"], CultureInfo.InvariantCulture)), DateTimeKind.Utc);
             }
         }
     }
diff --git a/lib/Twitterizer/Twitterizer2/Information.cs b/lib/Twitterizer/Twitterizer2/Information.cs
index f1a69cf..fc4dff9 100644
--- a/lib/Twitterizer/Twitterizer2/Information.cs
+++ b/lib/Twitterizer/Twitterizer2/Information.cs
@@ -45,7 +45,11 @@ namespace Twitterizer
         /// <returns>The assembly version string in the format (#.#.#.#)</returns>
         public static string AssemblyVersion()
         {
-            return System.Reflection.Assembly.GetAssembly(typeof(Information)).GetName().Version.ToString();
+#if !SILVERLIGHT
+            return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
+#else
+            return System.Reflection.Assembly.GetExecutingAssembly().FullName.Split(',')[1].Split('=')[1].ToString();
+#endif
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/RateLimitStatusCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/RateLimitStatusCommand.cs
index 3bfb979..ccdd82e 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Account/RateLimitStatusCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/RateLimitStatusCommand.cs
@@ -39,7 +39,9 @@ namespace Twitterizer.Commands
     /// <summary>
     /// The rate limit status command class.
     /// </summary>
-    [Serializable]
+#if !SILVERLIGHT
+    [System.Serializable]
+#endif
     internal sealed class RateLimitStatusCommand : TwitterCommand<TwitterRateLimitStatus>
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/TwitterAccount.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/TwitterAccount.cs
new file mode 100644
index 0000000..cea444d
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/TwitterAccount.cs
@@ -0,0 +1,155 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterAccount.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The TwitterAccount class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer
+{
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// Provides methods to request and modify details of an authorized user's account details.
+    /// </summary>
+    public static class TwitterAccount
+    {
+        /// <summary>
+        /// Verifies the user's credentials.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterUser> VerifyCredentials(OAuthTokens tokens, VerifyCredentialsOptions options)
+        {
+            Commands.VerifyCredentialsCommand command = new Commands.VerifyCredentialsCommand(tokens, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Verifies the user's credentials.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterUser> VerifyCredentials(OAuthTokens tokens)
+        {
+            return VerifyCredentials(tokens, null);
+        }
+
+        /// <summary>
+        /// Sets one or more hex values that control the color scheme of the authenticating user's profile page on twitter.com
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// The user, with updated data, as a <see cref="TwitterUser"/>
+        /// </returns>
+        public static TwitterResponse<TwitterUser> UpdateProfileColors(OAuthTokens tokens, UpdateProfileColorsOptions options)
+        {
+            Commands.UpdateProfileColorsCommand command = new Twitterizer.Commands.UpdateProfileColorsCommand(tokens, options);
+
+            return CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Updates the authenticating user's profile image.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="imageData">The image data.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// The user, with updated data, as a <see cref="TwitterUser"/>
+        /// </returns>
+        public static TwitterResponse<TwitterUser> UpdateProfileImage(OAuthTokens tokens, byte[] imageData, OptionalProperties options = null)
+        {
+            Commands.UpdateProfileImageCommand command = new Twitterizer.Commands.UpdateProfileImageCommand(tokens, imageData, options);
+
+            return CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Updates the authenticating user's profile image.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="imageLocation">The image location.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// The user, with updated data, as a <see cref="TwitterUser"/>
+        /// </returns>
+        public static TwitterResponse<TwitterUser> UpdateProfileImage(OAuthTokens tokens, string imageLocation, OptionalProperties options = null)
+        {
+            return UpdateProfileImage(tokens, System.IO.File.ReadAllBytes(imageLocation), options);
+        }
+
+        /// <summary>
+        /// Updates the authenticating user's profile background image. This method can also be used to enable or disable the profile background image.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="imageData">The image data.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterUser> UpdateProfileBackgroundImage(OAuthTokens tokens, byte[] imageData = null, UpdateProfileBackgroundImageOptions options = null)
+        {
+            if (imageData == null && options == null)
+            {
+                throw new System.ArgumentNullException("imageData", "You must provide image data or indicate you wish to not use any image in the options argument.");
+            }
+
+            Commands.UpdateProfileBackgroundImageCommand command = new Twitterizer.Commands.UpdateProfileBackgroundImageCommand(tokens, imageData, options);
+
+            return CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Updates the authenticating user's profile background image. This method can also be used to enable or disable the profile background image.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="imageLocation">The image location.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterUser> UpdateProfileBackgroundImage(OAuthTokens tokens, string imageLocation, UpdateProfileBackgroundImageOptions options = null)
+        {
+            return UpdateProfileBackgroundImage(tokens, System.IO.File.ReadAllBytes(imageLocation), options);
+        }
+
+        /// <summary>
+        /// Sets values that users are able to set under the "Account" tab of their settings page. Only the parameters specified will be updated.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        /// <remarks></remarks>
+        public static TwitterResponse<TwitterUser> UpdateProfile(OAuthTokens tokens, UpdateProfileOptions options)
+        {
+            Commands.UpdateProfileCommand command = new Commands.UpdateProfileCommand(tokens, options);
+            return Core.CommandPerformer.PerformAction(command);
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/TwitterRateLimitStatus.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/TwitterRateLimitStatus.cs
index a99e2d8..cfd21b3 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Account/TwitterRateLimitStatus.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/TwitterRateLimitStatus.cs
@@ -40,29 +40,12 @@ namespace Twitterizer
     /// <summary>
     /// The Twitter Rate Limit Status class
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
     public class TwitterRateLimitStatus : TwitterObject
     {
-        #region Constructors
-        /// <summary>
-        /// Initializes a new instance of the <see cref="TwitterRateLimitStatus"/> class.
-        /// </summary>
-        public TwitterRateLimitStatus()
-        {
-        }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="TwitterRateLimitStatus"/> class.
-        /// </summary>
-        /// <param name="tokens">OAuth access tokens.</param>
-        protected TwitterRateLimitStatus(OAuthTokens tokens)
-            : base()
-        {
-            this.Tokens = tokens;
-        }
-        #endregion
-
         #region API Properties
         /// <summary>
         /// Gets or sets the remaining hits.
@@ -88,26 +71,6 @@ namespace Twitterizer
         #endregion
 
         /// <summary>
-        /// Gets the rate limiting status status for the authenticated user asynchronously.
-        /// </summary>
-        /// <param name="tokens">The OAuth tokens.</param>
-        /// <param name="options">The options.</param>
-        /// <param name="function">The callback or anonymous funtion.</param>
-        /// <returns>
-        /// A <see cref="TwitterRateLimitStatus"/> instance.
-        /// </returns>
-        public static void GetStatus(OAuthTokens tokens, OptionalProperties options, Action<TwitterRateLimitStatus> function)
-        {
-            Func<OAuthTokens, OptionalProperties, TwitterRateLimitStatus> methodToCall = GetStatus;
-            
-            methodToCall.BeginInvoke(
-                tokens,
-                options,
-                result => function(methodToCall.EndInvoke(result)),
-                null);
-        }
-
-        /// <summary>
         /// Gets the rate limiting status status for the authenticated user.
         /// </summary>
         /// <param name="tokens">The OAuth tokens.</param>
@@ -115,10 +78,10 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterRateLimitStatus"/> instance.
         /// </returns>
-        public static TwitterRateLimitStatus GetStatus(OAuthTokens tokens, OptionalProperties options)
+        public static TwitterResponse<TwitterRateLimitStatus> GetStatus(OAuthTokens tokens, OptionalProperties options)
         {
             Commands.RateLimitStatusCommand command = new Twitterizer.Commands.RateLimitStatusCommand(tokens, options);
-            TwitterRateLimitStatus result = Core.CommandPerformer<TwitterRateLimitStatus>.PerformAction(command);
+            TwitterResponse<TwitterRateLimitStatus> result = Core.CommandPerformer.PerformAction(command);
 
             return result;
         }
@@ -130,7 +93,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterRateLimitStatus"/> instance.
         /// </returns>
-        public static TwitterRateLimitStatus GetStatus(OAuthTokens tokens)
+        public static TwitterResponse<TwitterRateLimitStatus> GetStatus(OAuthTokens tokens)
         {
             return GetStatus(tokens, null);
         }
@@ -141,7 +104,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterRateLimitStatus"/> instance.
         /// </returns>
-        public static TwitterRateLimitStatus GetStatus()
+        public static TwitterResponse<TwitterRateLimitStatus> GetStatus()
         {
             return GetStatus(null, null);
         }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileBackgroundImageCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileBackgroundImageCommand.cs
new file mode 100644
index 0000000..6ca5dc7
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileBackgroundImageCommand.cs
@@ -0,0 +1,96 @@
+//-----------------------------------------------------------------------
+// <copyright file="UpdateProfileBackgroundImageCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The update profile background image command class.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer.Commands
+{
+    using System;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// 
+    /// </summary>
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    internal sealed class UpdateProfileBackgroundImageCommand : TwitterCommand<TwitterUser>
+    {
+        private byte[] imageData;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="UpdateProfileBackgroundImageCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="image">The image.</param>
+        /// <param name="options">The options.</param>
+        public UpdateProfileBackgroundImageCommand(OAuthTokens tokens, byte[] image, UpdateProfileBackgroundImageOptions options)
+            : base(HTTPVerb.POST, "", tokens, options)
+        {
+            if (tokens == null)
+            {
+                throw new ArgumentNullException("tokens");
+            }
+
+            if ((options == null && (image == null || image.Length == 0)) || (options != null && !options.UseImage))
+            {
+                throw new ArgumentException("Image data cannot be null or zero length.");
+            }
+
+            if (image != null && image.Length > 102400)
+            {
+                throw new ArgumentException("Image cannot exceed 800Kb in size.");
+            }
+
+            this.imageData = image;
+            this.Multipart = true;
+        }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+            this.RequestParameters.Add("image", this.imageData);
+            this.RequestParameters.Add("include_entities", "true");
+
+            UpdateProfileBackgroundImageOptions options = this.OptionalProperties as UpdateProfileBackgroundImageOptions;
+            if (options == null)
+                return;
+
+            this.RequestParameters.Add("use", options.UseImage ? "1" : "0");
+
+            if (options.Tiled.HasValue)
+                this.RequestParameters.Add("tiled", options.Tiled.Value ? "1" : "0");
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileBackgroundImageOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileBackgroundImageOptions.cs
new file mode 100644
index 0000000..6c58920
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileBackgroundImageOptions.cs
@@ -0,0 +1,64 @@
+//-----------------------------------------------------------------------
+// <copyright file="UpdateProfileBackgroundImageCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The update profile background image command class.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer
+{
+    using System;
+
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    public sealed class UpdateProfileBackgroundImageOptions : OptionalProperties
+    {
+        /// <summary>
+        /// Gets or sets a value indicating whether or not to tile the background image.
+        /// </summary>
+        /// <value><c>true</c> if tiled; otherwise, <c>false</c>.</value>
+        public bool? Tiled { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether to display the profile background image or not.
+        /// </summary>
+        /// <value><c>true</c> to use an image; otherwise, <c>false</c>.</value>
+        public bool UseImage { get; set; }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="UpdateProfileBackgroundImageOptions"/> class.
+        /// </summary>
+        public UpdateProfileBackgroundImageOptions()
+        {
+            this.UseImage = true;
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileColorsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileColorsCommand.cs
index b7f2f80..e9cf653 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileColorsCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileColorsCommand.cs
@@ -35,14 +35,18 @@
 namespace Twitterizer.Commands
 {
     using System;
+#if !SILVERLIGHT
     using System.Drawing;
+#endif
     using Twitterizer.Core;
 
     /// <summary>
     /// Sets one or more hex values that control the color scheme of the authenticating user's profile page on twitter.com
     /// </summary>
     [AuthorizedCommand]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal class UpdateProfileColorsCommand : TwitterCommand<TwitterUser>
     {
         /// <summary>
@@ -73,27 +77,47 @@ namespace Twitterizer.Commands
 
             if (options.BackgroundColor != null)
             {
+#if !SILVERLIGHT
                 this.RequestParameters.Add("profile_background_color", ColorTranslator.ToHtml(options.BackgroundColor));
+#else
+                this.RequestParameters.Add("profile_background_color", options.BackgroundColor);
+#endif
             }
 
             if (options.TextColor != null)
             {
+#if !SILVERLIGHT
                 this.RequestParameters.Add("profile_text_color", ColorTranslator.ToHtml(options.TextColor));
+#else
+                this.RequestParameters.Add("profile_text_color", options.TextColor);
+#endif
             }
 
             if (options.LinkColor != null)
             {
+#if !SILVERLIGHT
                 this.RequestParameters.Add("profile_link_color", ColorTranslator.ToHtml(options.LinkColor));
+#else
+                this.RequestParameters.Add("profile_link_color", options.LinkColor);
+#endif
             }
 
             if (options.SidebarFillColor != null)
             {
+#if !SILVERLIGHT
                 this.RequestParameters.Add("profile_sidebar_fill_color", ColorTranslator.ToHtml(options.SidebarFillColor));
+#else
+                this.RequestParameters.Add("profile_sidebar_fill_color", options.SidebarFillColor);
+#endif
             }
 
             if (options.SidebarBorderColor != null)
             {
+#if !SILVERLIGHT
                 this.RequestParameters.Add("profile_sidebar_border_color", ColorTranslator.ToHtml(options.SidebarBorderColor));
+#else
+                this.RequestParameters.Add("profile_sidebar_border_color", options.SidebarBorderColor);
+#endif
             }
         }
     }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileColorsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileColorsOptions.cs
index b75be16..9a6257a 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileColorsOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileColorsOptions.cs
@@ -1,12 +1,49 @@
-namespace Twitterizer
+//-----------------------------------------------------------------------
+// <copyright file="UpdateProfileColorsOptions.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The update profile colors options class.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer
 {
+#if !SILVERLIGHT
     using System.Drawing;
+#endif
 
     /// <summary>
-    /// Optional properties for the <see cref="TwitterUser.UpdateProfileColors"/> method.
+    /// Optional properties for the <see cref="Twitterizer.TwitterUser.UpdateProfileColors"/> method.
     /// </summary>
     public class UpdateProfileColorsOptions : OptionalProperties
     {
+#if !SILVERLIGHT
         /// <summary>
         /// Gets or sets the color of the background.
         /// </summary>
@@ -36,5 +73,36 @@
         /// </summary>
         /// <value>The color of the sidebar border.</value>
         public Color SidebarBorderColor { get; set; }
+#else
+                /// <summary>
+        /// Gets or sets the color of the background.
+        /// </summary>
+        /// <value>The color of the background.</value>
+        public string BackgroundColor { get; set; }
+
+        /// <summary>
+        /// Gets or sets the color of the text.
+        /// </summary>
+        /// <value>The color of the text.</value>
+        public string TextColor { get; set; }
+
+        /// <summary>
+        /// Gets or sets the color of the link.
+        /// </summary>
+        /// <value>The color of the link.</value>
+        public string LinkColor { get; set; }
+
+        /// <summary>
+        /// Gets or sets the color of the sidebar fill.
+        /// </summary>
+        /// <value>The color of the sidebar fill.</value>
+        public string SidebarFillColor { get; set; }
+
+        /// <summary>
+        /// Gets or sets the color of the sidebar border.
+        /// </summary>
+        /// <value>The color of the sidebar border.</value>
+        public string SidebarBorderColor { get; set; }
+#endif
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileCommand.cs
new file mode 100644
index 0000000..7b54c07
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileCommand.cs
@@ -0,0 +1,73 @@
+//-----------------------------------------------------------------------
+// <copyright file="UpdateProfileCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The update profile command class</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer.Commands
+{
+    using System;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The update profile command class.
+    /// </summary>
+    sealed class UpdateProfileCommand : TwitterCommand<TwitterUser>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="UpdateProfileCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        public UpdateProfileCommand(OAuthTokens tokens, UpdateProfileOptions options)
+            : base(HTTPVerb.POST, "account/update_profile.json", tokens, options)
+        {
+        }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+            this.RequestParameters.Add("include_entities", "true");
+
+            UpdateProfileOptions options = this.OptionalProperties as UpdateProfileOptions;
+            if (options == null)
+            {
+                return;
+            }
+
+            this.RequestParameters.Add("name", options.Name);
+            this.RequestParameters.Add("description", options.Description);
+            this.RequestParameters.Add("location", options.Location);
+            this.RequestParameters.Add("url", options.Url);
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileImageCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileImageCommand.cs
index b74a6ca..9ae17fd 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileImageCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileImageCommand.cs
@@ -37,16 +37,20 @@ namespace Twitterizer.Commands
     using System;
     using Twitterizer.Core;
 
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal class UpdateProfileImageCommand : TwitterCommand<TwitterUser>
     {
+        private byte[] imageData;
+
         /// <summary>
         /// Initializes a new instance of the <see cref="UpdateProfileImageCommand"/> class.
         /// </summary>
         /// <param name="tokens">The tokens.</param>
         /// <param name="image">The image.</param>
         /// <param name="options">The options.</param>
-        public UpdateProfileImageCommand(OAuthTokens tokens, TwitterImage image, OptionalProperties options)
+        public UpdateProfileImageCommand(OAuthTokens tokens, byte[] image, OptionalProperties options)
             : base(HTTPVerb.POST, "account/update_profile_image.json", tokens, options)
         {
             if (tokens == null)
@@ -54,22 +58,18 @@ namespace Twitterizer.Commands
                 throw new ArgumentNullException("tokens");
             }
 
-            if (image == null)
-            {
-                throw new ArgumentNullException("image");
-            }
-
-            if (image.Data == null || image.Data.Length == 0)
+            if (image == null || image.Length == 0)
             {
                 throw new ArithmeticException("Image data cannot be null or zero length.");
             }
 
-            if (image.Data.Length > 89600)
+            if (image.Length > 89600)
             {
                 throw new ArithmeticException("Image cannot exceed 700Kb in size.");
             }
 
-            this.ImageToUpload = image;
+            this.imageData = image;
+            this.Multipart = true;
         }
 
         /// <summary>
@@ -77,6 +77,8 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
+            this.RequestParameters.Add("image", this.imageData);
+            this.RequestParameters.Add("include_entities", "true");
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileOptions.cs
new file mode 100644
index 0000000..3853235
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileOptions.cs
@@ -0,0 +1,70 @@
+//-----------------------------------------------------------------------
+// <copyright file="UpdateProfileOptions.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The update profile options class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Text;
+
+    /// <summary>
+    /// Optional properties for the <see cref="Twitterizer.Commands.UpdateProfileCommand"/> class.
+    /// </summary>
+    public class UpdateProfileOptions : OptionalProperties
+    {
+        /// <summary>
+        /// Gets or sets the name.
+        /// </summary>
+        /// <value>The name.</value>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// Gets or sets the URL.
+        /// </summary>
+        /// <value>The URL.</value>
+        public string Url { get; set; }
+
+        /// <summary>
+        /// Gets or sets the location.
+        /// </summary>
+        /// <value>The location.</value>
+        public string Location { get; set; }
+
+        /// <summary>
+        /// Gets or sets the description.
+        /// </summary>
+        /// <value>The description.</value>
+        public string Description { get; set; }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/VerifyCredentialsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/VerifyCredentialsCommand.cs
new file mode 100644
index 0000000..63d6086
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/VerifyCredentialsCommand.cs
@@ -0,0 +1,73 @@
+//-----------------------------------------------------------------------
+// <copyright file="VerifyCredentialsCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>David Golden</author>
+// <summary>The verify credentials optional parameters class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer.Commands
+{
+    using System;
+    using Core;
+
+    /// <summary>
+    /// The verify credentials command class.
+    /// </summary>
+    [AuthorizedCommand]
+#if !SILVERLIGHT
+    [System.Serializable]
+#endif
+    internal class VerifyCredentialsCommand : TwitterCommand<TwitterUser>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="RateLimitStatusCommand"/> class.
+        /// </summary>
+        /// <param name="requestTokens">The request tokens.</param>
+        /// <param name="options">The options.</param>
+        public VerifyCredentialsCommand(OAuthTokens requestTokens, VerifyCredentialsOptions options)
+            : base(HTTPVerb.GET, "account/verify_credentials.json", requestTokens, options)
+        {
+        }
+        
+        /// <summary>
+        /// Initializes the command.
+        /// </summary>
+        public override void Init()
+        {
+            VerifyCredentialsOptions options = this.OptionalProperties as VerifyCredentialsOptions;
+
+            if (options == null) return;
+
+            if (options.IncludeEntities == true)
+            {
+                this.RequestParameters.Add("include_entities", "true");
+            }
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/VerifyCredentialsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/VerifyCredentialsOptions.cs
new file mode 100644
index 0000000..d4fdbfe
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/VerifyCredentialsOptions.cs
@@ -0,0 +1,60 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterUser.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>David Golden</author>
+// <summary>The verify credentials command class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer
+{
+    using System;
+
+    /// <summary>
+    /// The Verify Credentials Options class. Provides a payload for optional parameters for the Verify Credentials Command.
+    /// </summary>
+#if !SILVERLIGHT
+    [System.Serializable]
+#endif
+    public class VerifyCredentialsOptions : OptionalProperties
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="VerifyCredentialsOptions"/> class.
+        /// </summary>
+        public VerifyCredentialsOptions()
+        {
+            this.IncludeEntities = false;
+        }
+        
+        /// <summary>
+        /// Gets or sets a value indicating whether [include entities].
+        /// </summary>
+        /// <value><c>true</c> if [include entities]; otherwise, <c>false</c>.</value>
+        public bool IncludeEntities { get; set; }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Block/BlockingCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Block/BlockingCommand.cs
new file mode 100644
index 0000000..729ea95
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Block/BlockingCommand.cs
@@ -0,0 +1,74 @@
+//-----------------------------------------------------------------------
+// <copyright file="BlockingCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The blocking command class</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer.Commands
+{
+    using System.Globalization;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The blocking command class.
+    /// </summary>
+    [AuthorizedCommand]
+    sealed class BlockingCommand : TwitterCommand<TwitterUserCollection>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="BlockingCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        public BlockingCommand(OAuthTokens tokens, BlockingOptions options) :
+            base(HTTPVerb.GET, "blocks/blocking.json", tokens, options)
+        {
+        }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+            this.RequestParameters.Add("include_entities", "true");
+
+            BlockingOptions options = this.OptionalProperties as BlockingOptions;
+            if (options == null || options.Page <= 0)
+            {
+                this.RequestParameters.Add("page", "1");
+            }
+            else
+            {
+                this.RequestParameters.Add("page", options.Page.ToString(CultureInfo.CurrentCulture));
+            }
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Block/BlockingIdsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Block/BlockingIdsCommand.cs
new file mode 100644
index 0000000..1df8861
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Block/BlockingIdsCommand.cs
@@ -0,0 +1,61 @@
+//-----------------------------------------------------------------------
+// <copyright file="BlockingIdsCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The blocking ids command class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer.Commands
+{
+    using System;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The blocking ids command class
+    /// </summary>
+    class BlockingIdsCommand : TwitterCommand<TwitterIdCollection>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="BlockingIdsCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        public BlockingIdsCommand(OAuthTokens tokens, OptionalProperties options)
+            : base(HTTPVerb.GET, "blocks/blocking/ids.json", tokens, options)
+        { 
+        }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Block/BlockingOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Block/BlockingOptions.cs
new file mode 100644
index 0000000..90ddfcc
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Block/BlockingOptions.cs
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------
+// <copyright file="BlockingOptions.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The blocking options class</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer
+{
+    /// <summary>
+    /// The optional parameters for the <see cref="Twitterizer.Commands.BlockingCommand"/> class.
+    /// </summary>
+    public class BlockingOptions : OptionalProperties
+    {
+        /// <summary>
+        /// Gets or sets the page.
+        /// </summary>
+        /// <value>The page.</value>
+        public int Page { get; set; }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Block/CreateBlockCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Block/CreateBlockCommand.cs
new file mode 100644
index 0000000..55f23dd
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Block/CreateBlockCommand.cs
@@ -0,0 +1,96 @@
+//-----------------------------------------------------------------------
+// <copyright file="CreateBlockCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The create block command class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer.Commands
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Text;
+    using Twitterizer.Core;
+    using System.Globalization;
+
+    /// <summary>
+    /// The create block command class.
+    /// </summary>
+    /// <remarks>http://dev.twitter.com/doc/post/blocks/create</remarks>
+    internal class CreateBlockCommand : TwitterCommand<TwitterUser>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CreateBlockCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenName">Name of the screen.</param>
+        /// <param name="userId">The user id.</param>
+        /// <param name="options">The options.</param>
+        public CreateBlockCommand(OAuthTokens tokens, string screenName, decimal userId, OptionalProperties options)
+            : base(HTTPVerb.POST, "blocks/create.json", tokens, options)
+        {
+            if (string.IsNullOrEmpty(screenName) && userId <= 0)
+            {
+                throw new ArgumentException("A screen name or user id is required.");
+            }
+            this.ScreenName = screenName;
+            this.UserId = userId;
+        }
+
+        /// <summary>
+        /// Gets or sets the name of the screen.
+        /// </summary>
+        /// <value>The name of the screen.</value>
+        public string ScreenName { get; set; }
+
+        /// <summary>
+        /// Gets or sets the user id.
+        /// </summary>
+        /// <value>The user id.</value>
+        public decimal UserId { get; set; }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+            if (this.UserId > 0)
+            {
+                this.RequestParameters.Add("user_id", this.UserId.ToString(CultureInfo.InvariantCulture));
+            }
+            else if (!string.IsNullOrEmpty(this.ScreenName))
+            {
+                this.RequestParameters.Add("screen_name", this.ScreenName);
+            }
+
+            this.RequestParameters.Add("include_entities", "true");
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Block/DestroyBlockCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Block/DestroyBlockCommand.cs
new file mode 100644
index 0000000..fafd5fc
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Block/DestroyBlockCommand.cs
@@ -0,0 +1,96 @@
+//-----------------------------------------------------------------------
+// <copyright file="DestroyBlockCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>David Golden</author>
+// <summary>The destroy block command class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer.Commands
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Text;
+    using Twitterizer.Core;
+    using System.Globalization;
+
+    /// <summary>
+    /// The destroy block command class.
+    /// </summary>
+    /// <remarks>http://dev.twitter.com/doc/post/blocks/destroy</remarks>
+    internal class DestroyBlockCommand : TwitterCommand<TwitterUser>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DestroyBlockCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenName">Name of the screen.</param>
+        /// <param name="userId">The user id.</param>
+        /// <param name="options">The options.</param>
+        public DestroyBlockCommand(OAuthTokens tokens, string screenName, decimal userId, OptionalProperties options)
+            : base(HTTPVerb.POST, "blocks/destroy.json", tokens, options)
+        {
+            if (string.IsNullOrEmpty(screenName) && userId <= 0)
+            {
+                throw new ArgumentException("A screen name or user id is required.");
+            }
+            this.ScreenName = screenName;
+            this.UserId = userId;
+        }
+
+        /// <summary>
+        /// Gets or sets the name of the screen.
+        /// </summary>
+        /// <value>The name of the screen.</value>
+        public string ScreenName { get; set; }
+
+        /// <summary>
+        /// Gets or sets the user id.
+        /// </summary>
+        /// <value>The user id.</value>
+        public decimal UserId { get; set; }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+            if (this.UserId > 0)
+            {
+                this.RequestParameters.Add("user_id", this.UserId.ToString(CultureInfo.InvariantCulture));
+            }
+            else if (!string.IsNullOrEmpty(this.ScreenName))
+            {
+                this.RequestParameters.Add("screen_name", this.ScreenName);
+            }
+
+            this.RequestParameters.Add("include_entities", "true");
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Block/ExistsBlockCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Block/ExistsBlockCommand.cs
new file mode 100644
index 0000000..ccdaa94
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Block/ExistsBlockCommand.cs
@@ -0,0 +1,96 @@
+//-----------------------------------------------------------------------
+// <copyright file="ExistsBlockCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>David Golden</author>
+// <summary>The exists block command class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer.Commands
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Text;
+    using Twitterizer.Core;
+    using System.Globalization;
+
+    /// <summary>
+    /// The exists block command class.
+    /// </summary>
+    /// <remarks>http://dev.twitter.com/doc/post/blocks/exists</remarks>
+    internal class ExistsBlockCommand : TwitterCommand<TwitterUser>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ExistsBlockCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenName">Name of the screen.</param>
+        /// <param name="userId">The user id.</param>
+        /// <param name="options">The options.</param>
+        public ExistsBlockCommand(OAuthTokens tokens, string screenName, decimal userId, OptionalProperties options)
+            : base(HTTPVerb.GET, "blocks/exists.json", tokens, options)
+        {
+            if (string.IsNullOrEmpty(screenName) && userId <= 0)
+            {
+                throw new ArgumentException("A screen name or user id is required.");
+            }
+            this.ScreenName = screenName;
+            this.UserId = userId;
+        }
+
+        /// <summary>
+        /// Gets or sets the name of the screen.
+        /// </summary>
+        /// <value>The name of the screen.</value>
+        public string ScreenName { get; set; }
+
+        /// <summary>
+        /// Gets or sets the user id.
+        /// </summary>
+        /// <value>The user id.</value>
+        public decimal UserId { get; set; }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+            if (this.UserId > 0)
+            {
+                this.RequestParameters.Add("user_id", this.UserId.ToString(CultureInfo.InvariantCulture));
+            }
+            else if (!string.IsNullOrEmpty(this.ScreenName))
+            {
+                this.RequestParameters.Add("screen_name", this.ScreenName);
+            }
+
+            this.RequestParameters.Add("include_entities", "true");
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Block/TwitterBlock.cs b/lib/Twitterizer/Twitterizer2/Methods/Block/TwitterBlock.cs
new file mode 100644
index 0000000..5ed393d
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Block/TwitterBlock.cs
@@ -0,0 +1,261 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterBlock.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The twitter block class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer
+{
+    /// <summary>
+    /// Provides methods for interacting with user blocks.
+    /// </summary>
+    public static class TwitterBlock
+    {
+        /// <summary>
+        /// Blocks the user specified as the authenticating user. Destroys a friendship to the blocked user if it exists.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userId">The user id.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// The blocked user in the requested format when successful.
+        /// </returns>
+        public static TwitterResponse<TwitterUser> Create(OAuthTokens tokens, decimal userId, OptionalProperties options)
+        {
+            Commands.CreateBlockCommand command = new Commands.CreateBlockCommand(tokens, string.Empty, userId, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Blocks the user specified as the authenticating user. Destroys a friendship to the blocked user if it exists.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userId">The user id.</param>
+        /// <returns>
+        /// The blocked user in the requested format when successful.
+        /// </returns>
+        public static TwitterResponse<TwitterUser> Create(OAuthTokens tokens, decimal userId)
+        {
+            return Create(tokens, userId, null);
+        }
+
+        /// <summary>
+        /// Blocks the user specified as the authenticating user. Destroys a friendship to the blocked user if it exists.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenName">The user's screen name.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// The blocked user in the requested format when successful.
+        /// </returns>
+        public static TwitterResponse<TwitterUser> Create(OAuthTokens tokens, string screenName, OptionalProperties options)
+        {
+            Commands.CreateBlockCommand command = new Commands.CreateBlockCommand(tokens, screenName, -1, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Blocks the user specified as the authenticating user. Destroys a friendship to the blocked user if it exists.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenName">The user's screen name.</param>
+        /// <returns>
+        /// The blocked user in the requested format when successful.
+        /// </returns>
+        public static TwitterResponse<TwitterUser> Create(OAuthTokens tokens, string screenName)
+        {
+            return Create(tokens, screenName, null);
+        }
+
+        /// <summary>
+        /// Unblocks the user specified as the authenticating user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userId">The user id.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// The unblocked user in the requested format when successful.
+        /// </returns>
+        public static TwitterResponse<TwitterUser> Destroy(OAuthTokens tokens, decimal userId, OptionalProperties options)
+        {
+            Commands.DestroyBlockCommand command = new Commands.DestroyBlockCommand(tokens, string.Empty, userId, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Unblocks the user specified as the authenticating user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userId">The user id.</param>
+        /// <returns>
+        /// The unblocked user in the requested format when successful.
+        /// </returns>
+        public static TwitterResponse<TwitterUser> Destroy(OAuthTokens tokens, decimal userId)
+        {
+            return Destroy(tokens, userId, null);
+        }
+
+        /// <summary>
+        /// Unblocks the user specified as the authenticating user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenName">The user's screen name.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// The unblocked user in the requested format when successful.
+        /// </returns>
+        public static TwitterResponse<TwitterUser> Destroy(OAuthTokens tokens, string screenName, OptionalProperties options)
+        {
+            Commands.DestroyBlockCommand command = new Commands.DestroyBlockCommand(tokens, screenName, -1, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Unblocks the user specified as the authenticating user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenName">The user's screen name.</param>
+        /// <returns>
+        /// The unblocked user in the requested format when successful.
+        /// </returns>
+        public static TwitterResponse<TwitterUser> Destroy(OAuthTokens tokens, string screenName)
+        {
+            return Destroy(tokens, screenName, null);
+        }
+
+        /// <summary>
+        /// Checks for a block against the the user specified as the authenticating user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userId">The user id.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// The blocked user in the requested format when successful.
+        /// </returns>
+        public static TwitterResponse<TwitterUser> Exists(OAuthTokens tokens, decimal userId, OptionalProperties options)
+        {
+            Commands.ExistsBlockCommand command = new Commands.ExistsBlockCommand(tokens, string.Empty, userId, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Checks for a block against the the user specified as the authenticating user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userId">The user id.</param>
+        /// <returns>
+        /// The blocked user in the requested format when successful.
+        /// </returns>
+        public static TwitterResponse<TwitterUser> Exists(OAuthTokens tokens, decimal userId)
+        {
+            return Exists(tokens, userId, null);
+        }
+
+        /// <summary>
+        /// Checks for a block against the the user specified as the authenticating user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenName">The user's screen name.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// The blocked user in the requested format when successful.
+        /// </returns>
+        public static TwitterResponse<TwitterUser> Exists(OAuthTokens tokens, string screenName, OptionalProperties options)
+        {
+            Commands.ExistsBlockCommand command = new Commands.ExistsBlockCommand(tokens, screenName, -1, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Checks for a block against the the user specified as the authenticating user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenName">The user's screen name.</param>
+        /// <returns>
+        /// The blocked user in the requested format when successful.
+        /// </returns>
+        public static TwitterResponse<TwitterUser> Exists(OAuthTokens tokens, string screenName)
+        {
+            return Exists(tokens, screenName, null);
+        }
+
+        /// <summary>
+        /// Returns a collection of user objects that the authenticating user is blocking.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterUserCollection> Blocking(OAuthTokens tokens, BlockingOptions options)
+        {
+            Commands.BlockingCommand command = new Commands.BlockingCommand(tokens, options);
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Returns a collection of user objects that the authenticating user is blocking.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <returns></returns>
+        /// <remarks></remarks>
+        public static TwitterResponse<TwitterUserCollection> Blocking(OAuthTokens tokens)
+        {
+            return Blocking(tokens, null);
+        }
+
+        /// <summary>
+        /// Returns an collection of user ids the authenticating user is blocking.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>A collection of user ids.</returns>
+        public static TwitterResponse<TwitterIdCollection> BlockingIds(OAuthTokens tokens, OptionalProperties options)
+        {
+            Commands.BlockingIdsCommand command = new Commands.BlockingIdsCommand(tokens, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Returns an collection of user ids the authenticating user is blocking.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <returns>A collection of user ids.</returns>
+        public static TwitterResponse<TwitterIdCollection> BlockingIds(OAuthTokens tokens)
+        {
+            return BlockingIds(tokens, null);
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DeleteDirectMessageCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DeleteDirectMessageCommand.cs
index 9ce2bc7..65dda40 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DeleteDirectMessageCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DeleteDirectMessageCommand.cs
@@ -41,7 +41,9 @@ namespace Twitterizer.Commands
     /// The Delete Direct Message Command class.
     /// </summary>
     [AuthorizedCommand]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class DeleteDirectMessageCommand : TwitterCommand<TwitterDirectMessage>
     {
         #region Constructors
diff --git a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesCommand.cs
index 727d208..e2ebe5a 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesCommand.cs
@@ -43,13 +43,8 @@ namespace Twitterizer.Commands
     /// The Direct Messages Command
     /// </summary>
     [AuthorizedCommandAttribute]
-    internal sealed class DirectMessagesCommand : PagedCommand<TwitterDirectMessageCollection>
+    internal sealed class DirectMessagesCommand : TwitterCommand<TwitterDirectMessageCollection>
     {
-        /// <summary>
-        /// The base address to the API method.
-        /// </summary>
-        private const string Path = "direct_messages.json";
-
         #region Constructors
         /// <summary>
         /// Initializes a new instance of the <see cref="DirectMessagesCommand"/> class.
@@ -57,7 +52,7 @@ namespace Twitterizer.Commands
         /// <param name="tokens">The request tokens.</param>
         /// <param name="options">The options.</param>
         public DirectMessagesCommand(OAuthTokens tokens, DirectMessagesOptions options)
-            : base(HTTPVerb.GET, Path, tokens, options)
+            : base(HTTPVerb.GET, "direct_messages.json", tokens, options)
         {
             if (tokens == null)
             {
@@ -71,27 +66,28 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
-            if (this.Page <= 0)
-                this.Page = 1;
-
             DirectMessagesOptions options = this.OptionalProperties as DirectMessagesOptions;
 
-            if (options != null)
+            if (options == null)
             {
-                if (options.SinceStatusId > 0)
-                    this.RequestParameters.Add("since_id", options.SinceStatusId.ToString(CultureInfo.InvariantCulture));
+                this.RequestParameters.Add("page", "1");
 
-                if (options.MaxStatusId > 0)
-                    this.RequestParameters.Add("max_id", options.MaxStatusId.ToString(CultureInfo.InvariantCulture));
+                return;
+            }
 
-                if (options.Count > 0)
-                    this.RequestParameters.Add("count", options.Count.ToString(CultureInfo.InvariantCulture));
+            if (options.SinceStatusId > 0)
+                this.RequestParameters.Add("since_id", options.SinceStatusId.ToString(CultureInfo.InvariantCulture));
 
-                if (this.Page <= 1 && options.Page > 1)
-                    this.Page = options.Page;
-            }
+            if (options.MaxStatusId > 0)
+                this.RequestParameters.Add("max_id", options.MaxStatusId.ToString(CultureInfo.InvariantCulture));
+
+            if (options.Count > 0)
+                this.RequestParameters.Add("count", options.Count.ToString(CultureInfo.InvariantCulture));
+
+            if (options.IncludeEntites)
+                this.RequestParameters.Add("include_entities", "true");
 
-            this.RequestParameters.Add("page", this.Page.ToString(CultureInfo.InvariantCulture));
+            this.RequestParameters.Add("page", options.Page > 0 ? options.Page.ToString(CultureInfo.InvariantCulture) : "1");
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesOptions.cs
index f6684a7..f8bf0a1 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesOptions.cs
@@ -39,7 +39,9 @@ namespace Twitterizer
     /// <summary>
     /// The direct messages options class. Provides a payload for the <see cref="Twitterizer.Commands.DirectMessagesCommand"/> command.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public sealed class DirectMessagesOptions : OptionalProperties
     {
         /// <summary>
@@ -74,5 +76,11 @@ namespace Twitterizer
         /// </summary>
         /// <value>The page number.</value>
         public int Page { get; set; }
+
+        /// <summary>
+        /// Gets or sets whether to include entities in the request.
+        /// </summary>
+        /// <value>Boolean.</value>
+        public bool IncludeEntites { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesSentCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesSentCommand.cs
index fc9baad..1c7524c 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesSentCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesSentCommand.cs
@@ -43,8 +43,10 @@ namespace Twitterizer.Commands
     /// The Direct Messages Sent Command class
     /// </summary>
     [AuthorizedCommand]
+#if !SILVERLIGHT
     [Serializable]
-    internal sealed class DirectMessagesSentCommand : PagedCommand<TwitterDirectMessageCollection>
+#endif
+    internal sealed class DirectMessagesSentCommand : TwitterCommand<TwitterDirectMessageCollection>
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="DirectMessagesSentCommand"/> class.
@@ -65,38 +67,27 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
-            if (this.Page <= 0)
-                this.Page = 1;
-
             DirectMessagesSentOptions options = this.OptionalProperties as DirectMessagesSentOptions;
 
-            if (options != null)
+            if (options == null)
             {
-                if (options.SinceStatusId > 0)
-                    this.RequestParameters.Add("since_id", options.SinceStatusId.ToString(CultureInfo.InvariantCulture));
+                this.RequestParameters.Add("page", "1");
+                return;
+            }
 
-                if (options.MaxStatusId > 0)
-                    this.RequestParameters.Add("max_id", options.MaxStatusId.ToString(CultureInfo.InvariantCulture));
+            if (options.SinceStatusId > 0)
+                this.RequestParameters.Add("since_id", options.SinceStatusId.ToString(CultureInfo.InvariantCulture));
 
-                if (options.Count > 0)
-                    this.RequestParameters.Add("count", options.Count.ToString(CultureInfo.InvariantCulture));
+            if (options.MaxStatusId > 0)
+                this.RequestParameters.Add("max_id", options.MaxStatusId.ToString(CultureInfo.InvariantCulture));
 
-                if (this.Page <= 1 && options.Page > 1)
-                    this.Page = options.Page;
-            }
+            if (options.Count > 0)
+                this.RequestParameters.Add("count", options.Count.ToString(CultureInfo.InvariantCulture));
 
-            this.RequestParameters.Add("page", this.Page.ToString(CultureInfo.InstalledUICulture));
-        }
+            if (options.IncludeEntites)
+                this.RequestParameters.Add("include_entities", "true");
 
-        /// <summary>
-        /// Clones this instance.
-        /// </summary>
-        /// <returns>
-        /// A new instance of the <see cref="Twitterizer.Core.PagedCommand{T}"/> interface.
-        /// </returns>
-        internal override TwitterCommand<TwitterDirectMessageCollection> Clone()
-        {
-            return new DirectMessagesSentCommand(this.Tokens, this.OptionalProperties as DirectMessagesSentOptions);
+            this.RequestParameters.Add("page", options.Page > 0 ? options.Page.ToString(CultureInfo.InvariantCulture) : "1");
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesSentOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesSentOptions.cs
index 313263a..16ed614 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesSentOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesSentOptions.cs
@@ -38,7 +38,9 @@ namespace Twitterizer
     /// <summary>
     /// The direct messages sent options class. Provides a payload for the <see cref="Twitterizer.Commands.DirectMessagesCommand"/> command.
     /// </summary>
-    [Serializable]
+#if !SILVERLIGHT
+    [System.Serializable]
+#endif
     public sealed class DirectMessagesSentOptions : OptionalProperties
     {
         /// <summary>
@@ -73,5 +75,11 @@ namespace Twitterizer
         /// </summary>
         /// <value>The page number.</value>
         public int Page { get; set; }
+
+        /// <summary>
+        /// Gets or sets whether to include entities in the request.
+        /// </summary>
+        /// <value>Boolean.</value>
+        public bool IncludeEntites { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/SendDirectMessageCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/SendDirectMessageCommand.cs
index 5aaca84..a623d38 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/SendDirectMessageCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/SendDirectMessageCommand.cs
@@ -42,7 +42,9 @@ namespace Twitterizer.Commands
     /// The Send Direct Message Command class
     /// </summary>
     [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class SendDirectMessageCommand : TwitterCommand<TwitterDirectMessage>
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/ShowDirectMessageCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/ShowDirectMessageCommand.cs
new file mode 100644
index 0000000..e7c849e
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/ShowDirectMessageCommand.cs
@@ -0,0 +1,71 @@
+//-----------------------------------------------------------------------
+// <copyright file="SendDirectMessageCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2011, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The Show Direct Message Command class</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer.Commands
+{
+    using System;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <remarks></remarks>
+    internal sealed class ShowDirectMessageCommand : Core.TwitterCommand<TwitterDirectMessage>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ShowDirectMessageCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="id">The id.</param>
+        /// <param name="options">The options.</param>
+        /// <remarks></remarks>
+        internal ShowDirectMessageCommand(OAuthTokens tokens, decimal id, OptionalProperties options)
+            : base(HTTPVerb.GET, string.Format("direct_messages/{0}.json", id), tokens, options)
+        {
+            if (tokens == null)
+            {
+                throw new ArgumentNullException("The tokens parameter is required.");
+            }
+
+            if (id <= 0)
+            {
+                throw new ArgumentOutOfRangeException("The id parameter must be greater than zero.");
+            }
+        }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        /// <remarks></remarks>
+        public override void Init() { }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/TwitterDirectMessage.cs b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/TwitterDirectMessage.cs
index ade05fa..3492210 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/TwitterDirectMessage.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/TwitterDirectMessage.cs
@@ -42,28 +42,11 @@ namespace Twitterizer
     /// The Direct Message Entity Class
     /// </summary>
     [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public class TwitterDirectMessage : TwitterObject
     {
-        #region Constructors
-        /// <summary>
-        /// Initializes a new instance of the <see cref="TwitterDirectMessage"/> class.
-        /// </summary>
-        public TwitterDirectMessage() : base() 
-        {
-        }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="TwitterDirectMessage"/> class.
-        /// </summary>
-        /// <param name="tokens">OAuth access tokens.</param>
-        public TwitterDirectMessage(OAuthTokens tokens) 
-            : base()
-        {
-            this.Tokens = tokens;
-        }
-        #endregion
-
         #region Properties
         /// <summary>
         /// Gets or sets the direct message id.
@@ -128,6 +111,14 @@ namespace Twitterizer
         /// <value>The recipient.</value>
         [JsonProperty(PropertyName = "recipient")]
         public TwitterUser Recipient { get; set; }
+
+        /// <summary>
+        /// Gets or sets the entities.
+        /// </summary>
+        /// <value>The entities.</value>
+        [JsonProperty(PropertyName = "entities")]
+        [JsonConverter(typeof(Entities.TwitterEntityCollection.Converter))]
+        public Entities.TwitterEntityCollection Entities { get; set; }
         #endregion
 
         /// <summary>
@@ -135,7 +126,7 @@ namespace Twitterizer
         /// </summary>
         /// <param name="tokens">The tokens.</param>
         /// <returns>A <see cref="TwitterDirectMessageCollection"/> instance.</returns>
-        public static TwitterDirectMessageCollection DirectMessages(OAuthTokens tokens)
+        public static TwitterResponse<TwitterDirectMessageCollection> DirectMessages(OAuthTokens tokens)
         {
             return DirectMessages(tokens, null);
         }
@@ -148,9 +139,9 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterDirectMessageCollection"/> instance.
         /// </returns>
-        public static TwitterDirectMessageCollection DirectMessages(OAuthTokens tokens, DirectMessagesOptions options)
+        public static TwitterResponse<TwitterDirectMessageCollection> DirectMessages(OAuthTokens tokens, DirectMessagesOptions options)
         {
-            return CommandPerformer<TwitterDirectMessageCollection>.PerformAction(new Commands.DirectMessagesCommand(tokens, options));
+            return CommandPerformer.PerformAction(new Commands.DirectMessagesCommand(tokens, options));
         }
 
         /// <summary>
@@ -160,7 +151,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterDirectMessageCollection"/> instance.
         /// </returns>
-        public static TwitterDirectMessageCollection DirectMessagesSent(OAuthTokens tokens)
+        public static TwitterResponse<TwitterDirectMessageCollection> DirectMessagesSent(OAuthTokens tokens)
         {
             return DirectMessagesSent(tokens, null);
         }
@@ -175,11 +166,11 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterDirectMessage"/> instance.
         /// </returns>
-        public static TwitterDirectMessage Send(OAuthTokens tokens, decimal userId, string text, OptionalProperties options)
+        public static TwitterResponse<TwitterDirectMessage> Send(OAuthTokens tokens, decimal userId, string text, OptionalProperties options)
         {
             Commands.SendDirectMessageCommand command = new Commands.SendDirectMessageCommand(tokens, text, userId, options);
 
-            TwitterDirectMessage result = Core.CommandPerformer<TwitterDirectMessage>.PerformAction(command);
+            TwitterResponse<TwitterDirectMessage> result = Core.CommandPerformer.PerformAction(command);
 
             return result;
         }
@@ -193,7 +184,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterDirectMessage"/> instance.
         /// </returns>
-        public static TwitterDirectMessage Send(OAuthTokens tokens, decimal userId, string text)
+        public static TwitterResponse<TwitterDirectMessage> Send(OAuthTokens tokens, decimal userId, string text)
         {
             return Send(tokens, userId, text, null);
         }
@@ -206,11 +197,11 @@ namespace Twitterizer
         /// <param name="text">The message text.</param>
         /// <param name="options">The options.</param>
         /// <returns>A <see cref="TwitterDirectMessage"/> object of the created direct message.</returns>
-        public static TwitterDirectMessage Send(OAuthTokens tokens, string screenName, string text, OptionalProperties options)
+        public static TwitterResponse<TwitterDirectMessage> Send(OAuthTokens tokens, string screenName, string text, OptionalProperties options)
         {
             Commands.SendDirectMessageCommand command = new Commands.SendDirectMessageCommand(tokens, text, screenName, options);
 
-            TwitterDirectMessage result = Core.CommandPerformer<TwitterDirectMessage>.PerformAction(command);
+            TwitterResponse<TwitterDirectMessage> result = Core.CommandPerformer.PerformAction(command);
 
             return result;
         }
@@ -222,7 +213,7 @@ namespace Twitterizer
         /// <param name="screenName">The user's screen name.</param>
         /// <param name="text">The message text.</param>
         /// <returns>A <see cref="TwitterDirectMessage"/> object of the created direct message.</returns>
-        public static TwitterDirectMessage Send(OAuthTokens tokens, string screenName, string text)
+        public static TwitterResponse<TwitterDirectMessage> Send(OAuthTokens tokens, string screenName, string text)
         {
             return Send(tokens, screenName, text, null);
         }
@@ -235,36 +226,60 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterDirectMessageCollection"/> instance.
         /// </returns>
-        public static TwitterDirectMessageCollection DirectMessagesSent(OAuthTokens tokens, DirectMessagesSentOptions options)
+        public static TwitterResponse<TwitterDirectMessageCollection> DirectMessagesSent(OAuthTokens tokens, DirectMessagesSentOptions options)
         {
-            return CommandPerformer<TwitterDirectMessageCollection>.PerformAction(new Commands.DirectMessagesSentCommand(tokens, options));
+            return CommandPerformer.PerformAction(new Commands.DirectMessagesSentCommand(tokens, options));
         }
 
         /// <summary>
         /// Deletes this direct message.
         /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
         /// <returns>
         /// A <see cref="TwitterDirectMessage"/> instance.
         /// </returns>
-        public TwitterDirectMessage Delete()
+        public TwitterResponse<TwitterDirectMessage> Delete(OAuthTokens tokens, OptionalProperties options)
         {
-            return this.Delete(null);
+            Commands.DeleteDirectMessageCommand command = new Commands.DeleteDirectMessageCommand(tokens, this.Id, options);
+
+            TwitterResponse<TwitterDirectMessage> result = Core.CommandPerformer.PerformAction(command);
+
+            return result;
         }
 
         /// <summary>
         /// Deletes this direct message.
         /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="id">The direct message id.</param>
         /// <param name="options">The options.</param>
         /// <returns>
         /// A <see cref="TwitterDirectMessage"/> instance.
         /// </returns>
-        public TwitterDirectMessage Delete(OptionalProperties options)
+        public static TwitterResponse<TwitterDirectMessage> Delete(OAuthTokens tokens, decimal id, OptionalProperties options)
         {
-            Commands.DeleteDirectMessageCommand command = new Commands.DeleteDirectMessageCommand(this.Tokens, this.Id, options);
+            Commands.DeleteDirectMessageCommand command = new Commands.DeleteDirectMessageCommand(tokens, id, options);
 
-            TwitterDirectMessage result = Core.CommandPerformer<TwitterDirectMessage>.PerformAction(command);
+            TwitterResponse<TwitterDirectMessage> result = Core.CommandPerformer.PerformAction(command);
 
             return result;
         }
+
+
+        /// <summary>
+        /// Returns a single direct message, specified by an id parameter. Like the /1/direct_messages.format request, this method will include the user objects of the sender and recipient.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="id">The id.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        /// <remarks></remarks>
+        public static TwitterResponse<TwitterDirectMessage> Show(OAuthTokens tokens, decimal id, OptionalProperties options)
+        {
+            Commands.ShowDirectMessageCommand command = new Commands.ShowDirectMessageCommand(tokens, id, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/TwitterDirectMessageCollection.cs b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/TwitterDirectMessageCollection.cs
index 5249bad..0357528 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/TwitterDirectMessageCollection.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/TwitterDirectMessageCollection.cs
@@ -40,8 +40,10 @@ namespace Twitterizer
     /// <summary>
     /// The Direct Message Collection class
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
-    public class TwitterDirectMessageCollection : TwitterCollection<TwitterDirectMessage>
+#endif
+    public class TwitterDirectMessageCollection : TwitterCollection<TwitterDirectMessage>, ITwitterObject
     {
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Favorites/CreateFavoriteCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Favorites/CreateFavoriteCommand.cs
index 91187d3..5a4bdb5 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Favorites/CreateFavoriteCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Favorites/CreateFavoriteCommand.cs
@@ -42,7 +42,9 @@ namespace Twitterizer.Commands
     /// The Create Favorite Command class. Favorites the status specified in the ID parameter as the authenticating user. Returns the favorite status when successful.
     /// </summary>
     [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class CreateFavoriteCommand : TwitterCommand<TwitterStatus>
     {
         /// <summary>
@@ -52,7 +54,7 @@ namespace Twitterizer.Commands
         /// <param name="statusId">The status id.</param>
         /// <param name="options">The options.</param>
         public CreateFavoriteCommand(OAuthTokens tokens, decimal statusId, OptionalProperties options) :
-            base(HTTPVerb.POST, string.Format(CultureInfo.InvariantCulture.NumberFormat, "/favorites/{0}/create.json", statusId), tokens, options)
+            base(HTTPVerb.POST, string.Format(CultureInfo.InvariantCulture.NumberFormat, "favorites/create/{0}.json", statusId), tokens, options)
         {
             if (tokens == null)
             {
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Favorites/DeleteFavoriteCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Favorites/DeleteFavoriteCommand.cs
index 901e2bf..bc4c704 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Favorites/DeleteFavoriteCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Favorites/DeleteFavoriteCommand.cs
@@ -44,7 +44,9 @@ namespace Twitterizer.Commands
     /// Returns the un-favorited status in the requested format when successful.
     /// </summary>
     [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class DeleteFavoriteCommand : TwitterCommand<TwitterStatus>
     {
         /// <summary>
@@ -54,7 +56,7 @@ namespace Twitterizer.Commands
         /// <param name="statusId">The status id.</param>
         /// <param name="options">The options.</param>
         public DeleteFavoriteCommand(OAuthTokens tokens, decimal statusId, OptionalProperties options)
-            : base(HTTPVerb.POST, "/favorites/destroy.json", tokens, options)
+            : base(HTTPVerb.POST, string.Format(CultureInfo.InvariantCulture.NumberFormat, "favorites/destroy/{0}.json", statusId), tokens, options)
         {
             if (statusId <= 0)
             {
@@ -65,22 +67,13 @@ namespace Twitterizer.Commands
             {
                 throw new ArgumentNullException("tokens");
             }
-
-            this.StatusId = statusId;
         }
 
         /// <summary>
-        /// Gets or sets the status id.
-        /// </summary>
-        /// <value>The status id.</value>
-        public decimal StatusId { get; set; }
-
-        /// <summary>
         /// Initializes the command.
         /// </summary>
         public override void Init()
         {
-            this.RequestParameters.Add("id", this.StatusId.ToString(CultureInfo.InvariantCulture));
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Favorites/ListFavoritesCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Favorites/ListFavoritesCommand.cs
index d5579fd..48c8732 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Favorites/ListFavoritesCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Favorites/ListFavoritesCommand.cs
@@ -41,7 +41,9 @@ namespace Twitterizer.Commands
     /// <summary>
     /// The ListFavoritesCommand class. Returns the 20 most recent favorite statuses for the authenticating user or user specified by the ID parameter in the requested format.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class ListFavoritesCommand : TwitterCommand<TwitterStatusCollection>
     {
         /// <summary>
@@ -52,7 +54,7 @@ namespace Twitterizer.Commands
         public ListFavoritesCommand(OAuthTokens tokens, ListFavoritesOptions options)
             : base(HTTPVerb.GET, "favorites.json", tokens, options)
         {
-            if (tokens == null && options == null)
+            if (tokens == null && (options == null || string.IsNullOrEmpty(options.UserNameOrId)))
             {
                 throw new ArgumentException("Valid tokens or user must be supplied.");
             }
@@ -63,21 +65,26 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
+            this.RequestParameters.Add("include_entities", "true");
+
             ListFavoritesOptions options = this.OptionalProperties as ListFavoritesOptions;
 
             if (options == null)
             {
+                this.RequestParameters.Add("page", "1");
                 return;
             }
 
+            this.RequestParameters.Add("page", options.Page > 0 ? options.Page.ToString(CultureInfo.InvariantCulture) : "1");
+
             if (!string.IsNullOrEmpty(options.UserNameOrId))
             {
                 this.RequestParameters.Add("id", options.UserNameOrId);
             }
 
-            if (options.Page > 0)
+            if (options.Count > 0)
             {
-                this.RequestParameters.Add("page", options.Page.ToString(CultureInfo.InvariantCulture));
+                this.RequestParameters.Add("count", options.Count.ToString(CultureInfo.InvariantCulture));
             }
         }
     }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Favorites/ListFavoritesOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Favorites/ListFavoritesOptions.cs
index abbf958..66306d9 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Favorites/ListFavoritesOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Favorites/ListFavoritesOptions.cs
@@ -37,10 +37,18 @@ namespace Twitterizer
     /// <summary>
     /// The list favorites options class. Provides a payload for optional parameters of the ListFavoritesCommand class.
     /// </summary>
+#if !SILVERLIGHT
     [System.Serializable]
+#endif
     public class ListFavoritesOptions : OptionalProperties
     {
         /// <summary>
+        /// Gets or sets the number of favorites to return.
+        /// </summary>
+		  /// <value>The number of favorites to return per page.</value>
+        public int Count { get;set; }
+
+        /// <summary>
         /// Gets or sets the user name or id of the user for whom to return results for.
         /// </summary>
         /// <value>The user name or id of the user for whom to return results for.</value>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Favorites/TwitterFavorite.cs b/lib/Twitterizer/Twitterizer2/Methods/Favorites/TwitterFavorite.cs
index bd81dc9..ded8856 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Favorites/TwitterFavorite.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Favorites/TwitterFavorite.cs
@@ -40,7 +40,9 @@ namespace Twitterizer
     /// <summary>
     /// The TwitterFavorite class. Provides static methods for manipulating favorite tweets.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public sealed class TwitterFavorite : TwitterObject
     {
         /// <summary>
@@ -57,9 +59,9 @@ namespace Twitterizer
         /// <param name="statusId">The status id.</param>
         /// <param name="options">The options.</param>
         /// <returns>The favorite status when successful.</returns>
-        public static TwitterStatus Create(OAuthTokens tokens, decimal statusId, OptionalProperties options)
+        public static TwitterResponse<TwitterStatus> Create(OAuthTokens tokens, decimal statusId, OptionalProperties options)
         {
-            return CommandPerformer<TwitterStatus>.PerformAction(
+            return CommandPerformer.PerformAction(
                 new Commands.CreateFavoriteCommand(tokens, statusId, options));
         }
 
@@ -69,7 +71,7 @@ namespace Twitterizer
         /// <param name="tokens">The tokens.</param>
         /// <param name="statusId">The status id.</param>
         /// <returns>The favorite status when successful.</returns>
-        public static TwitterStatus Create(OAuthTokens tokens, decimal statusId)
+        public static TwitterResponse<TwitterStatus> Create(OAuthTokens tokens, decimal statusId)
         {
             return Create(tokens, statusId, null);
         }
@@ -81,9 +83,9 @@ namespace Twitterizer
         /// <param name="statusId">The status id.</param>
         /// <param name="options">The options.</param>
         /// <returns>The un-favorited status in the requested format when successful.</returns>
-        public static TwitterStatus Delete(OAuthTokens tokens, decimal statusId, OptionalProperties options)
+        public static TwitterResponse<TwitterStatus> Delete(OAuthTokens tokens, decimal statusId, OptionalProperties options)
         {
-            return CommandPerformer<TwitterStatus>.PerformAction(
+            return CommandPerformer.PerformAction(
                 new Commands.DeleteFavoriteCommand(tokens, statusId, options));
         }
 
@@ -95,7 +97,7 @@ namespace Twitterizer
         /// <returns>
         /// The un-favorited status in the requested format when successful.
         /// </returns>
-        public static TwitterStatus Delete(OAuthTokens tokens, decimal statusId)
+        public static TwitterResponse<TwitterStatus> Delete(OAuthTokens tokens, decimal statusId)
         {
             return Delete(tokens, statusId, null);
         }
@@ -106,9 +108,9 @@ namespace Twitterizer
         /// <param name="tokens">The tokens.</param>
         /// <param name="options">The options.</param>
         /// <returns>The 20 most recent favorite statuses</returns>
-        public static TwitterStatusCollection List(OAuthTokens tokens, ListFavoritesOptions options)
+        public static TwitterResponse<TwitterStatusCollection> List(OAuthTokens tokens, ListFavoritesOptions options)
         {
-            return CommandPerformer<TwitterStatusCollection>.PerformAction(
+            return CommandPerformer.PerformAction(
                 new Commands.ListFavoritesCommand(tokens, options));
         }
 
@@ -117,9 +119,19 @@ namespace Twitterizer
         /// </summary>
         /// <param name="tokens">The tokens.</param>
         /// <returns>The 20 most recent favorite statuses</returns>
-        public static TwitterStatusCollection List(OAuthTokens tokens)
+        public static TwitterResponse<TwitterStatusCollection> List(OAuthTokens tokens)
         {
             return List(tokens, null);
         }
+
+        /// <summary>
+        /// Returns the 20 most recent favorite statuses for the authenticating user or user specified by the ID parameter in the requested format.
+        /// </summary>
+        /// <param name="options">The options.</param>
+        /// <returns>The 20 most recent favorite statuses</returns>
+        public static TwitterResponse<TwitterStatusCollection> List(ListFavoritesOptions options)
+        {
+            return List(null, options);
+        }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/CreateFriendshipCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/CreateFriendshipCommand.cs
index f1bf304..a8096ba 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Friendship/CreateFriendshipCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/CreateFriendshipCommand.cs
@@ -43,7 +43,9 @@ namespace Twitterizer.Commands
     /// Creates a friendship between the authenticated user and another user
     /// </summary>
     [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class CreateFriendshipCommand : Core.TwitterCommand<TwitterUser>
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/CreateFriendshipOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/CreateFriendshipOptions.cs
index 8be5aaa..4a5008c 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Friendship/CreateFriendshipOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/CreateFriendshipOptions.cs
@@ -38,7 +38,9 @@ namespace Twitterizer
     /// <summary>
     /// The Create Friendship Options class
     /// </summary>
-    [Serializable]
+#if !SILVERLIGHT
+    [System.Serializable]
+#endif
     public sealed class CreateFriendshipOptions : OptionalProperties
     {
          /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/DeleteFriendshipCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/DeleteFriendshipCommand.cs
index 40f6318..aae25f7 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Friendship/DeleteFriendshipCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/DeleteFriendshipCommand.cs
@@ -42,7 +42,9 @@ namespace Twitterizer.Commands
     /// The delete friendship command class.
     /// </summary>
     [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class DeleteFriendshipCommand : Core.TwitterCommand<TwitterUser>
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/FollowersIdsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/FollowersIdsCommand.cs
new file mode 100644
index 0000000..3f87fbe
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/FollowersIdsCommand.cs
@@ -0,0 +1,88 @@
+//-----------------------------------------------------------------------
+// <copyright file="FollowersIdsCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Edgardo Vega</author>
+// <summary>The Friendship Resources members command class.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer.Commands
+{
+    using System;
+    using System.Globalization;
+    using Twitterizer.Core;
+
+
+    /// <summary>
+    /// Returns the members of the specified list.
+    /// </summary>
+    [AuthorizedCommand]
+    internal class FollowersIdsCommand : TwitterCommand<UserIdCollection>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="GetListsCommand"/> class.
+        /// </summary>
+        /// <param name="requestTokens">The request tokens.</param>
+        /// <param name="options">The options.</param>
+        public FollowersIdsCommand(OAuthTokens requestTokens, UsersIdsOptions options)
+            : base(HTTPVerb.GET, string.Format(CultureInfo.CurrentCulture, "followers/ids.json"), requestTokens, options)
+        {
+
+            if (requestTokens == null)
+            {
+                throw new ArgumentNullException("requestTokens");
+            }
+
+
+            this.DeserializationHandler = UserIdCollection.DeserializeWrapper;
+        }
+               
+        /// <summary>
+        /// Initializes the command.
+        /// </summary>
+        public override void Init()
+        {
+            UsersIdsOptions options = this.OptionalProperties as UsersIdsOptions;
+
+            if (options == null)
+            {
+                this.RequestParameters.Add("cursor", "-1");
+                return;
+            }
+
+            if (options.UserId > 0)
+                this.RequestParameters.Add("user_id", options.UserId.ToString(CultureInfo.InvariantCulture.NumberFormat));
+
+            if (!string.IsNullOrEmpty(options.ScreenName))
+                this.RequestParameters.Add("screen_name", options.ScreenName);
+
+            this.RequestParameters.Add("cursor", options.Cursor > 0 ? options.Cursor.ToString(CultureInfo.InvariantCulture) : "-1");
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/FriendsIdsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/FriendsIdsCommand.cs
new file mode 100644
index 0000000..e911de0
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/FriendsIdsCommand.cs
@@ -0,0 +1,85 @@
+//-----------------------------------------------------------------------
+// <copyright file="FriendsIdsCommandCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Edgardo Vega</author>
+// <summary>The Friendship Resources members command class.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer.Commands
+{
+    using System;
+    using System.Globalization;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// Returns the members of the specified list.
+    /// </summary>
+    [AuthorizedCommand]
+    internal class FriendsIdsCommand : TwitterCommand<UserIdCollection>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="FriendsIdsCommand"/> class.
+        /// </summary>
+        /// <param name="requestTokens">The request tokens.</param>
+        /// <param name="options">The options.</param>
+        public FriendsIdsCommand(OAuthTokens requestTokens, UsersIdsOptions options)
+            : base(HTTPVerb.GET, string.Format(CultureInfo.CurrentCulture, "friends/ids.json"), requestTokens, options)
+        {
+            if (requestTokens == null)
+            {
+                throw new ArgumentNullException("requestTokens");
+            }
+
+            this.DeserializationHandler = UserIdCollection.DeserializeWrapper;
+        }
+
+        /// <summary>
+        /// Initializes the command.
+        /// </summary>
+        public override void Init()
+        {
+            UsersIdsOptions options = this.OptionalProperties as UsersIdsOptions;
+
+            if (options == null)
+            {
+                this.RequestParameters.Add("cursor", "-1");
+                return;
+            }
+
+            if (options.UserId > 0)
+                this.RequestParameters.Add("user_id", options.UserId.ToString(CultureInfo.InvariantCulture.NumberFormat));
+
+            if (!string.IsNullOrEmpty(options.ScreenName))
+                this.RequestParameters.Add("screen_name", options.ScreenName);
+
+            this.RequestParameters.Add("cursor", options.Cursor > 0 ? options.Cursor.ToString(CultureInfo.InvariantCulture) : "-1");
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/IncomingFriendshipsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/IncomingFriendshipsCommand.cs
new file mode 100644
index 0000000..07cb127
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/IncomingFriendshipsCommand.cs
@@ -0,0 +1,69 @@
+//-----------------------------------------------------------------------
+// <copyright file="IncomingFriendshipCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The incoming friendship command class</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer.Commands
+{
+    using System.Globalization;
+    using Twitterizer.Core;
+
+    class IncomingFriendshipsCommand : TwitterCommand<TwitterCursorPagedIdCollection>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="IncomingFriendshipsCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        public IncomingFriendshipsCommand(OAuthTokens tokens, IncomingFriendshipsOptions options)
+            : base(HTTPVerb.GET, "friendships/incoming.json", tokens, options)
+        {
+            this.DeserializationHandler = TwitterCursorPagedIdCollection.DeserializeWrapper;
+        }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+            IncomingFriendshipsOptions options = this.OptionalProperties as IncomingFriendshipsOptions;
+            if (options == null || options.Cursor == 0)
+            {
+                this.RequestParameters.Add("cursor", "-1");
+            }
+            else
+            {
+                this.RequestParameters.Add("Cursor", options.Cursor.ToString(CultureInfo.CurrentCulture));
+            }
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/IncomingFriendshipsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/IncomingFriendshipsOptions.cs
new file mode 100644
index 0000000..9a7bf1b
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/IncomingFriendshipsOptions.cs
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------
+// <copyright file="IncomingFriendshipOptions.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The optional parameters for the incoming friendship command.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer
+{
+    /// <summary>
+    /// The optional properties for the <see cref="Twitterizer.Commands.IncomingFriendshipsCommand"/> class.
+    /// </summary>
+    public class IncomingFriendshipsOptions : OptionalProperties
+    {
+        /// <summary>
+        /// Gets or sets the cursor.
+        /// </summary>
+        /// <value>The cursor.</value>
+        public long Cursor { get; set; }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/OutgoingFriendshipsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/OutgoingFriendshipsCommand.cs
new file mode 100644
index 0000000..a480e6f
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/OutgoingFriendshipsCommand.cs
@@ -0,0 +1,72 @@
+//-----------------------------------------------------------------------
+// <copyright file="OutgoingFriendshipsCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The outgoing friendship command class</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer.Commands
+{
+    using System.Globalization;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// Returns an array of numeric IDs for every user who has a pending request to follow the authenticating user.
+    /// </summary>
+    internal sealed class OutgoingFriendshipsCommand : TwitterCommand<TwitterCursorPagedIdCollection>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="IncomingFriendshipsCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        public OutgoingFriendshipsCommand(OAuthTokens tokens, OutgoingFriendshipsOptions options)
+            : base(HTTPVerb.GET, "friendships/outgoing.json", tokens, options)
+        {
+            this.DeserializationHandler = TwitterCursorPagedIdCollection.DeserializeWrapper;
+        }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+            OutgoingFriendshipsOptions options = this.OptionalProperties as OutgoingFriendshipsOptions;
+            if (options == null || options.Cursor == 0)
+            {
+                this.RequestParameters.Add("cursor", "-1");
+            }
+            else
+            {
+                this.RequestParameters.Add("Cursor", options.Cursor.ToString(CultureInfo.CurrentCulture));
+            }
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/OutgoingFriendshipsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/OutgoingFriendshipsOptions.cs
new file mode 100644
index 0000000..949f91d
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/OutgoingFriendshipsOptions.cs
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------
+// <copyright file="OutgoingFriendshipsOptions.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The optional parameters for the incoming friendship command.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer
+{
+    /// <summary>
+    /// The optional properties for the <see cref="Twitterizer.Commands.IncomingFriendshipsCommand"/> class.
+    /// </summary>
+    public class OutgoingFriendshipsOptions : OptionalProperties
+    {
+        /// <summary>
+        /// Gets or sets the cursor.
+        /// </summary>
+        /// <value>The cursor.</value>
+        public long Cursor { get; set; }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/ShowFriendshipCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/ShowFriendshipCommand.cs
index 5147003..3739c2f 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Friendship/ShowFriendshipCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/ShowFriendshipCommand.cs
@@ -42,7 +42,9 @@ namespace Twitterizer.Commands
     /// The show friendship command class.
     /// </summary>
     [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class ShowFriendshipCommand : Core.TwitterCommand<TwitterRelationship>
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterFriendship.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterFriendship.cs
index 64ba774..9d2238d 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterFriendship.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterFriendship.cs
@@ -34,11 +34,7 @@
 
 namespace Twitterizer
 {
-    using System;
-    using System.Collections.Generic;
-    using System.Linq;
-    using System.Text;
-    using Twitterizer.Core;
+    using Core;
 
     /// <summary>
     /// Provides interaction with the Twitter API to obtain and manage relationships between users.
@@ -54,15 +50,11 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterStatusCollection"/> instance.
         /// </returns>
-        public static TwitterUserCollection Followers(OAuthTokens tokens, FollowersOptions options)
+        public static TwitterResponse<TwitterUserCollection> Followers(OAuthTokens tokens, FollowersOptions options)
         {
             Commands.FollowersCommand command = new Commands.FollowersCommand(tokens, options);
 
-            TwitterUserCollection result = Core.CommandPerformer<TwitterUserCollection>.PerformAction(command);
-
-            result.CursorPagedCommand = command;
-
-            return result;
+            return CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -72,7 +64,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterStatusCollection"/> instance.
         /// </returns>
-        public static TwitterUserCollection Followers(OAuthTokens tokens)
+        public static TwitterResponse<TwitterUserCollection> Followers(OAuthTokens tokens)
         {
             return Followers(tokens, null);
         }
@@ -84,7 +76,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterStatusCollection"/> instance.
         /// </returns>
-        public static TwitterUserCollection Followers(FollowersOptions options)
+        public static TwitterResponse<TwitterUserCollection> Followers(FollowersOptions options)
         {
             return Followers(null, options);
         }
@@ -101,14 +93,12 @@ namespace Twitterizer
         /// A <see cref="TwitterUserCollection"/> instance.
         /// </returns>
         /// <remarks>Please note that the result set isn't guaranteed to be 100 every time as suspended users will be filtered out.</remarks>
-        public static TwitterUserCollection Friends(OAuthTokens tokens, FriendsOptions options)
+        [System.Obsolete("This method is deprecated as it will only return information about users who have Tweeted recently. It is not a functional way to retrieve all of a users friends. Instead of using this method use a combination of friends/ids and users/lookup.")]
+        public static TwitterResponse<TwitterUserCollection> Friends(OAuthTokens tokens, FriendsOptions options)
         {
             Commands.FriendsCommand command = new Commands.FriendsCommand(tokens, options);
 
-            TwitterUserCollection result = Core.CommandPerformer<TwitterUserCollection>.PerformAction(command);
-            result.CursorPagedCommand = command;
-
-            return result;
+            return CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -119,7 +109,8 @@ namespace Twitterizer
         /// A <see cref="TwitterUserCollection"/> instance.
         /// </returns>
         /// <remarks>Please note that the result set isn't guaranteed to be 100 every time as suspended users will be filtered out.</remarks>
-        public static TwitterUserCollection Friends(OAuthTokens tokens)
+        [System.Obsolete("This method is deprecated as it will only return information about users who have Tweeted recently. It is not a functional way to retrieve all of a users friends. Instead of using this method use a combination of friends/ids and users/lookup.")]
+        public static TwitterResponse<TwitterUserCollection> Friends(OAuthTokens tokens)
         {
             return Friends(tokens, null);
         }
@@ -132,7 +123,8 @@ namespace Twitterizer
         /// A <see cref="TwitterUserCollection"/> instance.
         /// </returns>
         /// <remarks>Please note that the result set isn't guaranteed to be 100 every time as suspended users will be filtered out.</remarks>
-        public static TwitterUserCollection Friends(FriendsOptions options)
+        [System.Obsolete("This method is deprecated as it will only return information about users who have Tweeted recently. It is not a functional way to retrieve all of a users friends. Instead of using this method use a combination of friends/ids and users/lookup.")]
+        public static TwitterResponse<TwitterUserCollection> Friends(FriendsOptions options)
         {
             return Friends(null, options);
         }
@@ -148,7 +140,7 @@ namespace Twitterizer
         /// <returns>
         /// Returns the followed user in the requested format when successful.
         /// </returns>
-        public static TwitterUser Create(OAuthTokens tokens, decimal userId)
+        public static TwitterResponse<TwitterUser> Create(OAuthTokens tokens, decimal userId)
         {
             return Create(tokens, userId, null);
         }
@@ -162,10 +154,10 @@ namespace Twitterizer
         /// <returns>
         /// Returns the followed user in the requested format when successful.
         /// </returns>
-        public static TwitterUser Create(OAuthTokens tokens, decimal userId, CreateFriendshipOptions options)
+        public static TwitterResponse<TwitterUser> Create(OAuthTokens tokens, decimal userId, CreateFriendshipOptions options)
         {
             Commands.CreateFriendshipCommand command = new Commands.CreateFriendshipCommand(tokens, userId, options);
-            return CommandPerformer<TwitterUser>.PerformAction(command);
+            return CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -176,7 +168,7 @@ namespace Twitterizer
         /// <returns>
         /// Returns the followed user in the requested format when successful.
         /// </returns>
-        public static TwitterUser Create(OAuthTokens tokens, string userName)
+        public static TwitterResponse<TwitterUser> Create(OAuthTokens tokens, string userName)
         {
             return Create(tokens, userName, null);
         }
@@ -190,10 +182,10 @@ namespace Twitterizer
         /// <returns>
         /// Returns the followed user in the requested format when successful.
         /// </returns>
-        public static TwitterUser Create(OAuthTokens tokens, string userName, CreateFriendshipOptions options)
+        public static TwitterResponse<TwitterUser> Create(OAuthTokens tokens, string userName, CreateFriendshipOptions options)
         {
             Commands.CreateFriendshipCommand command = new Commands.CreateFriendshipCommand(tokens, userName, options);
-            return CommandPerformer<TwitterUser>.PerformAction(command);
+            return CommandPerformer.PerformAction(command);
         }
 
         #endregion
@@ -208,7 +200,7 @@ namespace Twitterizer
         /// <returns>
         /// Returns the unfollowed user in the requested format when successful.
         /// </returns>
-        public static TwitterUser Delete(OAuthTokens tokens, decimal userId)
+        public static TwitterResponse<TwitterUser> Delete(OAuthTokens tokens, decimal userId)
         {
            return Delete(tokens, userId, null);
         }
@@ -222,10 +214,10 @@ namespace Twitterizer
         /// <returns>
         /// Returns the unfollowed user in the requested format when successful.
         /// </returns>
-        public static TwitterUser Delete(OAuthTokens tokens, decimal userId, OptionalProperties options)
+        public static TwitterResponse<TwitterUser> Delete(OAuthTokens tokens, decimal userId, OptionalProperties options)
         {
             Commands.DeleteFriendshipCommand command = new Commands.DeleteFriendshipCommand(tokens, userId, string.Empty, options);
-            return Core.CommandPerformer<TwitterUser>.PerformAction(command);
+            return CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -236,7 +228,7 @@ namespace Twitterizer
         /// <returns>
         /// Returns the unfollowed user in the requested format when successful.
         /// </returns>
-        public static TwitterUser Delete(OAuthTokens tokens, string userName)
+        public static TwitterResponse<TwitterUser> Delete(OAuthTokens tokens, string userName)
         {
             return Delete(tokens, userName, null);
         }
@@ -250,10 +242,10 @@ namespace Twitterizer
         /// <returns>
         /// Returns the unfollowed user in the requested format when successful.
         /// </returns>
-        public static TwitterUser Delete(OAuthTokens tokens, string userName, OptionalProperties options)
+        public static TwitterResponse<TwitterUser> Delete(OAuthTokens tokens, string userName, OptionalProperties options)
         {
             Commands.DeleteFriendshipCommand command = new Commands.DeleteFriendshipCommand(tokens, 0, userName, options);
-            return Core.CommandPerformer<TwitterUser>.PerformAction(command);
+            return Core.CommandPerformer.PerformAction(command);
         }
         #endregion
 
@@ -265,7 +257,7 @@ namespace Twitterizer
         /// <param name="tokens">The tokens.</param>
         /// <param name="targetUserId">The target user id.</param>
         /// <returns>A <see cref="TwitterRelationship"/> instance.</returns>
-        public static TwitterRelationship Show(OAuthTokens tokens, decimal targetUserId)
+        public static TwitterResponse<TwitterRelationship> Show(OAuthTokens tokens, decimal targetUserId)
         {
             return Show(tokens, targetUserId, null);
         }
@@ -277,7 +269,7 @@ namespace Twitterizer
         /// <param name="targetUserId">The target user id.</param>
         /// <param name="options">The options.</param>
         /// <returns>A <see cref="TwitterRelationship"/> instance.</returns>
-        public static TwitterRelationship Show(OAuthTokens tokens, decimal targetUserId, OptionalProperties options)
+        public static TwitterResponse<TwitterRelationship> Show(OAuthTokens tokens, decimal targetUserId, OptionalProperties options)
         {
             return Show(tokens, 0, targetUserId, options);
         }
@@ -289,7 +281,7 @@ namespace Twitterizer
         /// <param name="sourceUseId">The source user id.</param>
         /// <param name="targetUserId">The target user id.</param>
         /// <returns>A <see cref="TwitterRelationship"/> instance.</returns>
-        public static TwitterRelationship Show(OAuthTokens tokens, decimal sourceUseId, decimal targetUserId)
+        public static TwitterResponse<TwitterRelationship> Show(OAuthTokens tokens, decimal sourceUseId, decimal targetUserId)
         {
             return Show(tokens, sourceUseId, targetUserId, null);
         }
@@ -302,7 +294,7 @@ namespace Twitterizer
         /// <param name="targetUserId">The target user id.</param>
         /// <param name="options">The options.</param>
         /// <returns>A <see cref="TwitterRelationship"/> instance.</returns>
-        public static TwitterRelationship Show(OAuthTokens tokens, decimal sourceUseId, decimal targetUserId, OptionalProperties options)
+        public static TwitterResponse<TwitterRelationship> Show(OAuthTokens tokens, decimal sourceUseId, decimal targetUserId, OptionalProperties options)
         {
             Commands.ShowFriendshipCommand command = new Twitterizer.Commands.ShowFriendshipCommand(
                 tokens, 
@@ -312,7 +304,7 @@ namespace Twitterizer
                 string.Empty, 
                 options);
 
-            return Core.CommandPerformer<TwitterRelationship>.PerformAction(command);
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -321,7 +313,7 @@ namespace Twitterizer
         /// <param name="tokens">The tokens.</param>
         /// <param name="targetUserName">The target user name.</param>
         /// <returns>A <see cref="TwitterRelationship"/> instance.</returns>
-        public static TwitterRelationship Show(OAuthTokens tokens, string targetUserName)
+        public static TwitterResponse<TwitterRelationship> Show(OAuthTokens tokens, string targetUserName)
         {
             return Show(tokens, string.Empty, targetUserName, null);
         }
@@ -333,7 +325,7 @@ namespace Twitterizer
         /// <param name="targetUserName">The target user name.</param>
         /// <param name="options">The options.</param>
         /// <returns>A <see cref="TwitterRelationship"/> instance.</returns>
-        public static TwitterRelationship Show(OAuthTokens tokens, string targetUserName, OptionalProperties options)
+        public static TwitterResponse<TwitterRelationship> Show(OAuthTokens tokens, string targetUserName, OptionalProperties options)
         {
             return Show(tokens, string.Empty, targetUserName, options);
         }
@@ -345,7 +337,7 @@ namespace Twitterizer
         /// <param name="sourceUserName">The source user name.</param>
         /// <param name="targetUserName">The target user name.</param>
         /// <returns>A <see cref="TwitterRelationship"/> instance.</returns>
-        public static TwitterRelationship Show(OAuthTokens tokens, string sourceUserName, string targetUserName)
+        public static TwitterResponse<TwitterRelationship> Show(OAuthTokens tokens, string sourceUserName, string targetUserName)
         {
             return Show(tokens, sourceUserName, targetUserName, null);
         }
@@ -358,11 +350,11 @@ namespace Twitterizer
         /// <param name="targetUserName">The target user name.</param>
         /// <param name="options">The options.</param>
         /// <returns>A <see cref="TwitterRelationship"/> instance.</returns>
-        public static TwitterRelationship Show(OAuthTokens tokens, string sourceUserName, string targetUserName, OptionalProperties options)
+        public static TwitterResponse<TwitterRelationship> Show(OAuthTokens tokens, string sourceUserName, string targetUserName, OptionalProperties options)
         {
             Commands.ShowFriendshipCommand command = new Twitterizer.Commands.ShowFriendshipCommand(tokens, 0, sourceUserName, 0, targetUserName, options);
 
-            return Core.CommandPerformer<TwitterRelationship>.PerformAction(command);
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -373,7 +365,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterRelationship"/> instance.
         /// </returns>
-        public static TwitterRelationship Show(decimal sourceUseId, decimal targetUserId)
+        public static TwitterResponse<TwitterRelationship> Show(decimal sourceUseId, decimal targetUserId)
         {
             return Show(null, sourceUseId, targetUserId, null);
         }
@@ -386,11 +378,112 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterRelationship"/> instance.
         /// </returns>
-        public static TwitterRelationship Show(string sourceUserName, string targetUserName)
+        public static TwitterResponse<TwitterRelationship> Show(string sourceUserName, string targetUserName)
         {
             return Show(null, sourceUserName, targetUserName, null);
         }
 
         #endregion
+
+        #region User IDs lists
+        
+        /// <summary>
+        /// Returns the numeric IDs for every user the specified user is friends with.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// A <see cref="TwitterListCollection"/> instance.
+        /// </returns>
+        public static TwitterResponse<UserIdCollection> FriendsIds(OAuthTokens tokens, UsersIdsOptions options)
+        {
+            Commands.FriendsIdsCommand command = new Commands.FriendsIdsCommand(tokens, options);
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Returns the numeric IDs for every user the specified user is friends with.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <returns>
+        /// A <see cref="TwitterListCollection"/> instance.
+        /// </returns>
+        public static TwitterResponse<UserIdCollection> FriendsIds(OAuthTokens tokens)
+        {
+            return FriendsIds(tokens, null);
+        }
+
+        /// <summary>
+        /// Returns the numeric IDs for every user the specified user is following.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// A <see cref="TwitterListCollection"/> instance.
+        /// </returns>
+        public static TwitterResponse<UserIdCollection> FollowersIds(OAuthTokens tokens, UsersIdsOptions options)
+        {
+            Commands.FollowersIdsCommand command = new Commands.FollowersIdsCommand(tokens, options);
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Returns the numeric IDs for every user the specified user is following.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <returns>
+        /// A <see cref="TwitterListCollection"/> instance.
+        /// </returns>
+        public static TwitterResponse<UserIdCollection> FollowersIds(OAuthTokens tokens)
+        {
+            return FollowersIds(tokens, null);
+        }
+
+        #endregion
+
+        /// <summary>
+        /// Returns a collection of IDs for every user who has a pending request to follow the authenticating user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterCursorPagedIdCollection> IncomingRequests(OAuthTokens tokens, IncomingFriendshipsOptions options)
+        {
+            Commands.IncomingFriendshipsCommand command = new Commands.IncomingFriendshipsCommand(tokens, options);
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Returns a collection of IDs for every user who has a pending request to follow the authenticating user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterCursorPagedIdCollection> IncomingRequests(OAuthTokens tokens)
+        {
+            return IncomingRequests(tokens, null);
+        }
+
+        /// <summary>
+        /// Returns a collection of IDs for every protected user for whom the authenticating user has a pending follow request.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterCursorPagedIdCollection> OutgoingRequests(OAuthTokens tokens, OutgoingFriendshipsOptions options)
+        {
+            Commands.OutgoingFriendshipsCommand command = new Commands.OutgoingFriendshipsCommand(tokens, options);
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Returns a collection of IDs for every protected user for whom the authenticating user has a pending follow request.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterCursorPagedIdCollection> OutgoingRequests(OAuthTokens tokens)
+        {
+            return OutgoingRequests(tokens, null);
+        }
+
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterRelationship.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterRelationship.cs
index 85142dc..b5188fd 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterRelationship.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterRelationship.cs
@@ -44,7 +44,9 @@ namespace Twitterizer
     /// </summary>
     [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
     [DebuggerDisplay("TwitterRelationship = {Source} -> {Target}")]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public class TwitterRelationship : TwitterObject
     {
         /// <summary>
@@ -57,26 +59,6 @@ namespace Twitterizer
         /// </summary>
         private TwitterUser target;
 
-        #region Constructors
-        /// <summary>
-        /// Initializes a new instance of the <see cref="TwitterRelationship"/> class.
-        /// </summary>
-        /// <param name="tokens">OAuth access tokens.</param>
-        public TwitterRelationship(OAuthTokens tokens) 
-            : base()
-        {
-            this.Tokens = tokens;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="TwitterRelationship"/> class.
-        /// </summary>
-        public TwitterRelationship()
-            : base()
-        {
-        }
-        #endregion
-
         /// <summary>
         /// Gets or sets the source.
         /// </summary>
@@ -86,11 +68,6 @@ namespace Twitterizer
         {
             get
             {
-                if (!this.source.IsEmpty)
-                {
-                    this.source.Tokens = this.Tokens;
-                }
-
                 return this.source;
             }
 
@@ -109,11 +86,6 @@ namespace Twitterizer
         {
             get
             {
-                if (!this.target.IsEmpty)
-                {
-                    this.target.Tokens = this.Tokens;
-                }
-
                 return this.target;
             }
 
@@ -152,11 +124,11 @@ namespace Twitterizer
         /// <returns>
         /// Returns the unfollowed user in the requested format when successful. Returns a string describing the failure condition when unsuccessful.
         /// </returns>
-        public TwitterUser Delete(OAuthTokens tokens)
+        public TwitterResponse<TwitterUser> Delete(OAuthTokens tokens)
         {
             Commands.DeleteFriendshipCommand command = new Twitterizer.Commands.DeleteFriendshipCommand(tokens, this.Target.Id, string.Empty, null);
 
-            return CommandPerformer<TwitterUser>.PerformAction(command);
+            return CommandPerformer.PerformAction(command);
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/UserIdCollection.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/UserIdCollection.cs
new file mode 100644
index 0000000..b34b79d
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/UserIdCollection.cs
@@ -0,0 +1,96 @@
+//-----------------------------------------------------------------------
+// <copyright file="UserIdCollection.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Edgardo Vega</author>
+// <summary>The twitter list collection class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using Newtonsoft.Json;
+    using Newtonsoft.Json.Linq;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The twitter list collection class.
+    /// </summary>
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    public class UserIdCollection : TwitterIdCollection
+    {
+        /// <summary>
+        /// Gets or sets the next cursor.
+        /// </summary>
+        /// <value>The next cursor.</value>
+        public long NextCursor { get; set; }
+
+        /// <summary>
+        /// Gets or sets the previous cursor.
+        /// </summary>
+        /// <value>The previous cursor.</value>
+        public long PreviousCursor { get; set; }
+
+        /// <summary>
+        /// Gets or sets information about the user's rate usage.
+        /// </summary>
+        /// <value>The rate limiting object.</value>
+        public RateLimiting RateLimiting { get; set; }
+
+        /// <summary>
+        /// Deserializes the specified value.
+        /// </summary>
+        /// <param name="value">The value.</param>
+        /// <returns></returns>
+        internal static UserIdCollection DeserializeWrapper(JObject value)
+        {
+            if (value == null || value.SelectToken("ids") == null)
+                return null;
+
+            decimal[] parsedIds = JsonConvert.DeserializeObject<decimal[]>(value.SelectToken("ids").ToString());
+
+            UserIdCollection result = new UserIdCollection
+                                                      {
+                                                          NextCursor = value.SelectToken("next_cursor").Value<long>(),
+                                                          PreviousCursor =
+                                                              value.SelectToken("previous_cursor").Value<long>()
+                                                      };
+
+            foreach (decimal t in parsedIds)
+            {
+                result.Add(t);
+            }
+
+            return result;
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/UsersIdsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/UsersIdsOptions.cs
new file mode 100644
index 0000000..81febc6
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/UsersIdsOptions.cs
@@ -0,0 +1,64 @@
+//-----------------------------------------------------------------------
+// <copyright file="UsersIdsOptions.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Edgardo Vega</author>
+// <summary>Optional parameters for the Friendship Resource methods.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer
+{
+    using System;
+
+    /// <summary>
+    /// The Create Friendship Options class
+    /// </summary>
+#if !SILVERLIGHT
+    [System.Serializable]
+#endif
+    public sealed class UsersIdsOptions : OptionalProperties
+    {
+        /// <summary>
+        /// Gets or sets the cursor.
+        /// </summary>
+        /// <value>The cursor.</value>
+        public long Cursor { get; set; }
+
+        /// <summary>
+        /// Gets or sets the ID of the user for whom to request a list of followers.
+        /// </summary>
+        /// <value>The user id.</value>
+        public decimal UserId { get; set; }
+
+        /// <summary>
+        /// Gets or sets the screen name of the user for whom to request a list of followers. 
+        /// </summary>
+        /// <value>The name of the screen.</value>
+        public string ScreenName { get; set; }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Geo/Coordinate.cs b/lib/Twitterizer/Twitterizer2/Methods/Geo/Coordinate.cs
index 3c77fe3..d0afe8a 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Geo/Coordinate.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Geo/Coordinate.cs
@@ -41,7 +41,9 @@ namespace Twitterizer
     /// <summary>
     /// Represents a single point on planet earth.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public class Coordinate
     {
         /// <summary>
@@ -59,7 +61,11 @@ namespace Twitterizer
         /// <summary>
         /// Reads a json array of coordinates and converts it into a collection of coordinate objects.
         /// </summary>
+#if !SILVERLIGHT         
         internal class Converter : JsonConverter
+#else
+        public class Converter : JsonConverter
+#endif
         {
             /// <summary>
             /// Determines whether this instance can convert the specified object type.
@@ -83,42 +89,49 @@ namespace Twitterizer
             /// <returns>A deserialized <see cref="System.Collections.ObjectModel.Collection{Coordinate}"/></returns>
             public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
             {
-                Collection<Coordinate> result = existingValue as Collection<Coordinate>;
-
-                if (result == null)
-                    result = new Collection<Coordinate>();
-
-                int startDepth = reader.Depth;
-
-                if (reader.TokenType != JsonToken.StartArray)
+                try
                 {
-                    return null;
-                }
-
-                int depth = reader.Depth + 1;
-                double count = 1;
+                    Collection<Coordinate> result = existingValue as Collection<Coordinate>;
 
-                while (reader.Read() && reader.Depth >= startDepth)
-                {
-                    if (new[] { JsonToken.StartArray, JsonToken.EndArray }.Contains(reader.TokenType))
-                        continue;
+                    if (result == null)
+                        result = new Collection<Coordinate>();
 
-                    int itemIndex = Convert.ToInt32(Math.Ceiling(count / 2) - 1);
+                    int startDepth = reader.Depth;
 
-                    if (count % 2 > 0)
+                    if (reader.TokenType != JsonToken.StartArray)
                     {
-                        result.Add(new Coordinate());
-                        result[itemIndex].Latitude = (double)reader.Value;
+                        return null;
                     }
-                    else
+
+                    int depth = reader.Depth + 1;
+                    double count = 1;
+
+                    while (reader.Read() && reader.Depth >= startDepth)
                     {
-                        result[itemIndex].Longitude = (double)reader.Value;
+                        if (new[] { JsonToken.StartArray, JsonToken.EndArray }.Contains(reader.TokenType))
+                            continue;
+
+                        int itemIndex = Convert.ToInt32(Math.Ceiling(count / 2) - 1);
+
+                        if (count % 2 > 0)
+                        {
+                            result.Add(new Coordinate());
+                            result[itemIndex].Latitude = (double)reader.Value;
+                        }
+                        else
+                        {
+                            result[itemIndex].Longitude = (double)reader.Value;
+                        }
+
+                        count++;
                     }
 
-                    count++;
+                    return result;
+                }
+                catch
+                {
+                    return null;
                 }
-
-                return result;
             }
 
             /// <summary>
@@ -129,7 +142,8 @@ namespace Twitterizer
             /// <param name="serializer">The serializer.</param>
             public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
             {
-                throw new NotImplementedException();
+                // TODO: Implement this.
+                writer.WriteNull();
             }
         }
     }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Geo/ReverseGeocodeCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Geo/ReverseGeocodeCommand.cs
index b835369..4facc67 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Geo/ReverseGeocodeCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Geo/ReverseGeocodeCommand.cs
@@ -41,7 +41,9 @@ namespace Twitterizer.Commands
     /// <summary>
     /// The reverse geocode command class. Performs a reverse geocode lookup.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal class ReverseGeocodeCommand : TwitterCommand<TwitterPlaceCollection>
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterBoundingBox.cs b/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterBoundingBox.cs
index ec53b24..e390936 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterBoundingBox.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterBoundingBox.cs
@@ -42,7 +42,9 @@ namespace Twitterizer
     /// The twitter bounding box class. Represents a series of latitude and longitude coordinates that represents an area.
     /// </summary>
     [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public class TwitterBoundingBox : TwitterObject
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterGeo.cs b/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterGeo.cs
index ea50ce7..894b86c 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterGeo.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterGeo.cs
@@ -67,7 +67,9 @@ namespace Twitterizer
     /// <summary>
     /// Represents a geological area
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public class TwitterGeo
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterPlace.cs b/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterPlace.cs
index 4851ab7..e910fba 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterPlace.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterPlace.cs
@@ -42,7 +42,9 @@ namespace Twitterizer
     /// The twitter place class. Represents a place or area.
     /// </summary>
     [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     [System.Diagnostics.DebuggerDisplay("{FullName} ({Id})")]
     public sealed class TwitterPlace : TwitterObject
     {
@@ -110,26 +112,26 @@ namespace Twitterizer
         public TwitterBoundingBox BoundingBox { get; set; }
 
         /// <summary>
-        /// Lookups the specified latitude.
+        /// Retrieves a place based on the specified coordinates.
         /// </summary>
         /// <param name="latitude">The latitude.</param>
         /// <param name="longitude">The longitude.</param>
         /// <param name="options">The options.</param>
         /// <returns>A collection of matched <see cref="Twitterizer.TwitterPlace"/> items.</returns>
-        public static TwitterPlaceCollection Lookup(double latitude, double longitude, TwitterPlaceLookupOptions options)
+        public static TwitterResponse<TwitterPlaceCollection> Lookup(double latitude, double longitude, TwitterPlaceLookupOptions options)
         {
             Commands.ReverseGeocodeCommand command = new Twitterizer.Commands.ReverseGeocodeCommand(latitude, longitude, options);
 
-            return CommandPerformer<TwitterPlaceCollection>.PerformAction(command);
+            return CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
-        /// Lookups the specified latitude.
+        /// Retrieves a place based on the specified coordinates.
         /// </summary>
         /// <param name="latitude">The latitude.</param>
         /// <param name="longitude">The longitude.</param>
         /// <returns>A collection of matched <see cref="Twitterizer.TwitterPlace"/> items.</returns>
-        public static TwitterPlaceCollection Lookup(double latitude, double longitude)
+        public static TwitterResponse<TwitterPlaceCollection> Lookup(double latitude, double longitude)
         {
             return Lookup(latitude, longitude, null);
         }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterPlaceCollection.cs b/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterPlaceCollection.cs
index 3193cd3..0a5eec2 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterPlaceCollection.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterPlaceCollection.cs
@@ -41,15 +41,21 @@ namespace Twitterizer
     /// <summary>
     /// The Twitter Place Collection class. A collection of <see cref="TwitterPlace"/> objects.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     [JsonConverter(typeof(TwitterPlaceCollection.Converter))]
     [JsonObject]
-    public class TwitterPlaceCollection : TwitterCollection<TwitterPlace>
+    public class TwitterPlaceCollection : TwitterCollection<TwitterPlace>, ITwitterObject
     {
         /// <summary>
         /// Converts json data to a <see cref="TwitterPlaceCollection"/>.
         /// </summary>
+#if !SILVERLIGHT         
         internal class Converter : JsonConverter
+#else
+        public class Converter : JsonConverter
+#endif
         {
             /// <summary>
             /// Determines whether this instance can convert the specified object type.
@@ -107,7 +113,8 @@ namespace Twitterizer
             /// <param name="serializer">The calling serializer.</param>
             public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
             {
-                throw new NotImplementedException();
+                // TODO: Implement this.
+                // throw new NotImplementedException();
             }
         }
     }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/AddListMemberCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/AddListMemberCommand.cs
index 8de9768..55ace77 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/AddListMemberCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/AddListMemberCommand.cs
@@ -42,7 +42,9 @@ namespace Twitterizer.Commands
     /// Add a member to a list. The authenticated user must own the list to be able to add members to it. Lists are limited to having 500 members.
     /// </summary>
     [AuthorizedCommand]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal class AddListMemberCommand : TwitterCommand<TwitterList>
     {
         /// <summary>
@@ -53,8 +55,8 @@ namespace Twitterizer.Commands
         /// <param name="listId">The list id.</param>
         /// <param name="userId">The user id.</param>
         /// <param name="options">The options.</param>
-        public AddListMemberCommand(OAuthTokens requestTokens, string ownerUsername, decimal listId, decimal userId, OptionalProperties options)
-            : base(HTTPVerb.POST, string.Format(CultureInfo.CurrentCulture, "/{0}/{1}/members.json", ownerUsername, listId), requestTokens, options)
+        public AddListMemberCommand(OAuthTokens requestTokens, string ownerUsername, string listId, decimal userId, OptionalProperties options)
+            : base(HTTPVerb.POST, string.Format(CultureInfo.CurrentCulture, "{0}/{1}/members.json", ownerUsername, listId), requestTokens, options)
         {
             if (requestTokens == null)
             {
@@ -66,7 +68,7 @@ namespace Twitterizer.Commands
                 throw new ArgumentNullException("ownerUsername");
             }
 
-            if (listId <= 0)
+            if (string.IsNullOrEmpty(listId))
             {
                 throw new ArgumentNullException("listId");
             }
@@ -90,7 +92,7 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
-            this.RequestParameters.Add("user_id", this.UserId.ToString(CultureInfo.InvariantCulture.NumberFormat));
+            this.RequestParameters.Add("id", this.UserId.ToString(CultureInfo.InvariantCulture.NumberFormat));
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/CheckListMembershipCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/CheckListMembershipCommand.cs
index faec583..13cc8e6 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/CheckListMembershipCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/CheckListMembershipCommand.cs
@@ -42,7 +42,9 @@ namespace Twitterizer.Commands
     /// Check if a user is a member of the specified list.
     /// </summary>
     [AuthorizedCommand]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal class CheckListMembershipCommand : TwitterCommand<TwitterUser>
     {
         /// <summary>
@@ -53,8 +55,8 @@ namespace Twitterizer.Commands
         /// <param name="listId">The list id.</param>
         /// <param name="userId">The user id.</param>
         /// <param name="options">The options.</param>
-        public CheckListMembershipCommand(OAuthTokens requestTokens, string ownerUsername, decimal listId, decimal userId, OptionalProperties options)
-            : base(HTTPVerb.GET, string.Format(CultureInfo.CurrentCulture, "/{0}/{1}/members/{2}.json", ownerUsername, listId), requestTokens, options)
+        public CheckListMembershipCommand(OAuthTokens requestTokens, string ownerUsername, string listId, decimal userId, OptionalProperties options)
+            : base(HTTPVerb.GET, string.Format(CultureInfo.CurrentCulture, "{0}/{1}/members/{2}.json", ownerUsername, listId, userId), requestTokens, options)
         {
             if (requestTokens == null)
             {
@@ -66,7 +68,7 @@ namespace Twitterizer.Commands
                 throw new ArgumentNullException("ownerUsername");
             }
 
-            if (listId <= 0)
+            if (string.IsNullOrEmpty(listId))
             {
                 throw new ArgumentNullException("listId");
             }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/CreateListCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/CreateListCommand.cs
index c52bec7..d9e4bd8 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/CreateListCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/CreateListCommand.cs
@@ -43,18 +43,20 @@ namespace Twitterizer.Commands
     /// The create list command class
     /// </summary>
     [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class CreateListCommand : TwitterCommand<TwitterList>
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="CreateListCommand"/> class.
         /// </summary>
         /// <param name="requestTokens">The request tokens.</param>
-        /// <param name="name">The name of the list.</param>
-        /// <param name="username">The username.</param>
+        /// <param name="name">The name.</param>
         /// <param name="options">The options.</param>
-        public CreateListCommand(OAuthTokens requestTokens, string name, string username, OptionalProperties options)
-            : base(HTTPVerb.POST, string.Format(CultureInfo.CurrentCulture, "{0}/lists.json", username), requestTokens, options)
+        /// <remarks></remarks>
+        public CreateListCommand(OAuthTokens requestTokens, string name, OptionalProperties options)
+            : base(HTTPVerb.POST, "lists/create.json", requestTokens, options)
         {
             if (Tokens == null)
             {
@@ -66,11 +68,6 @@ namespace Twitterizer.Commands
                 throw new ArgumentNullException("name");
             }
 
-            if (string.IsNullOrEmpty(username))
-            {
-                throw new ArgumentNullException("username");
-            }
-
             this.Name = name;
         }
         
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/CreateListMembershipCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/CreateListMembershipCommand.cs
new file mode 100644
index 0000000..7297e38
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/CreateListMembershipCommand.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Twitterizer.Core;
+
+namespace Twitterizer.Commands
+{
+    internal class CreateListMembershipCommand : TwitterCommand<TwitterList>
+    {
+        private decimal listId;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CreateListMembershipCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="listId">The list id.</param>
+        /// <param name="options">The options.</param>
+        public CreateListMembershipCommand(OAuthTokens tokens, decimal listId, OptionalProperties options)
+            : base(HTTPVerb.POST, "/lists/subscribers/create.json", tokens, options)
+        {
+            if (tokens == null || !tokens.HasBothTokens)
+            {
+                throw new ArgumentNullException("tokens");
+            }
+
+            if (listId <= 0)
+            {
+                throw new ArgumentNullException("listId");
+            }
+
+            this.listId = listId;
+        }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+            this.RequestParameters.Add("list_id", this.listId.ToString());
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/DeleteListCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/DeleteListCommand.cs
index 233cd80..6d0a50b 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/DeleteListCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/DeleteListCommand.cs
@@ -43,7 +43,9 @@ namespace Twitterizer.Commands
     /// The create list command class
     /// </summary>
     [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class DeleteListCommand : TwitterCommand<TwitterList>
     {
         #region Constructors
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/DestroyListSubscriber.cs b/lib/Twitterizer/Twitterizer2/Methods/List/DestroyListSubscriber.cs
new file mode 100644
index 0000000..3d8f0d7
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/DestroyListSubscriber.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Twitterizer.Commands
+{
+    [Core.AuthorizedCommand]
+    internal class DestroyListSubscriber : Core.TwitterCommand<TwitterList>
+    {
+        /// <summary>
+        /// Gets or sets the list id.
+        /// </summary>
+        /// <value>The list id.</value>
+        /// <remarks></remarks>
+        public decimal ListId { get; set; }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DestroyListSubscriber"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="listId">The list id.</param>
+        /// <param name="options">The options.</param>
+        /// <remarks></remarks>
+        public DestroyListSubscriber(OAuthTokens tokens, decimal listId, OptionalProperties options)
+            : base(HTTPVerb.POST, "lists/subscribers/destroy.json", tokens, options)
+        {
+            this.ListId = listId;
+        }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        /// <remarks></remarks>
+        public override void Init()
+        {
+            this.RequestParameters.Add("list_id", this.ListId.ToString());
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/GetListCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/GetListCommand.cs
index 55f087f..cbf8a97 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/GetListCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/GetListCommand.cs
@@ -42,20 +42,24 @@ namespace Twitterizer.Commands
     /// <summary>
     /// The create list command class
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class GetListCommand : TwitterCommand<TwitterList>
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="GetListCommand"/> class.
         /// </summary>
         /// <param name="requestTokens">The request tokens.</param>
-        /// <param name="username">The username.</param>
-        /// <param name="listIdOrSlug">The list id or slug.</param>
+        /// <param name="slug">The slug.</param>
+        /// <param name="listId">The list id.</param>
         /// <param name="options">The options.</param>
-        public GetListCommand(OAuthTokens requestTokens, string username, string listIdOrSlug, OptionalProperties options)
+        /// <exception cref="System.ArgumentNullException"></exception>
+        /// <exception cref="System.ArgumentException"></exception>
+        public GetListCommand(OAuthTokens requestTokens, string slug, decimal listId, OptionalProperties options)
             : base(
                 HTTPVerb.GET, 
-                string.Format(CultureInfo.CurrentCulture, "{0}/lists/{1}.json", username, listIdOrSlug), 
+                "lists/show.json", 
                 requestTokens, 
                 options)
         {
@@ -64,22 +68,41 @@ namespace Twitterizer.Commands
                 throw new ArgumentNullException("requestTokens");
             }
 
-            if (string.IsNullOrEmpty(username))
+            if (!string.IsNullOrEmpty(slug) ^ listId > 0)
             {
-                throw new ArgumentNullException("username");
+                throw new ArgumentException("You must supply a list id number or slug, but not both.");
             }
 
-            if (string.IsNullOrEmpty(listIdOrSlug))
-            {
-                throw new ArgumentNullException("listIdOrSlug");
-            }
+            this.ListId = listId;
+            this.Slug = slug;
         }
 
         /// <summary>
+        /// Gets or sets the list id.
+        /// </summary>
+        /// <value>The list id.</value>
+        public decimal ListId { get; set; }
+
+        /// <summary>
+        /// Gets or sets the slug.
+        /// </summary>
+        /// <value>The slug.</value>
+        public string Slug { get; set; }
+
+        /// <summary>
         /// Initializes the command.
         /// </summary>
         public override void Init()
         {
+            if (ListId > 0)
+            {
+                this.RequestParameters.Add("list_id", this.ListId.ToString(CultureInfo.InvariantCulture));
+            }
+
+            if (!string.IsNullOrEmpty(this.Slug))
+            {
+                this.RequestParameters.Add("slug", this.Slug);
+            }
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/GetListMembersCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/GetListMembersCommand.cs
index 25c9d8d..884a40d 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/GetListMembersCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/GetListMembersCommand.cs
@@ -42,7 +42,7 @@ namespace Twitterizer.Commands
     /// Returns the members of the specified list.
     /// </summary>
     [AuthorizedCommand]
-    internal class GetListMembersCommand : CursorPagedCommand<TwitterUserCollection>
+    internal class GetListMembersCommand : TwitterCommand<TwitterUserCollection>
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="GetListsCommand"/> class.
@@ -69,51 +69,24 @@ namespace Twitterizer.Commands
                 throw new ArgumentNullException("listIdOrSlug");
             }
 
-            this.ListIdOrSlug = listIdOrSlug;
-            this.Username = username;
-
             this.DeserializationHandler = TwitterUserCollection.DeserializeWrapper;
         }
 
         /// <summary>
-        /// Gets or sets the username.
-        /// </summary>
-        /// <value>The username.</value>
-        public string Username { get; set; }
-
-        /// <summary>
-        /// Gets or sets the list id.
-        /// </summary>
-        /// <value>The list id.</value>
-        public string ListIdOrSlug { get; set; }
-
-        /// <summary>
         /// Initializes the command.
         /// </summary>
         public override void Init()
         {
-            if (this.Cursor <= 0)
+            GetListMembersOptions options = this.OptionalProperties as GetListMembersOptions;
+
+            if (options == null || options.Cursor == 0)
             {
-                this.Cursor = -1;
+                this.RequestParameters.Add("cursor", "-1");
+            }
+            else
+            {
+                this.RequestParameters.Add("cursor", options.Cursor.ToString(CultureInfo.InvariantCulture));
             }
-
-            this.RequestParameters.Add("cursor", this.Cursor.ToString(CultureInfo.InvariantCulture));
-        }
-
-        /// <summary>
-        /// Clones this instance.
-        /// </summary>
-        /// <returns>
-        /// A new instance of the <see cref="Twitterizer.Core.PagedCommand{T}"/> interface.
-        /// </returns>
-        internal override TwitterCommand<TwitterUserCollection> Clone()
-        {
-            GetListMembersCommand command = new GetListMembersCommand(this.Tokens, this.Username, this.ListIdOrSlug, this.OptionalProperties as GetListMembersOptions);
-
-            if (command != null && this.OptionalProperties != null && this.OptionalProperties is GetListMembersOptions)
-                command.Cursor = ((GetListMembersOptions)this.OptionalProperties).Cursor;
-
-            return command;
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/GetListMembersOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/List/GetListMembersOptions.cs
index 56e2f35..9828e0f 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/GetListMembersOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/GetListMembersOptions.cs
@@ -33,6 +33,9 @@
 //-----------------------------------------------------------------------
 namespace Twitterizer
 {
+    /// <summary>
+    /// Provides optional parameters for the <see cref="Twitterizer.TwitterList.GetMembers(Twitterizer.OAuthTokens, string, string, Twitterizer.GetListMembersOptions)"/> method.
+    /// </summary>
     public class GetListMembersOptions : OptionalProperties
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/GetListSubscriptionsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/GetListSubscriptionsCommand.cs
index b841b16..43604dc 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/GetListSubscriptionsCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/GetListSubscriptionsCommand.cs
@@ -43,14 +43,16 @@ namespace Twitterizer.Commands
     /// The create list command class
     /// </summary>
     [AuthorizedCommandAttribute]
-    internal sealed class GetListSubscriptionsCommand : CursorPagedCommand<TwitterListCollection>
+    internal sealed class GetListSubscriptionsCommand : TwitterCommand<TwitterListCollection>
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="GetListSubscriptionsCommand"/> class.
         /// </summary>
         /// <param name="requestTokens">The request tokens.</param>
+        /// <param name="userName">Name of the user.</param>
         /// <param name="options">The options.</param>
-        public GetListSubscriptionsCommand(OAuthTokens requestTokens, string userName, OptionalProperties options)
+        /// <remarks></remarks>
+        public GetListSubscriptionsCommand(OAuthTokens requestTokens, string userName, GetListSubscriptionsOptions options)
             : base(HTTPVerb.GET, string.Format("{0}/lists/subscriptions.json", userName), requestTokens, options)
         {
             if (requestTokens == null)
@@ -58,42 +60,22 @@ namespace Twitterizer.Commands
                 throw new ArgumentNullException("requestTokens");
             }
 
-            this.Username = userName;
-
             this.DeserializationHandler = TwitterListCollection.Deserialize;
         }
 
         /// <summary>
-        /// Gets or sets the username.
-        /// </summary>
-        /// <value>The username.</value>
-        public string Username { get; set; }
-
-        /// <summary>
         /// Initializes the command.
         /// </summary>
         public override void Init()
         {
-            if (this.Cursor <= 0)
+            GetListSubscriptionsOptions options = this.OptionalProperties as GetListSubscriptionsOptions;
+            if (options == null || options.Cursor <= 0)
             {
-                this.Cursor = -1;
-            }
-
-            this.RequestParameters.Add("cursor", this.Cursor.ToString(CultureInfo.CurrentCulture));
-        }
+                this.RequestParameters.Add("cursor", "-1");
 
-        /// <summary>
-        /// Clones this instance.
-        /// </summary>
-        /// <returns>
-        /// A new instance of the <see cref="Twitterizer.Core.PagedCommand{T}"/> interface.
-        /// </returns>
-        internal override TwitterCommand<TwitterListCollection> Clone()
-        {
-            return new GetListSubscriptionsCommand(this.Tokens, Username, this.OptionalProperties)
-            {
-                Cursor = this.Cursor
-            };
+            }
+            else
+                this.RequestParameters.Add("cursor", options.Cursor.ToString(CultureInfo.CurrentCulture));
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/GetListSubscriptionsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/List/GetListSubscriptionsOptions.cs
new file mode 100644
index 0000000..cc491df
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/GetListSubscriptionsOptions.cs
@@ -0,0 +1,47 @@
+//-----------------------------------------------------------------------
+// <copyright file="GetListSubscriptionsOptions.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The get list subscriptions options class</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer
+{
+    /// <summary>
+    /// The optional parameters for the <see cref="Twitterizer.Commands.GetListSubscriptionsCommand"/> class.
+    /// </summary>
+    public class GetListSubscriptionsOptions : OptionalProperties
+    {
+        /// <summary>
+        /// Gets or sets the cursor.
+        /// </summary>
+        /// <value>The cursor.</value>
+        public long Cursor { get; set; }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/GetListsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/GetListsCommand.cs
index b2e9992..2a06fb9 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/GetListsCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/GetListsCommand.cs
@@ -44,64 +44,43 @@ namespace Twitterizer.Commands
     /// <summary>
     /// The get lists command class
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
-    internal sealed class GetListsCommand : CursorPagedCommand<TwitterListCollection>
+#endif
+    internal sealed class GetListsCommand : TwitterCommand<TwitterListCollection>
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="GetListsCommand"/> class.
         /// </summary>
         /// <param name="requestTokens">The request tokens.</param>
-        /// <param name="username">The username.</param>
         /// <param name="options">The options.</param>
-        public GetListsCommand(OAuthTokens requestTokens, string username, OptionalProperties options)
-            : base(HTTPVerb.GET, string.Format(CultureInfo.CurrentCulture, "{0}/lists.json", username), requestTokens, options)
+        /// <remarks></remarks>
+        public GetListsCommand(OAuthTokens requestTokens, GetListsOptions options)
+            : base(HTTPVerb.GET, "lists.json", requestTokens, options)
         {
             if (requestTokens == null)
             {
                 throw new ArgumentNullException("requestTokens");
             }
 
-            if (string.IsNullOrEmpty(username))
-            {
-                throw new ArgumentNullException("username");
-            }
-
-            this.Username = username;
-
             this.DeserializationHandler = TwitterListCollection.Deserialize;
         }
 
         /// <summary>
-        /// Gets or sets the username.
-        /// </summary>
-        /// <value>The username.</value>
-        public string Username { get; set; }
-
-        /// <summary>
         /// Initializes the command.
         /// </summary>
         public override void Init()
         {
-            if (this.Cursor <= 0)
+            GetListsOptions options = this.OptionalProperties as GetListsOptions;
+
+            if (options == null || options.Cursor == 0)
             {
-                this.Cursor = -1;
+                this.RequestParameters.Add("cursor", "-1");
             }
-
-            this.RequestParameters.Add("cursor", this.Cursor.ToString(CultureInfo.InvariantCulture));
-        }
-
-        /// <summary>
-        /// Clones this instance.
-        /// </summary>
-        /// <returns>
-        /// A new instance of the <see cref="Twitterizer.Core.PagedCommand{T}"/> interface.
-        /// </returns>
-        internal override TwitterCommand<TwitterListCollection> Clone()
-        {
-            return new GetListsCommand(this.Tokens, this.Username, this.OptionalProperties)
+            else
             {
-                Cursor = this.Cursor
-            };
+                this.RequestParameters.Add("cursor", options.Cursor.ToString(CultureInfo.InvariantCulture));
+            }
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/GetListsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/List/GetListsOptions.cs
new file mode 100644
index 0000000..644d308
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/GetListsOptions.cs
@@ -0,0 +1,47 @@
+//-----------------------------------------------------------------------
+// <copyright file="GetListsOptions.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The get lists options class</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer
+{
+    /// <summary>
+    /// The Get Lists Options class
+    /// </summary>
+    public class GetListsOptions : OptionalProperties
+    {
+        /// <summary>
+        /// Gets or sets the cursor.
+        /// </summary>
+        /// <value>The cursor.</value>
+        public long Cursor { get; set; }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/ListMembershipsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/ListMembershipsCommand.cs
index e5ca6f5..6f6ff50 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/ListMembershipsCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/ListMembershipsCommand.cs
@@ -43,7 +43,7 @@ namespace Twitterizer.Commands
     /// The list membership command class
     /// </summary>
     [AuthorizedCommandAttribute]
-    internal sealed class ListMembershipsCommand : CursorPagedCommand<TwitterListCollection>
+    internal sealed class ListMembershipsCommand : TwitterCommand<TwitterListCollection>
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="ListMembershipsCommand"/> class.
@@ -51,7 +51,7 @@ namespace Twitterizer.Commands
         /// <param name="requestTokens">The request tokens.</param>
         /// <param name="username">The username.</param>
         /// <param name="options">The options.</param>
-        public ListMembershipsCommand(OAuthTokens requestTokens, string username, OptionalProperties options)
+        public ListMembershipsCommand(OAuthTokens requestTokens, string username, ListMembershipsOptions options)
             : base(
                 HTTPVerb.GET, 
                 string.Format("{0}/lists/memberships.json", username), 
@@ -68,42 +68,22 @@ namespace Twitterizer.Commands
                 throw new ArgumentNullException("requestTokens");
             }
 
-            this.Username = username;
-
             this.DeserializationHandler = TwitterListCollection.Deserialize;
         }
 
         /// <summary>
-        /// Gets or sets the username.
-        /// </summary>
-        /// <value>The username.</value>
-        public string Username { get; set; }
-
-        /// <summary>
         /// Initializes the command.
         /// </summary>
         public override void Init()
         {
-            if (this.Cursor <= 0)
+            ListMembershipsOptions options = this.OptionalProperties as ListMembershipsOptions;
+            if (options == null || options.Cursor <= 0)
             {
-                this.Cursor = -1;
-            }
-
-            this.RequestParameters.Add("cursor", this.Cursor.ToString(CultureInfo.InvariantCulture));
-        }
+                this.RequestParameters.Add("cursor", "-1");
 
-        /// <summary>
-        /// Clones this instance.
-        /// </summary>
-        /// <returns>
-        /// A new instance of the <see cref="Twitterizer.Core.PagedCommand{T}"/> interface.
-        /// </returns>
-        internal override TwitterCommand<TwitterListCollection> Clone()
-        {
-            return new ListMembershipsCommand(this.Tokens, this.Username, this.OptionalProperties)
-            {
-                Cursor = this.Cursor
-            };
+            }
+            else
+                this.RequestParameters.Add("cursor", options.Cursor.ToString(CultureInfo.CurrentCulture));
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/ListMembershipsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/List/ListMembershipsOptions.cs
new file mode 100644
index 0000000..5eb0ca1
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/ListMembershipsOptions.cs
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------
+// <copyright file="ListMembershipsCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The list membership command class</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer
+{
+    /// <summary>
+    /// The optional parameters for the <see cref="Twitterizer.Commands.ListMembershipsCommand"/> class
+    /// </summary>
+    public class ListMembershipsOptions : OptionalProperties
+    {
+        /// <summary>
+        /// Gets or sets the cursor.
+        /// </summary>
+        /// <value>The cursor.</value>
+        public long Cursor { get; set; }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/ListStatusesCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/ListStatusesCommand.cs
index 6452502..0fd7b4a 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/ListStatusesCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/ListStatusesCommand.cs
@@ -42,16 +42,16 @@ namespace Twitterizer.Commands
     /// <summary>
     /// The get list statuses command class
     /// </summary>
-    internal sealed class ListStatusesCommand : PagedCommand<TwitterStatusCollection>
+    internal sealed class ListStatusesCommand : TwitterCommand<TwitterStatusCollection>
     {
-        #region Constructors
         /// <summary>
         /// Initializes a new instance of the <see cref="ListStatusesCommand"/> class.
         /// </summary>
         /// <param name="requestTokens">The request tokens.</param>
         /// <param name="username">The username.</param>
-        /// <param name="listId">The list id.</param>
+        /// <param name="listIdOrSlug">The list id or slug.</param>
         /// <param name="options">The options.</param>
+        /// <remarks></remarks>
         public ListStatusesCommand(OAuthTokens requestTokens, string username, string listIdOrSlug, ListStatusesOptions options)
             : base(HTTPVerb.GET, string.Format("{0}/lists/{1}/statuses.json", username, listIdOrSlug), requestTokens, options)
         {
@@ -64,69 +64,43 @@ namespace Twitterizer.Commands
             {
                 throw new ArgumentNullException("listIdOrSlug");
             }
-
-            this.Username = username;
-            this.ListIdOrSlug = listIdOrSlug;
         }
-        #endregion
-
-        #region API Properties
-        /// <summary>
-        /// Gets the username.
-        /// </summary>
-        /// <value>The username.</value>
-        public string Username { get; private set; }
-
-        /// <summary>
-        /// Gets the list id.
-        /// </summary>
-        /// <value>The list id.</value>
-        public string ListIdOrSlug { get; private set; }
-        #endregion
-
+      
         /// <summary>
         /// Initializes the command.
         /// </summary>
         public override void Init()
         {
-            if (this.Page <= 0)
-                this.Page = 1;
-
             ListStatusesOptions options = this.OptionalProperties as ListStatusesOptions;
 
-            if (options != null)
+            if (options == null)
             {
-                if (options.SinceId > 0)
-                {
-                    this.RequestParameters.Add("since_id", options.SinceId.ToString(CultureInfo.InvariantCulture));
-                }
+                this.RequestParameters.Add("page", "1");
+
+                return;
+            }
 
-                if (options.MaxId > 0)
-                {
-                    this.RequestParameters.Add("max_id", options.MaxId.ToString(CultureInfo.InvariantCulture));
-                }
+            if (options.SinceId > 0)
+            {
+                this.RequestParameters.Add("since_id", options.SinceId.ToString(CultureInfo.InvariantCulture));
+            }
 
-                if (options.ItemsPerPage > 0)
-                {
-                    this.RequestParameters.Add("per_page", options.ItemsPerPage.ToString(CultureInfo.InvariantCulture));
-                }
+            if (options.MaxId > 0)
+            {
+                this.RequestParameters.Add("max_id", options.MaxId.ToString(CultureInfo.InvariantCulture));
+            }
 
-                if (this.Page <= 1 && options.Page > 1)
-                    this.Page = options.Page;
+            if (options.ItemsPerPage > 0)
+            {
+                this.RequestParameters.Add("per_page", options.ItemsPerPage.ToString(CultureInfo.InvariantCulture));
             }
 
-            this.RequestParameters.Add("page", this.Page.ToString(CultureInfo.InvariantCulture));
-        }
+            if (options.IncludeEntites)
+            {
+                this.RequestParameters.Add("include_entities", "true");
+            }
 
-        /// <summary>
-        /// Clones this instance.
-        /// </summary>
-        /// <returns>
-        /// A new instance of the <see cref="Twitterizer.Core.PagedCommand{T}"/> interface.
-        /// </returns>
-        internal override TwitterCommand<TwitterStatusCollection> Clone()
-        {
-            return new ListStatusesCommand(this.Tokens, this.Username, this.ListIdOrSlug, this.OptionalProperties as ListStatusesOptions);
+            this.RequestParameters.Add("page", options.Page > 0 ? options.Page.ToString(CultureInfo.InvariantCulture) : "1");
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/ListStatusesOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/List/ListStatusesOptions.cs
index 3ed1f94..a397012 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/ListStatusesOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/ListStatusesOptions.cs
@@ -37,7 +37,9 @@ namespace Twitterizer
     /// <summary>
     /// The list statuses options class. Provides a payload for the ListStatusesCommand class.
     /// </summary>
+#if !SILVERLIGHT
     [System.Serializable]
+#endif
     public sealed class ListStatusesOptions : OptionalProperties
     {
         /// <summary>
@@ -63,5 +65,11 @@ namespace Twitterizer
         /// </summary>
         /// <value>The page number.</value>
         public int Page { get; set; }
+
+        /// <summary>
+        /// Gets or sets whether to include entities in the request.
+        /// </summary>
+        /// <value>Boolean.</value>
+        public bool IncludeEntites { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/RemoveListMemberCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/RemoveListMemberCommand.cs
index 9deb54e..73f2b72 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/RemoveListMemberCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/RemoveListMemberCommand.cs
@@ -42,7 +42,9 @@ namespace Twitterizer.Commands
     /// Removes the specified member from the list. The authenticated user must be the list's owner to remove members from the list.
     /// </summary>
     [AuthorizedCommand]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal class RemoveListMemberCommand : TwitterCommand<TwitterList>
     {
         /// <summary>
@@ -53,8 +55,8 @@ namespace Twitterizer.Commands
         /// <param name="listId">The list id.</param>
         /// <param name="userId">The user id.</param>
         /// <param name="options">The options.</param>
-        public RemoveListMemberCommand(OAuthTokens requestTokens, string ownerUsername, decimal listId, decimal userId, OptionalProperties options)
-            : base(HTTPVerb.DELETE, string.Format(CultureInfo.CurrentCulture, "/{0}/{1}/members.json", ownerUsername, listId), requestTokens, options)
+        public RemoveListMemberCommand(OAuthTokens requestTokens, string ownerUsername, string listId, decimal userId, OptionalProperties options)
+            : base(HTTPVerb.DELETE, string.Format(CultureInfo.CurrentCulture, "{0}/{1}/members.json", ownerUsername, listId), requestTokens, options)
         {
             if (requestTokens == null)
             {
@@ -66,7 +68,7 @@ namespace Twitterizer.Commands
                 throw new ArgumentNullException("ownerUsername");
             }
 
-            if (listId <= 0)
+            if (string.IsNullOrEmpty(listId))
             {
                 throw new ArgumentNullException("listId");
             }
@@ -90,7 +92,7 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
-            this.RequestParameters.Add("user_id", this.UserId.ToString(CultureInfo.InvariantCulture.NumberFormat));
+            this.RequestParameters.Add("id", this.UserId.ToString(CultureInfo.InvariantCulture.NumberFormat));
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/TwitterList.cs b/lib/Twitterizer/Twitterizer2/Methods/List/TwitterList.cs
index dc38878..26d2f10 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/TwitterList.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/TwitterList.cs
@@ -36,6 +36,7 @@ namespace Twitterizer
 {
     using System;
     using System.Diagnostics;
+    using System.Runtime.Serialization;
     using Newtonsoft.Json;
     using Twitterizer.Core;
 
@@ -44,35 +45,19 @@ namespace Twitterizer
     /// </summary>
     [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
     [DebuggerDisplay("TwitterList = {FullName}")]
+#if !SILVERLIGHT
     [Serializable]
+#endif
+    [DataContract]
     public class TwitterList : TwitterObject
     {
-        #region Constructors
-        /// <summary>
-        /// Initializes a new instance of the <see cref="TwitterList"/> class.
-        /// </summary>
-        /// <param name="tokens">OAuth access tokens.</param>
-        public TwitterList(OAuthTokens tokens) 
-            : base()
-        {
-            this.Tokens = tokens;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="TwitterList"/> class.
-        /// </summary>
-        public TwitterList()
-            : base()
-        {
-        }
-        #endregion
-
         #region API properties
         /// <summary>
         /// Gets or sets the id.
         /// </summary>
         /// <value>The list id.</value>
         [JsonProperty(PropertyName = "id")]
+        [DataMember]
         public long Id { get; set; }
 
         /// <summary>
@@ -80,6 +65,7 @@ namespace Twitterizer
         /// </summary>
         /// <value>The list name.</value>
         [JsonProperty(PropertyName = "name")]
+        [DataMember]
         public string Name { get; set; }
 
         /// <summary>
@@ -87,6 +73,7 @@ namespace Twitterizer
         /// </summary>
         /// <value>The full name.</value>
         [JsonProperty(PropertyName = "full_name")]
+        [DataMember]
         public string FullName { get; set; }
 
         /// <summary>
@@ -94,6 +81,7 @@ namespace Twitterizer
         /// </summary>
         /// <value>The list slug.</value>
         [JsonProperty(PropertyName = "slug")]
+        [DataMember]
         public string Slug { get; set; }
 
         /// <summary>
@@ -101,6 +89,7 @@ namespace Twitterizer
         /// </summary>
         /// <value>The description.</value>
         [JsonProperty(PropertyName = "description")]
+        [DataMember]
         public string Description { get; set; }
 
         /// <summary>
@@ -108,6 +97,7 @@ namespace Twitterizer
         /// </summary>
         /// <value>The number of subscribers.</value>
         [JsonProperty(PropertyName = "subscriber_count")]
+        [DataMember]
         public int NumberOfSubscribers { get; set; }
 
         /// <summary>
@@ -115,6 +105,7 @@ namespace Twitterizer
         /// </summary>
         /// <value>The number of members.</value>
         [JsonProperty(PropertyName = "member_count")]
+        [DataMember]
         public int NumberOfMembers { get; set; }
 
         /// <summary>
@@ -122,6 +113,7 @@ namespace Twitterizer
         /// </summary>
         /// <value>The absolute path.</value>
         [JsonProperty(PropertyName = "uri")]
+        [DataMember]
         public string AbsolutePath { get; set; }
 
         /// <summary>
@@ -129,6 +121,7 @@ namespace Twitterizer
         /// </summary>
         /// <value>The list mode.</value>
         [JsonProperty(PropertyName = "mode")]
+        [DataMember]
         public string Mode { get; set; }
 
         /// <summary>
@@ -136,6 +129,7 @@ namespace Twitterizer
         /// </summary>
         /// <value>The owning user.</value>
         [JsonProperty(PropertyName = "user")]
+        [DataMember]
         public TwitterUser User { get; set; }
         #endregion
 
@@ -144,6 +138,7 @@ namespace Twitterizer
         /// Gets a value indicating whether this instance is public.
         /// </summary>
         /// <value><c>true</c> if this instance is public; otherwise, <c>false</c>.</value>
+        [DataMember]
         public bool IsPublic
         {
             get
@@ -163,18 +158,48 @@ namespace Twitterizer
         /// <param name="description">The description.</param>
         /// <param name="options">The options.</param>
         /// <returns>A <see cref="TwitterList"/> instance.</returns>
-        public static TwitterList New(OAuthTokens tokens, string username, string name, bool isPublic, string description, OptionalProperties options)
+        [Obsolete("The username parameter is no longer required.")]
+        public static TwitterResponse<TwitterList> New(OAuthTokens tokens, string username, string name, bool isPublic, string description, OptionalProperties options)
         {
-            Commands.CreateListCommand command = new Twitterizer.Commands.CreateListCommand(tokens, name, username, options)
+            return New(tokens, name, isPublic, description, options);
+        }
+
+        /// <summary>
+        /// Creates a new list for the authenticated user. Accounts are limited to 20 lists.
+        /// </summary>
+        /// <param name="tokens">The oauth tokens.</param>
+        /// <param name="name">The list name.</param>
+        /// <param name="isPublic">if set to <c>true</c> creates a public list.</param>
+        /// <param name="description">The description.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>A <see cref="TwitterList"/> instance.</returns>
+        public static TwitterResponse<TwitterList> New(OAuthTokens tokens, string name, bool isPublic, string description, OptionalProperties options)
+        {
+            Commands.CreateListCommand command = new Twitterizer.Commands.CreateListCommand(tokens, name, options)
             {
                 IsPublic = isPublic,
                 Description = description
             };
 
-            return Core.CommandPerformer<TwitterList>.PerformAction(command);
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
+        /// Creates a new list for the authenticated user. Accounts are limited to 20 lists.
+        /// </summary>
+        /// <param name="tokens">The oauth tokens.</param>
+        /// <param name="username">The username.</param>
+        /// <param name="name">The list name.</param>
+        /// <param name="isPublic">if set to <c>true</c> creates a public list.</param>
+        /// <param name="description">The description.</param>
+        /// <returns>A <see cref="TwitterList"/> instance.</returns>
+        /// <remarks></remarks>
+        public static TwitterResponse<TwitterList> New(OAuthTokens tokens, string username, string name, bool isPublic, string description)
+        {
+            return New(tokens, name, isPublic, description, null);
+        }
+
+         /// <summary>
         /// Updates the specified list.
         /// </summary>
         /// <param name="tokens">The oauth tokens.</param>
@@ -182,61 +207,90 @@ namespace Twitterizer
         /// <param name="listId">The list id.</param>
         /// <param name="options">The options.</param>
         /// <returns>A <see cref="TwitterList"/> instance.</returns>
-        public static TwitterList Update(OAuthTokens tokens, string username, long listId, UpdateListOptions options)
+        [Obsolete("The username parameter is no longer required.")]
+        public static TwitterResponse<TwitterList> Update(OAuthTokens tokens, string username, string listId, UpdateListOptions options)
+        {
+            return Update(tokens, listId, options);
+        }
+
+        /// <summary>
+        /// Updates the specified list.
+        /// </summary>
+        /// <param name="tokens">The oauth tokens.</param>
+        /// <param name="listId">The list id.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>A <see cref="TwitterList"/> instance.</returns>
+        /// <remarks></remarks>
+        public static TwitterResponse<TwitterList> Update(OAuthTokens tokens, string listId, UpdateListOptions options)
         {
-            Commands.UpdateListCommand command = new Twitterizer.Commands.UpdateListCommand(tokens, username, listId, options);
+            Commands.UpdateListCommand command = new Twitterizer.Commands.UpdateListCommand(tokens, listId, options);
 
-            return Core.CommandPerformer<TwitterList>.PerformAction(command);
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
         /// List the lists of the specified user. Private lists will be included if the authenticated users is the same as the user who's lists are being returned.
         /// </summary>
         /// <param name="tokens">The tokens.</param>
-        /// <param name="username">The username.</param>
         /// <param name="options">The options.</param>
         /// <returns>
         /// A <see cref="TwitterListCollection"/> instance.
         /// </returns>
-        public static TwitterListCollection GetLists(OAuthTokens tokens, string username, OptionalProperties options)
+        public static TwitterResponse<TwitterListCollection> GetLists(OAuthTokens tokens, GetListsOptions options = null)
         {
-            Commands.GetListsCommand command = new Twitterizer.Commands.GetListsCommand(tokens, username, options);
-            TwitterListCollection results = Core.CommandPerformer<TwitterListCollection>.PerformAction(command);
+            Commands.GetListsCommand command = new Twitterizer.Commands.GetListsCommand(tokens, options);
 
-            if (results != null)
-                results.Command = command;
+            return Core.CommandPerformer.PerformAction(command);
+        }
 
-            return results;
+        /// <summary>
+        /// Returns the specified list. Private lists will only be shown if the authenticated user owns the specified list.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="slug">The slug.</param>
+        /// <returns>A <see cref="TwitterList"/> instance.</returns>
+        public static TwitterResponse<TwitterList> Show(OAuthTokens tokens, string slug)
+        {
+            return Show(tokens, slug, null);
         }
 
         /// <summary>
-        /// List the lists of the specified user. Private lists will be included if the authenticated users is the same as the user who's lists are being returned.
+        /// Returns the specified list. Private lists will only be shown if the authenticated user owns the specified list.
         /// </summary>
         /// <param name="tokens">The tokens.</param>
-        /// <param name="username">The username.</param>
-        /// <returns>
-        /// A <see cref="TwitterListCollection"/> instance.
-        /// </returns>
-        public static TwitterListCollection GetLists(OAuthTokens tokens, string username)
+        /// <param name="slug">The slug.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>A <see cref="TwitterList"/> instance.</returns>
+        public static TwitterResponse<TwitterList> Show(OAuthTokens tokens, string slug, OptionalProperties options)
         {
-            return GetLists(tokens, username, null);
+            Commands.GetListCommand command = new Twitterizer.Commands.GetListCommand(tokens, slug, -1, options);
+
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
-        /// Show the specified list. Private lists will only be shown if the authenticated user owns the specified list.
+        /// Returns the specified list. Private lists will only be shown if the authenticated user owns the specified list.
         /// </summary>
         /// <param name="tokens">The tokens.</param>
-        /// <param name="username">The username.</param>
-        /// <param name="listIdOrSlug">The list id or slug.</param>
+        /// <param name="listId">The list id.</param>
+        /// <returns>A <see cref="TwitterList"/> instance.</returns>
+        public static TwitterResponse<TwitterList> Show(OAuthTokens tokens, decimal listId)
+        {
+            return Show(tokens, listId, null);
+        }
+
+        /// <summary>
+        /// Returns the specified list. Private lists will only be shown if the authenticated user owns the specified list.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="listId">The list id.</param>
         /// <param name="options">The options.</param>
-        /// <returns>
-        /// A <see cref="TwitterListCollection"/> instance.
-        /// </returns>
-        public static TwitterList GetList(OAuthTokens tokens, string username, string listIdOrSlug, OptionalProperties options)
+        /// <returns>A <see cref="TwitterList"/> instance.</returns>
+        public static TwitterResponse<TwitterList> Show(OAuthTokens tokens, decimal listId, OptionalProperties options)
         {
-            Commands.GetListCommand command = new Twitterizer.Commands.GetListCommand(tokens, username, listIdOrSlug, options);
+            Commands.GetListCommand command = new Twitterizer.Commands.GetListCommand(tokens, string.Empty, listId, options);
 
-            return Core.CommandPerformer<TwitterList>.PerformAction(command);
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -247,11 +301,11 @@ namespace Twitterizer
         /// <param name="listIdOrSlug">The list id or slug.</param>
         /// <param name="options">The options.</param>
         /// <returns>A <see cref="TwitterList"/> instance.</returns>
-        public static TwitterList Delete(OAuthTokens tokens, string username, string listIdOrSlug, OptionalProperties options)
+        public static TwitterResponse<TwitterList> Delete(OAuthTokens tokens, string username, string listIdOrSlug, OptionalProperties options)
         {
             Commands.DeleteListCommand command = new Twitterizer.Commands.DeleteListCommand(tokens, username, listIdOrSlug, options);
 
-            return Core.CommandPerformer<TwitterList>.PerformAction(command);
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -264,11 +318,11 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterStatusCollection"/> instance.
         /// </returns>
-        public static TwitterStatusCollection GetStatuses(OAuthTokens tokens, string username, string listIdOrSlug, ListStatusesOptions options)
+        public static TwitterResponse<TwitterStatusCollection> GetStatuses(OAuthTokens tokens, string username, string listIdOrSlug, ListStatusesOptions options)
         {
             Commands.ListStatusesCommand command = new Twitterizer.Commands.ListStatusesCommand(tokens, username, listIdOrSlug, options);
 
-            return Core.CommandPerformer<TwitterStatusCollection>.PerformAction(command);
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -280,14 +334,10 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterListCollection"/> instance.
         /// </returns>
-        public static TwitterListCollection GetMemberships(OAuthTokens tokens, string username, OptionalProperties options)
+        public static TwitterResponse<TwitterListCollection> GetMemberships(OAuthTokens tokens, string username, ListMembershipsOptions options)
         {
             Commands.ListMembershipsCommand command = new Twitterizer.Commands.ListMembershipsCommand(tokens, username, options);
-            TwitterListCollection result = Core.CommandPerformer<TwitterListCollection>.PerformAction(command);
-
-            result.Command = command;
-
-            return result;
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -298,7 +348,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterListCollection"/> instance.
         /// </returns>
-        public static TwitterListCollection GetMemberships(OAuthTokens tokens, string username)
+        public static TwitterResponse<TwitterListCollection> GetMemberships(OAuthTokens tokens, string username)
         {
             return GetMemberships(tokens, username, null);
         }
@@ -312,11 +362,11 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterListCollection"/> instance.
         /// </returns>
-        public static TwitterListCollection GetSubscriptions(OAuthTokens tokens, string userName, OptionalProperties options)
+        public static TwitterResponse<TwitterListCollection> GetSubscriptions(OAuthTokens tokens, string userName, GetListSubscriptionsOptions options)
         {
             Commands.GetListSubscriptionsCommand command = new Twitterizer.Commands.GetListSubscriptionsCommand(tokens, userName, options);
 
-            return Core.CommandPerformer<TwitterListCollection>.PerformAction(command);
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -327,7 +377,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterListCollection"/> instance.
         /// </returns>
-        public static TwitterListCollection GetSubscriptions(OAuthTokens tokens, string userName)
+        public static TwitterResponse<TwitterListCollection> GetSubscriptions(OAuthTokens tokens, string userName)
         {
             return GetSubscriptions(tokens, userName, null);
         }
@@ -343,14 +393,11 @@ namespace Twitterizer
         /// <returns>
         /// A collection of users as <see cref="TwitterUserCollection"/>.
         /// </returns>
-        public static TwitterUserCollection GetMembers(OAuthTokens tokens, string username, string listIdOrSlug, GetListMembersOptions options)
+        public static TwitterResponse<TwitterUserCollection> GetMembers(OAuthTokens tokens, string username, string listIdOrSlug, GetListMembersOptions options)
         {
             Commands.GetListMembersCommand command = new Twitterizer.Commands.GetListMembersCommand(tokens, username, listIdOrSlug, options);
 
-            TwitterUserCollection result = CommandPerformer<TwitterUserCollection>.PerformAction(command);
-            result.CursorPagedCommand = command;
-
-            return result;
+            return CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -358,11 +405,10 @@ namespace Twitterizer
         /// </summary>
         /// <param name="tokens">The tokens.</param>
         /// <param name="username">The username.</param>
-        /// <param name="listId">The list id.</param>
-        /// <returns>
-        /// A collection of users as <see cref="TwitterUserCollection"/>.
-        /// </returns>
-        public static TwitterUserCollection GetMembers(OAuthTokens tokens, string username, string listIdOrSlug)
+        /// <param name="listIdOrSlug">The list id or slug.</param>
+        /// <returns>A collection of users as <see cref="TwitterUserCollection"/>.</returns>
+        /// <remarks></remarks>
+        public static TwitterResponse<TwitterUserCollection> GetMembers(OAuthTokens tokens, string username, string listIdOrSlug)
         {
             return GetMembers(tokens, username, listIdOrSlug, null);
         }
@@ -378,11 +424,11 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterList"/> representing the list the user was added to, or <c>null</c>.
         /// </returns>
-        public static TwitterList AddMember(OAuthTokens tokens, string ownerUsername, decimal listId, decimal userIdToAdd, OptionalProperties options)
+        public static TwitterResponse<TwitterList> AddMember(OAuthTokens tokens, string ownerUsername, string listId, decimal userIdToAdd, OptionalProperties options)
         {
             Commands.AddListMemberCommand command = new Twitterizer.Commands.AddListMemberCommand(tokens, ownerUsername, listId, userIdToAdd, options);
 
-            return CommandPerformer<TwitterList>.PerformAction(command);
+            return CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -395,7 +441,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterList"/> representing the list the user was added to, or <c>null</c>.
         /// </returns>
-        public static TwitterList AddMember(OAuthTokens tokens, string ownerUsername, decimal listId, decimal userIdToAdd)
+        public static TwitterResponse<TwitterList> AddMember(OAuthTokens tokens, string ownerUsername, string listId, decimal userIdToAdd)
         {
             return AddMember(tokens, ownerUsername, listId, userIdToAdd, null);
         }
@@ -411,11 +457,11 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterList"/> representing the list the user was added to, or <c>null</c>.
         /// </returns>
-        public static TwitterList RemoveMember(OAuthTokens tokens, string ownerUsername, decimal listId, decimal userIdToAdd, OptionalProperties options)
+        public static TwitterResponse<TwitterList> RemoveMember(OAuthTokens tokens, string ownerUsername, string listId, decimal userIdToAdd, OptionalProperties options)
         {
             Commands.RemoveListMemberCommand command = new Twitterizer.Commands.RemoveListMemberCommand(tokens, ownerUsername, listId, userIdToAdd, options);
 
-            return CommandPerformer<TwitterList>.PerformAction(command);
+            return CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -428,7 +474,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterList"/> representing the list the user was added to, or <c>null</c>.
         /// </returns>
-        public static TwitterList RemoveMember(OAuthTokens tokens, string ownerUsername, decimal listId, decimal userIdToAdd)
+        public static TwitterResponse<TwitterList> RemoveMember(OAuthTokens tokens, string ownerUsername, string listId, decimal userIdToAdd)
         {
             return RemoveMember(tokens, ownerUsername, listId, userIdToAdd, null);
         }
@@ -444,7 +490,7 @@ namespace Twitterizer
         /// <returns>
         /// The user's details, if they are a member of the list, otherwise <c>null</c>.
         /// </returns>
-        public static TwitterUser CheckMembership(OAuthTokens tokens, string ownerUsername, decimal listId, decimal userId, OptionalProperties options)
+        public static TwitterResponse<TwitterUser> CheckMembership(OAuthTokens tokens, string ownerUsername, string listId, decimal userId, OptionalProperties options)
         {
             Commands.CheckListMembershipCommand command = new Twitterizer.Commands.CheckListMembershipCommand(
                 tokens,
@@ -453,7 +499,7 @@ namespace Twitterizer
                 userId,
                 options);
 
-            return CommandPerformer<TwitterUser>.PerformAction(command);
+            return CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -466,9 +512,49 @@ namespace Twitterizer
         /// <returns>
         /// The user's details, if they are a member of the list, otherwise <c>null</c>.
         /// </returns>
-        public static TwitterUser CheckMembership(OAuthTokens tokens, string ownerUsername, decimal listId, decimal userId)
+        public static TwitterResponse<TwitterUser> CheckMembership(OAuthTokens tokens, string ownerUsername, string listId, decimal userId)
         {
             return CheckMembership(tokens, ownerUsername, listId, userId, null);
         }
+
+        /// <summary>
+        /// Subscribes the specified tokens.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="listId">The list id.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterList> Subscribe(OAuthTokens tokens, decimal listId)
+        {
+            return Subscribe(tokens, listId, null);
+        }
+
+        /// <summary>
+        /// Subscribes the specified tokens.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="listId">The list id.</param>
+        /// <param name="optionalProperties">The optional properties.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterList> Subscribe(OAuthTokens tokens, decimal listId, OptionalProperties optionalProperties)
+        {
+            Commands.CreateListMembershipCommand command = new Commands.CreateListMembershipCommand(tokens, listId, optionalProperties);
+
+            return CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Unsubscribes the authenticated user from the specified list.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="listId">The list id.</param>
+        /// <param name="optionalProperties">The optional properties.</param>
+        /// <returns></returns>
+        /// <remarks></remarks>
+        public static TwitterResponse<TwitterList> UnSubscribe(OAuthTokens tokens, decimal listId, OptionalProperties optionalProperties)
+        {
+            Commands.DestroyListSubscriber command = new Commands.DestroyListSubscriber(tokens, listId, optionalProperties);
+
+            return CommandPerformer.PerformAction(command);
+        }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/TwitterListCollection.cs b/lib/Twitterizer/Twitterizer2/Methods/List/TwitterListCollection.cs
index 5d7efcc..eb92cd7 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/TwitterListCollection.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/TwitterListCollection.cs
@@ -42,8 +42,10 @@ namespace Twitterizer
     /// <summary>
     /// The twitter list collection class.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
-    public class TwitterListCollection : Core.TwitterCollection<TwitterList>
+#endif
+    public class TwitterListCollection : Core.TwitterCollection<TwitterList>, ITwitterObject
     {
         /// <summary>
         /// Gets or sets the next cursor.
@@ -58,51 +60,10 @@ namespace Twitterizer
         public int PreviousCursor { get; set; }
 
         /// <summary>
-        /// Gets or sets the request parameters.
-        /// </summary>
-        /// <value>The request parameters.</value>
-        public new OAuthTokens Tokens { get; set; }
-
-        /// <summary>
         /// Gets or sets information about the user's rate usage.
         /// </summary>
         /// <value>The rate limiting object.</value>
-        public new RateLimiting RateLimiting { get; set; }
-
-        /// <summary>
-        /// Gets or sets the command.
-        /// </summary>
-        /// <value>The command.</value>
-        internal Core.TwitterCommand<TwitterListCollection> Command { get; set; }
-
-        /// <summary>
-        /// Gets the next page.
-        /// </summary>
-        /// <returns>A <see cref="TwitterListCollection"/> instance.</returns>
-        /// <value>The next page.</value>
-        public TwitterListCollection NextPage()
-        {
-            CursorPagedCommand<TwitterListCollection> newCommand =
-                (CursorPagedCommand<TwitterListCollection>)this.Command.Clone();
-            newCommand.Cursor = this.NextCursor;
-
-            return CommandPerformer<TwitterListCollection>.PerformAction(newCommand);
-        }
-
-        /// <summary>
-        /// Gets the previous page.
-        /// </summary>
-        /// <returns>A <see cref="TwitterListCollection"/> instance.</returns>
-        /// <value>The previous page.</value>
-        public TwitterListCollection PreviousPage()
-        {
-            CursorPagedCommand<TwitterListCollection> newCommand =
-                (CursorPagedCommand<TwitterListCollection>)this.Command.Clone();
-            newCommand.Cursor = this.PreviousCursor;
-
-            return Core.CommandPerformer<TwitterListCollection>.PerformAction(newCommand);
-        }
-
+        public RateLimiting RateLimiting { get; set; }
 
         /// <summary>
         /// Deserializes the specified value.
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/UpdateListCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/UpdateListCommand.cs
index 0f16007..b14c82d 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/UpdateListCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/UpdateListCommand.cs
@@ -42,7 +42,9 @@ namespace Twitterizer.Commands
     /// <summary>
     /// The update list command class
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class UpdateListCommand : TwitterCommand<TwitterList>
     {
         #region Constructors
@@ -50,27 +52,22 @@ namespace Twitterizer.Commands
         /// Initializes a new instance of the <see cref="UpdateListCommand"/> class.
         /// </summary>
         /// <param name="tokens">The tokens.</param>
-        /// <param name="username">The username.</param>
-        /// <param name="id">The list id.</param>
+        /// <param name="id">The id.</param>
         /// <param name="options">The options.</param>
-        public UpdateListCommand(OAuthTokens tokens, string username, long id, UpdateListOptions options)
+        /// <remarks></remarks>
+        public UpdateListCommand(OAuthTokens tokens, string id, UpdateListOptions options)
             : base(
-                HTTPVerb.GET, 
-                string.Format(CultureInfo.CurrentCulture, "{0}/lists/{1}.json", username, id), 
+                HTTPVerb.POST,
+                "lists/update.json", 
                 tokens, 
                 options)
         {
-            if (Tokens == null)
+            if (tokens == null)
             {
-                throw new ArgumentNullException("requestTokens");
+                throw new ArgumentNullException("tokens");
             }
 
-            if (string.IsNullOrEmpty(username))
-            {
-                throw new ArgumentNullException("username");
-            }
-
-            if (id < 0)
+            if (string.IsNullOrEmpty(id))
             {
                 throw new ArgumentNullException("id");
             }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/UpdateListOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/List/UpdateListOptions.cs
index bf2e4d7..39afc63 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/UpdateListOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/UpdateListOptions.cs
@@ -37,7 +37,9 @@ namespace Twitterizer
     /// <summary>
     /// The UpdateListOptions class. Provides a payload for optional parameters for the UpdaetListCommand class.
     /// </summary>
+#if !SILVERLIGHT
     [System.Serializable]
+#endif
     public class UpdateListOptions : OptionalProperties
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Notification/NotificationFollowCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Notification/NotificationFollowCommand.cs
new file mode 100644
index 0000000..e877443
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Notification/NotificationFollowCommand.cs
@@ -0,0 +1,94 @@
+//-----------------------------------------------------------------------
+// <copyright file="NotificationFollowCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The notification follow command class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer.Commands
+{
+    using System;
+    using System.Globalization;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The notification follow command class.
+    /// </summary>
+    sealed class NotificationFollowCommand : TwitterCommand<TwitterUser>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="NotificationFollowCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userId">The user id.</param>
+        /// <param name="screenName">Name of the screen.</param>
+        /// <param name="options">The options.</param>
+        public NotificationFollowCommand(OAuthTokens tokens, decimal userId, string screenName, OptionalProperties options)
+            : base(HTTPVerb.POST, "notifications/follow.json", tokens, options)
+        {
+            if (userId <= 0 && string.IsNullOrEmpty(screenName))
+            {
+                throw new ArgumentNullException("userId", "User ID or Screen name must be supplied");
+            }
+
+            this.UserId = userId;
+            this.ScreenName = screenName;
+        }
+
+        /// <summary>
+        /// Gets or sets the user id.
+        /// </summary>
+        /// <value>The user id.</value>
+        public decimal UserId { get; set; }
+
+        /// <summary>
+        /// Gets or sets the name of the screen.
+        /// </summary>
+        /// <value>The name of the screen.</value>
+        public string ScreenName { get; set; }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+            this.RequestParameters.Add("include_entities", "true");
+
+            if (this.UserId > 0)
+            {
+                this.RequestParameters.Add("user_id", this.UserId.ToString(CultureInfo.CurrentCulture));
+            }
+
+            if (!string.IsNullOrEmpty(this.ScreenName))
+            {
+                this.RequestParameters.Add("screen_name", this.ScreenName);
+            }
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Notification/NotificationLeaveCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Notification/NotificationLeaveCommand.cs
new file mode 100644
index 0000000..a1a1fc9
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Notification/NotificationLeaveCommand.cs
@@ -0,0 +1,94 @@
+//-----------------------------------------------------------------------
+// <copyright file="NotificationLeaveCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The notification leave command class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer.Commands
+{
+    using System;
+    using System.Globalization;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The notification leave command class.
+    /// </summary>
+    sealed class NotificationLeaveCommand : TwitterCommand<TwitterUser>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="NotificationFollowCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userId">The user id.</param>
+        /// <param name="screenName">Name of the screen.</param>
+        /// <param name="options">The options.</param>
+        public NotificationLeaveCommand(OAuthTokens tokens, decimal userId, string screenName, OptionalProperties options)
+            : base(HTTPVerb.POST, "notifications/leave.json", tokens, options)
+        {
+            if (userId <= 0 && string.IsNullOrEmpty(screenName))
+            {
+                throw new ArgumentNullException("userId", "User ID or Screen name must be supplied");
+            }
+
+            this.UserId = userId;
+            this.ScreenName = screenName;
+        }
+
+        /// <summary>
+        /// Gets or sets the user id.
+        /// </summary>
+        /// <value>The user id.</value>
+        public decimal UserId { get; set; }
+
+        /// <summary>
+        /// Gets or sets the name of the screen.
+        /// </summary>
+        /// <value>The name of the screen.</value>
+        public string ScreenName { get; set; }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+            this.RequestParameters.Add("include_entities", "true");
+
+            if (this.UserId > 0)
+            {
+                this.RequestParameters.Add("user_id", this.UserId.ToString(CultureInfo.CurrentCulture));
+            }
+
+            if (!string.IsNullOrEmpty(this.ScreenName))
+            {
+                this.RequestParameters.Add("screen_name", this.ScreenName);
+            }
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Notification/TwitterNotification.cs b/lib/Twitterizer/Twitterizer2/Methods/Notification/TwitterNotification.cs
new file mode 100644
index 0000000..4cb005c
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Notification/TwitterNotification.cs
@@ -0,0 +1,141 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterNotification.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The twitter notification class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer
+{
+    /// <summary>
+    /// Provides methods to update a user's preferences on notifications. For example, whether a user will be notified on mention via SMS.
+    /// </summary>
+    public static class TwitterNotification
+    {
+        /// <summary>
+        /// Enables device notifications for updates from the specified user. Returns the specified user when successful.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userId">The user id.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterUser> Follow(OAuthTokens tokens, decimal userId, OptionalProperties options)
+        {
+            Commands.NotificationFollowCommand command = new Commands.NotificationFollowCommand(tokens, userId, string.Empty, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Enables device notifications for updates from the specified user. Returns the specified user when successful.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userId">The user id.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterUser> Follow(OAuthTokens tokens, decimal userId)
+        {
+            return Follow(tokens, userId, null);
+        }
+
+        /// <summary>
+        /// Enables device notifications for updates from the specified user. Returns the specified user when successful.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenName">The user's screen name.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterUser> Follow(OAuthTokens tokens, string screenName, OptionalProperties options)
+        {
+            Commands.NotificationFollowCommand command = new Commands.NotificationFollowCommand(tokens, 0, screenName, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Enables device notifications for updates from the specified user. Returns the specified user when successful.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenName">The user's screen name.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterUser> Follow(OAuthTokens tokens, string screenName)
+        {
+            return Follow(tokens, screenName, null);
+        }
+
+        /// <summary>
+        /// Disables notifications for updates from the specified user to the authenticating user. Returns the specified user when successful.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userId">The user id.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterUser> Leave(OAuthTokens tokens, decimal userId, OptionalProperties options)
+        {
+            Commands.NotificationLeaveCommand command = new Commands.NotificationLeaveCommand(tokens, userId, string.Empty, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Disables notifications for updates from the specified user to the authenticating user. Returns the specified user when successful.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userId">The user id.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterUser> Leave(OAuthTokens tokens, decimal userId)
+        {
+            return Follow(tokens, userId, null);
+        }
+
+        /// <summary>
+        /// Disables notifications for updates from the specified user to the authenticating user. Returns the specified user when successful.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenName">The user's screen name.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterUser> Leave(OAuthTokens tokens, string screenName, OptionalProperties options)
+        {
+            Commands.NotificationLeaveCommand command = new Commands.NotificationLeaveCommand(tokens, 0, screenName, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Disables notifications for updates from the specified user to the authenticating user. Returns the specified user when successful.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenName">The user's screen name.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterUser> Leave(OAuthTokens tokens, string screenName)
+        {
+            return Follow(tokens, screenName, null);
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/SavedSearches/CreateSavedSearchCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/SavedSearches/CreateSavedSearchCommand.cs
new file mode 100644
index 0000000..ef96e2a
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/SavedSearches/CreateSavedSearchCommand.cs
@@ -0,0 +1,89 @@
+//-----------------------------------------------------------------------
+// <copyright file="CreateSavedSearchCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>David Golden</author>
+// <summary>The create saved search command class.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer.Commands
+{
+    using System;
+    using System.Globalization;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The Create Saved Search Command class. Creates the Saved Search with the query provided as the authenticating user. Returns the saved search when successful.
+    /// </summary>
+    [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    internal sealed class CreateSavedSearchCommand : TwitterCommand<TwitterSavedSearch>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CreateSavedSearchCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="query">The query.</param>
+        /// <param name="options">The options.</param>
+        public CreateSavedSearchCommand(OAuthTokens tokens, string query, OptionalProperties options) :
+            base(HTTPVerb.POST, "saved_searches/create.json", tokens, options)
+        {
+            if (tokens == null)
+            {
+                throw new ArgumentNullException("tokens");
+            }
+
+            if (String.IsNullOrEmpty(query))
+            {
+                throw new ArgumentException("Query is required.");
+            }
+
+            this.Query = query;
+        }
+
+        /// <summary>
+        /// Gets or sets the query.
+        /// </summary>
+        /// <value>The query.</value>
+        public string Query { get; internal set; }
+
+        /// <summary>
+        /// Initializes the command.
+        /// </summary>
+        public override void Init()
+        {
+            if (!String.IsNullOrEmpty(this.Query))
+            {
+                this.RequestParameters.Add("query", this.Query.ToString(CultureInfo.InvariantCulture));
+            }
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/SavedSearches/DeleteSavedSearchCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/SavedSearches/DeleteSavedSearchCommand.cs
new file mode 100644
index 0000000..2ed59f8
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/SavedSearches/DeleteSavedSearchCommand.cs
@@ -0,0 +1,80 @@
+//-----------------------------------------------------------------------
+// <copyright file="DeleteSavedSearchCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>David Golden</author>
+// <summary>The delete saved search command class.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer.Commands
+{
+    using System;
+    using System.Globalization;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The delete saved search command class. 
+    /// Deletes the saved search specified in the ID parameter as the authenticating user. 
+    /// Returns the deleted saved search in the requested format when successful.
+    /// </summary>
+    [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    internal sealed class DeleteSavedSearchCommand : TwitterCommand<TwitterSavedSearch>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DeleteSavedSearchCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="savedsearchId">The savedsearch id.</param>
+        /// <param name="options">The options.</param>
+        /// <remarks></remarks>
+        public DeleteSavedSearchCommand(OAuthTokens tokens, decimal savedsearchId, OptionalProperties options)
+            : base(HTTPVerb.POST, string.Format(CultureInfo.InvariantCulture.NumberFormat, "saved_searches/destroy/{0}.json", savedsearchId), tokens, options)
+        {
+            if (savedsearchId <= 0)
+            {
+                throw new ArgumentException("Saved Search Id is required.");
+            }
+
+            if (tokens == null)
+            {
+                throw new ArgumentNullException("tokens");
+            }
+        }
+
+        /// <summary>
+        /// Initializes the command.
+        /// </summary>
+        public override void Init()
+        {
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/SavedSearches/SavedSearchesCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/SavedSearches/SavedSearchesCommand.cs
new file mode 100644
index 0000000..71fbe17
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/SavedSearches/SavedSearchesCommand.cs
@@ -0,0 +1,71 @@
+//-----------------------------------------------------------------------
+// <copyright file="SavedSearchesCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>David Golden</author>
+// <summary>The saved searches command class.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer.Commands
+{
+    using System;
+    using System.Globalization;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The Saved Searches Command class. Returns the saved searches collection when successful.
+    /// </summary>
+    [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    internal sealed class SavedSearchesCommand : TwitterCommand<TwitterSavedSearchCollection>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="SavedSearchesCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        public SavedSearchesCommand(OAuthTokens tokens, OptionalProperties options) :
+            base(HTTPVerb.GET, "saved_searches.json", tokens, options)
+        {
+            if (tokens == null)
+            {
+                throw new ArgumentNullException("tokens");
+            }
+        }
+
+        /// <summary>
+        /// Initializes the command.
+        /// </summary>
+        public override void Init()
+        {
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/SavedSearches/TwitterSavedSearch.cs b/lib/Twitterizer/Twitterizer2/Methods/SavedSearches/TwitterSavedSearch.cs
new file mode 100644
index 0000000..78f55ef
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/SavedSearches/TwitterSavedSearch.cs
@@ -0,0 +1,167 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterSavedSearch.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>David Golden</author>
+// <summary>The twitter saved search class.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer
+{
+    using System;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The TwitterSavedSearch class. Provides static methods for manipulating saved searches tweets.
+    /// </summary>
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    public sealed class TwitterSavedSearch : TwitterObject
+    {
+        ///// <summary>
+        ///// Prevents a default instance of the TwitterSavedSearch class from being created.
+        ///// </summary>
+        //private TwitterSavedSearch()
+        //{ 
+        //}
+
+        /// <summary>
+        /// Gets or sets the Id.
+        /// </summary>
+        /// <value>The Id of the saved search.</value>
+        public decimal Id { get; set; }
+
+        /// <summary>
+        /// Gets or sets the name.
+        /// </summary>
+        /// <value>The name of the saved search.</value>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// Gets or sets the query.
+        /// </summary>
+        /// <value>The query.</value>
+        public string Query { get; set; }
+
+        /// <summary>
+        /// Gets or sets the position.
+        /// </summary>
+        /// <value>The position.</value>
+        public int? Position { get; set; }
+
+        /// <summary>
+        /// Gets or sets the created at date time.
+        /// </summary>
+        /// <value>The created at.</value>
+        public DateTime CreatedAt { get; set; }
+
+        /// <summary>
+        /// Creates the saved search specified in the query parameter as the authenticating user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="query">The query.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>The saved search when successful.</returns>
+        public static TwitterResponse<TwitterSavedSearch> Create(OAuthTokens tokens, string query, OptionalProperties options)
+        {
+            return CommandPerformer.PerformAction(
+                new Commands.CreateSavedSearchCommand(tokens, query, options));
+        }
+
+        /// <summary>
+        /// Creates the saved search specified in the query parameter as the authenticating user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="query">The query.</param>
+        /// <returns>The saved search when successful.</returns>
+        public static TwitterResponse<TwitterSavedSearch> Create(OAuthTokens tokens, string query)
+        {
+            return Create(tokens, query, null);
+        }
+
+        /// <summary>
+        /// Deletes the saved search specified in the ID parameter as the authenticating user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="savedsearchId">The saved search id.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>The deleted saved search in the requested format when successful.</returns>
+        public static TwitterResponse<TwitterSavedSearch> Delete(OAuthTokens tokens, decimal savedsearchId, OptionalProperties options)
+        {
+            return CommandPerformer.PerformAction(
+                new Commands.DeleteSavedSearchCommand(tokens, savedsearchId, options));
+        }
+
+        /// <summary>
+        /// Deletes the saved search specified in the ID parameter as the authenticating user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="savedsearchId">The saved search id.</param>
+        /// <returns>
+        /// The deleted saved search in the requested format when successful
+        /// </returns>
+        public static TwitterResponse<TwitterSavedSearch> Delete(OAuthTokens tokens, decimal savedsearchId)
+        {
+            return Delete(tokens, savedsearchId, null);
+        }
+
+        /// <summary>
+        /// Returns the the authenticating user's saved search queries in the requested format.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>The saved searches</returns>
+        public static TwitterResponse<TwitterSavedSearchCollection> SavedSearches(OAuthTokens tokens, OptionalProperties options)
+        {
+            return CommandPerformer.PerformAction(
+                new Commands.SavedSearchesCommand(tokens, options));
+        }
+
+        /// <summary>
+        /// Returns the the authenticating user's saved search queries in the requested format.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <returns>The saved searches</returns>
+        public static TwitterResponse<TwitterSavedSearchCollection> SavedSearches(OAuthTokens tokens)
+        {
+            return SavedSearches(tokens, null);
+        }
+
+        /// <summary>
+        /// Returns the the authenticating user's saved search queries in the requested format.
+        /// </summary>
+        /// <param name="options">The options.</param>
+        /// <returns>The saved searches</returns>
+        public static TwitterResponse<TwitterSavedSearchCollection> SavedSearches(OptionalProperties options)
+        {
+            return SavedSearches(null, options);
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/SavedSearches/TwitterSavedSearchCollection.cs b/lib/Twitterizer/Twitterizer2/Methods/SavedSearches/TwitterSavedSearchCollection.cs
new file mode 100644
index 0000000..77658f2
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/SavedSearches/TwitterSavedSearchCollection.cs
@@ -0,0 +1,49 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterSavedSearchCollection.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>David Golden</author>
+// <summary>The collection of TwitterSavedSearch objects.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer
+{
+    using System;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The TwitterSavedSearchCollection class.
+    /// </summary>
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    public class TwitterSavedSearchCollection : TwitterCollection<TwitterSavedSearch>, ITwitterObject
+    {
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Search/SearchCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Search/SearchCommand.cs
index 2d33899..aa5c533 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Search/SearchCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Search/SearchCommand.cs
@@ -42,7 +42,9 @@ namespace Twitterizer.Commands
     /// <summary>
     /// The create list command class
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class SearchCommand : TwitterCommand<TwitterSearchResultCollection>
     {
         #region Constructors
@@ -55,7 +57,7 @@ namespace Twitterizer.Commands
         public SearchCommand(OAuthTokens requestTokens, string query, SearchOptions options)
             : base(HTTPVerb.GET, "search.json", requestTokens, options)
         {
-            if (string.IsNullOrEmpty(query))
+            if (string.IsNullOrEmpty(query) && options == null && string.IsNullOrEmpty(options.Locale))
             {
                 throw new ArgumentNullException("query");
             }
@@ -77,7 +79,11 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
+#if !SILVERLIGHT
             CultureInfo unitedStatesEnglishCulture = CultureInfo.GetCultureInfo("en-us");
+#else
+            CultureInfo unitedStatesEnglishCulture = CultureInfo.InvariantCulture;
+#endif
 
             this.RequestParameters.Add("q", this.Query);
 
@@ -115,7 +121,7 @@ namespace Twitterizer.Commands
 
             if (options.SinceDate > new DateTime())
             {
-                this.RequestParameters.Add("since", options.SinceDate.ToString("{0:YYYY-MM-DD}", unitedStatesEnglishCulture));
+                this.RequestParameters.Add("since", options.SinceDate.ToString("yyyy-MM-dd", unitedStatesEnglishCulture));
             }
 
             if (options.SinceId > 0)
@@ -135,7 +141,7 @@ namespace Twitterizer.Commands
 
             if (options.UntilDate > new DateTime())
             {
-                this.RequestParameters.Add("until", options.UntilDate.ToString("{0:YYYY-MM-DD}", unitedStatesEnglishCulture));
+                this.RequestParameters.Add("until", options.UntilDate.ToString("{0:yyyy-MM-dd}", unitedStatesEnglishCulture));
             }
 
             switch (options.ResultType)
@@ -150,6 +156,12 @@ namespace Twitterizer.Commands
                     this.RequestParameters.Add("result_type", "popular");
                     break;
             }
+
+            if (options.WithTwitterUserID)
+                this.RequestParameters.Add("with_twitter_user_id", "true");
+
+            if (options.IncludeEntities)
+                this.RequestParameters.Add("include_entities", "true");
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Search/SearchOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Search/SearchOptions.cs
index 1fc8dad..b2c605a 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Search/SearchOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Search/SearchOptions.cs
@@ -64,7 +64,9 @@ namespace Twitterizer
     /// <summary>
     /// The search options class. Provides a payload for optional parameters for the SearchCommand class.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public class SearchOptions : OptionalProperties
     {
         /// <summary>
@@ -144,5 +146,17 @@ namespace Twitterizer
         /// </summary>
         /// <value>The type of the result.</value>
         public SearchOptionsResultType ResultType { get; set; }
+
+        /// <summary>
+        /// Gets or sets whether to use Twitter.com user ids in the result.
+        /// </summary>
+        /// <value>The type of the result.</value>
+        public bool WithTwitterUserID { get; set; }
+
+        /// <summary>
+        /// Gets or sets whether to include some entities in the result.
+        /// </summary>
+        /// <value>The type of the result.</value>
+        public bool IncludeEntities { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Search/TwitterSearch.cs b/lib/Twitterizer/Twitterizer2/Methods/Search/TwitterSearch.cs
index 25ed53b..9be9f5e 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Search/TwitterSearch.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Search/TwitterSearch.cs
@@ -48,7 +48,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterSearchResultCollection"/> instance.
         /// </returns>
-        public static TwitterSearchResultCollection Search(string query)
+        public static TwitterResponse<TwitterSearchResultCollection> Search(string query)
         {
             return Search(query, null);
         }
@@ -61,14 +61,33 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterSearchResultCollection"/> instance.
         /// </returns>
-        public static TwitterSearchResultCollection Search(string query, SearchOptions options)
+        public static TwitterResponse<TwitterSearchResultCollection> Search(string query, SearchOptions options)
         {
-            Commands.SearchCommand command = new Twitterizer.Commands.SearchCommand(null, query, options);
+            return Search(null, query, options);
+        }
+
+        /// <summary>
+        /// Searches Twitter with the the specified query.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="query">The query.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// A <see cref="TwitterSearchResultCollection"/> instance.
+        /// </returns>
+        public static TwitterResponse<TwitterSearchResultCollection> Search(OAuthTokens tokens, string query, SearchOptions options)
+        {
+            if (options == null)
+                options = new SearchOptions();
 
-            TwitterSearchResultCollection results =
-                Core.CommandPerformer<TwitterSearchResultCollection>.PerformAction(command);
+            Commands.SearchCommand command = new Twitterizer.Commands.SearchCommand(tokens, query, options);
+
+            TwitterResponse<TwitterSearchResultCollection> results =
+                Core.CommandPerformer.PerformAction(command);
 
             return results;
         }
+
+
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Search/TwitterSearchResult.cs b/lib/Twitterizer/Twitterizer2/Methods/Search/TwitterSearchResult.cs
index 87f7a8a..65a7e91 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Search/TwitterSearchResult.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Search/TwitterSearchResult.cs
@@ -41,7 +41,9 @@ namespace Twitterizer
     /// <summary>
     /// The Twitter Search Result class.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
     public class TwitterSearchResult : Core.TwitterObject
     {
@@ -128,5 +130,14 @@ namespace Twitterizer
         /// <value>The location.</value>
         [JsonProperty(PropertyName = "location")]
         public string Location { get; set; }
+
+        /// <summary>
+        /// Gets or sets the entities.
+        /// </summary>
+        /// <value>The entities.</value>
+        [DataMember]
+        [JsonProperty(PropertyName = "entities")]
+        [JsonConverter(typeof(Entities.TwitterEntityCollection.Converter))]
+        public Entities.TwitterEntityCollection Entities { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Search/TwitterSearchResultCollection.cs b/lib/Twitterizer/Twitterizer2/Methods/Search/TwitterSearchResultCollection.cs
index e90833e..8fe1bc3 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Search/TwitterSearchResultCollection.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Search/TwitterSearchResultCollection.cs
@@ -32,6 +32,8 @@
 // <summary>The twitter search result collection class</summary>
 //-----------------------------------------------------------------------
 
+using Twitterizer.Core;
+
 namespace Twitterizer
 {
     using System;
@@ -41,8 +43,10 @@ namespace Twitterizer
     /// <summary>
     /// The Twitter Search Result Collection class
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
-    public class TwitterSearchResultCollection : Core.TwitterCollection<TwitterSearchResult>
+#endif
+    public class TwitterSearchResultCollection : Core.TwitterCollection<TwitterSearchResult>, ITwitterObject
     {
         /// <summary>
         /// Deserializes the specified value.
@@ -51,10 +55,10 @@ namespace Twitterizer
         /// <returns></returns>
         internal static TwitterSearchResultCollection Deserialize(JObject value)
         {
-            if (value == null || value.First == null || value.First.First == null)
+            if (value == null || value["results"] == null)
                 return null;
 
-            return JsonConvert.DeserializeObject<TwitterSearchResultCollection>(value.First.First.ToString());
+            return JsonConvert.DeserializeObject<TwitterSearchResultCollection>(value["results"].ToString());
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Spam/ReportSpamCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Spam/ReportSpamCommand.cs
new file mode 100644
index 0000000..fd2d5e6
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Spam/ReportSpamCommand.cs
@@ -0,0 +1,87 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterAccount.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The TwitterAccount class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer.Commands
+{
+    using System.Globalization;
+    using Twitterizer.Core;
+    using System;
+
+    internal class ReportSpamCommand : TwitterCommand<TwitterUser>
+    {
+        /// <summary>
+        /// Gets or sets the user id.
+        /// </summary>
+        /// <value>The user id.</value>
+        public decimal UserId { get; set; }
+
+        /// <summary>
+        /// Gets or sets the name of the screen.
+        /// </summary>
+        /// <value>The name of the screen.</value>
+        public string ScreenName { get; set; }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ReportSpamCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userId">The user id.</param>
+        /// <param name="screenName">Name of the screen.</param>
+        /// <param name="options">The options.</param>
+        public ReportSpamCommand(OAuthTokens tokens, decimal userId, string screenName, OptionalProperties options)
+            : base(HTTPVerb.POST, "report_spam.json", tokens, options)
+        {
+            if (string.IsNullOrEmpty(screenName) && userId <= 0)
+            {
+                throw new ArgumentException("A screen name or user id is required.");
+            }
+            this.ScreenName = screenName;
+            this.UserId = userId;
+        }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+            if (this.UserId > 0)
+            {
+                this.RequestParameters.Add("user_id", this.UserId.ToString(CultureInfo.InvariantCulture));
+            }
+            else if (!string.IsNullOrEmpty(this.ScreenName))
+            {
+                this.RequestParameters.Add("screen_name", this.ScreenName);
+            }
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Spam/TwitterSpam.cs b/lib/Twitterizer/Twitterizer2/Methods/Spam/TwitterSpam.cs
new file mode 100644
index 0000000..7e3b6b6
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Spam/TwitterSpam.cs
@@ -0,0 +1,91 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterSpam.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The TwitterSpam class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer
+{
+    /// <summary>
+    /// Provides methods for reporting users and tweets as inappropriate or spam.
+    /// </summary>
+    public class TwitterSpam
+    {
+        /// <summary>
+        /// Blocks the user and reports them for spam/abuse.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userId">The user id.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>The user details.</returns>
+        public static TwitterResponse<TwitterUser> ReportUser(OAuthTokens tokens, decimal userId, OptionalProperties options)
+        {
+            Commands.ReportSpamCommand command = new Commands.ReportSpamCommand(tokens, userId, string.Empty, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Blocks the user and reports them for spam/abuse.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userId">The user id.</param>
+        /// <returns>The user details.</returns>
+        public static TwitterResponse<TwitterUser> ReportUser(OAuthTokens tokens, decimal userId)
+        {
+            return ReportUser(tokens, userId, null);
+        }
+
+        /// <summary>
+        /// Blocks the user and reports them for spam/abuse.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenName">The user's screen name.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>The user details.</returns>
+        public static TwitterResponse<TwitterUser> ReportUser(OAuthTokens tokens, string screenName, OptionalProperties options)
+        {
+            Commands.ReportSpamCommand command = new Commands.ReportSpamCommand(tokens, 0, screenName, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Blocks the user and reports them for spam/abuse.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenName">The user's screen name.</param>
+        /// <returns>The user details.</returns>
+        public static TwitterResponse<TwitterUser> ReportUser(OAuthTokens tokens, string screenName)
+        {
+            return ReportUser(tokens, screenName);
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/FriendsTimelineCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/FriendsTimelineCommand.cs
index 1eb7cf1..762bd28 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/FriendsTimelineCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/FriendsTimelineCommand.cs
@@ -56,17 +56,15 @@ namespace Twitterizer.Commands
         #endregion
 
         /// <summary>
-        /// Clones this instance.
+        /// Inits this instance.
         /// </summary>
-        /// <returns>
-        /// A new instance of the <see cref="Twitterizer.Core.PagedCommand{T}"/> interface.
-        /// </returns>
-        internal override TwitterCommand<TwitterStatusCollection> Clone()
+        public override void Init()
         {
-            return new FriendsTimelineCommand(this.Tokens, this.OptionalProperties as TimelineOptions)
-            {
-                Page = this.Page
-            };
+            TimelineOptions options = this.OptionalProperties as TimelineOptions;
+            if (options == null)
+                options = new TimelineOptions();
+            
+            TimelineOptions.Init<TwitterStatusCollection>(this, options);
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/HomeTimelineCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/HomeTimelineCommand.cs
index 454f9bd..323fb3b 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/HomeTimelineCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/HomeTimelineCommand.cs
@@ -40,7 +40,9 @@ namespace Twitterizer.Commands
     /// <summary>
     /// The Home Timeline Command
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     [AuthorizedCommandAttribute]
     internal sealed class HomeTimelineCommand : PagedTimelineCommand<TwitterStatusCollection>
     {
@@ -59,15 +61,15 @@ namespace Twitterizer.Commands
         }
 
         /// <summary>
-        /// Clones this instance.
+        /// Inits this instance.
         /// </summary>
-        /// <returns>A cloned command object.</returns>
-        internal override Core.TwitterCommand<TwitterStatusCollection> Clone()
+        public override void Init()
         {
-            return new HomeTimelineCommand(this.Tokens, this.OptionalProperties as TimelineOptions)
-            {
-                Page = this.Page
-            };
+            TimelineOptions options = this.OptionalProperties as TimelineOptions;
+            if (options == null)
+                options = new TimelineOptions();
+
+            TimelineOptions.Init<TwitterStatusCollection>(this, options);
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/MentionsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/MentionsCommand.cs
index 3685b7e..88e64c0 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/MentionsCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/MentionsCommand.cs
@@ -42,7 +42,9 @@ namespace Twitterizer.Commands
     /// The Mentions Command class
     /// </summary>
     [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class MentionsCommand : PagedTimelineCommand<TwitterStatusCollection>
     {
         /// <summary>
@@ -58,19 +60,17 @@ namespace Twitterizer.Commands
                 throw new ArgumentNullException("tokens");
             }
         }
-        
+
         /// <summary>
-        /// Clones this instance.
+        /// Inits this instance.
         /// </summary>
-        /// <returns>
-        /// A new instance of the <see cref="Twitterizer.Core.PagedCommand{T}"/> interface.
-        /// </returns>
-        internal override TwitterCommand<TwitterStatusCollection> Clone()
+        public override void Init()
         {
-            return new MentionsCommand(this.Tokens, this.OptionalProperties as TimelineOptions)
-            {
-                Page = this.Page
-            };
+            TimelineOptions options = this.OptionalProperties as TimelineOptions;
+            if (options == null)
+                options = new TimelineOptions();
+
+            TimelineOptions.Init<TwitterStatusCollection>(this, options);
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/PagedTimelineCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/PagedTimelineCommand.cs
index 7d1381e..426da2b 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/PagedTimelineCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/PagedTimelineCommand.cs
@@ -42,8 +42,10 @@ namespace Twitterizer.Commands
     /// The Paged Timeline Command class. Provides common functionality for all of the paged timeline command classes.
     /// </summary>
     /// <typeparam name="T"></typeparam>
+#if !SILVERLIGHT
     [Serializable]
-    internal abstract class PagedTimelineCommand<T> : PagedCommand<TwitterStatusCollection>
+#endif
+    internal abstract class PagedTimelineCommand<T> : TwitterCommand<TwitterStatusCollection>
         where T : ITwitterObject
     {
         private NumberFormatInfo numberFormat = CultureInfo.InvariantCulture.NumberFormat;
@@ -68,30 +70,27 @@ namespace Twitterizer.Commands
             // Enable opt-in beta for entities
             this.RequestParameters.Add("include_entities", "true");
 
-            if (this.Page <= 0)
-                this.Page = 1;
-
             TimelineOptions options = this.OptionalProperties as TimelineOptions;
 
-            if (options != null)
+            if (options == null)
             {
-                if (options.SinceStatusId > 0)
-                    this.RequestParameters.Add("since_id", options.SinceStatusId.ToString(CultureInfo.InvariantCulture));
+                this.RequestParameters.Add("page", "1");
 
-                if (options.MaxStatusId > 0)
-                    this.RequestParameters.Add("max_id", options.MaxStatusId.ToString(CultureInfo.InvariantCulture));
+                return;
+            }
+            if (options.SinceStatusId > 0)
+                this.RequestParameters.Add("since_id", options.SinceStatusId.ToString(CultureInfo.InvariantCulture));
 
-                if (options.Count > 0)
-                    this.RequestParameters.Add("count", options.Count.ToString(CultureInfo.InvariantCulture));
+            if (options.MaxStatusId > 0)
+                this.RequestParameters.Add("max_id", options.MaxStatusId.ToString(CultureInfo.InvariantCulture));
 
-                if (this.Page <= 1 && options.Page > 1)
-                    this.Page = options.Page;
+            if (options.Count > 0)
+                this.RequestParameters.Add("count", options.Count.ToString(CultureInfo.InvariantCulture));
 
-                if (options.IncludeRetweets)
-                    this.RequestParameters.Add("include_rts", "true");
-            }
+            if (options.IncludeRetweets)
+                this.RequestParameters.Add("include_rts", "true");
 
-            this.RequestParameters.Add("page", this.Page.ToString(CultureInfo.InvariantCulture));
+            this.RequestParameters.Add("page", options.Page > 0 ? options.Page.ToString(CultureInfo.InvariantCulture) : "1");
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/PublicTimelineCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/PublicTimelineCommand.cs
index 23a71c5..5ef29c0 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/PublicTimelineCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/PublicTimelineCommand.cs
@@ -39,7 +39,9 @@ namespace Twitterizer.Commands
     /// <summary>
     /// The Public Timeline Command class
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class PublicTimelineCommand :
         Core.TwitterCommand<TwitterStatusCollection>
     {
@@ -48,8 +50,9 @@ namespace Twitterizer.Commands
         /// Initializes a new instance of the <see cref="PublicTimelineCommand"/> class.
         /// </summary>
         /// <param name="tokens">The request tokens.</param>
-        public PublicTimelineCommand(OAuthTokens tokens)
-            : base(HTTPVerb.GET, "statuses/public_timeline.json", tokens, null)
+        /// <param name="options">The options.</param>
+        public PublicTimelineCommand(OAuthTokens tokens, OptionalProperties options)
+            : base(HTTPVerb.GET, "statuses/public_timeline.json", tokens, options)
         {
         }
         #endregion
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/RetweetedByMeCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/RetweetedByMeCommand.cs
index 20d1d90..04c1060 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/RetweetedByMeCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/RetweetedByMeCommand.cs
@@ -42,7 +42,7 @@ namespace Twitterizer.Commands
     /// The Retweeted By Me Command.
     /// </summary>
     [AuthorizedCommandAttribute]
-    internal sealed class RetweetedByMeCommand : PagedCommand<TwitterStatusCollection>
+    internal sealed class RetweetedByMeCommand : TwitterCommand<TwitterStatusCollection>
     {
         #region Constructors
         /// <summary>
@@ -65,37 +65,24 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
-            if (this.Page <= 0)
-                this.Page = 1;
-
             TimelineOptions options = this.OptionalProperties as TimelineOptions;
-            if (options != null)
+            if (options == null)
             {
-                if (options.SinceStatusId > 0)
-                    this.RequestParameters.Add("since_id", options.SinceStatusId.ToString(CultureInfo.InvariantCulture));
+                this.RequestParameters.Add("page", "1");
 
-                if (options.MaxStatusId > 0)
-                    this.RequestParameters.Add("max_id", options.MaxStatusId.ToString(CultureInfo.InvariantCulture));
+                return;
+            }
 
-                if (options.Count > 0)
-                    this.RequestParameters.Add("count", options.Count.ToString(CultureInfo.InvariantCulture));
+            if (options.SinceStatusId > 0)
+                this.RequestParameters.Add("since_id", options.SinceStatusId.ToString(CultureInfo.InvariantCulture));
 
-                if (this.Page <= 1 && options.Page > 1)
-                    this.Page = options.Page;
-            }
+            if (options.MaxStatusId > 0)
+                this.RequestParameters.Add("max_id", options.MaxStatusId.ToString(CultureInfo.InvariantCulture));
 
-            this.RequestParameters.Add("page", this.Page.ToString(CultureInfo.InvariantCulture));
-        }
+            if (options.Count > 0)
+                this.RequestParameters.Add("count", options.Count.ToString(CultureInfo.InvariantCulture));
 
-        /// <summary>
-        /// Clones this instance.
-        /// </summary>
-        /// <returns>
-        /// A new instance of the <see cref="Twitterizer.Core.PagedCommand{T}"/> interface.
-        /// </returns>
-        internal override TwitterCommand<TwitterStatusCollection> Clone()
-        {
-            return new RetweetedByMeCommand(this.Tokens, this.OptionalProperties as TimelineOptions);
+            this.RequestParameters.Add("page", options.Page > 0 ? options.Page.ToString(CultureInfo.InvariantCulture) : "1");
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/RetweetedToMeCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/RetweetedToMeCommand.cs
index c1eb381..7bae07f 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/RetweetedToMeCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/RetweetedToMeCommand.cs
@@ -42,7 +42,7 @@ namespace Twitterizer.Commands
     /// The Retweeted By Me Command.
     /// </summary>
     [AuthorizedCommandAttribute]
-    internal sealed class RetweetedToMeCommand : PagedCommand<TwitterStatusCollection>
+    internal sealed class RetweetedToMeCommand : TwitterCommand<TwitterStatusCollection>
     {
         #region Constructors
         /// <summary>
@@ -65,38 +65,24 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
-            if (this.Page <= 0)
-                this.Page = 1;
-
             TimelineOptions options = this.OptionalProperties as TimelineOptions;
-            if (options != null)
+            if (options == null)
             {
+                this.RequestParameters.Add("page", "1");
 
-                if (options.SinceStatusId > 0)
-                    this.RequestParameters.Add("since_id", options.SinceStatusId.ToString(CultureInfo.InvariantCulture));
-
-                if (options.MaxStatusId > 0)
-                    this.RequestParameters.Add("max_id", options.MaxStatusId.ToString(CultureInfo.InvariantCulture));
-
-                if (options.Count > 0)
-                    this.RequestParameters.Add("count", options.Count.ToString(CultureInfo.InvariantCulture));
-
-                if (this.Page <= 1 && options.Page > 1)
-                    this.Page = options.Page;
+                return;
             }
 
-            this.RequestParameters.Add("page", this.Page.ToString(CultureInfo.InvariantCulture));
-        }
+            if (options.SinceStatusId > 0)
+                this.RequestParameters.Add("since_id", options.SinceStatusId.ToString(CultureInfo.InvariantCulture));
 
-        /// <summary>
-        /// Clones this instance.
-        /// </summary>
-        /// <returns>
-        /// A new instance of the <see cref="Twitterizer.Core.PagedCommand{T}"/> interface.
-        /// </returns>
-        internal override TwitterCommand<TwitterStatusCollection> Clone()
-        {
-            return new RetweetedToMeCommand(this.Tokens, this.OptionalProperties as TimelineOptions);
+            if (options.MaxStatusId > 0)
+                this.RequestParameters.Add("max_id", options.MaxStatusId.ToString(CultureInfo.InvariantCulture));
+
+            if (options.Count > 0)
+                this.RequestParameters.Add("count", options.Count.ToString(CultureInfo.InvariantCulture));
+            
+            this.RequestParameters.Add("page", options.Page > 0 ? options.Page.ToString(CultureInfo.InvariantCulture) : "1");
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/TimelineOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/TimelineOptions.cs
index 7499234..4d32825 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/TimelineOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/TimelineOptions.cs
@@ -37,7 +37,9 @@ namespace Twitterizer
     /// <summary>
     /// The timeline options class. Provides optional parameters for timeline methods.
     /// </summary>
+#if !SILVERLIGHT
     [System.Serializable]
+#endif
     public class TimelineOptions : OptionalProperties
     {
         /// <summary>
@@ -84,5 +86,37 @@ namespace Twitterizer
         /// </summary>
         /// <value><c>true</c> if [include retweets]; otherwise, <c>false</c>.</value>
         public bool IncludeRetweets { get; set; }
+
+        /// <summary>
+        /// Initializes the specified command.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="command">The command.</param>
+        /// <param name="options">The options.</param>
+        internal static void Init<T>(Core.TwitterCommand<T> command, TimelineOptions options)
+            where T : Core.ITwitterObject
+        {
+            command.RequestParameters.Add("include_entities", "true");
+
+            if (options == null)
+                options = new TimelineOptions();
+
+            if (options.Count > 0)
+                command.RequestParameters.Add("count", options.Count.ToString());
+
+            if (options.IncludeRetweets)
+                command.RequestParameters.Add("include_rts", "true");
+
+            if (options.MaxStatusId > 0)
+                command.RequestParameters.Add("max_id", options.MaxStatusId.ToString());
+
+            command.RequestParameters.Add("page", options.Page > 0 ? options.Page.ToString() : "1");
+
+            if (options.SinceStatusId > 0)
+                command.RequestParameters.Add("since_id", options.SinceStatusId.ToString());
+
+            if (options.SkipUser)
+                command.RequestParameters.Add("trim_user", "true");
+        }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/TwitterTimeline.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/TwitterTimeline.cs
index c93cb9f..43704e0 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/TwitterTimeline.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/TwitterTimeline.cs
@@ -48,75 +48,65 @@ namespace Twitterizer
         /// <param name="tokens">The tokens.</param>
         /// <param name="options">The options.</param>
         /// <returns>A collection of <see cref="TwitterStatus"/> items.</returns>
-        public static TwitterStatusCollection HomeTimeline(OAuthTokens tokens, TimelineOptions options)
+        public static TwitterResponse<TwitterStatusCollection> HomeTimeline(OAuthTokens tokens, TimelineOptions options)
         {
             Commands.HomeTimelineCommand command = new Commands.HomeTimelineCommand(tokens, options);
 
-            TwitterStatusCollection result = Core.CommandPerformer<TwitterStatusCollection>.PerformAction(command);
-
-            if (result != null)
-            {
-                result.Command = command;
-            }
-
-            return result;
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <param name="tokens">The tokens.</param>
         /// <returns>A collection of <see cref="TwitterStatus"/> items.</returns>
-        public static TwitterStatusCollection HomeTimeline(OAuthTokens tokens)
+        public static TwitterResponse<TwitterStatusCollection> HomeTimeline(OAuthTokens tokens)
         {
             return HomeTimeline(tokens, null);
         }
 
         /// <param name="options">The options.</param>
         /// <returns>A collection of <see cref="TwitterStatus"/> items.</returns>
-        public static TwitterStatusCollection HomeTimeline(TimelineOptions options)
+        public static TwitterResponse<TwitterStatusCollection> HomeTimeline(TimelineOptions options)
         {
             return HomeTimeline(null, options);
         }
 
         /// <summary>
-        /// Gets the user time line.
+        /// Returns the 20 most recent statuses posted by the authenticating user. It is also possible to request another user's timeline by using the screen_name or user_id parameter.
         /// </summary>
         /// <param name="tokens">The oauth tokens.</param>
         /// <param name="options">The options.</param>
         /// <returns>
         /// A <see cref="TwitterStatusCollection"/> instance.
         /// </returns>
-        public static TwitterStatusCollection UserTimeline(
+        public static TwitterResponse<TwitterStatusCollection> UserTimeline(
             OAuthTokens tokens,
             UserTimelineOptions options)
         {
             Commands.UserTimelineCommand command = new Commands.UserTimelineCommand(tokens, options);
 
-            TwitterStatusCollection result = Core.CommandPerformer<TwitterStatusCollection>.PerformAction(command);
-            result.Command = command;
-
-            return result;
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
-        /// Gets the user time line.
+        /// Returns the 20 most recent statuses posted by the authenticating user. It is also possible to request another user's timeline by using the screen_name or user_id parameter.
         /// </summary>
         /// <param name="tokens">The oauth tokens.</param>
         /// <returns>
         /// A <see cref="TwitterStatusCollection"/> instance.
         /// </returns>
-        public static TwitterStatusCollection UserTimeline(
+        public static TwitterResponse<TwitterStatusCollection> UserTimeline(
             OAuthTokens tokens)
         {
             return UserTimeline(tokens, null);
         }
 
         /// <summary>
-        /// Gets the user time line.
+        /// Returns the 20 most recent statuses posted by the authenticating user. It is also possible to request another user's timeline by using the screen_name or user_id parameter.
         /// </summary>
         /// <param name="options">The options.</param>
         /// <returns>
         /// A <see cref="TwitterStatusCollection"/> instance.
         /// </returns>
-        public static TwitterStatusCollection UserTimeline(
+        public static TwitterResponse<TwitterStatusCollection> UserTimeline(
             UserTimelineOptions options)
         {
             return UserTimeline(null, options);
@@ -126,22 +116,46 @@ namespace Twitterizer
         /// Gets the public timeline.
         /// </summary>
         /// <returns>A <see cref="TwitterStatusCollection"/>.</returns>
-        public static TwitterStatusCollection PublicTimeline()
+        public static TwitterResponse<TwitterStatusCollection> PublicTimeline()
         {
-            return PublicTimeline(null);
+            return PublicTimeline((OAuthTokens)null);
         }
 
         /// <summary>
-        /// Gets the public timeline.
+        /// Returns the 20 most recent statuses, including retweets if they exist, from non-protected users. The public timeline is cached for 60 seconds.
         /// </summary>
         /// <param name="tokens">The oauth tokens.</param>
         /// <returns>
         /// A <see cref="TwitterStatusCollection"/>.
         /// </returns>
-        public static TwitterStatusCollection PublicTimeline(OAuthTokens tokens)
+        public static TwitterResponse<TwitterStatusCollection> PublicTimeline(OAuthTokens tokens)
+        {
+            return PublicTimeline(tokens, null);
+        }
+
+        /// <summary>
+        /// Returns the 20 most recent statuses, including retweets if they exist, from non-protected users. The public timeline is cached for 60 seconds.
+        /// </summary>
+        /// <param name="options">The properties.</param>
+        /// <returns>
+        /// A <see cref="TwitterStatusCollection"/>.
+        /// </returns>
+        public static TwitterResponse<TwitterStatusCollection> PublicTimeline(OptionalProperties options)
         {
-            Commands.PublicTimelineCommand command = new Commands.PublicTimelineCommand(tokens);
-            TwitterStatusCollection result = CommandPerformer<TwitterStatusCollection>.PerformAction(command);
+            return PublicTimeline(null, options);
+        }
+
+        /// <summary>
+        /// Returns the 20 most recent statuses, including retweets if they exist, from non-protected users. The public timeline is cached for 60 seconds.
+        /// </summary>
+        /// <param name="tokens">The oauth tokens.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>A <see cref="TwitterStatusCollection"/>.</returns>
+        /// <remarks></remarks>
+        public static TwitterResponse<TwitterStatusCollection> PublicTimeline(OAuthTokens tokens, OptionalProperties options)
+        {
+            Commands.PublicTimelineCommand command = new Commands.PublicTimelineCommand(tokens, options);
+            TwitterResponse<TwitterStatusCollection> result = CommandPerformer.PerformAction(command);
 
             return result;
         }
@@ -151,7 +165,8 @@ namespace Twitterizer
         /// </summary>
         /// <param name="tokens">The tokens.</param>
         /// <returns>A <see cref="TwitterStatusCollection"/>.</returns>
-        public static TwitterStatusCollection FriendTimeline(OAuthTokens tokens)
+        [System.Obsolete("This method is deprecated and has been replaced by the HomeTimeline method.")]
+        public static TwitterResponse<TwitterStatusCollection> FriendTimeline(OAuthTokens tokens)
         {
             return FriendTimeline(tokens, null);
         }
@@ -162,15 +177,12 @@ namespace Twitterizer
         /// <param name="tokens">The tokens.</param>
         /// <param name="options">The options.</param>
         /// <returns>A <see cref="TwitterStatusCollection"/>.</returns>
-        public static TwitterStatusCollection FriendTimeline(OAuthTokens tokens, TimelineOptions options)
+        [System.Obsolete("This method is deprecated and has been replaced by the HomeTimeline method.")]
+        public static TwitterResponse<TwitterStatusCollection> FriendTimeline(OAuthTokens tokens, TimelineOptions options)
         {
             Commands.FriendsTimelineCommand command = new Commands.FriendsTimelineCommand(tokens, options);
-            TwitterStatusCollection result = CommandPerformer<TwitterStatusCollection>.PerformAction(command);
-
-            if (result != null)
-                result.Command = command;
 
-            return result;
+            return CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -179,9 +191,9 @@ namespace Twitterizer
         /// <param name="tokens">The tokens.</param>
         /// <param name="options">The options.</param>
         /// <returns>A <see cref="TwitterStatusCollection"/> instance.</returns>
-        public static TwitterStatusCollection RetweetsOfMe(OAuthTokens tokens, RetweetsOfMeOptions options)
+        public static TwitterResponse<TwitterStatusCollection> RetweetsOfMe(OAuthTokens tokens, RetweetsOfMeOptions options)
         {
-            return CommandPerformer<TwitterStatusCollection>.PerformAction(
+            return CommandPerformer.PerformAction(
                 new Commands.RetweetsOfMeCommand(tokens, options));
         }
 
@@ -192,7 +204,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterStatusCollection"/> instance.
         /// </returns>
-        public static TwitterStatusCollection RetweetsOfMe(OAuthTokens tokens)
+        public static TwitterResponse<TwitterStatusCollection> RetweetsOfMe(OAuthTokens tokens)
         {
             return RetweetsOfMe(tokens, null);
         }
@@ -203,9 +215,9 @@ namespace Twitterizer
         /// <param name="tokens">The tokens.</param>
         /// <param name="options">The options.</param>
         /// <returns>A <see cref="TwitterStatusCollection"/> instance.</returns>
-        public static TwitterStatusCollection RetweetedByMe(OAuthTokens tokens, TimelineOptions options)
+        public static TwitterResponse<TwitterStatusCollection> RetweetedByMe(OAuthTokens tokens, TimelineOptions options)
         {
-            return CommandPerformer<TwitterStatusCollection>.PerformAction(
+            return CommandPerformer.PerformAction(
                 new Commands.RetweetedByMeCommand(tokens, options));
         }
 
@@ -216,7 +228,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterStatusCollection"/> instance.
         /// </returns>
-        public static TwitterStatusCollection RetweetedByMe(OAuthTokens tokens)
+        public static TwitterResponse<TwitterStatusCollection> RetweetedByMe(OAuthTokens tokens)
         {
             return RetweetedByMe(tokens, null);
         }
@@ -227,9 +239,9 @@ namespace Twitterizer
         /// <param name="tokens">The tokens.</param>
         /// <param name="options">The options.</param>
         /// <returns>A <see cref="TwitterStatusCollection"/> instance.</returns>
-        public static TwitterStatusCollection RetweetedToMe(OAuthTokens tokens, TimelineOptions options)
+        public static TwitterResponse<TwitterStatusCollection> RetweetedToMe(OAuthTokens tokens, TimelineOptions options)
         {
-            return CommandPerformer<TwitterStatusCollection>.PerformAction(
+            return CommandPerformer.PerformAction(
                 new Commands.RetweetedToMeCommand(tokens, options));
         }
 
@@ -240,7 +252,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterStatusCollection"/> instance.
         /// </returns>
-        public static TwitterStatusCollection RetweetedToMe(OAuthTokens tokens)
+        public static TwitterResponse<TwitterStatusCollection> RetweetedToMe(OAuthTokens tokens)
         {
             return RetweetedToMe(tokens, null);
         }
@@ -251,15 +263,10 @@ namespace Twitterizer
         /// <param name="tokens">The tokens.</param>
         /// <param name="options">The options.</param>
         /// <returns>A <see cref="TwitterStatusCollection"/> instance.</returns>
-        public static TwitterStatusCollection Mentions(OAuthTokens tokens, TimelineOptions options)
+        public static TwitterResponse<TwitterStatusCollection> Mentions(OAuthTokens tokens, TimelineOptions options)
         {
             Commands.MentionsCommand command = new Commands.MentionsCommand(tokens, options);
-            TwitterStatusCollection results = CommandPerformer<TwitterStatusCollection>.PerformAction(command);
-
-            if (results != null)
-                results.Command = command;
-
-            return results;
+            return CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -269,7 +276,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterStatusCollection"/> instance.
         /// </returns>
-        public static TwitterStatusCollection Mentions(OAuthTokens tokens)
+        public static TwitterResponse<TwitterStatusCollection> Mentions(OAuthTokens tokens)
         {
             return Mentions(tokens, null);
         }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/UserTimelineCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/UserTimelineCommand.cs
index f2a9c4b..3846072 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/UserTimelineCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/UserTimelineCommand.cs
@@ -41,7 +41,9 @@ namespace Twitterizer.Commands
     /// <summary>
     /// The user timeline command.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class UserTimelineCommand :
         PagedTimelineCommand<TwitterStatusCollection>
     {
@@ -58,7 +60,7 @@ namespace Twitterizer.Commands
                 throw new ArgumentException("You must supply either OAuth tokens or identify a user in the TimelineOptions class.");
             }
 
-            if (options != null && string.IsNullOrEmpty(options.ScreenName) && options.UserId <= 0)
+            if (options != null && tokens == null && string.IsNullOrEmpty(options.ScreenName) && options.UserId <= 0)
             {
                 throw new ArgumentException("You must specify a user's screen name or id for unauthorized requests.");
             }
@@ -69,33 +71,17 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
-            base.Init();
-
             UserTimelineOptions options = this.OptionalProperties as UserTimelineOptions;
             if (options == null)
-            {
-                return;
-            }
+                options = new UserTimelineOptions();
 
+            TimelineOptions.Init<TwitterStatusCollection>(this, options);
+            
             if (options.UserId > 0)
                 this.RequestParameters.Add("user_id", options.UserId.ToString(CultureInfo.InvariantCulture.NumberFormat));
 
             if (!string.IsNullOrEmpty(options.ScreenName))
                 this.RequestParameters.Add("screen_name", options.ScreenName);
         }
-
-        /// <summary>
-        /// Clones this instance.
-        /// </summary>
-        /// <returns>A cloned command object.</returns>
-        internal override Core.TwitterCommand<TwitterStatusCollection> Clone()
-        {
-            return new UserTimelineCommand(
-                this.Tokens,
-                this.OptionalProperties as UserTimelineOptions)
-                {
-                    Page = this.Page
-                };
-        }
     }
 }
\ No newline at end of file
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/CurrentTrendsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/CurrentTrendsCommand.cs
deleted file mode 100644
index 01e6e2b..0000000
--- a/lib/Twitterizer/Twitterizer2/Methods/Trends/CurrentTrendsCommand.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="CurrentTrendsCommand.cs" company="Patrick 'Ricky' Smith">
-//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
-// 
-//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
-//  All rights reserved.
-//  
-//  Redistribution and use in source and binary forms, with or without modification, are 
-//  permitted provided that the following conditions are met:
-// 
-//  - Redistributions of source code must retain the above copyright notice, this list 
-//    of conditions and the following disclaimer.
-//  - 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.
-//  - Neither the name of the Twitterizer 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.
-// </copyright>
-// <author>Ricky Smith</author>
-// <summary>The current trends command class</summary>
-//-----------------------------------------------------------------------
-
-namespace Twitterizer.Commands
-{
-    using System;
-    using Twitterizer;
-    using Twitterizer.Core;
-
-    /// <summary>
-    /// The create list command class
-    /// </summary>
-    [Serializable]
-    internal sealed class CurrentTrendsCommand : TwitterCommand<TwitterTrendCollection>
-    {
-        #region Constructors
-        /// <summary>
-        /// Initializes a new instance of the <see cref="CurrentTrendsCommand"/> class.
-        /// </summary>
-        /// <param name="options">The options.</param>
-        public CurrentTrendsCommand(CurrentTrendsOptions options)
-            : base(HTTPVerb.GET, "trends/current.json", null, options)
-        {
-        }
-        #endregion
-
-        /// <summary>
-        /// Initializes the command.
-        /// </summary>
-        public override void Init()
-        {
-            CurrentTrendsOptions options = this.OptionalProperties as CurrentTrendsOptions;
-            if (options == null)
-            {
-                return;
-            }
-
-            if (options.ExcludeHashTags)
-            {
-                this.RequestParameters.Add("exclude", "hashtags");
-            }
-        }
-    }
-}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/CurrentTrendsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/CurrentTrendsOptions.cs
deleted file mode 100644
index 261ad1b..0000000
--- a/lib/Twitterizer/Twitterizer2/Methods/Trends/CurrentTrendsOptions.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="CurrentTrendsOptions.cs" company="Patrick 'Ricky' Smith">
-//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
-// 
-//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
-//  All rights reserved.
-//  
-//  Redistribution and use in source and binary forms, with or without modification, are 
-//  permitted provided that the following conditions are met:
-// 
-//  - Redistributions of source code must retain the above copyright notice, this list 
-//    of conditions and the following disclaimer.
-//  - 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.
-//  - Neither the name of the Twitterizer 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.
-// </copyright>
-// <author>Ricky Smith</author>
-// <summary>The current trends options class.</summary>
-//-----------------------------------------------------------------------
-
-namespace Twitterizer
-{
-    /// <summary>
-    /// The current trends options class. Provides a payload for optional parameters for the CurrentTrendsCommand class.
-    /// </summary>
-    [System.Serializable]
-    public class CurrentTrendsOptions : OptionalProperties
-    {
-        /// <summary>
-        /// Gets or sets a value indicating whether [exclude hash tags].
-        /// </summary>
-        /// <value><c>true</c> if [exclude hash tags]; otherwise, <c>false</c>.</value>
-        public bool ExcludeHashTags { get; set; } 
-    }
-}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/TrendsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/TrendsCommand.cs
new file mode 100644
index 0000000..8a6b86a
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/TrendsCommand.cs
@@ -0,0 +1,83 @@
+//-----------------------------------------------------------------------
+// <copyright file="TrendsCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The trends command class</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer.Commands
+{
+    using System;
+    using Twitterizer;
+    using Twitterizer.Core;
+    using System.Globalization;
+
+    /// <summary>
+    /// The create list command class
+    /// </summary>
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    internal sealed class TrendsCommand : TwitterCommand<TwitterTrendCollection>
+    {
+        #region Constructors
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TrendsCommand"/> class.
+        /// </summary>
+        /// <param name="options">The WOEID.</param>
+        /// <param name="options">The options.</param>
+        public TrendsCommand(int WOEID, TrendsOptions options)
+            : base(
+                HTTPVerb.GET,
+                string.Format(CultureInfo.InvariantCulture, "trends/{0}.json", WOEID), 
+                null, 
+                options)
+        {
+        }
+        #endregion
+
+        /// <summary>
+        /// Initializes the command.
+        /// </summary>
+        public override void Init()
+        {
+            TrendsOptions options = this.OptionalProperties as TrendsOptions;
+            if (options == null)
+            {
+                return;
+            }
+
+            if (options.ExcludeHashTags)
+            {
+                this.RequestParameters.Add("exclude", "hashtags");
+            }
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/TrendsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/TrendsOptions.cs
new file mode 100644
index 0000000..a434285
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/TrendsOptions.cs
@@ -0,0 +1,51 @@
+//-----------------------------------------------------------------------
+// <copyright file="TrendsOptions.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The trends options class.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer
+{
+    /// <summary>
+    /// The current trends options class. Provides a payload for optional parameters for the CurrentTrendsCommand class.
+    /// </summary>
+#if !SILVERLIGHT
+    [System.Serializable]
+#endif
+    public class TrendsOptions : OptionalProperties
+    {
+        /// <summary>
+        /// Gets or sets a value indicating whether [exclude hash tags].
+        /// </summary>
+        /// <value><c>true</c> if [exclude hash tags]; otherwise, <c>false</c>.</value>
+        public bool ExcludeHashTags { get; set; } 
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrend.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrend.cs
index 9af9172..701d23c 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrend.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrend.cs
@@ -41,50 +41,72 @@ namespace Twitterizer
     /// <summary>
     /// The TwitterTrend class.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
+    [DataContract]
     public class TwitterTrend : TwitterObject
     {
         /// <summary>
         /// Gets or sets the name.
         /// </summary>
         /// <value>The name of the trend.</value>
+        [DataMember]
         public string Name { get; set; }
 
         /// <summary>
         /// Gets or sets the address.
         /// </summary>
         /// <value>The address.</value>
+        [DataMember]
         public string Address { get; set; }
 
         /// <summary>
         /// Gets or sets the search query.
         /// </summary>
         /// <value>The search query.</value>
+        [DataMember]
         public string SearchQuery { get; set; }
 
         /// <summary>
-        /// Gets the current trends.
+        /// Gets or sets the promoted content value.
+        /// </summary>
+        /// <value>Promoted Content.</value>
+        [DataMember]
+        public string PromotedContent { get; set; }
+
+        /// <summary>
+        /// Gets or sets the events.
+        /// </summary>
+        /// <value>The events.</value>
+        [DataMember]
+        public string Events { get; set; }
+
+        /// <summary>
+        /// Gets the trends with the specified WOEID.
         /// </summary>
+        /// <param name="options">The WOEID.</param>
         /// <param name="options">The options.</param>
         /// <returns>
         /// A collection of <see cref="Twitterizer.TwitterTrend"/> objects.
         /// </returns>
-        public static TwitterTrendCollection Current(CurrentTrendsOptions options)
+        public static TwitterResponse<TwitterTrendCollection> Trends(int WoeID, TrendsOptions options)
         {
-            Commands.CurrentTrendsCommand command = new Twitterizer.Commands.CurrentTrendsCommand(options);
+            Commands.TrendsCommand command = new Twitterizer.Commands.TrendsCommand(WoeID, options);
 
-            return Core.CommandPerformer<TwitterTrendCollection>.PerformAction(command);
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
         /// Gets the current trends.
         /// </summary>
+        /// <param name="options">The WOEID.</param>
         /// <returns>
         /// A collection of <see cref="Twitterizer.TwitterTrend"/> objects.
         /// </returns>
-        public static TwitterTrendCollection Current()
+        public static TwitterResponse<TwitterTrendCollection> Trends(int WoeID)
         {
-            return Current(null);
+            return Trends(WoeID, null);
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendCollection.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendCollection.cs
index e792e6b..cd00fc6 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendCollection.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendCollection.cs
@@ -32,6 +32,8 @@
 // <summary>The twitter trend collection class.</summary>
 //-----------------------------------------------------------------------
 
+using Twitterizer.Core;
+
 namespace Twitterizer
 {
     using System;
@@ -41,13 +43,29 @@ namespace Twitterizer
     /// The TwitterTrendCollection class. Represents multiple <see cref="Twitterizer.TwitterTrend"/> elements.
     /// </summary>
     [JsonConverter(typeof(TwitterTrendCollection.Converter))]
+#if !SILVERLIGHT
     [Serializable]
-    public class TwitterTrendCollection : Core.TwitterCollection<TwitterTrend>
-    {
+#endif
+    public class TwitterTrendCollection : Core.TwitterCollection<TwitterTrend>, ITwitterObject
+    {        
+        [JsonProperty(PropertyName = "as_of")]
+        [JsonConverter(typeof(TwitterizerDateConverter))]
+        public DateTime AsOf { get; set; }
+
+        [JsonProperty(PropertyName = "created_at")]
+        [JsonConverter(typeof(TwitterizerDateConverter))]
+        public DateTime CreatedAt { get; set; }
+        
+        public TwitterTrendLocationCollection Locations { get; set; }
+        
         /// <summary>
         /// The Json converter class for the TwitterTrendCollection object
         /// </summary>
+#if !SILVERLIGHT
         internal class Converter : JsonConverter
+#else
+        public class Converter : JsonConverter
+#endif
         {
             /// <summary>
             /// Determines whether this instance can convert the specified object type.
@@ -80,6 +98,31 @@ namespace Twitterizer
 
                 while (reader.Read() && reader.Depth >= initialDepth)
                 {
+                    if (reader.TokenType == JsonToken.PropertyName && reader.Depth == 2)
+                    {
+                        switch ((string)reader.Value)
+                        {
+#if !SILVERLIGHT
+                            //TODO these two datetime converters don't seem to convert.
+                            case "as_of":
+                                reader.Read();
+                                var c = new TwitterizerDateConverter();
+                                result.AsOf = (DateTime)c.ReadJson(reader, typeof(DateTime), null, serializer);
+                                continue;
+
+                            case "created_at":
+                                reader.Read();
+                                var d = new TwitterizerDateConverter();
+                                result.CreatedAt = (DateTime)d.ReadJson(reader, typeof(DateTime), null, serializer);
+                                continue;
+#endif
+                            case "locations":
+                                reader.Read();
+                                var e = new TwitterTrendLocationCollection.Converter();
+                                result.Locations = (TwitterTrendLocationCollection)e.ReadJson(reader, typeof(TwitterTrendLocationCollection), null, serializer);
+                                continue;
+                        }
+                    }
                     if (reader.TokenType == JsonToken.StartObject && reader.Depth > 2)
                         result.Add(new TwitterTrend());
 
@@ -99,6 +142,14 @@ namespace Twitterizer
                                 reader.Read();
                                 result[result.Count - 1].Address = (string)reader.Value;
                                 continue;
+                            case "promoted_content":
+                                reader.Read();
+                                result[result.Count - 1].PromotedContent = (string)reader.Value;
+                                continue;
+                            case "events":
+                                reader.Read();
+                                result[result.Count - 1].Events = (string)reader.Value;
+                                continue;
                         }
                     }
                 }
@@ -114,7 +165,8 @@ namespace Twitterizer
             /// <param name="serializer">The serializer.</param>
             public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
             {
-                throw new System.NotImplementedException();
+                // TODO: Implement this.
+                // throw new System.NotImplementedException();
             }
         }
     }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendLocation.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendLocation.cs
new file mode 100644
index 0000000..14ebc67
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendLocation.cs
@@ -0,0 +1,64 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterTrendLocation.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>David Golden</author>
+// <summary>The Twitter Trend Location class</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer
+{
+    using System;
+    using System.Runtime.Serialization;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The TwitterTrendLocation class.
+    /// </summary>
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    [DataContract]
+    public class TwitterTrendLocation : TwitterObject
+    {
+        /// <summary>
+        /// Gets or sets the name.
+        /// </summary>
+        /// <value>The name of the trend.</value>
+        [DataMember]
+        public string Name { get; set; }
+
+        /// <summary>
+        /// Gets or sets the WOEID.
+        /// </summary>
+        /// <value>The WOEID of the trend.</value>
+        [DataMember]
+        public int WOEID { get; set; }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendLocationCollection.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendLocationCollection.cs
new file mode 100644
index 0000000..af8ad61
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendLocationCollection.cs
@@ -0,0 +1,126 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterTrendLocationCollection.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>David Golden</author>
+// <summary>The twitter trend location collection class.</summary>
+//-----------------------------------------------------------------------
+
+using Twitterizer.Core;
+
+namespace Twitterizer
+{
+    using System;
+    using Newtonsoft.Json;
+
+    /// <summary>
+    /// The TwitterTrendLocationCollection class. Represents multiple <see cref="Twitterizer.TwitterTrendLocation"/> elements.
+    /// </summary>
+    [JsonConverter(typeof(TwitterTrendLocationCollection.Converter))]
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    public class TwitterTrendLocationCollection : Core.TwitterCollection<TwitterTrendLocation>, ITwitterObject
+    {                
+        /// <summary>
+        /// The Json converter class for the TwitterTrendLocationCollection object
+        /// </summary>
+#if !SILVERLIGHT
+        internal class Converter : JsonConverter
+#else
+        public class Converter : JsonConverter
+#endif
+        {
+            /// <summary>
+            /// Determines whether this instance can convert the specified object type.
+            /// </summary>
+            /// <param name="objectType">Type of the object.</param>
+            /// <returns>
+            /// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
+            /// </returns>
+            public override bool CanConvert(Type objectType)
+            {
+                return objectType == typeof(TwitterTrendLocationCollection);
+            }
+
+            /// <summary>
+            /// Reads the json.
+            /// </summary>
+            /// <param name="reader">The reader.</param>
+            /// <param name="objectType">Type of the object.</param>
+            /// <param name="existingValue">The existing value.</param>
+            /// <param name="serializer">The serializer.</param>
+            /// <returns>A collection of <see cref="TwitterTrend"/> items.</returns>
+            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+            {
+                TwitterTrendLocationCollection result = existingValue as TwitterTrendLocationCollection;
+                
+                if (result == null)
+                    result = new TwitterTrendLocationCollection();
+
+                int initialDepth = reader.Depth;
+
+                while (reader.Read() && reader.Depth >= initialDepth)
+                {
+                    if (reader.TokenType == JsonToken.StartObject && reader.Depth > 2)
+                        result.Add(new TwitterTrendLocation());
+
+                    if (reader.TokenType == JsonToken.PropertyName)
+                    {
+                        switch ((string)reader.Value)
+                        {
+                            case "name":
+                                reader.Read();
+                                result[result.Count - 1].Name = (string)reader.Value;
+                                continue;
+                            case "woeid":
+                                reader.Read();
+                                result[result.Count - 1].WOEID = int.Parse(reader.Value.ToString());
+                                continue;                            
+                        }
+                    }
+                }
+
+                return result;
+            }
+
+            /// <summary>
+            /// Writes the json.
+            /// </summary>
+            /// <param name="writer">The writer.</param>
+            /// <param name="value">The value.</param>
+            /// <param name="serializer">The serializer.</param>
+            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+            {
+                // TODO: Implement this.
+                // throw new System.NotImplementedException();
+            }
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/DeleteStatusCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/DeleteStatusCommand.cs
index ee8cdbd..b290cf6 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/DeleteStatusCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/DeleteStatusCommand.cs
@@ -42,7 +42,9 @@ namespace Twitterizer.Commands
     /// The command class to delete a status update.
     /// </summary>
     [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class DeleteStatusCommand : TwitterCommand<TwitterStatus>
     {
         #region Constructors
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterEntity.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterEntity.cs
index a07f111..0ff91a5 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterEntity.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterEntity.cs
@@ -39,7 +39,9 @@ namespace Twitterizer.Entities
     /// <summary>
     /// The base class for twitter entities that describe tweet text. 
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public class TwitterEntity
     {
         /// <summary>
@@ -53,12 +55,12 @@ namespace Twitterizer.Entities
         /// Gets or sets the start index.
         /// </summary>
         /// <value>The start index.</value>
-        public long StartIndex { get; set; }
+        public int StartIndex { get; set; }
 
         /// <summary>
         /// Gets or sets the end index.
         /// </summary>
         /// <value>The end index.</value>
-        public long EndIndex { get; set; }
+        public int EndIndex { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterEntityCollection.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterEntityCollection.cs
index df763b7..ad5f4e0 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterEntityCollection.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterEntityCollection.cs
@@ -35,19 +35,29 @@
 namespace Twitterizer.Entities
 {
     using System;
+    using System.Linq;
     using System.Collections.ObjectModel;
     using Newtonsoft.Json;
+using System.Linq.Expressions;
+    using System.Reflection;
+    using System.Globalization;
 
     /// <summary>
     /// Represents multiple <see cref="Twitterizer.Entities.TwitterEntity"/> objects.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public class TwitterEntityCollection : Collection<TwitterEntity>
     {
         /// <summary>
         /// The Json converter for <see cref="TwitterEntityCollection"/> data.
         /// </summary>
+#if !SILVERLIGHT         
         internal class Converter : JsonConverter
+#else
+        public class Converter : JsonConverter
+#endif
         {
             /// <summary>
             /// Determines whether this instance can convert the specified object type.
@@ -78,98 +88,413 @@ namespace Twitterizer.Entities
                 int startDepth = reader.Depth;
                 string entityType = string.Empty;
                 TwitterEntity entity = null;
-
-                while (reader.Read() && reader.Depth >= startDepth)
+                try
                 {
-                    if (reader.TokenType == JsonToken.PropertyName && reader.Depth == startDepth + 1)
+                    while (reader.Read() && reader.Depth >= startDepth)
                     {
-                        entityType = (string)reader.Value;
-                        continue;
+                        if (reader.TokenType == JsonToken.PropertyName && reader.Depth == startDepth + 1)
+                        {
+                            entityType = (string)reader.Value;
+                            continue;
+                        }
+
+                        switch (entityType)
+                        {
+                            case "urls":
+                                if (reader.TokenType == JsonToken.StartObject)
+                                    entity = new TwitterUrlEntity();
+
+                                ReadFieldValue(reader, "url", entity, () => ((TwitterUrlEntity)entity).Url);
+                                ReadFieldValue(reader, "display_url", entity, () => ((TwitterUrlEntity)entity).DisplayUrl);
+                                ReadFieldValue(reader, "expanded_url", entity, () => ((TwitterUrlEntity)entity).ExpandedUrl);
+
+                                break;
+
+                            case "user_mentions":
+                                if (reader.TokenType == JsonToken.StartObject)
+                                    entity = new TwitterMentionEntity();
+
+                                ReadFieldValue(reader, "screen_name", entity, () => ((TwitterMentionEntity)entity).ScreenName);
+                                ReadFieldValue(reader, "name", entity, () => ((TwitterMentionEntity)entity).Name);
+                                ReadFieldValue(reader, "id", entity, () => ((TwitterMentionEntity)entity).UserId);
+
+                                break;
+
+                            case "hashtags":
+                                if (reader.TokenType == JsonToken.StartObject)
+                                    entity = new TwitterHashTagEntity();
+
+                                ReadFieldValue(reader, "text", entity, () => ((TwitterHashTagEntity)entity).Text);
+
+                                break;
+
+                            case "media":
+                                // Move to object start and parse the entity
+                                reader.Read();
+                                entity = parseMediaEntity(reader);
+
+                                break;
+
+                            default:
+                                break;
+                        }
+
+                        // Read the indicies (for all entities except Media)
+                        if (reader.TokenType == JsonToken.PropertyName && (string)reader.Value == "indices" && entity != null)
+                        {
+                            reader.Read();
+                            reader.Read();
+                            entity.StartIndex = Convert.ToInt32((long)reader.Value);
+                            reader.Read();
+                            entity.EndIndex = Convert.ToInt32((long)reader.Value);
+                        }
+
+                        if ((reader.TokenType == JsonToken.EndObject && entity != null) || entity is TwitterMediaEntity)
+                        {
+                            result.Add(entity);
+                            entity = null;
+                        }
                     }
+                }
+                catch { }
+
+                return result;
+            }
+
+            /// <summary>
+            /// Writes the JSON representation of the object.
+            /// </summary>
+            /// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter"/> to write to.</param>
+            /// <param name="value">The value.</param>
+            /// <param name="serializer">The calling serializer.</param>
+            /// <remarks>This is a best attempt to recreate the structure created by the Twitter API.</remarks>
+            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+            {
+                TwitterEntityCollection entities = (TwitterEntityCollection)value;
+
+                writer.WriteStartObject();
+                {
+                    WriteEntity(writer, entities.OfType<TwitterHashTagEntity>().ToList(), "hashtags", (w, e) =>
+                        {
+                            w.WritePropertyName("text");
+                            w.WriteValue(e.Text);
+                        });
+
+                    WriteEntity(writer, entities.OfType<TwitterMentionEntity>().ToList(), "user_mentions", (w, e) =>
+                        {
+                            w.WritePropertyName("screen_name");
+                            w.WriteValue(e.ScreenName);
+
+                            w.WritePropertyName("name");
+                            w.WriteValue(e.Name);
+
+                            w.WritePropertyName("id");
+                            w.WriteValue(e.UserId);
+                        });
 
-                    switch (entityType)
+                    WriteEntity(writer, entities.OfType<TwitterUrlEntity>().ToList(), "urls", (w, e) =>
+                        {
+                            w.WritePropertyName("url");
+                            w.WriteValue(e.Url);
+
+                            w.WritePropertyName("display_url");
+                            w.WriteValue(e.DisplayUrl);
+
+                            w.WritePropertyName("expanded_url");
+                            w.WriteValue(e.ExpandedUrl);
+                        });
+
+                    WriteEntity(writer, entities.OfType<TwitterMediaEntity>().ToList(), "media", WriteMediaEntity);
+
+                    writer.WriteEndObject();
+                }
+            }
+
+            /// <summary>
+            /// Writes the media entity.
+            /// </summary>
+            /// <param name="w">The w.</param>
+            /// <param name="e">The e.</param>
+            private static void WriteMediaEntity(JsonWriter w, TwitterMediaEntity e)
+            {
+                w.WritePropertyName("type");
+                switch (e.MediaType)
+                {
+                    case TwitterMediaEntity.MediaTypes.Unknown:
+                        w.WriteNull();
+                        break;
+                    case TwitterMediaEntity.MediaTypes.Photo:
+                        w.WriteValue("photo");
+                        break;
+                    default:
+                        break;
+                }
+
+                w.WritePropertyName("sizes");
+                w.WriteStartObject();
+                {
+                    foreach (var item in e.Sizes)
                     {
-                        case "urls":
-                            if (reader.TokenType == JsonToken.StartObject)
-                            entity = new TwitterUrlEntity();
+                        w.WritePropertyName(item.Size.ToString().ToLower());
+                        w.WriteStartObject();
+                        {
+                            w.WritePropertyName("h");
+                            w.WriteValue(item.Height);
+                            
+                            w.WritePropertyName("w");
+                            w.WriteValue(item.Width);
 
-                            if (reader.TokenType == JsonToken.PropertyName)
+                            w.WritePropertyName("resize");
+                            w.WriteValue(item.Resize == TwitterMediaEntity.MediaSize.MediaSizeResizes.Fit ? "fit" : "crop");
+                            w.WriteEndObject();
+                        }
+                    }
+                  
+                    w.WriteEndObject();
+                }
+
+                w.WritePropertyName("id");
+                w.WriteValue(e.Id);
+                
+                w.WritePropertyName("id_str");
+                w.WriteValue(e.IdString);
+
+                w.WritePropertyName("media_url");
+                w.WriteValue(e.MediaUrl);
+
+                w.WritePropertyName("media_url_https");
+                w.WriteValue(e.MediaUrlSecure);
+
+                w.WritePropertyName("url");
+                w.WriteValue(e.Url);
+
+                w.WritePropertyName("display_url");
+                w.WriteValue(e.DisplayUrl);
+
+                w.WritePropertyName("expanded_url");
+                w.WriteValue(e.ExpandedUrl);
+            }
+
+            /// <summary>
+            /// Writes an entity.
+            /// </summary>
+            /// <typeparam name="T"></typeparam>
+            /// <param name="writer">The writer.</param>
+            /// <param name="entities">The entities.</param>
+            /// <param name="entityName">Name of the entity.</param>
+            /// <param name="detailsAction">The details action.</param>
+            private static void WriteEntity<T>(JsonWriter writer, System.Collections.Generic.IList<T> entities, string entityName, Action<JsonWriter, T> detailsAction)
+                where T : TwitterEntity
+            {
+                // Note to people reading this code: Extra brackets exist to group code by json hierarchy. You're welcome.
+                writer.WritePropertyName(entityName);
+                writer.WriteStartArray();
+                {
+                    foreach (var item in entities)
+                    {
+                        writer.WriteStartObject();
+                        {
+                            writer.WritePropertyName("indices");
+                            writer.WriteStartArray();
                             {
-                                if ((string)reader.Value == "url")
-                                {
-                                    reader.Read();
-                                    ((TwitterUrlEntity)entity).Url = (string)reader.Value;
-                                }
+                                writer.WriteValue(item.StartIndex);
+                                writer.WriteValue(item.EndIndex);
+                                writer.WriteEndArray();
                             }
 
-                            break;
-                        case "user_mentions":
-                            if (reader.TokenType == JsonToken.StartObject)
-                            entity = new TwitterMentionEntity();
+                            detailsAction(writer, item);
 
-                            if (reader.TokenType == JsonToken.PropertyName)
-                            {
-                                if ((string)reader.Value == "screen_name")
-                                {
-                                    reader.Read();
-                                    ((TwitterMentionEntity)entity).ScreenName = (string)reader.Value;
-                                }
+                            writer.WriteEndObject();
+                        }
+                    }
+
+                    writer.WriteEndArray();
+                }
+            }
+
+            /// <summary>
+            /// Parses the media entity.
+            /// </summary>
+            /// <param name="reader">The reader.</param>
+            /// <returns></returns>
+            public TwitterMediaEntity parseMediaEntity(JsonReader reader)
+            {
+                try
+                {
+                    if (reader.TokenType != JsonToken.StartObject)
+                        return null;
+
+                    TwitterMediaEntity entity = new TwitterMediaEntity();
 
-                                if ((string)reader.Value == "name")
+                    int startDepth = reader.Depth;
+
+                    // Start looping through all of the child nodes
+                    while (reader.Read() && reader.Depth >= startDepth)
+                    {
+                        // If the current node isn't a property, skip it
+                        if (reader.TokenType != JsonToken.PropertyName)
+                        {
+                            continue;
+                        }
+
+                        string fieldName = reader.Value as string;
+                        if (string.IsNullOrEmpty(fieldName))
+                        {
+                            continue;
+                        }
+
+                        switch (fieldName)
+                        {
+                            case "type":
+                                entity.MediaType = string.IsNullOrEmpty((string)reader.Value) ?
+                                    TwitterMediaEntity.MediaTypes.Unknown :
+                                    TwitterMediaEntity.MediaTypes.Photo;
+                                break;
+
+                            case "sizes":
+                                entity.Sizes = new System.Collections.Generic.List<TwitterMediaEntity.MediaSize>();
+                                break;
+
+                            case "large":
+                            case "medium":
+                            case "small":
+                            case "thumb":
+                                if (reader.TokenType != JsonToken.PropertyName)
                                 {
-                                    reader.Read();
-                                    ((TwitterMentionEntity)entity).Name = (string)reader.Value;
+                                    break;
                                 }
 
-                                if ((string)reader.Value == "id")
+                                TwitterMediaEntity.MediaSize newSize = new TwitterMediaEntity.MediaSize();
+
+                                switch ((string)reader.Value)
                                 {
-                                    reader.Read();
-                                    ((TwitterMentionEntity)entity).UserId = Convert.ToDecimal(reader.Value);
+                                    case "large":
+                                        newSize.Size = TwitterMediaEntity.MediaSize.MediaSizes.Large;
+                                        break;
+                                    case "medium":
+                                        newSize.Size = TwitterMediaEntity.MediaSize.MediaSizes.Medium;
+                                        break;
+                                    case "small":
+                                        newSize.Size = TwitterMediaEntity.MediaSize.MediaSizes.Small;
+                                        break;
+                                    case "thumb":
+                                        newSize.Size = TwitterMediaEntity.MediaSize.MediaSizes.Thumb;
+                                        break;
+                                    default:
+                                        break;
                                 }
-                            }
+                                
+                                int sizeDepth = reader.Depth;
+                                // Loop through all of the properties of the size and read their values
+                                while (reader.Read() && sizeDepth < reader.Depth)
+                                {
+                                    if (reader.TokenType != JsonToken.PropertyName)
+                                    {
+                                        continue;
+                                    }
 
-                            break;
-                        case "hashtags":
-                            if (reader.TokenType == JsonToken.StartObject)
-                            entity = new TwitterHashTagEntity();
+                                    ReadFieldValue(reader, "h", newSize, () => newSize.Height);
+                                    ReadFieldValue(reader, "w", newSize, () => newSize.Width);
 
-                            if (reader.TokenType == JsonToken.PropertyName)
-                            {
-                                if ((string)reader.Value == "text")
-                                {
-                                    reader.Read();
-                                    ((TwitterHashTagEntity)entity).Text = (string)reader.Value;
+                                    if (reader.TokenType == JsonToken.PropertyName && (string)reader.Value == "resize")
+                                    {
+                                        reader.Read();
+                                        newSize.Resize = string.IsNullOrEmpty((string)reader.Value) ?
+                                            TwitterMediaEntity.MediaSize.MediaSizeResizes.Unknown : 
+                                            ((string)reader.Value == "fit" ? TwitterMediaEntity.MediaSize.MediaSizeResizes.Fit : TwitterMediaEntity.MediaSize.MediaSizeResizes.Crop);
+                                    }
                                 }
-                            }
 
-                            break;
-                        default:
-                            break;
+                                entity.Sizes.Add(newSize);
+
+                                break;
+                            case "indices":
+                                reader.Read();
+                                reader.Read();
+                                entity.StartIndex = Convert.ToInt32((long)reader.Value);
+                                reader.Read();
+                                entity.EndIndex = Convert.ToInt32((long)reader.Value);
+                                break;
+                            default:
+                                break;
+                        }
+
+                        ReadFieldValue(reader, "id", entity, () => entity.Id);
+                        ReadFieldValue(reader, "id_str", entity, () => entity.IdString);
+                        ReadFieldValue(reader, "media_url", entity, () => entity.MediaUrl);
+                        ReadFieldValue(reader, "media_url_https", entity, () => entity.MediaUrlSecure);
+                        ReadFieldValue(reader, "url", entity, () => entity.Url);
+                        ReadFieldValue(reader, "display_url", entity, () => entity.DisplayUrl);
+                        ReadFieldValue(reader, "expanded_url", entity, () => entity.ExpandedUrl);
                     }
-                    
-                    // Read the indicies (for all entities)
-                    if (reader.TokenType == JsonToken.PropertyName && (string)reader.Value == "indices")
+                    return entity;
+                }
+                catch
+                {
+                    return null;
+                }
+            }
+
+            private bool ReadFieldValue<T>(JsonReader reader, string fieldName, ref T result)
+            {
+                try
+                {
+                    if (reader.TokenType != JsonToken.PropertyName)
+                        return false;
+
+                    if ((string)reader.Value != fieldName)
+                        return false;
+
+                    reader.Read();
+
+                    if (reader.ValueType == typeof(T))
                     {
-                        reader.Read();
-                        reader.Read();
-                        entity.StartIndex = (long)reader.Value;
-                        reader.Read();
-                        entity.EndIndex = (long)reader.Value;
+                        result = (T)reader.Value;
                     }
-
-                    if (reader.TokenType == JsonToken.EndObject && entity != null)
+                    else
                     {
-                        result.Add(entity);
-                        entity = null;
+#if !SILVERLIGHT
+                        result = (T)Convert.ChangeType(reader.Value, typeof(T));
+#endif
+#if SILVERLIGHT
+                        result = (T)Convert.ChangeType(reader.Value, typeof(T), CultureInfo.InvariantCulture);
+#endif
+
                     }
-                }
 
-                return result;
+                    return true;
+                }
+                catch
+                {
+                    return false;
+                }
             }
 
-            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+            private bool ReadFieldValue<TSource, TProperty>(JsonReader reader, string fieldName, TSource source, Expression<Func<TProperty>> property)
             {
-                throw new NotImplementedException();
+                try
+                {
+                    if (reader == null || source == null)
+                    {
+                        return false;
+                    }
+
+                    var expr = (MemberExpression)property.Body;
+                    var prop = (PropertyInfo)expr.Member;
+
+                    TProperty value = (TProperty)prop.GetValue(source, null);
+                    if (ReadFieldValue<TProperty>(reader, fieldName, ref value))
+                    {
+                        prop.SetValue(source, value, null);
+                        return true;
+                    }
+
+                    return false;
+                }
+                catch
+                {
+                    return false;
+                }
             }
         }
     }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterHashTagEntity.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterHashTagEntity.cs
index 862bd49..ddafe35 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterHashTagEntity.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterHashTagEntity.cs
@@ -39,13 +39,15 @@ namespace Twitterizer.Entities
     /// <summary>
     /// Represents a pre-parsed hash tag in a <see cref="Twitterizer.TwitterStatus.Text"/> value.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public class TwitterHashTagEntity : TwitterEntity
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="TwitterHashTagEntity"/> class.
         /// </summary>
-        internal TwitterHashTagEntity()
+        public TwitterHashTagEntity()
         { 
         }
 
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterMediaEntity.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterMediaEntity.cs
new file mode 100644
index 0000000..917d4c0
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterMediaEntity.cs
@@ -0,0 +1,198 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterMediaEntity.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The twitter url entity class</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer.Entities
+{
+    using System.Collections.Generic;
+    using System;
+
+    /// <summary>
+    /// Represents a pre-parsed media entity located within the body of a <see cref="Twitterizer.TwitterStatus.Text"/>.
+    /// </summary>
+    /// <remarks></remarks>
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    public class TwitterMediaEntity : TwitterUrlEntity
+    {
+        /// <summary>
+        /// The list of currently available and supported media types.
+        /// </summary>
+        /// <remarks></remarks>
+        public enum MediaTypes
+        {
+            /// <summary>
+            /// (default) Indicates the media type returned is unsupported.
+            /// </summary>
+            Unknown,
+
+            /// <summary>
+            /// Indicates the media type returned is a photo.
+            /// </summary>
+            Photo
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TwitterMediaEntity"/> class.
+        /// </summary>
+        public TwitterMediaEntity()
+        {
+        }
+
+        /// <summary>
+        /// Gets or sets the type of the media.
+        /// </summary>
+        /// <value>The type of the media.</value>
+        /// <remarks></remarks>
+        public MediaTypes MediaType { get; set; }
+
+        /// <summary>
+        /// Gets or sets the id.
+        /// </summary>
+        /// <value>The id.</value>
+        /// <remarks></remarks>
+        public decimal Id { get; set; }
+
+        /// <summary>
+        /// Gets or sets the id string.
+        /// </summary>
+        /// <value>The id string.</value>
+        /// <remarks></remarks>
+        public string IdString { get; set; }
+
+        /// <summary>
+        /// Gets or sets the media URL.
+        /// </summary>
+        /// <value>The media URL.</value>
+        /// <remarks></remarks>
+        public string MediaUrl { get; set; }
+
+        /// <summary>
+        /// Gets or sets the media URL secure.
+        /// </summary>
+        /// <value>The media URL secure.</value>
+        /// <remarks></remarks>
+        public string MediaUrlSecure { get; set; }
+
+        /// <summary>
+        /// Gets or sets the sizes.
+        /// </summary>
+        /// <value>The sizes.</value>
+        /// <remarks></remarks>
+        public List<MediaSize> Sizes { get; set; }
+
+        /// <summary>
+        /// Represents the display size of a media entity.
+        /// </summary>
+        /// <remarks></remarks>
+        public class MediaSize
+        {
+            /// <summary>
+            /// The enumerated types of reszing that could be applied to the media entity.
+            /// </summary>
+            /// <remarks></remarks>
+            public enum MediaSizeResizes
+            {
+                /// <summary>
+                /// Indicates that the resizing method was unrecognized.
+                /// </summary>
+                Unknown,
+                /// <summary>
+                /// Indicates that the media entity was cropped.
+                /// </summary>
+                Crop,
+                /// <summary>
+                /// Indicates that the media entity was resized to fit without cropping.
+                /// </summary>
+                Fit
+            }
+
+            /// <summary>
+            /// The list of recognized media sizes.
+            /// </summary>
+            /// <remarks></remarks>
+            public enum MediaSizes
+            {
+                /// <summary>
+                /// (default) Indicates that the size provided by the API was unrecognized.
+                /// </summary>
+                Unknown,
+                /// <summary>
+                /// Indicates that the media entity is a thumbnail size.
+                /// </summary>
+                Thumb,
+                /// <summary>
+                /// Indicates that the media entity is a small size.
+                /// </summary>
+                Small,
+                /// <summary>
+                /// Indicates that the media entity is a medium size.
+                /// </summary>
+                Medium,
+                /// <summary>
+                /// Indicates that the media entity is a large size.
+                /// </summary>
+                Large
+            }
+
+            /// <summary>
+            /// Gets or sets the size.
+            /// </summary>
+            /// <value>The size.</value>
+            /// <remarks></remarks>
+            public MediaSizes Size { get; set; }
+
+            /// <summary>
+            /// Gets or sets the width.
+            /// </summary>
+            /// <value>The width.</value>
+            /// <remarks></remarks>
+            public int Width { get; set; }
+
+            /// <summary>
+            /// Gets or sets the height.
+            /// </summary>
+            /// <value>The height.</value>
+            /// <remarks></remarks>
+            public int Height { get; set; }
+
+            /// <summary>
+            /// Gets or sets the resize.
+            /// </summary>
+            /// <value>The resize.</value>
+            /// <remarks></remarks>
+            public MediaSizeResizes Resize { get; set; }
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterMentionEntity.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterMentionEntity.cs
index 726a184..5b95d92 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterMentionEntity.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterMentionEntity.cs
@@ -39,13 +39,15 @@ namespace Twitterizer.Entities
     /// <summary>
     /// Represents mention of a user within a <see cref="TwitterStatus.Text"/> value.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public class TwitterMentionEntity : TwitterEntity
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="TwitterMentionEntity"/> class.
         /// </summary>
-        internal TwitterMentionEntity()
+        public TwitterMentionEntity()
         {
         }
 
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterUrlEntity.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterUrlEntity.cs
index 759a791..23bbba6 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterUrlEntity.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterUrlEntity.cs
@@ -39,13 +39,15 @@ namespace Twitterizer.Entities
     /// <summary>
     /// Represents a pre-parsed url located within the body of a <see cref="Twitterizer.TwitterStatus.Text"/>.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public class TwitterUrlEntity : TwitterEntity
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="TwitterUrlEntity"/> class.
         /// </summary>
-        internal TwitterUrlEntity()
+        public TwitterUrlEntity()
         {
         }
 
@@ -54,5 +56,17 @@ namespace Twitterizer.Entities
         /// </summary>
         /// <value>The parsed URL.</value>
         public string Url { get; set; }
+
+        /// <summary>
+        /// Gets or sets the Display URL parsed from the tweet text.
+        /// </summary>
+        /// <value>The parsed Display URL.</value>
+        public string DisplayUrl { get; set; }
+
+        /// <summary>
+        /// Gets or sets the Expanded URL parsed from the tweet text.
+        /// </summary>
+        /// <value>The parsed Expanded URL.</value>
+        public string ExpandedUrl { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/RelatedResultsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/RelatedResultsCommand.cs
new file mode 100644
index 0000000..96f59ea
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/RelatedResultsCommand.cs
@@ -0,0 +1,83 @@
+//-----------------------------------------------------------------------
+// <copyright file="RelatedResultsCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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 SUCpH DAMAGE.
+// </copyright>
+// <author>Edgardo Vega and Ricky Smith</author>
+// <summary>The related results command.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer.Commands
+{
+    using System;
+    using System.Globalization;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The Related Results Command.
+    /// </summary>
+    [AuthorizedCommandAttribute]
+    internal sealed class RelatedResultsCommand : TwitterCommand<TwitterRelatedTweetsCollection>
+    {
+        /// <summary>
+        /// The base address to the API method.
+        /// </summary>
+        private const string Path = "related_results/show/{0}.json";
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="RelatedResultsCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The request tokens.</param>
+        /// <param name="statusId">The status id.</param>
+        /// <param name="options">The options.</param>
+        public RelatedResultsCommand(OAuthTokens tokens, decimal statusId, OptionalProperties options)
+            : base(
+                HTTPVerb.GET,
+                string.Format(CultureInfo.InvariantCulture, Path, statusId),
+                tokens,
+                options)
+        {
+            if (statusId <= 0)
+            {
+                throw new ArgumentException("Status ID is invalid", "statusId");
+            }
+
+            if (tokens == null)
+            {
+                throw new ArgumentNullException("tokens");
+            }
+        }
+
+        /// <summary>
+        /// Initializes the command.
+        /// </summary>
+        public override void Init()
+        {
+        }      
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetCommand.cs
index e669162..077e2a8 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetCommand.cs
@@ -42,7 +42,9 @@ namespace Twitterizer.Commands
     /// The retweet command class.
     /// </summary>
     [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class RetweetCommand : TwitterCommand<TwitterStatus>
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsCommand.cs
index a5a71b1..52a6fb2 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsCommand.cs
@@ -42,9 +42,17 @@ namespace Twitterizer.Commands
     /// The retweets command class.
     /// </summary>
     [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class RetweetsCommand : TwitterCommand<TwitterStatusCollection>
     {
+        /// <summary>
+        /// Gets or sets the status id.
+        /// </summary>
+        /// <value>The status id.</value>
+        public decimal StatusId { get; set; }
+
         #region Constructors
         /// <summary>
         /// Initializes a new instance of the <see cref="RetweetsCommand"/> class.
@@ -68,6 +76,8 @@ namespace Twitterizer.Commands
             {
                 throw new ArgumentNullException("statusId");
             }
+
+            this.StatusId = statusId;
         }
         #endregion
 
@@ -76,8 +86,15 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
+            this.RequestParameters.Add("id", this.StatusId.ToString(CultureInfo.InvariantCulture));
+
             RetweetsOptions options = this.OptionalProperties as RetweetsOptions;
 
+            if (options == null)
+            {
+                return;
+            }
+
             if (options.Count > 0)
                 this.RequestParameters.Add("count", options.Count.ToString(CultureInfo.InvariantCulture));
         }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsOfMeCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsOfMeCommand.cs
index 9f44edc..87c69f4 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsOfMeCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsOfMeCommand.cs
@@ -42,7 +42,7 @@ namespace Twitterizer.Commands
     /// The Retweets Of Me Command.
     /// </summary>
     [AuthorizedCommandAttribute]
-    internal sealed class RetweetsOfMeCommand : PagedCommand<TwitterStatusCollection>
+    internal sealed class RetweetsOfMeCommand : TwitterCommand<TwitterStatusCollection>
     {
         #region Constructors
         /// <summary>
@@ -65,37 +65,26 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
-            if (this.Page <= 0)
-                this.Page = 1;
+            this.RequestParameters.Add("include_entities", "true");
 
             RetweetsOfMeOptions options = this.OptionalProperties as RetweetsOfMeOptions;
-            if (options != null)
-            {
-                if (options.SinceStatusId > 0)
-                    this.RequestParameters.Add("since_id", options.SinceStatusId.ToString(CultureInfo.InvariantCulture));
 
-                if (options.MaxStatusId > 0)
-                    this.RequestParameters.Add("max_id", options.MaxStatusId.ToString(CultureInfo.InvariantCulture));
+            if (options == null)
+            {
+                this.RequestParameters.Add("page", options.Page.ToString(CultureInfo.InvariantCulture));
+                return;
+            }
 
-                if (options.Count > 0)
-                    this.RequestParameters.Add("count", options.Count.ToString(CultureInfo.InvariantCulture));
+            if (options.SinceStatusId > 0)
+                this.RequestParameters.Add("since_id", options.SinceStatusId.ToString(CultureInfo.InvariantCulture));
 
-                if (this.Page <= 1 && options.Page > 1)
-                    this.Page = options.Page;
-            }
+            if (options.MaxStatusId > 0)
+                this.RequestParameters.Add("max_id", options.MaxStatusId.ToString(CultureInfo.InvariantCulture));
 
-            this.RequestParameters.Add("page", this.Page.ToString(CultureInfo.InvariantCulture));
-        }
+            if (options.Count > 0)
+                this.RequestParameters.Add("count", options.Count.ToString(CultureInfo.InvariantCulture));
 
-        /// <summary>
-        /// Clones this instance.
-        /// </summary>
-        /// <returns>
-        /// A new instance of the <see cref="Twitterizer.Core.PagedCommand{T}"/> interface.
-        /// </returns>
-        internal override TwitterCommand<TwitterStatusCollection> Clone()
-        {
-            return new RetweetsOfMeCommand(this.Tokens, this.OptionalProperties as RetweetsOfMeOptions);
+            this.RequestParameters.Add("page", options.Page > 0 ? options.Page.ToString(CultureInfo.InvariantCulture) : "1");
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsOfMeOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsOfMeOptions.cs
index d058a6f..a17416b 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsOfMeOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsOfMeOptions.cs
@@ -39,7 +39,9 @@ namespace Twitterizer
     /// <summary>
     /// The Retweets of Me options class. Provides optional parameters for the RetweetsOfMeCommand class.
     /// </summary>
+#if !SILVERLIGHT
     [System.Serializable]
+#endif
     public class RetweetsOfMeOptions : OptionalProperties
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsOptions.cs
index da075e2..cfe191c 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsOptions.cs
@@ -37,7 +37,9 @@ namespace Twitterizer
     /// <summary>
     /// The Retweets Options class. Provides a payload for optional parameters for the Retweets Command
     /// </summary>
+#if !SILVERLIGHT
     [System.Serializable]
+#endif
     public class RetweetsOptions : OptionalProperties
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/ShowStatusCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/ShowStatusCommand.cs
index e270e15..ea8b0fc 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/ShowStatusCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/ShowStatusCommand.cs
@@ -42,7 +42,9 @@ namespace Twitterizer.Commands
     /// <summary>
     /// The Show Status Command
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class ShowStatusCommand : TwitterCommand<TwitterStatus>
     {
         #region Constructors
@@ -71,6 +73,7 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
+            this.RequestParameters.Add("include_entities", "true");
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/StatusUpdateOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/StatusUpdateOptions.cs
index 1afa27a..06b4d3d 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/StatusUpdateOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/StatusUpdateOptions.cs
@@ -39,7 +39,9 @@ namespace Twitterizer
     /// <summary>
     /// The Status Update Options class
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public sealed class StatusUpdateOptions : OptionalProperties
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterRelatedTweets.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterRelatedTweets.cs
new file mode 100644
index 0000000..999bbca
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterRelatedTweets.cs
@@ -0,0 +1,79 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterRelatedTweets.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The related tweets object.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer
+{
+    using System;
+    using System.Diagnostics;
+    using Newtonsoft.Json;
+
+    /// <summary>
+    /// The related tweets object. Represents the result from the related_results/show/:id.json endpoint.
+    /// </summary>
+    /// <seealso cref="Twitterizer.Commands.RelatedResultsCommand"/>
+    [JsonObject(MemberSerialization.OptIn)]
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    [DebuggerDisplay("{GroupName}/{ResultType}")]
+    public class TwitterRelatedTweets : Core.TwitterObject
+    {
+        /// <summary>
+        /// Gets or sets the results.
+        /// </summary>
+        /// <value>The results.</value>
+        [JsonProperty(PropertyName = "results")]
+        public TwitterStatusCollection Results { get; set; }
+
+        /// <summary>
+        /// Gets or sets the type of the result.
+        /// </summary>
+        /// <value>The type of the result.</value>
+        [JsonProperty(PropertyName = "resultType")]
+        public string ResultType { get; set; }
+
+        /// <summary>
+        /// Gets or sets the name of the group.
+        /// </summary>
+        /// <value>The name of the group.</value>
+        [JsonProperty(PropertyName = "groupName")]
+        public string GroupName { get; set; }
+
+        /// <summary>
+        /// Gets or sets the score.
+        /// </summary>
+        /// <value>The score.</value>
+        [JsonProperty(PropertyName = "score")]
+        public decimal Score { get; set; }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterRelatedTweetsCollection.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterRelatedTweetsCollection.cs
new file mode 100644
index 0000000..1073b26
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterRelatedTweetsCollection.cs
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterRelatedTweetsCollection.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The collection of TwitterRelatedTweets objects.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer
+{
+    using System;
+    using Twitterizer.Core;
+#if !SILVERLIGHT
+    /// <summary>
+    /// Represents a collection of <see cref="Twitterizer.TwitterRelatedTweets"/>.
+    /// </summary>
+    /// <remarks></remarks>
+    [Serializable]
+#endif
+    public class TwitterRelatedTweetsCollection : TwitterCollection<TwitterRelatedTweets>, ITwitterObject
+    {
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterStatus.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterStatus.cs
index 3564ff5..abc46d2 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterStatus.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterStatus.cs
@@ -34,45 +34,51 @@
 namespace Twitterizer
 {
     using System;
+    using System.Linq;
     using System.Diagnostics;
     using Newtonsoft.Json;
     using Twitterizer.Core;
+    using Twitterizer.Entities;
+    using System.Runtime.Serialization;
 
     /// <include file='TwitterStatus.xml' path='TwitterStatus/TwitterStatus/*'/>
     [JsonObject(MemberSerialization.OptIn)]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     [DebuggerDisplay("{User.ScreenName}/{Text}")]
+    [DataContract]
     public class TwitterStatus : TwitterObject
     {
-        /// <summary>
-        /// Initializes a new instance of the <see cref="TwitterStatus"/> class.
-        /// </summary>
-        public TwitterStatus()
-            : base()
-        {
-        }
-
         #region Properties
         /// <summary>
         /// Gets or sets the status id.
         /// </summary>
         /// <value>The status id.</value>
-        [JsonProperty(PropertyName = "id")]
+        [DataMember, JsonProperty(PropertyName = "id")]
         public decimal Id { get; set; }
 
         /// <summary>
+        /// Gets or sets the string id.
+        /// </summary>
+        /// <value>The string id.</value>
+        [DataMember, JsonProperty(PropertyName = "id_str")]
+        public string StringId { get; set; }
+
+        /// <summary>
         /// Gets or sets a value indicating whether this status message is truncated.
         /// </summary>
         /// <value>
         /// <c>true</c> if this status message is truncated; otherwise, <c>false</c>.
         /// </value>
-        [JsonProperty(PropertyName = "truncated")]
+        [DataMember, JsonProperty(PropertyName = "truncated")]
         public bool? IsTruncated { get; set; }
 
         /// <summary>
         /// Gets or sets the created date.
         /// </summary>
         /// <value>The created date.</value>
+        [DataMember]
         [JsonProperty(PropertyName = "created_at")]
         [JsonConverter(typeof(TwitterizerDateConverter))]
         public DateTime CreatedDate { get; set; }
@@ -81,28 +87,28 @@ namespace Twitterizer
         /// Gets or sets the source.
         /// </summary>
         /// <value>The source.</value>
-        [JsonProperty(PropertyName = "source")]
+        [DataMember, JsonProperty(PropertyName = "source")]
         public string Source { get; set; }
 
         /// <summary>
         /// Gets or sets the screenName the status is in reply to.
         /// </summary>
         /// <value>The screenName.</value>
-        [JsonProperty(PropertyName = "in_reply_to_screen_name")]
+        [DataMember, JsonProperty(PropertyName = "in_reply_to_screen_name")]
         public string InReplyToScreenName { get; set; }
 
         /// <summary>
         /// Gets or sets the user id the status is in reply to.
         /// </summary>
         /// <value>The user id.</value>
-        [JsonProperty(PropertyName = "in_reply_to_user_id")]
+        [DataMember, JsonProperty(PropertyName = "in_reply_to_user_id")]
         public decimal? InReplyToUserId { get; set; }
 
         /// <summary>
         /// Gets or sets the status id the status is in reply to.
         /// </summary>
         /// <value>The status id.</value>
-        [JsonProperty(PropertyName = "in_reply_to_status_id")]
+        [DataMember, JsonProperty(PropertyName = "in_reply_to_status_id")]
         public decimal? InReplyToStatusId { get; set; }
 
         /// <summary>
@@ -111,80 +117,183 @@ namespace Twitterizer
         /// <value>
         /// <c>true</c> if this instance is favorited; otherwise, <c>false</c>.
         /// </value>
-        [JsonProperty(PropertyName = "favorited")]
+        [DataMember, JsonProperty(PropertyName = "favorited")]
         public bool? IsFavorited { get; set; }
 
         /// <summary>
         /// Gets or sets the text of the status.
         /// </summary>
         /// <value>The status text.</value>
-        [JsonProperty(PropertyName = "text")]
+        [DataMember, JsonProperty(PropertyName = "text")]
         public string Text { get; set; }
 
         /// <summary>
         /// Gets or sets the user.
         /// </summary>
         /// <value>The user that posted this status.</value>
-        [JsonProperty(PropertyName = "user")]
+        [DataMember, JsonProperty(PropertyName = "user")]
         public TwitterUser User { get; set; }
 
         /// <summary>
         /// Gets or sets the retweeted status.
         /// </summary>
         /// <value>The retweeted status.</value>
-        [JsonProperty(PropertyName = "retweeted_status")]
+        [DataMember, JsonProperty(PropertyName = "retweeted_status")]
         public TwitterStatus RetweetedStatus { get; set; }
 
         /// <summary>
         /// Gets or sets the place.
         /// </summary>
         /// <value>The place.</value>
-        [JsonProperty(PropertyName = "place")]
+        [DataMember, JsonProperty(PropertyName = "place")]
         public TwitterPlace Place { get; set; }
 
         /// <summary>
         /// Gets or sets the geo location data.
         /// </summary>
         /// <value>The geo location data.</value>
-        [JsonProperty(PropertyName = "geo")]
+        [DataMember, JsonProperty(PropertyName = "geo")]
         public TwitterGeo Geo { get; set; }
 
         /// <summary>
         /// Gets or sets the entities.
         /// </summary>
         /// <value>The entities.</value>
-        [JsonProperty(PropertyName  = "entities")]
+        [DataMember]
+        [JsonProperty(PropertyName = "entities")]
         [JsonConverter(typeof(Entities.TwitterEntityCollection.Converter))]
         public Entities.TwitterEntityCollection Entities { get; set; }
 
         /// <summary>
-        /// Gets or sets the retweet count.
+        /// Gets or sets the retweet count string.
         /// </summary>
         /// <value>The retweet count.</value>
-        [JsonProperty(PropertyName = "retweet_count")]
-        public int? RetweetCount { get; set; }
+        [DataMember, JsonProperty(PropertyName = "retweet_count")]
+        public string RetweetCountString { get; set; }
+
+        /// <summary>
+        /// Gets the retweet count.
+        /// </summary>
+        /// <value>The retweet count.</value>
+        [DataMember]
+        public int? RetweetCount
+        {
+            get
+            {
+                if (string.IsNullOrEmpty(this.RetweetCountString)) return null;
+
+                int parsedResult = 0;
+
+                if (
+                    this.RetweetCountString.EndsWith("+") &&
+                    !int.TryParse(this.RetweetCountString.Substring(0, this.RetweetCountString.Length - 1), out parsedResult)
+                    )
+                {
+                    return null;
+                }
+
+                if (!int.TryParse(this.RetweetCountString, out parsedResult))
+                {
+                    return null;
+                }
+
+                return parsedResult;
+            }
+        }
+
+        /// <summary>
+        /// Gets a value indicating that the number of retweets exceeds the reported value in RetweetCount. For example, "more than 100"
+        /// </summary>
+        /// <value>The retweet count plus indicator.</value>
+        [DataMember]
+        public bool? RetweetCountPlus
+        {
+            get
+            {
+                if (string.IsNullOrEmpty(this.RetweetCountString)) return null;
+
+                return this.RetweetCountString.EndsWith("+");
+            }
+        }
 
         /// <summary>
         /// Gets or sets a value indicating whether this <see cref="TwitterStatus"/> is retweeted.
         /// </summary>
         /// <value><c>true</c> if retweeted; otherwise, <c>false</c>.</value>
-        [JsonProperty(PropertyName = "retweeted")]
+        [DataMember, JsonProperty(PropertyName = "retweeted")]
         public bool Retweeted { get; set; }
         #endregion
 
         /// <summary>
-        /// Updates the authenticated user's status to the supplied text.
+        /// Returns the status text with HTML links to users, urls, and hashtags.
+        /// </summary>
+        /// <returns></returns>
+        public string LinkifiedText()
+        {
+            if (this.Entities == null || this.Entities.Count == 0)
+            {
+                return this.Text;
+            }
+
+            string linkedText = this.Text;
+
+            var entitiesSorted = this
+                                  .Entities
+                                  .OrderBy(e => e.StartIndex)
+                                  .Reverse();
+
+            foreach (TwitterEntity entity in entitiesSorted)
+            {
+                if (entity is TwitterHashTagEntity)
+                {
+                    TwitterHashTagEntity tagEntity = (TwitterHashTagEntity)entity;
+
+                    linkedText = string.Format(
+                        "{0}<a href=\"http://twitter.com/search?q=%23{1}\">{1}</a>{2}",
+                        linkedText.Substring(0, entity.StartIndex),
+                        tagEntity.Text,
+                        linkedText.Substring(entity.EndIndex));
+                }
+
+                if (entity is TwitterUrlEntity)
+                {
+                    TwitterUrlEntity urlEntity = (TwitterUrlEntity)entity;
+
+                    linkedText = string.Format(
+                        "{0}<a href=\"{1}\">{1}</a>{2}",
+                        linkedText.Substring(0, entity.StartIndex),
+                        urlEntity.Url,
+                        linkedText.Substring(entity.EndIndex));
+                }
+
+                if (entity is TwitterMentionEntity)
+                {
+                    TwitterMentionEntity mentionEntity = (TwitterMentionEntity)entity;
+
+                    linkedText = string.Format(
+                        "{0}<a href=\"http://twitter.com/{1}\">@{1}</a>{2}",
+                        linkedText.Substring(0, entity.StartIndex),
+                        mentionEntity.ScreenName,
+                        linkedText.Substring(entity.EndIndex));
+                }
+            }
+
+            return linkedText;
+        }
+
+        /// <summary>
+        /// Updates the authenticating user's status. A status update with text identical to the authenticating user's text identical to the authenticating user's current status will be ignored to prevent duplicates.
         /// </summary>
         /// <param name="tokens">The tokens.</param>
         /// <param name="text">The status text.</param>
         /// <returns>A <see cref="TwitterStatus"/> object of the newly created status.</returns>
-        public static TwitterStatus Update(OAuthTokens tokens, string text)
+        public static TwitterResponse<TwitterStatus> Update(OAuthTokens tokens, string text)
         {
             return Update(tokens, text, null);
         }
 
         /// <summary>
-        /// Updates the specified tokens.
+        /// Updates the authenticating user's status. A status update with text identical to the authenticating user's text identical to the authenticating user's current status will be ignored to prevent duplicates.
         /// </summary>
         /// <param name="tokens">The tokens.</param>
         /// <param name="text">The status text.</param>
@@ -192,9 +301,39 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterStatus"/> object of the newly created status.
         /// </returns>
-        public static TwitterStatus Update(OAuthTokens tokens, string text, StatusUpdateOptions options)
+        public static TwitterResponse<TwitterStatus> Update(OAuthTokens tokens, string text, StatusUpdateOptions options)
         {
-            return CommandPerformer<TwitterStatus>.PerformAction(new Commands.UpdateStatusCommand(tokens, text, options));
+            return CommandPerformer.PerformAction(new Commands.UpdateStatusCommand(tokens, text, options));
+        }
+
+		/// <summary>
+		/// Updates the authenticating user's status. A status update with text identical to the authenticating user's text identical to the authenticating user's current status will be ignored to prevent duplicates.
+		/// </summary>
+		/// <param name="tokens">The tokens.</param>
+		/// <param name="text">The status text.</param>
+		/// <param name="file">The file to upload.</param>
+		/// <param name="options">The options.</param>
+		/// <returns>
+		/// A <see cref="TwitterStatus"/> object of the newly created status.
+		/// </returns>
+		public static TwitterResponse<TwitterStatus> UpdateWithMedia(OAuthTokens tokens, string text, byte[] fileData, StatusUpdateOptions options = null)
+		{
+            return CommandPerformer.PerformAction(new Commands.UpdateWithMediaCommand(tokens, text, fileData, options));
+		}
+
+        /// <summary>
+        /// Updates the authenticating user's status. A status update with text identical to the authenticating user's text identical to the authenticating user's current status will be ignored to prevent duplicates.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="text">The status text.</param>
+        /// <param name="fileLocation">The file location.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// A <see cref="TwitterStatus"/> object of the newly created status.
+        /// </returns>
+        public static TwitterResponse<TwitterStatus> UpdateWithMedia(OAuthTokens tokens, string text, string fileLocation, StatusUpdateOptions options = null)
+        {
+            return UpdateWithMedia(tokens, text, System.IO.File.ReadAllBytes(fileLocation), options);
         }
 
         /// <summary>
@@ -206,11 +345,11 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterStatus"/> object of the deleted status.
         /// </returns>
-        public static TwitterStatus Delete(OAuthTokens tokens, decimal id, OptionalProperties options)
+        public static TwitterResponse<TwitterStatus> Delete(OAuthTokens tokens, decimal id, OptionalProperties options)
         {
             Commands.DeleteStatusCommand command = new Twitterizer.Commands.DeleteStatusCommand(tokens, id, options);
 
-            return CommandPerformer<TwitterStatus>.PerformAction(command);
+            return CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
@@ -219,7 +358,7 @@ namespace Twitterizer
         /// <param name="tokens">The oauth tokens.</param>
         /// <param name="id">The status id.</param>
         /// <returns>A <see cref="TwitterStatus"/> object of the deleted status.</returns>
-        public static TwitterStatus Delete(OAuthTokens tokens, decimal id)
+        public static TwitterResponse<TwitterStatus> Delete(OAuthTokens tokens, decimal id)
         {
             return Delete(tokens, id, null);
         }
@@ -231,9 +370,9 @@ namespace Twitterizer
         /// <param name="statusId">The status id.</param>
         /// <param name="options">The options.</param>
         /// <returns>A <see cref="TwitterStatus"/> instance.</returns>
-        public static TwitterStatus Show(OAuthTokens tokens, decimal statusId, OptionalProperties options)
+        public static TwitterResponse<TwitterStatus> Show(OAuthTokens tokens, decimal statusId, OptionalProperties options)
         {
-            return CommandPerformer<TwitterStatus>.PerformAction(new Commands.ShowStatusCommand(tokens, statusId, options));
+            return CommandPerformer.PerformAction(new Commands.ShowStatusCommand(tokens, statusId, options));
         }
 
         /// <summary>
@@ -242,7 +381,7 @@ namespace Twitterizer
         /// <param name="tokens">The tokens.</param>
         /// <param name="statusId">The status id.</param>
         /// <returns>A <see cref="TwitterStatus"/> instance.</returns>
-        public static TwitterStatus Show(OAuthTokens tokens, decimal statusId)
+        public static TwitterResponse<TwitterStatus> Show(OAuthTokens tokens, decimal statusId)
         {
             return Show(tokens, statusId, null);
         }
@@ -252,7 +391,7 @@ namespace Twitterizer
         /// </summary>
         /// <param name="statusId">The status id.</param>
         /// <returns>A <see cref="TwitterStatus"/> instance.</returns>
-        public static TwitterStatus Show(decimal statusId)
+        public static TwitterResponse<TwitterStatus> Show(decimal statusId)
         {
             return Show(null, statusId);
         }
@@ -264,9 +403,9 @@ namespace Twitterizer
         /// <param name="statusId">The status id.</param>
         /// <param name="options">The options.</param>
         /// <returns>A <see cref="TwitterStatus"/> representing the newly created tweet.</returns>
-        public static TwitterStatus Retweet(OAuthTokens tokens, decimal statusId, OptionalProperties options)
+        public static TwitterResponse<TwitterStatus> Retweet(OAuthTokens tokens, decimal statusId, OptionalProperties options)
         {
-            return CommandPerformer<TwitterStatus>.PerformAction(
+            return CommandPerformer.PerformAction(
                 new Commands.RetweetCommand(tokens, statusId, options));
         }
 
@@ -276,7 +415,7 @@ namespace Twitterizer
         /// <param name="tokens">The tokens.</param>
         /// <param name="statusId">The status id.</param>
         /// <returns>A <see cref="TwitterStatus"/> representing the newly created tweet.</returns>
-        public static TwitterStatus Retweet(OAuthTokens tokens, decimal statusId)
+        public static TwitterResponse<TwitterStatus> Retweet(OAuthTokens tokens, decimal statusId)
         {
             return Retweet(tokens, statusId, null);
         }
@@ -290,9 +429,9 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterStatusCollection"/> instance.
         /// </returns>
-        public static TwitterStatusCollection Retweets(OAuthTokens tokens, decimal statusId, RetweetsOptions options)
+        public static TwitterResponse<TwitterStatusCollection> Retweets(OAuthTokens tokens, decimal statusId, RetweetsOptions options)
         {
-            return CommandPerformer<TwitterStatusCollection>.PerformAction(
+            return CommandPerformer.PerformAction(
                 new Commands.RetweetsCommand(tokens, statusId, options));
         }
 
@@ -302,7 +441,7 @@ namespace Twitterizer
         /// <param name="tokens">The tokens.</param>
         /// <param name="statusId">The status id.</param>
         /// <returns>A <see cref="TwitterStatusCollection"/> instance.</returns>
-        public static TwitterStatusCollection Retweets(OAuthTokens tokens, decimal statusId)
+        public static TwitterResponse<TwitterStatusCollection> Retweets(OAuthTokens tokens, decimal statusId)
         {
             return Retweets(tokens, statusId, null);
         }
@@ -315,7 +454,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterStatus"/> representing the newly created tweet.
         /// </returns>
-        public TwitterStatus Retweet(OAuthTokens tokens, OptionalProperties options)
+        public TwitterResponse<TwitterStatus> Retweet(OAuthTokens tokens, OptionalProperties options)
         {
             return Retweet(tokens, this.Id, options);
         }
@@ -327,7 +466,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterStatus"/> representing the newly created tweet.
         /// </returns>
-        public TwitterStatus Retweet(OAuthTokens tokens)
+        public TwitterResponse<TwitterStatus> Retweet(OAuthTokens tokens)
         {
             return Retweet(tokens, this.Id, null);
         }
@@ -340,7 +479,7 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterStatus"/> object of the deleted status.
         /// </returns>
-        public TwitterStatus Delete(OAuthTokens tokens, OptionalProperties options)
+        public TwitterResponse<TwitterStatus> Delete(OAuthTokens tokens, OptionalProperties options)
         {
             return Delete(tokens, this.Id, options);
         }
@@ -352,9 +491,36 @@ namespace Twitterizer
         /// <returns>
         /// A <see cref="TwitterStatus"/> object of the deleted status.
         /// </returns>
-        public TwitterStatus Delete(OAuthTokens tokens)
+        public TwitterResponse<TwitterStatus> Delete(OAuthTokens tokens)
         {
             return Delete(tokens, this.Id, null);
         }
+
+        /// <summary>
+        /// Shows Related Results of a tweet. Requires the id parameter of the tweet you are getting results for.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="statusId">The status id.</param>
+        /// <returns>A <see cref="TwitterStatus"/> representing the newly created tweet.</returns>
+        /// <remarks></remarks>
+        public static TwitterResponse<TwitterRelatedTweetsCollection> RelatedResultsShow(OAuthTokens tokens, decimal statusId)
+        {
+            return CommandPerformer.PerformAction(
+                new Commands.RelatedResultsCommand(tokens, statusId, null));
+        }
+
+
+        /// <summary>
+        /// Shows Related Results of a tweet. Requires the id parameter of the tweet you are getting results for.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="statusId">The status id.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>A <see cref="TwitterStatus"/> representing the newly created tweet.</returns>
+        public static TwitterResponse<TwitterRelatedTweetsCollection> RelatedResultsShow(OAuthTokens tokens, decimal statusId, OptionalProperties options)
+        {
+            return CommandPerformer.PerformAction(
+                new Commands.RelatedResultsCommand(tokens, statusId, options));
+        }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterStatusCollection.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterStatusCollection.cs
index 0e48ab1..f8ed41f 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterStatusCollection.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterStatusCollection.cs
@@ -35,63 +35,23 @@
 namespace Twitterizer
 {
     using System;
+    using System.Runtime.Serialization;
     using Twitterizer.Core;
 
     /// <summary>
     /// The TwitterStatusCollection class.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
-    public class TwitterStatusCollection : TwitterCollection<TwitterStatus>
+#endif
+    [DataContract]
+    public class TwitterStatusCollection : TwitterCollection<TwitterStatus>, ITwitterObject
     {
         /// <summary>
-        /// Gets or sets the command.
+        /// Gets or sets the current page number.
         /// </summary>
-        /// <value>The command.</value>
-        internal PagedCommand<TwitterStatusCollection> Command { get; set; }
-
-        /// <summary>
-        /// Gets the next page.
-        /// </summary>
-        /// <returns>A <see cref="TwitterStatusCollection"/> instance.</returns>
-        public TwitterStatusCollection NextPage()
-        {
-            if (this.Command == null || this.Command.Page < 0)
-            {
-                return null;
-            }
-
-            PagedCommand<TwitterStatusCollection> newCommand = 
-                (PagedCommand<TwitterStatusCollection>)this.Command.Clone();
-            newCommand.Page += 1;
-
-            TwitterStatusCollection result = Core.CommandPerformer<TwitterStatusCollection>.PerformAction(newCommand);
-            result.Command = newCommand;
-            return result;
-        }
-
-        /// <summary>
-        /// Gets the previous page.
-        /// </summary>
-        /// <returns>A <see cref="TwitterStatusCollection"/> instance.</returns>
-        public TwitterStatusCollection PreviousPage()
-        {
-            if (this.Command == null || this.Command.Page <= 1)
-            {
-                return null;
-            }
-
-            PagedCommand<TwitterStatusCollection> newCommand = 
-                (PagedCommand<TwitterStatusCollection>)this.Command.Clone();
-            newCommand.Page -= 1;
-
-            if (newCommand.Page <= 0)
-            {
-                return null;
-            }
-
-            TwitterStatusCollection result = Core.CommandPerformer<TwitterStatusCollection>.PerformAction(newCommand);
-            result.Command = newCommand;
-            return result;
-        }
+        /// <value>The current page number.</value>
+        [DataMember]
+        public int Page { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/UpdateStatusCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/UpdateStatusCommand.cs
index 0cc9213..c0debc9 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/UpdateStatusCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/UpdateStatusCommand.cs
@@ -42,7 +42,9 @@ namespace Twitterizer.Commands
     /// The command to update the user's status. (a.k.a. post a new tweet)
     /// </summary>
     [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class UpdateStatusCommand : TwitterCommand<TwitterStatus>
     {
         /// <summary>
@@ -85,14 +87,16 @@ namespace Twitterizer.Commands
             StatusUpdateOptions options = this.OptionalProperties as StatusUpdateOptions;
             if (options != null)
             {
+                NumberFormatInfo nfi = CultureInfo.InvariantCulture.NumberFormat;
+
                 if (options.InReplyToStatusId > 0)
                     this.RequestParameters.Add("in_reply_to_status_id", options.InReplyToStatusId.ToString(CultureInfo.CurrentCulture));
 
                 if (options.Latitude != 0)
-                    this.RequestParameters.Add("lat", options.Latitude.ToString());
+                    this.RequestParameters.Add("lat", options.Latitude.ToString(nfi));
 
                 if (options.Longitude != 0)
-                    this.RequestParameters.Add("long", options.Longitude.ToString());
+                    this.RequestParameters.Add("long", options.Longitude.ToString(nfi));
 
                 if (!string.IsNullOrEmpty(options.PlaceId))
                     this.RequestParameters.Add("place_id", options.PlaceId);
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/UpdateWithmediaCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/UpdateWithmediaCommand.cs
new file mode 100644
index 0000000..c9839de
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/UpdateWithmediaCommand.cs
@@ -0,0 +1,123 @@
+//-----------------------------------------------------------------------
+// <copyright file="UpdateStatusCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Daan Timmer</author>
+// <summary>The command to update the user's status. (a.k.a. post a new tweet)</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer.Commands
+{
+	using System;
+	using System.Globalization;
+	using Twitterizer.Core;
+
+	/// <summary>
+	/// The command to update the user's status. (a.k.a. post a new tweet)
+	/// </summary>
+	[AuthorizedCommandAttribute]
+#if !SILVERLIGHT
+	[Serializable]
+#endif
+	internal sealed class UpdateWithMediaCommand : TwitterCommand<TwitterStatus>
+	{
+        /// <summary>
+        /// Gets or sets the status text.
+        /// </summary>
+        /// <value>The status text.</value>
+        public string Text { get; set; }
+
+        /// <summary>
+        /// Gets or sets the file location.
+        /// </summary>
+        /// <value>The file location.</value>
+        public byte[] File { get; set; }
+
+		/// <summary>
+		/// Initializes a new instance of the <see cref="UpdateStatusCommand"/> class.
+		/// </summary>
+		/// <param name="tokens">The request tokens.</param>
+		/// <param name="text">The status text.</param>
+		/// <param name="file">The file to upload.</param>
+		/// <param name="optionalProperties">The optional properties.</param>
+		public UpdateWithMediaCommand(OAuthTokens tokens, string text, byte[] fileData, StatusUpdateOptions optionalProperties)
+			: base(HTTPVerb.POST, "Set below", tokens, optionalProperties)
+		{
+			if (tokens == null)
+			{
+				throw new ArgumentNullException("tokens");
+			}
+
+			if (string.IsNullOrEmpty(text))
+			{
+				throw new ArgumentNullException("text");
+			}
+
+            if (fileData == null || fileData.Length == 0)
+			{
+				throw new ArgumentException("file");
+			}
+
+            this.OptionalProperties.APIBaseAddress = "https://upload.twitter.com/1/";
+            this.SetCommandUri("statuses/update_with_media.json");
+
+			this.Text = text;
+            this.File = fileData;
+            this.Multipart = true;
+		}
+
+		/// <summary>
+		/// Initializes the command.
+		/// </summary>
+		public override void Init()
+		{
+			this.RequestParameters.Add("status", this.Text);
+			this.RequestParameters.Add("media[]", this.File);
+
+			StatusUpdateOptions options = this.OptionalProperties as StatusUpdateOptions;
+			if (options != null)
+			{
+				if (options.InReplyToStatusId > 0)
+					this.RequestParameters.Add("in_reply_to_status_id", options.InReplyToStatusId.ToString(CultureInfo.CurrentCulture));
+
+				if (options.Latitude != 0)
+					this.RequestParameters.Add("lat", options.Latitude.ToString());
+
+				if (options.Longitude != 0)
+					this.RequestParameters.Add("long", options.Longitude.ToString());
+
+				if (!string.IsNullOrEmpty(options.PlaceId))
+					this.RequestParameters.Add("place_id", options.PlaceId);
+
+				if (options.PlacePin)
+					this.RequestParameters.Add("display_coordinates", "true");
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/FollowersCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/User/FollowersCommand.cs
index 8d32c8d..3bc2d78 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/User/FollowersCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/FollowersCommand.cs
@@ -41,9 +41,11 @@ namespace Twitterizer.Commands
     /// <summary>
     /// The command to obtain followers of a user.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class FollowersCommand :
-        Core.CursorPagedCommand<TwitterUserCollection>
+        Core.TwitterCommand<TwitterUserCollection>
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="FollowersCommand"/> class.
@@ -71,12 +73,8 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
-            if (this.Cursor <= 0)
-            {
-                this.Cursor = -1;
-            }
-
-            this.RequestParameters.Add("cursor", this.Cursor.ToString(CultureInfo.CurrentCulture));
+            // Default values
+            this.RequestParameters.Add("cursor", "-1");
 
             // Handle optional parameters
             FollowersOptions options = this.OptionalProperties as FollowersOptions;
@@ -91,18 +89,10 @@ namespace Twitterizer.Commands
 
             if (!string.IsNullOrEmpty(options.ScreenName))
                 this.RequestParameters.Add("screen_name", options.ScreenName);
-        }
-
-        /// <summary>
-        /// Clones this instance.
-        /// </summary>
-        /// <returns>A cloned command object.</returns>
-        internal override Twitterizer.Core.TwitterCommand<TwitterUserCollection> Clone()
-        {
-            FollowersCommand newCommand = new FollowersCommand(this.Tokens, this.OptionalProperties as FollowersOptions);
-            newCommand.Cursor = this.Cursor;
 
-            return newCommand;
+            // Override the default
+            if (options.Cursor != 0)
+                this.RequestParameters["cursor"] = options.Cursor.ToString(CultureInfo.CurrentCulture);
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/FollowersOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/User/FollowersOptions.cs
index 5b8f88a..cce18d8 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/User/FollowersOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/FollowersOptions.cs
@@ -36,7 +36,9 @@ namespace Twitterizer
     /// <summary>
     /// The followers options class. Provides a payload for optional parameters of the FollowersCommand class.
     /// </summary>
+#if !SILVERLIGHT
     [System.Serializable]
+#endif
     public class FollowersOptions : OptionalProperties
     {
         /// <summary>
@@ -50,5 +52,11 @@ namespace Twitterizer
         /// </summary>
         /// <value>The name of the screen.</value>
         public string ScreenName { get; set; }
+
+        /// <summary>
+        /// Gets or sets the cursor.
+        /// </summary>
+        /// <value>The cursor.</value>
+        public long Cursor { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/FriendsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/User/FriendsCommand.cs
index c687a63..39e9188 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/User/FriendsCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/FriendsCommand.cs
@@ -41,8 +41,10 @@ namespace Twitterizer.Commands
     /// <summary>
     /// The command to obtain followers of a user.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
-    internal sealed class FriendsCommand : CursorPagedCommand<TwitterUserCollection>
+#endif
+    internal sealed class FriendsCommand : TwitterCommand<TwitterUserCollection>
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="FriendsCommand"/> class.
@@ -60,38 +62,25 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
-            FriendsOptions options = this.OptionalProperties as FriendsOptions;
-
-            if (options != null)
-            {
-                if (options.UserId > 0)
-                    this.RequestParameters.Add("user_id", options.UserId.ToString(CultureInfo.CurrentCulture));
+            // Default values
+            this.RequestParameters.Add("cursor", "-1");
 
-                if (!string.IsNullOrEmpty(options.ScreenName))
-                    this.RequestParameters.Add("screen_name", options.ScreenName);
-
-                if (options.Cursor != 0)
-                    this.Cursor = options.Cursor;
-            }
+            FriendsOptions options = this.OptionalProperties as FriendsOptions;
 
-            if (this.Cursor == 0)
+            if (options == null)
             {
-                this.Cursor = -1;
+                return;
             }
 
-            this.RequestParameters.Add("cursor", this.Cursor.ToString(CultureInfo.CurrentCulture));
-        }
+            if (options.UserId > 0)
+                this.RequestParameters.Add("user_id", options.UserId.ToString(CultureInfo.CurrentCulture));
 
-        /// <summary>
-        /// Clones this instance.
-        /// </summary>
-        /// <returns>A cloned command object.</returns>
-        internal override Twitterizer.Core.TwitterCommand<TwitterUserCollection> Clone()
-        {
-            FriendsCommand newCommand = new FriendsCommand(this.Tokens, this.OptionalProperties as FriendsOptions);
-            newCommand.Cursor = this.Cursor;
+            if (!string.IsNullOrEmpty(options.ScreenName))
+                this.RequestParameters.Add("screen_name", options.ScreenName);
 
-            return newCommand;
+            // Override the default
+            if (options.Cursor != 0)
+                this.RequestParameters["cursor"] = options.Cursor.ToString(CultureInfo.CurrentCulture);
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/FriendsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/User/FriendsOptions.cs
index 427f922..6f094aa 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/User/FriendsOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/FriendsOptions.cs
@@ -37,7 +37,9 @@ namespace Twitterizer
     /// <summary>
     /// The friends options class. Provides a payload for optional parameters of the <see cref="Twitterizer.Commands.FriendsCommand"/> class.
     /// </summary>
+#if !SILVERLIGHT
     [System.Serializable]
+#endif
     public class FriendsOptions : OptionalProperties
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/LookupUsersCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/User/LookupUsersCommand.cs
index 147df1f..636fb88 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/User/LookupUsersCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/LookupUsersCommand.cs
@@ -39,7 +39,9 @@ namespace Twitterizer.Commands
     /// <summary>
     /// The Lookup Users command class.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class LookupUsersCommand : Core.TwitterCommand<TwitterUserCollection>
     {
         /// <summary>
@@ -78,7 +80,8 @@ namespace Twitterizer.Commands
             }
 
             if (options.UserIds.Count > 0)
-                this.RequestParameters.Add("user_id", string.Join(",", options.UserIds.Cast<string>().ToArray()));
+                this.RequestParameters.Add("user_id",
+                                           string.Join(",", options.UserIds.Where(id => id > 0).Select(id => id.ToString()).ToArray()));
 
             if (options.ScreenNames.Count > 0)
                 this.RequestParameters.Add("screen_name", string.Join(",", options.ScreenNames.ToArray()));
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/LookupUsersOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/User/LookupUsersOptions.cs
index c1a4546..d862caa 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/User/LookupUsersOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/LookupUsersOptions.cs
@@ -3,6 +3,9 @@
     using System.Collections.Generic;
     using System.Collections.ObjectModel;
 
+    /// <summary>
+    /// Provides optional parameters for user lookup methods.
+    /// </summary>
     public class LookupUsersOptions : OptionalProperties
     {
         /// <summary>
@@ -11,7 +14,7 @@
         public LookupUsersOptions()
         {
             this.ScreenNames = new Collection<string>();
-            this.UserIds = new Collection<decimal>();
+            this.UserIds = new TwitterIdCollection();
         }
 
         /// <summary>
@@ -24,7 +27,7 @@
         /// Gets or sets the user ids.
         /// </summary>
         /// <value>The user ids.</value>
-        public Collection<decimal> UserIds { get; set; }
+        public TwitterIdCollection UserIds { get; set; }
 
         /// <summary>
         /// Gets or sets a value indicating whether [include entities].
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/RetweetedByCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/User/RetweetedByCommand.cs
new file mode 100644
index 0000000..0886418
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/RetweetedByCommand.cs
@@ -0,0 +1,95 @@
+//-----------------------------------------------------------------------
+// <copyright file="RetweetedByCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The retweeted by command class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer.Commands
+{
+    using System;
+    using Twitterizer;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The retweeted by command class.
+    /// </summary>
+    /// <remarks>http://dev.twitter.com/doc/get/statuses/:id/retweeted_by</remarks>
+    [AuthorizedCommandAttribute]
+    internal class RetweetedByCommand : TwitterCommand<TwitterUserCollection>
+    {
+        public RetweetedByCommand(OAuthTokens tokens, decimal statusId, RetweetedByOptions options)
+            : base(HTTPVerb.GET, string.Format("statuses/{0}/retweeted_by.json", statusId), tokens, options)
+        {
+            if (tokens == null)
+            {
+                throw new ArgumentNullException("tokens");
+            }
+
+            if (statusId <= 0)
+            {
+                throw new ArgumentNullException("statusId", "Status ID is required.");
+            }
+        }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+            RetweetedByOptions options = this.OptionalProperties as RetweetedByOptions;
+
+            if (options == null)
+            {
+                this.RequestParameters.Add("page", "1");
+                return;
+            }
+
+            if (options.Count > 1)
+            {
+                this.RequestParameters.Add("count", options.Count.ToString());
+            }
+
+            if (options.IncludeEntities)
+            {
+                this.RequestParameters.Add("include_entities", "true");
+            }
+
+            if (options.TrimUser)
+            {
+                this.RequestParameters.Add("trim_user", "true");
+            }
+
+            if (options.Page > 0)
+            {
+                this.RequestParameters.Add("page", options.Page.ToString());
+            }
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/RetweetedByIdsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/User/RetweetedByIdsCommand.cs
new file mode 100644
index 0000000..7e91a68
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/RetweetedByIdsCommand.cs
@@ -0,0 +1,95 @@
+//-----------------------------------------------------------------------
+// <copyright file="RetweetedByCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Fabien Warniez</author>
+// <summary>The retweeted by ids command class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer.Commands
+{
+    using System;
+    using Twitterizer;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The retweeted by ids command class.
+    /// </summary>
+    /// <remarks>http://dev.twitter.com/doc/get/statuses/:id/retweeted_by/ids</remarks>
+    [AuthorizedCommandAttribute]
+    internal class RetweetedByIdsCommand : TwitterCommand<UserIdCollection>
+    {
+        public RetweetedByIdsCommand(OAuthTokens tokens, decimal statusId, RetweetedByIdsOptions options)
+            : base(HTTPVerb.GET, string.Format("statuses/{0}/retweeted_by/ids.json", statusId), tokens, options)
+        {
+            if (tokens == null)
+            {
+                throw new ArgumentNullException("tokens");
+            }
+
+            if (statusId <= 0)
+            {
+                throw new ArgumentNullException("statusId", "Status ID is required.");
+            }
+        }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+            RetweetedByIdsOptions options = this.OptionalProperties as RetweetedByIdsOptions;
+
+            if (options == null)
+            {
+                this.RequestParameters.Add("page", "1");
+                return;
+            }
+
+            if (options.Count > 1)
+            {
+                this.RequestParameters.Add("count", options.Count.ToString());
+            }
+
+            if (options.IncludeEntities)
+            {
+                this.RequestParameters.Add("include_entities", "true");
+            }
+
+            if (options.TrimUser)
+            {
+                this.RequestParameters.Add("trim_user", "true");
+            }
+
+            if (options.Page > 0)
+            {
+                this.RequestParameters.Add("page", options.Page.ToString());
+            }
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/RetweetedByIdsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/User/RetweetedByIdsOptions.cs
new file mode 100644
index 0000000..f0870f6
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/RetweetedByIdsOptions.cs
@@ -0,0 +1,65 @@
+//-----------------------------------------------------------------------
+// <copyright file="RetweetedByCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <summary>The retweeted by ids options class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer
+{
+    /// <summary>
+    /// The optional properties class for the <see cref="Twitterizer.TwitterUser.RetweetedByIds(Twitterizer.OAuthTokens, decimal, Twitterizer.RetweetedByIdsOptions)"/> method.
+    /// </summary>
+    /// <remarks></remarks>
+    public class RetweetedByIdsOptions : OptionalProperties
+    {
+        /// <summary>
+        /// Specifies the number of records to retrieve. Must be less than or equal to 100.
+        /// </summary>
+        /// <value>The count.</value>
+        public int Count { get; set; }
+
+        /// <summary>
+        /// Specifies the page of results to retrieve.
+        /// </summary>
+        /// <value>The page.</value>
+        public int Page { get; set; }
+
+        /// <summary>
+        /// When set to true each tweet returned in a timeline will include a user object including only the status authors numerical ID. Omit this parameter to receive the complete user object.
+        /// </summary>
+        /// <value><c>true</c> if [trim user]; otherwise, <c>false</c>.</value>
+        public bool TrimUser { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether entities should be included in the results.
+        /// </summary>
+        /// <value><c>true</c> if entities should be included; otherwise, <c>false</c>.</value>
+        public bool IncludeEntities { get; set; }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/RetweetedByOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/User/RetweetedByOptions.cs
new file mode 100644
index 0000000..a93796a
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/RetweetedByOptions.cs
@@ -0,0 +1,65 @@
+//-----------------------------------------------------------------------
+// <copyright file="RetweetedByOptions.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The retweeted by options class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer
+{
+    /// <summary>
+    /// The optional parameters for the <see cref="Twitterizer.Commands.RetweetedByCommand"/> class.
+    /// </summary>
+    public class RetweetedByOptions : OptionalProperties
+    {
+        /// <summary>
+        /// Specifies the number of records to retrieve. Must be less than or equal to 100.
+        /// </summary>
+        /// <value>The count.</value>
+        public int Count { get; set; }
+
+        /// <summary>
+        /// Specifies the page of results to retrieve.
+        /// </summary>
+        /// <value>The page.</value>
+        public int Page { get; set; }
+
+        /// <summary>
+        /// When set to true each tweet returned in a timeline will include a user object including only the status authors numerical ID. Omit this parameter to receive the complete user object.
+        /// </summary>
+        /// <value><c>true</c> if [trim user]; otherwise, <c>false</c>.</value>
+        public bool TrimUser { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether entities should be included in the results.
+        /// </summary>
+        /// <value><c>true</c> if entities should be included; otherwise, <c>false</c>.</value>
+        public bool IncludeEntities { get; set; }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/ShowUserCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/User/ShowUserCommand.cs
index bd3efac..7312d35 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/User/ShowUserCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/ShowUserCommand.cs
@@ -43,7 +43,9 @@ namespace Twitterizer.Commands
     /// The Show User Command
     /// </summary>
     /// <remarks>http://dev.twitter.com/doc/get/users/show</remarks>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     internal sealed class ShowUserCommand : TwitterCommand<TwitterUser>
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/SuggestedUserCategoriesCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/User/SuggestedUserCategoriesCommand.cs
new file mode 100644
index 0000000..0e4541e
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/SuggestedUserCategoriesCommand.cs
@@ -0,0 +1,67 @@
+//-----------------------------------------------------------------------
+// <copyright file="SuggestedUserCategoriesCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The suggested user categories command class.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer.Commands
+{
+    using System;
+    using Twitterizer;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The suggested users categories command
+    /// </summary>
+    /// <remarks>http://dev.twitter.com/doc/get/users/suggestions</remarks>
+#if !SILVERLIGHT 
+    [Serializable]
+#endif
+    internal class SuggestedUserCategoriesCommand : TwitterCommand<TwitterUserCategoryCollection>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="SuggestedUserCategoriesCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        public SuggestedUserCategoriesCommand(OAuthTokens tokens, OptionalProperties options)
+            : base(HTTPVerb.GET, "users/suggestions.json", tokens, options)
+        {
+        }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/SuggestedUsersCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/User/SuggestedUsersCommand.cs
new file mode 100644
index 0000000..ccd072a
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/SuggestedUsersCommand.cs
@@ -0,0 +1,76 @@
+//-----------------------------------------------------------------------
+// <copyright file="SuggestedUsersCommand.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The suggested users command class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer.Commands
+{
+    using System;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The suggested users command class
+    /// </summary>
+    /// <remarks>http://dev.twitter.com/doc/get/users/suggestions/:slug</remarks>
+    internal class SuggestedUsersCommand : TwitterCommand<TwitterUserCategory>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="SuggestedUsersCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="categorySlug">The category slug.</param>
+        /// <param name="options">The options.</param>
+        public SuggestedUsersCommand(OAuthTokens tokens, string categorySlug, OptionalProperties options)
+            : base(HTTPVerb.GET, string.Format("users/suggestions/{0}.json", categorySlug), tokens, options)
+        {
+            if (string.IsNullOrEmpty(categorySlug))
+            {
+                throw new ArgumentNullException("categorySlug", "A category slug is required");
+            }
+
+            this.Slug = categorySlug;
+        }
+
+        /// <summary>
+        /// Gets or sets the slug.
+        /// </summary>
+        /// <value>The slug.</value>
+        public string Slug { get; set; }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        {
+            this.RequestParameters.Add("slug", this.Slug);
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/TwitterUser.cs b/lib/Twitterizer/Twitterizer2/Methods/User/TwitterUser.cs
index 7c246a8..4bcff05 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/User/TwitterUser.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/TwitterUser.cs
@@ -34,82 +34,64 @@
 namespace Twitterizer
 {
     using System;
-    using System.ComponentModel;
     using System.Diagnostics;
+#if !SILVERLIGHT
     using System.Drawing;
+#endif
     using Newtonsoft.Json;
-    using Twitterizer.Core;
+    using Core;
+    using System.Runtime.Serialization;
 
     /// <include file='TwitterUser.xml' path='TwitterUser/TwitterUser/*'/>
     [JsonObject(MemberSerialization.OptIn)]
     [DebuggerDisplay("@{ScreenName}")]
+#if !SILVERLIGHT
     [Serializable]
-    public class TwitterUser : Core.TwitterObject
+#endif
+    [DataContract]
+    public class TwitterUser : TwitterObject
     {
-        public static void Show(string username, OptionalProperties options, Action<TwitterUser> function)
-        {
-            Func<string, OptionalProperties, TwitterUser> methodToCall = new Func<string, OptionalProperties, TwitterUser>(Show);
-
-            AsyncOperation operation = AsyncOperationManager.CreateOperation(null);
-            methodToCall.BeginInvoke(
-                username,
-                options,
-                (AsyncCallback)((IAsyncResult result) =>
-                    {
-                        function(methodToCall.EndInvoke(result));
-                    }), 
-                null);
-        }
-
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="TwitterUser"/> class.
-        /// </summary>
-        public TwitterUser()
-            : base()
-        {
-        }
-
-        /// <summary>
-        /// Gets a value indicating whether this instance is empty.
-        /// </summary>
-        /// <value><c>true</c> if this instance is empty; otherwise, <c>false</c>.</value>
-        internal virtual bool IsEmpty { get { return false; } }
-
         #region Properties
         /// <summary>
         /// Gets or sets the User ID.
         /// </summary>
         /// <value>The User ID.</value>
-        [JsonProperty(PropertyName = "id")]
+        [DataMember, JsonProperty(PropertyName = "id")]
         public decimal Id { get; set; }
 
         /// <summary>
+        /// Gets or sets the string id.
+        /// </summary>
+        /// <value>The string id.</value>
+        [DataMember, JsonProperty(PropertyName = "str_id")]
+        public string StringId { get; set; }
+
+        /// <summary>
         /// Gets or sets the name of the user.
         /// </summary>
         /// <value>The name of the user.</value>
-        [JsonProperty(PropertyName = "name")]
+        [DataMember, JsonProperty(PropertyName = "name")]
         public string Name { get; set; }
 
         /// <summary>
         /// Gets or sets the location.
         /// </summary>
         /// <value>The location.</value>
-        [JsonProperty(PropertyName = "location")]
+        [DataMember, JsonProperty(PropertyName = "location")]
         public string Location { get; set; }
 
         /// <summary>
         /// Gets or sets the description.
         /// </summary>
         /// <value>The description.</value>
-        [JsonProperty(PropertyName = "description")]
+        [DataMember, JsonProperty(PropertyName = "description")]
         public string Description { get; set; }
 
         /// <summary>
         /// Gets or sets the status.
         /// </summary>
         /// <value>The status.</value>
-        [JsonProperty(PropertyName = "status")]
+        [DataMember, JsonProperty(PropertyName = "status")]
         public TwitterStatus Status { get; set; }
 
         /// <summary>
@@ -118,48 +100,49 @@ namespace Twitterizer
         /// <value>The created date.</value>
         [JsonProperty(PropertyName = "created_at")]
         [JsonConverter(typeof(TwitterizerDateConverter))]
+        [DataMember]
         public DateTime? CreatedDate { get; set; }
 
         /// <summary>
         /// Gets or sets the time zone.
         /// </summary>
         /// <value>The time zone.</value>
-        [JsonProperty(PropertyName = "time_zone")]
+        [DataMember, JsonProperty(PropertyName = "time_zone")]
         public string TimeZone { get; set; }
 
         /// <summary>
         /// Gets or sets the number of followers.
         /// </summary>
         /// <value>The number of followers.</value>
-        [JsonProperty(PropertyName = "followers_count")]
+        [DataMember, JsonProperty(PropertyName = "followers_count")]
         public long? NumberOfFollowers { get; set; }
 
         /// <summary>
         /// Gets or sets the number of statuses.
         /// </summary>
         /// <value>The number of statuses.</value>
-        [JsonProperty(PropertyName = "statuses_count")]
+        [DataMember, JsonProperty(PropertyName = "statuses_count")]
         public long NumberOfStatuses { get; set; }
 
         /// <summary>
         /// Gets or sets the number of friends.
         /// </summary>
         /// <value>The number of friends.</value>
-        [JsonProperty(PropertyName = "friends_count")]
+        [DataMember, JsonProperty(PropertyName = "friends_count")]
         public long NumberOfFriends { get; set; }
 
         /// <summary>
         /// Gets or sets a value indicating whether the user has enabled contributors access to his or her account.
         /// </summary>
         /// <value>The is contributors enabled value.</value>
-        [JsonProperty(PropertyName = "contributors_enabled")]
+        [DataMember, JsonProperty(PropertyName = "contributors_enabled")]
         public bool IsContributorsEnabled { get; set; }
 
         /// <summary>
         /// Gets or sets the language.
         /// </summary>
         /// <value>The language.</value>
-        [JsonProperty(PropertyName = "lang")]
+        [DataMember, JsonProperty(PropertyName = "lang")]
         public string Language { get; set; }
 
         /// <summary>
@@ -168,14 +151,14 @@ namespace Twitterizer
         /// <value>
         /// <c>true</c> if the user receives notifications; otherwise, <c>false</c>.
         /// </value>
-        [JsonProperty(PropertyName = "notifications")]
+        [DataMember, JsonProperty(PropertyName = "notifications")]
         public bool? DoesReceiveNotifications { get; set; }
 
         /// <summary>
         /// Gets or sets the screenname.
         /// </summary>
         /// <value>The screenname.</value>
-        [JsonProperty(PropertyName = "screen_name")]
+        [DataMember, JsonProperty(PropertyName = "screen_name")]
         public string ScreenName { get; set; }
 
         /// <summary>
@@ -184,21 +167,21 @@ namespace Twitterizer
         /// <value>
         /// <c>true</c> if the authenticated user is following this user; otherwise, <c>false</c>.
         /// </value>
-        [JsonProperty(PropertyName = "following")]
+        [DataMember, JsonProperty(PropertyName = "following")]
         public bool? IsFollowing { get; set; }
 
         /// <summary>
         /// Gets or sets the a value indicating whether the authenticated user is followed by this user.
         /// </summary>
         /// <value>The is followed by.</value>
-        [JsonProperty(PropertyName = "followed_by")]
+        [DataMember, JsonProperty(PropertyName = "followed_by")]
         public bool? IsFollowedBy { get; set; }
 
         /// <summary>
         /// Gets or sets the number of favorites.
         /// </summary>
         /// <value>The number of favorites.</value>
-        [JsonProperty(PropertyName = "favourites_count")]
+        [DataMember, JsonProperty(PropertyName = "favourites_count")]
         public long NumberOfFavorites { get; set; }
 
         /// <summary>
@@ -207,7 +190,7 @@ namespace Twitterizer
         /// <value>
         /// <c>true</c> if this user is protected; otherwise, <c>false</c>.
         /// </value>
-        [JsonProperty(PropertyName = "protected")]
+        [DataMember, JsonProperty(PropertyName = "protected")]
         public bool IsProtected { get; set; }
 
         /// <summary>
@@ -216,7 +199,7 @@ namespace Twitterizer
         /// <value>
         /// <c>true</c> if this user is geo enabled; otherwise, <c>false</c>.
         /// </value>
-        [JsonProperty(PropertyName = "geo_enabled")]
+        [DataMember, JsonProperty(PropertyName = "geo_enabled")]
         public bool? IsGeoEnabled { get; set; }
 
         /// <summary>
@@ -224,42 +207,51 @@ namespace Twitterizer
         /// </summary>
         /// <value>The time zone offset.</value>
         /// <remarks>Also called the Coordinated Universal Time (UTC) offset.</remarks>
-        [JsonProperty(PropertyName = "utc_offset")]
+        [DataMember, JsonProperty(PropertyName = "utc_offset")]
         public double? TimeZoneOffset { get; set; }
 
         /// <summary>
         /// Gets or sets the user's website.
         /// </summary>
         /// <value>The website address.</value>
-        [JsonProperty(PropertyName = "url")]
+        [DataMember, JsonProperty(PropertyName = "url")]
         public string Website { get; set; }
 
         /// <summary>
         /// Gets or sets the listed count.
         /// </summary>
         /// <value>The listed count.</value>
-        [JsonProperty(PropertyName = "listed_count")]
+        [DataMember, JsonProperty(PropertyName = "listed_count")]
         public int ListedCount { get; set; }
 
         /// <summary>
         /// Gets or sets a value indicating whether [follow request sent].
         /// </summary>
         /// <value><c>true</c> if [follow request sent]; otherwise, <c>false</c>.</value>
-        [JsonProperty(PropertyName = "follow_request_sent")]
+        [DataMember, JsonProperty(PropertyName = "follow_request_sent")]
         public bool? FollowRequestSent { get; set; }
 
+        /// <summary>
+        /// Gets or sets a value indicating whether the user is verified.
+        /// </summary>
+        /// <value><c>true</c> if the user is verified; otherwise, <c>false</c>.</value>
+        [DataMember, JsonProperty(PropertyName = "verified")]
+        public bool? Verified { get; set; }
+
         #region Profile Layout Properties
         /// <summary>
         /// Gets or sets the color of the profile background.
         /// </summary>
         /// <value>The color of the profile background.</value>
-        [JsonProperty(PropertyName = "profile_background_color")]
+        [DataMember, JsonProperty(PropertyName = "profile_background_color")]
         public string ProfileBackgroundColorString { get; set; }
 
+#if !SILVERLIGHT
         /// <summary>
         /// Gets the color of the profile background.
         /// </summary>
         /// <value>The color of the profile background.</value>
+        [DataMember]
         public Color ProfileBackgroundColor
         {
             get
@@ -267,27 +259,29 @@ namespace Twitterizer
                 return ConversionUtility.FromTwitterString(this.ProfileBackgroundColorString);
             }
         }
-
+#endif
         /// <summary>
         /// Gets or sets a value indicating whether this user's profile background image is tiled.
         /// </summary>
         /// <value>
         /// <c>true</c> if this user's profile background image is tiled; otherwise, <c>false</c>.
         /// </value>
-        [JsonProperty(PropertyName = "profile_background_tile")]
+        [DataMember, JsonProperty(PropertyName = "profile_background_tile")]
         public bool? IsProfileBackgroundTiled { get; set; }
 
         /// <summary>
         /// Gets or sets the color of the profile link.
         /// </summary>
         /// <value>The color of the profile link.</value>
-        [JsonProperty(PropertyName = "profile_link_color")]
+        [DataMember, JsonProperty(PropertyName = "profile_link_color")]
         public string ProfileLinkColorString { get; set; }
 
+#if !SILVERLIGHT
         /// <summary>
         /// Gets the color of the profile link.
         /// </summary>
         /// <value>The color of the profile link.</value>
+        [DataMember]
         public Color ProfileLinkColor
         {
             get
@@ -295,25 +289,28 @@ namespace Twitterizer
                 return ConversionUtility.FromTwitterString(this.ProfileLinkColorString);
             }
         }
+#endif
 
         /// <summary>
         /// Gets or sets the profile background image location.
         /// </summary>
         /// <value>The profile background image location.</value>
-        [JsonProperty(PropertyName = "profile_background_image_url")]
+        [DataMember, JsonProperty(PropertyName = "profile_background_image_url")]
         public string ProfileBackgroundImageLocation { get; set; }
 
         /// <summary>
         /// Gets or sets the color of the profile text.
         /// </summary>
         /// <value>The color of the profile text.</value>
-        [JsonProperty(PropertyName = "profile_text_color")]
+        [DataMember, JsonProperty(PropertyName = "profile_text_color")]
         public string ProfileTextColorString { get; set; }
 
+#if !SILVERLIGHT
         /// <summary>
         /// Gets the color of the profile text.
         /// </summary>
         /// <value>The color of the profile text.</value>
+        [DataMember]
         public Color ProfileTextColor
         {
             get
@@ -321,25 +318,35 @@ namespace Twitterizer
                 return ConversionUtility.FromTwitterString(this.ProfileTextColorString);
             }
         }
+#endif
 
         /// <summary>
         /// Gets or sets the profile image location.
         /// </summary>
         /// <value>The profile image location.</value>
-        [JsonProperty(PropertyName = "profile_image_url")]
+        [DataMember, JsonProperty(PropertyName = "profile_image_url")]
         public string ProfileImageLocation { get; set; }
 
         /// <summary>
+        /// Gets or sets the secure profile image location (https).
+        /// </summary>
+        /// <value>The profile image location.</value>
+        [DataMember, JsonProperty(PropertyName = "profile_image_url_https")]
+        public string ProfileImageSecureLocation { get; set; }
+
+        /// <summary>
         /// Gets or sets the color of the profile sidebar border.
         /// </summary>
         /// <value>The color of the profile sidebar border.</value>
-        [JsonProperty(PropertyName = "profile_sidebar_border_color")]
+        [DataMember, JsonProperty(PropertyName = "profile_sidebar_border_color")]
         public string ProfileSidebarBorderColorString { get; set; }
 
+#if !SILVERLIGHT
         /// <summary>
         /// Gets the color of the profile sidebar border.
         /// </summary>
         /// <value>The color of the profile sidebar border.</value>
+        [DataMember]
         public Color ProfileSidebarBorderColor
         {
             get
@@ -347,141 +354,149 @@ namespace Twitterizer
                 return ConversionUtility.FromTwitterString(this.ProfileSidebarBorderColorString);
             }
         }
+#endif
         #endregion
 
         #endregion
 
         /// <include file='TwitterUser.xml' path='TwitterUser/Show[@name="Common"]/*'/>
         /// <include file='TwitterUser.xml' path='TwitterUser/Show[@name="ByIDWithTokensAndOptions"]/*'/>
-        public static TwitterUser Show(OAuthTokens tokens, decimal id, OptionalProperties options)
+        public static TwitterResponse<TwitterUser> Show(OAuthTokens tokens, decimal id, OptionalProperties options)
         {
             Commands.ShowUserCommand command = new Commands.ShowUserCommand(tokens, id, string.Empty, options);
 
-            return Core.CommandPerformer<TwitterUser>.PerformAction(command);
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <include file='TwitterUser.xml' path='TwitterUser/Show[@name="Common"]/*'/>
         /// <include file='TwitterUser.xml' path='TwitterUser/Show[@name="ByIDWithOptions"]/*'/>
-        public static TwitterUser Show(decimal id, OptionalProperties options)
+        public static TwitterResponse<TwitterUser> Show(decimal id, OptionalProperties options)
         {
             return Show(null, id, options);
         }
 
         /// <include file='TwitterUser.xml' path='TwitterUser/Show[@name="Common"]/*'/>
         /// <include file='TwitterUser.xml' path='TwitterUser/Show[@name="ByIDWithTokens"]/*'/>
-        public static TwitterUser Show(OAuthTokens tokens, decimal id)
+        public static TwitterResponse<TwitterUser> Show(OAuthTokens tokens, decimal id)
         {
             return Show(tokens, id, null);
         }
 
         /// <include file='TwitterUser.xml' path='TwitterUser/Show[@name="Common"]/*'/>
         /// <include file='TwitterUser.xml' path='TwitterUser/Show[@name="ByID"]/*'/>
-        public static TwitterUser Show(decimal id)
+        public static TwitterResponse<TwitterUser> Show(decimal id)
         {
             return Show(null, id, null);
         }
 
         /// <include file='TwitterUser.xml' path='TwitterUser/Show[@name="Common"]/*'/>
         /// <include file='TwitterUser.xml' path='TwitterUser/Show[@name="ByUsernameWithTokensAndOptions"]/*'/>
-        public static TwitterUser Show(OAuthTokens tokens, string username, OptionalProperties options)
+        public static TwitterResponse<TwitterUser> Show(OAuthTokens tokens, string username, OptionalProperties options)
         {
             Commands.ShowUserCommand command = new Commands.ShowUserCommand(tokens, 0, username, options);
 
-            return Core.CommandPerformer<TwitterUser>.PerformAction(command);
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <include file='TwitterUser.xml' path='TwitterUser/Show[@name="Common"]/*'/>
         /// <include file='TwitterUser.xml' path='TwitterUser/Show[@name="ByUsernameWithOptions"]/*'/>
-        public static TwitterUser Show(string username, OptionalProperties options)
+        public static TwitterResponse<TwitterUser> Show(string username, OptionalProperties options)
         {
             return Show(null, username, options);
         }
 
         /// <include file='TwitterUser.xml' path='TwitterUser/Show[@name="Common"]/*'/>
         /// <include file='TwitterUser.xml' path='TwitterUser/Show[@name="ByUsernameWithTokens"]/*'/>
-        public static TwitterUser Show(OAuthTokens tokens, string username)
+        public static TwitterResponse<TwitterUser> Show(OAuthTokens tokens, string username)
         {
             return Show(tokens, username, null);
         }
 
         /// <include file='TwitterUser.xml' path='TwitterUser/Show[@name="Common"]/*'/>
         /// <include file='TwitterUser.xml' path='TwitterUser/Show[@name="ByUsername"]/*'/>
-        public static TwitterUser Show(string username)
+        public static TwitterResponse<TwitterUser> Show(string username)
         {
             return Show(null, username, null);
         }
 
         /// <include file='TwitterUser.xml' path='TwitterUser/Search[@name="Common"]/*'/>
         /// <include file='TwitterUser.xml' path='TwitterUser/Search[@name="WithTokensAndOptions"]/*'/>
-        public static TwitterUserCollection Search(OAuthTokens tokens, string query, UserSearchOptions options)
+        public static TwitterResponse<TwitterUserCollection> Search(OAuthTokens tokens, string query, UserSearchOptions options)
         {
             Commands.UserSearchCommand command = new Commands.UserSearchCommand(tokens, query, options);
 
-            TwitterUserCollection result = Core.CommandPerformer<TwitterUserCollection>.PerformAction(command);
-
-            if (result != null)
-                result.PagedCommand = command;
-
-            return result;
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <include file='TwitterUser.xml' path='TwitterUser/Search[@name="Common"]/*'/>
         /// <include file='TwitterUser.xml' path='TwitterUser/Search[@name="WithTokens"]/*'/>
-        public static TwitterUserCollection Search(OAuthTokens tokens, string query)
+        public static TwitterResponse<TwitterUserCollection> Search(OAuthTokens tokens, string query)
         {
             return Search(tokens, query, null);
         }
 
-        public static TwitterUserCollection Lookup(OAuthTokens tokens, LookupUsersOptions options)
+        /// <summary>
+        /// Return up to 100 users worth of extended information, specified by either ID, screen name, or combination of the two.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterUserCollection> Lookup(OAuthTokens tokens, LookupUsersOptions options)
         {
             Commands.LookupUsersCommand command = new Commands.LookupUsersCommand(tokens, options);
 
-            return Core.CommandPerformer<TwitterUserCollection>.PerformAction(command);
+            return Core.CommandPerformer.PerformAction(command);
         }
 
-        #region Account update methods
+        #region Retweeted By
         /// <summary>
-        /// Sets one or more hex values that control the color scheme of the authenticating user's profile page on twitter.com
+        /// Show user objects of up to 100 members who retweeted the status.
         /// </summary>
         /// <param name="tokens">The tokens.</param>
+        /// <param name="statusId">The status id.</param>
         /// <param name="options">The options.</param>
-        /// <returns>
-        /// The user, with updated data, as a <see cref="TwitterUser"/>
-        /// </returns>
-        public static TwitterUser UpdateProfileColors(OAuthTokens tokens, UpdateProfileColorsOptions options)
+        /// <returns>A collection of user objects.</returns>
+        public static TwitterResponse<TwitterUserCollection> RetweetedBy(OAuthTokens tokens, decimal statusId, RetweetedByOptions options)
         {
-            Commands.UpdateProfileColorsCommand command = new Twitterizer.Commands.UpdateProfileColorsCommand(tokens, options);
+            Commands.RetweetedByCommand command = new Commands.RetweetedByCommand(tokens, statusId, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
 
-            return CommandPerformer<TwitterUser>.PerformAction(command);
+        /// <summary>
+        /// Show user objects of up to 100 members who retweeted the status.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="statusId">The status id.</param>
+        /// <returns>A collection of user objects.</returns>
+        public static TwitterResponse<TwitterUserCollection> RetweetedBy(OAuthTokens tokens, decimal statusId)
+        {
+            return RetweetedBy(tokens, statusId, null);
         }
 
         /// <summary>
-        /// Updates the authenticating user's profile image. 
+        /// Show user ids of up to 100 members who retweeted the status.
         /// </summary>
         /// <param name="tokens">The tokens.</param>
-        /// <param name="image">The avatar image for the profile. Must be a valid GIF, JPG, or PNG image of less than 700 kilobytes in size. Images with width larger than 500 pixels will be scaled down.</param>
+        /// <param name="statusId">The status id.</param>
         /// <param name="options">The options.</param>
-        /// <returns>
-        /// The user, with updated data, as a <see cref="TwitterUser"/>
-        /// </returns>
-        public static TwitterUser UpdateProfileImage(OAuthTokens tokens, TwitterImage image, OptionalProperties options)
+        /// <returns>A collection of user ids.</returns>
+        public static TwitterResponse<UserIdCollection> RetweetedByIds(OAuthTokens tokens, decimal statusId, RetweetedByIdsOptions options)
         {
-            Commands.UpdateProfileImageCommand command = new Twitterizer.Commands.UpdateProfileImageCommand(tokens, image, options);
+            Commands.RetweetedByIdsCommand command = new Commands.RetweetedByIdsCommand(tokens, statusId, options);
 
-            return CommandPerformer<TwitterUser>.PerformAction(command);
+            return Core.CommandPerformer.PerformAction(command);
         }
 
         /// <summary>
-        /// Updates the authenticating user's profile image.
+        /// Show user ids of up to 100 members who retweeted the status.
         /// </summary>
         /// <param name="tokens">The tokens.</param>
-        /// <param name="image">The avatar image for the profile. Must be a valid GIF, JPG, or PNG image of less than 700 kilobytes in size. Images with width larger than 500 pixels will be scaled down.</param>
-        /// <returns>
-        /// The user, with updated data, as a <see cref="TwitterUser"/>
-        /// </returns>
-        public static TwitterUser UpdateProfileImage(OAuthTokens tokens, TwitterImage image)
+        /// <param name="statusId">The status id.</param>
+        /// <returns>A collection of user ids.</returns>
+        public static TwitterResponse<UserIdCollection> RetweetedByIds(OAuthTokens tokens, decimal statusId)
         {
-            return UpdateProfileImage(tokens, image, null);
+            return RetweetedByIds(tokens, statusId, null);
         }
         #endregion
     }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/TwitterUserCategory.cs b/lib/Twitterizer/Twitterizer2/Methods/User/TwitterUserCategory.cs
new file mode 100644
index 0000000..2856bd8
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/TwitterUserCategory.cs
@@ -0,0 +1,142 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterUserCategory.cs" company="Patrick 'Ricky' Smith">
+//  This file is part of the Twitterizer library (http://www.twitterizer.net/)
+// 
+//  Copyright (c) 2010, Patrick "Ricky" Smith (ricky at digitally-born.com)
+//  All rights reserved.
+//  
+//  Redistribution and use in source and binary forms, with or without modification, are 
+//  permitted provided that the following conditions are met:
+// 
+//  - Redistributions of source code must retain the above copyright notice, this list 
+//    of conditions and the following disclaimer.
+//  - 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.
+//  - Neither the name of the Twitterizer 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.
+// </copyright>
+// <author>Ricky Smith</author>
+// <summary>The TwitterUserCategory and TwitterUserCategoryCollection classes.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer
+{
+    using System;
+    using Newtonsoft.Json;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// Represents a suggested user category
+    /// </summary>
+#if !SILVERLIGHT 
+    [Serializable]
+#endif
+    public class TwitterUserCategory : Core.TwitterObject
+    {
+        /// <summary>
+        /// Gets or sets the name.
+        /// </summary>
+        /// <value>The name.</value>
+        [JsonProperty(PropertyName = "name")]
+        public string Name { get; set; }
+
+        /// <summary>
+        /// Gets or sets the slug.
+        /// </summary>
+        /// <value>The slug.</value>
+        [JsonProperty(PropertyName = "slug")]
+        public string Slug { get; set; }
+
+        /// <summary>
+        /// Gets or sets the number of users.
+        /// Only available in list of categories.
+        /// </summary>
+        /// <value>The number of users.</value>
+        [JsonProperty(PropertyName = "size")]
+        public int NumberOfUsers { get; set; }
+
+        /// <summary>
+        /// Gets or sets the users.
+        /// Users are only returned for a single category.
+        /// </summary>
+        /// <value>The users.</value>
+        [JsonProperty(PropertyName = "users")]
+        public TwitterUserCollection Users { get; set; }
+
+        /// <summary>
+        /// Access to Twitter's suggested user list. This returns the list of suggested user categories. The category can be used in the users/suggestions/category endpoint to get the users in that category.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>A collection of categories without user data.</returns>
+        public static TwitterResponse<TwitterUserCategoryCollection> SuggestedUserCategories(OAuthTokens tokens, OptionalProperties options)
+        {
+            Commands.SuggestedUserCategoriesCommand command = new Commands.SuggestedUserCategoriesCommand(tokens, options);
+
+            return CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Access to Twitter's suggested user list. This returns the list of suggested user categories. The category can be used in the users/suggestions/category endpoint to get the users in that category.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <returns>
+        /// A collection of categories without user data.
+        /// </returns>
+        public static TwitterResponse<TwitterUserCategoryCollection> SuggestedUserCategories(OAuthTokens tokens)
+        {
+            return SuggestedUserCategories(tokens, null);
+        }
+
+        /// <summary>
+        /// Access the users in a given category of the Twitter suggested user list.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="categorySlug">The category slug.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        /// <remarks>It is recommended that end clients cache this data for no more than one hour.</remarks>
+        public static TwitterResponse<TwitterUserCategory> SuggestedUsers(OAuthTokens tokens, string categorySlug, OptionalProperties options)
+        {
+            Commands.SuggestedUsersCommand command = new Commands.SuggestedUsersCommand(tokens, categorySlug, options);
+
+            return CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Access the users in a given category of the Twitter suggested user list.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="categorySlug">The category slug.</param>
+        /// <returns></returns>
+        /// <remarks>It is recommended that end clients cache this data for no more than one hour.</remarks>
+        public static TwitterResponse<TwitterUserCategory> SuggestedUsers(OAuthTokens tokens, string categorySlug)
+        {
+            return SuggestedUsers(tokens, categorySlug, null);
+        }
+    }
+
+    /// <summary>
+    /// Represents a suggested category
+    /// </summary>
+#if !SILVERLIGHT 
+    [Serializable]
+#endif
+    public class TwitterUserCategoryCollection : Core.TwitterCollection<TwitterUserCategory>, ITwitterObject
+    {
+        // This intentionally left blank.
+        // Check out Girl Talk. He's a great DJ.
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/TwitterUserCollection.cs b/lib/Twitterizer/Twitterizer2/Methods/User/TwitterUserCollection.cs
index 522bccf..0cd8798 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/User/TwitterUserCollection.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/TwitterUserCollection.cs
@@ -36,108 +36,37 @@ namespace Twitterizer
     using Twitterizer.Core;
     using Newtonsoft.Json.Linq;
     using Newtonsoft.Json;
+    using System.Runtime.Serialization;
 
     /// <summary>
     /// The TwitterUserCollection class.
     /// </summary>
+#if !SILVERLIGHT
     [System.Serializable]
-    public class TwitterUserCollection : TwitterCollection<TwitterUser>
+#endif
+    [DataContract]
+    public class TwitterUserCollection : TwitterCollection<TwitterUser>, ITwitterObject
     {
         /// <summary>
         /// Gets or sets the next cursor.
         /// </summary>
         /// <value>The next cursor.</value>
+        [DataMember]
         public long NextCursor { get; internal set; }
 
         /// <summary>
         /// Gets or sets the previous cursor.
         /// </summary>
         /// <value>The previous cursor.</value>
+        [DataMember]
         public long PreviousCursor { get; internal set; }
 
         /// <summary>
         /// Gets or sets information about the user's rate usage.
         /// </summary>
         /// <value>The rate limiting object.</value>
-        public new RateLimiting RateLimiting { get; internal set; }
-
-        /// <summary>
-        /// Gets or sets the paged command.
-        /// </summary>
-        /// <value>The paged command.</value>
-        internal PagedCommand<TwitterUserCollection> PagedCommand { get; set; }
-
-        /// <summary>
-        /// Gets or sets the cursor paged command.
-        /// </summary>
-        /// <value>The cursor paged command.</value>
-        internal CursorPagedCommand<TwitterUserCollection> CursorPagedCommand { get; set; }
-
-        /// <summary>
-        /// Gets the next page.
-        /// </summary>
-        /// <returns>A <see cref="TwitterUserCollection"/> instance.</returns>
-        /// <value>The next page.</value>
-        public TwitterUserCollection NextPage()
-        {
-            if (this.PagedCommand != null)
-            {
-                PagedCommand<TwitterUserCollection> newCommand =
-                    (PagedCommand<TwitterUserCollection>)this.PagedCommand.Clone();
-                newCommand.Page += 1;
-
-                TwitterUserCollection result = Core.CommandPerformer<TwitterUserCollection>.PerformAction(newCommand);
-                result.PagedCommand = newCommand;
-                return result;
-            }
-            else if (this.CursorPagedCommand != null)
-            {
-                CursorPagedCommand<TwitterUserCollection> newCommand =
-                    (CursorPagedCommand<TwitterUserCollection>)this.CursorPagedCommand.Clone();
-                newCommand.Cursor = this.NextCursor;
-
-                TwitterUserCollection result = Core.CommandPerformer<TwitterUserCollection>.PerformAction(newCommand);
-                result.CursorPagedCommand = newCommand;
-                return result;
-            }
-            else
-            {
-                throw new System.NotSupportedException("Paging is not supported for this API call.");
-            }
-        }
-
-        /// <summary>
-        /// Gets the previous page.
-        /// </summary>
-        /// <returns>A <see cref="TwitterUserCollection"/> instance.</returns>
-        /// <value>The previous page.</value>
-        public TwitterUserCollection PreviousPage()
-        {
-            if (this.PagedCommand != null)
-            {
-                PagedCommand<TwitterUserCollection> newCommand =
-                    (PagedCommand<TwitterUserCollection>)this.PagedCommand.Clone();
-                newCommand.Page -= 1;
-
-                TwitterUserCollection result = Core.CommandPerformer<TwitterUserCollection>.PerformAction(newCommand);
-                result.PagedCommand = newCommand;
-                return result;
-            }
-            else if (this.CursorPagedCommand != null)
-            {
-                CursorPagedCommand<TwitterUserCollection> newCommand =
-                    (CursorPagedCommand<TwitterUserCollection>)this.CursorPagedCommand.Clone();
-                newCommand.Cursor = this.PreviousCursor;
-
-                TwitterUserCollection result = Core.CommandPerformer<TwitterUserCollection>.PerformAction(newCommand);
-                result.CursorPagedCommand = newCommand;
-                return result;
-            }
-            else
-            {
-                throw new System.NotSupportedException("Paging is not supported for this API call.");
-            }
-        }
+        [DataMember]
+        public RateLimiting RateLimiting { get; internal set; }
 
         /// <summary>
         /// Deserializes the specified value.
@@ -147,7 +76,9 @@ namespace Twitterizer
         internal static TwitterUserCollection DeserializeWrapper(JObject value)
         {
             if (value == null || value.SelectToken("users") == null)
+            {
                 return null;
+            }
 
             TwitterUserCollection result = JsonConvert.DeserializeObject<TwitterUserCollection>(value.SelectToken("users").ToString());
             result.NextCursor = value.SelectToken("next_cursor").Value<long>();
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/UserSearchCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/User/UserSearchCommand.cs
index 40a2e48..a881e1d 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/User/UserSearchCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/UserSearchCommand.cs
@@ -41,7 +41,7 @@ namespace Twitterizer.Commands
     /// <summary>
     /// The User Search Command class.
     /// </summary>
-    internal sealed class UserSearchCommand : PagedCommand<TwitterUserCollection>
+    internal sealed class UserSearchCommand : TwitterCommand<TwitterUserCollection>
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="UserSearchCommand"/> class.
@@ -76,34 +76,21 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
-            if (this.Page <= 0)
-                this.Page = 1;
-
             this.RequestParameters.Add("q", this.Query);
 
             UserSearchOptions options = this.OptionalProperties as UserSearchOptions;
 
-            if (options != null)
+            if (options == null)
             {
-                if (options.NumberPerPage > 0)
-                    this.RequestParameters.Add("per_page", options.NumberPerPage.ToString(CultureInfo.InvariantCulture));
+                this.RequestParameters.Add("page", "1");
 
-                if (this.Page <= 1 && options.Page > 1)
-                    this.Page = options.Page;
+                return;
             }
 
-            this.RequestParameters.Add("page", this.Page.ToString(CultureInfo.InvariantCulture));
-        }
+            if (options.NumberPerPage > 0)
+                this.RequestParameters.Add("per_page", options.NumberPerPage.ToString(CultureInfo.InvariantCulture));
 
-        /// <summary>
-        /// Clones this instance.
-        /// </summary>
-        /// <returns>
-        /// A new instance of the <see cref="Twitterizer.Core.PagedCommand{T}"/> interface.
-        /// </returns>
-        internal override TwitterCommand<TwitterUserCollection> Clone()
-        {
-            return new UserSearchCommand(this.Tokens, this.Query, this.OptionalProperties as UserSearchOptions);
+            this.RequestParameters.Add("page", options.Page > 0 ? options.Page.ToString(CultureInfo.InvariantCulture) : "1");
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/User/UserSearchOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/User/UserSearchOptions.cs
index 89e9d09..61ce685 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/User/UserSearchOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/User/UserSearchOptions.cs
@@ -37,7 +37,9 @@ namespace Twitterizer
     /// <summary>
     /// The user search options class. Provides a payload for optional parameters of the UserSearchCommand class.
     /// </summary>
+#if !SILVERLIGHT
     [System.Serializable]
+#endif
     public class UserSearchOptions : OptionalProperties
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/OAuth/OAuthTokenResponse.cs b/lib/Twitterizer/Twitterizer2/OAuth/OAuthTokenResponse.cs
index 4b12c3a..85aa1ad 100644
--- a/lib/Twitterizer/Twitterizer2/OAuth/OAuthTokenResponse.cs
+++ b/lib/Twitterizer/Twitterizer2/OAuth/OAuthTokenResponse.cs
@@ -38,7 +38,9 @@ namespace Twitterizer
     /// <summary>
     /// Values returned by Twitter when getting a request token or an access token.
     /// </summary>
+#if !SILVERLIGHT
     [Serializable]
+#endif
     public class OAuthTokenResponse
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/OAuth/OAuthTokens.cs b/lib/Twitterizer/Twitterizer2/OAuth/OAuthTokens.cs
index 0d4aacd..44fd9b5 100644
--- a/lib/Twitterizer/Twitterizer2/OAuth/OAuthTokens.cs
+++ b/lib/Twitterizer/Twitterizer2/OAuth/OAuthTokens.cs
@@ -35,31 +35,75 @@
 namespace Twitterizer
 {
     /// <include file='OAuthTokens.xml' path='OAuthTokens/OAuthTokens/*'/>
+#if !SILVERLIGHT
     [System.Serializable]
+#endif
     public class OAuthTokens
     {
         /// <summary>
         /// Gets or sets the access token.
         /// </summary>
         /// <value>The access token.</value>
-        public string AccessToken { get; set; }
+        public string AccessToken { internal get; set; }
 
         /// <summary>
         /// Gets or sets the access token secret.
         /// </summary>
         /// <value>The access token secret.</value>
-        public string AccessTokenSecret { get; set; }
+        public string AccessTokenSecret { internal get; set; }
 
         /// <summary>
         /// Gets or sets the consumer key.
         /// </summary>
         /// <value>The consumer key.</value>
-        public string ConsumerKey { get; set; }
+        public string ConsumerKey { internal get; set; }
 
         /// <summary>
         /// Gets or sets the consumer secret.
         /// </summary>
         /// <value>The consumer secret.</value>
-        public string ConsumerSecret { get; set; }
+        public string ConsumerSecret { internal get; set; }
+
+        /// <summary>
+        /// Gets a value indicating whether this instance has consumer token values.
+        /// </summary>
+        /// <value>
+        /// 	<c>true</c> if this instance has consumer token; otherwise, <c>false</c>.
+        /// </value>
+        public bool HasConsumerToken
+        {
+            get
+            {
+                return !string.IsNullOrEmpty(this.ConsumerKey) && !string.IsNullOrEmpty(this.ConsumerSecret);
+            }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether this instance has access token values.
+        /// </summary>
+        /// <value>
+        /// 	<c>true</c> if this instance has access token; otherwise, <c>false</c>.
+        /// </value>
+        public bool HasAccessToken
+        {
+            get
+            {
+                return !string.IsNullOrEmpty(this.AccessToken) && !string.IsNullOrEmpty(this.AccessTokenSecret);
+            }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether this instance has values. This does not verify that the values are correct.
+        /// </summary>
+        /// <value>
+        /// <c>true</c> if this instance has values; otherwise, <c>false</c>.
+        /// </value>
+        public bool HasBothTokens
+        {
+            get
+            {
+                return this.HasAccessToken && this.HasConsumerToken;
+            }
+        }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/OAuth/OAuthUtility.cs b/lib/Twitterizer/Twitterizer2/OAuth/OAuthUtility.cs
index ae17145..3e8963a 100644
--- a/lib/Twitterizer/Twitterizer2/OAuth/OAuthUtility.cs
+++ b/lib/Twitterizer/Twitterizer2/OAuth/OAuthUtility.cs
@@ -35,13 +35,14 @@
 namespace Twitterizer
 {
     using System;
-    using System.Diagnostics.CodeAnalysis;
     using System.Globalization;
     using System.IO;
     using System.Net;
     using System.Text;
     using System.Text.RegularExpressions;
+#if !SILVERLIGHT
     using System.Web;
+#endif
 
     /// <include file='OAuthUtility.xml' path='OAuthUtility/OAuthUtility/*'/>
     public static class OAuthUtility
@@ -52,19 +53,83 @@ namespace Twitterizer
         /// </summary>
         /// <param name="consumerKey">The consumer key.</param>
         /// <param name="consumerSecret">The consumer secret.</param>
-        /// <param name="callbackAddress">The callback address.</param>
+        /// <param name="callbackAddress">The callback address. For PIN-based authentication "oob" should be supplied.</param>
         /// <returns></returns>
         public static OAuthTokenResponse GetRequestToken(string consumerKey, string consumerSecret, string callbackAddress)
         {
-            return GetRequestToken(consumerKey, consumerSecret, callbackAddress, null);
+            if (string.IsNullOrEmpty(consumerKey))
+            {
+                throw new ArgumentNullException("consumerKey");
+            }
+
+            if (string.IsNullOrEmpty(consumerSecret))
+            {
+                throw new ArgumentNullException("consumerSecret");
+            }
+
+            if (string.IsNullOrEmpty(callbackAddress))
+            {
+                throw new ArgumentNullException("callbackAddress", @"You must always provide a callback url when obtaining a request token. For PIN-based authentication, use ""oob"" as the callback url.");
+            }
+
+            WebRequestBuilder builder = new WebRequestBuilder(
+                new Uri("https://api.twitter.com/oauth/request_token"),
+                HTTPVerb.POST,
+                new OAuthTokens { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret },
+				"");
+
+            if (!string.IsNullOrEmpty(callbackAddress))
+            {
+                builder.Parameters.Add("oauth_callback", callbackAddress);
+            }
+
+            string responseBody = null;
+
+            try
+            {
+                HttpWebResponse webResponse = builder.ExecuteRequest();
+                Stream responseStream = webResponse.GetResponseStream();
+                if (responseStream != null) responseBody = new StreamReader(responseStream).ReadToEnd();
+            }
+            catch (WebException wex)
+            {
+                throw new TwitterizerException(wex.Message, wex);
+            }
+
+            return new OAuthTokenResponse
+            {
+                Token = ParseQuerystringParameter("oauth_token", responseBody),
+                TokenSecret = ParseQuerystringParameter("oauth_token_secret", responseBody),
+                VerificationString = ParseQuerystringParameter("oauth_verifier", responseBody)
+            };
         }
 
         /// <summary>
+        /// Tries to the parse querystring parameter.
+        /// </summary>
+        /// <param name="parameterName">Name of the parameter.</param>
+        /// <param name="text">The text.</param>
+        /// <returns>The value of the parameter or an empty string.</returns>
+        /// <remarks></remarks>
+        private static string ParseQuerystringParameter(string parameterName, string text)
+        {
+            Match expressionMatch = Regex.Match(text, string.Format(@"{0}=(?<value>[^&]+)", parameterName));
+
+            if (!expressionMatch.Success)
+            {
+                return string.Empty;
+            }
+
+            return expressionMatch.Groups["value"].Value;
+        }
+
+#if !SILVERLIGHT
+        /// <summary>
         /// Gets a new OAuth request token from the twitter api.
         /// </summary>
         /// <param name="consumerKey">The consumer key.</param>
         /// <param name="consumerSecret">The consumer secret.</param>
-        /// <param name="callbackAddress">Address of the callback.</param>
+        /// <param name="callbackAddress">The callback address. For PIN-based authentication "oob" should be supplied.</param>
         /// <param name="proxy">The proxy.</param>
         /// <returns>
         /// A new <see cref="Twitterizer.OAuthTokenResponse"/> instance.
@@ -83,13 +148,14 @@ namespace Twitterizer
 
             if (string.IsNullOrEmpty(callbackAddress))
             {
-                throw new ArgumentNullException("callbackAddress", "It is recommended that you always provide a callback url when obtaining a request token.");
+                throw new ArgumentNullException("callbackAddress", @"You must always provide a callback url when obtaining a request token. For PIN-based authentication, use ""oob"" as the callback url.");
             }
 
             WebRequestBuilder builder = new WebRequestBuilder(
                 new Uri("https://api.twitter.com/oauth/request_token"),
                 HTTPVerb.POST,
-                new OAuthTokens {ConsumerKey = consumerKey, ConsumerSecret = consumerSecret}) {Proxy = proxy};
+                new OAuthTokens { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret },
+				"") { Proxy = proxy };
 
             if (!string.IsNullOrEmpty(callbackAddress))
             {
@@ -113,15 +179,16 @@ namespace Twitterizer
                                               @"oauth_token=(?<token>[^&]+)|oauth_token_secret=(?<secret>[^&]+)|oauth_verifier=(?<verifier>[^&]+)");
 
             return new OAuthTokenResponse
-                       {
-                           Token = matchedValues.Groups["token"].Value,
-                           TokenSecret = matchedValues.Groups["secret"].Value,
-                           VerificationString = matchedValues.Groups["verifier"].Value
-                       };
+            {
+                Token = matchedValues.Groups["token"].Value,
+                TokenSecret = matchedValues.Groups["secret"].Value,
+                VerificationString = matchedValues.Groups["verifier"].Value
+            };
         }
+#endif
 
         /// <summary>
-        /// Gets the access token from pin.
+        /// Gets the access token.
         /// </summary>
         /// <param name="consumerKey">The consumer key.</param>
         /// <param name="consumerSecret">The consumer secret.</param>
@@ -132,11 +199,58 @@ namespace Twitterizer
         /// </returns>
         public static OAuthTokenResponse GetAccessToken(string consumerKey, string consumerSecret, string requestToken, string verifier)
         {
-            return GetAccessToken(consumerKey, consumerSecret, requestToken, verifier, null);
+            if (string.IsNullOrEmpty(consumerKey))
+            {
+                throw new ArgumentNullException("consumerKey");
+            }
+
+            if (string.IsNullOrEmpty(consumerSecret))
+            {
+                throw new ArgumentNullException("consumerSecret");
+            }
+
+            if (string.IsNullOrEmpty(requestToken))
+            {
+                throw new ArgumentNullException("requestToken");
+            }
+
+            WebRequestBuilder builder = new WebRequestBuilder(
+                new Uri("https://api.twitter.com/oauth/access_token"),
+                HTTPVerb.GET,
+				new OAuthTokens { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret },
+				"");
+
+            if (!string.IsNullOrEmpty(verifier))
+            {
+                builder.Parameters.Add("oauth_verifier", verifier);
+            }
+
+            builder.Parameters.Add("oauth_token", requestToken);
+
+            string responseBody;
+
+            try
+            {
+                HttpWebResponse webResponse = builder.ExecuteRequest();
+
+                responseBody = new StreamReader(webResponse.GetResponseStream()).ReadToEnd();
+            }
+            catch (WebException wex)
+            {
+                throw new TwitterizerException(wex.Message, wex);
+            }
+
+            OAuthTokenResponse response = new OAuthTokenResponse();
+            response.Token = Regex.Match(responseBody, @"oauth_token=([^&]+)").Groups[1].Value;
+            response.TokenSecret = Regex.Match(responseBody, @"oauth_token_secret=([^&]+)").Groups[1].Value;
+            response.UserId = long.Parse(Regex.Match(responseBody, @"user_id=([^&]+)").Groups[1].Value, CultureInfo.CurrentCulture);
+            response.ScreenName = Regex.Match(responseBody, @"screen_name=([^&]+)").Groups[1].Value;
+            return response;
         }
 
+#if !SILVERLIGHT
         /// <summary>
-        /// Gets the access token from pin.
+        /// Gets the access token.
         /// </summary>
         /// <param name="consumerKey">The consumer key.</param>
         /// <param name="consumerSecret">The consumer secret.</param>
@@ -166,7 +280,8 @@ namespace Twitterizer
             WebRequestBuilder builder = new WebRequestBuilder(
                 new Uri("https://api.twitter.com/oauth/access_token"),
                 HTTPVerb.GET,
-                new OAuthTokens { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret });
+				new OAuthTokens { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret },
+				"");
 
             builder.Proxy = proxy;
 
@@ -197,40 +312,7 @@ namespace Twitterizer
             response.ScreenName = Regex.Match(responseBody, @"screen_name=([^&]+)").Groups[1].Value;
             return response;
         }
-
-        /// <summary>
-        /// This is a different Url Encode implementation since the default .NET one outputs the percent encoding in lower case.
-        /// While this is not a problem with the percent encoding spec, it is used in upper case throughout OAuth
-        /// </summary>
-        /// <param name="value">The value to Url encode</param>
-        /// <returns>Returns a Url encoded string</returns>
-        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Justification = "Return type is not a URL.")]
-        public static string EncodeForUrl(string value)
-        {
-            if (string.IsNullOrEmpty(value))
-            {
-                return string.Empty;
-            }
-
-            value = HttpUtility.UrlEncode(value).Replace("+", "%20");
-
-            // UrlEncode escapes with lowercase characters (e.g. %2f) but oAuth needs %2F
-            value = Regex.Replace(value, "(%[0-9a-f][0-9a-f])", c => c.Value.ToUpper());
-
-            // these characters are not escaped by UrlEncode() but needed to be escaped
-            value = value
-                .Replace("(", "%28")
-                .Replace(")", "%29")
-                .Replace("$", "%24")
-                .Replace("!", "%21")
-                .Replace("*", "%2A")
-                .Replace("'", "%27");
-
-            // these characters are escaped by UrlEncode() but will fail if unescaped!
-            value = value.Replace("%7E", "~");
-
-            return value;
-        }
+#endif
         #endregion
 
         /// <summary>
@@ -267,6 +349,7 @@ namespace Twitterizer
             return new Uri(parameters.ToString());
         }
 
+        #if !LITE && !SILVERLIGHT
         /// <summary>
         /// Gets the access token during callback.
         /// </summary>
@@ -309,12 +392,14 @@ namespace Twitterizer
             WebRequestBuilder builder = new WebRequestBuilder(
                 new Uri("https://api.twitter.com/1/account/verify_credentials.json"), 
                 HTTPVerb.POST,
-                tokens);
+				tokens,
+				"");
 
             builder.PrepareRequest();
 
             request.Headers.Add("X-Verify-Credentials-Authorization", builder.GenerateAuthorizationHeader());
             request.Headers.Add("X-Auth-Service-Provider", "https://api.twitter.com/1/account/verify_credentials.json");
         }
+#endif
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/OAuth/WebRequestBuilder.cs b/lib/Twitterizer/Twitterizer2/OAuth/WebRequestBuilder.cs
index ed08d45..a1f1c5b 100644
--- a/lib/Twitterizer/Twitterizer2/OAuth/WebRequestBuilder.cs
+++ b/lib/Twitterizer/Twitterizer2/OAuth/WebRequestBuilder.cs
@@ -34,6 +34,7 @@
 namespace Twitterizer
 {
     using System;
+    using System.IO;
     using System.Collections.Generic;
     using System.Globalization;
     using System.Linq;
@@ -41,10 +42,14 @@ namespace Twitterizer
     using System.Security.Cryptography;
     using System.Text;
     using System.Text.RegularExpressions;
-    using System.Web;
+#if SILVERLIGHT
+    using System.Net.Browser;
+    using System.Threading;
+    using System.Windows.Threading;
+#endif
 
     /// <summary>
-    /// Enumeration of the supported HTTP verbs supported by the <see cref="Twitterizer.Core.CommandPerformer{T}"/>
+    /// Enumeration of the supported HTTP verbs supported by the <see cref="Twitterizer.Core.CommandPerformer"/>
     /// </summary>
     public enum HTTPVerb
     {
@@ -70,6 +75,11 @@ namespace Twitterizer
     public sealed class WebRequestBuilder
     {
         /// <summary>
+        /// Holds file data form performing multipart form posts.
+        /// </summary>
+        private byte[] formData = null;
+
+        /// <summary>
         /// The HTTP Authorization realm.
         /// </summary>
         public string Realm = "Twitter API";
@@ -84,7 +94,7 @@ namespace Twitterizer
         /// Gets or sets the parameters.
         /// </summary>
         /// <value>The parameters.</value>
-        public Dictionary<string, string> Parameters { get; private set; }
+		public Dictionary<string, object> Parameters { get; private set; }
 
         /// <summary>
         /// Gets or sets the verb.
@@ -96,13 +106,33 @@ namespace Twitterizer
         /// Gets or sets the oauth tokens.
         /// </summary>
         /// <value>The tokens.</value>
-        public OAuthTokens Tokens { get; set; }
+        public OAuthTokens Tokens { private get; set; }
+
+        /// <summary>
+        /// Gets or sets the UserAgent.
+        /// </summary>
+        /// <value>The User Agent.</value>
+        public String UserAgent { private get; set; }
+
+        /// <summary>
+        /// Gets or sets the Basic Auth Credentials.
+        /// </summary>
+        /// <value>The Basic Auth Credentials.</value>
+		public NetworkCredential NetworkCredentials { private get; set; }
+
+		/// <summary>
+		/// Gets or sets the Multipart config
+		/// </summary>
+		/// <value>Multipart</value>
+		public bool Multipart { get; set; }
 
+#if !SILVERLIGHT
         /// <summary>
         /// Gets or sets the proxy.
         /// </summary>
         /// <value>The proxy.</value>
         public WebProxy Proxy { get; set; }
+#endif
 
         /// <summary>
         /// Gets or sets a value indicating whether the request will be signed with an OAuth authorization header.
@@ -120,7 +150,8 @@ namespace Twitterizer
                                                               "oauth_timestamp",
                                                               "oauth_signature_method",
                                                               "oauth_consumer_key",
-                                                              "oauth_token"
+                                                              "oauth_token",
+                                                              "oauth_verifier"
                                                               // Leave signature omitted from the list, it is added manually
                                                               // "oauth_signature",
                                                           };
@@ -139,17 +170,24 @@ namespace Twitterizer
         /// Initializes a new instance of the <see cref="WebRequestBuilder"/> class.
         /// </summary>
         /// <param name="requestUri">The request URI.</param>
-        /// <param name="verb">The verb.</param>
-        public WebRequestBuilder(Uri requestUri, HTTPVerb verb)
+        /// <param name="verb">The http verb.</param>
+        /// <param name="KeepAlive">if set to <c>true</c> the <see cref="System.Net.HttpWebRequest"/> will be instructed to keep the connection alive.</param>
+        /// <param name="UserAgent">The http user agent.</param>
+        /// <param name="NetworkCredentials">The network credentials.</param>
+        /// <remarks></remarks>
+        public WebRequestBuilder(Uri requestUri, HTTPVerb verb, String UserAgent, NetworkCredential NetworkCredentials)
         {
             if (requestUri == null)
                 throw new ArgumentNullException("requestUri");
 
             this.RequestUri = requestUri;
             this.Verb = verb;
+            this.UserAgent = UserAgent;
             this.UseOAuth = false;
+            if (NetworkCredentials != null)
+                this.NetworkCredentials = NetworkCredentials;
 
-            this.Parameters = new Dictionary<string, string>();
+			this.Parameters = new Dictionary<string, object>();
 
             if (string.IsNullOrEmpty(this.RequestUri.Query)) return;
 
@@ -167,8 +205,10 @@ namespace Twitterizer
         /// <param name="requestUri">The request URI.</param>
         /// <param name="verb">The verb.</param>
         /// <param name="tokens">The tokens.</param>
-        public WebRequestBuilder(Uri requestUri, HTTPVerb verb, OAuthTokens tokens)
-            : this(requestUri, verb)
+        /// <param name="KeepAlive">if set to <c>true</c> the http request is instructed to keep the connection alive.</param>
+        /// <param name="UserAgent">The user agent.</param>
+        public WebRequestBuilder(Uri requestUri, HTTPVerb verb, OAuthTokens tokens, String UserAgent = "")
+            : this(requestUri, verb, UserAgent, null)
         {
             this.Tokens = tokens;
 
@@ -196,7 +236,31 @@ namespace Twitterizer
         {
             HttpWebRequest request = PrepareRequest();
 
+#if !SILVERLIGHT
             return (HttpWebResponse)request.GetResponse();
+#else
+            request.AllowReadStreamBuffering = true;
+            HttpWebResponse response = null;
+            AutoResetEvent alldone = new AutoResetEvent(false);
+            IAsyncResult asyncResult = request.BeginGetResponse(new AsyncCallback((param) => 
+            {
+                HttpWebRequest req = (HttpWebRequest)param.AsyncState;
+                try
+                {
+                    response = (HttpWebResponse)req.EndGetResponse(param);
+                }
+                catch (WebException we)
+                {
+                    response = (HttpWebResponse)we.Response;
+                }
+                finally
+                {
+                    alldone.Set();
+                }
+            }), request);
+            alldone.WaitOne();
+            return response;
+#endif
         }
 
         /// <summary>
@@ -206,22 +270,84 @@ namespace Twitterizer
         public HttpWebRequest PrepareRequest()
         {
             SetupOAuth();
-            AddQueryStringParametersToUri();
 
+			formData = null;
+			string contentType = string.Empty;
+
+			if (!Multipart)
+			{	//We don't add the paramters to the query if we are multipart-ing
+				AddQueryStringParametersToUri();
+			}
+			else
+			{
+				string dataBoundary = "--------------------r4nd0m";
+				contentType = "multipart/form-data; boundary=" + dataBoundary;
+
+				formData = GetMultipartFormData(Parameters, dataBoundary);
+
+				this.Verb = HTTPVerb.POST;
+			}
+#if SILVERLIGHT
+            WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
+            WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp);
+#endif
             HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.RequestUri);
+
+#if !SILVERLIGHT
             if (this.Proxy != null)
                 request.Proxy = Proxy;
+#endif
+            if (!this.UseOAuth && this.NetworkCredentials != null)
+            {
+                request.Credentials = this.NetworkCredentials;
+                request.UseDefaultCredentials = false;
+            }
+            else
+            {
+                request.UseDefaultCredentials = true;
+            }
+
             request.Method = this.Verb.ToString();
-            request.UserAgent = string.Format(CultureInfo.InvariantCulture, "Twitterizer/{0}", System.Reflection.Assembly.GetAssembly(typeof(WebRequestBuilder)).GetName().Version);
-            request.ServicePoint.Expect100Continue = false;
+
+			request.ContentLength = Multipart ? formData.Length : 0;
+
+
+#if !SILVERLIGHT // No silverlight user-agent as Assembly.GetName() isn't supported and setting the request.UserAgent is also not supported.
+            request.UserAgent = (String.IsNullOrEmpty(UserAgent)) ? string.Format(CultureInfo.InvariantCulture, "Twitterizer/{0}", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version) : UserAgent;
             
+            request.ServicePoint.Expect100Continue = false;
+#endif
             if (this.UseOAuth)
             {
+#if !SILVERLIGHT
                 request.Headers.Add("Authorization", GenerateAuthorizationHeader());
+#else
+                request.Headers["Authorization"] = GenerateAuthorizationHeader();
+#endif
             }
 
-            //AddFormFieldValuesToRequest(request);
-            
+			if (Multipart)
+			{	//Parameters are not added to the query string, post them in the request body instead
+
+				request.ContentType = contentType;
+
+
+#if !SILVERLIGHT
+                using (Stream requestStream = request.GetRequestStream())
+#else
+                IAsyncResult getRequestStreamResult = request.BeginGetRequestStream(
+                    (res) =>
+                    {
+
+                    }, null);
+
+                using (Stream requestStream = request.EndGetRequestStream(getRequestStreamResult))
+#endif
+                {
+                    requestStream.Write(formData, 0, formData.Length);
+                }
+			}
+
             return request;
         }
 
@@ -233,14 +359,14 @@ namespace Twitterizer
             StringBuilder requestParametersBuilder = new StringBuilder(this.RequestUri.AbsoluteUri);
             requestParametersBuilder.Append(this.RequestUri.Query.Length == 0 ? "?" : "&");
 
-            var fieldsToInclude = from p in this.Parameters
-                                  where !OAuthParametersToIncludeInHeader.Contains(p.Key) &&
-                                        !SecretParameters.Contains(p.Key)
-                                  select p;
 
-            foreach (KeyValuePair<string, string> item in fieldsToInclude)
+			Dictionary<string, object> fieldsToInclude = new Dictionary<string, object>(this.Parameters.Where(p => !OAuthParametersToIncludeInHeader.Contains(p.Key) &&
+                                         !SecretParameters.Contains(p.Key)).ToDictionary(p => p.Key, p => p.Value));
+
+			foreach (KeyValuePair<string, object> item in fieldsToInclude)
             {
-                requestParametersBuilder.AppendFormat("{0}={1}&", item.Key, UrlEncode(item.Value));
+				if( item.Value.GetType() == typeof(string) )
+					requestParametersBuilder.AppendFormat("{0}={1}&", item.Key, UrlEncode(item.Value as string));
             }
 
             if (requestParametersBuilder.Length == 0)
@@ -251,45 +377,48 @@ namespace Twitterizer
             this.RequestUri = new Uri(requestParametersBuilder.ToString());
         }
 
-        /// <summary>
-        /// Adds the form field values to request.
-        /// </summary>
-        /// <param name="request">The request.</param>
-        private void AddFormFieldValuesToRequest(WebRequest request)
-        {
-            throw new NotImplementedException("Multipart form data is not yet supported by the WebRequestBuilder.");
-
-/*
-            if (!(new[] { HTTPVerb.DELETE, HTTPVerb.POST }).Contains(this.Verb))
-                return;
-
-            request.ContentType = "application/x-www-form-urlencoded";
-
-            StringBuilder requestParametersBuilder = new StringBuilder();
+		private byte[] GetMultipartFormData(Dictionary<string, object> param, string boundary)
+		{
+			Stream formDataStream = new MemoryStream();
+			Encoding encoding = Encoding.UTF8;
+
+			Dictionary<string, object> fieldsToInclude = new Dictionary<string, object>(param.Where(p => !OAuthParametersToIncludeInHeader.Contains(p.Key) &&
+							 !SecretParameters.Contains(p.Key)).ToDictionary(p => p.Key, p => p.Value));
+
+			foreach (KeyValuePair<string, object> kvp in fieldsToInclude)
+			{
+				if (kvp.Value.GetType() == typeof(byte[]))
+				{	//assume this to be a byte stream
+					byte[] data = kvp.Value as byte[];
+
+					string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: application/octet-stream\r\n\r\n",
+						boundary,
+						kvp.Key,
+						kvp.Key);
+					formDataStream.Write(encoding.GetBytes(header), 0, header.Length);
+					formDataStream.Write(data, 0, data.Length);
+				}
+				else
+				{	//this is normal text data
+					string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n",
+						boundary,
+						kvp.Key,
+						kvp.Value);
+					formDataStream.Write(encoding.GetBytes(header), 0, header.Length);
+				}
+			}
+
+			string footer = string.Format("\r\n--{0}--\r\n", boundary);
+			formDataStream.Write(encoding.GetBytes(footer), 0, footer.Length);
+			formDataStream.Position = 0;
+			byte[] returndata = new byte[formDataStream.Length];
+
+			formDataStream.Read(returndata, 0, returndata.Length);
+			formDataStream.Close();
+
+			return returndata;
+		}
 
-            var fieldsToInclude = from p in this.Parameters
-                                  where !OAuthParametersToIncludeInHeader.Contains(p.Key) &&
-                                        !SecretParameters.Contains(p.Key)
-                                  select p;
-
-            foreach (KeyValuePair<string, string> item in fieldsToInclude)
-            {
-                requestParametersBuilder.AppendFormat("{0}={1}&", item.Key, item.Value);
-            }
-
-            if (requestParametersBuilder.Length == 0)
-                return;
-
-            requestParametersBuilder.Remove(requestParametersBuilder.Length - 1, 1);
-
-            byte[] formData = Encoding.UTF8.GetBytes(requestParametersBuilder.ToString());
-            request.ContentLength = formData.Length;
-            System.IO.Stream requestStream = request.GetRequestStream();
-            requestStream.Write(formData, 0, formData.Length);
-            requestStream.Close();
-*/
-        }
-        
         #region OAuth Helper Methods
         /// <summary>
         /// Sets up the OAuth request details.
@@ -332,16 +461,20 @@ namespace Twitterizer
         /// <returns></returns>
         public string GenerateSignature()
         {
-            var nonSecretParameters = (from p in this.Parameters
-                                       where !SecretParameters.Contains(p.Key)
-                                       select p);
-
-            var baseStringParameters =
-                (from p in this.Parameters
-                 where !(p.Key.EndsWith("_secret", StringComparison.OrdinalIgnoreCase) &&
-                         p.Key.StartsWith("oauth_", StringComparison.OrdinalIgnoreCase) &&
-                         !p.Key.EndsWith("_verifier", StringComparison.OrdinalIgnoreCase))
-                 select p);
+			IEnumerable<KeyValuePair<string, object>> nonSecretParameters = null;
+
+			if (Multipart)
+			{
+				nonSecretParameters = (from p in this.Parameters
+										   where (!SecretParameters.Contains(p.Key) && p.Key.StartsWith("oauth_"))
+										   select p);
+			}
+			else
+			{
+				nonSecretParameters = (from p in this.Parameters
+										   where (!SecretParameters.Contains(p.Key))
+										   select p);
+			}
 
             Uri urlForSigning = this.RequestUri;
 
@@ -351,7 +484,7 @@ namespace Twitterizer
                 "{0}&{1}&{2}",
                 this.Verb.ToString().ToUpper(CultureInfo.InvariantCulture),
                 UrlEncode(NormalizeUrl(urlForSigning)),
-                UrlEncode(baseStringParameters));
+                UrlEncode(nonSecretParameters));
 
             // Create our hash key (you might say this is a password)
             string key = string.Format(
@@ -362,8 +495,8 @@ namespace Twitterizer
 
 
             // Generate the hash
-            HMACSHA1 hmacsha1 = new HMACSHA1(Encoding.ASCII.GetBytes(key));
-            byte[] signatureBytes = hmacsha1.ComputeHash(Encoding.ASCII.GetBytes(signatureBaseString));
+            HMACSHA1 hmacsha1 = new HMACSHA1(Encoding.UTF8.GetBytes(key));
+            byte[] signatureBytes = hmacsha1.ComputeHash(Encoding.UTF8.GetBytes(signatureBaseString));
             return Convert.ToBase64String(signatureBytes);
         }
 
@@ -419,7 +552,7 @@ namespace Twitterizer
                 return string.Empty;
             }
 
-            value = HttpUtility.UrlEncode(value).Replace("+", "%20");
+            value = Uri.EscapeDataString(value);
 
             // UrlEncode escapes with lowercase characters (e.g. %2f) but oAuth needs %2F
             value = Regex.Replace(value, "(%[0-9a-f][0-9a-f])", c => c.Value.ToUpper());
@@ -444,7 +577,7 @@ namespace Twitterizer
         /// </summary>
         /// <param name="parameters">The parameters.</param>
         /// <returns>A string of all the <paramref name="parameters"/> keys and value pairs with the values encoded.</returns>
-        private static string UrlEncode(IEnumerable<KeyValuePair<string, string>> parameters)
+		private static string UrlEncode(IEnumerable<KeyValuePair<string, object>> parameters)
         {
             StringBuilder parameterString = new StringBuilder();
 
@@ -459,12 +592,13 @@ namespace Twitterizer
                     parameterString.Append("&");
                 }
 
-                parameterString.Append(
-                    string.Format(
-                        CultureInfo.InvariantCulture,
-                        "{0}={1}",
-                        UrlEncode(item.Key),
-                        UrlEncode(item.Value)));
+				if( item.Value.GetType() == typeof(string) )
+					parameterString.Append(
+						string.Format(
+							CultureInfo.InvariantCulture,
+							"{0}={1}",
+							UrlEncode(item.Key),
+							UrlEncode(item.Value as string)));
             }
 
             return UrlEncode(parameterString.ToString());
@@ -477,11 +611,11 @@ namespace Twitterizer
         public string GenerateAuthorizationHeader()
         {
             StringBuilder authHeaderBuilder = new StringBuilder();
-            authHeaderBuilder.AppendFormat("OAuth realm=\"{0}\"", Realm);
+            authHeaderBuilder.AppendFormat("OAuth realm=\"\"", Realm);
 
             var sortedParameters = from p in this.Parameters
                                    where OAuthParametersToIncludeInHeader.Contains(p.Key)
-                                   orderby p.Key, UrlEncode(p.Value)
+                                   orderby p.Key, UrlEncode( (p.Value.GetType() == typeof(string) )? p.Value as string : "")
                                    select p;
 
             foreach (var item in sortedParameters)
@@ -489,15 +623,14 @@ namespace Twitterizer
                 authHeaderBuilder.AppendFormat(
                     ",{0}=\"{1}\"",
                     UrlEncode(item.Key),
-                    UrlEncode(item.Value));
+                    UrlEncode(item.Value as string));
             }
 
-            authHeaderBuilder.AppendFormat(",oauth_signature=\"{0}\"", UrlEncode(this.Parameters["oauth_signature"]));
+            authHeaderBuilder.AppendFormat(",oauth_signature=\"{0}\"", UrlEncode(this.Parameters["oauth_signature"] as string));
 
             return authHeaderBuilder.ToString();
         }
         #endregion
-
-
+        
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/OAuth/XAuthUtility.cs b/lib/Twitterizer/Twitterizer2/OAuth/XAuthUtility.cs
index f447330..e6b99dc 100644
--- a/lib/Twitterizer/Twitterizer2/OAuth/XAuthUtility.cs
+++ b/lib/Twitterizer/Twitterizer2/OAuth/XAuthUtility.cs
@@ -84,7 +84,8 @@ namespace Twitterizer
                 WebRequestBuilder builder = new WebRequestBuilder(
                     new Uri("https://api.twitter.com/oauth/access_token"),
                     HTTPVerb.POST,
-                    new OAuthTokens() { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret });
+                    new OAuthTokens() { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret },
+					"");
 
                 builder.Parameters.Add("x_auth_username", username);
                 builder.Parameters.Add("x_auth_password", password);
@@ -94,7 +95,8 @@ namespace Twitterizer
 
                 response.Token = Regex.Match(responseBody, @"oauth_token=([^&]+)").Groups[1].Value;
                 response.TokenSecret = Regex.Match(responseBody, @"oauth_token_secret=([^&]+)").Groups[1].Value;
-                response.UserId = long.Parse(Regex.Match(responseBody, @"user_id=([^&]+)").Groups[1].Value, CultureInfo.CurrentCulture);
+                if (responseBody.Contains("user_id="))
+                    response.UserId = long.Parse(Regex.Match(responseBody, @"user_id=([^&]+)").Groups[1].Value, CultureInfo.CurrentCulture);
                 response.ScreenName = Regex.Match(responseBody, @"screen_name=([^&]+)").Groups[1].Value;
             }
             catch (WebException wex)
diff --git a/lib/Twitterizer/Twitterizer2/Properties/AssemblyInfo.cs b/lib/Twitterizer/Twitterizer2/Properties/AssemblyInfo.cs
index 3f5edd4..9043d81 100644
--- a/lib/Twitterizer/Twitterizer2/Properties/AssemblyInfo.cs
+++ b/lib/Twitterizer/Twitterizer2/Properties/AssemblyInfo.cs
@@ -35,34 +35,8 @@ using System.Reflection;
 using System.Runtime.InteropServices;
 using System.Security;
 
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Twitterizer")]
-[assembly: AssemblyDescription("Twitter integration library")]
-
-#if DEBUG
-[assembly: AssemblyConfiguration("Debug")]
-#else
-[assembly: AssemblyConfiguration("Release")]
-#endif
-
-[assembly: AssemblyCompany("Twitterizer Group (www.twitterizer.net)")]
-[assembly: AssemblyProduct("Twitterizer")]
-[assembly: AssemblyCopyright("2010 Patrick 'Ricky' Smith (www.ricky-dev.com)")]
-[assembly: AssemblyTrademark("")]
-//[assembly: SecurityRules(SecurityRuleSet.Level1)]
-[assembly: AllowPartiallyTrustedCallers]
-
-[assembly: CLSCompliant(true)]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
+// Uncomment this line for building a .NET 4.0 assembly
+// [assembly: SecurityRules(SecurityRuleSet.Level1)]
 
 // The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("e8e37171-9c87-46e0-9e2e-c16c3ff570a5")]
-
-[assembly: AssemblyVersion("2.2.2.*")]
-[assembly: AssemblyFileVersion("2.2.2.*")]
\ No newline at end of file
+[assembly: Guid("e8e37171-9c87-46e0-9e2e-c16c3ff570a5")]
\ No newline at end of file
diff --git a/lib/Twitterizer/Twitterizer2/TwitterResponse.cs b/lib/Twitterizer/Twitterizer2/TwitterResponse.cs
new file mode 100644
index 0000000..f178a4f
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/TwitterResponse.cs
@@ -0,0 +1,69 @@
+using System;
+
+namespace Twitterizer
+{
+    /// <summary>
+    /// The twitter response class provides details of the response from an api call to the twitter api.
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    public class TwitterResponse<T>
+        where T : Core.ITwitterObject
+    {
+        /// <summary>
+        /// Gets or sets the object that represents the data returned by the request to Twitter.
+        /// </summary>
+        /// <value>The response object.</value>
+        public T ResponseObject { get; set; }
+
+        /// <summary>
+        /// Gets or sets the result of the request.
+        /// </summary>
+        /// <value>The result.</value>
+        public RequestResult Result { get; set; }
+
+        /// <summary>
+        /// Gets or sets the request URL.
+        /// </summary>
+        /// <value>The request URL.</value>
+        public string RequestUrl { get; set; }
+
+        /// <summary>
+        /// Gets the raw json or xml response provided by Twitter.
+        /// </summary>
+        /// <value>The response body.</value>
+        public string Content { get; set; }
+
+        /// <summary>
+        /// Gets or sets the error message returned by the Twitter.
+        /// </summary>
+        /// <value>The error message.</value>
+        public string ErrorMessage { get; set; }
+
+        /// <summary>
+        /// Gets or sets the oauth tokens provided for the request.
+        /// </summary>
+        /// <value>The tokens.</value>
+        internal OAuthTokens Tokens { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether the response was retrieved from a cache.
+        /// </summary>
+        /// <value><c>true</c> if [response cached]; otherwise, <c>false</c>.</value>
+        public Boolean ResponseCached { get; set; }
+
+        /// <summary>
+        /// Gets or sets the rate limiting details.
+        /// </summary>
+        /// <value>The rate limiting object.</value>
+        public RateLimiting RateLimiting { get; set; }
+
+        /// <summary>
+        /// Gets or sets the OAuth Token Access Level details.
+        /// </summary>
+        /// <value>The access level.</value>
+        public AccessLevel AccessLevel { get; set; }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Twitterizer2.csproj b/lib/Twitterizer/Twitterizer2/Twitterizer2.csproj
index c87d4d3..a80e715 100644
--- a/lib/Twitterizer/Twitterizer2/Twitterizer2.csproj
+++ b/lib/Twitterizer/Twitterizer2/Twitterizer2.csproj
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -10,14 +10,16 @@
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>Twitterizer</RootNamespace>
     <AssemblyName>Twitterizer2</AssemblyName>
-    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
-    <SignAssembly>true</SignAssembly>
     <AssemblyOriginatorKeyFile>Twitterizer2.snk</AssemblyOriginatorKeyFile>
     <FileUpgradeFlags>
     </FileUpgradeFlags>
     <OldToolsVersion>3.5</OldToolsVersion>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
     <UpgradeBackupLocation />
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
     <PublishUrl>publish\</PublishUrl>
     <Install>true</Install>
     <InstallFrom>Disk</InstallFrom>
@@ -30,10 +32,8 @@
     <MapFileExtensions>true</MapFileExtensions>
     <ApplicationRevision>0</ApplicationRevision>
     <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
     <UseApplicationTrust>false</UseApplicationTrust>
     <BootstrapperEnabled>true</BootstrapperEnabled>
-    <TargetFrameworkProfile />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -49,11 +49,11 @@
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>pdbonly</DebugType>
     <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
+    <OutputPath>..\Release\Twitterizer2\</OutputPath>
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
-    <DocumentationFile>bin\Release\Twitterizer2.XML</DocumentationFile>
+    <DocumentationFile>..\Release\Twitterizer2.XML</DocumentationFile>
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Mono-Debug|AnyCPU' ">
@@ -93,42 +93,65 @@
   <ItemGroup>
     <Reference Include="System" />
     <Reference Include="System.configuration" />
-    <Reference Include="System.Core">
-      <RequiredTargetFramework>3.5</RequiredTargetFramework>
-    </Reference>
-    <Reference Include="System.Data" />
     <Reference Include="System.Drawing" />
+    <Reference Include="System.Runtime.Serialization" />
     <Reference Include="System.Web" />
-    <Reference Include="System.Web.Extensions">
-      <RequiredTargetFramework>3.5</RequiredTargetFramework>
-    </Reference>
-    <Reference Include="System.Xml.Linq">
-      <RequiredTargetFramework>3.5</RequiredTargetFramework>
-    </Reference>
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="..\CommonAssemblyInfo.cs">
+      <Link>CommonAssemblyInfo.cs</Link>
+    </Compile>
     <Compile Include="Attributes\RateLimitedAttribute.cs" />
     <Compile Include="Attributes\AuthorizedCommandAttribute.cs" />
-    <Compile Include="Core\TwitterEmptyObject.cs" />
+    <Compile Include="Core\RequestResult.cs" />
+    <Compile Include="Core\TwitterCursorPagedIdCollection.cs" />
+    <Compile Include="Core\ITwitterObject.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\TwitterIdCollection.cs" />
     <Compile Include="Core\TwitterImage.cs" />
     <Compile Include="Core\TwitterizerDateConverter.cs" />
+    <Compile Include="Exceptions\TwitterErrorDetails.cs" />
+    <Compile Include="Methods\Account\TwitterAccount.cs" />
+    <Compile Include="Methods\Account\UpdateProfileBackgroundImageCommand.cs" />
+    <Compile Include="Methods\Account\UpdateProfileBackgroundImageOptions.cs" />
     <Compile Include="Methods\Account\UpdateProfileColorsCommand.cs" />
     <Compile Include="Methods\Account\UpdateProfileColorsOptions.cs" />
+    <Compile Include="Methods\Account\UpdateProfileCommand.cs" />
     <Compile Include="Methods\Account\UpdateProfileImageCommand.cs" />
+    <Compile Include="Methods\Account\UpdateProfileOptions.cs" />
+    <Compile Include="Methods\Account\VerifyCredentialsCommand.cs" />
+    <Compile Include="Methods\Account\VerifyCredentialsOptions.cs" />
+    <Compile Include="Methods\Block\BlockingCommand.cs" />
+    <Compile Include="Methods\Block\BlockingIdsCommand.cs" />
+    <Compile Include="Methods\Block\BlockingOptions.cs" />
+    <Compile Include="Methods\Block\ExistsBlockCommand.cs" />
+    <Compile Include="Methods\Block\DestroyBlockCommand.cs" />
+    <Compile Include="Methods\Block\CreateBlockCommand.cs" />
+    <Compile Include="Methods\Block\TwitterBlock.cs" />
     <Compile Include="Methods\DirectMessage\DeleteDirectMessageCommand.cs" />
     <Compile Include="Methods\DirectMessage\DirectMessagesCommand.cs" />
-    <Compile Include="Methods\DirectMessage\DirectMessagesOptions.cs">
-      <SubType>Code</SubType>
-    </Compile>
+    <Compile Include="Methods\DirectMessage\DirectMessagesOptions.cs" />
     <Compile Include="Methods\DirectMessage\DirectMessagesSentCommand.cs" />
     <Compile Include="Methods\DirectMessage\DirectMessagesSentOptions.cs" />
     <Compile Include="Methods\DirectMessage\SendDirectMessageCommand.cs" />
+    <Compile Include="Methods\DirectMessage\ShowDirectMessageCommand.cs" />
+    <Compile Include="Methods\DirectMessage\TwitterDirectMessage.cs" />
+    <Compile Include="Methods\DirectMessage\TwitterDirectMessageCollection.cs" />
     <Compile Include="Methods\Favorites\CreateFavoriteCommand.cs" />
     <Compile Include="Methods\Favorites\DeleteFavoriteCommand.cs" />
     <Compile Include="Methods\Favorites\ListFavoritesCommand.cs" />
     <Compile Include="Methods\Favorites\ListFavoritesOptions.cs" />
     <Compile Include="Methods\Favorites\TwitterFavorite.cs" />
+    <Compile Include="Methods\Friendship\OutgoingFriendshipsCommand.cs" />
+    <Compile Include="Methods\Friendship\OutgoingFriendshipsOptions.cs" />
+    <Compile Include="Methods\Friendship\FriendsIdsCommand.cs" />
+    <Compile Include="Methods\Friendship\IncomingFriendshipsCommand.cs" />
+    <Compile Include="Methods\Friendship\IncomingFriendshipsOptions.cs" />
+    <Compile Include="Methods\Friendship\UserIdCollection.cs" />
+    <Compile Include="Methods\Friendship\FollowersIdsCommand.cs" />
+    <Compile Include="Methods\Friendship\UsersIdsOptions.cs" />
     <Compile Include="Methods\Friendship\CreateFriendshipCommand.cs" />
     <Compile Include="Methods\Friendship\CreateFriendshipOptions.cs" />
     <Compile Include="Methods\Friendship\TwitterFriendship.cs" />
@@ -141,7 +164,12 @@
     <Compile Include="Methods\Geo\TwitterPlaceLookupOptions.cs" />
     <Compile Include="Methods\List\AddListMemberCommand.cs" />
     <Compile Include="Methods\List\CheckListMembershipCommand.cs" />
+    <Compile Include="Methods\List\CreateListMembershipCommand.cs" />
+    <Compile Include="Methods\List\DestroyListSubscriber.cs" />
     <Compile Include="Methods\List\GetListMembersOptions.cs" />
+    <Compile Include="Methods\List\GetListsOptions.cs" />
+    <Compile Include="Methods\List\GetListSubscriptionsOptions.cs" />
+    <Compile Include="Methods\List\ListMembershipsOptions.cs" />
     <Compile Include="Methods\List\RemoveListMemberCommand.cs" />
     <Compile Include="Methods\List\CreateListCommand.cs" />
     <Compile Include="Methods\Friendship\DeleteFriendshipCommand.cs" />
@@ -150,11 +178,23 @@
     <Compile Include="Methods\List\GetListSubscriptionsCommand.cs" />
     <Compile Include="Methods\List\ListStatusesOptions.cs" />
     <Compile Include="Methods\List\UpdateListOptions.cs" />
+    <Compile Include="Methods\Notification\NotificationLeaveCommand.cs" />
+    <Compile Include="Methods\Notification\NotificationFollowCommand.cs" />
+    <Compile Include="Methods\Notification\TwitterNotification.cs" />
+    <Compile Include="Methods\SavedSearches\SavedSearchesCommand.cs" />
+    <Compile Include="Methods\SavedSearches\CreateSavedSearchCommand.cs" />
+    <Compile Include="Methods\SavedSearches\DeleteSavedSearchCommand.cs" />
+    <Compile Include="Methods\SavedSearches\TwitterSavedSearch.cs" />
+    <Compile Include="Methods\SavedSearches\TwitterSavedSearchCollection.cs" />
     <Compile Include="Methods\Search\SearchOptions.cs" />
+    <Compile Include="Methods\Spam\ReportSpamCommand.cs" />
+    <Compile Include="Methods\Spam\TwitterSpam.cs" />
     <Compile Include="Methods\Timeline\PagedTimelineCommand.cs" />
     <Compile Include="Methods\Timeline\UserTimelineOptions.cs" />
-    <Compile Include="Methods\Trends\CurrentTrendsCommand.cs" />
-    <Compile Include="Methods\Trends\CurrentTrendsOptions.cs" />
+    <Compile Include="Methods\Trends\TwitterTrendLocation.cs" />
+    <Compile Include="Methods\Trends\TwitterTrendLocationCollection.cs" />
+    <Compile Include="Methods\Trends\TrendsCommand.cs" />
+    <Compile Include="Methods\Trends\TrendsOptions.cs" />
     <Compile Include="Methods\Search\SearchCommand.cs" />
     <Compile Include="Methods\Timeline\TimelineOptions.cs" />
     <Compile Include="Methods\Timeline\TwitterTimeline.cs" />
@@ -163,10 +203,19 @@
     <Compile Include="Methods\Tweets\Entities\TwitterEntity.cs" />
     <Compile Include="Methods\Tweets\Entities\TwitterEntityCollection.cs" />
     <Compile Include="Methods\Tweets\Entities\TwitterHashTagEntity.cs" />
+    <Compile Include="Methods\Tweets\Entities\TwitterMediaEntity.cs" />
     <Compile Include="Methods\Tweets\Entities\TwitterMentionEntity.cs" />
     <Compile Include="Methods\Tweets\Entities\TwitterUrlEntity.cs" />
+    <Compile Include="Methods\Tweets\RelatedResultsCommand.cs" />
+    <Compile Include="Methods\Tweets\UpdateWithmediaCommand.cs" />
+    <Compile Include="Methods\User\RetweetedByCommand.cs" />
+    <Compile Include="Methods\User\RetweetedByIdsCommand.cs" />
+    <Compile Include="Methods\User\RetweetedByIdsOptions.cs" />
+    <Compile Include="Methods\User\RetweetedByOptions.cs" />
+    <Compile Include="Methods\Tweets\TwitterRelatedTweets.cs" />
     <Compile Include="Methods\Tweets\RetweetsOfMeOptions.cs" />
     <Compile Include="Methods\Tweets\RetweetsOptions.cs" />
+    <Compile Include="Methods\Tweets\TwitterRelatedTweetsCollection.cs" />
     <Compile Include="Methods\User\FollowersOptions.cs" />
     <Compile Include="Methods\User\FriendsCommand.cs" />
     <Compile Include="Methods\Timeline\FriendsTimelineCommand.cs" />
@@ -191,21 +240,19 @@
     <Compile Include="Methods\User\FriendsOptions.cs" />
     <Compile Include="Methods\User\LookupUsersOptions.cs" />
     <Compile Include="Methods\User\LookupUsersCommand.cs" />
+    <Compile Include="Methods\User\SuggestedUserCategoriesCommand.cs" />
+    <Compile Include="Methods\User\SuggestedUsersCommand.cs" />
+    <Compile Include="Methods\User\TwitterUserCategory.cs" />
     <Compile Include="Methods\User\UserSearchCommand.cs" />
     <Compile Include="Methods\Timeline\UserTimelineCommand.cs" />
     <Compile Include="Core\SerializationHelper.cs" />
     <Compile Include="Core\TwitterCollection.cs" />
     <Compile Include="Core\ConversionUtility.cs" />
-    <Compile Include="Core\CursorPagedCommand.cs" />
     <Compile Include="Core\ICommand.cs" />
-    <Compile Include="Core\PagedCommand.cs" />
     <Compile Include="Methods\User\ShowUserCommand.cs" />
     <Compile Include="Core\TwitterObject.cs" />
-    <Compile Include="Core\ITwitterObject.cs" />
     <Compile Include="Core\NamespaceDoc.cs" />
-    <Compile Include="Core\RequestStatus.cs" />
-    <Compile Include="Exceptions\CommandValidationException.cs" />
-    <Compile Include="Exceptions\TwitterErrorDetails.cs" />
+    <Compile Include="Core\AccessLevel.cs" />
     <Compile Include="Information.cs" />
     <Compile Include="Methods\User\UserSearchOptions.cs" />
     <Compile Include="OAuth\OAuthTokenResponse.cs" />
@@ -219,8 +266,6 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Core\OptionalProperties.cs" />
     <Compile Include="Methods\Tweets\StatusUpdateOptions.cs" />
-    <Compile Include="Methods\DirectMessage\TwitterDirectMessageCollection.cs" />
-    <Compile Include="Methods\DirectMessage\TwitterDirectMessage.cs" />
     <Compile Include="Methods\List\TwitterList.cs" />
     <Compile Include="Methods\List\TwitterListCollection.cs" />
     <Compile Include="Methods\Account\TwitterRateLimitStatus.cs" />
@@ -235,8 +280,10 @@
     <Compile Include="Methods\User\TwitterUserCollection.cs" />
     <Compile Include="Exceptions\TwitterizerException.cs" />
     <Compile Include="Methods\User\TwitterUser.cs" />
+    <Compile Include="TwitterResponse.cs" />
   </ItemGroup>
   <ItemGroup>
+    <None Include="packages.config" />
     <None Include="Settings.StyleCop" />
     <None Include="Twitterizer2.cd" />
     <None Include="Twitterizer2.snk" />
@@ -251,14 +298,11 @@
     <None Include="OAuth\OAuthUtility.xml" />
   </ItemGroup>
   <ItemGroup>
-    <None Include="Core\OptionalProperties.xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Folder Include="Methods\Block\" />
-    <Folder Include="Methods\Notification\" />
-    <Folder Include="Methods\SavedSearches\" />
-    <Folder Include="Methods\Spam\" />
+    <None Include="Core\OptionalProperties.xml">
+      <SubType>Designer</SubType>
+    </None>
   </ItemGroup>
+  <ItemGroup />
   <ItemGroup>
     <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
       <Visible>False</Visible>
@@ -276,6 +320,20 @@
       <Install>true</Install>
     </BootstrapperPackage>
   </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\GettingStarted.txt">
+      <Link>GettingStarted.txt</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\Json.NET.license.txt">
+      <Link>Json.NET.license.txt</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\Twitterizer2.license.txt">
+      <Link>Twitterizer2.license.txt</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
@@ -285,10 +343,8 @@
   </Target>
   -->
   <PropertyGroup>
-    <PostBuildEvent>IF '$(ConfigurationName)'=='Release' mkdir "$(SolutionDir)Release\"
-IF '$(ConfigurationName)'=='Release' copy "$(SolutionDir)*.license.txt" "$(TargetDir)"
-IF '$(ConfigurationName)'=='Release' copy "$(TargetDir)*.*" "$(SolutionDir)Release\"
-IF '$(ConfigurationName)'=='Release' del "$(SolutionDir)Release\*.tmp"</PostBuildEvent>
+    <PostBuildEvent>
+    </PostBuildEvent>
     <PreBuildEvent>
     </PreBuildEvent>
   </PropertyGroup>
@@ -298,4 +354,4 @@ IF '$(ConfigurationName)'=='Release' del "$(SolutionDir)Release\*.tmp"</PostBuil
       <Name>Newtonsoft.Json</Name>
     </ProjectReference>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation-2008.csproj b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation-2008.csproj
new file mode 100644
index 0000000..6b7e3fc
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation-2008.csproj
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build" ToolsVersion="3.5">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{FFA59708-14D1-4C22-B9A4-1A389EE796D5}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Db4objects.Db4o.Instrumentation</RootNamespace>
+    <AssemblyName>Db4objects.Db4o.Instrumentation</AssemblyName>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>2.0</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    
+    
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<SignAssembly>true</SignAssembly>
+<AssemblyOriginatorKeyFile>../db4objects.snk</AssemblyOriginatorKeyFile>
+</PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Debug\Db4objects.Db4o.Instrumentation.xml</DocumentationFile>
+    <NoWarn>1591;1572;1573;1574;0419;</NoWarn>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE;NET_3_5</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Release\Db4objects.Db4o.Instrumentation.xml</DocumentationFile>
+    <NoWarn>1591;1572;1573;1574;0419;</NoWarn>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Cecil.FlowAnalysis, Version=0.1.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\Libs\net-2.0\Cecil.FlowAnalysis.dll</HintPath>
+    </Reference>
+    <Reference Include="Mono.Cecil, Version=0.6.8.8607, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\Libs\net-2.0\Mono.Cecil.dll</HintPath>
+    </Reference>
+    <Reference Include="System"/>
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data"/>
+    <Reference Include="System.Xml"/>
+  </ItemGroup>
+  <ItemGroup>
+<Compile Include="Db4objects.Db4o.Instrumentation\Api\CallingConvention.cs"/>
+<Compile Include="Db4objects.Db4o.Instrumentation\Api\IFieldRef.cs"/>
+<Compile Include="Db4objects.Db4o.Instrumentation\Api\IMethodBuilder.cs"/>
+<Compile Include="Db4objects.Db4o.Instrumentation\Api\IMethodRef.cs"/>
+<Compile Include="Db4objects.Db4o.Instrumentation\Api\INativeClassFactory.cs"/>
+<Compile Include="Db4objects.Db4o.Instrumentation\Api\IReferenceProvider.cs"/>
+<Compile Include="Db4objects.Db4o.Instrumentation\Api\IReferenceResolver.cs"/>
+<Compile Include="Db4objects.Db4o.Instrumentation\Api\ITypeEditor.cs"/>
+<Compile Include="Db4objects.Db4o.Instrumentation\Api\ITypeRef.cs"/>
+<Compile Include="Db4objects.Db4o.Instrumentation\Api\InstrumentationException.cs"/>
+<Compile Include="Db4objects.Db4o.Instrumentation\Core\DefaultNativeClassFactory.cs"/>
+<Compile Include="Properties\AssemblyInfo.cs"/>
+<Compile Include="native\Db4objects.Db4o.Instrumentation\Cecil\CecilFieldRef.cs"/>
+<Compile Include="native\Db4objects.Db4o.Instrumentation\Cecil\CecilMethodBuilder.cs"/>
+<Compile Include="native\Db4objects.Db4o.Instrumentation\Cecil\CecilMethodRef.cs"/>
+<Compile Include="native\Db4objects.Db4o.Instrumentation\Cecil\CecilRef.cs"/>
+<Compile Include="native\Db4objects.Db4o.Instrumentation\Cecil\CecilReferenceProvider.cs"/>
+<Compile Include="native\Db4objects.Db4o.Instrumentation\Cecil\CecilReferenceResolver.cs"/>
+<Compile Include="native\Db4objects.Db4o.Instrumentation\Cecil\CecilTypeEditor.cs"/>
+<Compile Include="native\Db4objects.Db4o.Instrumentation\Cecil\CecilTypeRef.cs"/>
+</ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Db4objects.Db4o\Db4objects.Db4o-2008.csproj">
+      <Project>{600CD3BF-2ED2-4183-87F7-ADD78A968AE0}</Project>
+      <Name>Db4objects.Db4o-2008</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets"/>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/CallingConvention.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/CallingConvention.cs
new file mode 100644
index 0000000..c40e3ee
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/CallingConvention.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Instrumentation.Api
+{
+	public sealed class CallingConvention
+	{
+		public static readonly Db4objects.Db4o.Instrumentation.Api.CallingConvention Static
+			 = new Db4objects.Db4o.Instrumentation.Api.CallingConvention();
+
+		public static readonly Db4objects.Db4o.Instrumentation.Api.CallingConvention Virtual
+			 = new Db4objects.Db4o.Instrumentation.Api.CallingConvention();
+
+		public static readonly Db4objects.Db4o.Instrumentation.Api.CallingConvention Interface
+			 = new Db4objects.Db4o.Instrumentation.Api.CallingConvention();
+
+		private CallingConvention()
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IFieldRef.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IFieldRef.cs
new file mode 100644
index 0000000..9045045
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IFieldRef.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Instrumentation.Api;
+
+namespace Db4objects.Db4o.Instrumentation.Api
+{
+	/// <summary>A reference to a field..</summary>
+	/// <remarks>A reference to a field..</remarks>
+	public interface IFieldRef
+	{
+		ITypeRef Type
+		{
+			get;
+		}
+
+		string Name
+		{
+			get;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IMethodBuilder.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IMethodBuilder.cs
new file mode 100644
index 0000000..bcc24f8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IMethodBuilder.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.IO;
+using System.Reflection;
+using Db4objects.Db4o.Instrumentation.Api;
+
+namespace Db4objects.Db4o.Instrumentation.Api
+{
+	/// <summary>Cross platform interface for bytecode emission.</summary>
+	/// <remarks>Cross platform interface for bytecode emission.</remarks>
+	public interface IMethodBuilder
+	{
+		IReferenceProvider References
+		{
+			get;
+		}
+
+		void Ldc(object value);
+
+		void LoadArgument(int index);
+
+		void Pop();
+
+		void LoadArrayElement(ITypeRef elementType);
+
+		void Add(ITypeRef operandType);
+
+		void Subtract(ITypeRef operandType);
+
+		void Multiply(ITypeRef operandType);
+
+		void Divide(ITypeRef operandType);
+
+		void Invoke(IMethodRef method, CallingConvention convention);
+
+		void Invoke(MethodInfo method);
+
+		void LoadField(IFieldRef fieldRef);
+
+		void LoadStaticField(IFieldRef fieldRef);
+
+		void Box(ITypeRef boxedType);
+
+		void EndMethod();
+
+		void Print(TextWriter @out);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IMethodRef.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IMethodRef.cs
new file mode 100644
index 0000000..837a7a2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IMethodRef.cs
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Instrumentation.Api;
+
+namespace Db4objects.Db4o.Instrumentation.Api
+{
+	public interface IMethodRef
+	{
+		string Name
+		{
+			get;
+		}
+
+		ITypeRef ReturnType
+		{
+			get;
+		}
+
+		ITypeRef[] ParamTypes
+		{
+			get;
+		}
+
+		ITypeRef DeclaringType
+		{
+			get;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/INativeClassFactory.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/INativeClassFactory.cs
new file mode 100644
index 0000000..34e9f4e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/INativeClassFactory.cs
@@ -0,0 +1,13 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Instrumentation.Api
+{
+	/// <exclude></exclude>
+	public interface INativeClassFactory
+	{
+		/// <exception cref="System.TypeLoadException"></exception>
+		Type ForName(string className);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IReferenceProvider.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IReferenceProvider.cs
new file mode 100644
index 0000000..412ba4d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IReferenceProvider.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Reflection;
+using Db4objects.Db4o.Instrumentation.Api;
+
+namespace Db4objects.Db4o.Instrumentation.Api
+{
+	public interface IReferenceProvider
+	{
+		ITypeRef ForType(Type type);
+
+		IMethodRef ForMethod(MethodInfo method);
+
+		IMethodRef ForMethod(ITypeRef declaringType, string methodName, ITypeRef[] parameterTypes
+			, ITypeRef returnType);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IReferenceResolver.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IReferenceResolver.cs
new file mode 100644
index 0000000..02b98e8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IReferenceResolver.cs
@@ -0,0 +1,13 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Reflection;
+using Db4objects.Db4o.Instrumentation.Api;
+
+namespace Db4objects.Db4o.Instrumentation.Api
+{
+	public interface IReferenceResolver
+	{
+		/// <exception cref="Db4objects.Db4o.Instrumentation.Api.InstrumentationException"></exception>
+		MethodInfo Resolve(IMethodRef methodRef);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/ITypeEditor.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/ITypeEditor.cs
new file mode 100644
index 0000000..8787208
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/ITypeEditor.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Instrumentation.Api;
+
+namespace Db4objects.Db4o.Instrumentation.Api
+{
+	/// <summary>Cross platform interface for type instrumentation.</summary>
+	/// <remarks>Cross platform interface for type instrumentation.</remarks>
+	public interface ITypeEditor
+	{
+		ITypeRef Type
+		{
+			get;
+		}
+
+		IReferenceProvider References
+		{
+			get;
+		}
+
+		void AddInterface(ITypeRef type);
+
+		IMethodBuilder NewPublicMethod(string methodName, ITypeRef returnType, ITypeRef[]
+			 parameterTypes);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/ITypeRef.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/ITypeRef.cs
new file mode 100644
index 0000000..6f5f2d2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/ITypeRef.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Instrumentation.Api;
+
+namespace Db4objects.Db4o.Instrumentation.Api
+{
+	public interface ITypeRef
+	{
+		bool IsPrimitive
+		{
+			get;
+		}
+
+		ITypeRef ElementType
+		{
+			get;
+		}
+
+		string Name
+		{
+			get;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/InstrumentationException.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/InstrumentationException.cs
new file mode 100644
index 0000000..d6ccede
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/InstrumentationException.cs
@@ -0,0 +1,14 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Instrumentation.Api
+{
+	[System.Serializable]
+	public class InstrumentationException : Exception
+	{
+		public InstrumentationException(Exception cause) : base(cause.Message, cause)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Core/DefaultNativeClassFactory.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Core/DefaultNativeClassFactory.cs
new file mode 100644
index 0000000..a9ff4d2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Core/DefaultNativeClassFactory.cs
@@ -0,0 +1,17 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Instrumentation.Api;
+
+namespace Db4objects.Db4o.Instrumentation.Core
+{
+	/// <exclude></exclude>
+	public class DefaultNativeClassFactory : INativeClassFactory
+	{
+		/// <exception cref="System.TypeLoadException"></exception>
+		public virtual Type ForName(string className)
+		{
+			return Sharpen.Runtime.GetType(className);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Properties/AssemblyInfo.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Properties/AssemblyInfo.cs
new file mode 100755
index 0000000..3fc2e75
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/Properties/AssemblyInfo.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2009 Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Reflection;
+using System.Security;
+
+[assembly: AssemblyTitle("db4o - instrumentation layer")]
+[assembly: AssemblyCompany("Versant Corp., Redwood City, CA, USA")]
+[assembly: AssemblyProduct("db4o - database for objects")]
+[assembly: AssemblyCopyright("Versant Corp. 2000 - 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// attributes are automatically set by the build
+[assembly: AssemblyVersion("8.0.183.14430")]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyConfiguration(".NET")]
+[assembly: AssemblyDescription("Db4objects.Db4o.Instrumentation 8.0.183.14430 (.NET)")]
+
+#if !CF
+[assembly: AllowPartiallyTrustedCallers]
+#endif
+
+[assembly: CLSCompliant(true)]
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilFieldRef.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilFieldRef.cs
new file mode 100755
index 0000000..9f4858a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilFieldRef.cs
@@ -0,0 +1,28 @@
+using System;
+using Db4objects.Db4o.Instrumentation.Api;
+using Mono.Cecil;
+
+namespace Db4objects.Db4o.Instrumentation.Cecil
+{
+	public class CecilFieldRef : CecilRef<FieldReference>, IFieldRef
+	{
+		public CecilFieldRef(CecilReferenceProvider provider, FieldReference field) : base(provider, field)
+		{	
+		}
+
+		public FieldReference Field
+		{
+			get { return _reference; }
+		}
+
+		public TypeReference FieldType
+		{
+			get { return _reference.FieldType; }
+		}
+
+		public ITypeRef Type
+		{
+			get { return TypeRef(FieldType); }
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilMethodBuilder.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilMethodBuilder.cs
new file mode 100755
index 0000000..5bccebc
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilMethodBuilder.cs
@@ -0,0 +1,147 @@
+using System;
+using System.IO;
+using System.Reflection;
+using Cecil.FlowAnalysis.Utilities;
+using Db4objects.Db4o.Instrumentation.Api;
+using Mono.Cecil;
+using Mono.Cecil.Cil;
+
+namespace Db4objects.Db4o.Instrumentation.Cecil
+{
+	internal class CecilMethodBuilder : IMethodBuilder
+	{
+		private readonly MethodDefinition _method;
+		private readonly ILProcessor _il;
+
+		public CecilMethodBuilder(MethodDefinition method)
+		{
+			_method = method;
+			_il = method.Body.GetILProcessor();
+		}
+
+		public IReferenceProvider References
+		{
+			get { return CecilReferenceProvider.ForModule(_method.DeclaringType.Module.Assembly.MainModule); }
+		}
+
+		public void Ldc(object value)
+		{
+			Type type = value.GetType();
+			TypeCode code = Type.GetTypeCode(type);
+			switch (code)
+			{
+				case TypeCode.SByte:
+					_il.Emit(OpCodes.Ldc_I4_S, (SByte)value);
+					break;
+				case TypeCode.Int32:
+					_il.Emit(OpCodes.Ldc_I4, (Int32)value);
+					break;
+				case TypeCode.Int64:
+					_il.Emit(OpCodes.Ldc_I8, (Int64)value);
+					break;
+				case TypeCode.String:
+					_il.Emit(OpCodes.Ldstr, (String)value);
+					break;
+				default:
+					throw new NotImplementedException(code.ToString());
+			}
+		}
+
+		public void LoadArgument(int index)
+		{
+			switch (index)
+			{
+				case 0:
+					_il.Emit(OpCodes.Ldarg_0);
+					break;
+				case 1:
+					_il.Emit(OpCodes.Ldarg_1);
+					break;
+				default:
+					// TODO: This is wrong. Emit expects an VariableDefinition for a Ldarg .
+                    //       But actually no code passes idexes other than 0 and 1 
+                    _il.Emit(OpCodes.Ldarg, index);
+					break;
+			}
+		}
+
+		public void Pop()
+		{
+			_il.Emit(OpCodes.Pop);
+		}
+
+		public void LoadArrayElement(ITypeRef elementType)
+		{
+			throw new NotImplementedException();
+		}
+
+		public void Add(ITypeRef operandType)
+		{
+			throw new NotImplementedException();
+		}
+
+		public void Subtract(ITypeRef operandType)
+		{
+			throw new NotImplementedException();
+		}
+
+		public void Multiply(ITypeRef operandType)
+		{
+			throw new NotImplementedException();
+		}
+
+		public void Divide(ITypeRef operandType)
+		{
+			throw new NotImplementedException();
+		}
+
+		public void Invoke(IMethodRef method, CallingConvention convention)
+		{
+			_il.Emit(OpCodeForConvention(convention), CecilMethodRef.GetReference(method));
+		}
+
+		private static OpCode OpCodeForConvention(CallingConvention convention)
+		{
+			return convention == CallingConvention.Static
+			       	? OpCodes.Call
+			       	: OpCodes.Callvirt;
+		}
+
+		public void Invoke(MethodInfo method)
+		{
+			throw new NotImplementedException();
+		}
+
+		public void LoadField(IFieldRef fieldRef)
+		{
+			_il.Emit(OpCodes.Ldfld, GetReference(fieldRef));
+		}
+
+		private static FieldReference GetReference(IFieldRef fieldRef)
+		{
+			return CecilFieldRef.GetReference(fieldRef);
+		}
+
+		public void LoadStaticField(IFieldRef fieldRef)
+		{
+			_il.Emit(OpCodes.Ldsfld, GetReference(fieldRef));
+		}
+
+		public void Box(ITypeRef boxedType)
+		{
+			TypeReference type = CecilTypeRef.GetReference(boxedType);
+			if (!type.IsValueType) return;
+			_il.Emit(OpCodes.Box, type);
+		}
+
+		public void EndMethod()
+		{
+			_il.Emit(OpCodes.Ret);
+		}
+
+		public void Print(TextWriter @out)
+		{
+			Formatter.WriteMethodBody(@out, _method);
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilMethodRef.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilMethodRef.cs
new file mode 100755
index 0000000..6cbb689
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilMethodRef.cs
@@ -0,0 +1,28 @@
+using System;
+using Db4objects.Db4o.Instrumentation.Api;
+using Mono.Cecil;
+
+namespace Db4objects.Db4o.Instrumentation.Cecil
+{
+	internal class CecilMethodRef : CecilRef<MethodReference>, IMethodRef
+	{
+		public CecilMethodRef(CecilReferenceProvider provider, MethodReference method) : base(provider, method)
+		{
+		}
+
+		public ITypeRef ReturnType
+		{
+			get { return TypeRef(_reference.ReturnType); }
+		}
+
+		public ITypeRef[] ParamTypes
+		{
+			get { throw new NotImplementedException(); }
+		}
+
+		public ITypeRef DeclaringType
+		{
+			get { throw new NotImplementedException(); }
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilRef.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilRef.cs
new file mode 100755
index 0000000..da1a3ae
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilRef.cs
@@ -0,0 +1,43 @@
+using Db4objects.Db4o.Instrumentation.Api;
+using Mono.Cecil;
+
+namespace Db4objects.Db4o.Instrumentation.Cecil
+{
+	public class CecilRef<T> where T : MemberReference
+	{
+		public static T GetReference(object type)
+		{
+			return ((CecilRef<T>)type).Reference;
+		}
+
+		private readonly CecilReferenceProvider _provider;
+		protected T _reference;
+
+	    public CecilRef(CecilReferenceProvider provider, T reference)
+		{
+			_provider = provider;
+			_reference = reference;
+		}
+
+		protected ITypeRef TypeRef(TypeReference type)
+		{
+			return _provider.ForCecilType(type);
+		}
+
+		public T Reference
+		{
+			get { return _reference; }
+		    set { _reference = value; }
+		}
+
+		public virtual string Name
+		{
+			get { return _reference.Name;  }
+		}
+
+		public override string ToString()
+		{
+			return Name;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilReferenceProvider.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilReferenceProvider.cs
new file mode 100755
index 0000000..963105b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilReferenceProvider.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using Db4objects.Db4o.Instrumentation.Api;
+using Mono.Cecil;
+
+namespace Db4objects.Db4o.Instrumentation.Cecil
+{
+	public class CecilReferenceProvider : IReferenceProvider
+	{
+		public static CecilReferenceProvider ForModule(ModuleDefinition module)
+		{
+			return new CecilReferenceProvider(module);
+		}
+
+		private readonly ModuleDefinition _module;
+		private readonly Dictionary<TypeReference, ITypeRef> _typeCache = new Dictionary<TypeReference, ITypeRef>();
+
+		private CecilReferenceProvider(ModuleDefinition module)
+		{
+			if (null == module) throw new ArgumentNullException();
+			_module = module;
+		}
+
+		public ITypeRef ForType(Type type)
+		{
+#if CF
+			return ForCecilType(ImportType(type));
+#else
+			return ForCecilType(_module.Import(type));
+#endif
+		}
+
+		public ITypeRef ForCecilType(TypeReference type)
+		{
+			ITypeRef typeRef;
+			if (!_typeCache.TryGetValue(type, out typeRef))
+			{
+				typeRef = new CecilTypeRef(this, type);
+				_typeCache.Add(type, typeRef);
+			}
+			return typeRef;
+		}
+
+		public IMethodRef ForMethod(MethodInfo method)
+		{
+#if CF
+			return new CecilMethodRef(this, _module.Import(new MethodReference(method.Name, ImportType(method.ReturnType))));
+#else
+			return new CecilMethodRef(this, _module.Import(method));
+#endif
+		}
+
+#if CF
+		private TypeReference ImportType(Type type)
+		{
+			return _module.Import(new TypeReference(type.Namespace, type.Name, _module));
+		}
+#endif
+
+		public IMethodRef ForMethod(ITypeRef declaringType, string methodName, ITypeRef[] parameterTypes, ITypeRef returnType)
+		{
+			throw new NotImplementedException();
+		}
+
+		public IFieldRef ForCecilField(FieldReference field)
+		{
+			return new CecilFieldRef(this, field);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilReferenceResolver.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilReferenceResolver.cs
new file mode 100755
index 0000000..f72bb46
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilReferenceResolver.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Reflection;
+using Db4objects.Db4o.Instrumentation.Api;
+
+namespace Db4objects.Db4o.Instrumentation.Cecil
+{
+	public class CecilReferenceResolver : IReferenceResolver
+	{
+		public MethodInfo Resolve(IMethodRef methodRef)
+		{
+			throw new NotImplementedException();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilTypeEditor.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilTypeEditor.cs
new file mode 100755
index 0000000..1484d6c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilTypeEditor.cs
@@ -0,0 +1,60 @@
+using System;
+using System.IO;
+using System.Reflection;
+using Db4objects.Db4o.Instrumentation.Api;
+using Mono.Cecil;
+using MethodAttributes=Mono.Cecil.MethodAttributes;
+
+namespace Db4objects.Db4o.Instrumentation.Cecil
+{
+	public class CecilTypeEditor : ITypeEditor
+	{
+		private readonly TypeDefinition _type;
+		private readonly CecilReferenceProvider _references;
+
+		public CecilTypeEditor(TypeDefinition type)
+		{
+			_type = type;
+			_references = CecilReferenceProvider.ForModule(type.Module.Assembly.MainModule);
+		}
+
+		public ITypeRef Type
+		{
+			get { return _references.ForCecilType(_type); }
+		}
+
+		public IReferenceProvider References
+		{
+			get { return _references; }
+		}
+
+		public void AddInterface(ITypeRef type)
+		{
+			_type.Interfaces.Add(GetTypeReference(type));
+		}
+
+		public IMethodBuilder NewPublicMethod(string methodName, ITypeRef returnType, ITypeRef[] parameterTypes)
+		{
+			MethodDefinition method = NewMethod(methodName, parameterTypes, returnType);
+			_type.Methods.Add(method);
+			return new CecilMethodBuilder(method);
+		}
+
+		private static MethodDefinition NewMethod(string methodName, ITypeRef[] parameterTypes, ITypeRef returnType)
+		{
+			MethodDefinition method = new MethodDefinition(methodName,
+			                                               MethodAttributes.Virtual | MethodAttributes.Public,
+			                                               GetTypeReference(returnType));
+			foreach (ITypeRef paramType in parameterTypes)
+			{
+				method.Parameters.Add(new ParameterDefinition(GetTypeReference(paramType)));
+			}
+			return method;
+		}
+
+		private static TypeReference GetTypeReference(ITypeRef type)
+		{
+			return CecilTypeRef.GetReference(type);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilTypeRef.cs b/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilTypeRef.cs
new file mode 100755
index 0000000..8e71af6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilTypeRef.cs
@@ -0,0 +1,42 @@
+using System;
+using Db4objects.Db4o.Instrumentation.Api;
+using Mono.Cecil;
+
+namespace Db4objects.Db4o.Instrumentation.Cecil
+{
+	public class CecilTypeRef : CecilRef<TypeReference>, ITypeRef
+	{
+		public CecilTypeRef(CecilReferenceProvider provider, TypeReference type) : base(provider, type)
+		{
+		}
+
+		public bool IsPrimitive
+		{
+			get
+			{	
+				switch (_reference.FullName)
+				{
+					case "System.Int32":
+					case "System.Boolean":
+						return true;
+				}
+				return false;
+			}
+		}
+
+		public ITypeRef ElementType
+		{
+			get { throw new NotImplementedException(); }
+		}
+
+		public override string Name
+		{
+			get { return NormalizeNestedTypeNotation(_reference.FullName); }
+		}
+
+		private static string NormalizeNestedTypeNotation(string fullName)
+		{
+			return fullName.Replace('/', '+');
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries-2008.csproj b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries-2008.csproj
new file mode 100644
index 0000000..120f635
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries-2008.csproj
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build" ToolsVersion="3.5">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{AB1BF369-A9C4-4876-9797-178DB8AD437F}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Db4objects.Db4o.NativeQueries</RootNamespace>
+    <AssemblyName>Db4objects.Db4o.NativeQueries</AssemblyName>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>2.0</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    
+    
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<SignAssembly>true</SignAssembly>
+<AssemblyOriginatorKeyFile>../db4objects.snk</AssemblyOriginatorKeyFile>
+</PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE;NET_3_5</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Debug\Db4objects.Db4o.NativeQueries.xml</DocumentationFile>
+    <NoWarn>1591;1572;1573;1574;0419;</NoWarn>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE;NET_3_5</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Release\Db4objects.Db4o.NativeQueries.xml</DocumentationFile>
+    <NoWarn>1591;1572;1573;1574;0419;</NoWarn>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Cecil.FlowAnalysis, Version=0.1.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\Libs\net-2.0\Cecil.FlowAnalysis.dll</HintPath>
+    </Reference>
+    <Reference Include="Mono.Cecil, Version=0.6.8.8607, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\Libs\net-2.0\Mono.Cecil.dll</HintPath>
+    </Reference>
+    <Reference Include="System"/>
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data"/>
+    <Reference Include="System.Xml"/>
+  </ItemGroup>
+  <ItemGroup>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\AndExpression.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\BinaryExpression.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\BoolConstExpression.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Build\ExpressionBuilder.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Cmp\ArithmeticOperator.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Cmp\ComparisonOperator.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Cmp\Operand\ArithmeticExpression.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Cmp\Operand\ArrayAccessValue.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Cmp\Operand\CandidateFieldRoot.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Cmp\Operand\ComparisonOperandDescendant.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Cmp\Operand\ComparisonOperandRoot.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Cmp\Operand\ConstValue.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Cmp\Operand\FieldValue.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Cmp\Operand\IComparisonOperand.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Cmp\Operand\IComparisonOperandAnchor.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Cmp\Operand\IComparisonOperandVisitor.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Cmp\Operand\MethodCallValue.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Cmp\Operand\PredicateFieldRoot.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Cmp\Operand\StaticFieldRoot.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\Cmp\Operand\ThreeWayComparison.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\ComparisonExpression.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\IExpression.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\IExpressionPart.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\IExpressionVisitor.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\IgnoredExpression.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\NotExpression.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\OrExpression.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Expr\TraversingExpressionVisitor.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Instrumentation\ComparisonBytecodeGeneratingVisitor.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Instrumentation\SODAMethodBuilder.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Instrumentation\TypeDeducingVisitor.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Optimization\ComparisonQueryGeneratingVisitor.cs"/>
+<Compile Include="Db4objects.Db4o.NativeQueries\Optimization\SODAQueryBuilder.cs"/>
+<Compile Include="Properties\AssemblyInfo.cs"/>
+<Compile Include="native\Db4objects.Db4o.NativeQueries\AssemblyResolver.cs"/>
+<Compile Include="native\Db4objects.Db4o.NativeQueries\ICachingStrategy.cs"/>
+<Compile Include="native\Db4objects.Db4o.NativeQueries\NQOptimizer.cs"/>
+<Compile Include="native\Db4objects.Db4o.NativeQueries\Optimization\NativeQueriesPlatform.cs"/>
+<Compile Include="native\Db4objects.Db4o.NativeQueries\QueryExpressionBuilder.cs"/>
+<Compile Include="native\Db4objects.Db4o.NativeQueries\SingleItemCachingStrategy.cs"/>
+<Compile Include="native\Db4objects.Db4o.NativeQueries\UnsupportedPredicateException.cs"/>
+</ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Db4objects.Db4o.Instrumentation\Db4objects.Db4o.Instrumentation-2008.csproj">
+      <Project>{FFA59708-14D1-4C22-B9A4-1A389EE796D5}</Project>
+      <Name>Db4objects.Db4o.Instrumentation-2008</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Db4objects.Db4o\Db4objects.Db4o-2008.csproj">
+      <Project>{600CD3BF-2ED2-4183-87F7-ADD78A968AE0}</Project>
+      <Name>Db4objects.Db4o-2008</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets"/>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/AndExpression.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/AndExpression.cs
new file mode 100644
index 0000000..d408377
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/AndExpression.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr;
+
+namespace Db4objects.Db4o.NativeQueries.Expr
+{
+	public class AndExpression : BinaryExpression
+	{
+		public AndExpression(IExpression left, IExpression right) : base(left, right)
+		{
+		}
+
+		public override string ToString()
+		{
+			return "(" + _left + ")&&(" + _right + ")";
+		}
+
+		public override void Accept(IExpressionVisitor visitor)
+		{
+			visitor.Visit(this);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/BinaryExpression.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/BinaryExpression.cs
new file mode 100644
index 0000000..2396655
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/BinaryExpression.cs
@@ -0,0 +1,52 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr;
+
+namespace Db4objects.Db4o.NativeQueries.Expr
+{
+	public abstract class BinaryExpression : IExpression
+	{
+		protected IExpression _left;
+
+		protected IExpression _right;
+
+		public BinaryExpression(IExpression left, IExpression right)
+		{
+			this._left = left;
+			this._right = right;
+		}
+
+		public virtual IExpression Left()
+		{
+			return _left;
+		}
+
+		public virtual IExpression Right()
+		{
+			return _right;
+		}
+
+		public override bool Equals(object other)
+		{
+			if (this == other)
+			{
+				return true;
+			}
+			if (other == null || GetType() != other.GetType())
+			{
+				return false;
+			}
+			Db4objects.Db4o.NativeQueries.Expr.BinaryExpression casted = (Db4objects.Db4o.NativeQueries.Expr.BinaryExpression
+				)other;
+			return _left.Equals(casted._left) && (_right.Equals(casted._right)) || _left.Equals
+				(casted._right) && (_right.Equals(casted._left));
+		}
+
+		public override int GetHashCode()
+		{
+			return _left.GetHashCode() + _right.GetHashCode();
+		}
+
+		public abstract void Accept(IExpressionVisitor arg1);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/BoolConstExpression.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/BoolConstExpression.cs
new file mode 100644
index 0000000..64f26c7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/BoolConstExpression.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr;
+
+namespace Db4objects.Db4o.NativeQueries.Expr
+{
+	public class BoolConstExpression : IExpression
+	{
+		public static readonly Db4objects.Db4o.NativeQueries.Expr.BoolConstExpression True
+			 = new Db4objects.Db4o.NativeQueries.Expr.BoolConstExpression(true);
+
+		public static readonly Db4objects.Db4o.NativeQueries.Expr.BoolConstExpression False
+			 = new Db4objects.Db4o.NativeQueries.Expr.BoolConstExpression(false);
+
+		private bool _value;
+
+		private BoolConstExpression(bool value)
+		{
+			this._value = value;
+		}
+
+		public virtual bool Value()
+		{
+			return _value;
+		}
+
+		public override string ToString()
+		{
+			return _value.ToString();
+		}
+
+		public static Db4objects.Db4o.NativeQueries.Expr.BoolConstExpression Expr(bool value
+			)
+		{
+			return (value ? True : False);
+		}
+
+		public virtual void Accept(IExpressionVisitor visitor)
+		{
+			visitor.Visit(this);
+		}
+
+		public virtual IExpression Negate()
+		{
+			return (_value ? False : True);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Build/ExpressionBuilder.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Build/ExpressionBuilder.cs
new file mode 100644
index 0000000..0acb140
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Build/ExpressionBuilder.cs
@@ -0,0 +1,198 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Build
+{
+	public class ExpressionBuilder
+	{
+		/// <summary>Optimizations: !(Bool)->(!Bool), !!X->X, !(X==Bool)->(X==!Bool)
+		/// 	</summary>
+		public virtual IExpression Not(IExpression expr)
+		{
+			if (expr.Equals(BoolConstExpression.True))
+			{
+				return BoolConstExpression.False;
+			}
+			if (expr.Equals(BoolConstExpression.False))
+			{
+				return BoolConstExpression.True;
+			}
+			if (expr is NotExpression)
+			{
+				return ((NotExpression)expr).Expr();
+			}
+			if (expr is ComparisonExpression)
+			{
+				ComparisonExpression cmpExpr = (ComparisonExpression)expr;
+				if (cmpExpr.Right() is ConstValue)
+				{
+					ConstValue rightConst = (ConstValue)cmpExpr.Right();
+					if (rightConst.Value() is bool)
+					{
+						bool boolVal = (bool)rightConst.Value();
+						// new Boolean() instead of Boolean.valueOf() for .NET conversion
+						return new ComparisonExpression(cmpExpr.Left(), new ConstValue(!boolVal), cmpExpr
+							.Op());
+					}
+				}
+			}
+			return new NotExpression(expr);
+		}
+
+		/// <summary>Optimizations: f&&X->f, t&&X->X, X&&X->X, X&&!X->f</summary>
+		public virtual IExpression And(IExpression left, IExpression right)
+		{
+			if (left.Equals(BoolConstExpression.False) || right.Equals(BoolConstExpression.False
+				))
+			{
+				return BoolConstExpression.False;
+			}
+			if (left.Equals(BoolConstExpression.True))
+			{
+				return right;
+			}
+			if (right.Equals(BoolConstExpression.True))
+			{
+				return left;
+			}
+			if (left.Equals(right))
+			{
+				return left;
+			}
+			if (Negatives(left, right))
+			{
+				return BoolConstExpression.False;
+			}
+			return new AndExpression(left, right);
+		}
+
+		/// <summary>Optimizations: X||t->t, f||X->X, X||X->X, X||!X->t</summary>
+		public virtual IExpression Or(IExpression left, IExpression right)
+		{
+			if (left.Equals(BoolConstExpression.True) || right.Equals(BoolConstExpression.True
+				))
+			{
+				return BoolConstExpression.True;
+			}
+			if (left.Equals(BoolConstExpression.False))
+			{
+				return right;
+			}
+			if (right.Equals(BoolConstExpression.False))
+			{
+				return left;
+			}
+			if (left.Equals(right))
+			{
+				return left;
+			}
+			if (Negatives(left, right))
+			{
+				return BoolConstExpression.True;
+			}
+			return new OrExpression(left, right);
+		}
+
+		/// <summary>Optimizations: static bool roots</summary>
+		public virtual BoolConstExpression Constant(bool value)
+		{
+			return BoolConstExpression.Expr(value);
+		}
+
+		public virtual IExpression IfThenElse(IExpression cond, IExpression truePath, IExpression
+			 falsePath)
+		{
+			IExpression expr = CheckBoolean(cond, truePath, falsePath);
+			if (expr != null)
+			{
+				return expr;
+			}
+			return Or(And(cond, truePath), And(Not(cond), falsePath));
+		}
+
+		private IExpression CheckBoolean(IExpression cmp, IExpression trueExpr, IExpression
+			 falseExpr)
+		{
+			if (cmp is BoolConstExpression)
+			{
+				return null;
+			}
+			if (trueExpr is BoolConstExpression)
+			{
+				bool leftNegative = trueExpr.Equals(BoolConstExpression.False);
+				if (!leftNegative)
+				{
+					return Or(cmp, falseExpr);
+				}
+				else
+				{
+					return And(Not(cmp), falseExpr);
+				}
+			}
+			if (falseExpr is BoolConstExpression)
+			{
+				bool rightNegative = falseExpr.Equals(BoolConstExpression.False);
+				if (!rightNegative)
+				{
+					return And(cmp, trueExpr);
+				}
+				else
+				{
+					return Or(Not(cmp), falseExpr);
+				}
+			}
+			if (cmp is NotExpression)
+			{
+				cmp = ((NotExpression)cmp).Expr();
+				IExpression swap = trueExpr;
+				trueExpr = falseExpr;
+				falseExpr = swap;
+			}
+			if (trueExpr is OrExpression)
+			{
+				OrExpression orExpr = (OrExpression)trueExpr;
+				IExpression orLeft = orExpr.Left();
+				IExpression orRight = orExpr.Right();
+				if (falseExpr.Equals(orRight))
+				{
+					IExpression swap = orRight;
+					orRight = orLeft;
+					orLeft = swap;
+				}
+				if (falseExpr.Equals(orLeft))
+				{
+					return Or(orLeft, And(cmp, orRight));
+				}
+			}
+			if (falseExpr is AndExpression)
+			{
+				AndExpression andExpr = (AndExpression)falseExpr;
+				IExpression andLeft = andExpr.Left();
+				IExpression andRight = andExpr.Right();
+				if (trueExpr.Equals(andRight))
+				{
+					IExpression swap = andRight;
+					andRight = andLeft;
+					andLeft = swap;
+				}
+				if (trueExpr.Equals(andLeft))
+				{
+					return And(andLeft, Or(cmp, andRight));
+				}
+			}
+			return null;
+		}
+
+		private bool Negatives(IExpression left, IExpression right)
+		{
+			return NegativeOf(left, right) || NegativeOf(right, left);
+		}
+
+		private bool NegativeOf(IExpression right, IExpression left)
+		{
+			return (right is NotExpression) && ((NotExpression)right).Expr().Equals(left);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/ArithmeticOperator.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/ArithmeticOperator.cs
new file mode 100644
index 0000000..cfb0fe1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/ArithmeticOperator.cs
@@ -0,0 +1,50 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Cmp
+{
+	public sealed class ArithmeticOperator
+	{
+		public const int AddId = 0;
+
+		public const int SubtractId = 1;
+
+		public const int MultiplyId = 2;
+
+		public const int DivideId = 3;
+
+		public static readonly Db4objects.Db4o.NativeQueries.Expr.Cmp.ArithmeticOperator 
+			Add = new Db4objects.Db4o.NativeQueries.Expr.Cmp.ArithmeticOperator(AddId, "+");
+
+		public static readonly Db4objects.Db4o.NativeQueries.Expr.Cmp.ArithmeticOperator 
+			Subtract = new Db4objects.Db4o.NativeQueries.Expr.Cmp.ArithmeticOperator(SubtractId
+			, "-");
+
+		public static readonly Db4objects.Db4o.NativeQueries.Expr.Cmp.ArithmeticOperator 
+			Multiply = new Db4objects.Db4o.NativeQueries.Expr.Cmp.ArithmeticOperator(MultiplyId
+			, "*");
+
+		public static readonly Db4objects.Db4o.NativeQueries.Expr.Cmp.ArithmeticOperator 
+			Divide = new Db4objects.Db4o.NativeQueries.Expr.Cmp.ArithmeticOperator(DivideId, 
+			"/");
+
+		private string _op;
+
+		private int _id;
+
+		private ArithmeticOperator(int id, string op)
+		{
+			_id = id;
+			_op = op;
+		}
+
+		public int Id()
+		{
+			return _id;
+		}
+
+		public override string ToString()
+		{
+			return _op;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/ComparisonOperator.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/ComparisonOperator.cs
new file mode 100644
index 0000000..9330332
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/ComparisonOperator.cs
@@ -0,0 +1,78 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Cmp
+{
+	public sealed class ComparisonOperator
+	{
+		public const int EqualsId = 0;
+
+		public const int SmallerId = 1;
+
+		public const int GreaterId = 2;
+
+		public const int ContainsId = 3;
+
+		public const int StartswithId = 4;
+
+		public const int EndswithId = 5;
+
+		public const int IdentityId = 6;
+
+		public static readonly Db4objects.Db4o.NativeQueries.Expr.Cmp.ComparisonOperator 
+			ValueEquality = new Db4objects.Db4o.NativeQueries.Expr.Cmp.ComparisonOperator(EqualsId
+			, "==", true);
+
+		public static readonly Db4objects.Db4o.NativeQueries.Expr.Cmp.ComparisonOperator 
+			Smaller = new Db4objects.Db4o.NativeQueries.Expr.Cmp.ComparisonOperator(SmallerId
+			, "<", false);
+
+		public static readonly Db4objects.Db4o.NativeQueries.Expr.Cmp.ComparisonOperator 
+			Greater = new Db4objects.Db4o.NativeQueries.Expr.Cmp.ComparisonOperator(GreaterId
+			, ">", false);
+
+		public static readonly Db4objects.Db4o.NativeQueries.Expr.Cmp.ComparisonOperator 
+			Contains = new Db4objects.Db4o.NativeQueries.Expr.Cmp.ComparisonOperator(ContainsId
+			, "<CONTAINS>", false);
+
+		public static readonly Db4objects.Db4o.NativeQueries.Expr.Cmp.ComparisonOperator 
+			StartsWith = new Db4objects.Db4o.NativeQueries.Expr.Cmp.ComparisonOperator(StartswithId
+			, "<STARTSWITH>", false);
+
+		public static readonly Db4objects.Db4o.NativeQueries.Expr.Cmp.ComparisonOperator 
+			EndsWith = new Db4objects.Db4o.NativeQueries.Expr.Cmp.ComparisonOperator(EndswithId
+			, "<ENDSWITH>", false);
+
+		public static readonly Db4objects.Db4o.NativeQueries.Expr.Cmp.ComparisonOperator 
+			ReferenceEquality = new Db4objects.Db4o.NativeQueries.Expr.Cmp.ComparisonOperator
+			(IdentityId, "===", true);
+
+		private int _id;
+
+		private string _op;
+
+		private bool _symmetric;
+
+		private ComparisonOperator(int id, string op, bool symmetric)
+		{
+			// TODO: switch to individual classes and visitor dispatch?
+			_id = id;
+			_op = op;
+			_symmetric = symmetric;
+		}
+
+		public int Id()
+		{
+			return _id;
+		}
+
+		public override string ToString()
+		{
+			return _op;
+		}
+
+		public bool IsSymmetric()
+		{
+			return _symmetric;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ArithmeticExpression.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ArithmeticExpression.cs
new file mode 100644
index 0000000..0ff045a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ArithmeticExpression.cs
@@ -0,0 +1,73 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr.Cmp;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand
+{
+	public class ArithmeticExpression : IComparisonOperand
+	{
+		private ArithmeticOperator _op;
+
+		private IComparisonOperand _left;
+
+		private IComparisonOperand _right;
+
+		public ArithmeticExpression(IComparisonOperand left, IComparisonOperand right, ArithmeticOperator
+			 op)
+		{
+			this._op = op;
+			this._left = left;
+			this._right = right;
+		}
+
+		public virtual IComparisonOperand Left()
+		{
+			return _left;
+		}
+
+		public virtual IComparisonOperand Right()
+		{
+			return _right;
+		}
+
+		public virtual ArithmeticOperator Op()
+		{
+			return _op;
+		}
+
+		public override string ToString()
+		{
+			return "(" + _left + _op + _right + ")";
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj)
+			{
+				return true;
+			}
+			if (obj == null || obj.GetType() != GetType())
+			{
+				return false;
+			}
+			Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.ArithmeticExpression casted = (Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.ArithmeticExpression
+				)obj;
+			return _left.Equals(casted._left) && _right.Equals(casted._right) && _op.Equals(casted
+				._op);
+		}
+
+		public override int GetHashCode()
+		{
+			int hc = _left.GetHashCode();
+			hc *= 29 + _right.GetHashCode();
+			hc *= 29 + _op.GetHashCode();
+			return hc;
+		}
+
+		public virtual void Accept(IComparisonOperandVisitor visitor)
+		{
+			visitor.Visit(this);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ArrayAccessValue.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ArrayAccessValue.cs
new file mode 100644
index 0000000..46e729d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ArrayAccessValue.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Instrumentation.Api;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand
+{
+	public class ArrayAccessValue : ComparisonOperandDescendant
+	{
+		private IComparisonOperand _index;
+
+		public ArrayAccessValue(ComparisonOperandDescendant parent, IComparisonOperand index
+			) : base(parent)
+		{
+			_index = index;
+		}
+
+		public override void Accept(IComparisonOperandVisitor visitor)
+		{
+			visitor.Visit(this);
+		}
+
+		public virtual IComparisonOperand Index()
+		{
+			return _index;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (!base.Equals(obj))
+			{
+				return false;
+			}
+			Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.ArrayAccessValue casted = (Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.ArrayAccessValue
+				)obj;
+			return _index.Equals(casted._index);
+		}
+
+		public override int GetHashCode()
+		{
+			return base.GetHashCode() * 29 + _index.GetHashCode();
+		}
+
+		public override string ToString()
+		{
+			return base.ToString() + "[" + _index + "]";
+		}
+
+		public override ITypeRef Type
+		{
+			get
+			{
+				return ((ComparisonOperandDescendant)Parent()).Type.ElementType;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/CandidateFieldRoot.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/CandidateFieldRoot.cs
new file mode 100644
index 0000000..ba1e0c8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/CandidateFieldRoot.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand
+{
+	public class CandidateFieldRoot : ComparisonOperandRoot
+	{
+		public static readonly Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.CandidateFieldRoot
+			 Instance = new Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.CandidateFieldRoot
+			();
+
+		private CandidateFieldRoot()
+		{
+		}
+
+		public override string ToString()
+		{
+			return "CANDIDATE";
+		}
+
+		public override void Accept(IComparisonOperandVisitor visitor)
+		{
+			visitor.Visit(this);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ComparisonOperandDescendant.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ComparisonOperandDescendant.cs
new file mode 100644
index 0000000..1ee9e5e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ComparisonOperandDescendant.cs
@@ -0,0 +1,59 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Instrumentation.Api;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand
+{
+	public abstract class ComparisonOperandDescendant : IComparisonOperandAnchor
+	{
+		private IComparisonOperandAnchor _parent;
+
+		protected ComparisonOperandDescendant(IComparisonOperandAnchor _parent)
+		{
+			this._parent = _parent;
+		}
+
+		public IComparisonOperandAnchor Parent()
+		{
+			return _parent;
+		}
+
+		public IComparisonOperandAnchor Root()
+		{
+			return _parent.Root();
+		}
+
+		public abstract ITypeRef Type
+		{
+			get;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj)
+			{
+				return true;
+			}
+			if (obj == null || GetType() != obj.GetType())
+			{
+				return false;
+			}
+			Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.ComparisonOperandDescendant casted
+				 = (Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.ComparisonOperandDescendant)obj;
+			return _parent.Equals(casted._parent);
+		}
+
+		public override int GetHashCode()
+		{
+			return _parent.GetHashCode();
+		}
+
+		public override string ToString()
+		{
+			return _parent.ToString();
+		}
+
+		public abstract void Accept(IComparisonOperandVisitor arg1);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ComparisonOperandRoot.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ComparisonOperandRoot.cs
new file mode 100644
index 0000000..8e94198
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ComparisonOperandRoot.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand
+{
+	public abstract class ComparisonOperandRoot : IComparisonOperandAnchor
+	{
+		public virtual IComparisonOperandAnchor Parent()
+		{
+			return null;
+		}
+
+		public IComparisonOperandAnchor Root()
+		{
+			return this;
+		}
+
+		public abstract void Accept(IComparisonOperandVisitor arg1);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ConstValue.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ConstValue.cs
new file mode 100644
index 0000000..c87a7f3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ConstValue.cs
@@ -0,0 +1,72 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand
+{
+	public class ConstValue : IComparisonOperand
+	{
+		private object _value;
+
+		public ConstValue(object value)
+		{
+			this._value = value;
+		}
+
+		public virtual object Value()
+		{
+			return _value;
+		}
+
+		public virtual void Value(object value)
+		{
+			_value = value;
+		}
+
+		public override string ToString()
+		{
+			if (_value == null)
+			{
+				return "null";
+			}
+			if (_value is string)
+			{
+				return "\"" + _value + "\"";
+			}
+			return _value.ToString();
+		}
+
+		public override bool Equals(object other)
+		{
+			if (this == other)
+			{
+				return true;
+			}
+			if (other == null || GetType() != other.GetType())
+			{
+				return false;
+			}
+			object otherValue = ((Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.ConstValue)other
+				)._value;
+			if (otherValue == _value)
+			{
+				return true;
+			}
+			if (otherValue == null || _value == null)
+			{
+				return false;
+			}
+			return _value.Equals(otherValue);
+		}
+
+		public override int GetHashCode()
+		{
+			return _value.GetHashCode();
+		}
+
+		public virtual void Accept(IComparisonOperandVisitor visitor)
+		{
+			visitor.Visit(this);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/FieldValue.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/FieldValue.cs
new file mode 100644
index 0000000..86b8e85
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/FieldValue.cs
@@ -0,0 +1,64 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Instrumentation.Api;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand
+{
+	public class FieldValue : ComparisonOperandDescendant
+	{
+		private readonly IFieldRef _field;
+
+		public FieldValue(IComparisonOperandAnchor root, IFieldRef field) : base(root)
+		{
+			_field = field;
+		}
+
+		public virtual string FieldName()
+		{
+			return _field.Name;
+		}
+
+		public override bool Equals(object other)
+		{
+			if (!base.Equals(other))
+			{
+				return false;
+			}
+			Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.FieldValue casted = (Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.FieldValue
+				)other;
+			return _field.Equals(casted._field);
+		}
+
+		public override int GetHashCode()
+		{
+			return base.GetHashCode() * 29 + _field.GetHashCode();
+		}
+
+		public override string ToString()
+		{
+			return base.ToString() + "." + _field;
+		}
+
+		public override void Accept(IComparisonOperandVisitor visitor)
+		{
+			visitor.Visit(this);
+		}
+
+		public virtual IFieldRef Field
+		{
+			get
+			{
+				return _field;
+			}
+		}
+
+		public override ITypeRef Type
+		{
+			get
+			{
+				return _field.Type;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/IComparisonOperand.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/IComparisonOperand.cs
new file mode 100644
index 0000000..e6311f3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/IComparisonOperand.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand
+{
+	public interface IComparisonOperand : IExpressionPart
+	{
+		void Accept(IComparisonOperandVisitor visitor);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/IComparisonOperandAnchor.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/IComparisonOperandAnchor.cs
new file mode 100644
index 0000000..dc85e70
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/IComparisonOperandAnchor.cs
@@ -0,0 +1,13 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand
+{
+	public interface IComparisonOperandAnchor : IComparisonOperand
+	{
+		IComparisonOperandAnchor Parent();
+
+		IComparisonOperandAnchor Root();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/IComparisonOperandVisitor.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/IComparisonOperandVisitor.cs
new file mode 100644
index 0000000..0dbdcd8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/IComparisonOperandVisitor.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand
+{
+	public interface IComparisonOperandVisitor
+	{
+		void Visit(ArithmeticExpression operand);
+
+		void Visit(ConstValue operand);
+
+		void Visit(FieldValue operand);
+
+		void Visit(CandidateFieldRoot root);
+
+		void Visit(PredicateFieldRoot root);
+
+		void Visit(StaticFieldRoot root);
+
+		void Visit(ArrayAccessValue operand);
+
+		void Visit(MethodCallValue value);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/MethodCallValue.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/MethodCallValue.cs
new file mode 100644
index 0000000..170e028
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/MethodCallValue.cs
@@ -0,0 +1,89 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Instrumentation.Api;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand
+{
+	public class MethodCallValue : ComparisonOperandDescendant
+	{
+		private readonly IMethodRef _method;
+
+		private readonly IComparisonOperand[] _args;
+
+		private readonly Db4objects.Db4o.Instrumentation.Api.CallingConvention _callingConvention;
+
+		public MethodCallValue(IMethodRef method, Db4objects.Db4o.Instrumentation.Api.CallingConvention
+			 callingConvention, IComparisonOperandAnchor parent, IComparisonOperand[] args) : 
+			base(parent)
+		{
+			_method = method;
+			_args = args;
+			_callingConvention = callingConvention;
+		}
+
+		public override void Accept(IComparisonOperandVisitor visitor)
+		{
+			visitor.Visit(this);
+		}
+
+		public virtual IComparisonOperand[] Args
+		{
+			get
+			{
+				return _args;
+			}
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (!base.Equals(obj))
+			{
+				return false;
+			}
+			Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.MethodCallValue casted = (Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.MethodCallValue
+				)obj;
+			return _method.Equals(casted._method) && _callingConvention == casted._callingConvention;
+		}
+
+		public override int GetHashCode()
+		{
+			int hc = base.GetHashCode();
+			hc *= 29 + _method.GetHashCode();
+			hc *= 29 + _args.GetHashCode();
+			hc *= 29 + _callingConvention.GetHashCode();
+			return hc;
+		}
+
+		public override string ToString()
+		{
+			return base.ToString() + "." + _method.Name + Iterators.Join(Iterators.Iterate(_args
+				), "(", ")", ", ");
+		}
+
+		public virtual IMethodRef Method
+		{
+			get
+			{
+				return _method;
+			}
+		}
+
+		public virtual Db4objects.Db4o.Instrumentation.Api.CallingConvention CallingConvention
+		{
+			get
+			{
+				return _callingConvention;
+			}
+		}
+
+		public override ITypeRef Type
+		{
+			get
+			{
+				return _method.ReturnType;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/PredicateFieldRoot.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/PredicateFieldRoot.cs
new file mode 100644
index 0000000..5951433
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/PredicateFieldRoot.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand
+{
+	public class PredicateFieldRoot : ComparisonOperandRoot
+	{
+		public static readonly Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.PredicateFieldRoot
+			 Instance = new Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.PredicateFieldRoot
+			();
+
+		private PredicateFieldRoot()
+		{
+		}
+
+		public override string ToString()
+		{
+			return "PREDICATE";
+		}
+
+		public override void Accept(IComparisonOperandVisitor visitor)
+		{
+			visitor.Visit(this);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/StaticFieldRoot.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/StaticFieldRoot.cs
new file mode 100644
index 0000000..564d3fb
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/StaticFieldRoot.cs
@@ -0,0 +1,60 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Instrumentation.Api;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand
+{
+	public class StaticFieldRoot : ComparisonOperandRoot
+	{
+		private ITypeRef _type;
+
+		public StaticFieldRoot(ITypeRef type)
+		{
+			if (null == type)
+			{
+				throw new ArgumentNullException();
+			}
+			_type = type;
+		}
+
+		public virtual ITypeRef Type
+		{
+			get
+			{
+				return _type;
+			}
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (obj == this)
+			{
+				return true;
+			}
+			if (obj == null || GetType() != obj.GetType())
+			{
+				return false;
+			}
+			Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.StaticFieldRoot casted = (Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand.StaticFieldRoot
+				)obj;
+			return _type.Equals(casted._type);
+		}
+
+		public override int GetHashCode()
+		{
+			return _type.GetHashCode();
+		}
+
+		public override string ToString()
+		{
+			return _type.ToString();
+		}
+
+		public override void Accept(IComparisonOperandVisitor visitor)
+		{
+			visitor.Visit(this);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ThreeWayComparison.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ThreeWayComparison.cs
new file mode 100644
index 0000000..1f86800
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ThreeWayComparison.cs
@@ -0,0 +1,39 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand
+{
+	public class ThreeWayComparison : IExpressionPart
+	{
+		private FieldValue _left;
+
+		private IComparisonOperand _right;
+
+		private bool _swapped;
+
+		public ThreeWayComparison(FieldValue left, IComparisonOperand right, bool swapped
+			)
+		{
+			this._left = left;
+			this._right = right;
+			_swapped = swapped;
+		}
+
+		public virtual FieldValue Left()
+		{
+			return _left;
+		}
+
+		public virtual IComparisonOperand Right()
+		{
+			return _right;
+		}
+
+		public virtual bool Swapped()
+		{
+			return _swapped;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/ComparisonExpression.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/ComparisonExpression.cs
new file mode 100644
index 0000000..0760629
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/ComparisonExpression.cs
@@ -0,0 +1,76 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.NativeQueries.Expr;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr
+{
+	public class ComparisonExpression : IExpression
+	{
+		private FieldValue _left;
+
+		private IComparisonOperand _right;
+
+		private ComparisonOperator _op;
+
+		public ComparisonExpression(FieldValue left, IComparisonOperand right, ComparisonOperator
+			 op)
+		{
+			if (left == null || right == null || op == null)
+			{
+				throw new ArgumentNullException();
+			}
+			this._left = left;
+			this._right = right;
+			this._op = op;
+		}
+
+		public virtual FieldValue Left()
+		{
+			return _left;
+		}
+
+		public virtual IComparisonOperand Right()
+		{
+			return _right;
+		}
+
+		public virtual ComparisonOperator Op()
+		{
+			return _op;
+		}
+
+		public override string ToString()
+		{
+			return _left + " " + _op + " " + _right;
+		}
+
+		public override bool Equals(object other)
+		{
+			if (this == other)
+			{
+				return true;
+			}
+			if (other == null || GetType() != other.GetType())
+			{
+				return false;
+			}
+			Db4objects.Db4o.NativeQueries.Expr.ComparisonExpression casted = (Db4objects.Db4o.NativeQueries.Expr.ComparisonExpression
+				)other;
+			return _left.Equals(casted._left) && _right.Equals(casted._right) && _op.Equals(casted
+				._op);
+		}
+
+		public override int GetHashCode()
+		{
+			return (_left.GetHashCode() * 29 + _right.GetHashCode()) * 29 + _op.GetHashCode();
+		}
+
+		public virtual void Accept(IExpressionVisitor visitor)
+		{
+			visitor.Visit(this);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/IExpression.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/IExpression.cs
new file mode 100644
index 0000000..dcee3c2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/IExpression.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr;
+
+namespace Db4objects.Db4o.NativeQueries.Expr
+{
+	public interface IExpression : IExpressionPart
+	{
+		/// <param name="visitor">
+		/// must implement the visitor interface required
+		/// by the concrete Expression implementation.
+		/// </param>
+		void Accept(IExpressionVisitor visitor);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/IExpressionPart.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/IExpressionPart.cs
new file mode 100644
index 0000000..ac46943
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/IExpressionPart.cs
@@ -0,0 +1,8 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.NativeQueries.Expr
+{
+	public interface IExpressionPart
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/IExpressionVisitor.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/IExpressionVisitor.cs
new file mode 100644
index 0000000..eeb379b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/IExpressionVisitor.cs
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr;
+
+namespace Db4objects.Db4o.NativeQueries.Expr
+{
+	public interface IExpressionVisitor
+	{
+		void Visit(AndExpression expression);
+
+		void Visit(OrExpression expression);
+
+		void Visit(NotExpression expression);
+
+		void Visit(ComparisonExpression expression);
+
+		void Visit(BoolConstExpression expression);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/IgnoredExpression.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/IgnoredExpression.cs
new file mode 100644
index 0000000..b45b276
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/IgnoredExpression.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr;
+
+namespace Db4objects.Db4o.NativeQueries.Expr
+{
+	public sealed class IgnoredExpression : IExpression
+	{
+		public static Db4objects.Db4o.NativeQueries.Expr.IgnoredExpression Instance = new 
+			Db4objects.Db4o.NativeQueries.Expr.IgnoredExpression();
+
+		private IgnoredExpression()
+		{
+		}
+
+		public void Accept(IExpressionVisitor visitor)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/NotExpression.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/NotExpression.cs
new file mode 100644
index 0000000..9c64e79
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/NotExpression.cs
@@ -0,0 +1,51 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr;
+
+namespace Db4objects.Db4o.NativeQueries.Expr
+{
+	public class NotExpression : IExpression
+	{
+		private IExpression _expr;
+
+		public NotExpression(IExpression expr)
+		{
+			this._expr = expr;
+		}
+
+		public override string ToString()
+		{
+			return "!(" + _expr + ")";
+		}
+
+		public virtual IExpression Expr()
+		{
+			return _expr;
+		}
+
+		public override bool Equals(object other)
+		{
+			if (this == other)
+			{
+				return true;
+			}
+			if (other == null || GetType() != other.GetType())
+			{
+				return false;
+			}
+			Db4objects.Db4o.NativeQueries.Expr.NotExpression casted = (Db4objects.Db4o.NativeQueries.Expr.NotExpression
+				)other;
+			return _expr.Equals(casted._expr);
+		}
+
+		public override int GetHashCode()
+		{
+			return -_expr.GetHashCode();
+		}
+
+		public virtual void Accept(IExpressionVisitor visitor)
+		{
+			visitor.Visit(this);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/OrExpression.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/OrExpression.cs
new file mode 100644
index 0000000..c6176ae
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/OrExpression.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr;
+
+namespace Db4objects.Db4o.NativeQueries.Expr
+{
+	public class OrExpression : BinaryExpression
+	{
+		public OrExpression(IExpression left, IExpression right) : base(left, right)
+		{
+		}
+
+		public override string ToString()
+		{
+			return "(" + _left + ")||(" + _right + ")";
+		}
+
+		public override void Accept(IExpressionVisitor visitor)
+		{
+			visitor.Visit(this);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/TraversingExpressionVisitor.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/TraversingExpressionVisitor.cs
new file mode 100644
index 0000000..0b25f12
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/TraversingExpressionVisitor.cs
@@ -0,0 +1,85 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.NativeQueries.Expr;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Expr
+{
+	public class TraversingExpressionVisitor : IExpressionVisitor, IComparisonOperandVisitor
+	{
+		public virtual void Visit(AndExpression expression)
+		{
+			expression.Left().Accept(this);
+			expression.Right().Accept(this);
+		}
+
+		public virtual void Visit(BoolConstExpression expression)
+		{
+		}
+
+		public virtual void Visit(OrExpression expression)
+		{
+			expression.Left().Accept(this);
+			expression.Right().Accept(this);
+		}
+
+		public virtual void Visit(ComparisonExpression expression)
+		{
+			expression.Left().Accept(this);
+			expression.Right().Accept(this);
+		}
+
+		public virtual void Visit(NotExpression expression)
+		{
+			expression.Expr().Accept(this);
+		}
+
+		public virtual void Visit(ArithmeticExpression operand)
+		{
+			operand.Left().Accept(this);
+			operand.Right().Accept(this);
+		}
+
+		public virtual void Visit(ConstValue operand)
+		{
+		}
+
+		public virtual void Visit(FieldValue operand)
+		{
+			operand.Parent().Accept(this);
+		}
+
+		public virtual void Visit(CandidateFieldRoot root)
+		{
+		}
+
+		public virtual void Visit(PredicateFieldRoot root)
+		{
+		}
+
+		public virtual void Visit(StaticFieldRoot root)
+		{
+		}
+
+		public virtual void Visit(ArrayAccessValue operand)
+		{
+			operand.Parent().Accept(this);
+			operand.Index().Accept(this);
+		}
+
+		public virtual void Visit(MethodCallValue value)
+		{
+			value.Parent().Accept(this);
+			VisitArgs(value);
+		}
+
+		protected virtual void VisitArgs(MethodCallValue value)
+		{
+			IComparisonOperand[] args = value.Args;
+			for (int i = 0; i < args.Length; ++i)
+			{
+				args[i].Accept(this);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Instrumentation/ComparisonBytecodeGeneratingVisitor.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Instrumentation/ComparisonBytecodeGeneratingVisitor.cs
new file mode 100644
index 0000000..b6f6326
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Instrumentation/ComparisonBytecodeGeneratingVisitor.cs
@@ -0,0 +1,243 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Instrumentation.Api;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+using Db4objects.Db4o.NativeQueries.Instrumentation;
+
+namespace Db4objects.Db4o.NativeQueries.Instrumentation
+{
+	internal class ComparisonBytecodeGeneratingVisitor : IComparisonOperandVisitor
+	{
+		private IMethodBuilder _methodBuilder;
+
+		private ITypeRef _predicateClass;
+
+		private bool _inArithmetic = false;
+
+		private ITypeRef _opClass = null;
+
+		private ITypeRef _staticRoot = null;
+
+		public ComparisonBytecodeGeneratingVisitor(IMethodBuilder methodBuilder, ITypeRef
+			 predicateClass)
+		{
+			this._methodBuilder = methodBuilder;
+			this._predicateClass = predicateClass;
+		}
+
+		public virtual void Visit(ConstValue operand)
+		{
+			object value = operand.Value();
+			if (value != null)
+			{
+				_opClass = TypeRef(value.GetType());
+			}
+			_methodBuilder.Ldc(value);
+			if (value != null)
+			{
+				Box(_opClass, !_inArithmetic);
+			}
+		}
+
+		private ITypeRef TypeRef(Type type)
+		{
+			return _methodBuilder.References.ForType(type);
+		}
+
+		public virtual void Visit(FieldValue fieldValue)
+		{
+			ITypeRef lastFieldClass = fieldValue.Field.Type;
+			bool needConversion = lastFieldClass.IsPrimitive;
+			fieldValue.Parent().Accept(this);
+			if (_staticRoot != null)
+			{
+				_methodBuilder.LoadStaticField(fieldValue.Field);
+				_staticRoot = null;
+				return;
+			}
+			_methodBuilder.LoadField(fieldValue.Field);
+			Box(lastFieldClass, !_inArithmetic && needConversion);
+		}
+
+		public virtual void Visit(CandidateFieldRoot root)
+		{
+			_methodBuilder.LoadArgument(1);
+		}
+
+		public virtual void Visit(PredicateFieldRoot root)
+		{
+			_methodBuilder.LoadArgument(0);
+		}
+
+		public virtual void Visit(StaticFieldRoot root)
+		{
+			_staticRoot = root.Type;
+		}
+
+		public virtual void Visit(ArrayAccessValue operand)
+		{
+			ITypeRef cmpType = DeduceFieldClass(operand.Parent()).ElementType;
+			operand.Parent().Accept(this);
+			bool outerInArithmetic = _inArithmetic;
+			_inArithmetic = true;
+			operand.Index().Accept(this);
+			_inArithmetic = outerInArithmetic;
+			_methodBuilder.LoadArrayElement(cmpType);
+			Box(cmpType, !_inArithmetic);
+		}
+
+		public virtual void Visit(MethodCallValue operand)
+		{
+			IMethodRef method = operand.Method;
+			ITypeRef retType = method.ReturnType;
+			// FIXME: this should be handled within conversions
+			bool needConversion = retType.IsPrimitive;
+			operand.Parent().Accept(this);
+			bool oldInArithmetic = _inArithmetic;
+			for (int paramIdx = 0; paramIdx < operand.Args.Length; paramIdx++)
+			{
+				_inArithmetic = operand.Method.ParamTypes[paramIdx].IsPrimitive;
+				operand.Args[paramIdx].Accept(this);
+			}
+			_inArithmetic = oldInArithmetic;
+			_methodBuilder.Invoke(method, operand.CallingConvention);
+			Box(retType, !_inArithmetic && needConversion);
+		}
+
+		public virtual void Visit(ArithmeticExpression operand)
+		{
+			bool oldInArithmetic = _inArithmetic;
+			_inArithmetic = true;
+			operand.Left().Accept(this);
+			operand.Right().Accept(this);
+			ITypeRef operandType = ArithmeticType(operand);
+			switch (operand.Op().Id())
+			{
+				case ArithmeticOperator.AddId:
+				{
+					_methodBuilder.Add(operandType);
+					break;
+				}
+
+				case ArithmeticOperator.SubtractId:
+				{
+					_methodBuilder.Subtract(operandType);
+					break;
+				}
+
+				case ArithmeticOperator.MultiplyId:
+				{
+					_methodBuilder.Multiply(operandType);
+					break;
+				}
+
+				case ArithmeticOperator.DivideId:
+				{
+					_methodBuilder.Divide(operandType);
+					break;
+				}
+
+				default:
+				{
+					throw new Exception("Unknown operand: " + operand.Op());
+				}
+			}
+			Box(_opClass, !oldInArithmetic);
+			_inArithmetic = oldInArithmetic;
+		}
+
+		// FIXME: need to map dX,fX,...
+		private void Box(ITypeRef boxedType, bool canApply)
+		{
+			if (!canApply)
+			{
+				return;
+			}
+			_methodBuilder.Box(boxedType);
+		}
+
+		private ITypeRef DeduceFieldClass(IComparisonOperand fieldValue)
+		{
+			TypeDeducingVisitor visitor = new TypeDeducingVisitor(_methodBuilder.References, 
+				_predicateClass);
+			fieldValue.Accept(visitor);
+			return visitor.OperandClass();
+		}
+
+		private ITypeRef ArithmeticType(IComparisonOperand operand)
+		{
+			if (operand is ConstValue)
+			{
+				return PrimitiveType(((ConstValue)operand).Value().GetType());
+			}
+			if (operand is FieldValue)
+			{
+				return ((FieldValue)operand).Field.Type;
+			}
+			if (operand is ArithmeticExpression)
+			{
+				ArithmeticExpression expr = (ArithmeticExpression)operand;
+				ITypeRef left = ArithmeticType(expr.Left());
+				ITypeRef right = ArithmeticType(expr.Right());
+				if (left == DoubleType() || right == DoubleType())
+				{
+					return DoubleType();
+				}
+				if (left == FloatType() || right == FloatType())
+				{
+					return FloatType();
+				}
+				if (left == LongType() || right == LongType())
+				{
+					return LongType();
+				}
+				return IntType();
+			}
+			return null;
+		}
+
+		private ITypeRef PrimitiveType(Type klass)
+		{
+			if (klass == typeof(int) || klass == typeof(short) || klass == typeof(bool) || klass
+				 == typeof(byte))
+			{
+				return IntType();
+			}
+			if (klass == typeof(double))
+			{
+				return DoubleType();
+			}
+			if (klass == typeof(float))
+			{
+				return FloatType();
+			}
+			if (klass == typeof(long))
+			{
+				return LongType();
+			}
+			return TypeRef(klass);
+		}
+
+		private ITypeRef IntType()
+		{
+			return TypeRef(typeof(int));
+		}
+
+		private ITypeRef LongType()
+		{
+			return TypeRef(typeof(long));
+		}
+
+		private ITypeRef FloatType()
+		{
+			return TypeRef(typeof(float));
+		}
+
+		private ITypeRef DoubleType()
+		{
+			return TypeRef(typeof(double));
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Instrumentation/SODAMethodBuilder.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Instrumentation/SODAMethodBuilder.cs
new file mode 100644
index 0000000..c0090f6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Instrumentation/SODAMethodBuilder.cs
@@ -0,0 +1,250 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Instrumentation.Api;
+using Db4objects.Db4o.Internal.Query;
+using Db4objects.Db4o.NativeQueries.Expr;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+using Db4objects.Db4o.NativeQueries.Instrumentation;
+using Db4objects.Db4o.NativeQueries.Optimization;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.NativeQueries.Instrumentation
+{
+	public class SODAMethodBuilder
+	{
+		private const bool LogBytecode = false;
+
+		private IMethodRef descendRef;
+
+		private IMethodRef constrainRef;
+
+		private IMethodRef greaterRef;
+
+		private IMethodRef smallerRef;
+
+		private IMethodRef containsRef;
+
+		private IMethodRef startsWithRef;
+
+		private IMethodRef endsWithRef;
+
+		private IMethodRef notRef;
+
+		private IMethodRef andRef;
+
+		private IMethodRef orRef;
+
+		private IMethodRef identityRef;
+
+		private readonly ITypeEditor _editor;
+
+		private IMethodBuilder _builder;
+
+		public static readonly string OptimizeQueryMethodName = "optimizeQuery";
+
+		private class SODAExpressionBuilder : IExpressionVisitor
+		{
+			private ITypeRef predicateClass;
+
+			public SODAExpressionBuilder(SODAMethodBuilder _enclosing, ITypeRef predicateClass
+				)
+			{
+				this._enclosing = _enclosing;
+				this.predicateClass = predicateClass;
+			}
+
+			public virtual void Visit(AndExpression expression)
+			{
+				expression.Left().Accept(this);
+				expression.Right().Accept(this);
+				this._enclosing.Invoke(this._enclosing.andRef);
+			}
+
+			public virtual void Visit(BoolConstExpression expression)
+			{
+				this.LoadQuery();
+			}
+
+			//throw new RuntimeException("No boolean constants expected in parsed expression tree");
+			private void LoadQuery()
+			{
+				this._enclosing.LoadArgument(1);
+			}
+
+			public virtual void Visit(OrExpression expression)
+			{
+				expression.Left().Accept(this);
+				expression.Right().Accept(this);
+				this._enclosing.Invoke(this._enclosing.orRef);
+			}
+
+			public virtual void Visit(ComparisonExpression expression)
+			{
+				this.LoadQuery();
+				this.Descend(this.FieldNames(expression.Left()));
+				expression.Right().Accept(this.ComparisonEmitter());
+				this.Constrain(expression.Op());
+			}
+
+			private void Descend(IEnumerator fieldNames)
+			{
+				while (fieldNames.MoveNext())
+				{
+					this.Descend(fieldNames.Current);
+				}
+			}
+
+			private ComparisonBytecodeGeneratingVisitor ComparisonEmitter()
+			{
+				return new ComparisonBytecodeGeneratingVisitor(this._enclosing._builder, this.predicateClass
+					);
+			}
+
+			private void Constrain(ComparisonOperator op)
+			{
+				this._enclosing.Invoke(this._enclosing.constrainRef);
+				if (op.Equals(ComparisonOperator.ValueEquality))
+				{
+					return;
+				}
+				if (op.Equals(ComparisonOperator.ReferenceEquality))
+				{
+					this._enclosing.Invoke(this._enclosing.identityRef);
+					return;
+				}
+				if (op.Equals(ComparisonOperator.Greater))
+				{
+					this._enclosing.Invoke(this._enclosing.greaterRef);
+					return;
+				}
+				if (op.Equals(ComparisonOperator.Smaller))
+				{
+					this._enclosing.Invoke(this._enclosing.smallerRef);
+					return;
+				}
+				if (op.Equals(ComparisonOperator.Contains))
+				{
+					this._enclosing.Invoke(this._enclosing.containsRef);
+					return;
+				}
+				if (op.Equals(ComparisonOperator.StartsWith))
+				{
+					this._enclosing.Ldc(1);
+					this._enclosing.Invoke(this._enclosing.startsWithRef);
+					return;
+				}
+				if (op.Equals(ComparisonOperator.EndsWith))
+				{
+					this._enclosing.Ldc(1);
+					this._enclosing.Invoke(this._enclosing.endsWithRef);
+					return;
+				}
+				throw new Exception("Cannot interpret constraint: " + op);
+			}
+
+			private void Descend(object fieldName)
+			{
+				this._enclosing.Ldc(fieldName);
+				this._enclosing.Invoke(this._enclosing.descendRef);
+			}
+
+			public virtual void Visit(NotExpression expression)
+			{
+				expression.Expr().Accept(this);
+				this._enclosing.Invoke(this._enclosing.notRef);
+			}
+
+			private IEnumerator FieldNames(FieldValue fieldValue)
+			{
+				Collection4 coll = new Collection4();
+				IComparisonOperand curOp = fieldValue;
+				while (curOp is FieldValue)
+				{
+					FieldValue curField = (FieldValue)curOp;
+					coll.Prepend(curField.FieldName());
+					curOp = curField.Parent();
+				}
+				return coll.GetEnumerator();
+			}
+
+			private readonly SODAMethodBuilder _enclosing;
+		}
+
+		public SODAMethodBuilder(ITypeEditor editor)
+		{
+			_editor = editor;
+			BuildMethodReferences();
+		}
+
+		public virtual void InjectOptimization(IExpression expr)
+		{
+			_editor.AddInterface(TypeRef(typeof(IDb4oEnhancedFilter)));
+			_builder = _editor.NewPublicMethod(PlatformName(OptimizeQueryMethodName), TypeRef
+				(typeof(void)), new ITypeRef[] { TypeRef(typeof(IQuery)) });
+			ITypeRef predicateClass = _editor.Type;
+			expr.Accept(new SODAMethodBuilder.SODAExpressionBuilder(this, predicateClass));
+			_builder.Pop();
+			_builder.EndMethod();
+		}
+
+		private ITypeRef TypeRef(Type type)
+		{
+			return _editor.References.ForType(type);
+		}
+
+		private string PlatformName(string name)
+		{
+			return NativeQueriesPlatform.ToPlatformName(name);
+		}
+
+		private void LoadArgument(int index)
+		{
+			_builder.LoadArgument(index);
+		}
+
+		private void Invoke(IMethodRef method)
+		{
+			_builder.Invoke(method, CallingConvention.Interface);
+		}
+
+		private void Ldc(object value)
+		{
+			_builder.Ldc(value);
+		}
+
+		private void BuildMethodReferences()
+		{
+			descendRef = MethodRef(typeof(IQuery), "descend", new Type[] { typeof(string) });
+			constrainRef = MethodRef(typeof(IQuery), "constrain", new Type[] { typeof(object)
+				 });
+			greaterRef = MethodRef(typeof(IConstraint), "greater", new Type[] {  });
+			smallerRef = MethodRef(typeof(IConstraint), "smaller", new Type[] {  });
+			containsRef = MethodRef(typeof(IConstraint), "contains", new Type[] {  });
+			startsWithRef = MethodRef(typeof(IConstraint), "startsWith", new Type[] { typeof(
+				bool) });
+			endsWithRef = MethodRef(typeof(IConstraint), "endsWith", new Type[] { typeof(bool
+				) });
+			notRef = MethodRef(typeof(IConstraint), "not", new Type[] {  });
+			andRef = MethodRef(typeof(IConstraint), "and", new Type[] { typeof(IConstraint) }
+				);
+			orRef = MethodRef(typeof(IConstraint), "or", new Type[] { typeof(IConstraint) });
+			identityRef = MethodRef(typeof(IConstraint), "identity", new Type[] {  });
+		}
+
+		private IMethodRef MethodRef(Type parent, string name, Type[] args)
+		{
+			try
+			{
+				return _editor.References.ForMethod(parent.GetMethod(PlatformName(name), args));
+			}
+			catch (Exception e)
+			{
+				throw new InstrumentationException(e);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Instrumentation/TypeDeducingVisitor.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Instrumentation/TypeDeducingVisitor.cs
new file mode 100644
index 0000000..471d580
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Instrumentation/TypeDeducingVisitor.cs
@@ -0,0 +1,68 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Instrumentation.Api;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+
+namespace Db4objects.Db4o.NativeQueries.Instrumentation
+{
+	internal class TypeDeducingVisitor : IComparisonOperandVisitor
+	{
+		private ITypeRef _predicateClass;
+
+		private ITypeRef _clazz;
+
+		private IReferenceProvider _referenceProvider;
+
+		public TypeDeducingVisitor(IReferenceProvider provider, ITypeRef predicateClass)
+		{
+			this._predicateClass = predicateClass;
+			this._referenceProvider = provider;
+			_clazz = null;
+		}
+
+		public virtual void Visit(PredicateFieldRoot root)
+		{
+			_clazz = _predicateClass;
+		}
+
+		public virtual void Visit(CandidateFieldRoot root)
+		{
+		}
+
+		//		_clazz=_candidateClass;
+		public virtual void Visit(StaticFieldRoot root)
+		{
+			_clazz = root.Type;
+		}
+
+		public virtual ITypeRef OperandClass()
+		{
+			return _clazz;
+		}
+
+		public virtual void Visit(ArithmeticExpression operand)
+		{
+		}
+
+		public virtual void Visit(ConstValue operand)
+		{
+			_clazz = _referenceProvider.ForType(operand.Value().GetType());
+		}
+
+		public virtual void Visit(FieldValue operand)
+		{
+			_clazz = operand.Field.Type;
+		}
+
+		public virtual void Visit(ArrayAccessValue operand)
+		{
+			operand.Parent().Accept(this);
+			_clazz = _clazz.ElementType;
+		}
+
+		public virtual void Visit(MethodCallValue operand)
+		{
+			_clazz = operand.Method.ReturnType;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Optimization/ComparisonQueryGeneratingVisitor.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Optimization/ComparisonQueryGeneratingVisitor.cs
new file mode 100644
index 0000000..536baab
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Optimization/ComparisonQueryGeneratingVisitor.cs
@@ -0,0 +1,224 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Reflection;
+using Db4objects.Db4o.Instrumentation.Api;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+using Db4objects.Db4o.NativeQueries.Optimization;
+using Sharpen.Lang.Reflect;
+
+namespace Db4objects.Db4o.NativeQueries.Optimization
+{
+	internal sealed class ComparisonQueryGeneratingVisitor : IComparisonOperandVisitor
+	{
+		private object _predicate;
+
+		private object _value = null;
+
+		private readonly INativeClassFactory _classSource;
+
+		private readonly IReferenceResolver _resolver;
+
+		public object Value()
+		{
+			return _value;
+		}
+
+		public void Visit(ConstValue operand)
+		{
+			_value = operand.Value();
+		}
+
+		public void Visit(FieldValue operand)
+		{
+			operand.Parent().Accept(this);
+			Type clazz = ((operand.Parent() is StaticFieldRoot) ? (Type)_value : _value.GetType
+				());
+			try
+			{
+				FieldInfo field = Reflection4.GetField(clazz, operand.FieldName());
+				_value = field.GetValue(_value);
+			}
+			catch (Exception exc)
+			{
+				// arg is ignored for static
+				Sharpen.Runtime.PrintStackTrace(exc);
+			}
+		}
+
+		internal object Add(object a, object b)
+		{
+			if (a is double || b is double)
+			{
+				return ((double)a) + ((double)b);
+			}
+			if (a is float || b is float)
+			{
+				return ((float)a) + ((float)b);
+			}
+			if (a is long || b is long)
+			{
+				return ((long)a) + ((long)b);
+			}
+			return ((int)a) + ((int)b);
+		}
+
+		internal object Subtract(object a, object b)
+		{
+			if (a is double || b is double)
+			{
+				return ((double)a) - ((double)b);
+			}
+			if (a is float || b is float)
+			{
+				return ((float)a) - ((float)b);
+			}
+			if (a is long || b is long)
+			{
+				return ((long)a) - ((long)b);
+			}
+			return ((int)a) - ((int)b);
+		}
+
+		internal object Multiply(object a, object b)
+		{
+			if (a is double || b is double)
+			{
+				return ((double)a) * ((double)b);
+			}
+			if (a is float || b is float)
+			{
+				return ((float)a) * ((float)b);
+			}
+			if (a is long || b is long)
+			{
+				return ((long)a) * ((long)b);
+			}
+			return ((int)a) * ((int)b);
+		}
+
+		internal object Divide(object a, object b)
+		{
+			if (a is double || b is double)
+			{
+				return ((double)a) / ((double)b);
+			}
+			if (a is float || b is float)
+			{
+				return ((float)a) / ((float)b);
+			}
+			if (a is long || b is long)
+			{
+				return ((long)a) / ((long)b);
+			}
+			return ((int)a) / ((int)b);
+		}
+
+		public void Visit(ArithmeticExpression operand)
+		{
+			operand.Left().Accept(this);
+			object left = _value;
+			operand.Right().Accept(this);
+			object right = _value;
+			switch (operand.Op().Id())
+			{
+				case ArithmeticOperator.AddId:
+				{
+					_value = Add(left, right);
+					break;
+				}
+
+				case ArithmeticOperator.SubtractId:
+				{
+					_value = Subtract(left, right);
+					break;
+				}
+
+				case ArithmeticOperator.MultiplyId:
+				{
+					_value = Multiply(left, right);
+					break;
+				}
+
+				case ArithmeticOperator.DivideId:
+				{
+					_value = Divide(left, right);
+					break;
+				}
+			}
+		}
+
+		public void Visit(CandidateFieldRoot root)
+		{
+		}
+
+		public void Visit(PredicateFieldRoot root)
+		{
+			_value = _predicate;
+		}
+
+		public void Visit(StaticFieldRoot root)
+		{
+			try
+			{
+				_value = _classSource.ForName(root.Type.Name);
+			}
+			catch (TypeLoadException e)
+			{
+				Sharpen.Runtime.PrintStackTrace(e);
+			}
+		}
+
+		public void Visit(ArrayAccessValue operand)
+		{
+			operand.Parent().Accept(this);
+			object parent = _value;
+			operand.Index().Accept(this);
+			int index = (int)_value;
+			_value = Sharpen.Runtime.GetArrayValue(parent, index);
+		}
+
+		public void Visit(MethodCallValue operand)
+		{
+			operand.Parent().Accept(this);
+			object receiver = _value;
+			MethodInfo method = _resolver.Resolve(operand.Method);
+			try
+			{
+				_value = method.Invoke(IsStatic(method) ? null : receiver, Args(operand));
+			}
+			catch (Exception exc)
+			{
+				Sharpen.Runtime.PrintStackTrace(exc);
+				_value = null;
+			}
+		}
+
+		private object[] Args(MethodCallValue operand)
+		{
+			IComparisonOperand[] args = operand.Args;
+			object[] @params = new object[args.Length];
+			for (int paramIdx = 0; paramIdx < args.Length; paramIdx++)
+			{
+				args[paramIdx].Accept(this);
+				@params[paramIdx] = _value;
+			}
+			return @params;
+		}
+
+		private bool IsStatic(MethodInfo method)
+		{
+			return NativeQueriesPlatform.IsStatic(method);
+		}
+
+		public ComparisonQueryGeneratingVisitor(object predicate, INativeClassFactory classSource
+			, IReferenceResolver resolver) : base()
+		{
+			_predicate = predicate;
+			_classSource = classSource;
+			_resolver = resolver;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Optimization/SODAQueryBuilder.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Optimization/SODAQueryBuilder.cs
new file mode 100644
index 0000000..d4df5ad
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Optimization/SODAQueryBuilder.cs
@@ -0,0 +1,143 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Instrumentation.Api;
+using Db4objects.Db4o.NativeQueries.Expr;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp;
+using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
+using Db4objects.Db4o.NativeQueries.Optimization;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.NativeQueries.Optimization
+{
+	public class SODAQueryBuilder
+	{
+		private class SODAQueryVisitor : IExpressionVisitor
+		{
+			private object _predicate;
+
+			private IQuery _query;
+
+			private IConstraint _constraint;
+
+			private INativeClassFactory _classSource;
+
+			private IReferenceResolver _referenceResolver;
+
+			internal SODAQueryVisitor(IQuery query, object predicate, INativeClassFactory classSource
+				, IReferenceResolver referenceResolver)
+			{
+				_query = query;
+				_predicate = predicate;
+				_classSource = classSource;
+				_referenceResolver = referenceResolver;
+			}
+
+			public virtual void Visit(AndExpression expression)
+			{
+				expression.Left().Accept(this);
+				IConstraint left = _constraint;
+				expression.Right().Accept(this);
+				left.And(_constraint);
+				_constraint = left;
+			}
+
+			public virtual void Visit(BoolConstExpression expression)
+			{
+			}
+
+			public virtual void Visit(OrExpression expression)
+			{
+				expression.Left().Accept(this);
+				IConstraint left = _constraint;
+				expression.Right().Accept(this);
+				left.Or(_constraint);
+				_constraint = left;
+			}
+
+			public virtual void Visit(ComparisonExpression expression)
+			{
+				IQuery subQuery = Descend(expression.Left());
+				ComparisonQueryGeneratingVisitor visitor = new ComparisonQueryGeneratingVisitor(_predicate
+					, _classSource, _referenceResolver);
+				expression.Right().Accept(visitor);
+				_constraint = subQuery.Constrain(visitor.Value());
+				ComparisonOperator op = expression.Op();
+				if (op.Equals(ComparisonOperator.ValueEquality))
+				{
+					return;
+				}
+				if (op.Equals(ComparisonOperator.ReferenceEquality))
+				{
+					_constraint.Identity();
+					return;
+				}
+				if (op.Equals(ComparisonOperator.Greater))
+				{
+					_constraint.Greater();
+					return;
+				}
+				if (op.Equals(ComparisonOperator.Smaller))
+				{
+					_constraint.Smaller();
+					return;
+				}
+				if (op.Equals(ComparisonOperator.Contains))
+				{
+					_constraint.Contains();
+					return;
+				}
+				if (op.Equals(ComparisonOperator.StartsWith))
+				{
+					_constraint.StartsWith(true);
+					return;
+				}
+				if (op.Equals(ComparisonOperator.EndsWith))
+				{
+					_constraint.EndsWith(true);
+					return;
+				}
+				throw new Exception("Can't handle constraint: " + op);
+			}
+
+			private IQuery Descend(FieldValue left)
+			{
+				IQuery subQuery = _query;
+				IEnumerator fieldNameIterator = FieldNames(left);
+				while (fieldNameIterator.MoveNext())
+				{
+					subQuery = subQuery.Descend((string)fieldNameIterator.Current);
+				}
+				return subQuery;
+			}
+
+			public virtual void Visit(NotExpression expression)
+			{
+				expression.Expr().Accept(this);
+				_constraint.Not();
+			}
+
+			private IEnumerator FieldNames(FieldValue fieldValue)
+			{
+				Collection4 coll = new Collection4();
+				IComparisonOperand curOp = fieldValue;
+				while (curOp is FieldValue)
+				{
+					FieldValue curField = (FieldValue)curOp;
+					coll.Prepend(curField.FieldName());
+					curOp = curField.Parent();
+				}
+				return coll.GetEnumerator();
+			}
+		}
+
+		public virtual void OptimizeQuery(IExpression expr, IQuery query, object predicate
+			, INativeClassFactory classSource, IReferenceResolver referenceResolver)
+		{
+			expr.Accept(new SODAQueryBuilder.SODAQueryVisitor(query, predicate, classSource, 
+				referenceResolver));
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Properties/AssemblyInfo.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Properties/AssemblyInfo.cs
new file mode 100755
index 0000000..88e5f1b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/Properties/AssemblyInfo.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2009 Versant Inc.   http://www.db4o.com */
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Security;
+
+[assembly: AssemblyTitle("db4o - native query handling")]
+[assembly: AssemblyCompany("Versant Corp., Redwood City, CA, USA")]
+[assembly: AssemblyProduct("db4o - database for objects")]
+[assembly: AssemblyCopyright("Versant Corp. 2000 - 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// attributes are automatically set by the build
+[assembly: AssemblyVersion("8.0.183.14430")]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyConfiguration(".NET")]
+[assembly: AssemblyDescription("Db4objects.Db4o.NativeQueries 8.0.183.14430 (.NET)")]
+
+#if !CF
+[assembly: AllowPartiallyTrustedCallers]
+#endif
+
+[assembly: ComVisible(false)]
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/AssemblyResolver.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/AssemblyResolver.cs
new file mode 100644
index 0000000..d7e1ed6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/AssemblyResolver.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2009 Versant Inc.   http://www.db4o.com */
+using System.Collections.Generic;
+using System.Reflection;
+using Db4objects.Db4o.Internal.Query;
+using Mono.Cecil;
+
+namespace Db4objects.Db4o.NativeQueries
+{
+	internal class AssemblyResolver
+	{
+		public AssemblyResolver(ICachingStrategy<string, AssemblyDefinition> assemblyCache)
+		{
+			_assemblyCachingStrategy = assemblyCache;
+		}
+
+		public AssemblyDefinition ForTypeReference(TypeReference type)
+		{
+			AssemblyNameReference scope = (AssemblyNameReference)type.Scope;
+			string assemblyName = scope.FullName;
+			AssemblyDefinition definition = LookupAssembly(assemblyName);
+			if (null == definition)
+			{
+				Assembly assembly = Assembly.Load(assemblyName);
+				string location = assembly.GetType(type.FullName, true).Module.FullyQualifiedName;
+				definition = _assemblyCachingStrategy.Get(location);
+				RegisterAssembly(definition);
+			}
+			return definition;
+		}
+		
+		private AssemblyDefinition LookupAssembly(string fullName)
+		{
+			return _assemblies.ContainsKey(fullName) ? _assemblies[fullName] : null;
+		}
+
+		/// <summary>
+		/// Registers an assembly so it can be looked up by its assembly name
+		/// string later.
+		/// </summary>
+		/// <param name="assembly"></param>
+		private void RegisterAssembly(AssemblyDefinition assembly)
+		{
+			_assemblies.Add(assembly.Name.FullName, assembly);
+		}
+
+		public AssemblyDefinition ForType(TypeDefinition type)
+		{
+			AssemblyDefinition assembly = type.Module.Assembly;
+			RegisterAssembly(assembly);
+
+			return assembly;
+		}
+
+		private readonly ICachingStrategy<string, AssemblyDefinition> _assemblyCachingStrategy;
+		readonly IDictionary<string, AssemblyDefinition> _assemblies = new Dictionary<string, AssemblyDefinition>();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/ICachingStrategy.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/ICachingStrategy.cs
new file mode 100644
index 0000000..5a8c2e8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/ICachingStrategy.cs
@@ -0,0 +1,9 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+namespace Db4objects.Db4o.Internal.Query
+{
+	public interface ICachingStrategy<K,V>
+	{
+		void Add(K key, V item);
+		V Get(K key);
+	}
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/NQOptimizer.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/NQOptimizer.cs
new file mode 100755
index 0000000..7f77fe5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/NQOptimizer.cs
@@ -0,0 +1,24 @@
+using System.Reflection;
+using Db4objects.Db4o.Instrumentation.Api;
+using Db4objects.Db4o.Instrumentation.Cecil;
+using Db4objects.Db4o.Instrumentation.Core;
+using Db4objects.Db4o.Internal.Query;
+using Db4objects.Db4o.NativeQueries.Expr;
+using Db4objects.Db4o.NativeQueries.Optimization;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.NativeQueries
+{
+	public class NQOptimizer : INQOptimizer
+	{	
+		private readonly INativeClassFactory _classFactory = new DefaultNativeClassFactory();
+
+		public void Optimize(IQuery q, object predicate, MethodBase filterMethod)
+		{
+			// TODO: cache predicate expressions here
+			QueryExpressionBuilder builder = new QueryExpressionBuilder();
+			IExpression expression = builder.FromMethod(filterMethod);
+			new SODAQueryBuilder().OptimizeQuery(expression, q, predicate, _classFactory, new CecilReferenceResolver());
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/Optimization/NativeQueriesPlatform.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/Optimization/NativeQueriesPlatform.cs
new file mode 100755
index 0000000..ad4321f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/Optimization/NativeQueriesPlatform.cs
@@ -0,0 +1,17 @@
+using System.Reflection;
+
+namespace Db4objects.Db4o.NativeQueries.Optimization
+{
+	class NativeQueriesPlatform
+	{
+		public static bool IsStatic(MethodInfo method)
+		{
+			return method.IsStatic;
+		}
+
+		public static string ToPlatformName(string name)
+		{
+			return char.ToUpper(name[0]) + name.Substring(1);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/QueryExpressionBuilder.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/QueryExpressionBuilder.cs
new file mode 100644
index 0000000..e3da254
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/QueryExpressionBuilder.cs
@@ -0,0 +1,916 @@
+/* Copyright (C) 2004-2006   Versant Inc.   http://www.db4o.com */
+
+using System.Collections.Generic;
+using Db4objects.Db4o.Activation;
+using Db4objects.Db4o.Instrumentation.Cecil;
+using Db4objects.Db4o.TA;
+using Mono.Collections.Generic;
+
+namespace Db4objects.Db4o.NativeQueries
+{
+	using System;
+	using System.Collections;
+	using System.Reflection;
+
+	using Mono.Cecil;
+
+	using Cecil.FlowAnalysis;
+	using Cecil.FlowAnalysis.ActionFlow;
+	using Cecil.FlowAnalysis.CodeStructure;
+	using Ast = Cecil.FlowAnalysis.CodeStructure;
+
+	using Expr;
+	using Expr.Cmp;
+	using Expr.Cmp.Operand;
+	using NQExpression = Expr.IExpression;
+	using Internal.Query;
+
+	/// <summary>
+	/// Build a Db4objects.Db4o.Nativequery.Expr tree out of a predicate method definition.
+	/// </summary>
+	public class QueryExpressionBuilder
+	{
+		protected static ICachingStrategy<string, AssemblyDefinition> _assemblyCachingStrategy = 
+				new SingleItemCachingStrategy<string, AssemblyDefinition>( delegate(string location)
+																			{
+																				return AssemblyDefinition.ReadAssembly(location);
+																			});
+
+		protected static ICachingStrategy<MethodBase, IExpression> _expressionCachingStrategy = 
+				new SingleItemCachingStrategy<MethodBase, IExpression>(
+																		delegate(MethodBase method)
+																			{
+																				MethodDefinition methodDef = GetMethodDefinition(method);
+																				return AdjustBoxedValueTypes(FromMethodDefinition(methodDef));
+																			}
+																		);
+
+		public NQExpression FromMethod(MethodBase method)
+		{
+			if (method == null) throw new ArgumentNullException("method");
+			
+			return GetCachedExpression(method);
+		}
+
+		private static NQExpression GetCachedExpression(MethodBase method)
+		{
+			return _expressionCachingStrategy.Get(method);
+		}
+
+		private static MethodDefinition GetMethodDefinition(MethodBase method)
+		{
+			string location = GetAssemblyLocation(method);
+#if CF
+			MethodDefinition methodDef = MethodDefinitionFor(method);
+#else
+			AssemblyDefinition assembly = _assemblyCachingStrategy.Get(location);
+
+			MethodDefinition methodDef = (MethodDefinition)assembly.MainModule.LookupToken(method.MetadataToken);
+#endif
+			if (null == methodDef) UnsupportedPredicate(string.Format("Unable to load the definition of '{0}' from assembly '{1}'", method, location));
+			
+			return methodDef;
+		}
+
+		private static MethodDefinition MethodDefinitionFor(MethodBase method)
+		{
+			string location = GetAssemblyLocation(method);
+			AssemblyDefinition assembly = _assemblyCachingStrategy.Get(location);
+
+#if CF
+			TypeDefinition declaringType = FindTypeDefinition(assembly.MainModule, method.DeclaringType);
+			if (declaringType == null)
+			{
+				return null;
+			}
+
+			foreach (MethodDefinition candidate in declaringType.Methods)
+			{
+				if (candidate.Name != method.Name) continue;
+				if (candidate.Parameters.Count != method.GetParameters().Length) continue;
+				if (!ParametersMatch(candidate.Parameters, GetParameterTypes(method, assembly.MainModule))) continue;
+				{
+					return candidate;
+				}
+			}
+
+			return null;
+
+#else
+			return (MethodDefinition) assembly.MainModule.LookupToken(method.MetadataToken);
+#endif
+		}
+
+		private static NQExpression AdjustBoxedValueTypes(NQExpression expression)
+		{
+			expression.Accept(new BoxedValueTypeProcessor());
+			return expression;
+		}
+
+		private static IList<TypeReference> GetParameterTypes(MethodBase method, ModuleDefinition module)
+		{
+			IList<TypeReference> types = new List<TypeReference>();
+			foreach (ParameterInfo parameter in ParametersFor(method))
+			{
+				types.Add(FindTypeDefinition(module, parameter.ParameterType));
+			}
+
+			return types;
+		}
+
+		private static ParameterInfo[] ParametersFor(MethodBase method)
+		{
+			if (method.IsGenericMethod)
+			{
+				MethodInfo methodInfo = (MethodInfo) method;
+				return methodInfo.GetGenericMethodDefinition().GetParameters();
+			}
+
+			return method.DeclaringType.IsGenericType 
+								? method.DeclaringType.GetGenericTypeDefinition().GetMethod(method.Name).GetParameters() 
+								: method.GetParameters();
+		}
+
+		private static TypeDefinition FindTypeDefinition(ModuleDefinition module, Type type)
+		{
+			return IsNested(type)
+				? FindNestedTypeDefinition(module, type)
+				: FindTypeDefinition(module, type.IsGenericType ? type.Name : type.FullName);
+		}
+
+		private static bool IsNested(Type type)
+		{
+			return type.IsNestedPublic || type.IsNestedPrivate || type.IsNestedAssembly;
+		}
+
+		private static TypeDefinition FindNestedTypeDefinition(ModuleDefinition module, Type type)
+		{
+			foreach (TypeDefinition td in FindTypeDefinition(module, type.DeclaringType).NestedTypes)
+			{
+				if (td.Name == type.Name) return td;
+			}
+			return null;
+		}
+
+		private static TypeDefinition FindTypeDefinition(ModuleDefinition module, string name)
+		{
+			return module.GetType(name);
+		}
+
+		private static string GetAssemblyLocation(MethodBase method)
+		{
+			return method.DeclaringType.Module.FullyQualifiedName;
+		}
+
+		public static NQExpression FromMethodDefinition(MethodDefinition method)
+		{
+			ValidatePredicateMethodDefinition(method);
+
+			Expression expression = GetQueryExpression(method);
+			if (null == expression) UnsupportedPredicate("No expression found.");
+			
+			Visitor visitor = new Visitor(method, new AssemblyResolver(_assemblyCachingStrategy));
+			expression.Accept(visitor);
+			return visitor.Expression;
+		}
+
+		private static void ValidatePredicateMethodDefinition(MethodDefinition method)
+		{
+			if (method == null)
+				throw new ArgumentNullException("method");
+			if (1 != method.Parameters.Count)
+				UnsupportedPredicate("A predicate must take a single argument.");
+			if (0 != method.Body.ExceptionHandlers.Count)
+				UnsupportedPredicate("A predicate can not contain exception handlers.");
+			if (method.ReturnType.FullName != typeof(bool).FullName)
+				UnsupportedPredicate("A predicate must have a boolean return type.");
+		}
+
+		private static Expression GetQueryExpression(MethodDefinition method)
+		{
+			ActionFlowGraph afg = FlowGraphFactory.CreateActionFlowGraph(FlowGraphFactory.CreateControlFlowGraph(method));
+			return GetQueryExpression(afg);
+		}
+
+		private static void UnsupportedPredicate(string reason)
+		{
+			throw new UnsupportedPredicateException(reason);
+		}
+
+		private static void UnsupportedExpression(Expression node)
+		{
+			UnsupportedPredicate("Unsupported expression: " + ExpressionPrinter.ToString(node));
+		}
+
+		private static Expression GetQueryExpression(ActionFlowGraph afg)
+		{
+			IDictionary<int, Expression> variables = new Dictionary<int, Expression>();
+			ActionBlock block = afg.Blocks[0];
+			while (block != null)
+			{
+				switch (block.ActionType)
+				{
+					case ActionType.Invoke:
+						InvokeActionBlock invokeBlock = (InvokeActionBlock)block;
+						MethodInvocationExpression invocation = invokeBlock.Expression;
+						if (IsActivateInvocation(invocation) 
+							|| IsNoSideEffectIndirectActivationInvocation(invocation))
+						{
+							block = invokeBlock.Next;
+							break;
+						}
+
+						UnsupportedExpression(invocation);
+						break;
+
+					case ActionType.ConditionalBranch:
+						UnsupportedPredicate("Conditional blocks are not supported.");
+						break;
+
+					case ActionType.Branch:
+						block = ((BranchActionBlock)block).Target;
+						break;
+
+					case ActionType.Assign:
+						{
+							AssignActionBlock assignBlock = (AssignActionBlock)block;
+							AssignExpression assign = assignBlock.AssignExpression;
+							VariableReferenceExpression variable = assign.Target as VariableReferenceExpression;
+							if (null == variable)
+							{
+								UnsupportedExpression(assign);
+							}
+							else
+							{
+								if (variables.ContainsKey(variable.Variable.Index))
+									UnsupportedExpression(assign.Expression);
+								
+								variables.Add(variable.Variable.Index, assign.Expression);
+								block = assignBlock.Next;
+							}
+							break;
+						}
+
+					case ActionType.Return:
+						{
+							Expression expression = ((ReturnActionBlock)block).Expression;
+							VariableReferenceExpression variable = expression as VariableReferenceExpression;
+							return null == variable
+								? expression
+								: variables[variable.Variable.Index];
+						}
+				}
+			}
+			return null;
+		}
+
+		private static bool IsNoSideEffectIndirectActivationInvocation(MethodInvocationExpression invocation)
+		{
+			MethodDefinition methodDefinition = MethodDefinitionFor(invocation);
+			if (null == methodDefinition) return false;
+			ActionFlowGraph afg = FlowGraphFactory.CreateActionFlowGraph(FlowGraphFactory.CreateControlFlowGraph(methodDefinition));
+
+			if (afg.Blocks.Count == 2 && afg.Blocks[0].ActionType == ActionType.Invoke)
+			{
+				InvokeActionBlock invocationBlock = (InvokeActionBlock) afg.Blocks[0];
+				return IsActivateInvocation(invocationBlock.Expression);
+			}
+
+			return false;
+		}
+
+		private static MethodDefinition MethodDefinitionFor(MethodInvocationExpression invocation)
+		{
+			MethodReferenceExpression methodRef = invocation.Target as MethodReferenceExpression;
+			if (null == methodRef) return null;
+
+			return GetMethodDefinition(methodRef);
+		}
+
+		private static bool IsActivateInvocation(MethodInvocationExpression invocation)
+		{
+			MethodReferenceExpression methodRef = invocation.Target as MethodReferenceExpression;
+			if (null == methodRef) return false;
+			return IsActivateMethod(methodRef.Method);
+		}
+
+		private static bool IsActivateMethod(MethodReference method)
+		{
+			if (method.Name != "Activate") return false;
+			return method.DeclaringType.FullName == typeof(IActivatable).FullName ||
+				   IsOverridenActivateMethod(method);
+		}
+
+		private static bool IsOverridenActivateMethod(MethodReference method)
+		{
+			TypeDefinition declaringType = FindTypeDefinition(method.DeclaringType.Module, method.DeclaringType.FullName);
+			if (!DeclaringTypeImplementsIActivatable(declaringType)) return false;
+			if (method.Parameters.Count != 1 || 
+				method.Parameters[0].ParameterType.FullName != typeof(ActivationPurpose).FullName) return false;
+
+			return true;
+		}
+
+		private static bool DeclaringTypeImplementsIActivatable(TypeDefinition type)
+		{
+			foreach (TypeReference itf in type.Interfaces)
+			{
+				if (itf.FullName == typeof (IActivatable).FullName)
+				{
+					return true;
+				}
+			}
+
+			return false;
+		}
+
+		private static MethodDefinition GetMethodDefinition(MethodReferenceExpression methodRef)
+		{
+			MethodDefinition definition = methodRef.Method as MethodDefinition;
+			return definition ?? LoadExternalMethodDefinition(methodRef);
+		}
+
+		private static MethodDefinition LoadExternalMethodDefinition(MethodReferenceExpression methodRef)
+		{
+			MethodReference method = methodRef.Method;
+			AssemblyDefinition assemblyDef = new AssemblyResolver(_assemblyCachingStrategy).ForTypeReference(method.DeclaringType);
+			TypeDefinition type = assemblyDef.MainModule.GetType(method.DeclaringType.FullName);
+			return GetMethod(type, method);
+		}
+
+		private static MethodDefinition GetMethod(TypeDefinition type, MethodReference template)
+		{
+			foreach (MethodDefinition method in type.Methods)
+			{
+				if (method.Name != template.Name) continue;
+				if (method.Parameters.Count != template.Parameters.Count) continue;
+				if (!ParametersMatch(method.Parameters, template.Parameters)) continue;
+
+				return method;
+			}
+
+			return null;
+		}
+
+#if CF
+		private static bool ParametersMatch(Collection<ParameterDefinition> parameters, IList<TypeReference> templates)
+		{
+			return ParametersMatch(parameters, templates, delegate(ParameterDefinition candidate, TypeReference template)
+			{
+				return candidate.ParameterType.FullName == template.FullName;
+			});
+		}
+#endif
+
+		private static bool ParametersMatch(IList<ParameterDefinition> parameters, IList<ParameterDefinition> templates)
+		{
+			return ParametersMatch(parameters, templates, delegate(ParameterDefinition candidate, ParameterDefinition template)
+			                                               	{
+			                                               		return candidate.ParameterType.FullName == template.ParameterType.FullName;
+			                                               	});
+		}
+
+		private static bool ParametersMatch<T>(IList<ParameterDefinition> parameters, IList<T> templates, ParameterMatch<T> predicate)
+		{
+			if (parameters.Count != templates.Count) return false;
+
+			for (int i = 0; i < parameters.Count; i++)
+			{
+				ParameterDefinition parameter = parameters[i];
+				if (!predicate(parameter, templates[i])) return false;
+			}
+
+			return true;
+		}
+
+		private delegate bool ParameterMatch<T>(ParameterDefinition candidate, T template);
+
+		class Visitor : AbstractCodeStructureVisitor
+		{
+			private object _current;
+			private int _insideCandidate;
+			readonly IList _methodDefinitionStack = new ArrayList();
+			private readonly CecilReferenceProvider _referenceProvider;
+
+			public Visitor(MethodDefinition topLevelMethod, AssemblyResolver resolver)
+			{
+				EnterMethodDefinition(topLevelMethod);
+				AssemblyDefinition assembly = resolver.ForType(topLevelMethod.DeclaringType);
+				_referenceProvider = CecilReferenceProvider.ForModule(assembly.MainModule);
+			}
+
+			private void EnterMethodDefinition(MethodDefinition method)
+			{
+				_methodDefinitionStack.Add(method);
+			}
+
+			private void LeaveMethodDefinition(MethodDefinition method)
+			{
+				int lastIndex = _methodDefinitionStack.Count - 1;
+				object popped = _methodDefinitionStack[lastIndex];
+				System.Diagnostics.Debug.Assert(method == popped);
+				_methodDefinitionStack.RemoveAt(lastIndex);
+			}
+
+			public NQExpression Expression
+			{
+				get
+				{
+				    ConstValue value = _current as ConstValue;
+				    if (null != value)
+				    {
+                        return ToNQExpression(value);
+				    }
+				    return (NQExpression)_current;
+				}
+			}
+
+		    private static NQExpression ToNQExpression(ConstValue value)
+		    {
+                if (IsTrue(value.Value())) return BoolConstExpression.True;
+		        return BoolConstExpression.False;
+		    }
+
+		    private static bool IsTrue(object o)
+		    {
+                return ((IConvertible) o).ToBoolean(null);
+		    }
+
+		    private bool InsideCandidate
+			{
+				get { return _insideCandidate > 0; }
+			}
+
+			public override void Visit(CastExpression node)
+			{
+				node.Target.Accept(this);
+			}
+
+			public override void Visit(AssignExpression node)
+			{
+				UnsupportedExpression(node);
+			}
+
+			public override void Visit(VariableReferenceExpression node)
+			{
+				UnsupportedExpression(node);
+			}
+
+			public override void Visit(ArgumentReferenceExpression node)
+			{
+				UnsupportedExpression(node);
+			}
+
+			public override void Visit(UnaryExpression node)
+			{
+				switch (node.Operator)
+				{
+					case UnaryOperator.Not:
+						Visit(node.Operand);
+						Negate();
+						break;
+
+					default:
+						UnsupportedExpression(node);
+						break;
+				}
+			}
+
+			public override void Visit(Ast.BinaryExpression node)
+			{
+				switch (node.Operator)
+				{
+					case BinaryOperator.ValueEquality:
+						PushComparison(node.Left, node.Right, ComparisonOperator.ValueEquality);
+						break;
+
+					case BinaryOperator.ValueInequality:
+						PushComparison(node.Left, node.Right, ComparisonOperator.ValueEquality);
+						Negate();
+						break;
+
+					case BinaryOperator.LessThan:
+						PushComparison(node.Left, node.Right, ComparisonOperator.Smaller);
+						break;
+
+					case BinaryOperator.GreaterThan:
+						PushComparison(node.Left, node.Right, ComparisonOperator.Greater);
+						break;
+
+					case BinaryOperator.GreaterThanOrEqual:
+						PushComparison(node.Left, node.Right, ComparisonOperator.Smaller);
+						Negate();
+						break;
+
+					case BinaryOperator.LessThanOrEqual:
+						PushComparison(node.Left, node.Right, ComparisonOperator.Greater);
+						Negate();
+						break;
+
+					case BinaryOperator.LogicalOr:
+						Push(new OrExpression(Convert(node.Left), Convert(node.Right)));
+						break;
+
+					case BinaryOperator.LogicalAnd:
+						Push(new AndExpression(Convert(node.Left), Convert(node.Right)));
+						break;
+
+					default:
+						UnsupportedExpression(node);
+						break;
+				}
+			}
+
+			private void Negate()
+			{
+				NQExpression top = (NQExpression)Pop();
+				NotExpression topNot = top as NotExpression;
+				if (topNot != null)
+				{
+					Push(topNot.Expr());
+					return;
+				}
+				Push(new NotExpression(top));
+			}
+
+			private void PushComparison(Expression lhs, Expression rhs, ComparisonOperator op)
+			{
+				Visit(lhs);
+				object left = Pop();
+				Visit(rhs);
+				object right = Pop();
+
+				bool areOperandsSwapped = IsCandidateFieldValue(right);
+				if (areOperandsSwapped)
+				{
+					object temp = left;
+					left = right;
+					right = temp;
+				}
+
+				AssertType(left, typeof(FieldValue), lhs);
+				AssertType(right, typeof(IComparisonOperand), rhs);
+
+				Push(new ComparisonExpression((FieldValue)left, (IComparisonOperand)right, op));
+
+				if (areOperandsSwapped && !op.IsSymmetric())
+				{
+					Negate();
+				}
+			}
+
+			private static bool IsCandidateFieldValue(object o)
+			{
+				FieldValue value = o as FieldValue;
+				if (value == null) return false;
+				return value.Root() is CandidateFieldRoot;
+			}
+
+			public override void Visit(MethodInvocationExpression node)
+			{
+				MethodReferenceExpression methodRef = node.Target as MethodReferenceExpression;
+				if (null == methodRef)
+					UnsupportedExpression(node);
+
+				MethodReference method = methodRef.Method;
+				if (IsOperator(method))
+				{
+					ProcessOperatorMethodInvocation(node, method);
+					return;
+				}
+
+				if (IsSystemString(method.DeclaringType))
+				{
+					ProcessStringMethod(node, methodRef);
+					return;
+				}
+
+				ProcessRegularMethodInvocation(node, methodRef);
+			}
+
+			private static bool IsSystemString(TypeReference type)
+			{
+				return type.FullName == "System.String";
+			}
+
+			private void ProcessStringMethod(MethodInvocationExpression node, MethodReferenceExpression methodRef)
+			{
+				MethodReference method = methodRef.Method;
+
+				if (method.Parameters.Count != 1
+					|| !IsSystemString(method.Parameters[0].ParameterType))
+				{
+					UnsupportedExpression(methodRef);
+				}
+
+				switch (method.Name)
+				{
+					case "Contains":
+						PushComparison(methodRef.Target, node.Arguments[0], ComparisonOperator.Contains);
+						break;
+
+					case "StartsWith":
+						PushComparison(methodRef.Target, node.Arguments[0], ComparisonOperator.StartsWith);
+						break;
+
+					case "EndsWith":
+						PushComparison(methodRef.Target, node.Arguments[0], ComparisonOperator.EndsWith);
+						break;
+
+					case "Equals":
+						PushComparison(methodRef.Target, node.Arguments[0], ComparisonOperator.ValueEquality);
+						break;
+
+					default:
+						UnsupportedExpression(methodRef);
+						break;
+				}
+			}
+
+			private void ProcessRegularMethodInvocation(MethodInvocationExpression node, MethodReferenceExpression methodRef)
+			{
+				if (node.Arguments.Count != 0)
+					UnsupportedExpression(node);
+
+				Expression target = methodRef.Target;
+				switch (target.CodeElementType)
+				{
+					case CodeElementType.ThisReferenceExpression:
+						if (!InsideCandidate)
+							UnsupportedExpression(node);
+						ProcessCandidateMethodInvocation(node, methodRef);
+						break;
+
+					case CodeElementType.ArgumentReferenceExpression:
+						ProcessCandidateMethodInvocation(node, methodRef);
+						break;
+
+					default:
+						Push(ToFieldValue(target));
+						ProcessCandidateMethodInvocation(node, methodRef);
+						break;
+				}
+			}
+
+			private void ProcessOperatorMethodInvocation(MethodInvocationExpression node, MemberReference methodReference)
+			{
+				switch (methodReference.Name)
+				{
+					case "op_Equality":
+						PushComparison(node.Arguments[0], node.Arguments[1], ComparisonOperator.ValueEquality);
+						break;
+
+					case "op_Inequality":
+						PushComparison(node.Arguments[0], node.Arguments[1], ComparisonOperator.ValueEquality);
+						Negate();
+						break;
+
+					// XXX: check if the operations below are really supported for the
+					// data types in question
+					case "op_GreaterThanOrEqual":
+						PushComparison(node.Arguments[0], node.Arguments[1], ComparisonOperator.Smaller);
+						Negate();
+						break;
+
+					case "op_LessThanOrEqual":
+						PushComparison(node.Arguments[0], node.Arguments[1], ComparisonOperator.Greater);
+						Negate();
+						break;
+
+					case "op_LessThan":
+						PushComparison(node.Arguments[0], node.Arguments[1], ComparisonOperator.Smaller);
+						break;
+
+					case "op_GreaterThan":
+						PushComparison(node.Arguments[0], node.Arguments[1], ComparisonOperator.Greater);
+						break;
+
+					default:
+						UnsupportedExpression(node);
+						break;
+				}
+			}
+
+			private void ProcessCandidateMethodInvocation(Expression methodInvocationExpression, MethodReferenceExpression methodRef)
+			{
+				MethodDefinition method = GetMethodDefinition(methodRef);
+				if (null == method)
+					UnsupportedExpression(methodInvocationExpression);
+
+				AssertMethodCanBeVisited(methodInvocationExpression, method);
+
+				Expression expression = GetQueryExpression(method);
+				if (null == expression)
+					UnsupportedExpression(methodInvocationExpression);
+
+				EnterCandidateMethod(method);
+				try
+				{
+					Visit(expression);
+				}
+				finally
+				{
+					LeaveCandidateMethod(method);
+				}
+			}
+
+			private void AssertMethodCanBeVisited(Expression methodInvocationExpression, MethodDefinition method)
+			{
+				if (_methodDefinitionStack.Contains(method))
+					UnsupportedExpression(methodInvocationExpression);
+			}
+
+			private void EnterCandidateMethod(MethodDefinition method)
+			{
+				EnterMethodDefinition(method);
+				++_insideCandidate;
+			}
+
+			private void LeaveCandidateMethod(MethodDefinition method)
+			{
+				--_insideCandidate;
+				LeaveMethodDefinition(method);
+			}
+
+			private static bool IsOperator(MethodReference method)
+			{
+				return !method.HasThis && method.Name.StartsWith("op_") && 2 == method.Parameters.Count;
+			}
+
+			public override void Visit(FieldReferenceExpression node)
+			{
+				PushFieldValueForTarget(node, node.Target);
+			}
+
+			private void PushFieldValueForTarget(FieldReferenceExpression node, Expression target)
+			{
+				switch (target.CodeElementType)
+				{
+					case CodeElementType.ArgumentReferenceExpression:
+						PushFieldValue(CandidateFieldRoot.Instance, node.Field);
+						break;
+
+					case CodeElementType.ThisReferenceExpression:
+						if (InsideCandidate)
+						{
+							if (_current != null)
+							{
+								FieldValue current = PopFieldValue(node);
+								PushFieldValue(current, node.Field);
+							}
+							else
+							{
+								PushFieldValue(CandidateFieldRoot.Instance, node.Field);
+							}
+						}
+						else
+						{
+							PushFieldValue(PredicateFieldRoot.Instance, node.Field);
+						}
+						break;
+
+					case CodeElementType.MethodInvocationExpression:
+					case CodeElementType.FieldReferenceExpression:
+						FieldValue value = ToFieldValue(target);
+						PushFieldValue(value, node.Field);
+						break;
+
+					case CodeElementType.CastExpression:
+						PushFieldValueForTarget(node, ((CastExpression)node.Target).Target);
+						break;
+
+					default:
+						UnsupportedExpression(node);
+						break;
+				}
+			}
+
+			private void PushFieldValue(IComparisonOperandAnchor value, FieldReference field)
+			{	
+				Push(new FieldValue(value, _referenceProvider.ForCecilField(field)));
+			}
+
+			public override void Visit(LiteralExpression node)
+			{
+				Push(new ConstValue(node.Value));
+			}
+
+			NQExpression Convert(Expression node)
+			{
+				return ReconstructNullComparisonIfNecessary(node);
+			}
+
+			private NQExpression ReconstructNullComparisonIfNecessary(Expression node)
+			{
+				Visit(node);
+
+				object top = Pop();
+				FieldValue fieldValue = top as FieldValue;
+				if (fieldValue == null)
+				{
+					AssertType(top, typeof(NQExpression), node);
+					return (NQExpression)top;
+				}
+
+				return
+					new NotExpression(
+						new ComparisonExpression(
+							fieldValue,
+							new ConstValue(null),
+							ComparisonOperator.ValueEquality));
+			}
+
+			FieldValue ToFieldValue(Expression node)
+			{
+				Visit(node);
+				return PopFieldValue(node);
+			}
+
+			private FieldValue PopFieldValue(Expression node)
+			{
+				return (FieldValue)Pop(node, typeof(FieldValue));
+			}
+
+			void Push(object value)
+			{
+				Assert(_current == null, "expression stack must be empty before Push");
+				_current = value;
+			}
+
+			object Pop(Expression node, Type expectedType)
+			{
+				object value = Pop();
+				AssertType(value, expectedType, node);
+				return value;
+			}
+
+			private static void AssertType(object value, Type expectedType, Expression sourceExpression)
+			{
+				Type actualType = value.GetType();
+				if (!expectedType.IsAssignableFrom(actualType))
+				{
+					UnsupportedPredicate(
+						string.Format("Unsupported expression: {0}. Unexpected type on stack. Expected: {1}, Got: {2}.",
+									  ExpressionPrinter.ToString(sourceExpression), expectedType, actualType));
+				}
+			}
+
+			object Pop()
+			{
+				Assert(_current != null, "expression stack is empty");
+				object value = _current;
+				_current = null;
+				return value;
+			}
+
+			private static void Assert(bool condition, string message)
+			{
+				System.Diagnostics.Debug.Assert(condition, message);
+			}
+		}
+	}
+
+	internal class BoxedValueTypeProcessor : TraversingExpressionVisitor
+	{
+		override public void Visit(ComparisonExpression expression)
+		{
+			TypeReference fieldType = GetFieldType(expression.Left());
+			if (!fieldType.IsValueType) return;
+			
+			ConstValue constValue = expression.Right() as ConstValue;
+			if (constValue == null) return;
+
+			AdjustConstValue(fieldType, constValue);
+		}
+
+		private static TypeReference GetFieldType(FieldValue field)
+		{
+			return ((CecilFieldRef) field.Field).FieldType;
+		}
+
+		private static void AdjustConstValue(TypeReference typeRef, ConstValue constValue)
+		{
+			object value = constValue.Value();
+			if (!value.GetType().IsValueType) return;
+			
+			System.Type type = ResolveTypeReference(typeRef);
+			if (!type.IsEnum || value.GetType() == type) return;
+
+			constValue.Value(Enum.ToObject(type, value));
+		}
+
+		private static Type ResolveTypeReference(TypeReference typeRef)
+		{
+			Assembly assembly = LoadAssembly(typeRef.Scope);
+			return assembly.GetType(typeRef.FullName.Replace('/', '+'), true);
+		}
+
+		private static Assembly LoadAssembly(IMetadataScope scope)
+		{
+			AssemblyNameReference nameRef = scope as AssemblyNameReference;
+			if (null != nameRef) return Assembly.Load(nameRef.FullName);
+			ModuleDefinition moduleDef = scope as ModuleDefinition;
+			return LoadAssembly(moduleDef.Assembly.Name);
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/SingleItemCachingStrategy.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/SingleItemCachingStrategy.cs
new file mode 100644
index 0000000..eb70b65
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/SingleItemCachingStrategy.cs
@@ -0,0 +1,66 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+using System;
+
+namespace Db4objects.Db4o.Internal.Query
+{
+	public delegate R Producer<T, R>(T arg);
+
+	/// <summary>
+	/// A very simple caching strategy that caches only the last added item.
+	/// </summary>
+	public class SingleItemCachingStrategy<K,V> : ICachingStrategy<K,V>
+	{
+
+		private K _lastKey;
+		private V _lastItem;
+		private object _monitor = new object();
+		private readonly Producer<K, V> _producer;
+		
+		public SingleItemCachingStrategy(Producer<K,V> producer)
+		{
+			_producer = producer;
+		}
+
+		#region ICachingStrategy Members
+		public void Add(K key, V item)
+		{
+			if (!typeof(K).IsValueType && null == key) throw new ArgumentNullException("key");
+			lock (_monitor)
+			{
+				_lastKey = key;
+				_lastItem = item;
+			}
+		}
+
+		public V Get(K key)
+		{
+			if (null == key) throw new ArgumentNullException("key");
+			lock (_monitor)
+			{
+				if (!key.Equals(_lastKey))
+				{
+					Add(key, _producer(key));
+				}
+				
+				return _lastItem;
+			}
+		}
+		#endregion
+	}
+    
+    public class NullCachingStrategy : ICachingStrategy<object, object>
+    {
+        public static readonly ICachingStrategy<object, object> Default = new NullCachingStrategy();
+        
+        #region ICachingStrategy Members
+        public void Add(object key, object item)
+        {   
+        }
+
+        public object Get(object key)
+        {
+            return null;
+        }
+        #endregion
+    }
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/UnsupportedPredicateException.cs b/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/UnsupportedPredicateException.cs
new file mode 100644
index 0000000..f648282
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/UnsupportedPredicateException.cs
@@ -0,0 +1,14 @@
+/* Copyright (C) 2006   Versant Inc.   http://www.db4o.com */
+
+namespace Db4objects.Db4o.NativeQueries
+{
+	using System;
+
+	public class UnsupportedPredicateException : Exception
+	{
+		public UnsupportedPredicateException(string reason)
+			: base(reason)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o-2008.csproj b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o-2008.csproj
new file mode 100755
index 0000000..02e754c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o-2008.csproj
@@ -0,0 +1,1046 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build" ToolsVersion="3.5">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{600CD3BF-2ED2-4183-87F7-ADD78A968AE0}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Db4objects.Db4o</RootNamespace>
+    <AssemblyName>Db4objects.Db4o</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    
+    
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<SignAssembly>true</SignAssembly>
+<AssemblyOriginatorKeyFile>../db4objects.snk</AssemblyOriginatorKeyFile>
+</PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;NET_3_5</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Debug\Db4objects.Db4o.xml</DocumentationFile>
+    <NoWarn>1591;1572;1573;1574;0419;</NoWarn>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE;NET_3_5</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>1591;1572;1573;1574;0419;</NoWarn>
+    <DocumentationFile>bin\Release\Db4objects.Db4o.xml</DocumentationFile>
+    <DebugSymbols>true</DebugSymbols>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System"/>
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data"/>
+    <Reference Include="System.Xml"/>
+  </ItemGroup>
+  <ItemGroup>
+<Compile Include="Db4objects.Db4o\Activation\ActivationPurpose.cs"/>
+<Compile Include="Db4objects.Db4o\Activation\IActivator.cs"/>
+<Compile Include="Db4objects.Db4o\Collections\ArrayDictionary4.cs"/>
+<Compile Include="Db4objects.Db4o\Collections\ArrayList4.cs"/>
+<Compile Include="Db4objects.Db4o\Collections\CollectionFactory.cs"/>
+<Compile Include="Db4objects.Db4o\Config\ConfigScope.cs"/>
+<Compile Include="Db4objects.Db4o\Config\Encoding\IStringEncoding.cs"/>
+<Compile Include="Db4objects.Db4o\Config\Encoding\StringEncodings.cs"/>
+<Compile Include="Db4objects.Db4o\Config\Entry.cs"/>
+<Compile Include="Db4objects.Db4o\Config\GlobalOnlyConfigException.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IAlias.cs"/>
+<Compile Include="Db4objects.Db4o\Config\ICacheConfiguration.cs"/>
+<Compile Include="Db4objects.Db4o\Config\ICacheConfigurationProvider.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IClientServerConfiguration.cs"/>
+<Compile Include="Db4objects.Db4o\Config\ICommonConfiguration.cs"/>
+<Compile Include="Db4objects.Db4o\Config\ICommonConfigurationProvider.cs"/>
+<Compile Include="Db4objects.Db4o\Config\ICompare.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IConfiguration.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IConfigurationItem.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IEmbeddedConfiguration.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IEmbeddedConfigurationItem.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IEnvironmentConfiguration.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IFileConfiguration.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IFileConfigurationProvider.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IFreespaceConfiguration.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IFreespaceFiller.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IIdSystemConfiguration.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IIdSystemConfigurationProvider.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IIdSystemFactory.cs"/>
+<Compile Include="Db4objects.Db4o\Config\ILegacyClientServerFactory.cs"/>
+<Compile Include="Db4objects.Db4o\Config\INameProvider.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IObjectAttribute.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IObjectClass.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IObjectConstructor.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IObjectField.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IObjectTranslator.cs"/>
+<Compile Include="Db4objects.Db4o\Config\IQueryConfiguration.cs"/>
+<Compile Include="Db4objects.Db4o\Config\QueryEvaluationMode.cs"/>
+<Compile Include="Db4objects.Db4o\Config\SimpleNameProvider.cs"/>
+<Compile Include="Db4objects.Db4o\Config\TNull.cs"/>
+<Compile Include="Db4objects.Db4o\Config\TypeAlias.cs"/>
+<Compile Include="Db4objects.Db4o\Config\WildcardAlias.cs"/>
+<Compile Include="Db4objects.Db4o\Constraints\ConstraintViolationException.cs"/>
+<Compile Include="Db4objects.Db4o\Constraints\UniqueFieldValueConstraint.cs"/>
+<Compile Include="Db4objects.Db4o\Constraints\UniqueFieldValueConstraintViolationException.cs"/>
+<Compile Include="Db4objects.Db4o\CorruptionException.cs"/>
+<Compile Include="Db4objects.Db4o\DTrace.cs"/>
+<Compile Include="Db4objects.Db4o\Db4oEmbedded.cs"/>
+<Compile Include="Db4objects.Db4o\Db4oFactory.cs"/>
+<Compile Include="Db4objects.Db4o\Db4oVersion.cs"/>
+<Compile Include="Db4objects.Db4o\Debug4.cs"/>
+<Compile Include="Db4objects.Db4o\Defragment\AbstractIdMapping.cs"/>
+<Compile Include="Db4objects.Db4o\Defragment\DatabaseIdMapping.cs"/>
+<Compile Include="Db4objects.Db4o\Defragment\Defragment.cs"/>
+<Compile Include="Db4objects.Db4o\Defragment\DefragmentConfig.cs"/>
+<Compile Include="Db4objects.Db4o\Defragment\DefragmentInfo.cs"/>
+<Compile Include="Db4objects.Db4o\Defragment\DefragmentServicesImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Defragment\FirstPassCommand.cs"/>
+<Compile Include="Db4objects.Db4o\Defragment\IDMappingCollector.cs"/>
+<Compile Include="Db4objects.Db4o\Defragment\IDefragmentListener.cs"/>
+<Compile Include="Db4objects.Db4o\Defragment\IDefragmentServices.cs"/>
+<Compile Include="Db4objects.Db4o\Defragment\IIdMapping.cs"/>
+<Compile Include="Db4objects.Db4o\Defragment\IStoredClassFilter.cs"/>
+<Compile Include="Db4objects.Db4o\Defragment\InMemoryIdMapping.cs"/>
+<Compile Include="Db4objects.Db4o\Defragment\PassCommand.cs"/>
+<Compile Include="Db4objects.Db4o\Defragment\SecondPassCommand.cs"/>
+<Compile Include="Db4objects.Db4o\Deploy.cs"/>
+<Compile Include="Db4objects.Db4o\Diagnostic\ClassHasNoFields.cs"/>
+<Compile Include="Db4objects.Db4o\Diagnostic\DefragmentRecommendation.cs"/>
+<Compile Include="Db4objects.Db4o\Diagnostic\DeletionFailed.cs"/>
+<Compile Include="Db4objects.Db4o\Diagnostic\DescendIntoTranslator.cs"/>
+<Compile Include="Db4objects.Db4o\Diagnostic\DiagnosticBase.cs"/>
+<Compile Include="Db4objects.Db4o\Diagnostic\DiagnosticToConsole.cs"/>
+<Compile Include="Db4objects.Db4o\Diagnostic\IDiagnostic.cs"/>
+<Compile Include="Db4objects.Db4o\Diagnostic\IDiagnosticConfiguration.cs"/>
+<Compile Include="Db4objects.Db4o\Diagnostic\IDiagnosticListener.cs"/>
+<Compile Include="Db4objects.Db4o\Diagnostic\LoadedFromClassIndex.cs"/>
+<Compile Include="Db4objects.Db4o\Diagnostic\MissingClass.cs"/>
+<Compile Include="Db4objects.Db4o\Diagnostic\NativeQueryNotOptimized.cs"/>
+<Compile Include="Db4objects.Db4o\Diagnostic\NativeQueryOptimizerNotLoaded.cs"/>
+<Compile Include="Db4objects.Db4o\Diagnostic\ObjectFieldDoesNotExist.cs"/>
+<Compile Include="Db4objects.Db4o\Diagnostic\UpdateDepthGreaterOne.cs"/>
+<Compile Include="Db4objects.Db4o\Events\CancellableObjectEventArgs.cs"/>
+<Compile Include="Db4objects.Db4o\Events\ClassEventArgs.cs"/>
+<Compile Include="Db4objects.Db4o\Events\CommitEventArgs.cs"/>
+<Compile Include="Db4objects.Db4o\Events\EventException.cs"/>
+<Compile Include="Db4objects.Db4o\Events\EventRegistryFactory.cs"/>
+<Compile Include="Db4objects.Db4o\Events\ICancellableEventArgs.cs"/>
+<Compile Include="Db4objects.Db4o\Events\IEventRegistry.cs"/>
+<Compile Include="Db4objects.Db4o\Events\ObjectContainerEventArgs.cs"/>
+<Compile Include="Db4objects.Db4o\Events\ObjectEventArgs.cs"/>
+<Compile Include="Db4objects.Db4o\Events\ObjectInfoEventArgs.cs"/>
+<Compile Include="Db4objects.Db4o\Events\QueryEventArgs.cs"/>
+<Compile Include="Db4objects.Db4o\Events\StringEventArgs.cs"/>
+<Compile Include="Db4objects.Db4o\Events\TransactionalEventArgs.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\BackupInProgressException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\CompositeDb4oException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\DatabaseClosedException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\DatabaseFileLockedException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\DatabaseMaximumSizeReachedException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\DatabaseReadOnlyException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\Db4oDatabase.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\Db4oException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\Db4oFatalException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\Db4oFileHeaderCorruptionException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\Db4oIOException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\Db4oIllegalStateException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\Db4oRecoverableException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\Db4oUUID.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\Db4oUnexpectedException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\EmergencyShutdownReadOnlyException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\IDb4oCallback.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\IExtClient.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\IExtObjectContainer.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\IExtObjectServer.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\IExtObjectSet.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\IObjectCallbacks.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\IObjectInfo.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\IObjectInfoCollection.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\IStoredClass.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\IStoredField.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\ISystemInfo.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\IncompatibleFileFormatException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\InvalidIDException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\InvalidPasswordException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\InvalidSlotException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\ObjectNotStorableException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\OldFormatException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\Status.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\UnsupportedOldFormatException.cs"/>
+<Compile Include="Db4objects.Db4o\Ext\VirtualField.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\AbstractTreeIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\Algorithms4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\ArrayIterator4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\Arrays4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\AutoStopWatch.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\BitMap4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\BlockingQueue.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\BlockingQueueStoppedException.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\BooleanByRef.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\ByRef.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\CircularBuffer4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\CircularIntBuffer4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\CircularLongBuffer4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\Collection4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\Collection4Iterator.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\Collections4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\CompositeIterable4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\CompositeIterator4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\DelegatingBlockingQueue.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\DynamicVariable.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\EnumerateIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\Environments.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\FilteredIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\FlatteningIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\FunctionApplicationIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\HashSet4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\Hashtable4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\HashtableBase.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\HashtableByteArrayEntry.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\HashtableIdentityEntry.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\HashtableIntEntry.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\HashtableIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\HashtableLongEntry.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\HashtableObjectEntry.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IArrayFactory.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IBlock4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IBlockingQueue4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\ICancellableVisitor4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IClosure4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IComparison4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IDeepClone.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IEntry4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IEnvironment.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IFixedSizeIntIterator4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IFunction4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IIntComparator.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IIntIterator4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IIntObjectVisitor.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IListener4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IMap4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IObjectPool.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IPausableBlockingQueue4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IPredicate4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IPreparedComparison.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IProcedure4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IQueue4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\ISequence4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\ISet4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IShallowClone.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\ISortable4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\ITimeoutBlockingQueue4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IVisitable.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IVisitor4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IdentityHashtable4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IdentitySet4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IndexedIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IntArrayByRef.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IntArrayList.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IntByRef.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IntIdGenerator.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IntIterator4Adaptor.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IntIterator4Impl.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\IntIterators.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\InvalidIteratorException.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\Iterable4Adaptor.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\Iterator4Impl.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\Iterators.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\KeySpec.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\KeySpecHashtable4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\List4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\ListenerRegistry.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\LongByRef.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\MappingIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\NativeCollections.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\No4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\NoDuplicatesQueue.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\NonblockingQueue.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\ObjectByRef.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\Pair.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\PausableBlockingQueue.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\PrimitiveCodec.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\Runnable4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\Runtime4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\RuntimeInterruptedException.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\SimpleObjectPool.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\SimpleTimer.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\SingleValueIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\SortedCollection4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\Stack4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\StopWatch.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\SubTypePredicate.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\SynchronizedHashtable4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\SynchronizedIterator4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\TernaryBool.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\ThreadLocal4.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\TimeStampIdGenerator.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\TimeoutBlockingQueue.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\Tree.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\TreeKeyIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\TreeNodeIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Foundation\TreeObject.cs"/>
+<Compile Include="Db4objects.Db4o\IBlobStatus.cs"/>
+<Compile Include="Db4objects.Db4o\IBlobTransport.cs"/>
+<Compile Include="Db4objects.Db4o\IEmbeddedObjectContainer.cs"/>
+<Compile Include="Db4objects.Db4o\IInternal4.cs"/>
+<Compile Include="Db4objects.Db4o\IO\BinConfiguration.cs"/>
+<Compile Include="Db4objects.Db4o\IO\BinDecorator.cs"/>
+<Compile Include="Db4objects.Db4o\IO\BlockAwareBin.cs"/>
+<Compile Include="Db4objects.Db4o\IO\BlockAwareBinWindow.cs"/>
+<Compile Include="Db4objects.Db4o\IO\CachedIoAdapter.cs"/>
+<Compile Include="Db4objects.Db4o\IO\CachingBin.cs"/>
+<Compile Include="Db4objects.Db4o\IO\CachingStorage.cs"/>
+<Compile Include="Db4objects.Db4o\IO\ConstantGrowthStrategy.cs"/>
+<Compile Include="Db4objects.Db4o\IO\DoublingGrowthStrategy.cs"/>
+<Compile Include="Db4objects.Db4o\IO\FileStorage.cs"/>
+<Compile Include="Db4objects.Db4o\IO\IBin.cs"/>
+<Compile Include="Db4objects.Db4o\IO\IBlockSize.cs"/>
+<Compile Include="Db4objects.Db4o\IO\IGrowthStrategy.cs"/>
+<Compile Include="Db4objects.Db4o\IO\IStorage.cs"/>
+<Compile Include="Db4objects.Db4o\IO\IoAdapter.cs"/>
+<Compile Include="Db4objects.Db4o\IO\IoAdapterStorage.cs"/>
+<Compile Include="Db4objects.Db4o\IO\MemoryBin.cs"/>
+<Compile Include="Db4objects.Db4o\IO\MemoryStorage.cs"/>
+<Compile Include="Db4objects.Db4o\IO\NonFlushingStorage.cs"/>
+<Compile Include="Db4objects.Db4o\IO\PagingMemoryBin.cs"/>
+<Compile Include="Db4objects.Db4o\IO\PagingMemoryStorage.cs"/>
+<Compile Include="Db4objects.Db4o\IO\RandomAccessFileAdapter.cs"/>
+<Compile Include="Db4objects.Db4o\IO\ReadOnlyBin.cs"/>
+<Compile Include="Db4objects.Db4o\IO\StorageDecorator.cs"/>
+<Compile Include="Db4objects.Db4o\IO\SynchronizedBin.cs"/>
+<Compile Include="Db4objects.Db4o\IO\ThreadedSyncBin.cs"/>
+<Compile Include="Db4objects.Db4o\IO\VanillaIoAdapter.cs"/>
+<Compile Include="Db4objects.Db4o\IObjectServer.cs"/>
+<Compile Include="Db4objects.Db4o\IObjectSet.cs"/>
+<Compile Include="Db4objects.Db4o\ITransactionAware.cs"/>
+<Compile Include="Db4objects.Db4o\ITransactionListener.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\AbstractBufferContext.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\ActivatableBase.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\ActivationContext4.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\ActivationDepthImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\ActivationMode.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\DepthUtil.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\DescendingActivationDepth.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\FixedActivationDepth.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\FixedUpdateDepth.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\FullActivationDepth.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\IActivationDepth.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\IActivationDepthProvider.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\IFixedDepth.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\IModifiedObjectQuery.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\ITransparentActivationDepthProvider.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\IUpdateDepth.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\IUpdateDepthProvider.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\LegacyActivationDepth.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\LegacyActivationDepthProvider.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\LegacyFixedUpdateDepth.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\LegacyUnspecifiedUpdateDepth.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\LegacyUpdateDepthProvider.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\NonDescendingActivationDepth.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\NullModifiedObjectQuery.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\TPFixedUpdateDepth.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\TPUnspecifiedUpdateDepth.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\TPUpdateDepthProvider.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\TransparentActivationDepthProviderImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\UnknownActivationDepth.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Activation\UnspecifiedUpdateDepth.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ArrayType.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\BlobImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\BlockSizeBlockConverter.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\AbstractBTreeRangeIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\Algebra\BTreeAlgebra.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\Algebra\BTreeRangeOperation.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\Algebra\BTreeRangeSingleIntersect.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\Algebra\BTreeRangeSingleOperation.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\Algebra\BTreeRangeSingleUnion.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\Algebra\BTreeRangeUnionIntersect.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\Algebra\BTreeRangeUnionOperation.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\Algebra\BTreeRangeUnionUnion.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\BTree.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\BTreeAdd.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\BTreeCancelledRemoval.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\BTreeConfiguration.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\BTreeIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\BTreeNode.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\BTreeNodeCacheEntry.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\BTreeNodeSearchResult.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\BTreePatch.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\BTreePointer.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\BTreeRangeKeyIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\BTreeRangePointerIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\BTreeRangeSingle.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\BTreeRangeUnion.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\BTreeRemove.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\BTreeUpdate.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\FieldIndexKeyHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\FieldIndexKeyImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\IBTreeRange.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\IBTreeRangeVisitor.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\IBTreeStructureListener.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\IFieldIndexKey.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\SearchTarget.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Btree\Searcher.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ByteArrayBuffer.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Caching\CacheFactory.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Caching\CacheStatistics.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Caching\ICache4.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Caching\IPurgeableCache4.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Caching\LRU2QCache.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Caching\LRU2QLongCache.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Caching\LRU2QXCache.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Caching\LRUCache.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Caching\LRUIntCache.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Caching\LRULongCache.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Caching\NullCache4.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\CallBackMode.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\CallbackObjectInfoCollections.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Callbacks\ICallbacks.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Callbacks\NullCallbacks.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ClassAspect.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ClassMetadata.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ClassMetadataIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ClassMetadataRepository.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Classindex\AbstractClassIndexStrategy.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Classindex\BTreeClassIndexStrategy.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Classindex\IClassIndexStrategy.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Collections\BigSet.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Collections\BigSetBTreeManager.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Collections\BigSetTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Collections\IBigSetPersistence.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\CommitTimestampFieldMetadata.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\CommitTimestampSupport.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Config4Abstract.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Config4Class.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Config4Field.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Config4Impl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Config\CacheConfigurationImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Config\CommonConfigurationImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Config\Db4oLegacyConfigurationBridge.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Config\EmbeddedConfigurationImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Config\FileConfigurationImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Config\ILegacyConfigurationProvider.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Config\IdSystemConfigurationImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Const4.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Convert\Conversion.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Convert\ConversionStage.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Convert\Conversions\ClassAspects_7_4.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Convert\Conversions\ClassIndexesToBTrees_5_5.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Convert\Conversions\CommonConversions.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Convert\Conversions\DropDateTimeOffsetClassIndexes_7_12.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Convert\Conversions\DropEnumClassIndexes_7_10.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Convert\Conversions\DropGuidClassIndexes_7_12.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Convert\Conversions\FieldIndexesToBTrees_5_7.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Convert\Conversions\ReindexNetDateTime_7_8.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Convert\Conversions\VersionNumberToCommitTimestamp_8_0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Convert\Converter.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\DefragmentContextImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\DeleteInfo.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Delete\DeleteContextImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Delete\IDeleteContext.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Diagnostic\DiagnosticProcessor.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\DisabledBlockConverter.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Encoding\BuiltInStringEncoding.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Encoding\DelegatingStringIO.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Encoding\LatinStringEncoding.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Encoding\LatinStringIO.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Encoding\UnicodeStringEncoding.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Encoding\UnicodeStringIO.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\EventDispatchers.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Events\EventRegistryImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Exceptions4.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ExternalObjectContainer.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\FieldIndexException.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\FieldMetadata.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\FieldMetadataState.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fieldindex\AndIndexedLeaf.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fieldindex\FieldIndexProcessor.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fieldindex\FieldIndexProcessorResult.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fieldindex\IIndexedNode.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fieldindex\IIndexedNodeWithRange.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fieldindex\IndexedLeaf.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fieldindex\IndexedNodeBase.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fieldindex\IndexedNodeCollector.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fieldindex\IndexedPath.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fieldindex\IndexedPathIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fieldindex\JoinedLeaf.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fieldindex\OrIndexedLeaf.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fieldindex\QEBitmap.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fileheader\FileHeader.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fileheader\FileHeader1.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fileheader\FileHeader2.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fileheader\FileHeader3.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fileheader\FileHeaderVariablePart.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fileheader\FileHeaderVariablePart1.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fileheader\FileHeaderVariablePart2.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fileheader\FileHeaderVariablePart3.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fileheader\NewFileHeaderBase.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fileheader\TimerFileLock.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Fileheader\TimerFileLockDisabled.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Freespace\AbstractFreespaceManager.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Freespace\AddressKeySlotHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Freespace\BTreeFreespaceManager.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Freespace\BlockAwareFreespaceManager.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Freespace\FreeSlotNode.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Freespace\FreespaceManagerIx.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Freespace\IFreespaceListener.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Freespace\IFreespaceManager.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Freespace\InMemoryFreespaceManager.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Freespace\LengthKeySlotHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Freespace\NullFreespaceListener.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Freespace\NullFreespaceManager.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Freespace\SlotHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\FrozenObjectInfo.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\HandlerRegistry.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\HandlerVersionRegistry.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers4.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Array\ArrayHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Array\ArrayHandler0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Array\ArrayHandler1.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Array\ArrayHandler3.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Array\ArrayHandler5.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Array\ArrayVersionHelper.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Array\ArrayVersionHelper0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Array\ArrayVersionHelper3.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Array\ArrayVersionHelper5.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Array\MultidimensionalArrayHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Array\MultidimensionalArrayHandler0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Array\MultidimensionalArrayHandler3.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Array\MultidimensionalArrayIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Array\ReflectArrayIterator.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\BooleanHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\ByteHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\CharHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\DateHandler0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\DateHandlerBase.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\DoubleHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\DoubleHandler0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\FloatHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\FloatHandler0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\HandlerVersion.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\IFieldAwareTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\IVariableLengthTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\IVirtualAttributeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\IntHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\IntHandler0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\LongHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\LongHandler0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\NetType.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\NetTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\NullFieldAwareTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\PlainObjectHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\PrimitiveHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\ShortHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\ShortHandler0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\StandardReferenceTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\StandardReferenceTypeHandler0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\StringBasedValueTypeHandlerBase.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\StringBufferHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\StringHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\StringHandler0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\TypeHandlerPredicatePair.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Versions\OpenTypeHandler0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Versions\OpenTypeHandler2.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Handlers\Versions\OpenTypeHandler7.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\HardObjectReference.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IBlockConverter.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IBuiltinTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ICallbackInfoCollector.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ICommittedCallbackDispatcher.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IComparable4.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IDGenerator.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IDHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IDb4oTypeImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IDefragmentContext.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IEventDispatcher.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IIndexable4.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IIndexableTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IInternalObjectContainer.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ILinkLengthAware.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IModificationAware.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IO\BlockSizeImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IObjectContainerSpec.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IPersistent.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IQueryResultIteratorFactory.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IReadWriteBuffer.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IReadWriteable.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IReadable.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IReadsObjectIds.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ISlotCopyHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ITransactionParticipant.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IVersionedTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Identifiable.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Ids\BTreeIdSystem.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Ids\FreespaceCommitter.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Ids\IIdSystem.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Ids\IStackableIdSystem.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Ids\ITransactionalIdSystem.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Ids\IdSlotChanges.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Ids\IdSlotMapping.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Ids\IdSlotTree.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Ids\InMemoryIdSystem.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Ids\PointerBasedIdSystem.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Ids\SequentialIdGenerator.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Ids\StandardIdSystemFactory.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Ids\TransactionalIdSystemImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Ids\TransportIdSystem.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IllegalComparisonException.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\InCallback.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IntMatcher.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\InterfaceTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\IoAdaptedObjectContainer.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\LazyObjectReference.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\LocalObjectContainer.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\LocalPersistentBase.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\LocalTransaction.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\LockedTree.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Mapping\IIDMapping.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Mapping\IdSource.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Mapping\MappedIDPair.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Mapping\MappedIDPairHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Mapping\MappingNotFoundException.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\AbstractFieldMarshaller.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\AbstractReadContext.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\AspectType.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\AspectVersionContextImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\ClassMarshaller.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\ClassMarshaller0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\ClassMarshaller1.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\ClassMarshaller2.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\CollectIdContext.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\ContextState.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\FieldMarshaller0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\FieldMarshaller1.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\FieldMarshaller2.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\IAspectVersionContext.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\IFieldMarshaller.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\IHandlerVersionContext.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\IInternalReadContext.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\IMarshallingInfo.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\IObjectIdContext.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\IdObjectCollector.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\MarshallerFamily.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\MarshallingContext.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\MarshallingContextState.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\ObjectHeader.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\ObjectHeaderAttributes.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\ObjectHeaderContext.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\ObjectIdContextImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\ObjectReferenceContext.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\PrimitiveMarshaller.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\PrimitiveMarshaller0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\PrimitiveMarshaller1.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\QueryingReadContext.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\RawClassSpec.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\RawFieldSpec.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\SlotFormat.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\SlotFormat0.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\SlotFormat2.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\SlotFormatCurrent.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\UnknownTypeHandlerAspect.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Marshall\UnmarshallingContext.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\MarshallingBuffer.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\MessageOutput.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Messages.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Metadata\HierarchyAnalyzer.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Metadata\IAspectTraversalStrategy.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Metadata\ITraverseAspectCommand.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Metadata\MarshallingInfoTraverseAspectCommand.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Metadata\ModifiedAspectTraversalStrategy.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Metadata\StandardAspectTraversalStrategy.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Metadata\TraverseFieldCommand.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Null.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\NullFieldMetadata.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\NullTransactionListener.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ObjectAnalyzer.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ObjectContainerBase.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ObjectContainerFactory.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ObjectContainerSession.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ObjectID.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ObjectInfoCollectionImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ObjectReference.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ObjectTypeMetadata.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\OpenTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\PendingClassInits.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\PersistentBase.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\PersistentIntegerArray.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\PreparedArrayContainsComparison.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\PrimitiveTypeMetadata.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Qlin\QLinConstraint.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Qlin\QLinField.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Qlin\QLinNode.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Qlin\QLinOrderBy.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Qlin\QLinRoot.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Qlin\QLinSodaNode.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Qlin\QLinSubNode.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\IDb4oEnhancedFilter.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\IDb4oNQOptimizer.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\IDb4oQueryExecutionListener.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\NQOptimizationInfo.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\PredicateEvaluation.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\IInternalQuery.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QCandidate.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QCandidates.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QCon.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QConClass.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QConEvaluation.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QConJoin.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QConObject.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QConPath.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QConUnconditional.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QConstraints.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QE.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QEAbstract.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QEContains.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QEEndsWith.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QEEqual.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QEGreater.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QEIdentity.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QEMulti.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QENot.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QESmaller.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QEStartsWith.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QEStringCmp.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QField.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QPending.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QQuery.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Processor\QQueryBase.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Result\AbstractLateQueryResult.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Result\AbstractQueryResult.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Result\HybridQueryResult.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Result\IQueryResult.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Result\IdListQueryResult.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Result\IdTreeQueryResult.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Result\LazyQueryResult.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Result\SnapShotQueryResult.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\Result\StatefulQueryResult.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Query\SodaQueryComparator.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\References\HashcodeReferenceSystem.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\References\IReferenceSystem.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\References\IReferenceSystemFactory.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\References\ReferenceSystemRegistry.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\References\TransactionalReferenceSystem.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\References\TransactionalReferenceSystemBase.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ReflectException.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Reflect\Generic\KnownClassesCollector.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Reflect\IFieldAccessor.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Reflect\LenientFieldAccessor.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Reflect\ReflectClasses.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Reflect\StrictFieldAccessor.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Reflection4.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ReflectorConfigurationImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Renames.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Replication\IDb4oReplicationReference.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Replication\IDb4oReplicationReferenceProvider.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\SerializedGraph.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Serializer.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\SharedIndexedFields.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\ShutDownRunnable.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Slots\FreespaceSlotChange.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Slots\IdSystemSlotChange.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Slots\Pointer4.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Slots\ReferencedSlot.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Slots\Slot.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Slots\SlotChange.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Slots\SlotChangeFactory.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Slots\SystemSlotChange.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\StatefulBuffer.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\StoredClassImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\StoredFieldImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\SystemData.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\SystemInfoFileImpl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Threading\IThreadPool4.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Threading\ThreadPool4Impl.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Threading\UncaughtExceptionEventArgs.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Transaction.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\TransactionContext.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\TransactionLocal.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\TransactionObjectCarrier.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Transactionlog\EmbeddedTransactionLogHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Transactionlog\FileBasedTransactionLogHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Transactionlog\TransactionLogHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\TranslatedAspect.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\TransportObjectContainer.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\TreeInt.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\TreeIntObject.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\TreeReader.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\TypeHandlerAspect.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\TypeHandlerCloneContext.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\TypeHandlerConfiguration.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\UUIDFieldMetadata.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\VersionFieldMetadata.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\VirtualAttributes.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\VirtualFieldMetadata.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Weakref\EnabledWeakReferenceSupport.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Weakref\IWeakReferenceSupport.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\Weakref\WeakReferenceSupportFactory.cs"/>
+<Compile Include="Db4objects.Db4o\Internal\WriteUpdateProcessor.cs"/>
+<Compile Include="Db4objects.Db4o\Marshall\IBufferContext.cs"/>
+<Compile Include="Db4objects.Db4o\Marshall\IContext.cs"/>
+<Compile Include="Db4objects.Db4o\Marshall\IReadBuffer.cs"/>
+<Compile Include="Db4objects.Db4o\Marshall\IReadContext.cs"/>
+<Compile Include="Db4objects.Db4o\Marshall\IReferenceActivationContext.cs"/>
+<Compile Include="Db4objects.Db4o\Marshall\IReservedBuffer.cs"/>
+<Compile Include="Db4objects.Db4o\Marshall\IWriteBuffer.cs"/>
+<Compile Include="Db4objects.Db4o\Marshall\IWriteContext.cs"/>
+<Compile Include="Db4objects.Db4o\Messaging\IMessageContext.cs"/>
+<Compile Include="Db4objects.Db4o\Messaging\IMessageRecipient.cs"/>
+<Compile Include="Db4objects.Db4o\Messaging\IMessageSender.cs"/>
+<Compile Include="Db4objects.Db4o\Qlin\IQLin.cs"/>
+<Compile Include="Db4objects.Db4o\Qlin\IQLinable.cs"/>
+<Compile Include="Db4objects.Db4o\Qlin\Prototypes.cs"/>
+<Compile Include="Db4objects.Db4o\Qlin\PrototypesException.cs"/>
+<Compile Include="Db4objects.Db4o\Qlin\QLinException.cs"/>
+<Compile Include="Db4objects.Db4o\Qlin\QLinOrderByDirection.cs"/>
+<Compile Include="Db4objects.Db4o\Qlin\QLinSupport.cs"/>
+<Compile Include="Db4objects.Db4o\Query\ICandidate.cs"/>
+<Compile Include="Db4objects.Db4o\Query\IConstraint.cs"/>
+<Compile Include="Db4objects.Db4o\Query\IConstraints.cs"/>
+<Compile Include="Db4objects.Db4o\Query\IEvaluation.cs"/>
+<Compile Include="Db4objects.Db4o\Query\IQuery.cs"/>
+<Compile Include="Db4objects.Db4o\Query\IQueryComparator.cs"/>
+<Compile Include="Db4objects.Db4o\Query\Predicate.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\ArrayInfo.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Core\AbstractReflectArray.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Core\ConstructorSupport.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Core\IConstructorAwareReflectClass.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Core\IReflectConstructor.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Core\PlatformReflectConstructor.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Core\ReflectConstructorSpec.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Core\ReflectorUtils.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Generic\CollectionUpdateDepthEntry.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Generic\GenericArray.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Generic\GenericArrayClass.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Generic\GenericArrayReflector.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Generic\GenericClass.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Generic\GenericClassBuilder.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Generic\GenericField.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Generic\GenericObject.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Generic\GenericReflector.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Generic\GenericVirtualField.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Generic\IGenericConverter.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Generic\IReflectClassBuilder.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\Generic\KnownClassesRepository.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\IReflectArray.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\IReflectClass.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\IReflectClassPredicate.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\IReflectField.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\IReflectMethod.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\IReflector.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\IReflectorConfiguration.cs"/>
+<Compile Include="Db4objects.Db4o\Reflect\MultidimensionalArrayInfo.cs"/>
+<Compile Include="Db4objects.Db4o\Rename.cs"/>
+<Compile Include="Db4objects.Db4o\StaticClass.cs"/>
+<Compile Include="Db4objects.Db4o\StaticField.cs"/>
+<Compile Include="Db4objects.Db4o\TA\DeactivatingRollbackStrategy.cs"/>
+<Compile Include="Db4objects.Db4o\TA\IActivatable.cs"/>
+<Compile Include="Db4objects.Db4o\TA\IActivatableInstrumented.cs"/>
+<Compile Include="Db4objects.Db4o\TA\IRollbackStrategy.cs"/>
+<Compile Include="Db4objects.Db4o\TA\NotTransparentActivationEnabled.cs"/>
+<Compile Include="Db4objects.Db4o\TA\TransactionalActivator.cs"/>
+<Compile Include="Db4objects.Db4o\TA\TransparentActivationSupport.cs"/>
+<Compile Include="Db4objects.Db4o\TA\TransparentPersistenceSupport.cs"/>
+<Compile Include="Db4objects.Db4o\Typehandlers\CollectionTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Typehandlers\IActivationContext.cs"/>
+<Compile Include="Db4objects.Db4o\Typehandlers\ICascadingTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Typehandlers\IInstantiatingTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Typehandlers\IQueryableTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Typehandlers\IReferenceTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Typehandlers\ITypeFamilyTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Typehandlers\ITypeHandler4.cs"/>
+<Compile Include="Db4objects.Db4o\Typehandlers\ITypeHandlerPredicate.cs"/>
+<Compile Include="Db4objects.Db4o\Typehandlers\IValueTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Typehandlers\IgnoreFieldsTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Typehandlers\Internal\KeyValueHandlerPair.cs"/>
+<Compile Include="Db4objects.Db4o\Typehandlers\MapTypeHandler.cs"/>
+<Compile Include="Db4objects.Db4o\Typehandlers\SingleClassTypeHandlerPredicate.cs"/>
+<Compile Include="Db4objects.Db4o\Types\IBlob.cs"/>
+<Compile Include="Db4objects.Db4o\Types\IDb4oType.cs"/>
+<Compile Include="Db4objects.Db4o\Types\ITransientClass.cs"/>
+<Compile Include="Db4objects.Db4o\Types\IUnversioned.cs"/>
+<Compile Include="Db4objects.Db4o\User.cs"/>
+<Compile Include="Properties\AssemblyInfo.cs"/>
+<Compile Include="native\Db4objects.Db4o\Collections\ActivatableDictionary.cs"/>
+<Compile Include="native\Db4objects.Db4o\Collections\ActivatableList.cs"/>
+<Compile Include="native\Db4objects.Db4o\Collections\ArrayDictionary4.cs"/>
+<Compile Include="native\Db4objects.Db4o\Collections\ArrayList4.cs"/>
+<Compile Include="native\Db4objects.Db4o\Collections\IActivatableCollection.cs"/>
+<Compile Include="native\Db4objects.Db4o\Collections\ISet.cs"/>
+<Compile Include="native\Db4objects.Db4o\Config\Attributes\ConfigurationIntrospector.cs"/>
+<Compile Include="native\Db4objects.Db4o\Config\Attributes\IDb4oAttribute.cs"/>
+<Compile Include="native\Db4objects.Db4o\Config\Attributes\IndexedAttribute.cs"/>
+<Compile Include="native\Db4objects.Db4o\Config\TClass.cs"/>
+<Compile Include="native\Db4objects.Db4o\Config\TCultureInfo.cs"/>
+<Compile Include="native\Db4objects.Db4o\Config\TDictionary.cs"/>
+<Compile Include="native\Db4objects.Db4o\Config\TList.cs"/>
+<Compile Include="native\Db4objects.Db4o\Config\TQueue.cs"/>
+<Compile Include="native\Db4objects.Db4o\Config\TStack.cs"/>
+<Compile Include="native\Db4objects.Db4o\Config\TTransient.cs"/>
+<Compile Include="native\Db4objects.Db4o\Config\TType.cs"/>
+<Compile Include="native\Db4objects.Db4o\Defragment\AvailableTypeFilter.cs"/>
+<Compile Include="native\Db4objects.Db4o\Diagnostic\DiagnosticToTrace.cs"/>
+<Compile Include="native\Db4objects.Db4o\Dynamic.cs"/>
+<Compile Include="native\Db4objects.Db4o\Foundation\CRC32.cs"/>
+<Compile Include="native\Db4objects.Db4o\Foundation\Closures4.cs"/>
+<Compile Include="native\Db4objects.Db4o\Foundation\Coercion4.cs"/>
+<Compile Include="native\Db4objects.Db4o\Foundation\Collections\CollectionInitializer.cs"/>
+<Compile Include="native\Db4objects.Db4o\Foundation\Environments.cs"/>
+<Compile Include="native\Db4objects.Db4o\Foundation\IO\File4.cs"/>
+<Compile Include="native\Db4objects.Db4o\Foundation\Iterators.cs"/>
+<Compile Include="native\Db4objects.Db4o\Foundation\My.cs"/>
+<Compile Include="native\Db4objects.Db4o\Foundation\RunnableAction.cs"/>
+<Compile Include="native\Db4objects.Db4o\Foundation\SignatureGenerator.cs"/>
+<Compile Include="native\Db4objects.Db4o\IO\RandomAccessFileFactory.cs"/>
+<Compile Include="native\Db4objects.Db4o\IObjectContainer.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Collections\BigSet.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\ComparerAdaptor.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Config4Impl.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Const4.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Convert\Conversions\DropClassIndexesConversion.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Convert\Conversions\DropDateTimeOffsetClassIndexes_7_12.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Convert\Conversions\DropEnumClassIndexes_7_10.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Convert\Conversions\DropGuidClassIndexes_7_12.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Convert\Conversions\ReindexNetDateTime_7_8.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Encoding\UTF8StringEncoding.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\GenericTypeHandlerPredicate.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Handlers\DateHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Handlers\DateTimeHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Handlers\DateTimeHandler6.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Handlers\DecimalHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Handlers\IntegralTypeHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Handlers\PreparedComparisonFor.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Handlers\SByteHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Handlers\StructHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Handlers\UIntHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Handlers\ULongHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Handlers\UShortHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Handlers\WeakReferenceHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Handlers\WeakReferenceHandlerQueue.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\IInternalObjectContainer.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\LegacyDb4oAssemblyNameMapper.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Marshall\MarshallingConstants0.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\ObjectContainerBase.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\ObjectContainerSession.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Platform4.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Query\EvaluationDelegateWrapper.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Query\GenericObjectSetFacade.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Query\INQOptimizer.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Query\NQOptimizerFactory.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Query\NativeQueryHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Query\ObjectSetFacade.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Query\QueryExecutionHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Query\QueryOptimizationFailureHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Query\SilverlightArrayListExtensions.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\ReflectPlatform.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Reflect\Emitters\AccessorFactory.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Reflect\Emitters\Emitter.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Reflect\Emitters\GetFieldEmitter.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Reflect\Emitters\SetFieldEmitter.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\Reflect\FastNetReflector.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\TagAttribute.cs"/>
+<Compile Include="native\Db4objects.Db4o\Internal\TypeHandlerConfigurationDotNet.cs"/>
+<Compile Include="native\Db4objects.Db4o\Query\EvaluationDelegate.cs"/>
+<Compile Include="native\Db4objects.Db4o\Query\ISodaQueryFactory.cs"/>
+<Compile Include="native\Db4objects.Db4o\Query\PredicatePlatform.cs"/>
+<Compile Include="native\Db4objects.Db4o\Reflect\Net\NetArray.cs"/>
+<Compile Include="native\Db4objects.Db4o\Reflect\Net\NetClass.cs"/>
+<Compile Include="native\Db4objects.Db4o\Reflect\Net\NetConstructor.cs"/>
+<Compile Include="native\Db4objects.Db4o\Reflect\Net\NetField.cs"/>
+<Compile Include="native\Db4objects.Db4o\Reflect\Net\NetMethod.cs"/>
+<Compile Include="native\Db4objects.Db4o\Reflect\Net\NetReflector.cs"/>
+<Compile Include="native\Db4objects.Db4o\TransientAttribute.cs"/>
+<Compile Include="native\Db4objects.Db4o\Typehandlers\CollectionTypeHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Typehandlers\ComparablePreparedComparison.cs"/>
+<Compile Include="native\Db4objects.Db4o\Typehandlers\DateTimeOffsetTypeHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Typehandlers\EnumTypeHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Typehandlers\GenericCollectionTypeHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Typehandlers\GuidTypeHandler.cs"/>
+<Compile Include="native\Db4objects.Db4o\Typehandlers\SystemArrayTypeHandler.cs"/>
+<Compile Include="native\Sharpen\Collections.cs"/>
+<Compile Include="native\Sharpen\IO\BufferedInputStream.cs"/>
+<Compile Include="native\Sharpen\IO\BufferedOutputStream.cs"/>
+<Compile Include="native\Sharpen\IO\ByteArrayInputStream.cs"/>
+<Compile Include="native\Sharpen\IO\ByteArrayOutputStream.cs"/>
+<Compile Include="native\Sharpen\IO\File.cs"/>
+<Compile Include="native\Sharpen\IO\FileInputStream.cs"/>
+<Compile Include="native\Sharpen\IO\FileOutputStream.cs"/>
+<Compile Include="native\Sharpen\IO\IFilenameFilter.cs"/>
+<Compile Include="native\Sharpen\IO\IInputStream.cs"/>
+<Compile Include="native\Sharpen\IO\IOutputStream.cs"/>
+<Compile Include="native\Sharpen\IO\InputStream.cs"/>
+<Compile Include="native\Sharpen\IO\OutputStream.cs"/>
+<Compile Include="native\Sharpen\IO\RandomAccessFile.cs"/>
+<Compile Include="native\Sharpen\IO\StreamAdaptor.cs"/>
+<Compile Include="native\Sharpen\Lang\IdentityHashCodeProvider.cs"/>
+<Compile Include="native\Sharpen\Lang\Reflect.cs"/>
+<Compile Include="native\Sharpen\Lang\Runnable.cs"/>
+<Compile Include="native\Sharpen\Lang\SimpleTypeReference.Silverlight.cs"/>
+<Compile Include="native\Sharpen\Lang\Thread.cs"/>
+<Compile Include="native\Sharpen\Lang\ThreadLocal.cs"/>
+<Compile Include="native\Sharpen\Lang\TypeReference.cs"/>
+<Compile Include="native\Sharpen\Lang\TypeReferenceLexer.cs"/>
+<Compile Include="native\Sharpen\Lang\TypeReferenceParser.cs"/>
+<Compile Include="native\Sharpen\Net\ServerSocket.cs"/>
+<Compile Include="native\Sharpen\Net\Socket.cs"/>
+<Compile Include="native\Sharpen\Net\SocketWrapper.cs"/>
+<Compile Include="native\Sharpen\Runtime.cs"/>
+<Compile Include="native\Sharpen\Text\DecimalFormat.cs"/>
+<Compile Include="native\Sharpen\Util\Arrays.cs"/>
+<Compile Include="native\Sharpen\Util\HashSet.cs"/>
+<Compile Include="native\Sharpen\Util\ISet.cs"/>
+<Compile Include="native\Sharpen\Util\Random.cs"/>
+<Compile Include="native\Silverlight\Db4objects.Db4o\Config\SilverlightSupport.cs"/>
+<Compile Include="native\Silverlight\Db4objects.Db4o\Foundation\IO\File4.cs"/>
+<Compile Include="native\Silverlight\Db4objects.Db4o\IO\IsolatedStorageFileBin.cs"/>
+<Compile Include="native\Silverlight\Db4objects.Db4o\IO\IsolatedStorageStorage.cs"/>
+<Compile Include="native\Silverlight\Db4objects.Db4o\IO\SilverlightIO.cs"/>
+<Compile Include="native\Silverlight\Db4objects.Db4o\Internal\BlobImpl.cs"/>
+<Compile Include="native\Silverlight\System\Collections\ArrayList.cs"/>
+<Compile Include="native\Silverlight\System\Collections\Hashtable.cs"/>
+<Compile Include="native\Silverlight\System\NonSerialized.cs"/>
+<Compile Include="native\Silverlight\System\Serializable.cs"/>
+<Compile Include="native\compact\Lock4.cs"/>
+<Compile Include="native\net\Compat.cs"/>
+<Compile Include="native\net\Lock4.cs"/>
+<Compile Include="native\net\SerializationConstructor.cs"/>
+<Compile Include="native\net\TSerializable.cs"/>
+</ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets"/>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Activation/ActivationPurpose.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Activation/ActivationPurpose.cs
new file mode 100644
index 0000000..bb9cc46
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Activation/ActivationPurpose.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Activation
+{
+	public enum ActivationPurpose
+	{
+		Read,
+		Write
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Activation/IActivator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Activation/IActivator.cs
new file mode 100644
index 0000000..108bdd5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Activation/IActivator.cs
@@ -0,0 +1,33 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Activation;
+
+namespace Db4objects.Db4o.Activation
+{
+	/// <summary>
+	/// Activator interface.<br />
+	/// <br /><br />
+	/// <see cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable</see>
+	/// objects need to have a reference to
+	/// an Activator implementation, which is called
+	/// by Transparent Activation, when a request is received to
+	/// activate the host object.
+	/// </summary>
+	/// <seealso><a href="http://developer.db4o.com/resources/view.aspx/reference/Object_Lifecycle/Activation/Transparent_Activation_Framework">Transparent Activation framework.</a>
+	/// 	</seealso>
+	public interface IActivator
+	{
+		/// <summary>Method to be called to activate the host object.</summary>
+		/// <remarks>Method to be called to activate the host object.</remarks>
+		/// <param name="purpose">
+		/// for which purpose is the object being activated?
+		/// <see cref="ActivationPurpose.Write">ActivationPurpose.Write</see>
+		/// will cause the object
+		/// to be saved on the next
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Commit()">Db4objects.Db4o.IObjectContainer.Commit()
+		/// 	</see>
+		/// operation.
+		/// </param>
+		void Activate(ActivationPurpose purpose);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Collections/ArrayDictionary4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Collections/ArrayDictionary4.cs
new file mode 100644
index 0000000..12da193
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Collections/ArrayDictionary4.cs
@@ -0,0 +1,210 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections.Generic;
+using Db4objects.Db4o.Activation;
+using Sharpen;
+using Sharpen.Util;
+
+namespace Db4objects.Db4o.Collections
+{
+	/// <summary>Transparent activatable IDictionary implementation.
+	/// </summary>
+	/// <remarks>
+	/// Transparent activatable IDictionary implementation. Implements IDictionary interface
+	/// using two arrays to store keys and values.
+	/// <br/>
+	/// <br/>
+	/// When instantiated as a result of a query, all the internal members
+	/// are NOT activated at all. When internal members are required to
+	/// perform an operation, the instance transparently activates all the
+	/// members.
+	/// </remarks>
+	/// <seealso cref="System.Collections.Generic.IDictionary">System.Collections.IDictionary
+	/// </seealso>
+	/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable
+	/// </seealso>
+	public partial class ArrayDictionary4<K, V>
+	{
+		private K[] _keys;
+
+		private V[] _values;
+
+		private int _size;
+
+		[System.NonSerialized]
+		private IActivator _activator;
+
+		/// <summary>
+		/// Initializes a new collection with the initial capacity = 16.
+		/// </summary>
+		public ArrayDictionary4() : this(16)
+		{
+		}
+
+		/// <summary>
+		/// Initializes a collection of the specified initial capacity.
+		/// </summary>
+		public ArrayDictionary4(int initialCapacity)
+		{
+			InitializeBackingArray(initialCapacity);
+		}
+
+		/// <summary>activate basic implementation.</summary>
+		/// <remarks>activate basic implementation.</remarks>
+		/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable</seealso>
+		public virtual void Activate(ActivationPurpose purpose)
+		{
+			if (_activator != null)
+			{
+				_activator.Activate(purpose);
+			}
+		}
+
+		/// <summary>bind basic implementation.</summary>
+		/// <remarks>bind basic implementation.</remarks>
+		/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable</seealso>
+		public virtual void Bind(IActivator activator)
+		{
+			if (_activator == activator)
+			{
+				return;
+			}
+			if (activator != null && _activator != null)
+			{
+				throw new InvalidOperationException();
+			}
+			_activator = activator;
+		}
+
+		/// <summary> System.Collections.Generic.IDictionary implementation but transparently activates
+		/// the members as required.</summary>
+		/// <remarks> System.Collections.Generic.IDictionary implementation but transparently activates
+		/// the members as required.</remarks>
+		/// <seealso cref="System.Collections.Generic.IDictionary"/>
+		/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable
+		/// </seealso>
+		public virtual void Clear()
+		{
+			Activate(ActivationPurpose.Write);
+			_size = 0;
+			Arrays.Fill(_keys, DefaultKeyValue());
+			Arrays.Fill(_values, DefaultValue());
+		}
+
+		private bool ContainsKeyImpl(K key)
+		{
+			Activate(ActivationPurpose.Read);
+			return IndexOfKey(key) != -1;
+		}
+
+		private V ValueAt(int index)
+		{
+			return _values[index];
+		}
+
+		private K KeyAt(int i)
+		{
+			return _keys[i];
+		}
+
+		private V Replace(int index, V value)
+		{
+			V oldValue = ValueAt(index);
+			_values[index] = value;
+			return oldValue;
+		}
+
+		/// <summary> Returns the number of elements in the collection.</summary>
+		/// <remarks> Returns the number of elements in the collection. The collection gets activated. </remarks>
+		/// <seealso cref="System.Collections.Generic.IDictionary"/>
+		/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable
+		/// </seealso>
+		public virtual int Count
+		{
+			get
+			{
+				Activate(ActivationPurpose.Read);
+				return _size;
+			}
+		}
+
+		/// <summary> Returns the values of the collection.</summary>
+		/// <remarks> Returns the values of the collection. The collection gets activated.</remarks>
+		/// <seealso cref="System.Collections.Generic.IDictionary"/>
+		/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable
+		/// </seealso>
+		public virtual ICollection<V> Values
+		{
+			get
+			{
+				Activate(ActivationPurpose.Read);
+				List<V> list = new List<V>();
+				for (int i = 0; i < _size; i++)
+				{
+					list.Add(ValueAt(i));
+				}
+				return list;
+			}
+		}
+
+		/// <summary> Returns the hash code of the collection.</summary>
+		/// <remarks> Returns the hash code of the collection. Collection members
+		/// get activated as required.</remarks>
+		/// <seealso cref="System.Collections.Generic.IDictionary"/>
+		/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable
+		/// </seealso>
+		public override int GetHashCode()
+		{
+			int hashCode = 0;
+			foreach (KeyValuePair<K, V> entry in this)
+			{
+				hashCode += entry.GetHashCode();
+			}
+			return hashCode;
+		}
+
+		private void InitializeBackingArray(int length)
+		{
+			_keys = AllocateKeyStorage(length);
+			_values = AllocateValueStorage(length);
+		}
+
+		private void Insert(K key, V value)
+		{
+			EnsureCapacity();
+			_keys[_size] = key;
+			_values[_size] = value;
+			_size++;
+		}
+
+		private void EnsureCapacity()
+		{
+			if (_size == _keys.Length)
+			{
+				int count = _keys.Length * 2;
+				K[] newKeys = AllocateKeyStorage(count);
+				V[] newValues = AllocateValueStorage(count);
+				System.Array.Copy(_keys, 0, newKeys, 0, _size);
+				System.Array.Copy(_values, 0, newValues, 0, _size);
+				_keys = newKeys;
+				_values = newValues;
+			}
+		}
+
+		private V Delete(int index)
+		{
+			Activate(ActivationPurpose.Write);
+			V value = ValueAt(index);
+			for (int i = index; i < _size - 1; i++)
+			{
+				_keys[i] = _keys[i + 1];
+				_values[i] = _values[i + 1];
+			}
+			_size--;
+			_keys[_size] = DefaultKeyValue();
+			_values[_size] = DefaultValue();
+			return value;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Collections/ArrayList4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Collections/ArrayList4.cs
new file mode 100644
index 0000000..10222ae
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Collections/ArrayList4.cs
@@ -0,0 +1,280 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+#if !SILVERLIGHT
+using System;
+using System.Collections.Generic;
+using Db4objects.Db4o.Activation;
+using Sharpen;
+using Sharpen.Util;
+
+namespace Db4objects.Db4o.Collections
+{
+	/// <summary>Transparent activatable ArrayList implementation.
+	/// </summary>
+	/// <remarks>
+	/// Transparent activatable ArrayList implementation. Implements IList
+	/// interface using an array to store elements. Each ArrayList4 instance
+	/// has a capacity, which indicates the size of the internal array.
+	/// <br/>
+	/// <br/>
+	/// When instantiated as a result of a query, all the internal members
+	/// are NOT activated at all. When internal members are required to
+	/// perform an operation, the instance transparently activates all the
+	/// members.
+	/// </remarks>
+	/// <seealso cref="System.Collections.ArrayList">System.Collections.ArrayList
+	/// </seealso>
+	/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable
+	/// </seealso>
+	public partial class ArrayList4<E>
+	{
+		private E[] elements;
+
+		private int listSize;
+
+		[System.NonSerialized]
+		private IActivator _activator;
+
+		/// <summary>activate basic implementation.</summary>
+		/// <remarks>activate basic implementation.</remarks>
+		/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable</seealso>
+		public virtual void Activate(ActivationPurpose purpose)
+		{
+			if (_activator != null)
+			{
+				_activator.Activate(purpose);
+			}
+		}
+
+		/// <summary>bind basic implementation.</summary>
+		/// <remarks>bind basic implementation.</remarks>
+		/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable</seealso>
+		public virtual void Bind(IActivator activator)
+		{
+			if (_activator == activator)
+			{
+				return;
+			}
+			if (activator != null && _activator != null)
+			{
+				throw new InvalidOperationException();
+			}
+			_activator = activator;
+		}
+
+		/// <summary>
+		/// Initializes a new collection with the initial capacity = 10.
+		/// </summary>
+		public ArrayList4() : this(10)
+		{
+		}
+
+		/// <summary>
+		/// Initializes a collection with the members of the parameter collection.
+		/// </summary>
+		public ArrayList4(ICollection<E> c)
+		{
+			E[] data = CollectionToArray(c);
+			elements = AllocateStorage(data.Length);
+			listSize = data.Length;
+			System.Array.Copy(data, 0, elements, 0, data.Length);
+		}
+
+		/// <summary>
+		/// Initializes a collection of the specified initial capacity.
+		/// </summary>
+		public ArrayList4(int initialCapacity)
+		{
+			if (initialCapacity < 0)
+			{
+				throw new ArgumentException();
+			}
+			elements = AllocateStorage(initialCapacity);
+			listSize = 0;
+		}
+
+		/// <summary> Inserts an element into the collection
+		/// at the specified index. </summary>
+		/// <remarks> Inserts an element into the collection
+		/// at the specified index.</remarks>
+		/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable
+		/// </seealso>
+		internal virtual void Add(int index, E element)
+		{
+			CheckIndex(index, 0, Count);
+			EnsureCapacity(Count + 1);
+			ArrayCopyElements(index, index + 1, listSize - index);
+			elements[index] = element;
+			IncreaseSize(1);
+			MarkModified();
+		}
+
+		private void ArrayCopyElements(int sourceIndex, int targetIndex, int length)
+		{
+			ActivateForWrite();
+			System.Array.Copy(elements, sourceIndex, elements, targetIndex, length);
+		}
+
+		internal bool AddAllImpl(int index, E[] toBeAdded)
+		{
+			CheckIndex(index, 0, Count);
+			int length = toBeAdded.Length;
+			if (length == 0)
+			{
+				return false;
+			}
+			EnsureCapacity(Count + length);
+			ArrayCopyElements(index, index + length, Count - index);
+			System.Array.Copy(toBeAdded, 0, elements, index, length);
+			IncreaseSize(length);
+			MarkModified();
+			return true;
+		}
+
+		/// <summary> Removes all elements from the collection.</summary>
+		/// <remarks> Removes all elements from the collection.</remarks>
+		/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable
+		/// </seealso>
+		public virtual void Clear()
+		{
+			int size = Count;
+			ActivateForWrite();
+			Arrays.Fill(elements, 0, size, DefaultValue());
+			SetSize(0);
+			MarkModified();
+		}
+
+		/// <summary> Resizes the collection capacity to the specified size if the
+		/// current capacity is less than the parameter value.</summary>
+		/// <remarks> Resizes the collection capacity to the specified size if the
+		/// current capacity is less than the parameter value.</remarks>
+		/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable
+		/// </seealso>
+		public virtual void EnsureCapacity(int minCapacity)
+		{
+			Activate(ActivationPurpose.Read);
+			if (minCapacity <= Capacity())
+			{
+				return;
+			}
+			Resize(minCapacity);
+		}
+
+		private int Capacity()
+		{
+			return elements.Length;
+		}
+
+		/// <summary> Returns the collection element at the specified index.</summary>
+		/// <remarks> Returns the collection element at the specified index.</remarks>
+		/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable
+		/// </seealso>
+		public virtual E Get(int index)
+		{
+			CheckIndex(index, 0, Count - 1);
+			return elements[index];
+		}
+
+		/// <summary> Removes the collection element at the specified index.</summary>
+		/// <remarks> Removes the collection element at the specified index.</remarks>
+		/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable
+		/// </seealso>
+		internal virtual E RemoveImpl(int index)
+		{
+			int size = Count;
+			E element = this[index];
+			ArrayCopyElements(index + 1, index, size - index - 1);
+			elements[size - 1] = DefaultValue();
+			DecreaseSize(1);
+			MarkModified();
+			return element;
+		}
+
+		private void RemoveRangeImpl(int fromIndex, int count)
+		{
+			int size = Count;
+			int toIndex = fromIndex + count;
+			if ((fromIndex < 0 || fromIndex >= size || toIndex > size || toIndex < fromIndex))
+			{
+				throw new IndexOutOfRangeException();
+			}
+			if (count == 0)
+			{
+				return;
+			}
+			System.Array.Copy(elements, toIndex, elements, fromIndex, size - toIndex);
+			Arrays.Fill(elements, size - count, size, DefaultValue());
+			DecreaseSize(count);
+			MarkModified();
+		}
+
+		/// <summary> Replaces the collection element with the specified object at the specified index.</summary>
+		/// <remarks> Replaces the collection element with the specified object at the specified index.</remarks>
+		/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable
+		/// </seealso>
+		internal virtual E Set(int index, E element)
+		{
+			E oldValue = this[index];
+			ActivateForWrite();
+			elements[index] = element;
+			return oldValue;
+		}
+
+		/// <summary> Returns the size of the collection.</summary>
+		/// <remarks> Returns the size of the collection.</remarks>
+		/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable
+		/// </seealso>
+		public virtual int Count
+		{
+			get
+			{
+				Activate(ActivationPurpose.Read);
+				return listSize;
+			}
+		}
+
+		/// <summary> Resizes the collection to its actual size.</summary>
+		/// <remarks> Resizes the collection to its actual size.</remarks>
+		/// <seealso cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable
+		/// </seealso>
+		public virtual void TrimExcess()
+		{
+			ActivateForWrite();
+			Resize(Count);
+		}
+
+		private void Resize(int minCapacity)
+		{
+			MarkModified();
+			E[] temp = AllocateStorage(minCapacity);
+			System.Array.Copy(elements, 0, temp, 0, Count);
+			elements = temp;
+		}
+
+		internal virtual void SetSize(int count)
+		{
+			listSize = count;
+		}
+
+		internal virtual void IncreaseSize(int count)
+		{
+			listSize += count;
+		}
+
+		internal virtual void DecreaseSize(int count)
+		{
+			listSize -= count;
+		}
+
+		internal virtual void MarkModified()
+		{
+			++modCount;
+		}
+
+		private void ActivateForWrite()
+		{
+			Activate(ActivationPurpose.Write);
+		}
+	}
+}
+#endif // !SILVERLIGHT
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Collections/CollectionFactory.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Collections/CollectionFactory.cs
new file mode 100644
index 0000000..9cb2759
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Collections/CollectionFactory.cs
@@ -0,0 +1,66 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Collections;
+
+namespace Db4objects.Db4o.Collections
+{
+	/// <summary>
+	/// Collection factory with methods to create collections with behaviour
+	/// that is optimized for db4o.<br/><br/>
+	/// Example usage:<br/>
+	/// <code>CollectionFactory.forObjectContainer(objectContainer).newBigSet();</code>
+	/// </summary>
+	public class CollectionFactory
+	{
+		private readonly IObjectContainer _objectContainer;
+
+		private CollectionFactory(IObjectContainer objectContainer)
+		{
+			_objectContainer = objectContainer;
+		}
+
+		/// <summary>returns a collection factory for an ObjectContainer</summary>
+		/// <param name="objectContainer">- the ObjectContainer</param>
+		/// <returns>the CollectionFactory</returns>
+		public static Db4objects.Db4o.Collections.CollectionFactory ForObjectContainer(IObjectContainer
+			 objectContainer)
+		{
+			if (IsClient(objectContainer))
+			{
+				throw new NotSupportedException("CollectionFactory is not yet available for Client/Server."
+					);
+			}
+			return new Db4objects.Db4o.Collections.CollectionFactory(objectContainer);
+		}
+
+		/// <summary>
+		/// creates a new BigSet.<br/><br/>
+		/// Characteristics of BigSet:<br/>
+		/// - It is optimized by using a BTree of IDs of persistent objects.<br/>
+		/// - It can only hold persistent first class objects (no primitives, no strings, no objects that are not persistent)<br/>
+		/// - Objects are activated upon getting them from the BigSet.
+		/// </summary>
+		/// <remarks>
+		/// creates a new BigSet.<br/><br/>
+		/// Characteristics of BigSet:<br/>
+		/// - It is optimized by using a BTree of IDs of persistent objects.<br/>
+		/// - It can only hold persistent first class objects (no primitives, no strings, no objects that are not persistent)<br/>
+		/// - Objects are activated upon getting them from the BigSet.
+		/// <br/><br/>
+		/// BigSet is recommend whenever one object references a huge number of other objects and sorting is not required.
+		/// </remarks>
+		/// <returns></returns>
+		public virtual Db4objects.Db4o.Collections.ISet<E> NewBigSet<E>()
+		{
+			return new BigSet<E>((LocalObjectContainer)_objectContainer);
+		}
+
+		private static bool IsClient(IObjectContainer oc)
+		{
+			return ((IInternalObjectContainer)oc).IsClient;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ConfigScope.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ConfigScope.cs
new file mode 100644
index 0000000..ddd0ee3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ConfigScope.cs
@@ -0,0 +1,139 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// Defines a scope of applicability of a config setting.<br /><br />
+	/// Some of the configuration settings can be either: <br /><br />
+	/// - enabled globally; <br />
+	/// - enabled individually for a specified class; <br />
+	/// - disabled.<br /><br />
+	/// </summary>
+	/// <seealso cref="IConfiguration.GenerateUUIDs(ConfigScope)">IConfiguration.GenerateUUIDs(ConfigScope)
+	/// 	</seealso>
+	/// <seealso cref="IConfiguration.GenerateVersionNumbers(ConfigScope)">IConfiguration.GenerateVersionNumbers(ConfigScope)
+	/// 	</seealso>
+	[System.Serializable]
+	public sealed class ConfigScope
+	{
+		public const int DisabledId = -1;
+
+		public const int IndividuallyId = 1;
+
+		public const int GloballyId = int.MaxValue;
+
+		private static readonly string DisabledName = "disabled";
+
+		private static readonly string IndividuallyName = "individually";
+
+		private static readonly string GloballyName = "globally";
+
+		/// <summary>Marks a configuration feature as globally disabled.</summary>
+		/// <remarks>Marks a configuration feature as globally disabled.</remarks>
+		public static readonly Db4objects.Db4o.Config.ConfigScope Disabled = new Db4objects.Db4o.Config.ConfigScope
+			(DisabledId, DisabledName);
+
+		/// <summary>Marks a configuration feature as individually configurable.</summary>
+		/// <remarks>Marks a configuration feature as individually configurable.</remarks>
+		public static readonly Db4objects.Db4o.Config.ConfigScope Individually = new Db4objects.Db4o.Config.ConfigScope
+			(IndividuallyId, IndividuallyName);
+
+		/// <summary>Marks a configuration feature as globally enabled.</summary>
+		/// <remarks>Marks a configuration feature as globally enabled.</remarks>
+		public static readonly Db4objects.Db4o.Config.ConfigScope Globally = new Db4objects.Db4o.Config.ConfigScope
+			(GloballyId, GloballyName);
+
+		private readonly int _value;
+
+		private readonly string _name;
+
+		private ConfigScope(int value, string name)
+		{
+			_value = value;
+			_name = name;
+		}
+
+		/// <summary>
+		/// Checks if the current configuration scope is globally
+		/// enabled or disabled.
+		/// </summary>
+		/// <remarks>
+		/// Checks if the current configuration scope is globally
+		/// enabled or disabled.
+		/// </remarks>
+		/// <param name="defaultValue">- default result</param>
+		/// <returns>
+		/// false if disabled, true if globally enabled, default
+		/// value otherwise
+		/// </returns>
+		public bool ApplyConfig(TernaryBool defaultValue)
+		{
+			switch (_value)
+			{
+				case DisabledId:
+				{
+					return false;
+				}
+
+				case GloballyId:
+				{
+					return !defaultValue.DefiniteNo();
+				}
+
+				default:
+				{
+					return defaultValue.DefiniteYes();
+					break;
+				}
+			}
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj)
+			{
+				return true;
+			}
+			if (obj == null || GetType() != obj.GetType())
+			{
+				return false;
+			}
+			Db4objects.Db4o.Config.ConfigScope tb = (Db4objects.Db4o.Config.ConfigScope)obj;
+			return _value == tb._value;
+		}
+
+		public override int GetHashCode()
+		{
+			return _value;
+		}
+
+		private object ReadResolve()
+		{
+			switch (_value)
+			{
+				case DisabledId:
+				{
+					return Disabled;
+				}
+
+				case IndividuallyId:
+				{
+					return Individually;
+				}
+
+				default:
+				{
+					return Globally;
+					break;
+				}
+			}
+		}
+
+		public override string ToString()
+		{
+			return _name;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/Encoding/IStringEncoding.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/Encoding/IStringEncoding.cs
new file mode 100644
index 0000000..3df0635
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/Encoding/IStringEncoding.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Config.Encoding
+{
+	/// <summary>
+	/// encodes a String to a byte array and decodes a String
+	/// from a part of a byte array
+	/// </summary>
+	public interface IStringEncoding
+	{
+		/// <summary>called when a string is to be encoded to a byte array.</summary>
+		/// <remarks>called when a string is to be encoded to a byte array.</remarks>
+		/// <param name="str">the string to encode</param>
+		/// <returns>the encoded byte array</returns>
+		byte[] Encode(string str);
+
+		/// <summary>called when a byte array is to be decoded to a string.</summary>
+		/// <remarks>called when a byte array is to be decoded to a string.</remarks>
+		/// <param name="bytes">the byte array</param>
+		/// <param name="start">the start offset in the byte array</param>
+		/// <param name="length">the length of the encoded string in the byte array</param>
+		/// <returns>the string</returns>
+		string Decode(byte[] bytes, int start, int length);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/Encoding/StringEncodings.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/Encoding/StringEncodings.cs
new file mode 100644
index 0000000..9d48fde
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/Encoding/StringEncodings.cs
@@ -0,0 +1,28 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config.Encoding;
+using Db4objects.Db4o.Internal.Encoding;
+
+namespace Db4objects.Db4o.Config.Encoding
+{
+	/// <summary>All built in String encodings</summary>
+	/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.StringEncoding(IStringEncoding)
+	/// 	">Db4objects.Db4o.Config.IConfiguration.StringEncoding(IStringEncoding)</seealso>
+	public class StringEncodings
+	{
+		public static IStringEncoding Utf8()
+		{
+			return new UTF8StringEncoding();
+		}
+
+		public static IStringEncoding Unicode()
+		{
+			return new UnicodeStringEncoding();
+		}
+
+		public static IStringEncoding Latin()
+		{
+			return new LatinStringEncoding();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/Entry.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/Entry.cs
new file mode 100644
index 0000000..6ba93bb
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/Entry.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <exclude></exclude>
+	public class Entry : ICompare, IInternal4
+	{
+		public object key;
+
+		public object value;
+
+		public virtual object Compare()
+		{
+			return key;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/GlobalOnlyConfigException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/GlobalOnlyConfigException.cs
new file mode 100644
index 0000000..932b581
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/GlobalOnlyConfigException.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when a global configuration
+	/// setting is attempted on an open object container.
+	/// </summary>
+	/// <remarks>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when a global configuration
+	/// setting is attempted on an open object container.
+	/// </remarks>
+	/// <seealso cref="IConfiguration.BlockSize(int)">IConfiguration.BlockSize(int)</seealso>
+	/// <seealso cref="IConfiguration.Encrypt(bool)">IConfiguration.Encrypt(bool)</seealso>
+	/// <seealso cref="IConfiguration.Io(Db4objects.Db4o.IO.IoAdapter)">IConfiguration.Io(Db4objects.Db4o.IO.IoAdapter)
+	/// 	</seealso>
+	/// <seealso cref="IConfiguration.Password(string)">IConfiguration.Password(string)</seealso>
+	[System.Serializable]
+	public class GlobalOnlyConfigException : Db4oRecoverableException
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IAlias.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IAlias.cs
new file mode 100644
index 0000000..0e66ea1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IAlias.cs
@@ -0,0 +1,73 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// Implement this interface when implementing special custom Aliases
+	/// for classes, packages or namespaces.
+	/// 
+	/// </summary>
+	/// <remarks>
+	/// Implement this interface when implementing special custom Aliases
+	/// for classes, packages or namespaces.
+	/// <br/><br/>Aliases can be used to persist classes in the running
+	/// application to different persistent classes in a database file
+	/// or on a db4o server.
+	/// <br/><br/>Two simple Alias implementations are supplied along with
+	/// db4o:<br/>
+	/// -
+	/// <see cref="TypeAlias">TypeAlias</see>
+	/// provides an #equals() resolver to match
+	/// names directly.<br/>
+	/// -
+	/// <see cref="WildcardAlias">WildcardAlias</see>
+	/// allows simple pattern matching
+	/// with one single '*' wildcard character.<br/>
+	/// <br/>
+	/// It is possible to create
+	/// own complex
+	/// <see cref="IAlias">IAlias</see>
+	/// constructs by creating own resolvers
+	/// that implement the
+	/// <see cref="IAlias">IAlias</see>
+	/// interface.
+	/// <br/><br/>
+	/// Examples of concrete usecases:
+	/// <br/><br/>
+	/// <code>
+	/// <b>// Creating an Alias for a single class</b><br/>
+	/// ICommonConfiguration.AddAlias(<br/>
+	///   new TypeAlias("Tutorial.Pilot", "Tutorial.Driver"));<br/>
+	/// <br/><br/>
+	/// <b>// Accessing a Java package from a .NET assembly </b><br/>
+	/// ICommonConfiguration.AddAlias(<br/>
+	///   new WildcardAlias(<br/>
+	///     "com.f1.*",<br/>
+	///     "Tutorial.F1.*, Tutorial"));<br/>
+	/// <br/><br/>
+	/// <b>// Using a different local .NET assembly</b><br/>
+	/// ICommonConfiguration.AddAlias(<br/>
+	///   new WildcardAlias(<br/>
+	///     "Tutorial.F1.*, F1Race",<br/>
+	///     "Tutorial.F1.*, Tutorial"));<br/>
+	/// <br/><br/>
+	/// </code>
+	/// <br/><br/>Aliases that translate the persistent name of a class to
+	/// a name that already exists as a persistent name in the database
+	/// (or on the server) are not permitted and will throw an exception
+	/// when the database file is opened.
+	/// <br/><br/>Aliases should be configured before opening a database file
+	/// or connecting to a server.
+	/// 
+	/// </remarks>
+	public interface IAlias
+	{
+		/// <summary>return the stored name for a runtime name or null if not handled.</summary>
+		/// <remarks>return the stored name for a runtime name or null if not handled.</remarks>
+		string ResolveRuntimeName(string runtimeTypeName);
+
+		/// <summary>return the runtime name for a stored name or null if not handled.</summary>
+		/// <remarks>return the runtime name for a stored name or null if not handled.</remarks>
+		string ResolveStoredName(string storedTypeName);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ICacheConfiguration.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ICacheConfiguration.cs
new file mode 100644
index 0000000..5851c0e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ICacheConfiguration.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>Interface to configure the cache configurations.</summary>
+	/// <remarks>Interface to configure the cache configurations.</remarks>
+	public interface ICacheConfiguration
+	{
+		/// <summary>
+		/// configures the size of the slot cache to hold a number of
+		/// slots in the cache.
+		/// </summary>
+		/// <remarks>
+		/// configures the size of the slot cache to hold a number of
+		/// slots in the cache.
+		/// </remarks>
+		/// <value>the number of slots</value>
+		[System.ObsoleteAttribute(@"since 7.14 BTrees have their own LRU cache now.")]
+		int SlotCacheSize
+		{
+			set;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ICacheConfigurationProvider.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ICacheConfigurationProvider.cs
new file mode 100644
index 0000000..f7bc0cc
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ICacheConfigurationProvider.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// A configuration provider that provides access
+	/// to the cache-related configuration methods.
+	/// </summary>
+	/// <remarks>
+	/// A configuration provider that provides access
+	/// to the cache-related configuration methods.
+	/// </remarks>
+	public interface ICacheConfigurationProvider
+	{
+		/// <summary>Access to the cache-related configuration methods.</summary>
+		/// <remarks>Access to the cache-related configuration methods.</remarks>
+		ICacheConfiguration Cache
+		{
+			get;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IClientServerConfiguration.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IClientServerConfiguration.cs
new file mode 100644
index 0000000..e1b9c6b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IClientServerConfiguration.cs
@@ -0,0 +1,152 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Messaging;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>Client/Server configuration interface.</summary>
+	/// <remarks>Client/Server configuration interface.</remarks>
+	public interface IClientServerConfiguration
+	{
+		/// <summary>
+		/// Sets the number of IDs to be pre-allocated in the database for new
+		/// objects created on the client.
+		/// </summary>
+		/// <remarks>
+		/// Sets the number of IDs to be pre-allocated in the database for new
+		/// objects created on the client.
+		/// This setting should be used on the client side. In embedded mode this setting
+		/// has no effect.
+		/// </remarks>
+		/// <param name="prefetchIDCount">The number of IDs to be prefetched</param>
+		void PrefetchIDCount(int prefetchIDCount);
+
+		/// <summary>Sets the number of objects to be prefetched for an ObjectSet.</summary>
+		/// <remarks>
+		/// Sets the number of objects to be prefetched for an ObjectSet.
+		/// This setting should be used on the server side.
+		/// </remarks>
+		/// <param name="prefetchObjectCount">The number of objects to be prefetched</param>
+		void PrefetchObjectCount(int prefetchObjectCount);
+
+		/// <summary>Sets the depth to which prefetched objects are activated.</summary>
+		/// <remarks>
+		/// Sets the depth to which prefetched objects are activated.
+		/// This setting should be used on the client side.
+		/// </remarks>
+		/// <param name="prefetchDepth"></param>
+		void PrefetchDepth(int prefetchDepth);
+
+		/// <summary>Sets the slot cache size to the given value.</summary>
+		/// <remarks>Sets the slot cache size to the given value.</remarks>
+		/// <param name="slotCacheSize"></param>
+		void PrefetchSlotCacheSize(int slotCacheSize);
+
+		/// <summary>sets the MessageRecipient to receive Client Server messages.</summary>
+		/// <remarks>
+		/// sets the MessageRecipient to receive Client Server messages. <br />
+		/// <br />
+		/// This setting should be used on the server side.<br /><br />
+		/// </remarks>
+		/// <param name="messageRecipient">the MessageRecipient to be used</param>
+		void SetMessageRecipient(IMessageRecipient messageRecipient);
+
+		/// <summary>returns the MessageSender for this Configuration context.</summary>
+		/// <remarks>
+		/// returns the MessageSender for this Configuration context.
+		/// This setting should be used on the client side.
+		/// </remarks>
+		/// <returns>MessageSender</returns>
+		IMessageSender GetMessageSender();
+
+		/// <summary>
+		/// configures the time a client waits for a message response
+		/// from the server.
+		/// </summary>
+		/// <remarks>
+		/// configures the time a client waits for a message response
+		/// from the server. <br />
+		/// <br />
+		/// Default value: 600000ms (10 minutes)<br />
+		/// <br />
+		/// It is recommended to use the same values for
+		/// <see cref="TimeoutClientSocket(int)">TimeoutClientSocket(int)</see>
+		/// and
+		/// <see cref="TimeoutServerSocket(int)">TimeoutServerSocket(int)</see>
+		/// .
+		/// <br />
+		/// This setting can be used on both client and server.<br /><br />
+		/// </remarks>
+		/// <param name="milliseconds">time in milliseconds</param>
+		void TimeoutClientSocket(int milliseconds);
+
+		/// <summary>configures the timeout of the serverside socket.</summary>
+		/// <remarks>
+		/// configures the timeout of the serverside socket. <br />
+		/// <br />
+		/// The serverside handler waits for messages to arrive from the client.
+		/// If no more messages arrive for the duration configured in this
+		/// setting, the client will be disconnected.
+		/// <br />
+		/// Clients send PING messages to the server at an interval of
+		/// Math.min(timeoutClientSocket(), timeoutServerSocket()) / 2
+		/// and the server will respond to keep connections alive.
+		/// <br />
+		/// Decrease this setting if you want clients to disconnect faster.
+		/// <br />
+		/// Increase this setting if you have a large number of clients and long
+		/// running queries and you are getting disconnected clients that you
+		/// would like to wait even longer for a response from the server.
+		/// <br />
+		/// Default value: 600000ms (10 minutes)<br />
+		/// <br />
+		/// It is recommended to use the same values for
+		/// <see cref="TimeoutClientSocket(int)">TimeoutClientSocket(int)</see>
+		/// and
+		/// <see cref="TimeoutServerSocket(int)">TimeoutServerSocket(int)</see>
+		/// .
+		/// <br />
+		/// This setting can be used on both client and server.<br /><br />
+		/// </remarks>
+		/// <param name="milliseconds">time in milliseconds</param>
+		void TimeoutServerSocket(int milliseconds);
+
+		/// <summary>
+		/// configures the client messaging system to be single threaded
+		/// or multithreaded.
+		/// </summary>
+		/// <remarks>
+		/// configures the client messaging system to be single threaded
+		/// or multithreaded.
+		/// <br /><br />Recommended settings:<br />
+		/// - <code>true</code> for low resource systems.<br />
+		/// - <code>false</code> for best asynchronous performance and fast
+		/// GUI response.
+		/// <br /><br />Default value:<br />
+		/// - .NET Compactframework: <code>true</code><br />
+		/// - all other platforms: <code>false</code><br /><br />
+		/// This setting can be used on both client and server.<br /><br />
+		/// </remarks>
+		/// <param name="flag">the desired setting</param>
+		void SingleThreadedClient(bool flag);
+
+		/// <summary>Configures to batch messages between client and server.</summary>
+		/// <remarks>
+		/// Configures to batch messages between client and server. By default, batch
+		/// mode is enabled.<br /><br />
+		/// This setting can be used on both client and server.<br /><br />
+		/// </remarks>
+		/// <param name="flag">false, to turn message batching off.</param>
+		void BatchMessages(bool flag);
+
+		/// <summary>Configures the maximum memory buffer size for batched message.</summary>
+		/// <remarks>
+		/// Configures the maximum memory buffer size for batched message. If the
+		/// size of batched messages is greater than <code>maxSize</code>, batched
+		/// messages will be sent to server.<br /><br />
+		/// This setting can be used on both client and server.<br /><br />
+		/// </remarks>
+		/// <param name="maxSize"></param>
+		void MaxBatchQueueSize(int maxSize);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ICommonConfiguration.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ICommonConfiguration.cs
new file mode 100644
index 0000000..7575de1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ICommonConfiguration.cs
@@ -0,0 +1,656 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.IO;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Config.Encoding;
+using Db4objects.Db4o.Diagnostic;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// Common configuration methods, applicable for
+	/// embedded, client and server use of db4o.<br /><br />
+	/// In Client/Server use it is good practice to configure the
+	/// client and the server in exactly the same way.
+	/// </summary>
+	/// <remarks>
+	/// Common configuration methods, applicable for
+	/// embedded, client and server use of db4o.<br /><br />
+	/// In Client/Server use it is good practice to configure the
+	/// client and the server in exactly the same way.
+	/// </remarks>
+	/// <since>7.5</since>
+	public interface ICommonConfiguration
+	{
+		/// <summary>adds a new Alias for a class, namespace or package.</summary>
+		/// <remarks>
+		/// adds a new Alias for a class, namespace or package.
+		/// <br /><br />Aliases can be used to persist classes in the running
+		/// application to different persistent classes in a database file
+		/// or on a db4o server.
+		/// <br /><br />Two simple Alias implementations are supplied along with
+		/// db4o:<br />
+		/// -
+		/// <see cref="TypeAlias">TypeAlias</see>
+		/// provides an #equals() resolver to match
+		/// names directly.<br />
+		/// -
+		/// <see cref="WildcardAlias">WildcardAlias</see>
+		/// allows simple pattern matching
+		/// with one single '*' wildcard character.<br />
+		/// <br />
+		/// It is possible to create
+		/// own complex
+		/// <see cref="IAlias">IAlias</see>
+		/// constructs by creating own resolvers
+		/// that implement the
+		/// <see cref="IAlias">IAlias</see>
+		/// interface.
+		/// <br /><br />
+		/// Examples of concrete usecases:
+		/// <br /><br />
+		/// <code>
+		/// <b>// Creating an Alias for a single class</b><br />
+		/// Db4o.configure().addAlias(<br />
+		///   new TypeAlias("com.f1.Pilot", "com.f1.Driver"));<br />
+		/// <br /><br />
+		/// <b>// Accessing a .NET assembly from a Java package</b><br />
+		/// Db4o.configure().addAlias(<br />
+		///   new WildcardAlias(<br />
+		///     "Tutorial.F1.*, Tutorial",<br />
+		///     "com.f1.*"));<br />
+		/// <br /><br />
+		/// <b>// Mapping a Java package onto another</b><br />
+		/// Db4o.configure().addAlias(<br />
+		///   new WildcardAlias(<br />
+		///     "com.f1.*",<br />
+		///     "com.f1.client*"));<br /></code>
+		/// <br /><br />Aliases that translate the persistent name of a class to
+		/// a name that already exists as a persistent name in the database
+		/// (or on the server) are not permitted and will throw an exception
+		/// when the database file is opened.
+		/// <br /><br />Aliases should be configured before opening a database file
+		/// or connecting to a server.<br /><br />
+		/// In client/server environment it is good practice to configure the
+		/// client and the server in exactly the same way.
+		/// </remarks>
+		void AddAlias(IAlias alias);
+
+		/// <summary>
+		/// Removes an alias previously added with
+		/// <see cref="IConfiguration.AddAlias(IAlias)">IConfiguration.AddAlias(IAlias)</see>
+		/// .
+		/// </summary>
+		/// <param name="alias">the alias to remove</param>
+		void RemoveAlias(IAlias alias);
+
+		/// <summary>sets the activation depth to the specified value.</summary>
+		/// <remarks>
+		/// sets the activation depth to the specified value.
+		/// <br/><br/><b>Why activation?</b><br/>
+		/// When objects are instantiated from the database, the instantiation of member
+		/// objects needs to be limited to a certain depth. Otherwise a single object
+		/// could lead to loading the complete database into memory, if all objects where
+		/// reachable from a single root object.<br/><br/>
+		/// db4o uses the concept "depth", the number of field-to-field hops an object
+		/// is away from another object. <b>The preconfigured "activation depth" db4o uses
+		/// in the default setting is 5.</b>
+		/// <br/><br/>Whenever an application iterates through the
+		/// <see cref="Db4objects.Db4o.IObjectSet">IObjectSet</see>
+		/// of a query result, the result objects
+		/// will be activated to the configured activation depth.<br/><br/>
+		/// A concrete example with the preconfigured activation depth of 5:<br/>
+		/// <pre>
+		/// // Object foo is the result of a query, it is delivered by the ObjectSet
+		/// object foo = objectSet.Next();</pre>
+		/// foo.member1.member2.member3.member4.member5 will be a valid object<br/>
+		/// foo, member1, member2, member3 and member4 will be activated<br/>
+		/// member5 will be deactivated, all of it's members will be null<br/>
+		/// member5 can be activated at any time by calling
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Activate">IObjectContainer.Activate(member5, depth)
+		/// </see>
+		/// .
+		/// <br/><br/>
+		/// Note that raising the global activation depth will consume more memory and
+		/// have negative effects on the performance of first-time retrievals. Lowering
+		/// the global activation depth needs more individual activation work but can
+		/// increase performance of queries.<br/><br/>
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Deactivate">IObjectContainer.Deactivate(object, depth)
+		/// </see>
+		/// can be used to manually free memory by deactivating objects.<br/><br/>
+		/// In client/server environment it is good practice to configure the
+		/// client and the server in exactly the same way. <br/><br/>.
+		/// </remarks>
+		/// <seealso cref="Db4objects.Db4o.Config.IObjectClass.MaximumActivationDepth">configuring classes individually
+		/// </seealso>
+		/// <summary>gets the configured activation depth.</summary>
+		/// <summary>sets the activation depth to the specified value.</summary>
+		/// <remarks>
+		/// sets the activation depth to the specified value.
+		/// <br/><br/><b>Why activation?</b><br/>
+		/// When objects are instantiated from the database, the instantiation of member
+		/// objects needs to be limited to a certain depth. Otherwise a single object
+		/// could lead to loading the complete database into memory, if all objects where
+		/// reachable from a single root object.<br/><br/>
+		/// db4o uses the concept "depth", the number of field-to-field hops an object
+		/// is away from another object. <b>The preconfigured "activation depth" db4o uses
+		/// in the default setting is 5.</b>
+		/// <br/><br/>Whenever an application iterates through the
+		/// <see cref="Db4objects.Db4o.IObjectSet">IObjectSet</see>
+		/// of a query result, the result objects
+		/// will be activated to the configured activation depth.<br/><br/>
+		/// A concrete example with the preconfigured activation depth of 5:<br/>
+		/// <pre>
+		/// // Object foo is the result of a query, it is delivered by the ObjectSet
+		/// object foo = objectSet.Next();</pre>
+		/// foo.member1.member2.member3.member4.member5 will be a valid object<br/>
+		/// foo, member1, member2, member3 and member4 will be activated<br/>
+		/// member5 will be deactivated, all of it's members will be null<br/>
+		/// member5 can be activated at any time by calling
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Activate">IObjectContainer.Activate(member5, depth)
+		/// </see>
+		/// .
+		/// <br/><br/>
+		/// Note that raising the global activation depth will consume more memory and
+		/// have negative effects on the performance of first-time retrievals. Lowering
+		/// the global activation depth needs more individual activation work but can
+		/// increase performance of queries.<br/><br/>
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Deactivate">IObjectContainer.Deactivate(object, depth)
+		/// </see>
+		/// can be used to manually free memory by deactivating objects.<br/><br/>
+		/// In client/server environment it is good practice to configure the
+		/// client and the server in exactly the same way. <br/><br/>.
+		/// </remarks>
+		/// <seealso cref="Db4objects.Db4o.Config.IObjectClass.MaximumActivationDepth">configuring classes individually
+		/// </seealso>
+		/// <summary>gets the configured activation depth.</summary>
+		int ActivationDepth
+		{
+			get;
+			set;
+		}
+
+		/// <summary>
+		/// adds ConfigurationItems to be applied when
+		/// an ObjectContainer or ObjectServer is opened.
+		/// </summary>
+		/// <remarks>
+		/// adds ConfigurationItems to be applied when
+		/// an ObjectContainer or ObjectServer is opened.
+		/// </remarks>
+		/// <param name="configurationItem">the ConfigurationItem</param>
+		void Add(IConfigurationItem configurationItem);
+
+		/// <summary>turns automatic database file format version updates on.</summary>
+		/// <remarks>
+		/// turns automatic database file format version updates on.
+		/// <br /><br />Upon db4o database file format version changes,
+		/// db4o can automatically update database files to the
+		/// current version. db4objects does not provide functionality
+		/// to reverse this process. It is not ensured that updated
+		/// database files can be read with older db4o versions.
+		/// In some cases (Example: using ObjectManager) it may not be
+		/// desirable to update database files automatically therefore
+		/// automatic updating is turned off by default for
+		/// security reasons.
+		/// <br /><br />Call this method to turn automatic database file
+		/// version updating on.
+		/// <br /><br />If automatic updating is turned off, db4o will refuse
+		/// to open database files that use an older database file format.<br /><br />
+		/// In client/server environment it is good practice to configure the
+		/// client and the server in exactly the same way.
+		/// </remarks>
+		bool AllowVersionUpdates
+		{
+			set;
+		}
+
+		/// <summary>turns automatic shutdown of the engine on and off.</summary>
+		/// <remarks>
+		/// turns automatic shutdown of the engine on and off.
+		/// The default and recommended setting is <code>true</code>.<br/><br/>
+		/// </remarks>
+		bool AutomaticShutDown
+		{
+			set;
+		}
+
+		/// <summary>configures the size of BTree nodes in indexes.</summary>
+		/// <remarks>
+		/// configures the size of BTree nodes in indexes.
+		/// <br /><br />Default setting: 100
+		/// <br />Lower values will allow a lower memory footprint
+		/// and more efficient reading and writing of small slots.
+		/// <br />Higher values will reduce the overall number of
+		/// read and write operations and allow better performance
+		/// at the cost of more RAM use.<br /><br />
+		/// In client/server environment it is good practice to configure the
+		/// client and the server in exactly the same way.
+		/// </remarks>
+		/// <value>the number of elements held in one BTree node.</value>
+		int BTreeNodeSize
+		{
+			set;
+		}
+
+		/// <summary>turns callback methods on and off.</summary>
+		/// <remarks>
+		/// turns callback methods on and off.
+		/// <br /><br />Callbacks are turned on by default.<br /><br />
+		/// A tuning hint: If callbacks are not used, you can turn this feature off, to
+		/// prevent db4o from looking for callback methods in persistent classes. This will
+		/// increase the performance on system startup.<br /><br />
+		/// In a client/server environment it is good practice to configure the
+		/// client and the server in exactly the same way.
+		/// </remarks>
+		/// <value>false to turn callback methods off</value>
+		/// <seealso cref="Db4objects.Db4o.Ext.IObjectCallbacks">Using callbacks</seealso>
+		bool Callbacks
+		{
+			set;
+		}
+
+		/// <summary>
+		/// advises db4o to try instantiating objects with/without calling
+		/// constructors.
+		/// </summary>
+		/// <remarks>
+		/// advises db4o to try instantiating objects with/without calling
+		/// constructors.
+		/// <br/><br/>
+		/// Not all .NET-environments support this feature. db4o will
+		/// attempt, to follow the setting as good as the enviroment supports.
+		/// This setting may also be overridden for individual classes in
+		/// <see cref="Db4objects.Db4o.Config.IObjectClass.CallConstructor">Db4objects.Db4o.Config.IObjectClass.CallConstructor
+		/// </see>
+		/// .
+		/// <br/><br/>The default setting depends on the features supported by your current environment.<br/><br/>
+		/// In a client/server environment it is good practice to configure the
+		/// client and the server in exactly the same way.
+		/// <br/><br/>
+		/// </remarks>
+		/// <seealso cref="Db4objects.Db4o.Config.IObjectClass.CallConstructor">Db4objects.Db4o.Config.IObjectClass.CallConstructor
+		/// </seealso>
+		bool CallConstructors
+		{
+			set;
+		}
+
+		/// <summary>
+		/// tuning feature: configures whether db4o checks all persistent classes upon system
+		/// startup, for added or removed fields.
+		/// </summary>
+		/// <remarks>
+		/// tuning feature: configures whether db4o checks all persistent classes upon system
+		/// startup, for added or removed fields.
+		/// <br /><br />If this configuration setting is set to false while a database is
+		/// being created, members of classes will not be detected and stored.
+		/// <br /><br />This setting can be set to false in a production environment after
+		/// all persistent classes have been stored at least once and classes will not
+		/// be modified any further in the future.<br /><br />
+		/// In a client/server environment it is good practice to configure the
+		/// client and the server in exactly the same way.
+		/// <br /><br />Default value:<br />
+		/// <code>true</code>
+		/// </remarks>
+		/// <value>the desired setting</value>
+		bool DetectSchemaChanges
+		{
+			set;
+		}
+
+		/// <summary>returns the configuration interface for diagnostics.</summary>
+		/// <remarks>returns the configuration interface for diagnostics.</remarks>
+		/// <returns>the configuration interface for diagnostics.</returns>
+		IDiagnosticConfiguration Diagnostic
+		{
+			get;
+		}
+
+		/// <summary>configures whether Exceptions are to be thrown, if objects can not be stored.
+		/// 	</summary>
+		/// <remarks>
+		/// configures whether Exceptions are to be thrown, if objects can not be stored.
+		/// <br /><br />db4o requires the presence of a constructor that can be used to
+		/// instantiate objects. If no default public constructor is present, all
+		/// available constructors are tested, whether an instance of the class can
+		/// be instantiated. Null is passed to all constructor parameters.
+		/// The first constructor that is successfully tested will
+		/// be used throughout the running db4o session. If an instance of the class
+		/// can not be instantiated, the object will not be stored. By default,
+		/// execution will be stopped with an Exception. This method can
+		/// be used to configure db4o to not throw an
+		/// <see cref="Db4objects.Db4o.Ext.ObjectNotStorableException">ObjectNotStorableException
+		/// 	</see>
+		/// if an object can not be stored.
+		/// <br /><br />
+		/// The default for this setting is <b>true</b>.<br /><br />
+		/// In a client/server environment it is good practice to configure the
+		/// client and the server in exactly the same way.<br /><br />
+		/// </remarks>
+		/// <value>true to throw Exceptions if objects can not be stored.</value>
+		bool ExceptionsOnNotStorable
+		{
+			set;
+		}
+
+		/// <summary>configures db4o to call Intern() on strings upon retrieval.</summary>
+		/// <remarks>
+		/// configures db4o to call Intern on strings upon retrieval if set to true.
+		/// In client/server environment the setting should be used on both
+		/// client and server.
+		/// </remarks>
+		bool InternStrings
+		{
+			set;
+		}
+
+		// TODO: refactor to use provider?
+		/// <summary>allows to mark fields as transient with custom attributes.</summary>
+		/// <remarks>
+		/// allows to mark fields as transient with custom attributes.
+		/// <br /><br />.NET only: Call this method with the attribute name that you
+		/// wish to use to mark fields as transient. Multiple transient attributes
+		/// are possible by calling this method multiple times with different
+		/// attribute names.<br /><br />
+		/// In a client/server environment it is good practice to configure the
+		/// client and the server in exactly the same way. <br /><br />
+		/// </remarks>
+		/// <param name="attributeName">
+		/// - the fully qualified name of the attribute, including
+		/// it's namespace
+		/// TODO: can we provide meaningful java side semantics for this one?
+		/// TODO: USE A CLASS!!!!!!
+		/// </param>
+		void MarkTransient(string attributeName);
+
+		/// <summary>sets the detail level of db4o messages.</summary>
+		/// <remarks>
+		/// sets the detail level of db4o messages. Messages will be output to the
+		/// configured output
+		/// <see cref="System.IO.TextWriter">TextWriter</see>
+		/// .
+		/// <br /><br />
+		/// Level 0 - no messages<br />
+		/// Level 1 - open and close messages<br />
+		/// Level 2 - messages for new, update and delete<br />
+		/// Level 3 - messages for activate and deactivate<br /><br />
+		/// When using client-server and the level is set to 0, the server will override this and set it to 1.  To get around this you can set the level to -1.  This has the effect of not returning any messages.<br /><br />
+		/// In client-server environment this setting can be used on client or on server
+		/// depending on which information do you want to track (server side provides more
+		/// detailed information).<br /><br />
+		/// </remarks>
+		/// <value>integer from 0 to 3</value>
+		/// <seealso cref="OutStream(System.IO.TextWriter)">TODO: replace int with enumeration
+		/// 	</seealso>
+		int MessageLevel
+		{
+			set;
+		}
+
+		/// <summary>
+		/// returns an
+		/// <see cref="IObjectClass">IObjectClass</see>
+		/// object
+		/// to configure the specified class.
+		/// <br /><br />
+		/// The clazz parameter can be any of the following:<br />
+		/// - a fully qualified classname as a String.<br />
+		/// - a Class object.<br />
+		/// - any other object to be used as a template.<br /><br />
+		/// </summary>
+		/// <param name="clazz">class name, Class object, or example object.<br /><br /></param>
+		/// <returns>
+		/// an instance of an
+		/// <see cref="IObjectClass">IObjectClass</see>
+		/// object for configuration.
+		/// </returns>
+		IObjectClass ObjectClass(object clazz);
+
+		/// <summary>
+		/// If set to true, db4o will try to optimize native queries
+		/// dynamically at query execution time, otherwise it will
+		/// run native queries in unoptimized mode as SODA evaluations.
+		/// </summary>
+		/// <remarks>
+		/// If set to true, db4o will try to optimize native queries
+		/// dynamically at query execution time, otherwise it will
+		/// run native queries in unoptimized mode as SODA evaluations.
+		/// The following assemblies should be available for native query switch to take effect:
+		/// Db4objects.Db4o.NativeQueries.dll, Db4objects.Db4o.Instrumentation.dll.
+		/// <br/><br/>The default setting is <code>true</code>.<br/><br/>
+		/// In a client/server environment it is good practice to configure the
+		/// client and the server in exactly the same way. <br/><br/>
+		/// </remarks>
+		/// <seealso cref="Db4objects.Db4o.Config.ICommonConfiguration.OptimizeNativeQueries">Db4objects.Db4o.Config.ICommonConfiguration.OptimizeNativeQueries</seealso>
+		/// <summary>
+		/// If set to true, db4o will try to optimize native queries
+		/// dynamically at query execution time, otherwise it will
+		/// run native queries in unoptimized mode as SODA evaluations.
+		/// </summary>
+		/// <remarks>
+		/// If set to true, db4o will try to optimize native queries
+		/// dynamically at query execution time, otherwise it will
+		/// run native queries in unoptimized mode as SODA evaluations.
+		/// The following assemblies should be available for native query switch to take effect:
+		/// Db4objects.Db4o.NativeQueries.dll, Db4objects.Db4o.Instrumentation.dll.
+		/// <br/><br/>The default setting is <code>true</code>.<br/><br/>
+		/// In a client/server environment it is good practice to configure the
+		/// client and the server in exactly the same way. <br/><br/>
+		/// </remarks>
+		/// <seealso cref="Db4objects.Db4o.Config.ICommonConfiguration.OptimizeNativeQueries">Db4objects.Db4o.Config.ICommonConfiguration.OptimizeNativeQueries</seealso>
+		bool OptimizeNativeQueries
+		{
+			get;
+			set;
+		}
+
+		/// <summary>returns the Query configuration interface.</summary>
+		/// <remarks>returns the Query configuration interface.</remarks>
+		IQueryConfiguration Queries
+		{
+			get;
+		}
+
+		/// <summary>configures the use of a specially designed reflection implementation.</summary>
+		/// <remarks>
+		/// configures the use of a specially designed reflection implementation.
+		/// <br /><br />
+		/// db4o internally uses java.lang.reflect.* by default. On platforms that
+		/// do not support this package, customized implementations may be written
+		/// to supply all the functionality of the interfaces in the com.db4o.reflect
+		/// package. This method can be used to install a custom reflection
+		/// implementation.<br /><br />
+		/// In client-server environment this setting should be used on both the client and
+		/// the server side (reflector class must be available)<br /><br />
+		/// </remarks>
+		void ReflectWith(IReflector reflector);
+
+		/// <summary>
+		/// Assigns a
+		/// <see cref="System.IO.TextWriter">TextWriter</see>
+		/// where db4o is to print its event messages.
+		/// <br /><br />Messages are useful for debugging purposes and for learning
+		/// to understand, how db4o works. The message level can be raised with
+		/// <see cref="IConfiguration.MessageLevel(int)">IConfiguration.MessageLevel(int)</see>
+		/// to produce more detailed messages.
+		/// <br /><br />Use <code>outStream(System.out)</code> to print messages to the
+		/// console.<br /><br />
+		/// In client-server environment this setting should be used on the same side
+		/// where
+		/// <see cref="IConfiguration.MessageLevel(int)">IConfiguration.MessageLevel(int)</see>
+		/// is used.<br /><br />
+		/// </summary>
+		/// <value>the new <code>PrintStream</code> for messages.</value>
+		/// <seealso cref="MessageLevel(int)">MessageLevel(int)</seealso>
+		TextWriter OutStream
+		{
+			set;
+		}
+
+		/// <summary>configures the string encoding to be used.</summary>
+		/// <remarks>
+		/// configures the string encoding to be used.
+		/// <br/><br/>The string encoding can not be changed in the lifetime of a
+		/// database file. To set up the database with the correct string encoding,
+		/// this configuration needs to be set correctly <b>before</b> a database
+		/// file is created with the first call to
+		/// <see cref="Db4objects.Db4o.Db4oFactory.OpenFile">Db4objects.Db4o.Db4oFactory.OpenFile
+		/// </see>
+		/// or
+		/// <see cref="Db4objects.Db4o.Db4oFactory.OpenServer">Db4objects.Db4o.Db4oFactory.OpenServer
+		/// </see>
+		/// .
+		/// <br/><br/>For subsequent open calls, db4o remembers built-in
+		/// string encodings. If a custom encoding is used (an encoding that is
+		/// not supplied from within the db4o library), the correct encoding
+		/// needs to be configured correctly again for all subsequent calls
+		/// that open database files.
+		/// <br/><br/>
+		/// In client-server mode, the server and all clients need to have the same string encoding.<br/><br/>
+		/// Example:<br/>
+		/// <code>config.StringEncoding = StringEncodings.Utf8();</code>
+		/// </remarks>
+		/// <seealso cref="Db4objects.Db4o.Config.Encoding.StringEncodings">Db4objects.Db4o.Config.Encoding.StringEncodings
+		/// </seealso>
+		IStringEncoding StringEncoding
+		{
+			set;
+		}
+
+		/// <summary>
+		/// tuning feature: configures whether db4o should try to instantiate one instance
+		/// of each persistent class on system startup.
+		/// </summary>
+		/// <remarks>
+		/// tuning feature: configures whether db4o should try to instantiate one instance
+		/// of each persistent class on system startup.
+		/// <br /><br />In a production environment this setting can be set to <code>false</code>,
+		/// if all persistent classes have public default constructors.
+		/// <br /><br />
+		/// In a client/server environment it is good practice to configure the
+		/// client and the server in exactly the same way. <br /><br />
+		/// Default value:<br />
+		/// <code>true</code>
+		/// </remarks>
+		/// <value>the desired setting</value>
+		bool TestConstructors
+		{
+			set;
+		}
+
+		/// <summary>specifies the global updateDepth.</summary>
+		/// <remarks>
+		/// specifies the global updateDepth.
+		/// <br /><br />see the documentation of
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Store(object)"></see>
+		/// for further details.<br /><br />
+		/// The value be may be overridden for individual classes.<br /><br />
+		/// The default setting is 1: Only the object passed to
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Store(object)">Db4objects.Db4o.IObjectContainer.Store(object)
+		/// 	</see>
+		/// will be updated.<br /><br />
+		/// In a client/server environment it is good practice to configure the
+		/// client and the server in exactly the same way. <br /><br />
+		/// </remarks>
+		/// <value>the depth of the desired update.</value>
+		/// <seealso cref="IObjectClass.UpdateDepth(int)">IObjectClass.UpdateDepth(int)</seealso>
+		/// <seealso cref="IObjectClass.CascadeOnUpdate(bool)">IObjectClass.CascadeOnUpdate(bool)
+		/// 	</seealso>
+		/// <seealso cref="Db4objects.Db4o.Ext.IObjectCallbacks">Using callbacks</seealso>
+		int UpdateDepth
+		{
+			set;
+		}
+
+		/// <summary>turns weak reference management on or off.</summary>
+		/// <remarks>
+		/// turns weak reference management on or off.
+		/// <br /><br />
+		/// This method must be called before opening a database.
+		/// <br /><br />
+		/// Performance may be improved by running db4o without using weak
+		/// references durring memory management at the cost of higher
+		/// memory consumption or by alternatively implementing a manual
+		/// memory management scheme using
+		/// <see cref="Db4objects.Db4o.Ext.IExtObjectContainer.Purge(object)">Db4objects.Db4o.Ext.IExtObjectContainer.Purge(object)
+		/// 	</see>
+		/// <br /><br />Setting the value to <code>false</code> causes db4o to use hard
+		/// references to objects, preventing the garbage collection process
+		/// from disposing of unused objects.
+		/// <br /><br />The default setting is <code>true</code>.
+		/// <br /><br />Ignored on JDKs before 1.2.
+		/// </remarks>
+		bool WeakReferences
+		{
+			set;
+		}
+
+		/// <summary>configures the timer for WeakReference collection.</summary>
+		/// <remarks>
+		/// configures the timer for WeakReference collection.
+		/// <br /><br />The default setting is 1000 milliseconds.
+		/// <br /><br />Configure this setting to zero to turn WeakReference
+		/// collection off.
+		/// <br /><br />Ignored on JDKs before 1.2.<br /><br />
+		/// </remarks>
+		/// <value>the time in milliseconds</value>
+		int WeakReferenceCollectionInterval
+		{
+			set;
+		}
+
+		/// <summary>
+		/// allows registering special TypeHandlers for customized marshalling
+		/// and customized comparisons.
+		/// </summary>
+		/// <remarks>
+		/// allows registering special TypeHandlers for customized marshalling
+		/// and customized comparisons.
+		/// </remarks>
+		/// <param name="predicate">
+		/// to specify for which classes and versions the
+		/// TypeHandler is to be used.
+		/// </param>
+		/// <param name="typeHandler">to be used for the classes that match the predicate.</param>
+		void RegisterTypeHandler(ITypeHandlerPredicate predicate, ITypeHandler4 typeHandler
+			);
+
+		/// <seealso cref="Db4objects.Db4o.Foundation.IEnvironment">Db4objects.Db4o.Foundation.IEnvironment
+		/// 	</seealso>
+		IEnvironmentConfiguration Environment
+		{
+			get;
+		}
+
+		/// <summary>
+		/// Registers a
+		/// <see cref="INameProvider">INameProvider</see>
+		/// that assigns a custom name to the database to be used in
+		/// <see cref="object.ToString()">object.ToString()</see>
+		/// .
+		/// </summary>
+		void NameProvider(INameProvider provider);
+
+		/// <summary><p>Sets the max stack depth that will be used for recursive storing and activating an object.
+		/// 	</summary>
+		/// <remarks>
+		/// <p>Sets the max stack depth that will be used for recursive storing and activating an object.
+		/// <p>The default value is set to
+		/// <see cref="Db4objects.Db4o.Internal.Const4.DefaultMaxStackDepth">Db4objects.Db4o.Internal.Const4.DefaultMaxStackDepth
+		/// 	</see>
+		/// <p>On Android platform, we recomend setting this to 2.
+		/// </remarks>
+		/// <value>the desired max stack depth.</value>
+		/// <summary>gets the configured max stack depth.</summary>
+		/// <remarks>gets the configured max stack depth.</remarks>
+		/// <returns>the configured max stack depth.</returns>
+		int MaxStackDepth
+		{
+			get;
+			set;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ICommonConfigurationProvider.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ICommonConfigurationProvider.cs
new file mode 100644
index 0000000..dea8056
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ICommonConfigurationProvider.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// A configuration provider that provides access to
+	/// the common configuration methods that can be called
+	/// for embedded, server and client use of db4o.
+	/// </summary>
+	/// <remarks>
+	/// A configuration provider that provides access to
+	/// the common configuration methods that can be called
+	/// for embedded, server and client use of db4o.
+	/// </remarks>
+	/// <since>7.5</since>
+	public interface ICommonConfigurationProvider
+	{
+		/// <summary>Access to the common configuration methods.</summary>
+		/// <remarks>Access to the common configuration methods.</remarks>
+		ICommonConfiguration Common
+		{
+			get;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ICompare.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ICompare.cs
new file mode 100644
index 0000000..06cb5fb
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ICompare.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>allows special comparison behaviour during query evaluation.</summary>
+	/// <remarks>
+	/// allows special comparison behaviour during query evaluation.
+	/// <br /><br />db4o will use the Object returned by the
+	/// <see cref="Compare()">Compare()</see>
+	/// method for all query comparisons.
+	/// </remarks>
+	public interface ICompare
+	{
+		/// <summary>return the Object to be compared during query evaluation.</summary>
+		/// <remarks>return the Object to be compared during query evaluation.</remarks>
+		object Compare();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IConfiguration.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IConfiguration.cs
new file mode 100644
index 0000000..562cade
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IConfiguration.cs
@@ -0,0 +1,888 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.IO;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Config.Encoding;
+using Db4objects.Db4o.Diagnostic;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>configuration interface.</summary>
+	/// <remarks>
+	/// configuration interface.
+	/// <br /><br />This interface contains methods to configure db4o.<br /><br />
+	/// The global Configuration context is available with
+	/// <see cref="Db4objects.Db4o.Db4oFactory.Configure()">Db4objects.Db4o.Db4oFactory.Configure()
+	/// 	</see>
+	/// .
+	/// When an ObjectContainer or ObjectServer is opened, the global Configuration
+	/// context is cloned and copied into the ObjectContainer/ObjectServer.
+	/// That means every ObjectContainer/ObjectServer gets it's own copy of
+	/// configuration settings.<br /><br />
+	/// <b>Most configuration settings should be set before opening an
+	/// ObjectContainer/ObjectServer</b>.
+	/// <br /><br />Some configuration settings can be modified on an open
+	/// ObjectContainer/ObjectServer. The local Configuration context is
+	/// available with
+	/// <see cref="Db4objects.Db4o.Ext.IExtObjectContainer.Configure()">Db4objects.Db4o.Ext.IExtObjectContainer.Configure()
+	/// 	</see>
+	/// and
+	/// <see cref="Db4objects.Db4o.Ext.IExtObjectServer.Configure()">Db4objects.Db4o.Ext.IExtObjectServer.Configure()
+	/// 	</see>
+	/// .
+	/// </remarks>
+	public interface IConfiguration
+	{
+		/// <summary>sets the activation depth to the specified value.</summary>
+		/// <remarks>
+		/// sets the activation depth to the specified value.
+		/// <br/><br/><b>Why activation?</b><br/>
+		/// When objects are instantiated from the database, the instantiation of member
+		/// objects needs to be limited to a certain depth. Otherwise a single object
+		/// could lead to loading the complete database into memory, if all objects where
+		/// reachable from a single root object.<br/><br/>
+		/// db4o uses the concept "depth", the number of field-to-field hops an object
+		/// is away from another object. <b>The preconfigured "activation depth" db4o uses
+		/// in the default setting is 5.</b>
+		/// <br/><br/>Whenever an application iterates through the
+		/// <see cref="Db4objects.Db4o.IObjectSet">IObjectSet</see>
+		/// of a query result, the result objects
+		/// will be activated to the configured activation depth.<br/><br/>
+		/// A concrete example with the preconfigured activation depth of 5:<br/>
+		/// <pre>
+		/// // Object foo is the result of a query, it is delivered by the ObjectSet
+		/// object foo = objectSet.Next();</pre>
+		/// foo.member1.member2.member3.member4.member5 will be a valid object<br/>
+		/// foo, member1, member2, member3 and member4 will be activated<br/>
+		/// member5 will be deactivated, all of it's members will be null<br/>
+		/// member5 can be activated at any time by calling
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Activate">IObjectContainer.Activate(member5, depth)
+		/// </see>
+		/// .
+		/// <br/><br/>
+		/// Note that raising the global activation depth will consume more memory and
+		/// have negative effects on the performance of first-time retrievals. Lowering
+		/// the global activation depth needs more individual activation work but can
+		/// increase performance of queries.<br/><br/>
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Deactivate">IObjectContainer.Deactivate(object, depth)
+		/// </see>
+		/// can be used to manually free memory by deactivating objects.<br/><br/>
+		/// In client/server environment the same setting should be used on both
+		/// client and server<br/><br/>.
+		/// </remarks>
+		/// <param name="depth">the desired global activation depth.</param>
+		/// 
+		/// <seealso cref="Db4objects.Db4o.Config.IObjectClass.MaximumActivationDepth">configuring classes individually
+		/// </seealso>
+		/// 
+		/// <summary>gets the configured activation depth.</summary>
+		void ActivationDepth(int depth);
+
+		/// <summary>gets the configured activation depth.</summary>
+		/// <remarks>gets the configured activation depth.</remarks>
+		/// <returns>the configured activation depth.</returns>
+		int ActivationDepth();
+
+		/// <summary>
+		/// adds ConfigurationItems to be applied when
+		/// an ObjectContainer or ObjectServer is opened.
+		/// </summary>
+		/// <remarks>
+		/// adds ConfigurationItems to be applied when
+		/// an ObjectContainer or ObjectServer is opened.
+		/// </remarks>
+		/// <param name="configurationItem">the ConfigurationItem</param>
+		void Add(IConfigurationItem configurationItem);
+
+		/// <summary>adds a new Alias for a class, namespace or package.
+		/// </summary>
+		/// <remarks>
+		/// adds a new Alias for a class, namespace or package.
+		/// <br/>
+		/// <br/>
+		/// Aliases can be used to persist classes in the running application
+		/// to different persistent classes in a database file or on a db4o
+		/// server.
+		/// <br/>
+		/// <br/>
+		/// Two simple Alias implementations are supplied along with db4o:
+		/// <br/>
+		/// -
+		/// <see cref="TypeAlias">TypeAlias</see>
+		/// provides an #equals() resolver to match names directly.
+		/// <br/>
+		/// -
+		/// <see cref="WildcardAlias">WildcardAlias</see>
+		/// allows simple pattern matching with one single '*' wildcard
+		/// character.
+		/// <br/>
+		/// <br/>
+		/// It is possible to create own complex
+		/// <see cref="IAlias">IAlias</see>
+		/// constructs by creating own resolvers that implement the
+		/// <see cref="IAlias">IAlias</see>
+		/// interface.
+		/// <br/>
+		/// <br/>
+		/// Four examples of concrete usecases:
+		/// <br/>
+		/// <br/>
+		/// <code>
+		/// <b>// Creating an Alias for a single class</b>
+		/// <br/>
+		/// Db4oFactory.Configure().AddAlias(
+		/// <br/>  new TypeAlias("Tutorial.F1.Pilot", "Tutorial.F1.Driver"));<br/>
+		/// <br/><br/>
+		/// <b>// Accessing a Java package from a .NET assembly</b><br/>
+		/// Db4o.configure().addAlias(<br/>
+		///   new WildcardAlias(<br/>
+		///     "com.f1.*",<br/>
+		///     "Tutorial.F1.*, Tutorial"));<br/>
+		/// <br/><br/>
+		/// <b>// Using a different local .NET assembly</b><br/>
+		/// Db4o.configure().addAlias(<br/>
+		///   new WildcardAlias(<br/>
+		///     "Tutorial.F1.*, Tutorial",<br/>
+		///     "Tutorial.F1.*, RaceClient"));<br/>
+		/// </code>
+		/// <br/><br/>Aliases that translate the persistent name of a class to
+		/// a name that already exists as a persistent name in the database
+		/// (or on the server) are not permitted and will throw an exception
+		/// when the database file is opened.
+		/// <br/><br/>Aliases should be configured before opening a database file
+		/// or connecting to a server.
+		/// </remarks>
+		void AddAlias(IAlias alias);
+
+		/// <summary>
+		/// Removes an alias previously added with
+		/// <see cref="AddAlias(IAlias)">AddAlias(IAlias)</see>
+		/// .
+		/// </summary>
+		/// <param name="alias">the alias to remove</param>
+		void RemoveAlias(IAlias alias);
+
+		/// <summary>turns automatic database file format version updates on.</summary>
+		/// <remarks>
+		/// turns automatic database file format version updates on.
+		/// <br /><br />Upon db4o database file format version changes,
+		/// db4o can automatically update database files to the
+		/// current version. db4objects does not provide functionality
+		/// to reverse this process. It is not ensured that updated
+		/// database files can be read with older db4o versions.
+		/// In some cases (Example: using ObjectManager) it may not be
+		/// desirable to update database files automatically therefore
+		/// automatic updating is turned off by default for
+		/// security reasons.
+		/// <br /><br />Call this method to turn automatic database file
+		/// version updating on.
+		/// <br /><br />If automatic updating is turned off, db4o will refuse
+		/// to open database files that use an older database file format.<br /><br />
+		/// In client-server environment this setting should be used on both client
+		/// and server.
+		/// </remarks>
+		void AllowVersionUpdates(bool flag);
+
+		/// <summary>turns automatic shutdown of the engine on and off.</summary>
+		/// <remarks>
+		/// turns automatic shutdown of the engine on and off.
+		/// </remarks>
+		/// <param name="flag">whether db4o should shut down automatically.</param>
+		void AutomaticShutDown(bool flag);
+
+		/// <summary>sets the storage data blocksize for new ObjectContainers.</summary>
+		/// <remarks>
+		/// sets the storage data blocksize for new ObjectContainers.
+		/// <br /><br />The standard setting is 1 allowing for a maximum
+		/// database file size of 2GB. This value can be increased
+		/// to allow larger database files, although some space will
+		/// be lost to padding because the size of some stored objects
+		/// will not be an exact multiple of the block size. A
+		/// recommended setting for large database files is 8, since
+		/// internal pointers have this length.<br /><br />
+		/// This setting is only effective when the database is first created, in
+		/// client-server environment in most cases it means that the setting
+		/// should be used on the server side.
+		/// </remarks>
+		/// <param name="bytes">the size in bytes from 1 to 127</param>
+		/// <exception cref="Db4objects.Db4o.Config.GlobalOnlyConfigException"></exception>
+		void BlockSize(int bytes);
+
+		/// <summary>configures the size of BTree nodes in indexes.</summary>
+		/// <remarks>
+		/// configures the size of BTree nodes in indexes.
+		/// <br /><br />Default setting: 100
+		/// <br />Lower values will allow a lower memory footprint
+		/// and more efficient reading and writing of small slots.
+		/// <br />Higher values will reduce the overall number of
+		/// read and write operations and allow better performance
+		/// at the cost of more RAM use.<br /><br />
+		/// This setting should be used on both client and server in
+		/// client-server environment.
+		/// </remarks>
+		/// <param name="size">the number of elements held in one BTree node.</param>
+		void BTreeNodeSize(int size);
+
+		/// <summary>configures caching of BTree nodes.</summary>
+		/// <remarks>
+		/// configures caching of BTree nodes.
+		/// <br /><br />Clean BTree nodes will be unloaded on #commit and
+		/// #rollback unless they are configured as cached here.
+		/// <br /><br />Default setting: 0
+		/// <br />Possible settings: 1, 2 or 3
+		/// <br /><br /> The potential number of cached BTree nodes can be
+		/// calculated with the following formula:<br />
+		/// maxCachedNodes = bTreeNodeSize ^ bTreeCacheHeight<br /><br />
+		/// This setting should be used on both client and server in
+		/// client-server environment.
+		/// </remarks>
+		/// <param name="height">the height of the cache from the root</param>
+		void BTreeCacheHeight(int height);
+
+		/// <summary>returns the Cache configuration interface.</summary>
+		/// <remarks>returns the Cache configuration interface.</remarks>
+		ICacheConfiguration Cache();
+
+		/// <summary>turns callback methods on and off.</summary>
+		/// <remarks>
+		/// turns callback methods on and off.
+		/// <br /><br />Callbacks are turned on by default.<br /><br />
+		/// A tuning hint: If callbacks are not used, you can turn this feature off, to
+		/// prevent db4o from looking for callback methods in persistent classes. This will
+		/// increase the performance on system startup.<br /><br />
+		/// In client/server environment this setting should be used on both
+		/// client and server.
+		/// </remarks>
+		/// <param name="flag">false to turn callback methods off</param>
+		/// <seealso cref="Db4objects.Db4o.Ext.IObjectCallbacks">Using callbacks</seealso>
+		void Callbacks(bool flag);
+
+		/// <summary>
+		/// advises db4o to try instantiating objects with/without calling
+		/// constructors.
+		/// </summary>
+		/// <remarks>
+		/// advises db4o to try instantiating objects with/without calling
+		/// constructors.
+		/// <br/><br/>
+		/// Not all .NET-environments support this feature. db4o will
+		/// attempt, to follow the setting as good as the enviroment supports.
+		/// This setting may also be overridden for individual classes in
+		/// <see cref="Db4objects.Db4o.Config.IObjectClass.CallConstructor">Db4objects.Db4o.Config.IObjectClass.CallConstructor
+		/// </see>
+		/// .
+		/// <br/><br/>The default setting depends on the features supported by your current environment.<br/><br/>
+		/// In client/server environment this setting should be used on both
+		/// client and server.
+		/// <br/><br/>
+		/// </remarks>
+		/// <param name="flag">
+		/// - specify true, to request calling constructors, specify
+		/// false to request <b>not</b> calling constructors.
+		/// </param>
+		/// <seealso cref="Db4objects.Db4o.Config.IObjectClass.CallConstructor">Db4objects.Db4o.Config.IObjectClass.CallConstructor
+		/// </seealso>
+		void CallConstructors(bool flag);
+
+		/// <summary>
+		/// turns
+		/// <see cref="IObjectClass.MaximumActivationDepth(int)">individual class activation depth configuration
+		/// 	</see>
+		/// on
+		/// and off.
+		/// <br /><br />This feature is turned on by default.<br /><br />
+		/// In client/server environment this setting should be used on both
+		/// client and server.<br /><br />
+		/// </summary>
+		/// <param name="flag">
+		/// false to turn the possibility to individually configure class
+		/// activation depths off
+		/// </param>
+		/// <seealso cref="ActivationDepth()">Why activation?</seealso>
+		void ClassActivationDepthConfigurable(bool flag);
+
+		/// <summary>returns client/server configuration interface.</summary>
+		/// <remarks>returns client/server configuration interface.</remarks>
+		IClientServerConfiguration ClientServer();
+
+		/// <summary>
+		/// configures the size database files should grow in bytes, when no
+		/// free slot is found within.
+		/// </summary>
+		/// <remarks>
+		/// configures the size database files should grow in bytes, when no
+		/// free slot is found within.
+		/// <br /><br />Tuning setting.
+		/// <br /><br />Whenever no free slot of sufficient length can be found
+		/// within the current database file, the database file's length
+		/// is extended. This configuration setting configures by how much
+		/// it should be extended, in bytes.<br /><br />
+		/// This configuration setting is intended to reduce fragmentation.
+		/// Higher values will produce bigger database files and less
+		/// fragmentation.<br /><br />
+		/// To extend the database file, a single byte array is created
+		/// and written to the end of the file in one write operation. Be
+		/// aware that a high setting will require allocating memory for
+		/// this byte array.
+		/// </remarks>
+		/// <param name="bytes">amount of bytes</param>
+		void DatabaseGrowthSize(int bytes);
+
+		/// <summary>
+		/// tuning feature: configures whether db4o checks all persistent classes upon system
+		/// startup, for added or removed fields.
+		/// </summary>
+		/// <remarks>
+		/// tuning feature: configures whether db4o checks all persistent classes upon system
+		/// startup, for added or removed fields.
+		/// <br /><br />If this configuration setting is set to false while a database is
+		/// being created, members of classes will not be detected and stored.
+		/// <br /><br />This setting can be set to false in a production environment after
+		/// all persistent classes have been stored at least once and classes will not
+		/// be modified any further in the future.<br /><br />
+		/// In a client/server environment this setting should be configured both on the
+		/// client and and on the server.
+		/// <br /><br />Default value:<br />
+		/// <code>true</code>
+		/// </remarks>
+		/// <param name="flag">the desired setting</param>
+		void DetectSchemaChanges(bool flag);
+
+		/// <summary>returns the configuration interface for diagnostics.</summary>
+		/// <remarks>returns the configuration interface for diagnostics.</remarks>
+		/// <returns>the configuration interface for diagnostics.</returns>
+		IDiagnosticConfiguration Diagnostic();
+
+		/// <summary>turns commit recovery off.</summary>
+		/// <remarks>
+		/// turns commit recovery off.
+		/// <br /><br />db4o uses a two-phase commit algorithm. In a first step all intended
+		/// changes are written to a free place in the database file, the "transaction commit
+		/// record". In a second step the
+		/// actual changes are performed. If the system breaks down during commit, the
+		/// commit process is restarted when the database file is opened the next time.
+		/// On very rare occasions (possibilities: hardware failure or editing the database
+		/// file with an external tool) the transaction commit record may be broken. In this
+		/// case, this method can be used to try to open the database file without commit
+		/// recovery. The method should only be used in emergency situations after consulting
+		/// db4o support.
+		/// </remarks>
+		void DisableCommitRecovery();
+
+		/// <summary>configures the use of encryption.</summary>
+		/// <remarks>
+		/// configures the use of encryption.
+		/// <br /><br />This method needs to be called <b>before</b> a database file
+		/// is created with the first
+		/// <see cref="Db4objects.Db4o.Db4oFactory.OpenFile(string)">Db4objects.Db4o.Db4oFactory.OpenFile(string)
+		/// 	</see>
+		/// .
+		/// <br /><br />If encryption is set to true,
+		/// you need to supply a password to seed the encryption mechanism.<br /><br />
+		/// db4o database files keep their encryption format after creation.<br /><br />
+		/// </remarks>
+		/// <param name="flag">
+		/// true for turning encryption on, false for turning encryption
+		/// off.
+		/// </param>
+		/// <seealso cref="Password(string)">Password(string)</seealso>
+		/// <exception cref="Db4objects.Db4o.Config.GlobalOnlyConfigException"></exception>
+		[System.ObsoleteAttribute(@"use a custom encrypting  instead")]
+		void Encrypt(bool flag);
+
+		/// <summary>configures whether Exceptions are to be thrown, if objects can not be stored.
+		/// 	</summary>
+		/// <remarks>
+		/// configures whether Exceptions are to be thrown, if objects can not be stored.
+		/// <br /><br />db4o requires the presence of a constructor that can be used to
+		/// instantiate objects. If no default public constructor is present, all
+		/// available constructors are tested, whether an instance of the class can
+		/// be instantiated. Null is passed to all constructor parameters.
+		/// The first constructor that is successfully tested will
+		/// be used throughout the running db4o session. If an instance of the class
+		/// can not be instantiated, the object will not be stored. By default,
+		/// execution will continue without any message or error. This method can
+		/// be used to configure db4o to throw an
+		/// <see cref="Db4objects.Db4o.Ext.ObjectNotStorableException">ObjectNotStorableException
+		/// 	</see>
+		/// if an object can not be stored.
+		/// <br /><br />
+		/// The default for this setting is <b>true</b>.<br /><br />
+		/// In client/server environment this setting should be used on both
+		/// client and server.<br /><br />
+		/// </remarks>
+		/// <param name="flag">false to not throw Exceptions if objects can not be stored (fail silently).
+		/// 	</param>
+		void ExceptionsOnNotStorable(bool flag);
+
+		/// <summary>returns the freespace configuration interface.</summary>
+		/// <remarks>returns the freespace configuration interface.</remarks>
+		IFreespaceConfiguration Freespace();
+
+		/// <summary>configures db4o to generate UUIDs for stored objects.</summary>
+		/// <remarks>
+		/// configures db4o to generate UUIDs for stored objects.
+		/// This setting should be used when the database is first created.<br /><br />
+		/// </remarks>
+		/// <param name="setting">the scope for UUID generation: disabled, generate for all classes, or configure individually
+		/// 	</param>
+		void GenerateUUIDs(ConfigScope setting);
+
+		/// <summary>configures db4o to generate version numbers for stored objects.</summary>
+		/// <remarks>
+		/// configures db4o to generate version numbers for stored objects.
+		/// This setting should be used when the database is first created.
+		/// </remarks>
+		/// <param name="setting">the scope for version number generation: disabled, generate for all classes, or configure individually
+		/// 	</param>
+		[System.ObsoleteAttribute(@"As of version 8.0 please use GenerateCommitTimestamps(bool) instead."
+			)]
+		void GenerateVersionNumbers(ConfigScope setting);
+
+		/// <summary>
+		/// Configures db4o to generate commit timestamps for all stored objects.<br />
+		/// <br />
+		/// All the objects commited within a transaction will share the same commit timestamp.
+		/// </summary>
+		/// <remarks>
+		/// Configures db4o to generate commit timestamps for all stored objects.<br />
+		/// <br />
+		/// All the objects commited within a transaction will share the same commit timestamp.
+		/// <br />
+		/// This setting should be used when the database is first created.<br />
+		/// <br />
+		/// Afterwards you can access the object's commit timestamp like this:<br />
+		/// <br />
+		/// <pre>
+		/// ObjectContainer container = ...;
+		/// ObjectInfo objectInfo = container.ext().getObjectInfo(obj);
+		/// long commitTimestamp = objectInfo.getVersion();
+		/// </pre>
+		/// </remarks>
+		/// <param name="flag">
+		/// if true, commit timetamps will be generated for all stored
+		/// objects. If you already have commit timestamps for stored
+		/// objects and later set this flag to false, although you wont be
+		/// able to access them, the commit timestamps will still be taking
+		/// space in your file container. The only way to free that space
+		/// is defragmenting the container.
+		/// </param>
+		/// <since>8.0</since>
+		void GenerateCommitTimestamps(bool flag);
+
+		/// <summary>configures db4o to call #intern() on strings upon retrieval.</summary>
+		/// <remarks>
+		/// configures db4o to call #intern() on strings upon retrieval.
+		/// In client/server environment the setting should be used on both
+		/// client and server.
+		/// </remarks>
+		/// <param name="flag">true to intern strings</param>
+		void InternStrings(bool flag);
+
+		/// <summary>returns true if strings will be interned.</summary>
+		/// <remarks>returns true if strings will be interned.</remarks>
+		bool InternStrings();
+
+		/// <summary>allows to configure db4o to use a customized byte IO adapter.</summary>
+		/// <remarks>
+		/// allows to configure db4o to use a customized byte IO adapter.
+		/// <br /><br />Derive from the abstract class
+		/// <see cref="Db4objects.Db4o.IO.IoAdapter">Db4objects.Db4o.IO.IoAdapter</see>
+		/// to
+		/// write your own. Possible usecases could be improved performance
+		/// with a native library, mirrored write to two files, encryption or
+		/// read-on-write fail-safety control.<br /><br />An example of a custom
+		/// io adapter can be found in xtea_db4o community project:<br />
+		/// http://developer.db4o.com/ProjectSpaces/view.aspx/XTEA<br /><br />
+		/// In client-server environment this setting should be used on the server
+		/// (adapter class must be available)<br /><br />
+		/// </remarks>
+		/// <param name="adapter">- the IoAdapter</param>
+		/// <exception cref="Db4objects.Db4o.Config.GlobalOnlyConfigException"></exception>
+		[System.ObsoleteAttribute(@"Use Storage(Db4objects.Db4o.IO.IStorage) instead.")]
+		void Io(IoAdapter adapter);
+
+		/// <summary>allows to configure db4o to use a customized byte IO storage mechanism.</summary>
+		/// <remarks>
+		/// allows to configure db4o to use a customized byte IO storage mechanism.
+		/// <br /><br />Implement the interface
+		/// <see cref="Db4objects.Db4o.IO.IStorage">Db4objects.Db4o.IO.IStorage</see>
+		/// to
+		/// write your own. Possible usecases could be improved performance
+		/// with a native library, mirrored write to two files, encryption or
+		/// read-on-write fail-safety control.<br /><br />
+		/// </remarks>
+		/// <value>- the factory</value>
+		/// <seealso cref="Db4objects.Db4o.IO.CachingStorage">Db4objects.Db4o.IO.CachingStorage
+		/// 	</seealso>
+		/// <seealso cref="Db4objects.Db4o.IO.MemoryStorage">Db4objects.Db4o.IO.MemoryStorage
+		/// 	</seealso>
+		/// <seealso cref="Db4objects.Db4o.IO.FileStorage">Db4objects.Db4o.IO.FileStorage</seealso>
+		/// <seealso cref="Db4objects.Db4o.IO.StorageDecorator">Db4objects.Db4o.IO.StorageDecorator
+		/// 	</seealso>
+		/// <exception cref="Db4objects.Db4o.Config.GlobalOnlyConfigException"></exception>
+		/// <summary>
+		/// returns the configured
+		/// <see cref="Db4objects.Db4o.IO.IStorage">Db4objects.Db4o.IO.IStorage</see>
+		/// </summary>
+		IStorage Storage
+		{
+			get;
+			set;
+		}
+
+		/// <summary>
+		/// returns the configured
+		/// <see cref="Db4objects.Db4o.IO.IoAdapter">Db4objects.Db4o.IO.IoAdapter</see>
+		/// .
+		/// </summary>
+		/// <returns></returns>
+		[System.ObsoleteAttribute(@"Use Storage() instead.")]
+		IoAdapter Io();
+
+		/// <summary>allows to mark fields as transient with custom attributes.</summary>
+		/// <remarks>
+		/// allows to mark fields as transient with custom attributes.
+		/// <br /><br />.NET only: Call this method with the attribute name that you
+		/// wish to use to mark fields as transient. Multiple transient attributes
+		/// are possible by calling this method multiple times with different
+		/// attribute names.<br /><br />
+		/// In client/server environment the setting should be used on both
+		/// client and server.<br /><br />
+		/// </remarks>
+		/// <param name="attributeName">
+		/// - the fully qualified name of the attribute, including
+		/// it's namespace
+		/// </param>
+		void MarkTransient(string attributeName);
+
+		/// <summary>sets the detail level of db4o messages.</summary>
+		/// <remarks>
+		/// sets the detail level of db4o messages. Messages will be output to the
+		/// configured output
+		/// <see cref="System.IO.TextWriter">TextWriter</see>
+		/// .
+		/// <br /><br />
+		/// Level 0 - no messages<br />
+		/// Level 1 - open and close messages<br />
+		/// Level 2 - messages for new, update and delete<br />
+		/// Level 3 - messages for activate and deactivate<br /><br />
+		/// When using client-server and the level is set to 0, the server will override this and set it to 1.  To get around this you can set the level to -1.  This has the effect of not returning any messages.<br /><br />
+		/// In client-server environment this setting can be used on client or on server
+		/// depending on which information do you want to track (server side provides more
+		/// detailed information).<br /><br />
+		/// </remarks>
+		/// <param name="level">integer from 0 to 3</param>
+		/// <seealso cref="SetOut(System.IO.TextWriter)">SetOut(System.IO.TextWriter)</seealso>
+		void MessageLevel(int level);
+
+		/// <summary>can be used to turn the database file locking thread off.</summary>
+		/// <param name="flag">
+		/// <code>false</code> to turn database file locking off.
+		/// </param>
+		void LockDatabaseFile(bool flag);
+
+		/// <summary>
+		/// returns an
+		/// <see cref="IObjectClass">IObjectClass</see>
+		/// object
+		/// to configure the specified class.
+		/// <br /><br />
+		/// The clazz parameter can be any of the following:<br />
+		/// - a fully qualified classname as a String.<br />
+		/// - a Class object.<br />
+		/// - any other object to be used as a template.<br /><br />
+		/// </summary>
+		/// <param name="clazz">class name, Class object, or example object.<br /><br /></param>
+		/// <returns>
+		/// an instance of an
+		/// <see cref="IObjectClass">IObjectClass</see>
+		/// object for configuration.
+		/// </returns>
+		IObjectClass ObjectClass(object clazz);
+
+		/// <summary>
+		/// If set to true, db4o will try to optimize native queries
+		/// dynamically at query execution time, otherwise it will
+		/// run native queries in unoptimized mode as SODA evaluations.
+		/// </summary>
+		/// <remarks>
+		/// If set to true, db4o will try to optimize native queries
+		/// dynamically at query execution time, otherwise it will
+		/// run native queries in unoptimized mode as SODA evaluations.
+		/// The following assemblies should be available for native query switch to take effect:
+		/// Db4objects.Db4o.NativeQueries.dll, Db4objects.Db4o.Instrumentation.dll.
+		/// <br/><br/>The default setting is <code>true</code>.<br/><br/>
+		/// In client-server environment this setting should be used on both client and server.<br/><br/>
+		/// </remarks>
+		/// <param name="optimizeNQ">
+		/// true, if db4o should try to optimize
+		/// native queries at query execution time, false otherwise
+		/// </param>
+		/// 
+		/// <seealso cref="Db4objects.Db4o.Config.ICommonConfiguration.OptimizeNativeQueries">Db4objects.Db4o.Config.ICommonConfiguration.OptimizeNativeQueries</seealso>
+		void OptimizeNativeQueries(bool optimizeNQ);
+
+		/// <summary>indicates whether Native Queries will be optimized dynamically.</summary>
+		/// <remarks>indicates whether Native Queries will be optimized dynamically.</remarks>
+		/// <returns>
+		/// boolean true if Native Queries will be optimized
+		/// dynamically.
+		/// </returns>
+		/// <seealso cref="OptimizeNativeQueries()">OptimizeNativeQueries()</seealso>
+		bool OptimizeNativeQueries();
+
+		/// <summary>protects the database file with a password.</summary>
+		/// <remarks>
+		/// protects the database file with a password.
+		/// <br /><br />To set a password for a database file, this method needs to be
+		/// called <b>before</b> a database file is created with the first
+		/// <see cref="Db4objects.Db4o.Db4oFactory.OpenFile(string)">Db4objects.Db4o.Db4oFactory.OpenFile(string)
+		/// 	</see>
+		/// .
+		/// <br /><br />All further attempts to open
+		/// the file, are required to set the same password.<br /><br />The password
+		/// is used to seed the encryption mechanism, which makes it impossible
+		/// to read the database file without knowing the password.<br /><br />
+		/// </remarks>
+		/// <param name="pass">the password to be used.</param>
+		/// <exception cref="Db4objects.Db4o.Config.GlobalOnlyConfigException"></exception>
+		[System.ObsoleteAttribute(@"use a custom encrypting  instead")]
+		void Password(string pass);
+
+		/// <summary>returns the Query configuration interface.</summary>
+		/// <remarks>returns the Query configuration interface.</remarks>
+		IQueryConfiguration Queries();
+
+		/// <summary>turns readOnly mode on and off.</summary>
+		/// <remarks>
+		/// turns readOnly mode on and off.
+		/// <br /><br />This method configures the mode in which subsequent calls to
+		/// <see cref="Db4objects.Db4o.Db4oFactory.OpenFile(string)">Db4o.openFile()</see>
+		/// will open files.
+		/// <br /><br />Readonly mode allows to open an unlimited number of reading
+		/// processes on one database file. It is also convenient
+		/// for deploying db4o database files on CD-ROM.<br /><br />
+		/// In client-server environment this setting should be used on the server side
+		/// in embedded mode and ONLY on client side in networked mode.<br /><br />
+		/// </remarks>
+		/// <param name="flag">
+		/// <code>true</code> for configuring readOnly mode for subsequent
+		/// calls to
+		/// <see cref="Db4objects.Db4o.Db4oFactory.OpenFile(string)">Db4o.openFile()</see>
+		/// .
+		/// </param>
+		void ReadOnly(bool flag);
+
+		/// <summary>
+		/// turns recovery mode on and off.<br /><br />
+		/// Recovery mode can be used to try to retrieve as much as possible
+		/// out of an already corrupted database.
+		/// </summary>
+		/// <remarks>
+		/// turns recovery mode on and off.<br /><br />
+		/// Recovery mode can be used to try to retrieve as much as possible
+		/// out of an already corrupted database. In recovery mode internal
+		/// checks are more relaxed. Null or invalid objects may be returned
+		/// instead of throwing exceptions.<br /><br />
+		/// Use this method with care as a last resort to get data out of a
+		/// corrupted database.
+		/// </remarks>
+		/// <param name="flag"><code>true</code> to turn recover mode on.</param>
+		void RecoveryMode(bool flag);
+
+		/// <summary>configures the use of a specially designed reflection implementation.</summary>
+		/// <remarks>
+		/// configures the use of a specially designed reflection implementation.
+		/// <br/><br/>
+		/// db4o internally uses System.Reflection by default. On platforms that
+		/// do not support this package, customized implementations may be written
+		/// to supply all the functionality of the interfaces in System.Reflection
+		/// namespace. This method can be used to install a custom reflection
+		/// implementation.
+		/// 
+		/// </remarks>
+		void ReflectWith(IReflector reflector);
+
+		/// <summary>tuning feature only: reserves a number of bytes in database files.</summary>
+		/// <remarks>
+		/// tuning feature only: reserves a number of bytes in database files.
+		/// <br /><br />The global setting is used for the creation of new database
+		/// files. Continous calls on an ObjectContainer Configuration context
+		/// (see
+		/// <see cref="Db4objects.Db4o.Ext.IExtObjectContainer.Configure()">Db4objects.Db4o.Ext.IExtObjectContainer.Configure()
+		/// 	</see>
+		/// ) will
+		/// continually allocate space.
+		/// <br /><br />The allocation of a fixed number of bytes at one time
+		/// makes it more likely that the database will be stored in one
+		/// chunk on the mass storage. Less read/write head movement can result
+		/// in improved performance.<br /><br />
+		/// <b>Note:</b><br /> Allocated space will be lost on abnormal termination
+		/// of the database engine (hardware crash, VM crash). A Defragment run
+		/// will recover the lost space. For the best possible performance, this
+		/// method should be called before the Defragment run to configure the
+		/// allocation of storage space to be slightly greater than the anticipated
+		/// database file size.
+		/// <br /><br />
+		/// In client-server environment this setting should be used on the server side. <br /><br />
+		/// Default configuration: 0<br /><br />
+		/// </remarks>
+		/// <param name="byteCount">the number of bytes to reserve</param>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		/// <exception cref="System.NotSupportedException"></exception>
+		void ReserveStorageSpace(long byteCount);
+
+		/// <summary>
+		/// configures the path to be used to store and read
+		/// Blob data.
+		/// </summary>
+		/// <remarks>
+		/// configures the path to be used to store and read
+		/// Blob data.
+		/// <br /><br />
+		/// In client-server environment this setting should be used on the
+		/// server side. <br /><br />
+		/// </remarks>
+		/// <param name="path">the path to be used</param>
+		/// <exception cref="System.IO.IOException"></exception>
+		void SetBlobPath(string path);
+
+		/// <summary>
+		/// Assigns a
+		/// <see cref="System.IO.TextWriter">TextWriter</see>
+		/// where db4o is to print its event messages.
+		/// <br /><br />Messages are useful for debugging purposes and for learning
+		/// to understand, how db4o works. The message level can be raised with
+		/// <see cref="MessageLevel(int)">MessageLevel(int)</see>
+		/// to produce more detailed messages.
+		/// <br /><br />Use <code>setOut(System.out)</code> to print messages to the
+		/// console.<br /><br />
+		/// In client-server environment this setting should be used on the same side
+		/// where
+		/// <see cref="MessageLevel(int)">MessageLevel(int)</see>
+		/// is used.<br /><br />
+		/// </summary>
+		/// <param name="outStream">the new <code>PrintStream</code> for messages.</param>
+		/// <seealso cref="MessageLevel(int)">MessageLevel(int)</seealso>
+		void SetOut(TextWriter outStream);
+
+		/// <summary>configures the string encoding to be used.</summary>
+		/// <remarks>
+		/// configures the string encoding to be used.
+		/// <br/><br/>The string encoding can not be changed in the lifetime of a
+		/// database file. To set up the database with the correct string encoding,
+		/// this configuration needs to be set correctly <b>before</b> a database
+		/// file is created with the first call to
+		/// <see cref="Db4objects.Db4o.Db4oFactory.OpenFile">Db4objects.Db4o.Db4oFactory.OpenFile
+		/// </see>
+		/// or
+		/// <see cref="Db4objects.Db4o.Db4oFactory.OpenServer">Db4objects.Db4o.Db4oFactory.OpenServer
+		/// </see>
+		/// .
+		/// <br/><br/>For subsequent open calls, db4o remembers built-in
+		/// string encodings. If a custom encoding is used (an encoding that is
+		/// not supplied from within the db4o library), the correct encoding
+		/// needs to be configured correctly again for all subsequent calls
+		/// that open database files.
+		/// <br/><br/>Example:<br/>
+		/// <code>config.StringEncoding(StringEncodings.Utf8());</code>
+		/// </remarks>
+		/// <seealso cref="Db4objects.Db4o.Config.Encoding.StringEncodings">Db4objects.Db4o.Config.Encoding.StringEncodings
+		/// </seealso>
+		void StringEncoding(IStringEncoding encoding);
+
+		/// <summary>
+		/// tuning feature: configures whether db4o should try to instantiate one instance
+		/// of each persistent class on system startup.
+		/// </summary>
+		/// <remarks>
+		/// tuning feature: configures whether db4o should try to instantiate one instance
+		/// of each persistent class on system startup.
+		/// <br /><br />In a production environment this setting can be set to <code>false</code>,
+		/// if all persistent classes have public default constructors.
+		/// <br /><br />
+		/// In client-server environment this setting should be used on both client and server
+		/// side. <br /><br />
+		/// Default value:<br />
+		/// <code>true</code>
+		/// </remarks>
+		/// <param name="flag">the desired setting</param>
+		void TestConstructors(bool flag);
+
+		/// <summary>specifies the global updateDepth.</summary>
+		/// <remarks>
+		/// specifies the global updateDepth.
+		/// <br /><br />see the documentation of
+		/// <see cref="com.db4o.ObjectContainer#set"></see>
+		/// for further details.<br /><br />
+		/// The value be may be overridden for individual classes.<br /><br />
+		/// The default setting is 1: Only the object passed to
+		/// <see cref="com.db4o.ObjectContainer#set">com.db4o.ObjectContainer#set</see>
+		/// will be updated.<br /><br />
+		/// In client-server environment this setting should be used on both client and
+		/// server sides.<br /><br />
+		/// </remarks>
+		/// <param name="depth">the depth of the desired update.</param>
+		/// <seealso cref="IObjectClass.UpdateDepth(int)">IObjectClass.UpdateDepth(int)</seealso>
+		/// <seealso cref="IObjectClass.CascadeOnUpdate(bool)">IObjectClass.CascadeOnUpdate(bool)
+		/// 	</seealso>
+		/// <seealso cref="Db4objects.Db4o.Ext.IObjectCallbacks">Using callbacks</seealso>
+		void UpdateDepth(int depth);
+
+		/// <summary>turns weak reference management on or off.</summary>
+		/// <remarks>
+		/// turns weak reference management on or off.
+		/// <br/><br/>
+		/// This method must be called before opening a database.
+		/// <br/><br/>
+		/// Performance may be improved by running db4o without using weak
+		/// references durring memory management at the cost of higher
+		/// memory consumption or by alternatively implementing a manual
+		/// memory management scheme using
+		/// <see cref="IExtObjectContainer.Purge">IExtObjectContainer.Purge</see>
+		/// <br/><br/>Setting the value to <code>false</code> causes db4o to use hard
+		/// references to objects, preventing the garbage collection process
+		/// from disposing of unused objects.
+		/// <br/><br/>The default setting is <code>true</code>.
+		/// </remarks>
+		void WeakReferences(bool flag);
+
+		/// <summary>configures the timer for WeakReference collection.</summary>
+		/// <remarks>
+		/// configures the timer for WeakReference collection.
+		/// <br/><br/>The default setting is 1000 milliseconds.
+		/// <br/><br/>Configure this setting to zero to turn WeakReference
+		/// collection off.
+		/// 
+		/// </remarks>
+		/// <param name="milliseconds">the time in milliseconds</param>
+		void WeakReferenceCollectionInterval(int milliseconds);
+
+		/// <summary>
+		/// allows registering special TypeHandlers for customized marshalling
+		/// and customized comparisons.
+		/// </summary>
+		/// <remarks>
+		/// allows registering special TypeHandlers for customized marshalling
+		/// and customized comparisons.
+		/// </remarks>
+		/// <param name="predicate">
+		/// to specify for which classes and versions the
+		/// TypeHandler is to be used.
+		/// </param>
+		/// <param name="typeHandler">to be used for the classes that match the predicate.</param>
+		void RegisterTypeHandler(ITypeHandlerPredicate predicate, ITypeHandler4 typeHandler
+			);
+
+		/// <seealso cref="ICommonConfiguration.MaxStackDepth()">ICommonConfiguration.MaxStackDepth()
+		/// 	</seealso>
+		int MaxStackDepth();
+
+		/// <seealso cref="ICommonConfiguration.MaxStackDepth(int)"></seealso>
+		void MaxStackDepth(int maxStackDepth);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IConfigurationItem.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IConfigurationItem.cs
new file mode 100644
index 0000000..fbed260
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IConfigurationItem.cs
@@ -0,0 +1,32 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// Implement this interface for configuration items that encapsulate
+	/// a batch of configuration settings or that need to be applied
+	/// to ObjectContainers after they are opened.
+	/// </summary>
+	/// <remarks>
+	/// Implement this interface for configuration items that encapsulate
+	/// a batch of configuration settings or that need to be applied
+	/// to ObjectContainers after they are opened.
+	/// </remarks>
+	public interface IConfigurationItem
+	{
+		/// <summary>Gives a chance for the item to augment the configuration.</summary>
+		/// <remarks>Gives a chance for the item to augment the configuration.</remarks>
+		/// <param name="configuration">the configuration that the item was added to</param>
+		void Prepare(IConfiguration configuration);
+
+		/// <summary>Gives a chance for the item to configure the just opened ObjectContainer.
+		/// 	</summary>
+		/// <remarks>Gives a chance for the item to configure the just opened ObjectContainer.
+		/// 	</remarks>
+		/// <param name="container">the ObjectContainer to configure</param>
+		void Apply(IInternalObjectContainer container);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IEmbeddedConfiguration.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IEmbeddedConfiguration.cs
new file mode 100644
index 0000000..eaf7a52
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IEmbeddedConfiguration.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>Configuration interface for db4o in embedded use.</summary>
+	/// <remarks>Configuration interface for db4o in embedded use.</remarks>
+	/// <since>7.5</since>
+	public interface IEmbeddedConfiguration : IFileConfigurationProvider, ICommonConfigurationProvider
+		, ICacheConfigurationProvider, IIdSystemConfigurationProvider
+	{
+		/// <summary>
+		/// adds ConfigurationItems to be applied when
+		/// a networking
+		/// <see cref="EmbeddedObjectContainer">EmbeddedObjectContainer</see>
+		/// is opened.
+		/// </summary>
+		/// <param name="configItem">
+		/// the
+		/// <see cref="IEmbeddedConfigurationItem">IEmbeddedConfigurationItem</see>
+		/// </param>
+		/// <since>7.12</since>
+		void AddConfigurationItem(IEmbeddedConfigurationItem configItem);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IEmbeddedConfigurationItem.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IEmbeddedConfigurationItem.cs
new file mode 100644
index 0000000..559d1f6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IEmbeddedConfigurationItem.cs
@@ -0,0 +1,33 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// Implement this interface for configuration items that encapsulate
+	/// a batch of configuration settings or that need to be applied
+	/// to EmbeddedObjectContainers after they are opened.
+	/// </summary>
+	/// <remarks>
+	/// Implement this interface for configuration items that encapsulate
+	/// a batch of configuration settings or that need to be applied
+	/// to EmbeddedObjectContainers after they are opened.
+	/// </remarks>
+	/// <since>7.12</since>
+	public interface IEmbeddedConfigurationItem
+	{
+		/// <summary>Gives a chance for the item to augment the configuration.</summary>
+		/// <remarks>Gives a chance for the item to augment the configuration.</remarks>
+		/// <param name="configuration">the configuration that the item was added to</param>
+		void Prepare(IEmbeddedConfiguration configuration);
+
+		/// <summary>Gives a chance for the item to configure the just opened ObjectContainer.
+		/// 	</summary>
+		/// <remarks>Gives a chance for the item to configure the just opened ObjectContainer.
+		/// 	</remarks>
+		/// <param name="container">the ObjectContainer to configure</param>
+		void Apply(IEmbeddedObjectContainer db);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IEnvironmentConfiguration.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IEnvironmentConfiguration.cs
new file mode 100644
index 0000000..570010b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IEnvironmentConfiguration.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>Configures the environment (set of services) used by db4o.</summary>
+	/// <remarks>Configures the environment (set of services) used by db4o.</remarks>
+	/// <seealso cref="Db4objects.Db4o.Foundation.IEnvironment">Db4objects.Db4o.Foundation.IEnvironment
+	/// 	</seealso>
+	/// <seealso cref="Db4objects.Db4o.Foundation.Environments.My(System.Type{T})">Db4objects.Db4o.Foundation.Environments.My(System.Type<T>)
+	/// 	</seealso>
+	public interface IEnvironmentConfiguration
+	{
+		/// <summary>Contributes a service to the db4o environment.</summary>
+		/// <remarks>Contributes a service to the db4o environment.</remarks>
+		/// <param name="service"></param>
+		void Add(object service);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IFileConfiguration.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IFileConfiguration.cs
new file mode 100644
index 0000000..13a53e3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IFileConfiguration.cs
@@ -0,0 +1,316 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.IO;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// File-related configuration methods, applicable
+	/// for db4o embedded use and on the server in a
+	/// Client/Server setup.
+	/// </summary>
+	/// <remarks>
+	/// File-related configuration methods, applicable
+	/// for db4o embedded use and on the server in a
+	/// Client/Server setup.
+	/// </remarks>
+	/// <since>7.5</since>
+	/// <seealso cref="IFileConfigurationProvider.File()">IFileConfigurationProvider.File()
+	/// 	</seealso>
+	public interface IFileConfiguration
+	{
+		/// <summary>sets the storage data blocksize for new ObjectContainers.</summary>
+		/// <remarks>
+		/// sets the storage data blocksize for new ObjectContainers.
+		/// <br /><br />The standard setting is 1 allowing for a maximum
+		/// database file size of 2GB. This value can be increased
+		/// to allow larger database files, although some space will
+		/// be lost to padding because the size of some stored objects
+		/// will not be an exact multiple of the block size. A
+		/// recommended setting for large database files is 8, since
+		/// internal pointers have this length.<br /><br />
+		/// This setting is only effective when the database is first created.
+		/// </remarks>
+		/// <value>the size in bytes from 1 to 127</value>
+		int BlockSize
+		{
+			set;
+		}
+
+		/// <summary>
+		/// configures the size database files should grow in bytes, when no
+		/// free slot is found within.
+		/// </summary>
+		/// <remarks>
+		/// configures the size database files should grow in bytes, when no
+		/// free slot is found within.
+		/// <br /><br />Tuning setting.
+		/// <br /><br />Whenever no free slot of sufficient length can be found
+		/// within the current database file, the database file's length
+		/// is extended. This configuration setting configures by how much
+		/// it should be extended, in bytes.<br /><br />
+		/// This configuration setting is intended to reduce fragmentation.
+		/// Higher values will produce bigger database files and less
+		/// fragmentation.<br /><br />
+		/// To extend the database file, a single byte array is created
+		/// and written to the end of the file in one write operation. Be
+		/// aware that a high setting will require allocating memory for
+		/// this byte array.
+		/// </remarks>
+		/// <value>amount of bytes</value>
+		int DatabaseGrowthSize
+		{
+			set;
+		}
+
+		/// <summary>turns commit recovery off.</summary>
+		/// <remarks>
+		/// turns commit recovery off.
+		/// <br /><br />db4o uses a two-phase commit algorithm. In a first step all intended
+		/// changes are written to a free place in the database file, the "transaction commit
+		/// record". In a second step the
+		/// actual changes are performed. If the system breaks down during commit, the
+		/// commit process is restarted when the database file is opened the next time.
+		/// On very rare occasions (possibilities: hardware failure or editing the database
+		/// file with an external tool) the transaction commit record may be broken. In this
+		/// case, this method can be used to try to open the database file without commit
+		/// recovery. The method should only be used in emergency situations after consulting
+		/// db4o support.
+		/// </remarks>
+		void DisableCommitRecovery();
+
+		/// <summary>returns the freespace configuration interface.</summary>
+		/// <remarks>returns the freespace configuration interface.</remarks>
+		IFreespaceConfiguration Freespace
+		{
+			get;
+		}
+
+		/// <summary>configures db4o to generate UUIDs for stored objects.</summary>
+		/// <remarks>
+		/// configures db4o to generate UUIDs for stored objects.
+		/// This setting should be used when the database is first created.<br /><br />
+		/// </remarks>
+		/// <value>the scope for UUID generation: disabled, generate for all classes, or configure individually
+		/// 	</value>
+		ConfigScope GenerateUUIDs
+		{
+			set;
+		}
+
+		/// <summary>configures db4o to generate version numbers for stored objects.</summary>
+		/// <remarks>
+		/// configures db4o to generate version numbers for stored objects.
+		/// This setting should be used when the database is first created.
+		/// </remarks>
+		/// <value>the scope for version number generation: disabled, generate for all classes, or configure individually
+		/// 	</value>
+		[System.ObsoleteAttribute(@"As of version 8.0 please use GenerateCommitTimestamps(bool) instead."
+			)]
+		ConfigScope GenerateVersionNumbers
+		{
+			set;
+		}
+
+		/// <summary>
+		/// Configures db4o to generate commit timestamps for all stored objects.<br />
+		/// <br />
+		/// All the objects commited within a transaction will share the same commit timestamp.
+		/// </summary>
+		/// <remarks>
+		/// Configures db4o to generate commit timestamps for all stored objects.<br />
+		/// <br />
+		/// All the objects commited within a transaction will share the same commit timestamp.
+		/// <br />
+		/// This setting should be used when the database is first created.<br />
+		/// <br />
+		/// Afterwards you can access the object's commit timestamp like this:<br />
+		/// <br />
+		/// <pre>
+		/// ObjectContainer container = ...;
+		/// ObjectInfo objectInfo = container.ext().getObjectInfo(obj);
+		/// long commitTimestamp = objectInfo.getVersion();
+		/// </pre>
+		/// </remarks>
+		/// <value>
+		/// if true, commit timetamps will be generated for all stored
+		/// objects. If you already have commit timestamps for stored
+		/// objects and later set this flag to false, although you wont be
+		/// able to access them, the commit timestamps will still be taking
+		/// space in your file container. The only way to free that space
+		/// is defragmenting the container.
+		/// </value>
+		/// <since>8.0</since>
+		bool GenerateCommitTimestamps
+		{
+			set;
+		}
+
+		/// <summary>allows to configure db4o to use a customized byte IO storage mechanism.</summary>
+		/// <remarks>
+		/// allows to configure db4o to use a customized byte IO storage mechanism.
+		/// <br /><br />You can implement the interface
+		/// <see cref="Db4objects.Db4o.IO.IStorage">Db4objects.Db4o.IO.IStorage</see>
+		/// to
+		/// write your own. Possible usecases could be improved performance
+		/// with a native library, mirrored write to two files, encryption or
+		/// read-on-write fail-safety control.<br /><br />
+		/// </remarks>
+		/// <value>- the storage</value>
+		/// <seealso cref="Db4objects.Db4o.IO.FileStorage">Db4objects.Db4o.IO.FileStorage</seealso>
+		/// <seealso cref="Db4objects.Db4o.IO.CachingStorage">Db4objects.Db4o.IO.CachingStorage
+		/// 	</seealso>
+		/// <seealso cref="Db4objects.Db4o.IO.MemoryStorage">Db4objects.Db4o.IO.MemoryStorage
+		/// 	</seealso>
+		/// <exception cref="Db4objects.Db4o.Config.GlobalOnlyConfigException"></exception>
+		/// <summary>
+		/// returns the configured
+		/// <see cref="Db4objects.Db4o.IO.IStorage">Db4objects.Db4o.IO.IStorage</see>
+		/// .
+		/// </summary>
+		/// <returns></returns>
+		IStorage Storage
+		{
+			get;
+			set;
+		}
+
+		/// <summary>can be used to turn the database file locking thread off.</summary>
+		/// <remarks>
+		/// can be used to turn the database file locking thread off.
+		/// <br/><br/><b>Caution!</b><br/>If database file
+		/// locking is turned off, concurrent write access to the same
+		/// database file from different sessions will <b>corrupt</b> the
+		/// database file immediately.<br/><br/> This method
+		/// has no effect on open ObjectContainers. It will only affect how
+		/// ObjectContainers are opened.<br/><br/>
+		/// The default setting is <code>true</code>.<br/><br/>
+		/// 
+		/// </remarks>
+		bool LockDatabaseFile
+		{
+			set;
+		}
+
+		/// <summary>tuning feature only: reserves a number of bytes in database files.</summary>
+		/// <remarks>
+		/// tuning feature only: reserves a number of bytes in database files.
+		/// <br /><br />The global setting is used for the creation of new database
+		/// files.
+		/// <br /><br />Without this setting, storage space will be allocated
+		/// continuously as required. However, allocation of a fixed number
+		/// of bytes at one time makes it more likely that the database will be
+		/// stored in one chunk on the mass storage. Less read/write head movement
+		/// can result in improved performance.<br /><br />
+		/// <b>Note:</b><br /> Allocated space will be lost on abnormal termination
+		/// of the database engine (hardware crash, VM crash). A Defragment run
+		/// will recover the lost space. For the best possible performance, this
+		/// method should be called before the Defragment run to configure the
+		/// allocation of storage space to be slightly greater than the anticipated
+		/// database file size.
+		/// <br /><br />
+		/// Default configuration: 0<br /><br />
+		/// </remarks>
+		/// <value>the number of bytes to reserve</value>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		/// <exception cref="System.NotSupportedException"></exception>
+		long ReserveStorageSpace
+		{
+			set;
+		}
+
+		/// <summary>
+		/// configures the path to be used to store and read
+		/// Blob data.
+		/// </summary>
+		/// <remarks>
+		/// configures the path to be used to store and read
+		/// Blob data.
+		/// <br /><br />
+		/// </remarks>
+		/// <value>the path to be used</value>
+		/// <exception cref="System.IO.IOException"></exception>
+		string BlobPath
+		{
+			set;
+		}
+
+		/// <summary>turns readOnly mode on and off.</summary>
+		/// <remarks>
+		/// turns readOnly mode on and off.
+		/// <br /><br />This method configures the mode in which subsequent calls to
+		/// <see cref="Db4objects.Db4o.Db4oEmbedded.OpenFile(IEmbeddedConfiguration, string)"
+		/// 	>Db4objects.Db4o.Db4oEmbedded.OpenFile(IEmbeddedConfiguration, string)</see>
+		/// 
+		/// will open files.
+		/// <br /><br />Readonly mode allows to open an unlimited number of reading
+		/// processes on one database file. It is also convenient
+		/// for deploying db4o database files on CD-ROM.<br /><br />
+		/// </remarks>
+		/// <value>
+		/// <code>true</code> for configuring readOnly mode for subsequent
+		/// calls to
+		/// <see cref="Db4objects.Db4o.Db4oFactory.OpenFile(string)">Db4o.openFile()</see>
+		/// .
+		/// TODO: this is rather embedded + client than base?
+		/// </value>
+		bool ReadOnly
+		{
+			set;
+		}
+
+		/// <summary>
+		/// turns recovery mode on and off.<br /><br />
+		/// Recovery mode can be used to try to retrieve as much as possible
+		/// out of an already corrupted database.
+		/// </summary>
+		/// <remarks>
+		/// turns recovery mode on and off.<br /><br />
+		/// Recovery mode can be used to try to retrieve as much as possible
+		/// out of an already corrupted database. In recovery mode internal
+		/// checks are more relaxed. Null or invalid objects may be returned
+		/// instead of throwing exceptions.<br /><br />
+		/// Use this method with care as a last resort to get data out of a
+		/// corrupted database.
+		/// </remarks>
+		/// <value><code>true</code> to turn recover mode on.</value>
+		bool RecoveryMode
+		{
+			set;
+		}
+
+		/// <summary>
+		/// turns asynchronous sync on and off.<br /><br />
+		/// One of the most costly operations during commit is the call to
+		/// flush the buffers of the database file.
+		/// </summary>
+		/// <remarks>
+		/// turns asynchronous sync on and off.<br /><br />
+		/// One of the most costly operations during commit is the call to
+		/// flush the buffers of the database file. In regular mode the
+		/// commit call has to wait until this operation has completed.
+		/// When asynchronous sync is turned on, the sync operation will
+		/// run in a dedicated thread, blocking all other file access
+		/// until it has completed. This way the commit call can return
+		/// immediately. This will allow db4o and other processes to
+		/// continue running side-by-side while the flush call executes.
+		/// Use this setting with care: It means that you can not be sure
+		/// when a commit call has actually made the changes of a
+		/// transaction durable (flushed through OS and file system
+		/// buffers). The latency time until flushing happens is extremely
+		/// short. The dedicated sync thread does nothing else
+		/// except for calling sync and writing the header of the database
+		/// file when needed. A setup with this option still guarantees
+		/// ACID transaction processing: A database file always will be
+		/// either in the state before commit or in the state after
+		/// commit. Corruption can not occur. You can just not rely
+		/// on the transaction already having been applied when the
+		/// commit() call returns.
+		/// </remarks>
+		bool AsynchronousSync
+		{
+			set;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IFileConfigurationProvider.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IFileConfigurationProvider.cs
new file mode 100644
index 0000000..1341cf1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IFileConfigurationProvider.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// A configuration provider that provides access
+	/// to the file-related configuration methods.
+	/// </summary>
+	/// <remarks>
+	/// A configuration provider that provides access
+	/// to the file-related configuration methods.
+	/// </remarks>
+	public interface IFileConfigurationProvider
+	{
+		/// <summary>Access to the file-related configuration methods.</summary>
+		/// <remarks>Access to the file-related configuration methods.</remarks>
+		IFileConfiguration File
+		{
+			get;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IFreespaceConfiguration.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IFreespaceConfiguration.cs
new file mode 100644
index 0000000..fe607a4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IFreespaceConfiguration.cs
@@ -0,0 +1,86 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>interface to configure the freespace system to be used.</summary>
+	/// <remarks>
+	/// interface to configure the freespace system to be used.
+	/// <br /><br />All methods should be called before opening database files.
+	/// If db4o is instructed to exchange the system
+	/// (
+	/// <see cref="UseBTreeSystem()">UseBTreeSystem()</see>
+	/// ,
+	/// <see cref="UseRamSystem()">UseRamSystem()</see>
+	/// )
+	/// this will happen on opening the database file.<br /><br />
+	/// By default the ram based system will be used.
+	/// </remarks>
+	public interface IFreespaceConfiguration
+	{
+		/// <summary>
+		/// tuning feature: configures the minimum size of free space slots in the database file
+		/// that are to be reused.
+		/// </summary>
+		/// <remarks>
+		/// tuning feature: configures the minimum size of free space slots in the database file
+		/// that are to be reused.
+		/// <br /><br />When objects are updated or deleted, the space previously occupied in the
+		/// database file is marked as "free", so it can be reused. db4o maintains two lists
+		/// in RAM, sorted by address and by size. Adjacent entries are merged. After a large
+		/// number of updates or deletes have been executed, the lists can become large, causing
+		/// RAM consumption and performance loss for maintenance. With this method you can
+		/// specify an upper bound for the byte slot size to discard.
+		/// <br /><br />Pass <code>Integer.MAX_VALUE</code> to this method to discard all free slots for
+		/// the best possible startup time.<br /><br />
+		/// The downside of setting this value: Database files will necessarily grow faster.
+		/// <br /><br />Default value:<br />
+		/// <code>0</code> all space is reused
+		/// </remarks>
+		/// <param name="byteCount">Slots with this size or smaller will be lost.</param>
+		void DiscardSmallerThan(int byteCount);
+
+		/// <summary>
+		/// Configure a way to overwrite freed space in the database file with custom
+		/// (for example: random) bytes.
+		/// </summary>
+		/// <remarks>
+		/// Configure a way to overwrite freed space in the database file with custom
+		/// (for example: random) bytes. Will slow down I/O operation.
+		/// The value of this setting may be cached internally and can thus not be
+		/// reliably set after an object container has been opened.
+		/// </remarks>
+		/// <param name="freespaceFiller">The freespace overwriting callback to use</param>
+		void FreespaceFiller(IFreespaceFiller freespaceFiller);
+
+		/// <summary>configures db4o to use a BTree-based freespace system.</summary>
+		/// <remarks>
+		/// configures db4o to use a BTree-based freespace system.
+		/// <br /><br /><b>Advantages</b><br />
+		/// - ACID, no freespace is lost on abnormal system termination<br />
+		/// - low memory consumption<br />
+		/// <br /><b>Disadvantages</b><br />
+		/// - slower than the RAM-based system, since freespace information
+		/// is written during every commit<br />
+		/// </remarks>
+		void UseBTreeSystem();
+
+		/// <summary>discontinued freespace system, only available before db4o 7.0.</summary>
+		/// <remarks>discontinued freespace system, only available before db4o 7.0.</remarks>
+		[System.ObsoleteAttribute(@"Please use the BTree freespace system instead by calling UseBTreeSystem() ."
+			)]
+		void UseIndexSystem();
+
+		/// <summary>configures db4o to use a RAM-based freespace system.</summary>
+		/// <remarks>
+		/// configures db4o to use a RAM-based freespace system.
+		/// <br /><br /><b>Advantages</b><br />
+		/// - best performance<br />
+		/// <br /><b>Disadvantages</b><br />
+		/// - upon abnormal system termination all freespace is lost<br />
+		/// - memory consumption<br />
+		/// </remarks>
+		void UseRamSystem();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IFreespaceFiller.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IFreespaceFiller.cs
new file mode 100644
index 0000000..b8894b2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IFreespaceFiller.cs
@@ -0,0 +1,17 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.IO;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>Callback hook for overwriting freed space in the database file.</summary>
+	/// <remarks>Callback hook for overwriting freed space in the database file.</remarks>
+	public interface IFreespaceFiller
+	{
+		/// <summary>Called to overwrite freed space in the database file.</summary>
+		/// <remarks>Called to overwrite freed space in the database file.</remarks>
+		/// <param name="io">Handle for the freed slot</param>
+		/// <exception cref="System.IO.IOException"></exception>
+		void Fill(BlockAwareBinWindow io);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IIdSystemConfiguration.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IIdSystemConfiguration.cs
new file mode 100644
index 0000000..77ca9ce
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IIdSystemConfiguration.cs
@@ -0,0 +1,59 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>Interface to configure the IdSystem.</summary>
+	/// <remarks>Interface to configure the IdSystem.</remarks>
+	public interface IIdSystemConfiguration
+	{
+		/// <summary>configures db4o to store IDs as pointers.</summary>
+		/// <remarks>configures db4o to store IDs as pointers.</remarks>
+		void UsePointerBasedSystem();
+
+		/// <summary>
+		/// configures db4o to use a stack of two BTreeIdSystems on
+		/// top of an InMemoryIdSystem.
+		/// </summary>
+		/// <remarks>
+		/// configures db4o to use a stack of two BTreeIdSystems on
+		/// top of an InMemoryIdSystem. This setup is scalable for
+		/// large numbers of IDs. It is the default configuration
+		/// when new databases are created.
+		/// </remarks>
+		void UseStackedBTreeSystem();
+
+		/// <summary>
+		/// configures db4o to use a single BTreeIdSystem on
+		/// top of an InMemoryIdSystem.
+		/// </summary>
+		/// <remarks>
+		/// configures db4o to use a single BTreeIdSystem on
+		/// top of an InMemoryIdSystem. This setup is suitable for
+		/// smaller databases with a small number of IDs.
+		/// For larger numbers of IDs call
+		/// <see cref="UseStackedBTreeSystem()">UseStackedBTreeSystem()</see>
+		/// .
+		/// </remarks>
+		void UseSingleBTreeSystem();
+
+		/// <summary>configures db4o to use an in-memory ID system.</summary>
+		/// <remarks>
+		/// configures db4o to use an in-memory ID system.
+		/// All IDs get written to the database file on every commit.
+		/// </remarks>
+		void UseInMemorySystem();
+
+		/// <summary>configures db4o to use a custom ID system.</summary>
+		/// <remarks>
+		/// configures db4o to use a custom ID system.
+		/// Pass an
+		/// <see cref="IIdSystemFactory">IIdSystemFactory</see>
+		/// that creates the IdSystem.
+		/// Note that this factory has to be configured every time you
+		/// open a database that you configured to use a custom IdSystem.
+		/// </remarks>
+		void UseCustomSystem(IIdSystemFactory factory);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IIdSystemConfigurationProvider.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IIdSystemConfigurationProvider.cs
new file mode 100644
index 0000000..88631aa
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IIdSystemConfigurationProvider.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// A configuration provider that provides access
+	/// to the IdSystem-related configuration methods.
+	/// </summary>
+	/// <remarks>
+	/// A configuration provider that provides access
+	/// to the IdSystem-related configuration methods.
+	/// </remarks>
+	public interface IIdSystemConfigurationProvider
+	{
+		/// <summary>Access to the IdSystem-related configuration methods.</summary>
+		/// <remarks>Access to the IdSystem-related configuration methods.</remarks>
+		IIdSystemConfiguration IdSystem
+		{
+			get;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IIdSystemFactory.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IIdSystemFactory.cs
new file mode 100644
index 0000000..aff6124
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IIdSystemFactory.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Ids;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>Factory interface to create a custom IdSystem.</summary>
+	/// <remarks>Factory interface to create a custom IdSystem.</remarks>
+	/// <seealso cref="IIdSystemConfiguration.UseCustomSystem(IIdSystemFactory)"></seealso>
+	public interface IIdSystemFactory
+	{
+		/// <summary>creates</summary>
+		/// <param name="container"></param>
+		/// <returns></returns>
+		IIdSystem NewInstance(LocalObjectContainer container);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ILegacyClientServerFactory.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ILegacyClientServerFactory.cs
new file mode 100644
index 0000000..da1f47c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/ILegacyClientServerFactory.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <exclude></exclude>
+	public interface ILegacyClientServerFactory
+	{
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.OldFormatException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.InvalidPasswordException"></exception>
+		IObjectContainer OpenClient(IConfiguration config, string hostName, int port, string
+			 user, string password);
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.IncompatibleFileFormatException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.OldFormatException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseFileLockedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		IObjectServer OpenServer(IConfiguration config, string databaseFileName, int port
+			);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/INameProvider.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/INameProvider.cs
new file mode 100644
index 0000000..9b3ab30
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/INameProvider.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>A provider for custom database names.</summary>
+	/// <remarks>A provider for custom database names.</remarks>
+	public interface INameProvider
+	{
+		/// <summary>
+		/// Derives a name for the given
+		/// <see cref="Db4objects.Db4o.IObjectContainer">Db4objects.Db4o.IObjectContainer</see>
+		/// . This method will be called when
+		/// database startup has completed, i.e. the method will see a completely initialized
+		/// <see cref="Db4objects.Db4o.IObjectContainer">Db4objects.Db4o.IObjectContainer</see>
+		/// .
+		/// Any code invoked during the startup process (for example
+		/// <see cref="IConfigurationItem">IConfigurationItem</see>
+		/// instances) will still
+		/// see the default naming.
+		/// </summary>
+		string Name(IObjectContainer db);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IObjectAttribute.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IObjectAttribute.cs
new file mode 100644
index 0000000..3a851fd
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IObjectAttribute.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>generic interface to allow returning an attribute of an object.</summary>
+	/// <remarks>generic interface to allow returning an attribute of an object.</remarks>
+	public interface IObjectAttribute
+	{
+		/// <summary>generic method to return an attribute of a parent object.</summary>
+		/// <remarks>generic method to return an attribute of a parent object.</remarks>
+		/// <param name="parent">the parent object</param>
+		/// <returns>Object - the attribute</returns>
+		object Attribute(object parent);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IObjectClass.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IObjectClass.cs
new file mode 100644
index 0000000..efa3a9f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IObjectClass.cs
@@ -0,0 +1,347 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>configuration interface for classes.</summary>
+	/// <remarks>
+	/// configuration interface for classes.
+	/// <br /><br />
+	/// Use the global
+	/// <see cref="ICommonConfiguration.ObjectClass(object)">ICommonConfiguration.ObjectClass(object)
+	/// 	</see>
+	/// to configure
+	/// object class settings.
+	/// </remarks>
+	public interface IObjectClass
+	{
+		/// <summary>
+		/// advises db4o to try instantiating objects of this class with/without
+		/// calling constructors.
+		/// </summary>
+		/// <remarks>
+		/// advises db4o to try instantiating objects of this class with/without
+		/// calling constructors.
+		/// <br/><br/>
+		/// Not all .NET-environments support this feature. db4o will
+		/// attempt, to follow the setting as good as the enviroment supports.
+		/// <br/><br/>
+		/// This setting may also be set globally for all classes in
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration.CallConstructors">Db4objects.Db4o.Config.IConfiguration.CallConstructors
+		/// </see>
+		/// .<br/><br/>
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br/><br/>
+		/// This setting can be applied to an open object container. <br/><br/>
+		/// </remarks>
+		/// <param name="flag">
+		/// - specify true, to request calling constructors, specify
+		/// false to request <b>not</b> calling constructors.
+		/// </param>
+		/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.CallConstructors">Db4objects.Db4o.Config.IConfiguration.CallConstructors
+		/// </seealso>
+		void CallConstructor(bool flag);
+
+		/// <summary>sets cascaded activation behaviour.</summary>
+		/// <remarks>
+		/// sets cascaded activation behaviour.
+		/// <br /><br />
+		/// Setting cascadeOnActivate to true will result in the activation
+		/// of all member objects if an instance of this class is activated.
+		/// <br /><br />
+		/// The default setting is <b>false</b>.<br /><br />
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br /><br />
+		/// Can be applied to an open ObjectContainer.<br /><br />
+		/// </remarks>
+		/// <param name="flag">whether activation is to be cascaded to member objects.</param>
+		/// <seealso cref="IObjectField.CascadeOnActivate(bool)">IObjectField.CascadeOnActivate(bool)
+		/// 	</seealso>
+		/// <seealso cref="Db4objects.Db4o.IObjectContainer.Activate(object, int)">Db4objects.Db4o.IObjectContainer.Activate(object, int)
+		/// 	</seealso>
+		/// <seealso cref="Db4objects.Db4o.Ext.IObjectCallbacks">Using callbacks</seealso>
+		/// <seealso cref="IConfiguration.ActivationDepth()">Why activation?</seealso>
+		void CascadeOnActivate(bool flag);
+
+		/// <summary>sets cascaded delete behaviour.</summary>
+		/// <remarks>
+		/// sets cascaded delete behaviour.
+		/// <br/><br/>
+		/// Setting CascadeOnDelete to true will result in the deletion of
+		/// all member objects of instances of this class, if they are
+		/// passed to
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Delete">Db4objects.Db4o.IObjectContainer.Delete
+		/// </see>
+		/// .
+		/// <br/><br/>
+		/// <b>Caution !</b><br/>
+		/// This setting will also trigger deletion of old member objects, on
+		/// calls to
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Store">Db4objects.Db4o.IObjectContainer.Store
+		/// </see>
+		/// .<br/><br/>
+		/// An example of the behaviour:<br/>
+		/// <code>
+		/// ObjectContainer con;<br/>
+		/// Bar bar1 = new Bar();<br/>
+		/// Bar bar2 = new Bar();<br/>
+		/// foo.bar = bar1;<br/>
+		/// con.Store(foo);  // bar1 is stored as a member of foo<br/>
+		/// foo.bar = bar2;<br/>
+		/// con.Store(foo);  // bar2 is stored as a member of foo
+		/// </code><br/>The last statement will <b>also</b> delete bar1 from the
+		/// ObjectContainer, no matter how many other stored objects hold references
+		/// to bar1.
+		/// <br/><br/>
+		/// The default setting is <b>false</b>.<br/><br/>
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br/><br/>
+		/// This setting can be applied to an open object container. <br/><br/>
+		/// </remarks>
+		/// <param name="flag">whether deletes are to be cascaded to member objects.</param>
+		/// <seealso cref="Db4objects.Db4o.Config.IObjectField.CascadeOnDelete">Db4objects.Db4o.Config.IObjectField.CascadeOnDelete
+		/// </seealso>
+		/// <seealso cref="Db4objects.Db4o.IObjectContainer.Delete">Db4objects.Db4o.IObjectContainer.Delete
+		/// </seealso>
+		/// <seealso cref="Db4objects.Db4o.Ext.IObjectCallbacks">Using callbacks</seealso>
+		void CascadeOnDelete(bool flag);
+
+		/// <summary>sets cascaded update behaviour.</summary>
+		/// <remarks>
+		/// sets cascaded update behaviour.
+		/// <br /><br />
+		/// Setting cascadeOnUpdate to true will result in the update
+		/// of all member objects if a stored instance of this class is passed
+		/// to
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Store(object)">Db4objects.Db4o.IObjectContainer.Store(object)
+		/// 	</see>
+		/// .<br /><br />
+		/// The default setting is <b>false</b>. Setting it to true
+		/// may result in serious performance degradation.<br /><br />
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br /><br />
+		/// This setting can be applied to an open object container. <br /><br />
+		/// </remarks>
+		/// <param name="flag">whether updates are to be cascaded to member objects.</param>
+		/// <seealso cref="IObjectField.CascadeOnUpdate(bool)">IObjectField.CascadeOnUpdate(bool)
+		/// 	</seealso>
+		/// <seealso cref="com.db4o.ObjectContainer#set">com.db4o.ObjectContainer#set</seealso>
+		/// <seealso cref="Db4objects.Db4o.Ext.IObjectCallbacks">Using callbacks</seealso>
+		void CascadeOnUpdate(bool flag);
+
+		/// <summary>registers an attribute provider for special query behavior.</summary>
+		/// <remarks>
+		/// registers an attribute provider for special query behavior.
+		/// <br /><br />The query processor will compare the object returned by the
+		/// attribute provider instead of the actual object, both for the constraint
+		/// and the candidate persistent object.<br /><br />
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br /><br />
+		/// </remarks>
+		/// <param name="attributeProvider">the attribute provider to be used</param>
+		[System.ObsoleteAttribute(@"since version 7.0")]
+		void Compare(IObjectAttribute attributeProvider);
+
+		/// <summary>
+		/// Must be called before databases are created or opened
+		/// so that db4o will control versions and generate UUIDs
+		/// for objects of this class, which is required for using replication.
+		/// </summary>
+		/// <remarks>
+		/// Must be called before databases are created or opened
+		/// so that db4o will control versions and generate UUIDs
+		/// for objects of this class, which is required for using replication.
+		/// </remarks>
+		/// <param name="setting"></param>
+		[System.ObsoleteAttribute(@"As of version 8.0 please use GenerateUUIDs(bool) and IFileConfiguration.GenerateCommitTimestamps(bool) instead"
+			)]
+		void EnableReplication(bool setting);
+
+		/// <summary>generate UUIDs for stored objects of this class.</summary>
+		/// <remarks>
+		/// generate UUIDs for stored objects of this class.
+		/// This setting should be used before the database is first created.<br /><br />
+		/// </remarks>
+		/// <param name="setting"></param>
+		void GenerateUUIDs(bool setting);
+
+		/// <summary>generate version numbers for stored objects of this class.</summary>
+		/// <remarks>
+		/// generate version numbers for stored objects of this class.
+		/// This setting should be used before the database is first created.<br /><br />
+		/// </remarks>
+		/// <param name="setting"></param>
+		[System.ObsoleteAttribute(@"As of version 8.0 please use IFileConfiguration.GenerateCommitTimestamps(bool) instead"
+			)]
+		void GenerateVersionNumbers(bool setting);
+
+		/// <summary>turns the class index on or off.</summary>
+		/// <remarks>
+		/// turns the class index on or off.
+		/// <br /><br />db4o maintains an index for each class to be able to
+		/// deliver all instances of a class in a query. If the class
+		/// index is never needed, it can be turned off with this method
+		/// to improve the performance to create and delete objects of
+		/// a class.
+		/// <br /><br />Common cases where a class index is not needed:<br />
+		/// - The application always works with sub classes or super classes.<br />
+		/// - There are convenient field indexes that will always find instances
+		/// of a class.<br />
+		/// - The application always works with IDs.<br /><br />
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br /><br />
+		/// This setting can be applied to an open object container. <br /><br />
+		/// </remarks>
+		void Indexed(bool flag);
+
+		/// <summary>sets the maximum activation depth to the desired value.</summary>
+		/// <remarks>
+		/// sets the maximum activation depth to the desired value.
+		/// <br /><br />A class specific setting overrides the
+		/// <see cref="IConfiguration.ActivationDepth(int)">global setting</see>
+		/// <br /><br />
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br /><br />
+		/// This setting can be applied to an open object container. <br /><br />
+		/// </remarks>
+		/// <param name="depth">the desired maximum activation depth</param>
+		/// <seealso cref="IConfiguration.ActivationDepth()">Why activation?</seealso>
+		/// <seealso cref="CascadeOnActivate(bool)">CascadeOnActivate(bool)</seealso>
+		void MaximumActivationDepth(int depth);
+
+		/// <summary>sets the minimum activation depth to the desired value.</summary>
+		/// <remarks>
+		/// sets the minimum activation depth to the desired value.
+		/// <br /><br />A class specific setting overrides the
+		/// <see cref="IConfiguration.ActivationDepth(int)">global setting</see>
+		/// <br /><br />
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br /><br />
+		/// This setting can be applied to an open object container. <br /><br />
+		/// </remarks>
+		/// <param name="depth">the desired minimum activation depth</param>
+		/// <seealso cref="IConfiguration.ActivationDepth()">Why activation?</seealso>
+		/// <seealso cref="CascadeOnActivate(bool)">CascadeOnActivate(bool)</seealso>
+		void MinimumActivationDepth(int depth);
+
+		/// <summary>gets the configured minimum activation depth.</summary>
+		/// <remarks>
+		/// gets the configured minimum activation depth.
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br /><br />
+		/// </remarks>
+		/// <returns>the configured minimum activation depth.</returns>
+		int MinimumActivationDepth();
+
+		/// <summary>
+		/// returns an
+		/// <see cref="IObjectField">IObjectField</see>
+		/// object
+		/// to configure the specified field.
+		/// <br /><br />
+		/// </summary>
+		/// <param name="fieldName">the name of the field to be configured.<br /><br /></param>
+		/// <returns>
+		/// an instance of an
+		/// <see cref="IObjectField">IObjectField</see>
+		/// object for configuration.
+		/// </returns>
+		IObjectField ObjectField(string fieldName);
+
+		/// <summary>turns on storing static field values for this class.</summary>
+		/// <remarks>
+		/// turns on storing static field values for this class.
+		/// <br/><br/>By default, static field values of classes are not stored
+		/// to the database file. By turning the setting on for a specific class
+		/// with this switch, all <b>non-simple-typed</b> static field values of this
+		/// class are stored the first time an object of the class is stored, and
+		/// restored, every time a database file is opened afterwards, <b>after
+		/// class meta information is loaded for this class</b> (which can happen
+		/// by querying for a class or by loading an instance of a class).<br/><br/>
+		/// To update a static field value, once it is stored, you have to the following
+		/// in this order:<br/>
+		/// (1) open the database file you are working agains<br/>
+		/// (2) make sure the class metadata is loaded<br/>
+		/// <code>objectContainer.Query().Constrain(typeof(Foo)); </code><br/>
+		/// (3) change the static member<br/>
+		/// (4) store the static member explicitely<br/>
+		/// <code>objectContainer.Store(Foo.staticMember); </code>
+		/// <br/><br/>The setting will be ignored for simple types.
+		/// <br/><br/>Use this setting for constant static object members.
+		/// <br/><br/>This option will slow down the process of opening database
+		/// files and the stored objects will occupy space in the database file.
+		/// <br/><br/>In client-server environment this setting should be used on both
+		/// client and server. <br/><br/>
+		/// This setting can NOT be applied to an open object container. <br/><br/>
+		/// </remarks>
+		void PersistStaticFieldValues();
+
+		/// <summary>renames a stored class.</summary>
+		/// <remarks>
+		/// renames a stored class.
+		/// <br /><br />Use this method to refactor classes.
+		/// <br /><br />In client-server environment this setting should be used on both
+		/// client and server. <br /><br />
+		/// This setting can NOT be applied to an open object container. <br /><br />
+		/// </remarks>
+		/// <param name="newName">the new fully qualified class name.</param>
+		void Rename(string newName);
+
+		/// <summary>allows to specify if transient fields are to be stored.</summary>
+		/// <remarks>
+		/// allows to specify if transient fields are to be stored.
+		/// <br />The default for every class is <code>false</code>.<br /><br />
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br /><br />
+		/// This setting can be applied to an open object container. <br /><br />
+		/// </remarks>
+		/// <param name="flag">whether or not transient fields are to be stored.</param>
+		void StoreTransientFields(bool flag);
+
+		/// <summary>registers a translator for this class.</summary>
+		/// <remarks>
+		/// registers a translator for this class.
+		/// <br /><br />
+		/// <br /><br />The use of an
+		/// <see cref="IObjectTranslator">IObjectTranslator</see>
+		/// is not
+		/// compatible with the use of an
+		/// internal class ObjectMarshaller.<br /><br />
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br /><br />
+		/// This setting can be applied to an open object container. <br /><br />
+		/// </remarks>
+		/// <param name="translator">
+		/// this may be an
+		/// <see cref="IObjectTranslator">IObjectTranslator</see>
+		/// or an
+		/// <see cref="IObjectConstructor">IObjectConstructor</see>
+		/// </param>
+		/// <seealso cref="IObjectTranslator">IObjectTranslator</seealso>
+		/// <seealso cref="IObjectConstructor">IObjectConstructor</seealso>
+		void Translate(IObjectTranslator translator);
+
+		/// <summary>specifies the updateDepth for this class.</summary>
+		/// <remarks>
+		/// specifies the updateDepth for this class.
+		/// <br /><br />see the documentation of
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Store(object)">Db4objects.Db4o.IObjectContainer.Store(object)
+		/// 	</see>
+		/// for further details.<br /><br />
+		/// The default setting is 0: Only the object passed to
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Store(object)">Db4objects.Db4o.IObjectContainer.Store(object)
+		/// 	</see>
+		/// will be updated.<br /><br />
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br /><br />
+		/// </remarks>
+		/// <param name="depth">the depth of the desired update for this class.</param>
+		/// <seealso cref="IConfiguration.UpdateDepth(int)">IConfiguration.UpdateDepth(int)</seealso>
+		/// <seealso cref="CascadeOnUpdate(bool)">CascadeOnUpdate(bool)</seealso>
+		/// <seealso cref="IObjectField.CascadeOnUpdate(bool)">IObjectField.CascadeOnUpdate(bool)
+		/// 	</seealso>
+		/// <seealso cref="Db4objects.Db4o.Ext.IObjectCallbacks">Using callbacks</seealso>
+		void UpdateDepth(int depth);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IObjectConstructor.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IObjectConstructor.cs
new file mode 100644
index 0000000..9ddd176
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IObjectConstructor.cs
@@ -0,0 +1,46 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// interface to allow instantiating objects by calling specific constructors.
+	/// 
+	/// </summary>
+	/// <remarks>
+	/// interface to allow instantiating objects by calling specific constructors.
+	/// <br/><br/>
+	/// By writing classes that implement this interface, it is possible to
+	/// define which constructor is to be used during the instantiation of a stored object.
+	/// <br/><br/>
+	/// Before starting a db4o session, translator classes that implement the
+	/// <code>ObjectConstructor</code> or
+	/// <see cref="IObjectTranslator">IObjectTranslator</see>
+	/// need to be registered.<br/><br/>
+	/// Example:<br/>
+	/// <code>
+	/// IConfiguration config = Db4oFactory.Configure();<br/>
+	/// IObjectClass oc = config.ObjectClass("Namespace.ClassName");<br/>
+	/// oc.Translate(new FooTranslator());
+	/// </code><br/><br/>
+	/// </remarks>
+	public interface IObjectConstructor : IObjectTranslator
+	{
+		/// <summary>db4o calls this method when a stored object needs to be instantiated.</summary>
+		/// <remarks>
+		/// db4o calls this method when a stored object needs to be instantiated.
+		/// <br /><br />
+		/// </remarks>
+		/// <param name="container">the ObjectContainer used</param>
+		/// <param name="storedObject">
+		/// the object stored with
+		/// <see cref="IObjectTranslator.OnStore(Db4objects.Db4o.IObjectContainer, object)">ObjectTranslator.onStore
+		/// 	</see>
+		/// .
+		/// </param>
+		/// <returns>the instantiated object.</returns>
+		object OnInstantiate(IObjectContainer container, object storedObject);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IObjectField.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IObjectField.cs
new file mode 100644
index 0000000..03d0f76
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IObjectField.cs
@@ -0,0 +1,130 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>configuration interface for fields of classes.</summary>
+	/// <remarks>
+	/// configuration interface for fields of classes.
+	/// <br/><br/>
+	/// Use
+	/// <see cref="IObjectClass.ObjectField(string)">IObjectClass.ObjectField(string)</see>
+	/// to access this setting.<br/><br/>
+	/// </remarks>
+	public interface IObjectField
+	{
+		/// <summary>sets cascaded activation behaviour.</summary>
+		/// <remarks>
+		/// sets cascaded activation behaviour.
+		/// <br/><br/>
+		/// Setting cascadeOnActivate to true will result in the activation
+		/// of the object attribute stored in this field if the parent object
+		/// is activated.
+		/// <br/><br/>
+		/// The default setting is <b>false</b>.<br/><br/>
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br/><br/>
+		/// This setting can be applied to an open object container. <br/><br/>
+		/// </remarks>
+		/// <param name="flag">whether activation is to be cascaded to the member object.</param>
+		/// <seealso cref="IConfiguration.ActivationDepth()">Why activation?</seealso>
+		/// <seealso cref="IObjectClass.CascadeOnActivate(bool)">IObjectClass.CascadeOnActivate(bool)
+		/// 	</seealso>
+		/// <seealso cref="Db4objects.Db4o.IObjectContainer.Activate(object, int)">Db4objects.Db4o.IObjectContainer.Activate(object, int)
+		/// 	</seealso>
+		/// <seealso cref="Db4objects.Db4o.Ext.IObjectCallbacks">Using callbacks</seealso>
+		void CascadeOnActivate(bool flag);
+
+		/// <summary>sets cascaded delete behaviour.</summary>
+		/// <remarks>
+		/// sets cascaded delete behaviour.
+		/// <br/><br/>
+		/// Setting cascadeOnDelete to true will result in the deletion of
+		/// the object attribute stored in this field on the parent object
+		/// if the parent object is passed to
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Delete(object)">Db4objects.Db4o.IObjectContainer.Delete(object)
+		/// 	</see>
+		/// .
+		/// <br/><br/>
+		/// <b>Caution !</b><br/>
+		/// This setting will also trigger deletion of the old member object, on
+		/// calls to
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Store(object)"></see>
+		/// .
+		/// An example of the behaviour can be found in
+		/// <see cref="IObjectClass.CascadeOnDelete(bool)">IObjectClass.CascadeOnDelete(bool)
+		/// 	</see>
+		/// <br/><br/>
+		/// The default setting is <b>false</b>.<br/><br/>
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br/><br/>
+		/// This setting can be applied to an open object container. <br/><br/>
+		/// </remarks>
+		/// <param name="flag">whether deletes are to be cascaded to the member object.</param>
+		/// <seealso cref="IObjectClass.CascadeOnDelete(bool)">IObjectClass.CascadeOnDelete(bool)
+		/// 	</seealso>
+		/// <seealso cref="Db4objects.Db4o.IObjectContainer.Delete(object)">Db4objects.Db4o.IObjectContainer.Delete(object)
+		/// 	</seealso>
+		/// <seealso cref="Db4objects.Db4o.Ext.IObjectCallbacks">Using callbacks</seealso>
+		void CascadeOnDelete(bool flag);
+
+		/// <summary>sets cascaded update behaviour.</summary>
+		/// <remarks>
+		/// sets cascaded update behaviour.
+		/// <br/><br/>
+		/// Setting cascadeOnUpdate to true will result in the update
+		/// of the object attribute stored in this field if the parent object
+		/// is passed to
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Store(object)">Db4objects.Db4o.IObjectContainer.Store(object)
+		/// 	</see>
+		/// .
+		/// <br/><br/>
+		/// The default setting is <b>false</b>.<br/><br/>
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br/><br/>
+		/// This setting can be applied to an open object container. <br/><br/>
+		/// </remarks>
+		/// <param name="flag">whether updates are to be cascaded to the member object.</param>
+		/// <seealso cref="com.db4o.ObjectContainer#set">com.db4o.ObjectContainer#set</seealso>
+		/// <seealso cref="IObjectClass.CascadeOnUpdate(bool)">IObjectClass.CascadeOnUpdate(bool)
+		/// 	</seealso>
+		/// <seealso cref="IObjectClass.UpdateDepth(int)">IObjectClass.UpdateDepth(int)</seealso>
+		/// <seealso cref="Db4objects.Db4o.Ext.IObjectCallbacks">Using callbacks</seealso>
+		void CascadeOnUpdate(bool flag);
+
+		/// <summary>turns indexing on or off.</summary>
+		/// <remarks>
+		/// turns indexing on or off.
+		/// <br/><br/>Field indices dramatically improve query performance but they may
+		/// considerably reduce storage and update performance.<br/>The best benchmark whether
+		/// or not an index on a field achieves the desired result is the completed application
+		/// - with a data load that is typical for it's use.<br/><br/>This configuration setting
+		/// is only checked when the
+		/// <see cref="Db4objects.Db4o.IObjectContainer">Db4objects.Db4o.IObjectContainer</see>
+		/// is opened. If the
+		/// setting is set to <code>true</code> and an index does not exist, the index will be
+		/// created. If the setting is set to <code>false</code> and an index does exist the
+		/// index will be dropped.<br/><br/>
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br/><br/>
+		/// If this setting is applied to an open ObjectContainer it will take an effect on the next
+		/// time ObjectContainer is opened.<br/><br/>
+		/// </remarks>
+		/// <param name="flag">
+		/// specify <code>true</code> or <code>false</code> to turn indexing on for
+		/// this field
+		/// </param>
+		void Indexed(bool flag);
+
+		/// <summary>renames a field of a stored class.</summary>
+		/// <remarks>
+		/// renames a field of a stored class.
+		/// <br/><br/>Use this method to refactor classes.
+		/// <br/><br/>
+		/// In client-server environment this setting should be used on both
+		/// client and server. <br/><br/>
+		/// This setting can NOT be applied to an open object container. <br/><br/>
+		/// </remarks>
+		/// <param name="newName">the new field name.</param>
+		void Rename(string newName);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IObjectTranslator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IObjectTranslator.cs
new file mode 100644
index 0000000..423ce20
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IObjectTranslator.cs
@@ -0,0 +1,51 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>translator interface to translate objects on storage and activation.</summary>
+	/// <remarks>
+	/// translator interface to translate objects on storage and activation.
+	/// <br/><br/>
+	/// By writing classes that implement this interface, it is possible to
+	/// define how application classes are to be converted to be stored more efficiently.
+	/// <br/><br/>
+	/// Before starting a db4o session, translator classes need to be registered. An example:<br/>
+	/// <code>
+	/// IObjectClass oc = config.ObjectClass("Namespace.ClassName");<br/>
+	/// oc.Translate(new FooTranslator());
+	/// </code><br/><br/>
+	/// </remarks>
+	public interface IObjectTranslator
+	{
+		/// <summary>db4o calls this method during storage and query evaluation.</summary>
+		/// <remarks>db4o calls this method during storage and query evaluation.</remarks>
+		/// <param name="container">the ObjectContainer used</param>
+		/// <param name="applicationObject">the Object to be translated</param>
+		/// <returns>
+		/// return the object to store.<br />It needs to be of the class
+		/// <see cref="StoredClass()">StoredClass()</see>
+		/// .
+		/// </returns>
+		object OnStore(IObjectContainer container, object applicationObject);
+
+		/// <summary>db4o calls this method during activation.</summary>
+		/// <remarks>db4o calls this method during activation.</remarks>
+		/// <param name="container">the ObjectContainer used</param>
+		/// <param name="applicationObject">the object to set the members on</param>
+		/// <param name="storedObject">the object that was stored</param>
+		void OnActivate(IObjectContainer container, object applicationObject, object storedObject
+			);
+
+		/// <summary>return the Class you are converting to.</summary>
+		/// <remarks>return the Class you are converting to.</remarks>
+		/// <returns>
+		/// the Class of the object you are returning with the method
+		/// <see cref="OnStore(Db4objects.Db4o.IObjectContainer, object)">OnStore(Db4objects.Db4o.IObjectContainer, object)
+		/// 	</see>
+		/// </returns>
+		Type StoredClass();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IQueryConfiguration.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IQueryConfiguration.cs
new file mode 100644
index 0000000..4d5b6be
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/IQueryConfiguration.cs
@@ -0,0 +1,135 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>interface to configure the querying settings to be used by the query processor.
+	/// 	</summary>
+	/// <remarks>
+	/// interface to configure the querying settings to be used by the query processor.
+	/// <br /><br />All settings can be configured after opening an ObjectContainer.
+	/// In a Client/Server setup the client-side configuration will be used.
+	/// </remarks>
+	public interface IQueryConfiguration
+	{
+		/// <summary>configures the query processor evaluation mode.</summary>
+		/// <remarks>
+		/// configures the query processor evaluation mode.
+		/// <br /><br />The db4o query processor can run in three modes:<br />
+		/// - <b>Immediate</b> mode<br />
+		/// - <b>Snapshot</b> mode<br />
+		/// - <b>Lazy</b> mode<br /><br />
+		/// In <b>Immediate</b> mode, a query will be fully evaluated when
+		/// <see cref="Db4objects.Db4o.Query.IQuery.Execute()">Db4objects.Db4o.Query.IQuery.Execute()
+		/// 	</see>
+		/// 
+		/// is called. The complete
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// of all matching IDs is
+		/// generated immediately.<br /><br />
+		/// In <b>Snapshot</b> mode, the
+		/// <see cref="Db4objects.Db4o.Query.IQuery.Execute()">Db4objects.Db4o.Query.IQuery.Execute()
+		/// 	</see>
+		/// call will trigger all index
+		/// processing immediately. A snapshot of the current state of all relevant indexes
+		/// is taken for further processing by the SODA query processor. All non-indexed
+		/// constraints and all evaluations will be run when the user application iterates
+		/// through the resulting
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// .<br /><br />
+		/// In <b>Lazy</b> mode, the
+		/// <see cref="Db4objects.Db4o.Query.IQuery.Execute()">Db4objects.Db4o.Query.IQuery.Execute()
+		/// 	</see>
+		/// call will only create an Iterator
+		/// against the best index found. Further query processing (including all index
+		/// processing) will happen when the user application iterates through the resulting
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// .<br /><br />
+		/// Advantages and disadvantages of the individual modes:<br /><br />
+		/// <b>Immediate</b> mode<br />
+		/// <b>+</b> If the query is intended to iterate through the entire resulting
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// ,
+		/// this mode will be slightly faster than the others.<br />
+		/// <b>+</b> The query will process without intermediate side effects from changed
+		/// objects (by the caller or by other transactions).<br />
+		/// <b>-</b> Query processing can block the server for a long time.<br />
+		/// <b>-</b> In comparison to the other modes it will take longest until the first results
+		/// are returned.<br />
+		/// <b>-</b> The ObjectSet will require a considerate amount of memory to hold the IDs of
+		/// all found objects.<br /><br />
+		/// <b>Snapshot</b> mode<br />
+		/// <b>+</b> Index processing will happen without possible side effects from changes made
+		/// by the caller or by other transaction.<br />
+		/// <b>+</b> Since index processing is fast, a server will not be blocked for a long time.<br />
+		/// <b>-</b> The entire candidate index will be loaded into memory. It will stay there
+		/// until the query ObjectSet is garbage collected. In a C/S setup, the memory will
+		/// be used on the server side.<br /><br />
+		/// <b>Lazy</b> mode<br />
+		/// <b>+</b> The call to
+		/// <see cref="Db4objects.Db4o.Query.IQuery.Execute()">Db4objects.Db4o.Query.IQuery.Execute()
+		/// 	</see>
+		/// will return very fast. First results can be
+		/// made available to the application before the query is fully processed.<br />
+		/// <b>+</b> A query will consume hardly any memory at all because no intermediate ID
+		/// representation is ever created.<br />
+		/// <b>-</b> Lazy queries check candidates when iterating through the resulting
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// .
+		/// In doing so the query processor takes changes into account that may have happened
+		/// since the Query#execute()call: committed changes from other transactions, <b>and
+		/// uncommitted changes from the calling transaction</b>. There is a wide range
+		/// of possible side effects. The underlying index may have changed. Objects themselves
+		/// may have changed in the meanwhile. There even is the chance of creating an endless
+		/// loop, if the caller of the iterates through the
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// and changes each
+		/// object in a way that it is placed at the end of the index: The same objects can be
+		/// revisited over and over. <b>In lazy mode it can make sense to work in a way one would
+		/// work with collections to avoid concurrent modification exceptions.</b> For instance one
+		/// could iterate through the
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// first and store all objects to a temporary
+		/// other collection representation before changing objects and storing them back to db4o.<br /><br />
+		/// Note: Some method calls against a lazy
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// will require the query
+		/// processor to create a snapshot or to evaluate the query fully. An example of such
+		/// a call is
+		/// <see cref="Db4objects.Db4o.IObjectSet.Count()">Db4objects.Db4o.IObjectSet.Count()
+		/// 	</see>
+		/// .
+		/// <br /><br />
+		/// The default query evaluation mode is <b>Immediate</b> mode.
+		/// <br /><br />
+		/// Recommendations:<br />
+		/// - <b>Lazy</b> mode can be an excellent choice for single transaction read use,
+		/// to keep memory consumption as low as possible.<br />
+		/// - Client/Server applications with the risk of concurrent modifications should prefer
+		/// <b>Snapshot</b> mode to avoid side effects from other transactions.
+		/// <br /><br />
+		/// To change the evaluationMode, pass any of the three static
+		/// <see cref="QueryEvaluationMode">QueryEvaluationMode</see>
+		/// constants from the
+		/// <see cref="QueryEvaluationMode">QueryEvaluationMode</see>
+		/// class to this method:<br />
+		/// -
+		/// <see cref="QueryEvaluationMode.Immediate">QueryEvaluationMode.Immediate</see>
+		/// <br />
+		/// -
+		/// <see cref="QueryEvaluationMode.Snapshot">QueryEvaluationMode.Snapshot</see>
+		/// <br />
+		/// -
+		/// <see cref="QueryEvaluationMode.Lazy">QueryEvaluationMode.Lazy</see>
+		/// <br /><br />
+		/// This setting must be issued from the client side.
+		/// </remarks>
+		void EvaluationMode(QueryEvaluationMode mode);
+
+		/// <seealso cref="EvaluationMode(QueryEvaluationMode)">EvaluationMode(QueryEvaluationMode)
+		/// 	</seealso>
+		/// <returns>the currently configured query evaluation mode</returns>
+		QueryEvaluationMode EvaluationMode();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/QueryEvaluationMode.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/QueryEvaluationMode.cs
new file mode 100644
index 0000000..8d97435
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/QueryEvaluationMode.cs
@@ -0,0 +1,113 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// This class provides static constants for the query evaluation
+	/// modes that db4o supports.
+	/// </summary>
+	/// <remarks>
+	/// This class provides static constants for the query evaluation
+	/// modes that db4o supports.
+	/// <br /><br /><b>For detailed documentation please see
+	/// <see cref="IQueryConfiguration.EvaluationMode(QueryEvaluationMode)">IQueryConfiguration.EvaluationMode(QueryEvaluationMode)
+	/// 	</see>
+	/// </b>
+	/// </remarks>
+	public class QueryEvaluationMode
+	{
+		private readonly string _id;
+
+		private QueryEvaluationMode(string id)
+		{
+			_id = id;
+		}
+
+		/// <summary>Constant for immediate query evaluation.</summary>
+		/// <remarks>
+		/// Constant for immediate query evaluation. The query is executed fully
+		/// when
+		/// <see cref="Db4objects.Db4o.Query.IQuery.Execute()">Db4objects.Db4o.Query.IQuery.Execute()
+		/// 	</see>
+		/// is called.
+		/// <br /><br /><b>For detailed documentation please see
+		/// <see cref="IQueryConfiguration.EvaluationMode(QueryEvaluationMode)">IQueryConfiguration.EvaluationMode(QueryEvaluationMode)
+		/// 	</see>
+		/// </b>
+		/// </remarks>
+		public static readonly Db4objects.Db4o.Config.QueryEvaluationMode Immediate = new 
+			Db4objects.Db4o.Config.QueryEvaluationMode("IMMEDIATE");
+
+		/// <summary>Constant for snapshot query evaluation.</summary>
+		/// <remarks>
+		/// Constant for snapshot query evaluation. When
+		/// <see cref="Db4objects.Db4o.Query.IQuery.Execute()">Db4objects.Db4o.Query.IQuery.Execute()
+		/// 	</see>
+		/// is called,
+		/// the query processor chooses the best indexes, does all index processing
+		/// and creates a snapshot of the index at this point in time. Non-indexed
+		/// constraints are evaluated lazily when the application iterates through
+		/// the
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// resultset of the query.
+		/// <br /><br /><b>For detailed documentation please see
+		/// <see cref="IQueryConfiguration.EvaluationMode(QueryEvaluationMode)">IQueryConfiguration.EvaluationMode(QueryEvaluationMode)
+		/// 	</see>
+		/// </b>
+		/// </remarks>
+		public static readonly Db4objects.Db4o.Config.QueryEvaluationMode Snapshot = new 
+			Db4objects.Db4o.Config.QueryEvaluationMode("SNAPSHOT");
+
+		/// <summary>Constant for lazy query evaluation.</summary>
+		/// <remarks>
+		/// Constant for lazy query evaluation. When
+		/// <see cref="Db4objects.Db4o.Query.IQuery.Execute()">Db4objects.Db4o.Query.IQuery.Execute()
+		/// 	</see>
+		/// is called, the
+		/// query processor only chooses the best index and creates an iterator on
+		/// this index. Indexes and constraints are evaluated lazily when the
+		/// application iterates through the
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// resultset of the query.
+		/// <br /><br /><b>For detailed documentation please see
+		/// <see cref="IQueryConfiguration.EvaluationMode(QueryEvaluationMode)">IQueryConfiguration.EvaluationMode(QueryEvaluationMode)
+		/// 	</see>
+		/// </b>
+		/// </remarks>
+		public static readonly Db4objects.Db4o.Config.QueryEvaluationMode Lazy = new Db4objects.Db4o.Config.QueryEvaluationMode
+			("LAZY");
+
+		private static readonly Db4objects.Db4o.Config.QueryEvaluationMode[] Modes = new 
+			Db4objects.Db4o.Config.QueryEvaluationMode[] { Db4objects.Db4o.Config.QueryEvaluationMode
+			.Immediate, Db4objects.Db4o.Config.QueryEvaluationMode.Snapshot, Db4objects.Db4o.Config.QueryEvaluationMode
+			.Lazy };
+
+		/// <summary>internal method, ignore please.</summary>
+		/// <remarks>internal method, ignore please.</remarks>
+		public virtual int AsInt()
+		{
+			for (int i = 0; i < Modes.Length; i++)
+			{
+				if (Modes[i] == this)
+				{
+					return i;
+				}
+			}
+			throw new InvalidOperationException();
+		}
+
+		/// <summary>internal method, ignore please.</summary>
+		/// <remarks>internal method, ignore please.</remarks>
+		public static Db4objects.Db4o.Config.QueryEvaluationMode FromInt(int i)
+		{
+			return Modes[i];
+		}
+
+		public override string ToString()
+		{
+			return _id;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/SimpleNameProvider.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/SimpleNameProvider.cs
new file mode 100644
index 0000000..d46695a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/SimpleNameProvider.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// Assigns a fixed, pre-defined name to the given
+	/// <see cref="Db4objects.Db4o.IObjectContainer">Db4objects.Db4o.IObjectContainer</see>
+	/// .
+	/// </summary>
+	public class SimpleNameProvider : INameProvider
+	{
+		private readonly string _name;
+
+		public SimpleNameProvider(string name)
+		{
+			_name = name;
+		}
+
+		public virtual string Name(IObjectContainer db)
+		{
+			return _name;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/TNull.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/TNull.cs
new file mode 100644
index 0000000..a847dd2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/TNull.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <exclude></exclude>
+	public class TNull : IObjectTranslator
+	{
+		public virtual object OnStore(IObjectContainer con, object @object)
+		{
+			return null;
+		}
+
+		public virtual void OnActivate(IObjectContainer con, object @object, object members
+			)
+		{
+		}
+
+		public virtual Type StoredClass()
+		{
+			return typeof(object);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/TypeAlias.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/TypeAlias.cs
new file mode 100644
index 0000000..9abd9ae
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/TypeAlias.cs
@@ -0,0 +1,63 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// a simple Alias for a single Class or Type, using equals on
+	/// the names in the resolve method.
+	/// </summary>
+	/// <remarks>
+	/// a simple Alias for a single Class or Type, using equals on
+	/// the names in the resolve method.
+	/// <br /><br />See
+	/// <see cref="IAlias">IAlias</see>
+	/// for concrete examples.
+	/// </remarks>
+	public class TypeAlias : IAlias
+	{
+		private readonly string _storedType;
+
+		private readonly string _runtimeType;
+
+		/// <summary>
+		/// pass the stored name as the first
+		/// parameter and the desired runtime name as the second parameter.
+		/// </summary>
+		/// <remarks>
+		/// pass the stored name as the first
+		/// parameter and the desired runtime name as the second parameter.
+		/// </remarks>
+		public TypeAlias(string storedType, string runtimeType)
+		{
+			if (null == storedType || null == runtimeType)
+			{
+				throw new ArgumentException();
+			}
+			_storedType = storedType;
+			_runtimeType = runtimeType;
+		}
+
+		public TypeAlias(Type storedClass, Type runtimeClass) : this(ReflectPlatform.FullyQualifiedName
+			(storedClass), ReflectPlatform.FullyQualifiedName(runtimeClass))
+		{
+		}
+
+		/// <summary>returns the stored type name if the alias was written for the passed runtime type name
+		/// 	</summary>
+		public virtual string ResolveRuntimeName(string runtimeTypeName)
+		{
+			return _runtimeType.Equals(runtimeTypeName) ? _storedType : null;
+		}
+
+		/// <summary>returns the runtime type name if the alias was written for the passed stored type name
+		/// 	</summary>
+		public virtual string ResolveStoredName(string storedTypeName)
+		{
+			return _storedType.Equals(storedTypeName) ? _runtimeType : null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/WildcardAlias.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/WildcardAlias.cs
new file mode 100644
index 0000000..d9b9ba4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Config/WildcardAlias.cs
@@ -0,0 +1,114 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// Wildcard Alias functionality to create aliases for packages,
+	/// namespaces or multiple similar named classes.
+	/// </summary>
+	/// <remarks>
+	/// Wildcard Alias functionality to create aliases for packages,
+	/// namespaces or multiple similar named classes. One single '*'
+	/// wildcard character is supported in the names.
+	/// <br /><br />See
+	/// <see cref="IAlias">IAlias</see>
+	/// for concrete examples.
+	/// </remarks>
+	public class WildcardAlias : IAlias
+	{
+		private readonly WildcardAlias.WildcardPattern _storedPattern;
+
+		private readonly WildcardAlias.WildcardPattern _runtimePattern;
+
+		/// <summary>
+		/// Create a WildcardAlias with two patterns, the
+		/// stored pattern and the pattern that is to be used
+		/// at runtime.
+		/// </summary>
+		/// <remarks>
+		/// Create a WildcardAlias with two patterns, the
+		/// stored pattern and the pattern that is to be used
+		/// at runtime. One single '*' is allowed as a wildcard
+		/// character.
+		/// </remarks>
+		public WildcardAlias(string storedPattern, string runtimePattern)
+		{
+			if (null == storedPattern)
+			{
+				throw new ArgumentNullException("storedPattern");
+			}
+			if (null == runtimePattern)
+			{
+				throw new ArgumentNullException("runtimePattern");
+			}
+			_storedPattern = new WildcardAlias.WildcardPattern(storedPattern);
+			_runtimePattern = new WildcardAlias.WildcardPattern(runtimePattern);
+		}
+
+		/// <summary>resolving is done through simple pattern matching</summary>
+		public virtual string ResolveRuntimeName(string runtimeTypeName)
+		{
+			return Resolve(_runtimePattern, _storedPattern, runtimeTypeName);
+		}
+
+		/// <summary>resolving is done through simple pattern matching</summary>
+		public virtual string ResolveStoredName(string storedTypeName)
+		{
+			return Resolve(_storedPattern, _runtimePattern, storedTypeName);
+		}
+
+		private string Resolve(WildcardAlias.WildcardPattern from, WildcardAlias.WildcardPattern
+			 to, string typeName)
+		{
+			string match = from.Matches(typeName);
+			return match != null ? to.Inject(match) : null;
+		}
+
+		internal class WildcardPattern
+		{
+			private string _head;
+
+			private string _tail;
+
+			public WildcardPattern(string pattern)
+			{
+				string[] parts = Split(pattern);
+				_head = parts[0];
+				_tail = parts[1];
+			}
+
+			public virtual string Inject(string s)
+			{
+				return _head + s + _tail;
+			}
+
+			public virtual string Matches(string s)
+			{
+				if (!s.StartsWith(_head) || !s.EndsWith(_tail))
+				{
+					return null;
+				}
+				return Sharpen.Runtime.Substring(s, _head.Length, s.Length - _tail.Length);
+			}
+
+			private void InvalidPattern()
+			{
+				throw new ArgumentException("only one '*' character");
+			}
+
+			internal virtual string[] Split(string pattern)
+			{
+				int index = pattern.IndexOf('*');
+				if (-1 == index || index != pattern.LastIndexOf('*'))
+				{
+					InvalidPattern();
+				}
+				return new string[] { Sharpen.Runtime.Substring(pattern, 0, index), Sharpen.Runtime.Substring
+					(pattern, index + 1) };
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Constraints/ConstraintViolationException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Constraints/ConstraintViolationException.cs
new file mode 100644
index 0000000..46be998
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Constraints/ConstraintViolationException.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Constraints
+{
+	/// <summary>Base class for all constraint exceptions.</summary>
+	/// <remarks>Base class for all constraint exceptions.</remarks>
+	[System.Serializable]
+	public class ConstraintViolationException : Db4oRecoverableException
+	{
+		/// <summary>
+		/// ConstraintViolationException constructor with a specific
+		/// message.
+		/// </summary>
+		/// <remarks>
+		/// ConstraintViolationException constructor with a specific
+		/// message.
+		/// </remarks>
+		/// <param name="msg">exception message</param>
+		public ConstraintViolationException(string msg) : base(msg)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Constraints/UniqueFieldValueConstraint.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Constraints/UniqueFieldValueConstraint.cs
new file mode 100644
index 0000000..7997216
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Constraints/UniqueFieldValueConstraint.cs
@@ -0,0 +1,146 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Constraints;
+using Db4objects.Db4o.Events;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Core;
+
+namespace Db4objects.Db4o.Constraints
+{
+	/// <summary>configures a field of a class to allow unique values only.</summary>
+	/// <remarks>configures a field of a class to allow unique values only.</remarks>
+	public class UniqueFieldValueConstraint : IConfigurationItem
+	{
+		protected readonly object _clazz;
+
+		protected readonly string _fieldName;
+
+		/// <summary>constructor to create a UniqueFieldValueConstraint.</summary>
+		/// <remarks>constructor to create a UniqueFieldValueConstraint.</remarks>
+		/// <param name="clazz">can be a class (Java) / Type (.NET) / instance of the class / fully qualified class name
+		/// 	</param>
+		/// <param name="fieldName">the name of the field that is to be unique.</param>
+		public UniqueFieldValueConstraint(object clazz, string fieldName)
+		{
+			_clazz = clazz;
+			_fieldName = fieldName;
+		}
+
+		public virtual void Prepare(IConfiguration configuration)
+		{
+		}
+
+		// Nothing to do...
+		/// <summary>internal method, public for implementation reasons.</summary>
+		/// <remarks>internal method, public for implementation reasons.</remarks>
+		public virtual void Apply(IInternalObjectContainer objectContainer)
+		{
+			if (objectContainer.IsClient)
+			{
+				throw new InvalidOperationException(GetType().FullName + " should be configured on the server."
+					);
+			}
+			EventRegistryFactory.ForObjectContainer(objectContainer).Committing += new System.EventHandler<Db4objects.Db4o.Events.CommitEventArgs>
+				(new _IEventListener4_46(this, objectContainer).OnEvent);
+		}
+
+		private sealed class _IEventListener4_46
+		{
+			public _IEventListener4_46(UniqueFieldValueConstraint _enclosing, IInternalObjectContainer
+				 objectContainer)
+			{
+				this._enclosing = _enclosing;
+				this.objectContainer = objectContainer;
+			}
+
+			private FieldMetadata _fieldMetaData;
+
+			private void EnsureSingleOccurence(Transaction trans, IObjectInfoCollection col)
+			{
+				IEnumerator i = col.GetEnumerator();
+				while (i.MoveNext())
+				{
+					IObjectInfo objectInfo = (IObjectInfo)i.Current;
+					if (this.ReflectClass() != this._enclosing.ReflectorFor(trans, objectInfo.GetObject
+						()))
+					{
+						continue;
+					}
+					object obj = this.ObjectFor(trans, objectInfo);
+					object fieldValue = this.FieldMetadata().GetOn(trans, obj);
+					if (fieldValue == null)
+					{
+						continue;
+					}
+					IBTreeRange range = this.FieldMetadata().Search(trans, fieldValue);
+					if (range.Size() > 1)
+					{
+						throw new UniqueFieldValueConstraintViolationException(this.ClassMetadata().GetName
+							(), this.FieldMetadata().GetName());
+					}
+				}
+			}
+
+			private bool IsClassMetadataAvailable()
+			{
+				return null != this.ClassMetadata();
+			}
+
+			private FieldMetadata FieldMetadata()
+			{
+				if (this._fieldMetaData != null)
+				{
+					return this._fieldMetaData;
+				}
+				this._fieldMetaData = this.ClassMetadata().FieldMetadataForName(this._enclosing._fieldName
+					);
+				return this._fieldMetaData;
+			}
+
+			private ClassMetadata ClassMetadata()
+			{
+				return objectContainer.ClassMetadataForReflectClass(this.ReflectClass());
+			}
+
+			private IReflectClass ReflectClass()
+			{
+				return ReflectorUtils.ReflectClassFor(objectContainer.Reflector(), this._enclosing
+					._clazz);
+			}
+
+			public void OnEvent(object sender, Db4objects.Db4o.Events.CommitEventArgs args)
+			{
+				if (!this.IsClassMetadataAvailable())
+				{
+					return;
+				}
+				CommitEventArgs commitEventArgs = (CommitEventArgs)args;
+				Transaction trans = (Transaction)commitEventArgs.Transaction();
+				this.EnsureSingleOccurence(trans, commitEventArgs.Added);
+				this.EnsureSingleOccurence(trans, commitEventArgs.Updated);
+			}
+
+			private object ObjectFor(Transaction trans, IObjectInfo info)
+			{
+				int id = (int)info.GetInternalID();
+				HardObjectReference @ref = HardObjectReference.PeekPersisted(trans, id, 1);
+				return @ref._object;
+			}
+
+			private readonly UniqueFieldValueConstraint _enclosing;
+
+			private readonly IInternalObjectContainer objectContainer;
+		}
+
+		private IReflectClass ReflectorFor(Transaction trans, object obj)
+		{
+			return trans.Container().Reflector().ForObject(obj);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Constraints/UniqueFieldValueConstraintViolationException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Constraints/UniqueFieldValueConstraintViolationException.cs
new file mode 100644
index 0000000..6a966bb
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Constraints/UniqueFieldValueConstraintViolationException.cs
@@ -0,0 +1,36 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Constraints;
+
+namespace Db4objects.Db4o.Constraints
+{
+	/// <summary>
+	/// db4o-specific exception.<br /><br />
+	/// This exception can be thrown by a
+	/// <see cref="UniqueFieldValueConstraint">UniqueFieldValueConstraint</see>
+	/// on commit.
+	/// </summary>
+	/// <seealso cref="Db4objects.Db4o.Config.IObjectField.Indexed(bool)">Db4objects.Db4o.Config.IObjectField.Indexed(bool)
+	/// 	</seealso>
+	/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.Add(Db4objects.Db4o.Config.IConfigurationItem)
+	/// 	">Db4objects.Db4o.Config.IConfiguration.Add(Db4objects.Db4o.Config.IConfigurationItem)
+	/// 	</seealso>
+	[System.Serializable]
+	public class UniqueFieldValueConstraintViolationException : ConstraintViolationException
+	{
+		/// <summary>
+		/// Constructor with a message composed from the class and field
+		/// name of the entity causing the exception.
+		/// </summary>
+		/// <remarks>
+		/// Constructor with a message composed from the class and field
+		/// name of the entity causing the exception.
+		/// </remarks>
+		/// <param name="className">class, which caused the exception</param>
+		/// <param name="fieldName">field, which caused the exception</param>
+		public UniqueFieldValueConstraintViolationException(string className, string fieldName
+			) : base("class: " + className + " field: " + fieldName)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/CorruptionException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/CorruptionException.cs
new file mode 100644
index 0000000..4660ec1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/CorruptionException.cs
@@ -0,0 +1,13 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o
+{
+	/// <exclude></exclude>
+	[System.Serializable]
+	public class CorruptionException : Exception
+	{
+		// TODO implement exception basics (message, etc.)
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/DTrace.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/DTrace.cs
new file mode 100644
index 0000000..6a45f63
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/DTrace.cs
@@ -0,0 +1,774 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.IO;
+using System.Text;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Slots;
+using Sharpen.IO;
+
+namespace Db4objects.Db4o
+{
+	/// <exclude></exclude>
+	public class DTrace
+	{
+		public static bool enabled = false;
+
+		public static bool writeToLogFile = false;
+
+		public static bool writeToConsole = true;
+
+		private static readonly string logFilePath = "C://";
+
+		private static string logFileName;
+
+		private static readonly object Lock = new object();
+
+		private static readonly LatinStringIO stringIO = new LatinStringIO();
+
+		public static RandomAccessFile _logFile;
+
+		private static int Unused = -1;
+
+		private static void BreakPoint()
+		{
+			if (enabled)
+			{
+				int xxx = 1;
+			}
+		}
+
+		private static void Configure()
+		{
+			if (enabled)
+			{
+			}
+		}
+
+		// addRange(15);
+		// breakOnEvent(540);
+		//        	
+		//        	addRangeWithEnd(448, 460);
+		//        	addRangeWithLength(770,53);
+		// breakOnEvent(125);
+		//            trackEventsWithoutRange();
+		//            turnAllOffExceptFor(new DTrace[] {WRITE_BYTES});
+		//            turnAllOffExceptFor(new DTrace[] {
+		//                PERSISTENT_OWN_LENGTH,
+		//                });
+		//            turnAllOffExceptFor(new DTrace[] {
+		//                GET_SLOT,
+		//                FILE_FREE,
+		//                TRANS_COMMIT,
+		//                });
+		// turnAllOffExceptFor(new DTrace[] {WRITE_BYTES});
+		//            turnAllOffExceptFor(new DTrace[] {BTREE_NODE_REMOVE, BTREE_NODE_COMMIT_OR_ROLLBACK YAPMETA_SET_ID});
+		private static void Init()
+		{
+			if (enabled)
+			{
+				AddToClassIndex = new Db4objects.Db4o.DTrace(true, true, "add to class index tree"
+					, true);
+				BeginTopLevelCall = new Db4objects.Db4o.DTrace(true, true, "begin top level call"
+					, true);
+				Bind = new Db4objects.Db4o.DTrace(true, true, "bind", true);
+				BlockingQueueStoppedException = new Db4objects.Db4o.DTrace(true, true, "blocking queue stopped exception"
+					, true);
+				BtreeNodeRemove = new Db4objects.Db4o.DTrace(true, true, "btreenode remove", true
+					);
+				BtreeNodeCommitOrRollback = new Db4objects.Db4o.DTrace(true, true, "btreenode commit or rollback"
+					, true);
+				BtreeProduceNode = new Db4objects.Db4o.DTrace(true, true, "btree produce node", true
+					);
+				CandidateRead = new Db4objects.Db4o.DTrace(true, true, "candidate read", true);
+				ClassmetadataById = new Db4objects.Db4o.DTrace(true, true, "classmetadata by id", 
+					true);
+				ClassmetadataInit = new Db4objects.Db4o.DTrace(true, true, "classmetadata init", 
+					true);
+				ClientMessageLoopException = new Db4objects.Db4o.DTrace(true, true, "client message loop exception"
+					, true);
+				Close = new Db4objects.Db4o.DTrace(true, true, "close", true);
+				CloseCalled = new Db4objects.Db4o.DTrace(true, true, "close called", true);
+				CollectChildren = new Db4objects.Db4o.DTrace(true, true, "collect children", true
+					);
+				Commit = new Db4objects.Db4o.DTrace(false, false, "commit", true);
+				Continueset = new Db4objects.Db4o.DTrace(true, true, "continueset", true);
+				CreateCandidate = new Db4objects.Db4o.DTrace(true, true, "create candidate", true
+					);
+				Delete = new Db4objects.Db4o.DTrace(true, true, "delete", true);
+				Donotinclude = new Db4objects.Db4o.DTrace(true, true, "donotinclude", true);
+				EndTopLevelCall = new Db4objects.Db4o.DTrace(true, true, "end top level call", true
+					);
+				EvaluateSelf = new Db4objects.Db4o.DTrace(true, true, "evaluate self", true);
+				FatalException = new Db4objects.Db4o.DTrace(true, true, "fatal exception", true);
+				Free = new Db4objects.Db4o.DTrace(true, true, "free", true);
+				FileFree = new Db4objects.Db4o.DTrace(true, true, "fileFree", true);
+				FileRead = new Db4objects.Db4o.DTrace(true, true, "fileRead", true);
+				FileWrite = new Db4objects.Db4o.DTrace(true, true, "fileWrite", true);
+				FreespacemanagerGetSlot = new Db4objects.Db4o.DTrace(true, true, "FreespaceManager getSlot"
+					, true);
+				FreespacemanagerRamFree = new Db4objects.Db4o.DTrace(true, true, "InMemoryfreespaceManager free"
+					, true);
+				FreespacemanagerBtreeFree = new Db4objects.Db4o.DTrace(true, true, "BTreeFreeSpaceManager free"
+					, true);
+				FreeOnCommit = new Db4objects.Db4o.DTrace(true, true, "trans freeOnCommit", true);
+				FreeOnRollback = new Db4objects.Db4o.DTrace(true, true, "trans freeOnRollback", true
+					);
+				FreePointerOnRollback = new Db4objects.Db4o.DTrace(true, true, "freePointerOnRollback"
+					, true);
+				GetPointerSlot = new Db4objects.Db4o.DTrace(true, true, "getPointerSlot", true);
+				GetSlot = new Db4objects.Db4o.DTrace(true, true, "getSlot", true);
+				GetFreespaceRam = new Db4objects.Db4o.DTrace(true, true, "getFreespaceRam", true);
+				GetYapobject = new Db4objects.Db4o.DTrace(true, true, "get ObjectReference", true
+					);
+				IdTreeAdd = new Db4objects.Db4o.DTrace(true, true, "id tree add", true);
+				IdTreeRemove = new Db4objects.Db4o.DTrace(true, true, "id tree remove", true);
+				IoCopy = new Db4objects.Db4o.DTrace(true, true, "io copy", true);
+				JustSet = new Db4objects.Db4o.DTrace(true, true, "just set", true);
+				NewInstance = new Db4objects.Db4o.DTrace(true, true, "newInstance", true);
+				NotifySlotCreated = new Db4objects.Db4o.DTrace(true, true, "notifySlotCreated", true
+					);
+				NotifySlotUpdated = new Db4objects.Db4o.DTrace(true, true, "notify Slot updated", 
+					true);
+				NotifySlotDeleted = new Db4objects.Db4o.DTrace(true, true, "notifySlotDeleted", true
+					);
+				ObjectReferenceCreated = new Db4objects.Db4o.DTrace(true, true, "new ObjectReference"
+					, true);
+				PersistentBaseNewSlot = new Db4objects.Db4o.DTrace(true, true, "PersistentBase new slot"
+					, true);
+				PersistentOwnLength = new Db4objects.Db4o.DTrace(true, true, "Persistent own length"
+					, true);
+				PersistentbaseWrite = new Db4objects.Db4o.DTrace(true, true, "persistentbase write"
+					, true);
+				PersistentbaseSetId = new Db4objects.Db4o.DTrace(true, true, "persistentbase setid"
+					, true);
+				ProduceSlotChange = new Db4objects.Db4o.DTrace(true, true, "produce slot change", 
+					true);
+				QueryProcess = new Db4objects.Db4o.DTrace(true, true, "query process", true);
+				ReadArrayWrapper = new Db4objects.Db4o.DTrace(true, true, "read array wrapper", true
+					);
+				ReadBytes = new Db4objects.Db4o.DTrace(true, true, "readBytes", true);
+				ReadSlot = new Db4objects.Db4o.DTrace(true, true, "read slot", true);
+				ReferenceRemoved = new Db4objects.Db4o.DTrace(true, true, "reference removed", true
+					);
+				RegularSeek = new Db4objects.Db4o.DTrace(true, true, "regular seek", true);
+				RemoveFromClassIndex = new Db4objects.Db4o.DTrace(true, true, "trans removeFromClassIndexTree"
+					, true);
+				RereadOldUuid = new Db4objects.Db4o.DTrace(true, true, "reread old uuid", true);
+				ServerMessageLoopException = new Db4objects.Db4o.DTrace(true, true, "server message loop exception"
+					, true);
+				SlotMapped = new Db4objects.Db4o.DTrace(true, true, "slot mapped", true);
+				SlotCommitted = new Db4objects.Db4o.DTrace(true, true, "slot committed", true);
+				SlotFreeOnCommit = new Db4objects.Db4o.DTrace(true, true, "slot free on commit", 
+					true);
+				SlotFreeOnRollbackId = new Db4objects.Db4o.DTrace(true, true, "slot free on rollback id"
+					, true);
+				SlotFreeOnRollbackAddress = new Db4objects.Db4o.DTrace(true, true, "slot free on rollback address"
+					, true);
+				SlotRead = new Db4objects.Db4o.DTrace(true, true, "slot read", true);
+				TransCommit = new Db4objects.Db4o.DTrace(true, true, "trans commit", true);
+				TransDelete = new Db4objects.Db4o.DTrace(true, true, "trans delete", true);
+				TransDontDelete = new Db4objects.Db4o.DTrace(true, true, "trans dontDelete", true
+					);
+				TransFlush = new Db4objects.Db4o.DTrace(true, true, "trans flush", true);
+				WriteBytes = new Db4objects.Db4o.DTrace(true, true, "writeBytes", true);
+				WritePointer = new Db4objects.Db4o.DTrace(true, true, "write pointer", true);
+				WriteUpdateAdjustIndexes = new Db4objects.Db4o.DTrace(true, true, "trans writeUpdateDeleteMembers"
+					, true);
+				WriteXbytes = new Db4objects.Db4o.DTrace(true, true, "writeXBytes", true);
+				Configure();
+			}
+		}
+
+		private static void TrackEventsWithoutRange()
+		{
+			_trackEventsWithoutRange = true;
+		}
+
+		private DTrace(bool enabled_, bool break_, string tag_, bool log_)
+		{
+			if (enabled)
+			{
+				_enabled = enabled_;
+				_break = break_;
+				_tag = tag_;
+				_log = log_;
+				if (all == null)
+				{
+					all = new Db4objects.Db4o.DTrace[100];
+				}
+				all[current++] = this;
+			}
+		}
+
+		private bool _enabled;
+
+		private bool _break;
+
+		private bool _log;
+
+		private string _tag;
+
+		private static long[] _rangeStart;
+
+		private static long[] _rangeEnd;
+
+		private static int _rangeCount;
+
+		public static long _eventNr;
+
+		private static long[] _breakEventNrs;
+
+		private static int _breakEventCount;
+
+		private static bool _breakAfterEvent;
+
+		private static bool _trackEventsWithoutRange;
+
+		public static Db4objects.Db4o.DTrace AddToClassIndex;
+
+		public static Db4objects.Db4o.DTrace BeginTopLevelCall;
+
+		public static Db4objects.Db4o.DTrace Bind;
+
+		public static Db4objects.Db4o.DTrace BlockingQueueStoppedException;
+
+		public static Db4objects.Db4o.DTrace BtreeNodeCommitOrRollback;
+
+		public static Db4objects.Db4o.DTrace BtreeNodeRemove;
+
+		public static Db4objects.Db4o.DTrace BtreeProduceNode;
+
+		public static Db4objects.Db4o.DTrace CandidateRead;
+
+		public static Db4objects.Db4o.DTrace ClassmetadataById;
+
+		public static Db4objects.Db4o.DTrace ClassmetadataInit;
+
+		public static Db4objects.Db4o.DTrace ClientMessageLoopException;
+
+		public static Db4objects.Db4o.DTrace Close;
+
+		public static Db4objects.Db4o.DTrace CloseCalled;
+
+		public static Db4objects.Db4o.DTrace CollectChildren;
+
+		public static Db4objects.Db4o.DTrace Commit;
+
+		public static Db4objects.Db4o.DTrace Continueset;
+
+		public static Db4objects.Db4o.DTrace CreateCandidate;
+
+		public static Db4objects.Db4o.DTrace Delete;
+
+		public static Db4objects.Db4o.DTrace Donotinclude;
+
+		public static Db4objects.Db4o.DTrace EndTopLevelCall;
+
+		public static Db4objects.Db4o.DTrace EvaluateSelf;
+
+		public static Db4objects.Db4o.DTrace FatalException;
+
+		public static Db4objects.Db4o.DTrace FileFree;
+
+		public static Db4objects.Db4o.DTrace FileRead;
+
+		public static Db4objects.Db4o.DTrace FileWrite;
+
+		public static Db4objects.Db4o.DTrace Free;
+
+		public static Db4objects.Db4o.DTrace FreespacemanagerGetSlot;
+
+		public static Db4objects.Db4o.DTrace FreespacemanagerRamFree;
+
+		public static Db4objects.Db4o.DTrace FreespacemanagerBtreeFree;
+
+		public static Db4objects.Db4o.DTrace FreeOnCommit;
+
+		public static Db4objects.Db4o.DTrace FreeOnRollback;
+
+		public static Db4objects.Db4o.DTrace FreePointerOnRollback;
+
+		public static Db4objects.Db4o.DTrace GetSlot;
+
+		public static Db4objects.Db4o.DTrace GetPointerSlot;
+
+		public static Db4objects.Db4o.DTrace GetFreespaceRam;
+
+		public static Db4objects.Db4o.DTrace GetYapobject;
+
+		public static Db4objects.Db4o.DTrace IdTreeAdd;
+
+		public static Db4objects.Db4o.DTrace IdTreeRemove;
+
+		public static Db4objects.Db4o.DTrace IoCopy;
+
+		public static Db4objects.Db4o.DTrace JustSet;
+
+		public static Db4objects.Db4o.DTrace NewInstance;
+
+		public static Db4objects.Db4o.DTrace NotifySlotCreated;
+
+		public static Db4objects.Db4o.DTrace NotifySlotUpdated;
+
+		public static Db4objects.Db4o.DTrace NotifySlotDeleted;
+
+		public static Db4objects.Db4o.DTrace ObjectReferenceCreated;
+
+		public static Db4objects.Db4o.DTrace PersistentBaseNewSlot;
+
+		public static Db4objects.Db4o.DTrace PersistentOwnLength;
+
+		public static Db4objects.Db4o.DTrace PersistentbaseSetId;
+
+		public static Db4objects.Db4o.DTrace PersistentbaseWrite;
+
+		public static Db4objects.Db4o.DTrace ProduceSlotChange;
+
+		public static Db4objects.Db4o.DTrace QueryProcess;
+
+		public static Db4objects.Db4o.DTrace ReadArrayWrapper;
+
+		public static Db4objects.Db4o.DTrace ReadBytes;
+
+		public static Db4objects.Db4o.DTrace ReadSlot;
+
+		public static Db4objects.Db4o.DTrace ReferenceRemoved;
+
+		public static Db4objects.Db4o.DTrace RegularSeek;
+
+		public static Db4objects.Db4o.DTrace RemoveFromClassIndex;
+
+		public static Db4objects.Db4o.DTrace RereadOldUuid;
+
+		public static Db4objects.Db4o.DTrace ServerMessageLoopException;
+
+		public static Db4objects.Db4o.DTrace SlotMapped;
+
+		public static Db4objects.Db4o.DTrace SlotCommitted;
+
+		public static Db4objects.Db4o.DTrace SlotFreeOnCommit;
+
+		public static Db4objects.Db4o.DTrace SlotFreeOnRollbackId;
+
+		public static Db4objects.Db4o.DTrace SlotFreeOnRollbackAddress;
+
+		public static Db4objects.Db4o.DTrace SlotRead;
+
+		public static Db4objects.Db4o.DTrace TransCommit;
+
+		public static Db4objects.Db4o.DTrace TransDontDelete;
+
+		public static Db4objects.Db4o.DTrace TransDelete;
+
+		public static Db4objects.Db4o.DTrace TransFlush;
+
+		public static Db4objects.Db4o.DTrace WriteBytes;
+
+		public static Db4objects.Db4o.DTrace WritePointer;
+
+		public static Db4objects.Db4o.DTrace WriteXbytes;
+
+		public static Db4objects.Db4o.DTrace WriteUpdateAdjustIndexes;
+
+		static DTrace()
+		{
+			Init();
+		}
+
+		private static Db4objects.Db4o.DTrace[] all;
+
+		private static int current;
+
+		public virtual void Log()
+		{
+			if (enabled)
+			{
+				Log(Unused);
+			}
+		}
+
+		public virtual void Log(string msg)
+		{
+			if (enabled)
+			{
+				Log(Unused, msg);
+			}
+		}
+
+		public virtual void Log(long p)
+		{
+			if (enabled)
+			{
+				LogLength(p, 1);
+			}
+		}
+
+		public virtual void LogInfo(string info)
+		{
+			if (enabled)
+			{
+				LogEnd(Unused, Unused, 0, info);
+			}
+		}
+
+		public virtual void Log(long p, string info)
+		{
+			if (enabled)
+			{
+				LogEnd(Unused, p, 0, info);
+			}
+		}
+
+		public virtual void LogLength(long start, long length)
+		{
+			if (enabled)
+			{
+				LogLength(Unused, start, length);
+			}
+		}
+
+		public virtual void LogLength(long id, long start, long length)
+		{
+			if (enabled)
+			{
+				LogEnd(id, start, start + length - 1);
+			}
+		}
+
+		public virtual void LogLength(Slot slot)
+		{
+			if (enabled)
+			{
+				LogLength(Unused, slot);
+			}
+		}
+
+		public virtual void LogLength(long id, Slot slot)
+		{
+			if (enabled)
+			{
+				if (slot == null)
+				{
+					return;
+				}
+				LogLength(id, slot.Address(), slot.Length());
+			}
+		}
+
+		public virtual void LogEnd(long start, long end)
+		{
+			if (enabled)
+			{
+				LogEnd(Unused, start, end);
+			}
+		}
+
+		public virtual void LogEnd(long id, long start, long end)
+		{
+			if (enabled)
+			{
+				LogEnd(id, start, end, null);
+			}
+		}
+
+		public virtual void LogEnd(long id, long start, long end, string info)
+		{
+			//    	if(! Deploy.log){
+			//    		return;
+			//    	}
+			if (enabled)
+			{
+				if (!_enabled)
+				{
+					return;
+				}
+				bool inRange = false;
+				if (_rangeCount == 0)
+				{
+					inRange = true;
+				}
+				for (int i = 0; i < _rangeCount; i++)
+				{
+					// Case 0 ID in range
+					if (id >= _rangeStart[i] && id <= _rangeEnd[i])
+					{
+						inRange = true;
+						break;
+					}
+					// Case 1 start in range
+					if (start >= _rangeStart[i] && start <= _rangeEnd[i])
+					{
+						inRange = true;
+						break;
+					}
+					if (end != 0)
+					{
+						// Case 2 end in range
+						if (end >= _rangeStart[i] && end <= _rangeEnd[i])
+						{
+							inRange = true;
+							break;
+						}
+						// Case 3 start before range, end after range
+						if (start <= _rangeStart[i] && end >= _rangeEnd[i])
+						{
+							inRange = true;
+							break;
+						}
+					}
+				}
+				if (inRange || (_trackEventsWithoutRange && (start == Unused)))
+				{
+					if (_log)
+					{
+						_eventNr++;
+						StringBuilder sb = new StringBuilder(":");
+						sb.Append(FormatInt(_eventNr, 6));
+						sb.Append(":");
+						sb.Append(FormatInt(id));
+						sb.Append(":");
+						sb.Append(FormatInt(start));
+						sb.Append(":");
+						if (end != 0 && start != end)
+						{
+							sb.Append(FormatInt(end));
+							sb.Append(":");
+							sb.Append(FormatInt(end - start + 1));
+						}
+						else
+						{
+							sb.Append(FormatUnused());
+							sb.Append(":");
+							sb.Append(FormatUnused());
+						}
+						sb.Append(":");
+						if (info != null)
+						{
+							sb.Append(" " + info + " ");
+							sb.Append(":");
+						}
+						sb.Append(" ");
+						sb.Append(_tag);
+						LogToOutput(sb.ToString());
+					}
+					if (_break)
+					{
+						if (_breakEventCount > 0)
+						{
+							for (int i = 0; i < _breakEventCount; i++)
+							{
+								if (_breakEventNrs[i] == _eventNr)
+								{
+									BreakPoint();
+									break;
+								}
+							}
+							if (_breakAfterEvent)
+							{
+								for (int i = 0; i < _breakEventCount; i++)
+								{
+									if (_breakEventNrs[i] <= _eventNr)
+									{
+										BreakPoint();
+										break;
+									}
+								}
+							}
+						}
+						else
+						{
+							BreakPoint();
+						}
+					}
+				}
+			}
+		}
+
+		private string FormatUnused()
+		{
+			return FormatInt(Unused);
+		}
+
+		private static void LogToOutput(string msg)
+		{
+			if (enabled)
+			{
+				LogToFile(msg);
+				LogToConsole(msg);
+			}
+		}
+
+		private static void LogToConsole(string msg)
+		{
+			if (enabled)
+			{
+				if (writeToConsole)
+				{
+					Sharpen.Runtime.Out.WriteLine(msg);
+				}
+			}
+		}
+
+		private static void LogToFile(string msg)
+		{
+			if (enabled)
+			{
+				if (!writeToLogFile)
+				{
+					return;
+				}
+				lock (Lock)
+				{
+					if (_logFile == null)
+					{
+						try
+						{
+							_logFile = new RandomAccessFile(LogFile(), "rw");
+							LogToFile("\r\n\r\n ********** BEGIN LOG ********** \r\n\r\n ");
+						}
+						catch (IOException e)
+						{
+							Sharpen.Runtime.PrintStackTrace(e);
+						}
+					}
+					msg = DateHandlerBase.Now() + "\r\n" + msg + "\r\n";
+					byte[] bytes = stringIO.Write(msg);
+					try
+					{
+						_logFile.Write(bytes);
+					}
+					catch (IOException e)
+					{
+						Sharpen.Runtime.PrintStackTrace(e);
+					}
+				}
+			}
+		}
+
+		private static string LogFile()
+		{
+			if (enabled)
+			{
+				if (logFileName != null)
+				{
+					return logFileName;
+				}
+				logFileName = "db4oDTrace_" + DateHandlerBase.Now() + "_" + SignatureGenerator.GenerateSignature
+					() + ".log";
+				logFileName = logFileName.Replace(' ', '_');
+				logFileName = logFileName.Replace(':', '_');
+				logFileName = logFileName.Replace('-', '_');
+				return logFilePath + logFileName;
+			}
+			return null;
+		}
+
+		public static void AddRange(long pos)
+		{
+			if (enabled)
+			{
+				AddRangeWithEnd(pos, pos);
+			}
+		}
+
+		public static void AddRangeWithLength(long start, long length)
+		{
+			if (enabled)
+			{
+				AddRangeWithEnd(start, start + length - 1);
+			}
+		}
+
+		public static void AddRangeWithEnd(long start, long end)
+		{
+			if (enabled)
+			{
+				if (_rangeStart == null)
+				{
+					_rangeStart = new long[1000];
+					_rangeEnd = new long[1000];
+				}
+				_rangeStart[_rangeCount] = start;
+				_rangeEnd[_rangeCount] = end;
+				_rangeCount++;
+			}
+		}
+
+		//    private static void breakFromEvent(long eventNr){
+		//        breakOnEvent(eventNr);
+		//        _breakAfterEvent = true;
+		//    }
+		private static void BreakOnEvent(long eventNr)
+		{
+			if (enabled)
+			{
+				if (_breakEventNrs == null)
+				{
+					_breakEventNrs = new long[100];
+				}
+				_breakEventNrs[_breakEventCount] = eventNr;
+				_breakEventCount++;
+			}
+		}
+
+		private string FormatInt(long i, int len)
+		{
+			if (enabled)
+			{
+				string str = "              ";
+				if (i != Unused)
+				{
+					str += i + " ";
+				}
+				return Sharpen.Runtime.Substring(str, str.Length - len);
+			}
+			return null;
+		}
+
+		private string FormatInt(long i)
+		{
+			if (enabled)
+			{
+				return FormatInt(i, 10);
+			}
+			return null;
+		}
+
+		private static void TurnAllOffExceptFor(Db4objects.Db4o.DTrace[] these)
+		{
+			if (enabled)
+			{
+				for (int i = 0; i < all.Length; i++)
+				{
+					if (all[i] == null)
+					{
+						break;
+					}
+					bool turnOff = true;
+					for (int j = 0; j < these.Length; j++)
+					{
+						if (all[i] == these[j])
+						{
+							turnOff = false;
+							break;
+						}
+					}
+					if (turnOff)
+					{
+						all[i]._break = false;
+						all[i]._enabled = false;
+						all[i]._log = false;
+					}
+				}
+			}
+		}
+
+		public static void NoWarnings()
+		{
+			BreakOnEvent(0);
+			TrackEventsWithoutRange();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Db4oEmbedded.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Db4oEmbedded.cs
new file mode 100644
index 0000000..4007fe8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Db4oEmbedded.cs
@@ -0,0 +1,121 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Config;
+
+namespace Db4objects.Db4o
+{
+	/// <summary>Factory class to open db4o instances in embedded
+	/// mode.</summary>
+	/// <remarks> Factory class to open db4o instances in embedded mode.
+	/// </remarks>
+	/// <seealso cref="Db4objects.Db4o.CS.Db4oClientServer"> Db4objects.Db4o.CS.Db4oClientServer in
+	/// Db4objects.Db4o.CS.dll for methods to open db4o servers and db4o
+	/// clients.</seealso>
+	/// <since>7.5</since>
+	public class Db4oEmbedded
+	{
+		/// <summary>
+		/// Creates a fresh
+		/// <see cref="Db4objects.Db4o.Config.IEmbeddedConfiguration">IEmbeddedConfiguration</see>
+		/// instance.
+		/// </summary>
+		/// <returns>a fresh, independent configuration with all options set to their default values
+		/// 	</returns>
+		public static IEmbeddedConfiguration NewConfiguration()
+		{
+			return new EmbeddedConfigurationImpl(Db4oFactory.NewConfiguration());
+		}
+
+		/// <summary>
+		/// opens an
+		/// <see cref="Db4objects.Db4o.IObjectContainer">IObjectContainer</see>
+		/// on the specified database file for local use.
+		/// <br/>
+		/// <br/>
+		/// A database file can only be opened once, subsequent attempts to
+		/// open another
+		/// <see cref="Db4objects.Db4o.IObjectContainer">IObjectContainer</see>
+		/// against the same file will result in a
+		/// <see cref="Db4objects.Db4o.Ext.DatabaseFileLockedException"> DatabaseFileLockedException</see>
+		/// .
+		/// <br/>
+		/// <br/>
+		/// Database files can only be accessed for readwrite access from one
+		/// process at one time. All versions except for db4o mobile edition
+		/// use an internal mechanism to lock the database file for other
+		/// processes.
+		/// <br/>
+		/// <br/>
+		/// </summary>
+		/// <param name="config">
+		/// a custom
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">IConfiguration</see>
+		/// instance to be obtained via
+		/// <see cref="newConfiguration">newConfiguration</see>
+		/// </param>
+		/// <param name="databaseFileName">an absolute or relative path to the database
+		/// file</param>
+		/// <returns>
+		/// an open
+		/// <see cref="Db4objects.Db4o.IObjectContainer">IObjectContainer</see>
+		/// </returns>
+		/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.ReadOnly">
+		/// Db4objects.Db4o.Config.IConfiguration.ReadOnly</seealso>
+		/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.Encrypt"> Db4objects.Db4o.Config.IConfiguration.Encrypt
+		/// </seealso>
+		/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.Password">
+		/// Db4objects.Db4o.Config.IConfiguration.Password</seealso>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"> I/O operation failed or was unexpectedly
+		/// interrupted.</exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseFileLockedException"> the required database file is locked by
+		/// another process.</exception>
+		/// <exception cref="Db4objects.Db4o.Ext.IncompatibleFileFormatException">
+		/// runtime
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">configuration</see>
+		/// is not compatible with the configuration of the database file.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.OldFormatException">
+		/// open operation failed because the database file is in old format
+		/// and
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration.AllowVersionUpdates">
+		/// Db4objects.Db4o.Config.IConfiguration.AllowVersionUpdates</see>
+		/// is set to false.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"> database was configured as read-only.
+		/// </exception>
+		public static IEmbeddedObjectContainer OpenFile(IEmbeddedConfiguration config, string
+			 databaseFileName)
+		{
+			if (null == config)
+			{
+				throw new ArgumentNullException();
+			}
+			return ObjectContainerFactory.OpenObjectContainer(config, databaseFileName);
+		}
+
+		/// <summary>
+		/// Same as calling
+		/// <see cref="OpenFile(Db4objects.Db4o.Config.IEmbeddedConfiguration, string)">OpenFile(Db4objects.Db4o.Config.IEmbeddedConfiguration, string)
+		/// 	</see>
+		/// with a fresh configuration (
+		/// <see cref="NewConfiguration()">NewConfiguration()</see>
+		/// ).
+		/// </summary>
+		/// <param name="databaseFileName">an absolute or relative path to the database file</param>
+		/// <seealso cref="OpenFile(Db4objects.Db4o.Config.IEmbeddedConfiguration, string)">OpenFile(Db4objects.Db4o.Config.IEmbeddedConfiguration, string)
+		/// 	</seealso>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseFileLockedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.IncompatibleFileFormatException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.OldFormatException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		public static IEmbeddedObjectContainer OpenFile(string databaseFileName)
+		{
+			return OpenFile(NewConfiguration(), databaseFileName);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Db4oFactory.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Db4oFactory.cs
new file mode 100644
index 0000000..b1ed144
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Db4oFactory.cs
@@ -0,0 +1,554 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Config;
+
+namespace Db4objects.Db4o
+{
+	/// <summary>factory class to start db4o database engines.</summary>
+	/// <remarks>
+	/// factory class to start db4o database engines.
+	/// <br /><br />This class provides static methods to<br />
+	/// - open single-user databases
+	/// <see cref="OpenFile(string)">OpenFile(string)</see>
+	/// <br />
+	/// - open db4o servers
+	/// <see cref="OpenServer(string, int)">OpenServer(string, int)</see>
+	/// <br />
+	/// - connect to db4o servers
+	/// <see cref="OpenClient(string, int, string, string)">OpenClient(string, int, string, string)
+	/// 	</see>
+	/// <br />
+	/// - provide access to the global configuration context
+	/// <see cref="Configure()">Configure()</see>
+	/// <br />
+	/// - print the version number of this db4o version
+	/// <see cref="Main(java.lang.String[])">Main(java.lang.String[])</see>
+	/// 
+	/// </remarks>
+	/// <seealso cref="ExtDb4o">ExtDb4o for extended functionality.</seealso>
+	public class Db4oFactory
+	{
+		internal static readonly Config4Impl i_config = new Config4Impl();
+
+		static Db4oFactory()
+		{
+			Platform4.GetDefaultConfiguration(i_config);
+		}
+
+		/// <summary>prints the version name of this db4o version to <code>System.out</code>.
+		/// 	</summary>
+		/// <remarks>prints the version name of this db4o version to <code>System.out</code>.
+		/// 	</remarks>
+		public static void Main(string[] args)
+		{
+			Sharpen.Runtime.Out.WriteLine(Version());
+		}
+
+		/// <summary>
+		/// returns the global db4o
+		/// <see cref="IConfiguration">IConfiguration</see>
+		/// context
+		/// for the running CLR session.
+		/// <br/><br/>
+		/// The
+		/// <see cref="IConfiguration">IConfiguration</see>
+		/// can be overriden in each
+		/// <see cref="IExtObjectContainer.Configure">ObjectContainer</see>
+		/// .<br/><br/>
+		/// </summary>
+		/// <returns>
+		/// the global
+		/// <see cref="IConfiguration">configuration</see>
+		/// context
+		/// 
+		/// </returns>
+		public static IConfiguration Configure()
+		{
+			return i_config;
+		}
+
+		/// <summary>
+		/// Creates a fresh
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">IConfiguration</see>
+		/// instance.
+		/// </summary>
+		/// <returns>a fresh, independent configuration with all options set to their default values
+		/// 	</returns>
+		[System.ObsoleteAttribute(@"Use Db4oEmbedded.NewConfiguration() instead.")]
+		public static IConfiguration NewConfiguration()
+		{
+			Config4Impl config = new Config4Impl();
+			Platform4.GetDefaultConfiguration(config);
+			return config;
+		}
+
+		/// <summary>
+		/// Creates a clone of the global db4o
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">IConfiguration</see>
+		/// .
+		/// </summary>
+		/// <returns>
+		/// a fresh configuration with all option values set to the values
+		/// currently configured for the global db4o configuration context
+		/// </returns>
+		[System.ObsoleteAttribute(@"use explicit configuration via Db4oEmbedded.NewConfiguration() instead"
+			)]
+		public static IConfiguration CloneConfiguration()
+		{
+			return (Config4Impl)((IDeepClone)Db4oFactory.Configure()).DeepClone(null);
+		}
+
+		/// <summary>
+		/// Operates just like
+		/// <see cref="Db4objects.Db4o.Db4oFactory.OpenClient">
+		/// Db4objects.Db4o.Db4oFactory.OpenClient
+		/// </see>, but uses
+		/// the global db4o
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">IConfiguration</see>
+		/// context.
+		/// opens an
+		/// <see cref="Db4objects.Db4o.IObjectContainer">IObjectContainer</see>
+		/// client and connects it to the specified named server and port.
+		/// <br/><br/>
+		/// The server needs to
+		/// <see cref="Db4objects.Db4o.IObjectServer.GrantAccess">allow access</see>
+		/// for the specified user and password.
+		/// <br/><br/>
+		/// A client
+		/// <see cref="Db4objects.Db4o.IObjectContainer">IObjectContainer</see>
+		/// can be cast to
+		/// <see cref="Db4objects.Db4o.Ext.IExtClient">IExtClient</see>
+		/// to use extended
+		/// <see cref="Db4objects.Db4o.Ext.IExtObjectContainer">IExtObjectContainer</see>
+		/// 
+		/// and
+		/// <see cref="Db4objects.Db4o.Ext.IExtClient">IExtClient</see>
+		/// methods.
+		/// <br/><br/>
+		/// This method is obsolete, see the Db4objects.Db4o.CS.Db4oClientServer class in
+		/// Db4objects.Db4o.CS.dll for methods to open db4o servers and db4o clients.
+		/// </summary>
+		/// <param name="config">
+		/// a custom
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">IConfiguration</see>
+		/// instance to be obtained via
+		/// <see cref="Db4objects.Db4o.Db4oEmbedded.NewConfiguration">
+		/// Db4objects.Db4o.Db4oEmbedded.NewConfiguration
+		/// </see>
+		/// </param>
+		/// <param name="hostName">the host name</param>
+		/// <param name="port">the port the server is using</param>
+		/// <param name="user">the user name</param>
+		/// <param name="password">the user password</param>
+		/// <returns>
+		/// an open
+		/// <see cref="Db4objects.Db4o.IObjectContainer">IObjectContainer</see>
+		/// </returns>
+		/// <seealso cref="Db4objects.Db4o.IObjectServer.GrantAccess">
+		/// Db4objects.Db4o.IObjectServer.GrantAccess
+		/// </seealso>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException">
+		/// I/O operation failed or was unexpectedly interrupted.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.OldFormatException">
+		/// open operation failed because the database file
+		/// is in old format and
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration.AllowVersionUpdates">
+		/// Db4objects.Db4o.Config.IConfiguration.AllowVersionUpdates
+		/// </see>
+		/// 
+		/// is set to false.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.InvalidPasswordException">
+		/// password supplied for the connection is
+		/// invalid.
+		/// </exception>
+		public static IObjectContainer OpenClient(string hostName, int port, string user, 
+			string password)
+		{
+			return OpenClient(Db4oFactory.CloneConfiguration(), hostName, port, user, password
+				);
+		}
+
+		/// <summary>
+		/// opens an
+		/// <see cref="Db4objects.Db4o.IObjectContainer">IObjectContainer</see>
+		/// client and connects it to the specified named server and port.
+		/// <br/><br/>
+		/// The server needs to
+		/// <see cref="Db4objects.Db4o.IObjectServer.GrantAccess">allow access</see>
+		/// for the specified user and password.
+		/// <br/><br/>
+		/// A client
+		/// <see cref="Db4objects.Db4o.IObjectContainer">IObjectContainer</see>
+		/// can be cast to
+		/// <see cref="Db4objects.Db4o.Ext.IExtClient">IExtClient</see>
+		/// to use extended
+		/// <see cref="Db4objects.Db4o.Ext.IExtObjectContainer">IExtObjectContainer</see>
+		/// 
+		/// and
+		/// <see cref="Db4objects.Db4o.Ext.IExtClient">IExtClient</see>
+		/// methods.
+		/// <br/><br/>
+		/// This method is obsolete, see the Db4objects.Db4o.CS.Db4oClientServer class in
+		/// Db4objects.Db4o.CS.dll for methods to open db4o servers and db4o clients.
+		/// </summary>
+		/// <param name="config">
+		/// a custom
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">IConfiguration</see>
+		/// instance to be obtained via
+		/// <see cref="Db4objects.Db4o.Db4oEmbedded.NewConfiguration">
+		/// Db4objects.Db4o.Db4oEmbedded.NewConfiguration
+		/// </see>
+		/// </param>
+		/// <param name="hostName">the host name</param>
+		/// <param name="port">the port the server is using</param>
+		/// <param name="user">the user name</param>
+		/// <param name="password">the user password</param>
+		/// <returns>
+		/// an open
+		/// <see cref="Db4objects.Db4o.IObjectContainer">IObjectContainer</see>
+		/// </returns>
+		/// <seealso cref="Db4objects.Db4o.IObjectServer.GrantAccess">
+		/// Db4objects.Db4o.IObjectServer.GrantAccess
+		/// </seealso>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException">
+		/// I/O operation failed or was unexpectedly interrupted.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.OldFormatException">
+		/// open operation failed because the database file
+		/// is in old format and
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration.AllowVersionUpdates">
+		/// Db4objects.Db4o.Config.IConfiguration.AllowVersionUpdates
+		/// </see>
+		/// 
+		/// is set to false.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.InvalidPasswordException">
+		/// password supplied for the connection is
+		/// invalid.
+		/// </exception>
+		public static IObjectContainer OpenClient(IConfiguration config, string hostName, 
+			int port, string user, string password)
+		{
+			return ((Config4Impl)config).ClientServerFactory().OpenClient(config, hostName, port
+				, user, password);
+		}
+
+		/// <summary>
+		/// Operates just like
+		/// <see cref="Db4oFactory.OpenFile">Db4oFactory.OpenFile</see>
+		/// , but uses
+		/// the global db4o
+		/// <see cref="IConfiguration">IConfiguration</see>
+		/// context.
+		/// opens an
+		/// <see cref="IObjectContainer">IObjectContainer</see>
+		/// on the specified database file for local use.
+		/// <br/><br/>A database file can only be opened once, subsequent attempts to open
+		/// another
+		/// <see cref="IObjectContainer">IObjectContainer</see>
+		/// against the same file will result in
+		/// a
+		/// <see cref="DatabaseFileLockedException">DatabaseFileLockedException</see>
+		/// .<br/><br/>
+		/// Database files can only be accessed for readwrite access from one process
+		/// at one time. All versions except for db4o mobile edition use an
+		/// internal mechanism to lock the database file for other processes.
+		/// <br/><br/>
+		/// 
+		/// </summary>
+		/// <param name="databaseFileName">an absolute or relative path to the database file</param>
+		/// <returns>
+		/// an open
+		/// <see cref="IObjectContainer">IObjectContainer</see>
+		/// 
+		/// </returns>
+		/// <seealso cref="IConfiguration.ReadOnly">IConfiguration.ReadOnly</seealso>
+		/// <seealso cref="IConfiguration.Encrypt">IConfiguration.Encrypt</seealso>
+		/// <seealso cref="IConfiguration.Password">IConfiguration.Password</seealso>
+		/// <exception cref="Db4oIOException">
+		/// I/O operation failed or was unexpectedly interrupted.
+		/// 
+		/// </exception>
+		/// <exception cref="DatabaseFileLockedException">
+		/// the required database file is locked by
+		/// another process.
+		/// 
+		/// </exception>
+		/// <exception cref="IncompatibleFileFormatException">
+		/// runtime
+		/// <see cref="IConfiguration">configuration</see>
+		/// is not compatible
+		/// with the configuration of the database file.
+		/// 
+		/// </exception>
+		/// <exception cref="OldFormatException">
+		/// open operation failed because the database file
+		/// is in old format and
+		/// <see cref="IConfiguration.AllowVersionUpdates">
+		/// IConfiguration.AllowVersionUpdates
+		/// </see>
+		/// is set to false.
+		/// </exception>
+		/// <exception cref="DatabaseReadOnlyException">
+		/// database was configured as read-only.
+		/// </exception>
+		public static IObjectContainer OpenFile(string databaseFileName)
+		{
+			return Db4oFactory.OpenFile(CloneConfiguration(), databaseFileName);
+		}
+
+		/// <summary>
+		/// opens an
+		/// <see cref="IObjectContainer">IObjectContainer</see>
+		/// on the specified database file for local use.
+		/// <br/><br/>A database file can only be opened once, subsequent attempts to open
+		/// another
+		/// <see cref="IObjectContainer">IObjectContainer</see>
+		/// against the same file will result in
+		/// a
+		/// <see cref="DatabaseFileLockedException">DatabaseFileLockedException</see>
+		/// .<br/><br/>
+		/// Database files can only be accessed for readwrite access from one process
+		/// at one time. All versions except for db4o mobile edition use an
+		/// internal mechanism to lock the database file for other processes.
+		/// <br/><br/>
+		/// 
+		/// </summary>
+		/// <param name="config">
+		/// a custom
+		/// <see cref="IConfiguration">IConfiguration</see>
+		/// instance to be obtained via
+		/// <see cref="Db4oFactory.NewConfiguration">Db4oFactory.NewConfiguration</see>
+		/// 
+		/// </param>
+		/// <param name="databaseFileName">an absolute or relative path to the database file</param>
+		/// <returns>
+		/// an open
+		/// <see cref="IObjectContainer">IObjectContainer</see>
+		/// 
+		/// </returns>
+		/// <seealso cref="IConfiguration.ReadOnly">IConfiguration.ReadOnly</seealso>
+		/// <seealso cref="IConfiguration.Encrypt">IConfiguration.Encrypt</seealso>
+		/// <seealso cref="IConfiguration.Password">IConfiguration.Password</seealso>
+		/// <exception cref="Db4oIOException">
+		/// I/O operation failed or was unexpectedly interrupted.
+		/// 
+		/// </exception>
+		/// <exception cref="DatabaseFileLockedException">
+		/// the required database file is locked by
+		/// another process.
+		/// 
+		/// </exception>
+		/// <exception cref="IncompatibleFileFormatException">
+		/// runtime
+		/// <see cref="IConfiguration">configuration</see>
+		/// is not compatible
+		/// with the configuration of the database file.
+		/// 
+		/// </exception>
+		/// <exception cref="OldFormatException">
+		/// open operation failed because the database file
+		/// is in old format and
+		/// <see cref="IConfiguration.AllowVersionUpdates">
+		/// IConfiguration.AllowVersionUpdates
+		/// 
+		/// </see>
+		/// 
+		/// is set to false.
+		/// 
+		/// </exception>
+		/// <exception cref="DatabaseReadOnlyException">
+		/// database was configured as read-only.
+		/// 
+		/// </exception>
+		public static IObjectContainer OpenFile(IConfiguration config, string databaseFileName
+			)
+		{
+			return ObjectContainerFactory.OpenObjectContainer(Db4oLegacyConfigurationBridge.AsEmbeddedConfiguration
+				(config), databaseFileName);
+		}
+
+		/// <summary>
+		/// Operates just like
+		/// <see cref="Db4objects.Db4o.Db4oFactory.OpenServer">
+		/// Db4objects.Db4o.Db4oFactory.OpenServer
+		/// </see>
+		/// , but uses
+		/// the global db4o
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">IConfiguration</see>
+		/// context.
+		/// Opens an
+		/// <see cref="Db4objects.Db4o.IObjectServer">IObjectServer</see>
+		/// on the specified database file and port.
+		/// <br/><br/>
+		/// If the server does not need to listen on a port because it will only be used
+		/// in embedded mode with
+		/// <see cref="Db4objects.Db4o.IObjectServer.OpenClient">
+		/// Db4objects.Db4o.IObjectServer.OpenClient
+		/// </see>
+		/// , specify '0' as the
+		/// port number.
+		/// <br/><br/>This method is obsolete, see the Db4objects.Db4o.CS.Db4oClientServer class in
+		/// Db4objects.Db4o.CS.dll for methods to open db4o servers and db4o clients.
+		/// </summary>
+		/// <param name="databaseFileName">an absolute or relative path to the database file</param>
+		/// <param name="port">
+		/// the port to be used, or 0, if the server should not open a port,
+		/// because it will only be used with
+		/// <see cref="Db4objects.Db4o.IObjectServer.OpenClient">
+		/// Db4objects.Db4o.IObjectServer.OpenClient
+		/// </see>
+		/// .
+		/// Specify a value < 0 if an arbitrary free port should be chosen - see
+		/// <see cref="Db4objects.Db4o.Ext.IExtObjectServer.Port">
+		/// Db4objects.Db4o.Ext.IExtObjectServer.Port
+		/// </see>
+		/// .
+		/// </param>
+		/// <returns>
+		/// an
+		/// <see cref="Db4objects.Db4o.IObjectServer">IObjectServer</see>
+		/// listening
+		/// on the specified port.
+		/// </returns>
+		/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.ReadOnly">
+		/// Db4objects.Db4o.Config.IConfiguration.ReadOnly
+		/// </seealso>
+		/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.Encrypt">
+		/// Db4objects.Db4o.Config.IConfiguration.Encrypt
+		/// </seealso>
+		/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.Password">
+		/// Db4objects.Db4o.Config.IConfiguration.Password
+		/// </seealso>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException">
+		/// I/O operation failed or was unexpectedly interrupted.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseFileLockedException">
+		/// the required database file is locked by
+		/// another process.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.IncompatibleFileFormatException">
+		/// runtime
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">configuration</see>
+		/// is not compatible
+		/// with the configuration of the database file.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.OldFormatException">
+		/// open operation failed because the database file
+		/// is in old format and
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration.AllowVersionUpdates">
+		/// Db4objects.Db4o.Config.IConfiguration.AllowVersionUpdates
+		/// </see>
+		/// 
+		/// is set to false.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException">
+		/// database was configured as read-only.
+		/// </exception>
+		public static IObjectServer OpenServer(string databaseFileName, int port)
+		{
+			return OpenServer(CloneConfiguration(), databaseFileName, port);
+		}
+
+		/// <summary>
+		/// opens an
+		/// <see cref="Db4objects.Db4o.IObjectServer">IObjectServer</see>
+		/// on the specified database file and port.
+		/// <br/><br/>
+		/// If the server does not need to listen on a port because it will only be used
+		/// in embedded mode with
+		/// <see cref="Db4objects.Db4o.IObjectServer.OpenClient">
+		/// Db4objects.Db4o.IObjectServer.OpenClient
+		/// </see>
+		/// , specify '0' as the
+		/// port number.
+		/// <br/><br/>This method is obsolete, see the Db4objects.Db4o.CS.Db4oClientServer class in
+		/// Db4objects.Db4o.CS.dll for methods to open db4o servers and db4o clients.
+		/// </summary>
+		/// <param name="config">
+		/// a custom
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">IConfiguration</see>
+		/// instance to be obtained via
+		/// <see cref="Db4objects.Db4o.Db4oEmbedded.NewConfiguration">
+		/// Db4objects.Db4o.Db4oEmbedded.NewConfiguration
+		/// </see>
+		/// </param>
+		/// <param name="databaseFileName">an absolute or relative path to the database file</param>
+		/// <param name="port">
+		/// the port to be used, or 0, if the server should not open a port,
+		/// because it will only be used with
+		/// <see cref="Db4objects.Db4o.IObjectServer.OpenClient">
+		/// Db4objects.Db4o.IObjectServer.OpenClient
+		/// </see>
+		/// .
+		/// Specify a value < 0 if an arbitrary free port should be chosen - see
+		/// <see cref="Db4objects.Db4o.Ext.IExtObjectServer.Port">
+		/// Db4objects.Db4o.Ext.IExtObjectServer.Port
+		/// </see>
+		/// .
+		/// </param>
+		/// <returns>
+		/// an
+		/// <see cref="Db4objects.Db4o.IObjectServer">IObjectServer</see>
+		/// listening
+		/// on the specified port.
+		/// </returns>
+		/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.ReadOnly">
+		/// Db4objects.Db4o.Config.IConfiguration.ReadOnly
+		/// </seealso>
+		/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.Encrypt">
+		/// Db4objects.Db4o.Config.IConfiguration.Encrypt
+		/// </seealso>
+		/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.Password">
+		/// Db4objects.Db4o.Config.IConfiguration.Password
+		/// </seealso>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException">
+		/// I/O operation failed or was unexpectedly interrupted.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseFileLockedException">
+		/// the required database file is locked by
+		/// another process.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.IncompatibleFileFormatException">
+		/// runtime
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">configuration</see>
+		/// is not compatible
+		/// with the configuration of the database file.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.OldFormatException">
+		/// open operation failed because the database file
+		/// is in old format and
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration.AllowVersionUpdates">
+		/// Db4objects.Db4o.Config.IConfiguration.AllowVersionUpdates
+		/// </see>
+		/// 
+		/// is set to false.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException">
+		/// database was configured as read-only.
+		/// </exception>
+		public static IObjectServer OpenServer(IConfiguration config, string databaseFileName
+			, int port)
+		{
+			return ((Config4Impl)config).ClientServerFactory().OpenServer(config, databaseFileName
+				, port);
+		}
+
+		/// <summary>returns the version name of the used db4o version.</summary>
+		/// <remarks>
+		/// returns the version name of the used db4o version.
+		/// <br /><br />
+		/// </remarks>
+		/// <returns>version information as a <code>String</code>.</returns>
+		public static string Version()
+		{
+			return "db4o " + Db4oVersion.Name;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Db4oVersion.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Db4oVersion.cs
new file mode 100644
index 0000000..117efa7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Db4oVersion.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o
+{
+	/// <exclude></exclude>
+	public class Db4oVersion
+	{
+		public static readonly string Name = "8.0.183.14430";
+
+		public const int Major = 8;
+
+		public const int Minor = 0;
+
+		public const int Iteration = 183;
+
+		public const int Revision = 14430;
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Debug4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Debug4.cs
new file mode 100644
index 0000000..4d7fe7e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Debug4.cs
@@ -0,0 +1,140 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o
+{
+	/// <exclude></exclude>
+	public sealed class Debug4
+	{
+		/// <summary>indexes all fields</summary>
+		public const bool indexAllFields = false;
+
+		/// <summary>prints query graph information to the console</summary>
+		public const bool queries = false;
+
+		/// <summary>
+		/// allows faking the Db4oDatabase identity object, so the first
+		/// stored object in the debugger is the actually persisted object
+		/// Changing this setting to true will fail some tests that expect
+		/// database files to have identity
+		/// </summary>
+		public const bool staticIdentity = queries;
+
+		/// <summary>prints more stack traces</summary>
+		public const bool atHome = false;
+
+		/// <summary>makes C/S timeouts longer, so C/S does not time out in the debugger</summary>
+		public const bool longTimeOuts = false;
+
+		/// <summary>turns freespace debuggin on</summary>
+		public const bool freespace = Deploy.debug;
+
+		/// <summary>
+		/// fills deleted slots with 'X' and overrides any configured
+		/// freespace filler
+		/// </summary>
+		public const bool xbytes = freespace;
+
+		/// <summary>
+		/// checks monitor conditions to make sure only the thread
+		/// with the global monitor is allowed entry to the core
+		/// </summary>
+		public const bool checkSychronization = false;
+
+		/// <summary>
+		/// makes sure a configuration entry is generated for each persistent
+		/// class
+		/// </summary>
+		public const bool configureAllClasses = indexAllFields;
+
+		/// <summary>
+		/// makes sure a configuration entry is generated for each persistent
+		/// field
+		/// </summary>
+		public const bool configureAllFields = indexAllFields;
+
+		/// <summary>allows turning weak references off</summary>
+		public const bool weakReferences = true;
+
+		/// <summary>prints all communicated messages to the console</summary>
+		public const bool messages = false;
+
+		/// <summary>allows turning NIO off on Java</summary>
+		public const bool nio = true;
+
+		/// <summary>allows overriding the file locking mechanism to turn it off</summary>
+		public const bool lockFile = true;
+
+		public static void Expect(bool cond)
+		{
+			if (!cond)
+			{
+				throw new Exception("Should never happen");
+			}
+		}
+
+		public static void EnsureLock(object obj)
+		{
+		}
+
+		public static bool ExceedsMaximumBlockSize(int a_length)
+		{
+			if (a_length > Const4.MaximumBlockSize)
+			{
+				return true;
+			}
+			return false;
+		}
+
+		public static bool ExceedsMaximumArrayEntries(int a_entries, bool a_primitive)
+		{
+			if (a_entries > (a_primitive ? Const4.MaximumArrayEntriesPrimitive : Const4.MaximumArrayEntries
+				))
+			{
+				return true;
+			}
+			return false;
+		}
+
+		public static void ReadBegin(IReadBuffer buffer, byte identifier)
+		{
+		}
+
+		public static void ReadEnd(IReadBuffer buffer)
+		{
+			if (Deploy.debug && Deploy.brackets)
+			{
+				if (buffer.ReadByte() != Const4.Yapend)
+				{
+					throw new Exception("Debug.readEnd() YAPEND expected");
+				}
+			}
+		}
+
+		public static void WriteBegin(IWriteBuffer buffer, byte identifier)
+		{
+		}
+
+		public static void WriteEnd(IWriteBuffer buffer)
+		{
+			if (Deploy.debug && Deploy.brackets)
+			{
+				if (buffer is MarshallingContext)
+				{
+					((MarshallingContext)buffer).DebugWriteEnd(Const4.Yapend);
+					return;
+				}
+				buffer.WriteByte(Const4.Yapend);
+			}
+		}
+
+		private Debug4()
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/AbstractIdMapping.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/AbstractIdMapping.cs
new file mode 100644
index 0000000..9bf1cea
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/AbstractIdMapping.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Defragment;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Defragment
+{
+	/// <summary>Base class for defragment ID mappings.</summary>
+	/// <remarks>Base class for defragment ID mappings.</remarks>
+	/// <seealso cref="Defragment">Defragment</seealso>
+	public abstract class AbstractIdMapping : IIdMapping
+	{
+		private Hashtable4 _classIDs = new Hashtable4();
+
+		public void MapId(int origID, int mappedID, bool isClassID)
+		{
+			if (isClassID)
+			{
+				MapClassIDs(origID, mappedID);
+				return;
+			}
+			MapNonClassIDs(origID, mappedID);
+		}
+
+		protected virtual int MappedClassID(int origID)
+		{
+			object obj = _classIDs.Get(origID);
+			if (obj == null)
+			{
+				return 0;
+			}
+			return ((int)obj);
+		}
+
+		private void MapClassIDs(int oldID, int newID)
+		{
+			_classIDs.Put(oldID, newID);
+		}
+
+		protected abstract void MapNonClassIDs(int origID, int mappedID);
+
+		public abstract int AddressForId(int arg1);
+
+		public abstract void Close();
+
+		public abstract void Commit();
+
+		public abstract void MapId(int arg1, Slot arg2);
+
+		public abstract int MappedId(int arg1);
+
+		public abstract void Open();
+
+		public abstract IVisitable SlotChanges();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/DatabaseIdMapping.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/DatabaseIdMapping.cs
new file mode 100644
index 0000000..10d7cc0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/DatabaseIdMapping.cs
@@ -0,0 +1,222 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Defragment;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Mapping;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Defragment
+{
+	/// <summary>Database based mapping for IDs during a defragmentation run.</summary>
+	/// <remarks>
+	/// Database based mapping for IDs during a defragmentation run.
+	/// Use this mapping to keep memory consumption lower than when
+	/// using the
+	/// <see cref="InMemoryIdMapping">InMemoryIdMapping</see>
+	/// .
+	/// </remarks>
+	/// <seealso cref="Defragment">Defragment</seealso>
+	public class DatabaseIdMapping : AbstractIdMapping
+	{
+		private string _fileName;
+
+		private LocalObjectContainer _mappingDb;
+
+		private BTree _idTree;
+
+		private BTree _slotTree;
+
+		private MappedIDPair _cache = new MappedIDPair(0, 0);
+
+		private DatabaseIdMapping.BTreeSpec _treeSpec = null;
+
+		private int _commitFrequency = 0;
+
+		private int _idInsertCount = 0;
+
+		private int _slotInsertCount = 0;
+
+		/// <summary>Will maintain the ID mapping as a BTree in the file with the given path.
+		/// 	</summary>
+		/// <remarks>
+		/// Will maintain the ID mapping as a BTree in the file with the given path.
+		/// If a file exists in this location, it will be DELETED.
+		/// Node size and cache height of the tree will be the default values used by
+		/// the BTree implementation. The tree will never commit.
+		/// </remarks>
+		/// <param name="fileName">The location where the BTree file should be created.</param>
+		public DatabaseIdMapping(string fileName) : this(fileName, null, 0)
+		{
+		}
+
+		/// <summary>Will maintain the ID mapping as a BTree in the file with the given path.
+		/// 	</summary>
+		/// <remarks>
+		/// Will maintain the ID mapping as a BTree in the file with the given path.
+		/// If a file exists in this location, it will be DELETED.
+		/// </remarks>
+		/// <param name="fileName">The location where the BTree file should be created.</param>
+		/// <param name="nodeSize">The size of a BTree node</param>
+		/// <param name="commitFrequency">The number of inserts after which a commit should be issued (<=0: never commit)
+		/// 	</param>
+		public DatabaseIdMapping(string fileName, int nodeSize, int commitFrequency) : this
+			(fileName, new DatabaseIdMapping.BTreeSpec(nodeSize), commitFrequency)
+		{
+		}
+
+		private DatabaseIdMapping(string fileName, DatabaseIdMapping.BTreeSpec treeSpec, 
+			int commitFrequency)
+		{
+			// <=0 : never commit
+			_fileName = fileName;
+			_treeSpec = treeSpec;
+			_commitFrequency = commitFrequency;
+		}
+
+		public override int MappedId(int oldID)
+		{
+			if (_cache.Orig() == oldID)
+			{
+				return _cache.Mapped();
+			}
+			int classID = MappedClassID(oldID);
+			if (classID != 0)
+			{
+				return classID;
+			}
+			IBTreeRange range = _idTree.SearchRange(Trans(), new MappedIDPair(oldID, 0));
+			IEnumerator pointers = range.Pointers();
+			if (pointers.MoveNext())
+			{
+				BTreePointer pointer = (BTreePointer)pointers.Current;
+				_cache = (MappedIDPair)pointer.Key();
+				return _cache.Mapped();
+			}
+			return 0;
+		}
+
+		protected override void MapNonClassIDs(int origID, int mappedID)
+		{
+			_cache = new MappedIDPair(origID, mappedID);
+			_idTree.Add(Trans(), _cache);
+			if (_commitFrequency > 0)
+			{
+				_idInsertCount++;
+				if (_commitFrequency == _idInsertCount)
+				{
+					_idTree.Commit(Trans());
+					_idInsertCount = 0;
+				}
+			}
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public override void Open()
+		{
+			_mappingDb = DefragmentServicesImpl.FreshTempFile(_fileName, 1);
+			_idTree = (_treeSpec == null ? new BTree(Trans(), 0, new MappedIDPairHandler()) : 
+				new BTree(Trans(), 0, new MappedIDPairHandler(), _treeSpec.NodeSize()));
+			_slotTree = (_treeSpec == null ? new BTree(Trans(), 0, new BTreeIdSystem.IdSlotMappingHandler
+				()) : new BTree(Trans(), 0, new BTreeIdSystem.IdSlotMappingHandler(), _treeSpec.
+				NodeSize()));
+		}
+
+		public override void Close()
+		{
+			_mappingDb.Close();
+		}
+
+		private Transaction Trans()
+		{
+			return _mappingDb.SystemTransaction();
+		}
+
+		private class BTreeSpec
+		{
+			private int _nodeSize;
+
+			public BTreeSpec(int nodeSize)
+			{
+				_nodeSize = nodeSize;
+			}
+
+			public virtual int NodeSize()
+			{
+				return _nodeSize;
+			}
+		}
+
+		public override void MapId(int id, Slot slot)
+		{
+			_slotTree.Add(Trans(), new IdSlotMapping(id, slot.Address(), slot.Length()));
+			if (_commitFrequency > 0)
+			{
+				_slotInsertCount++;
+				if (_commitFrequency == _slotInsertCount)
+				{
+					_slotTree.Commit(Trans());
+					_slotInsertCount = 0;
+				}
+			}
+		}
+
+		public override IVisitable SlotChanges()
+		{
+			return new _IVisitable_137(this);
+		}
+
+		private sealed class _IVisitable_137 : IVisitable
+		{
+			public _IVisitable_137(DatabaseIdMapping _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Accept(IVisitor4 outSideVisitor)
+			{
+				this._enclosing._slotTree.TraverseKeys(this._enclosing.Trans(), new _IVisitor4_139
+					(outSideVisitor));
+			}
+
+			private sealed class _IVisitor4_139 : IVisitor4
+			{
+				public _IVisitor4_139(IVisitor4 outSideVisitor)
+				{
+					this.outSideVisitor = outSideVisitor;
+				}
+
+				public void Visit(object idSlotMapping)
+				{
+					SlotChange slotChange = new SlotChange(((IdSlotMapping)idSlotMapping)._id);
+					slotChange.NotifySlotCreated(((IdSlotMapping)idSlotMapping).Slot());
+					outSideVisitor.Visit(slotChange);
+				}
+
+				private readonly IVisitor4 outSideVisitor;
+			}
+
+			private readonly DatabaseIdMapping _enclosing;
+		}
+
+		public override int AddressForId(int id)
+		{
+			IBTreeRange range = _slotTree.SearchRange(Trans(), new IdSlotMapping(id, 0, 0));
+			IEnumerator pointers = range.Pointers();
+			if (pointers.MoveNext())
+			{
+				BTreePointer pointer = (BTreePointer)pointers.Current;
+				return ((IdSlotMapping)pointer.Key())._address;
+			}
+			return 0;
+		}
+
+		public override void Commit()
+		{
+			_mappingDb.Commit();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/Defragment.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/Defragment.cs
new file mode 100644
index 0000000..2f78608
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/Defragment.cs
@@ -0,0 +1,447 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.IO;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Defragment;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Classindex;
+using Db4objects.Db4o.Internal.Mapping;
+
+namespace Db4objects.Db4o.Defragment
+{
+	/// <summary>defragments database files.</summary>
+	/// <remarks>
+	/// defragments database files.
+	/// <br/>
+	/// <br/>
+	/// db4o structures storage inside database files as free and occupied
+	/// slots, very much like a file system - and just like a file system it
+	/// can be fragmented.
+	/// <br/>
+	/// <br/>
+	/// The simplest way to defragment a database file:
+	/// <br/>
+	/// <br/>
+	/// <code>Defragment.Defrag("sample.yap");
+	/// </code>
+	/// <br/>
+	/// <br/>
+	/// This will move the file to "sample.yap.backup", then create a
+	/// defragmented version of this file in the original position, using a
+	/// temporary file "sample.yap.mapping". If the backup file already
+	/// exists, this will throw an exception and no action will be taken.
+	/// <br/>
+	/// <br/>
+	/// For more detailed configuration of the defragmentation process,
+	/// provide a DefragmentConfig instance:
+	/// <br/>
+	/// <br/>
+	/// <code>
+	/// DefragmentConfig config=new
+	/// DefragmentConfig("sample.yap","sample.bap",new
+	/// BTreeIDMapping("sample.map"));
+	/// <br/>
+	/// config.ForceBackupDelete(true);
+	/// <br/>
+	/// config.StoredClassFilter(new AvailableClassFilter());
+	/// <br/>
+	/// config.Db4oConfig(db4oConfig);
+	/// <br/>
+	/// Defragment.Defrag(config);
+	/// </code>
+	/// <br/>
+	/// <br/>
+	/// This will move the file to "sample.bap", then create a defragmented
+	/// version of this file in the original position, using a temporary
+	/// file "sample.map" for BTree mapping. If the backup file already
+	/// exists, it will be deleted. The defragmentation process will skip
+	/// all classes that have instances stored within the yap file, but that
+	/// are not available on the class path (through the current
+	/// classloader). Custom db4o configuration options are read from the
+	/// <see cref="IConfiguration">IConfiguration</see>
+	/// passed as db4oConfig.
+	/// <strong>Note:</strong>
+	/// For some specific, non-default configuration settings like UUID
+	/// generation, etc., you
+	/// <strong>must</strong>
+	/// pass an appropriate db4o configuration, just like you'd use it
+	/// within your application for normal database operation.
+	/// </remarks>
+	public class Defragment
+	{
+		/// <summary>
+		/// Renames the file at the given original path to a backup file and then
+		/// builds a defragmented version of the file in the original place.
+		/// </summary>
+		/// <remarks>
+		/// Renames the file at the given original path to a backup file and then
+		/// builds a defragmented version of the file in the original place.
+		/// </remarks>
+		/// <param name="origPath">The path to the file to be defragmented.</param>
+		/// <exception cref="System.IO.IOException">if the original file cannot be moved to the backup location
+		/// 	</exception>
+		public static void Defrag(string origPath)
+		{
+			Defrag(new DefragmentConfig(origPath), new Defragment.NullListener());
+		}
+
+		/// <summary>
+		/// Renames the file at the given original path to the given backup file and
+		/// then builds a defragmented version of the file in the original place.
+		/// </summary>
+		/// <remarks>
+		/// Renames the file at the given original path to the given backup file and
+		/// then builds a defragmented version of the file in the original place.
+		/// </remarks>
+		/// <param name="origPath">The path to the file to be defragmented.</param>
+		/// <param name="backupPath">The path to the backup file to be created.</param>
+		/// <exception cref="System.IO.IOException">if the original file cannot be moved to the backup location
+		/// 	</exception>
+		public static void Defrag(string origPath, string backupPath)
+		{
+			Defrag(new DefragmentConfig(origPath, backupPath), new Defragment.NullListener());
+		}
+
+		/// <summary>
+		/// Renames the file at the configured original path to the configured backup
+		/// path and then builds a defragmented version of the file in the original
+		/// place.
+		/// </summary>
+		/// <remarks>
+		/// Renames the file at the configured original path to the configured backup
+		/// path and then builds a defragmented version of the file in the original
+		/// place.
+		/// </remarks>
+		/// <param name="config">The configuration for this defragmentation run.</param>
+		/// <exception cref="System.IO.IOException">if the original file cannot be moved to the backup location
+		/// 	</exception>
+		public static void Defrag(DefragmentConfig config)
+		{
+			Defrag(config, new Defragment.NullListener());
+		}
+
+		/// <summary>
+		/// Renames the file at the configured original path to the configured backup
+		/// path and then builds a defragmented version of the file in the original
+		/// place.
+		/// </summary>
+		/// <remarks>
+		/// Renames the file at the configured original path to the configured backup
+		/// path and then builds a defragmented version of the file in the original
+		/// place.
+		/// </remarks>
+		/// <param name="config">The configuration for this defragmentation run.</param>
+		/// <param name="listener">
+		/// A listener for status notifications during the defragmentation
+		/// process.
+		/// </param>
+		/// <exception cref="System.IO.IOException">if the original file cannot be moved to the backup location
+		/// 	</exception>
+		public static void Defrag(DefragmentConfig config, IDefragmentListener listener)
+		{
+			IStorage storage = config.Db4oConfig().Storage;
+			EnsureFileExists(storage, config.OrigPath());
+			IStorage backupStorage = config.BackupStorage();
+			if (backupStorage.Exists(config.BackupPath()))
+			{
+				if (!config.ForceBackupDelete())
+				{
+					throw new IOException("Could not use '" + config.BackupPath() + "' as backup path - file exists."
+						);
+				}
+			}
+			// Always delete, because !exists can indicate length == 0
+			backupStorage.Delete(config.BackupPath());
+			MoveToBackup(config);
+			if (config.FileNeedsUpgrade())
+			{
+				UpgradeFile(config);
+			}
+			DefragmentServicesImpl services = new DefragmentServicesImpl(config, listener);
+			try
+			{
+				FirstPass(services, config);
+				services.CommitIds();
+				SecondPass(services, config);
+				services.CommitIds();
+				DefragUnindexed(services);
+				services.CommitIds();
+				services.DefragIdToTimestampBtree();
+				services.ReplaceClassMetadataRepository();
+			}
+			catch (CorruptionException exc)
+			{
+				Sharpen.Runtime.PrintStackTrace(exc);
+			}
+			finally
+			{
+				services.Close();
+			}
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		private static void MoveToBackup(DefragmentConfig config)
+		{
+			IStorage origStorage = config.Db4oConfig().Storage;
+			if (origStorage == config.BackupStorage())
+			{
+				origStorage.Rename(config.OrigPath(), config.BackupPath());
+				return;
+			}
+			CopyBin(origStorage, config.BackupStorage(), config.OrigPath(), config.BackupPath
+				());
+			origStorage.Delete(config.OrigPath());
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		private static void CopyBin(IStorage sourceStorage, IStorage targetStorage, string
+			 sourcePath, string targetPath)
+		{
+			IBin origBin = sourceStorage.Open(new BinConfiguration(sourcePath, true, 0, true)
+				);
+			try
+			{
+				IBin backupBin = targetStorage.Open(new BinConfiguration(targetPath, true, origBin
+					.Length(), false));
+				try
+				{
+					byte[] buffer = new byte[4096];
+					int bytesRead = -1;
+					int pos = 0;
+					while ((bytesRead = origBin.Read(pos, buffer, buffer.Length)) >= 0)
+					{
+						backupBin.Write(pos, buffer, bytesRead);
+						pos += bytesRead;
+					}
+				}
+				finally
+				{
+					SyncAndClose(backupBin);
+				}
+			}
+			finally
+			{
+				SyncAndClose(origBin);
+			}
+		}
+
+		private static void SyncAndClose(IBin bin)
+		{
+			try
+			{
+				bin.Sync();
+			}
+			finally
+			{
+				bin.Close();
+			}
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		private static void EnsureFileExists(IStorage storage, string origPath)
+		{
+			if (!storage.Exists(origPath))
+			{
+				throw new IOException("Source database file '" + origPath + "' does not exist.");
+			}
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		private static void UpgradeFile(DefragmentConfig config)
+		{
+			CopyBin(config.BackupStorage(), config.BackupStorage(), config.BackupPath(), config
+				.TempPath());
+			IConfiguration db4oConfig = (IConfiguration)((Config4Impl)config.Db4oConfig()).DeepClone
+				(null);
+			db4oConfig.Storage = config.BackupStorage();
+			db4oConfig.AllowVersionUpdates(true);
+			IObjectContainer db = Db4oFactory.OpenFile(db4oConfig, config.TempPath());
+			db.Close();
+		}
+
+		private static void DefragUnindexed(DefragmentServicesImpl services)
+		{
+			IdSource unindexedIDs = services.UnindexedIDs();
+			while (unindexedIDs.HasMoreIds())
+			{
+				int origID = unindexedIDs.NextId();
+				DefragmentContextImpl.ProcessCopy(services, origID, new _ISlotCopyHandler_208());
+			}
+		}
+
+		private sealed class _ISlotCopyHandler_208 : ISlotCopyHandler
+		{
+			public _ISlotCopyHandler_208()
+			{
+			}
+
+			public void ProcessCopy(DefragmentContextImpl context)
+			{
+				ClassMetadata.DefragObject(context);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="System.IO.IOException"></exception>
+		private static void FirstPass(DefragmentServicesImpl context, DefragmentConfig config
+			)
+		{
+			// System.out.println("FIRST");
+			Pass(context, config, new FirstPassCommand());
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="System.IO.IOException"></exception>
+		private static void SecondPass(DefragmentServicesImpl context, DefragmentConfig config
+			)
+		{
+			// System.out.println("SECOND");
+			Pass(context, config, new SecondPassCommand(config.ObjectCommitFrequency()));
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="System.IO.IOException"></exception>
+		private static void Pass(DefragmentServicesImpl context, DefragmentConfig config, 
+			IPassCommand command)
+		{
+			command.ProcessClassCollection(context);
+			IStoredClass[] classes = context.StoredClasses(DefragmentServicesImpl.Sourcedb);
+			for (int classIdx = 0; classIdx < classes.Length; classIdx++)
+			{
+				ClassMetadata classMetadata = (ClassMetadata)classes[classIdx];
+				if (!config.StoredClassFilter().Accept(classMetadata))
+				{
+					continue;
+				}
+				ProcessClass(context, classMetadata, command);
+				command.Flush(context);
+				if (config.ObjectCommitFrequency() > 0)
+				{
+					context.TargetCommit();
+				}
+			}
+			BTree uuidIndex = context.SourceUuidIndex();
+			if (uuidIndex != null)
+			{
+				command.ProcessBTree(context, uuidIndex);
+			}
+			command.Flush(context);
+			context.TargetCommit();
+		}
+
+		// TODO order of class index/object slot processing is crucial:
+		// - object slots before field indices (object slots register addresses for
+		// use by string indices)
+		// - class index before object slots, otherwise phantom btree entries from
+		// deletions appear in the source class index?!?
+		// reproducable with SelectiveCascadingDeleteTestCase and ObjectSetTestCase
+		// - investigate.
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="System.IO.IOException"></exception>
+		private static void ProcessClass(DefragmentServicesImpl context, ClassMetadata curClass
+			, IPassCommand command)
+		{
+			ProcessClassIndex(context, curClass, command);
+			if (!ParentHasIndex(curClass))
+			{
+				ProcessObjectsForClass(context, curClass, command);
+			}
+			ProcessClassAndFieldIndices(context, curClass, command);
+		}
+
+		private static bool ParentHasIndex(ClassMetadata curClass)
+		{
+			ClassMetadata parentClass = curClass.GetAncestor();
+			while (parentClass != null)
+			{
+				if (parentClass.HasClassIndex())
+				{
+					return true;
+				}
+				parentClass = parentClass.GetAncestor();
+			}
+			return false;
+		}
+
+		private static void ProcessObjectsForClass(DefragmentServicesImpl context, ClassMetadata
+			 curClass, IPassCommand command)
+		{
+			context.TraverseAll(curClass, new _IVisitor4_284(command, context, curClass));
+		}
+
+		private sealed class _IVisitor4_284 : IVisitor4
+		{
+			public _IVisitor4_284(IPassCommand command, DefragmentServicesImpl context, ClassMetadata
+				 curClass)
+			{
+				this.command = command;
+				this.context = context;
+				this.curClass = curClass;
+			}
+
+			public void Visit(object obj)
+			{
+				int id = ((int)obj);
+				try
+				{
+					// FIXME bubble up exceptions
+					command.ProcessObjectSlot(context, curClass, id);
+				}
+				catch (CorruptionException e)
+				{
+					Sharpen.Runtime.PrintStackTrace(e);
+				}
+				catch (IOException e)
+				{
+					Sharpen.Runtime.PrintStackTrace(e);
+				}
+			}
+
+			private readonly IPassCommand command;
+
+			private readonly DefragmentServicesImpl context;
+
+			private readonly ClassMetadata curClass;
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="System.IO.IOException"></exception>
+		private static void ProcessClassAndFieldIndices(DefragmentServicesImpl context, ClassMetadata
+			 curClass, IPassCommand command)
+		{
+			int sourceClassIndexID = 0;
+			int targetClassIndexID = 0;
+			if (curClass.HasClassIndex())
+			{
+				sourceClassIndexID = curClass.Index().Id();
+				targetClassIndexID = context.MappedID(sourceClassIndexID, -1);
+			}
+			command.ProcessClass(context, curClass, curClass.GetID(), targetClassIndexID);
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="System.IO.IOException"></exception>
+		private static void ProcessClassIndex(DefragmentServicesImpl context, ClassMetadata
+			 curClass, IPassCommand command)
+		{
+			if (curClass.HasClassIndex())
+			{
+				BTreeClassIndexStrategy indexStrategy = (BTreeClassIndexStrategy)curClass.Index();
+				BTree btree = indexStrategy.Btree();
+				command.ProcessBTree(context, btree);
+			}
+		}
+
+		internal class NullListener : IDefragmentListener
+		{
+			public virtual void NotifyDefragmentInfo(DefragmentInfo info)
+			{
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/DefragmentConfig.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/DefragmentConfig.cs
new file mode 100644
index 0000000..8a30468
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/DefragmentConfig.cs
@@ -0,0 +1,305 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Defragment;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Config;
+
+namespace Db4objects.Db4o.Defragment
+{
+	/// <summary>Configuration for a defragmentation run.</summary>
+	/// <remarks>Configuration for a defragmentation run.</remarks>
+	/// <seealso cref="Defragment">Defragment</seealso>
+	public class DefragmentConfig
+	{
+		public const bool Debug = false;
+
+		public static readonly string BackupSuffix = "backup";
+
+		private string _origPath;
+
+		private string _backupPath;
+
+		private string _tempPath;
+
+		private IIdMapping _mapping;
+
+		private IConfiguration _config;
+
+		private IStoredClassFilter _storedClassFilter = null;
+
+		private bool _forceBackupDelete = false;
+
+		private bool _readOnly = true;
+
+		private int _objectCommitFrequency;
+
+		private IStorage _backupStorage;
+
+		/// <summary>Creates a configuration for a defragmentation run.</summary>
+		/// <remarks>
+		/// Creates a configuration for a defragmentation run. The backup and mapping
+		/// file paths are generated from the original path by appending the default
+		/// suffixes. All properties other than the provided paths are set to FALSE
+		/// by default.
+		/// </remarks>
+		/// <param name="origPath">
+		/// The path to the file to be defragmented. Must exist and must be
+		/// a valid db4o file.
+		/// </param>
+		public DefragmentConfig(string origPath) : this(origPath, origPath + "." + BackupSuffix
+			)
+		{
+		}
+
+		/// <summary>Creates a configuration for a defragmentation run with in-memory mapping.
+		/// 	</summary>
+		/// <remarks>
+		/// Creates a configuration for a defragmentation run with in-memory mapping.
+		/// All properties other than the provided paths are set to FALSE by default.
+		/// </remarks>
+		/// <param name="origPath">
+		/// The path to the file to be defragmented. Must exist and must be
+		/// a valid db4o file.
+		/// </param>
+		/// <param name="backupPath">
+		/// The path to the backup of the original file. No file should
+		/// exist at this position, otherwise it will be OVERWRITTEN if forceBackupDelete()
+		/// is set to true!
+		/// </param>
+		public DefragmentConfig(string origPath, string backupPath) : this(origPath, backupPath
+			, new InMemoryIdMapping())
+		{
+		}
+
+		/// <summary>Creates a configuration for a defragmentation run.</summary>
+		/// <remarks>
+		/// Creates a configuration for a defragmentation run. All properties other
+		/// than the provided paths are set to FALSE by default.
+		/// </remarks>
+		/// <param name="origPath">
+		/// The path to the file to be defragmented. Must exist and must be
+		/// a valid db4o file.
+		/// </param>
+		/// <param name="backupPath">
+		/// The path to the backup of the original file. No file should
+		/// exist at this position, otherwise it will be OVERWRITTEN if forceBackupDelete()
+		/// is set to true!
+		/// </param>
+		/// <param name="mapping">
+		/// The Id mapping to be used internally. Pass either a
+		/// <see cref="InMemoryIdMapping">InMemoryIdMapping</see>
+		/// for fastest defragment or a
+		/// <see cref="DatabaseIdMapping">DatabaseIdMapping</see>
+		/// for low memory consumption.
+		/// </param>
+		public DefragmentConfig(string origPath, string backupPath, IIdMapping mapping)
+		{
+			_origPath = origPath;
+			_backupPath = backupPath;
+			_mapping = mapping;
+		}
+
+		/// <returns>The path to the file to be defragmented.</returns>
+		public virtual string OrigPath()
+		{
+			return _origPath;
+		}
+
+		/// <returns>The path to the backup of the original file.</returns>
+		public virtual string BackupPath()
+		{
+			return _backupPath;
+		}
+
+		/// <returns>The temporary ID mapping used internally. For internal use only.</returns>
+		public virtual IIdMapping Mapping()
+		{
+			return _mapping;
+		}
+
+		/// <returns>
+		/// The
+		/// <see cref="IStoredClassFilter">IStoredClassFilter</see>
+		/// used to select stored class extents to
+		/// be included into the defragmented file.
+		/// </returns>
+		public virtual IStoredClassFilter StoredClassFilter()
+		{
+			return (_storedClassFilter == null ? Nullfilter : _storedClassFilter);
+		}
+
+		/// <param name="storedClassFilter">
+		/// The
+		/// <see cref="IStoredClassFilter">IStoredClassFilter</see>
+		/// used to select stored class extents to
+		/// be included into the defragmented file.
+		/// </param>
+		public virtual void StoredClassFilter(IStoredClassFilter storedClassFilter)
+		{
+			_storedClassFilter = storedClassFilter;
+		}
+
+		/// <returns>true, if an existing backup file should be deleted, false otherwise.</returns>
+		public virtual bool ForceBackupDelete()
+		{
+			return _forceBackupDelete;
+		}
+
+		/// <param name="forceBackupDelete">true, if an existing backup file should be deleted, false otherwise.
+		/// 	</param>
+		public virtual void ForceBackupDelete(bool forceBackupDelete)
+		{
+			_forceBackupDelete = forceBackupDelete;
+		}
+
+		/// <summary>
+		/// allows turning on and off readonly mode.<br /><br />
+		/// When changed classes are likely to be detected defragment, it may be required
+		/// to open the original database in read/write mode.
+		/// </summary>
+		/// <remarks>
+		/// allows turning on and off readonly mode.<br /><br />
+		/// When changed classes are likely to be detected defragment, it may be required
+		/// to open the original database in read/write mode. <br /><br />
+		/// Readonly mode is the default setting.
+		/// </remarks>
+		/// <param name="flag">false, to turn off readonly mode.</param>
+		public virtual void ReadOnly(bool flag)
+		{
+			_readOnly = flag;
+		}
+
+		/// <returns>true, if the original database file is to be opened in readonly mode.</returns>
+		public virtual bool ReadOnly()
+		{
+			return _readOnly;
+		}
+
+		/// <returns>
+		/// The db4o
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">IConfiguration</see>
+		/// to be applied
+		/// during the defragment process.
+		/// </returns>
+		public virtual IConfiguration Db4oConfig()
+		{
+			if (_config == null)
+			{
+				_config = VanillaDb4oConfig(1);
+			}
+			return _config;
+		}
+
+		/// <param name="config">
+		/// The db4o
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">IConfiguration</see>
+		/// to be applied
+		/// during the defragment process.
+		/// </param>
+		[System.ObsoleteAttribute(@"since 7.9: use Db4oConfig(Db4objects.Db4o.Config.IEmbeddedConfiguration) instead"
+			)]
+		public virtual void Db4oConfig(IConfiguration config)
+		{
+			_config = config;
+		}
+
+		/// <param name="config">
+		/// The db4o
+		/// <see cref="Db4objects.Db4o.Config.IEmbeddedConfiguration">IEmbeddedConfiguration</see>
+		/// to be applied
+		/// during the defragment process.
+		/// </param>
+		/// <since>7.9</since>
+		public virtual void Db4oConfig(IEmbeddedConfiguration config)
+		{
+			_config = ((EmbeddedConfigurationImpl)config).Legacy();
+		}
+
+		public virtual int ObjectCommitFrequency()
+		{
+			return _objectCommitFrequency;
+		}
+
+		/// <param name="objectCommitFrequency">
+		/// The number of processed object (slots) that should trigger an
+		/// intermediate commit of the target file. Default: 0, meaning: never.
+		/// </param>
+		public virtual void ObjectCommitFrequency(int objectCommitFrequency)
+		{
+			_objectCommitFrequency = objectCommitFrequency;
+		}
+
+		/// <summary>
+		/// Instruct the defragment process to upgrade the source file to the current db4o
+		/// version prior to defragmenting it.
+		/// </summary>
+		/// <remarks>
+		/// Instruct the defragment process to upgrade the source file to the current db4o
+		/// version prior to defragmenting it. Use this option if your source file has been created
+		/// with an older db4o version than the one you are using.
+		/// </remarks>
+		/// <param name="tempPath">The location for an intermediate, upgraded version of the source file.
+		/// 	</param>
+		public virtual void UpgradeFile(string tempPath)
+		{
+			_tempPath = tempPath;
+		}
+
+		public virtual bool FileNeedsUpgrade()
+		{
+			return _tempPath != null;
+		}
+
+		public virtual string TempPath()
+		{
+			return (_tempPath != null ? _tempPath : _backupPath);
+		}
+
+		public virtual int BlockSize()
+		{
+			return ((Config4Impl)Db4oConfig()).BlockSize();
+		}
+
+		protected class NullFilter : IStoredClassFilter
+		{
+			public virtual bool Accept(IStoredClass storedClass)
+			{
+				return true;
+			}
+		}
+
+		private static readonly IStoredClassFilter Nullfilter = new DefragmentConfig.NullFilter
+			();
+
+		public static IConfiguration VanillaDb4oConfig(int blockSize)
+		{
+			IConfiguration config = Db4oFactory.NewConfiguration();
+			config.WeakReferences(false);
+			config.BlockSize(blockSize);
+			return config;
+		}
+
+		public virtual IConfiguration ClonedDb4oConfig()
+		{
+			return (IConfiguration)((Config4Impl)Db4oConfig()).DeepClone(null);
+		}
+
+		public virtual void BackupStorage(IStorage backupStorage)
+		{
+			_backupStorage = backupStorage;
+		}
+
+		public virtual IStorage BackupStorage()
+		{
+			if (_backupStorage != null)
+			{
+				return _backupStorage;
+			}
+			return _config.Storage;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/DefragmentInfo.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/DefragmentInfo.cs
new file mode 100644
index 0000000..2ce055e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/DefragmentInfo.cs
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Defragment
+{
+	/// <summary>A message from the defragmentation process.</summary>
+	/// <remarks>
+	/// A message from the defragmentation process. This is a stub only
+	/// and will be refined.
+	/// Currently instances of these class will only be created and sent
+	/// to registered listeners when invalid IDs are encountered during
+	/// the defragmentation process. These probably are harmless and the
+	/// result of a user-initiated delete operation.
+	/// </remarks>
+	/// <seealso cref="Defragment">Defragment</seealso>
+	public class DefragmentInfo
+	{
+		private string _msg;
+
+		public DefragmentInfo(string msg)
+		{
+			_msg = msg;
+		}
+
+		public override string ToString()
+		{
+			return _msg;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/DefragmentServicesImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/DefragmentServicesImpl.cs
new file mode 100644
index 0000000..c8d0394
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/DefragmentServicesImpl.cs
@@ -0,0 +1,560 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Defragment;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Classindex;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Mapping;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Defragment
+{
+	/// <exclude></exclude>
+	public class DefragmentServicesImpl : IDefragmentServices
+	{
+		public abstract class DbSelector
+		{
+			internal DbSelector()
+			{
+			}
+
+			internal abstract LocalObjectContainer Db(DefragmentServicesImpl context);
+
+			internal virtual Db4objects.Db4o.Internal.Transaction Transaction(DefragmentServicesImpl
+				 context)
+			{
+				return Db(context).SystemTransaction();
+			}
+		}
+
+		private sealed class _DbSelector_39 : DefragmentServicesImpl.DbSelector
+		{
+			public _DbSelector_39()
+			{
+			}
+
+			internal override LocalObjectContainer Db(DefragmentServicesImpl context)
+			{
+				return context._sourceDb;
+			}
+		}
+
+		public static readonly DefragmentServicesImpl.DbSelector Sourcedb = new _DbSelector_39
+			();
+
+		private sealed class _DbSelector_45 : DefragmentServicesImpl.DbSelector
+		{
+			public _DbSelector_45()
+			{
+			}
+
+			internal override LocalObjectContainer Db(DefragmentServicesImpl context)
+			{
+				return context._targetDb;
+			}
+		}
+
+		public static readonly DefragmentServicesImpl.DbSelector Targetdb = new _DbSelector_45
+			();
+
+		private readonly LocalObjectContainer _sourceDb;
+
+		private readonly LocalObjectContainer _targetDb;
+
+		private readonly IIdMapping _mapping;
+
+		private IDefragmentListener _listener;
+
+		private IQueue4 _unindexed = new NonblockingQueue();
+
+		private DefragmentConfig _defragConfig;
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public DefragmentServicesImpl(DefragmentConfig defragConfig, IDefragmentListener 
+			listener)
+		{
+			_listener = listener;
+			Config4Impl originalConfig = (Config4Impl)defragConfig.Db4oConfig();
+			IStorage storage = defragConfig.BackupStorage();
+			if (defragConfig.ReadOnly())
+			{
+				storage = new NonFlushingStorage(storage);
+			}
+			Config4Impl sourceConfig = PrepareConfig(originalConfig, storage, defragConfig.ReadOnly
+				());
+			_sourceDb = (LocalObjectContainer)Db4oFactory.OpenFile(sourceConfig, defragConfig
+				.TempPath()).Ext();
+			_sourceDb.ShowInternalClasses(true);
+			defragConfig.Db4oConfig().BlockSize(_sourceDb.BlockSize());
+			if (!originalConfig.GenerateCommitTimestamps().DefiniteNo())
+			{
+				defragConfig.Db4oConfig().GenerateCommitTimestamps(_sourceDb.Config().GenerateCommitTimestamps
+					().DefiniteYes());
+			}
+			_targetDb = FreshTargetFile(defragConfig);
+			_mapping = defragConfig.Mapping();
+			_mapping.Open();
+			_defragConfig = defragConfig;
+		}
+
+		private Config4Impl PrepareConfig(Config4Impl originalConfig, IStorage storage, bool
+			 readOnly)
+		{
+			Config4Impl sourceConfig = (Config4Impl)originalConfig.DeepClone(null);
+			sourceConfig.WeakReferences(false);
+			sourceConfig.Storage = storage;
+			sourceConfig.ReadOnly(readOnly);
+			return sourceConfig;
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		internal static LocalObjectContainer FreshTempFile(string fileName, int blockSize
+			)
+		{
+			FileStorage storage = new FileStorage();
+			storage.Delete(fileName);
+			IConfiguration db4oConfig = DefragmentConfig.VanillaDb4oConfig(blockSize);
+			db4oConfig.ObjectClass(typeof(IdSlotMapping)).ObjectField("_id").Indexed(true);
+			db4oConfig.Storage = storage;
+			return (LocalObjectContainer)Db4oFactory.OpenFile(db4oConfig, fileName).Ext();
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		internal static LocalObjectContainer FreshTargetFile(DefragmentConfig config)
+		{
+			config.Db4oConfig().Storage.Delete(config.OrigPath());
+			return (LocalObjectContainer)Db4oFactory.OpenFile(config.ClonedDb4oConfig(), config
+				.OrigPath());
+		}
+
+		public virtual int MappedID(int oldID, int defaultID)
+		{
+			int mapped = InternalMappedID(oldID);
+			return (mapped != 0 ? mapped : defaultID);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.Mapping.MappingNotFoundException"></exception>
+		public virtual int StrictMappedID(int oldID)
+		{
+			int mapped = InternalMappedID(oldID);
+			if (mapped == 0)
+			{
+				throw new MappingNotFoundException(oldID);
+			}
+			return mapped;
+		}
+
+		public virtual int MappedID(int id)
+		{
+			if (id == 0)
+			{
+				return 0;
+			}
+			int mapped = InternalMappedID(id);
+			if (mapped == 0)
+			{
+				_listener.NotifyDefragmentInfo(new DefragmentInfo("No mapping found for ID " + id
+					));
+				return Const4.InvalidObjectId;
+			}
+			return mapped;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.Mapping.MappingNotFoundException"></exception>
+		private int InternalMappedID(int oldID)
+		{
+			if (oldID == 0)
+			{
+				return 0;
+			}
+			int mappedId = _mapping.MappedId(oldID);
+			if (mappedId == 0 && _sourceDb.Handlers.IsSystemHandler(oldID))
+			{
+				return oldID;
+			}
+			return mappedId;
+		}
+
+		public virtual void MapIDs(int oldID, int newID, bool isClassID)
+		{
+			_mapping.MapId(oldID, newID, isClassID);
+		}
+
+		public virtual void Close()
+		{
+			_sourceDb.Close();
+			_targetDb.Close();
+			_mapping.Close();
+		}
+
+		public virtual ByteArrayBuffer BufferByID(DefragmentServicesImpl.DbSelector selector
+			, int id)
+		{
+			Slot slot = CommittedSlot(selector, id);
+			return BufferByAddress(selector, slot.Address(), slot.Length());
+		}
+
+		private Slot CommittedSlot(DefragmentServicesImpl.DbSelector selector, int id)
+		{
+			return selector.Db(this).IdSystem().CommittedSlot(id);
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual ByteArrayBuffer SourceBufferByAddress(int address, int length)
+		{
+			return BufferByAddress(Sourcedb, address, length);
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual ByteArrayBuffer TargetBufferByAddress(int address, int length)
+		{
+			return BufferByAddress(Targetdb, address, length);
+		}
+
+		public virtual ByteArrayBuffer BufferByAddress(DefragmentServicesImpl.DbSelector 
+			selector, int address, int length)
+		{
+			return selector.Db(this).DecryptedBufferByAddress(address, length);
+		}
+
+		/// <exception cref="System.ArgumentException"></exception>
+		public virtual StatefulBuffer TargetStatefulBufferByAddress(int address, int length
+			)
+		{
+			return _targetDb.ReadWriterByAddress(Targetdb.Transaction(this), address, length);
+		}
+
+		public virtual Slot AllocateTargetSlot(int length)
+		{
+			return _targetDb.AllocateSlot(length);
+		}
+
+		public virtual void TargetWriteBytes(DefragmentContextImpl context, int address)
+		{
+			context.Write(_targetDb, address);
+		}
+
+		public virtual void TargetWriteBytes(ByteArrayBuffer reader, int address)
+		{
+			_targetDb.WriteBytes(reader, address, 0);
+		}
+
+		public virtual IStoredClass[] StoredClasses(DefragmentServicesImpl.DbSelector selector
+			)
+		{
+			LocalObjectContainer db = selector.Db(this);
+			db.ShowInternalClasses(true);
+			try
+			{
+				return db.ClassCollection().StoredClasses();
+			}
+			finally
+			{
+				db.ShowInternalClasses(false);
+			}
+		}
+
+		public virtual LatinStringIO StringIO()
+		{
+			return _sourceDb.StringIO();
+		}
+
+		public virtual void TargetCommit()
+		{
+			_targetDb.Commit();
+		}
+
+		public virtual ITypeHandler4 SourceHandler(int id)
+		{
+			return _sourceDb.TypeHandlerForClassMetadataID(id);
+		}
+
+		public virtual int SourceClassCollectionID()
+		{
+			return _sourceDb.ClassCollection().GetID();
+		}
+
+		private Hashtable4 _classIndices = new Hashtable4(16);
+
+		public virtual int ClassIndexID(ClassMetadata classMetadata)
+		{
+			return ClassIndex(classMetadata).Id();
+		}
+
+		public virtual void TraverseAll(ClassMetadata classMetadata, IVisitor4 command)
+		{
+			if (!classMetadata.HasClassIndex())
+			{
+				return;
+			}
+			classMetadata.Index().TraverseAll(Sourcedb.Transaction(this), command);
+		}
+
+		public virtual void TraverseAllIndexSlots(ClassMetadata classMetadata, IVisitor4 
+			command)
+		{
+			IEnumerator slotIDIter = classMetadata.Index().AllSlotIDs(Sourcedb.Transaction(this
+				));
+			while (slotIDIter.MoveNext())
+			{
+				command.Visit(slotIDIter.Current);
+			}
+		}
+
+		public virtual void TraverseAllIndexSlots(BTree btree, IVisitor4 command)
+		{
+			IEnumerator slotIDIter = btree.AllNodeIds(Sourcedb.Transaction(this));
+			while (slotIDIter.MoveNext())
+			{
+				command.Visit(slotIDIter.Current);
+			}
+		}
+
+		public virtual void RegisterBTreeIDs(BTree btree, IDMappingCollector collector)
+		{
+			collector.CreateIDMapping(this, btree.GetID(), false);
+			TraverseAllIndexSlots(btree, new _IVisitor4_244(this, collector));
+		}
+
+		private sealed class _IVisitor4_244 : IVisitor4
+		{
+			public _IVisitor4_244(DefragmentServicesImpl _enclosing, IDMappingCollector collector
+				)
+			{
+				this._enclosing = _enclosing;
+				this.collector = collector;
+			}
+
+			public void Visit(object obj)
+			{
+				int id = ((int)obj);
+				collector.CreateIDMapping(this._enclosing, id, false);
+			}
+
+			private readonly DefragmentServicesImpl _enclosing;
+
+			private readonly IDMappingCollector collector;
+		}
+
+		public virtual int DatabaseIdentityID(DefragmentServicesImpl.DbSelector selector)
+		{
+			LocalObjectContainer db = selector.Db(this);
+			Db4oDatabase identity = db.Identity();
+			if (identity == null)
+			{
+				return 0;
+			}
+			return identity.GetID(selector.Transaction(this));
+		}
+
+		private IClassIndexStrategy ClassIndex(ClassMetadata classMetadata)
+		{
+			IClassIndexStrategy classIndex = (IClassIndexStrategy)_classIndices.Get(classMetadata
+				);
+			if (classIndex == null)
+			{
+				classIndex = new BTreeClassIndexStrategy(classMetadata);
+				_classIndices.Put(classMetadata, classIndex);
+				classIndex.Initialize(_targetDb);
+			}
+			return classIndex;
+		}
+
+		public virtual Db4objects.Db4o.Internal.Transaction SystemTrans()
+		{
+			return Sourcedb.Transaction(this);
+		}
+
+		public virtual void CopyIdentity()
+		{
+			_targetDb.SetIdentity(_sourceDb.Identity());
+		}
+
+		public virtual void ReplaceClassMetadataRepository()
+		{
+			Db4objects.Db4o.Internal.Transaction systemTransaction = _targetDb.SystemTransaction
+				();
+			// Can't use strictMappedID because the repository ID can
+			// be lower than HandlerRegisrtry _highestBuiltinTypeID and
+			// the ClassRepository ID would be treated as a system handler
+			// and the unmapped ID would be returned.
+			int newRepositoryId = _mapping.MappedId(SourceClassCollectionID());
+			int sourceIdentityID = DatabaseIdentityID(DefragmentServicesImpl.Sourcedb);
+			int targetIdentityID = _mapping.MappedId(sourceIdentityID);
+			int targetUuidIndexID = _mapping.MappedId(SourceUuidIndexID());
+			int oldIdentityId = _targetDb.SystemData().Identity().GetID(systemTransaction);
+			int oldRepositoryId = _targetDb.ClassCollection().GetID();
+			ClassMetadataRepository oldRepository = _targetDb.ClassCollection();
+			ClassMetadataRepository newRepository = new ClassMetadataRepository(systemTransaction
+				);
+			newRepository.SetID(newRepositoryId);
+			newRepository.Read(systemTransaction);
+			newRepository.InitOnUp(systemTransaction);
+			_targetDb.SystemData().ClassCollectionID(newRepositoryId);
+			_targetDb.ReplaceClassMetadataRepository(newRepository);
+			_targetDb.SystemData().UuidIndexId(targetUuidIndexID);
+			Db4oDatabase identity = (Db4oDatabase)_targetDb.GetByID(systemTransaction, targetIdentityID
+				);
+			_targetDb.SetIdentity(identity);
+			ClassMetadataIterator iterator = oldRepository.Iterator();
+			while (iterator.MoveNext())
+			{
+				ClassMetadata classMetadata = iterator.CurrentClass();
+				BTreeClassIndexStrategy index = (BTreeClassIndexStrategy)classMetadata.Index();
+				index.Btree().Free(_targetDb.LocalSystemTransaction());
+				FreeById(classMetadata.GetID());
+			}
+			FreeById(oldIdentityId);
+			FreeById(oldRepositoryId);
+		}
+
+		public virtual void DefragIdToTimestampBtree()
+		{
+			if (_sourceDb.SystemData().IdToTimestampIndexId() == 0)
+			{
+				return;
+			}
+			LocalTransaction targetTransaction = (LocalTransaction)_targetDb.SystemTransaction
+				();
+			LocalTransaction sourceTransaction = (LocalTransaction)_sourceDb.SystemTransaction
+				();
+			CommitTimestampSupport target = targetTransaction.CommitTimestampSupport();
+			CommitTimestampSupport source = sourceTransaction.CommitTimestampSupport();
+			if (source.IdToTimestamp() == null)
+			{
+				return;
+			}
+			source.IdToTimestamp().TraverseKeys(sourceTransaction, new _IVisitor4_336(this, target
+				, targetTransaction));
+		}
+
+		private sealed class _IVisitor4_336 : IVisitor4
+		{
+			public _IVisitor4_336(DefragmentServicesImpl _enclosing, CommitTimestampSupport target
+				, LocalTransaction targetTransaction)
+			{
+				this._enclosing = _enclosing;
+				this.target = target;
+				this.targetTransaction = targetTransaction;
+			}
+
+			public void Visit(object te)
+			{
+				int mappedID = this._enclosing.MappedID(((CommitTimestampSupport.TimestampEntry)te
+					).ParentID());
+				target.Put(targetTransaction, mappedID, ((CommitTimestampSupport.TimestampEntry)te
+					).GetCommitTimestamp());
+			}
+
+			private readonly DefragmentServicesImpl _enclosing;
+
+			private readonly CommitTimestampSupport target;
+
+			private readonly LocalTransaction targetTransaction;
+		}
+
+		private void FreeById(int id)
+		{
+			_targetDb.SystemTransaction().IdSystem().NotifySlotDeleted(id, SlotChangeFactory.
+				SystemObjects);
+		}
+
+		public virtual ByteArrayBuffer SourceBufferByID(int sourceID)
+		{
+			return BufferByID(Sourcedb, sourceID);
+		}
+
+		public virtual BTree SourceUuidIndex()
+		{
+			if (SourceUuidIndexID() == 0)
+			{
+				return null;
+			}
+			return _sourceDb.UUIDIndex().GetIndex(SystemTrans());
+		}
+
+		public virtual void TargetUuidIndexID(int id)
+		{
+			_targetDb.SystemData().UuidIndexId(id);
+		}
+
+		public virtual int SourceUuidIndexID()
+		{
+			return _sourceDb.SystemData().UuidIndexId();
+		}
+
+		public virtual int SourceIdToTimestampIndexID()
+		{
+			return _sourceDb.SystemData().IdToTimestampIndexId();
+		}
+
+		public virtual ClassMetadata ClassMetadataForId(int id)
+		{
+			return _sourceDb.ClassMetadataForID(id);
+		}
+
+		public virtual void RegisterUnindexed(int id)
+		{
+			_unindexed.Add(id);
+		}
+
+		public virtual IdSource UnindexedIDs()
+		{
+			return new IdSource(_unindexed);
+		}
+
+		public virtual ObjectHeader SourceObjectHeader(ByteArrayBuffer buffer)
+		{
+			return new ObjectHeader(_sourceDb, buffer);
+		}
+
+		public virtual int BlockSize()
+		{
+			return _sourceDb.BlockSize();
+		}
+
+		public virtual int SourceAddressByID(int sourceID)
+		{
+			return CommittedSlot(Sourcedb, sourceID).Address();
+		}
+
+		public virtual int TargetAddressByID(int sourceID)
+		{
+			return _mapping.AddressForId(sourceID);
+		}
+
+		public virtual bool Accept(IStoredClass klass)
+		{
+			return this._defragConfig.StoredClassFilter().Accept(klass);
+		}
+
+		public virtual int TargetNewId()
+		{
+			return _targetDb.IdSystem().NewId();
+		}
+
+		public virtual IIdMapping Mapping()
+		{
+			return _mapping;
+		}
+
+		public virtual void CommitIds()
+		{
+			FreespaceCommitter freespaceCommitter = new FreespaceCommitter(_targetDb.FreespaceManager
+				());
+			freespaceCommitter.TransactionalIdSystem(SystemTrans().IdSystem());
+			_targetDb.IdSystem().Commit(Mapping().SlotChanges(), freespaceCommitter);
+			freespaceCommitter.Commit();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/FirstPassCommand.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/FirstPassCommand.cs
new file mode 100644
index 0000000..8c72d6e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/FirstPassCommand.cs
@@ -0,0 +1,76 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Defragment;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Metadata;
+
+namespace Db4objects.Db4o.Defragment
+{
+	/// <summary>
+	/// First step in the defragmenting process: Allocates pointer slots in the target file for
+	/// each ID (but doesn't fill them in, yet) and registers the mapping from source pointer address
+	/// to target pointer address.
+	/// </summary>
+	/// <remarks>
+	/// First step in the defragmenting process: Allocates pointer slots in the target file for
+	/// each ID (but doesn't fill them in, yet) and registers the mapping from source pointer address
+	/// to target pointer address.
+	/// </remarks>
+	/// <exclude></exclude>
+	public sealed class FirstPassCommand : IPassCommand
+	{
+		private IDMappingCollector _collector = new IDMappingCollector();
+
+		public void ProcessClass(DefragmentServicesImpl context, ClassMetadata classMetadata
+			, int id, int classIndexID)
+		{
+			_collector.CreateIDMapping(context, id, true);
+			classMetadata.TraverseAllAspects(new _TraverseFieldCommand_24(this, context));
+		}
+
+		private sealed class _TraverseFieldCommand_24 : TraverseFieldCommand
+		{
+			public _TraverseFieldCommand_24(FirstPassCommand _enclosing, DefragmentServicesImpl
+				 context)
+			{
+				this._enclosing = _enclosing;
+				this.context = context;
+			}
+
+			protected override void Process(FieldMetadata field)
+			{
+				if (!field.IsVirtual() && field.HasIndex())
+				{
+					this._enclosing.ProcessBTree(context, field.GetIndex(context.SystemTrans()));
+				}
+			}
+
+			private readonly FirstPassCommand _enclosing;
+
+			private readonly DefragmentServicesImpl context;
+		}
+
+		public void ProcessObjectSlot(DefragmentServicesImpl context, ClassMetadata classMetadata
+			, int sourceID)
+		{
+			_collector.CreateIDMapping(context, sourceID, false);
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		public void ProcessClassCollection(DefragmentServicesImpl context)
+		{
+			_collector.CreateIDMapping(context, context.SourceClassCollectionID(), false);
+		}
+
+		public void ProcessBTree(DefragmentServicesImpl context, BTree btree)
+		{
+			context.RegisterBTreeIDs(btree, _collector);
+		}
+
+		public void Flush(DefragmentServicesImpl context)
+		{
+			_collector.Flush(context);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/IDMappingCollector.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/IDMappingCollector.cs
new file mode 100644
index 0000000..2ca012b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/IDMappingCollector.cs
@@ -0,0 +1,54 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Defragment;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Defragment
+{
+	public class IDMappingCollector
+	{
+		private const int IdBatchSize = 4096;
+
+		private TreeInt _ids;
+
+		internal virtual void CreateIDMapping(DefragmentServicesImpl context, int objectID
+			, bool isClassID)
+		{
+			if (BatchFull())
+			{
+				Flush(context);
+			}
+			_ids = TreeInt.Add(_ids, (isClassID ? -objectID : objectID));
+		}
+
+		private bool BatchFull()
+		{
+			return _ids != null && _ids.Size() == IdBatchSize;
+		}
+
+		public virtual void Flush(DefragmentServicesImpl context)
+		{
+			if (_ids == null)
+			{
+				return;
+			}
+			IEnumerator idIter = new TreeKeyIterator(_ids);
+			while (idIter.MoveNext())
+			{
+				int objectID = ((int)idIter.Current);
+				bool isClassID = false;
+				if (objectID < 0)
+				{
+					objectID = -objectID;
+					isClassID = true;
+				}
+				// seen object ids don't come by here anymore - any other candidates?
+				context.MapIDs(objectID, context.TargetNewId(), isClassID);
+			}
+			context.Mapping().Commit();
+			_ids = null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/IDefragmentListener.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/IDefragmentListener.cs
new file mode 100644
index 0000000..6729219
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/IDefragmentListener.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Defragment;
+
+namespace Db4objects.Db4o.Defragment
+{
+	/// <summary>Listener for defragmentation process messages.</summary>
+	/// <remarks>Listener for defragmentation process messages.</remarks>
+	/// <seealso cref="Defragment">Defragment</seealso>
+	public interface IDefragmentListener
+	{
+		/// <summary>
+		/// This method will be called when the defragment process encounters
+		/// file layout anomalies during the defragmentation process.
+		/// </summary>
+		/// <remarks>
+		/// This method will be called when the defragment process encounters
+		/// file layout anomalies during the defragmentation process.
+		/// </remarks>
+		/// <param name="info">The message from the defragmentation process.</param>
+		void NotifyDefragmentInfo(DefragmentInfo info);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/IDefragmentServices.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/IDefragmentServices.cs
new file mode 100644
index 0000000..dd350cb
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/IDefragmentServices.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Defragment;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Mapping;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Defragment
+{
+	/// <summary>Encapsulates services involving source and target database files during defragmenting.
+	/// 	</summary>
+	/// <remarks>Encapsulates services involving source and target database files during defragmenting.
+	/// 	</remarks>
+	/// <exclude></exclude>
+	public interface IDefragmentServices : IIDMapping
+	{
+		/// <exception cref="System.IO.IOException"></exception>
+		ByteArrayBuffer SourceBufferByAddress(int address, int length);
+
+		/// <exception cref="System.IO.IOException"></exception>
+		ByteArrayBuffer TargetBufferByAddress(int address, int length);
+
+		ByteArrayBuffer SourceBufferByID(int sourceID);
+
+		Slot AllocateTargetSlot(int targetLength);
+
+		void TargetWriteBytes(ByteArrayBuffer targetPointerReader, int targetAddress);
+
+		Transaction SystemTrans();
+
+		void TargetWriteBytes(DefragmentContextImpl context, int targetAddress);
+
+		void TraverseAllIndexSlots(BTree tree, IVisitor4 visitor4);
+
+		void RegisterBTreeIDs(BTree tree, IDMappingCollector collector);
+
+		ClassMetadata ClassMetadataForId(int id);
+
+		int MappedID(int id);
+
+		void RegisterUnindexed(int id);
+
+		IdSource UnindexedIDs();
+
+		int SourceAddressByID(int sourceID);
+
+		int TargetAddressByID(int sourceID);
+
+		int TargetNewId();
+
+		IIdMapping Mapping();
+
+		void CommitIds();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/IIdMapping.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/IIdMapping.cs
new file mode 100644
index 0000000..e84a14e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/IIdMapping.cs
@@ -0,0 +1,53 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Defragment
+{
+	/// <summary>The ID mapping used internally during a defragmentation run.</summary>
+	/// <remarks>The ID mapping used internally during a defragmentation run.</remarks>
+	/// <seealso cref="Defragment">Defragment</seealso>
+	public interface IIdMapping
+	{
+		/// <summary>Returns a previously registered mapping ID for the given ID if it exists.
+		/// 	</summary>
+		/// <remarks>Returns a previously registered mapping ID for the given ID if it exists.
+		/// 	</remarks>
+		/// <param name="origID">The original ID</param>
+		/// <returns>The mapping ID for the given original ID or 0, if none has been registered.
+		/// 	</returns>
+		int MappedId(int origId);
+
+		/// <summary>Registers a mapping for the given IDs.</summary>
+		/// <remarks>Registers a mapping for the given IDs.</remarks>
+		/// <param name="origID">The original ID</param>
+		/// <param name="mappedID">The ID to be mapped to the original ID.</param>
+		/// <param name="isClassID">true if the given original ID specifies a class slot, false otherwise.
+		/// 	</param>
+		void MapId(int origId, int mappedId, bool isClassId);
+
+		/// <summary>Maps an ID to a slot</summary>
+		/// <param name="id"></param>
+		/// <param name="slot"></param>
+		void MapId(int id, Slot slot);
+
+		/// <summary>provides a Visitable of all mappings of IDs to slots.</summary>
+		/// <remarks>provides a Visitable of all mappings of IDs to slots.</remarks>
+		IVisitable SlotChanges();
+
+		/// <summary>Prepares the mapping for use.</summary>
+		/// <remarks>Prepares the mapping for use.</remarks>
+		/// <exception cref="System.IO.IOException"></exception>
+		void Open();
+
+		/// <summary>Shuts down the mapping after use.</summary>
+		/// <remarks>Shuts down the mapping after use.</remarks>
+		void Close();
+
+		/// <summary>returns the slot address for an ID</summary>
+		int AddressForId(int id);
+
+		void Commit();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/IStoredClassFilter.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/IStoredClassFilter.cs
new file mode 100644
index 0000000..2870f15
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/IStoredClassFilter.cs
@@ -0,0 +1,16 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Defragment
+{
+	/// <summary>Filter for StoredClass instances.</summary>
+	/// <remarks>Filter for StoredClass instances.</remarks>
+	public interface IStoredClassFilter
+	{
+		/// <param name="storedClass">StoredClass instance to be checked</param>
+		/// <returns>true, if the given StoredClass instance should be accepted, false otherwise.
+		/// 	</returns>
+		bool Accept(IStoredClass storedClass);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/InMemoryIdMapping.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/InMemoryIdMapping.cs
new file mode 100644
index 0000000..5560476
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/InMemoryIdMapping.cs
@@ -0,0 +1,115 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Defragment;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Defragment
+{
+	/// <summary>In-memory mapping for IDs during a defragmentation run.</summary>
+	/// <remarks>
+	/// In-memory mapping for IDs during a defragmentation run.
+	/// This is faster than the
+	/// <see cref="DatabaseIdMapping">DatabaseIdMapping</see>
+	/// but
+	/// it uses more memory. If you have OutOfMemory conditions
+	/// with this id mapping, use the
+	/// <see cref="DatabaseIdMapping">DatabaseIdMapping</see>
+	/// instead.
+	/// </remarks>
+	/// <seealso cref="Defragment">Defragment</seealso>
+	public class InMemoryIdMapping : AbstractIdMapping
+	{
+		private IdSlotTree _idsToSlots;
+
+		private Tree _tree;
+
+		public override int MappedId(int oldID)
+		{
+			int classID = MappedClassID(oldID);
+			if (classID != 0)
+			{
+				return classID;
+			}
+			TreeIntObject res = (TreeIntObject)TreeInt.Find(_tree, oldID);
+			if (res != null)
+			{
+				return ((int)res._object);
+			}
+			return 0;
+		}
+
+		public override void Open()
+		{
+		}
+
+		public override void Close()
+		{
+		}
+
+		protected override void MapNonClassIDs(int origID, int mappedID)
+		{
+			_tree = Tree.Add(_tree, new TreeIntObject(origID, mappedID));
+		}
+
+		public override int AddressForId(int id)
+		{
+			IdSlotTree node = (IdSlotTree)_idsToSlots.Find(id);
+			if (node == null)
+			{
+				throw new InvalidOperationException();
+			}
+			return node.Slot().Address();
+		}
+
+		public override void MapId(int id, Slot slot)
+		{
+			IdSlotTree idSlotMapping = new IdSlotTree(id, slot);
+			_idsToSlots = ((IdSlotTree)Tree.Add(_idsToSlots, idSlotMapping));
+		}
+
+		public override IVisitable SlotChanges()
+		{
+			return new _IVisitable_62(this);
+		}
+
+		private sealed class _IVisitable_62 : IVisitable
+		{
+			public _IVisitable_62(InMemoryIdMapping _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Accept(IVisitor4 outSideVisitor)
+			{
+				Tree.Traverse(this._enclosing._idsToSlots, new _IVisitor4_64(outSideVisitor));
+			}
+
+			private sealed class _IVisitor4_64 : IVisitor4
+			{
+				public _IVisitor4_64(IVisitor4 outSideVisitor)
+				{
+					this.outSideVisitor = outSideVisitor;
+				}
+
+				public void Visit(object idSlotMapping)
+				{
+					SlotChange slotChange = new SlotChange(((TreeInt)idSlotMapping)._key);
+					slotChange.NotifySlotCreated(((IdSlotTree)idSlotMapping).Slot());
+					outSideVisitor.Visit(slotChange);
+				}
+
+				private readonly IVisitor4 outSideVisitor;
+			}
+
+			private readonly InMemoryIdMapping _enclosing;
+		}
+
+		public override void Commit()
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/PassCommand.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/PassCommand.cs
new file mode 100644
index 0000000..2a39199
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/PassCommand.cs
@@ -0,0 +1,34 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Defragment;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Defragment
+{
+	/// <summary>Implements one step in the defragmenting process.</summary>
+	/// <remarks>Implements one step in the defragmenting process.</remarks>
+	/// <exclude></exclude>
+	internal interface IPassCommand
+	{
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="System.IO.IOException"></exception>
+		void ProcessObjectSlot(DefragmentServicesImpl context, ClassMetadata classMetadata
+			, int id);
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="System.IO.IOException"></exception>
+		void ProcessClass(DefragmentServicesImpl context, ClassMetadata classMetadata, int
+			 id, int classIndexID);
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="System.IO.IOException"></exception>
+		void ProcessClassCollection(DefragmentServicesImpl context);
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="System.IO.IOException"></exception>
+		void ProcessBTree(DefragmentServicesImpl context, BTree btree);
+
+		void Flush(DefragmentServicesImpl context);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/SecondPassCommand.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/SecondPassCommand.cs
new file mode 100644
index 0000000..c1e9f98
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Defragment/SecondPassCommand.cs
@@ -0,0 +1,169 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Defragment;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Defragment
+{
+	/// <summary>
+	/// Second step in the defragmenting process: Fills in target file pointer slots, copies
+	/// content slots from source to target and triggers ID remapping therein by calling the
+	/// appropriate db4o/marshaller defrag() implementations.
+	/// </summary>
+	/// <remarks>
+	/// Second step in the defragmenting process: Fills in target file pointer slots, copies
+	/// content slots from source to target and triggers ID remapping therein by calling the
+	/// appropriate db4o/marshaller defrag() implementations. During the process, the actual address
+	/// mappings for the content slots are registered for use with string indices.
+	/// </remarks>
+	/// <exclude></exclude>
+	internal sealed class SecondPassCommand : IPassCommand
+	{
+		protected readonly int _objectCommitFrequency;
+
+		protected int _objectCount = 0;
+
+		public SecondPassCommand(int objectCommitFrequency)
+		{
+			_objectCommitFrequency = objectCommitFrequency;
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="System.IO.IOException"></exception>
+		public void ProcessClass(DefragmentServicesImpl services, ClassMetadata classMetadata
+			, int id, int classIndexID)
+		{
+			if (services.MappedID(id, -1) == -1)
+			{
+				Sharpen.Runtime.Err.WriteLine("MAPPING NOT FOUND: " + id);
+			}
+			DefragmentContextImpl.ProcessCopy(services, id, new _ISlotCopyHandler_34(classMetadata
+				, classIndexID));
+		}
+
+		private sealed class _ISlotCopyHandler_34 : ISlotCopyHandler
+		{
+			public _ISlotCopyHandler_34(ClassMetadata classMetadata, int classIndexID)
+			{
+				this.classMetadata = classMetadata;
+				this.classIndexID = classIndexID;
+			}
+
+			public void ProcessCopy(DefragmentContextImpl context)
+			{
+				classMetadata.DefragClass(context, classIndexID);
+			}
+
+			private readonly ClassMetadata classMetadata;
+
+			private readonly int classIndexID;
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="System.IO.IOException"></exception>
+		public void ProcessObjectSlot(DefragmentServicesImpl services, ClassMetadata classMetadata
+			, int id)
+		{
+			ByteArrayBuffer sourceBuffer = services.SourceBufferByID(id);
+			DefragmentContextImpl.ProcessCopy(services, id, new _ISlotCopyHandler_43(this, services
+				), sourceBuffer);
+		}
+
+		private sealed class _ISlotCopyHandler_43 : ISlotCopyHandler
+		{
+			public _ISlotCopyHandler_43(SecondPassCommand _enclosing, DefragmentServicesImpl 
+				services)
+			{
+				this._enclosing = _enclosing;
+				this.services = services;
+			}
+
+			public void ProcessCopy(DefragmentContextImpl context)
+			{
+				ClassMetadata.DefragObject(context);
+				if (this._enclosing._objectCommitFrequency > 0)
+				{
+					this._enclosing._objectCount++;
+					if (this._enclosing._objectCount == this._enclosing._objectCommitFrequency)
+					{
+						services.TargetCommit();
+						services.Mapping().Commit();
+						this._enclosing._objectCount = 0;
+					}
+				}
+			}
+
+			private readonly SecondPassCommand _enclosing;
+
+			private readonly DefragmentServicesImpl services;
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="System.IO.IOException"></exception>
+		public void ProcessClassCollection(DefragmentServicesImpl services)
+		{
+			DefragmentContextImpl.ProcessCopy(services, services.SourceClassCollectionID(), new 
+				_ISlotCopyHandler_59(services));
+		}
+
+		private sealed class _ISlotCopyHandler_59 : ISlotCopyHandler
+		{
+			public _ISlotCopyHandler_59(DefragmentServicesImpl services)
+			{
+				this.services = services;
+			}
+
+			public void ProcessCopy(DefragmentContextImpl context)
+			{
+				int acceptedClasses = 0;
+				int numClassesOffset = context.TargetBuffer().Offset();
+				acceptedClasses = this.CopyAcceptedClasses(context, acceptedClasses);
+				this.WriteIntAt(context.TargetBuffer(), numClassesOffset, acceptedClasses);
+			}
+
+			private int CopyAcceptedClasses(DefragmentContextImpl context, int acceptedClasses
+				)
+			{
+				int numClasses = context.ReadInt();
+				for (int classIdx = 0; classIdx < numClasses; classIdx++)
+				{
+					int classId = context.SourceBuffer().ReadInt();
+					if (!this.Accept(classId))
+					{
+						continue;
+					}
+					++acceptedClasses;
+					context.WriteMappedID(classId);
+				}
+				return acceptedClasses;
+			}
+
+			private void WriteIntAt(ByteArrayBuffer target, int offset, int value)
+			{
+				int currentOffset = target.Offset();
+				target.Seek(offset);
+				target.WriteInt(value);
+				target.Seek(currentOffset);
+			}
+
+			private bool Accept(int classId)
+			{
+				return services.Accept(services.ClassMetadataForId(classId));
+			}
+
+			private readonly DefragmentServicesImpl services;
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="System.IO.IOException"></exception>
+		public void ProcessBTree(DefragmentServicesImpl context, BTree btree)
+		{
+			btree.DefragBTree(context);
+		}
+
+		public void Flush(DefragmentServicesImpl context)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Deploy.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Deploy.cs
new file mode 100644
index 0000000..cb2c5d4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Deploy.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o
+{
+	/// <exclude></exclude>
+	public sealed class Deploy
+	{
+		/// <summary>turning debug on makes the file format human readable</summary>
+		public const bool debug = false;
+
+		public const bool overwrite = true;
+
+		public const bool brackets = true;
+
+		public const bool identifiers = true;
+
+		public const bool flush = true;
+
+		public const bool debugLong = true;
+
+		public const bool csharp = true;
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/ClassHasNoFields.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/ClassHasNoFields.cs
new file mode 100644
index 0000000..21a49d2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/ClassHasNoFields.cs
@@ -0,0 +1,34 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Diagnostic;
+
+namespace Db4objects.Db4o.Diagnostic
+{
+	/// <summary>Diagnostic, if class has no fields.</summary>
+	/// <remarks>Diagnostic, if class has no fields.</remarks>
+	public class ClassHasNoFields : DiagnosticBase
+	{
+		private readonly string _className;
+
+		public ClassHasNoFields(string className)
+		{
+			_className = className;
+		}
+
+		public override object Reason()
+		{
+			return _className;
+		}
+
+		public override string Problem()
+		{
+			return "Class does not contain any persistent fields";
+		}
+
+		public override string Solution()
+		{
+			return "Every class in the hierarchy requires overhead for the maintenance of a class index."
+				 + " Consider removing this class from the hierarchy, if it is not needed.";
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/DefragmentRecommendation.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/DefragmentRecommendation.cs
new file mode 100644
index 0000000..47c6f4a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/DefragmentRecommendation.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Diagnostic;
+
+namespace Db4objects.Db4o.Diagnostic
+{
+	/// <summary>Diagnostic to recommend Defragment when needed.</summary>
+	/// <remarks>Diagnostic to recommend Defragment when needed.</remarks>
+	public class DefragmentRecommendation : DiagnosticBase
+	{
+		private readonly DefragmentRecommendation.DefragmentRecommendationReason _reason;
+
+		public DefragmentRecommendation(DefragmentRecommendation.DefragmentRecommendationReason
+			 reason)
+		{
+			_reason = reason;
+		}
+
+		public class DefragmentRecommendationReason
+		{
+			internal readonly string _message;
+
+			public DefragmentRecommendationReason(string reason)
+			{
+				_message = reason;
+			}
+
+			public static readonly DefragmentRecommendation.DefragmentRecommendationReason DeleteEmbeded
+				 = new DefragmentRecommendation.DefragmentRecommendationReason("Delete Embedded not supported on old file format."
+				);
+		}
+
+		public override string Problem()
+		{
+			return "Database file format is old or database is highly fragmented.";
+		}
+
+		public override object Reason()
+		{
+			return _reason._message;
+		}
+
+		public override string Solution()
+		{
+			return "Defragment the database.";
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/DeletionFailed.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/DeletionFailed.cs
new file mode 100644
index 0000000..b613f3f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/DeletionFailed.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Diagnostic;
+
+namespace Db4objects.Db4o.Diagnostic
+{
+	/// <summary>Diagnostic on failed delete.</summary>
+	/// <remarks>Diagnostic on failed delete.</remarks>
+	public class DeletionFailed : DiagnosticBase
+	{
+		public override string Problem()
+		{
+			return "Cascading delete to members failed. Possible reasons: db4o engine updates, corruption, changed class hierarchies.";
+		}
+
+		public override object Reason()
+		{
+			return string.Empty;
+		}
+
+		public override string Solution()
+		{
+			return "Running Defragment may fix.";
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/DescendIntoTranslator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/DescendIntoTranslator.cs
new file mode 100644
index 0000000..f881a67
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/DescendIntoTranslator.cs
@@ -0,0 +1,42 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Diagnostic;
+
+namespace Db4objects.Db4o.Diagnostic
+{
+	/// <summary>
+	/// Query tries to descend into a field of a class that is configured to be translated
+	/// (and thus cannot be descended into).
+	/// </summary>
+	/// <remarks>
+	/// Query tries to descend into a field of a class that is configured to be translated
+	/// (and thus cannot be descended into).
+	/// </remarks>
+	public class DescendIntoTranslator : DiagnosticBase
+	{
+		private string className;
+
+		private string fieldName;
+
+		public DescendIntoTranslator(string className_, string fieldName_)
+		{
+			className = className_;
+			fieldName = fieldName_;
+		}
+
+		public override string Problem()
+		{
+			return "Query descends into field(s) of translated class.";
+		}
+
+		public override object Reason()
+		{
+			return className + "." + fieldName;
+		}
+
+		public override string Solution()
+		{
+			return "Consider dropping the translator configuration or resort to evaluations/unoptimized NQs.";
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/DiagnosticBase.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/DiagnosticBase.cs
new file mode 100644
index 0000000..e73a37a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/DiagnosticBase.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Diagnostic;
+
+namespace Db4objects.Db4o.Diagnostic
+{
+	/// <summary>base class for Diagnostic messages</summary>
+	public abstract class DiagnosticBase : IDiagnostic
+	{
+		/// <summary>returns the reason for the message</summary>
+		public abstract object Reason();
+
+		/// <summary>returns the potential problem that triggered the message</summary>
+		public abstract string Problem();
+
+		/// <summary>suggests a possible solution for the possible problem</summary>
+		public abstract string Solution();
+
+		public override string ToString()
+		{
+			return ":: db4o " + Db4oVersion.Name + " Diagnostics ::\n  " + Reason() + " :: " 
+				+ Problem() + "\n    " + Solution();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/DiagnosticToConsole.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/DiagnosticToConsole.cs
new file mode 100644
index 0000000..f38f49d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/DiagnosticToConsole.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Diagnostic;
+
+namespace Db4objects.Db4o.Diagnostic
+{
+	/// <summary>prints Diagnostic messsages to the Console.</summary>
+	/// <remarks>
+	/// prints Diagnostic messages to the Console.
+	/// Install this
+	/// <see cref="Db4objects.Db4o.Diagnostic.IDiagnosticListener">Db4objects.Db4o.Diagnostic.IDiagnosticListener
+	/// </see>
+	/// with: <br/>
+	/// <code>commonConfig.Diagnostic.AddListener(new DiagnosticToConsole());</code><br/>
+	/// </remarks>
+	/// <seealso cref="Db4objects.Db4o.Diagnostic.IDiagnosticConfiguration">Db4objects.Db4o.Diagnostic.IDiagnosticConfiguration
+	/// </seealso>
+	public class DiagnosticToConsole : IDiagnosticListener
+	{
+		/// <summary>redirects Diagnostic messages to the Console.</summary>
+		/// <remarks>redirects Diagnostic messages to the Console.</remarks>
+		public virtual void OnDiagnostic(IDiagnostic d)
+		{
+			Sharpen.Runtime.Out.WriteLine(d.ToString());
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/IDiagnostic.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/IDiagnostic.cs
new file mode 100644
index 0000000..9d60fd7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/IDiagnostic.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Diagnostic
+{
+	/// <summary>
+	/// Marker interface for Diagnostic messages<br /><br />
+	/// Diagnostic system can be enabled on a running db4o database
+	/// to notify a user about possible problems or misconfigurations.
+	/// </summary>
+	/// <remarks>
+	/// Marker interface for Diagnostic messages<br /><br />
+	/// Diagnostic system can be enabled on a running db4o database
+	/// to notify a user about possible problems or misconfigurations. Diagnostic
+	/// messages must implement this interface and are usually derived from
+	/// <see cref="DiagnosticBase">DiagnosticBase</see>
+	/// class. A separate Diagnostic implementation
+	/// should be used for each problem.
+	/// </remarks>
+	/// <seealso cref="DiagnosticBase">DiagnosticBase</seealso>
+	/// <seealso cref="IDiagnosticConfiguration">IDiagnosticConfiguration</seealso>
+	public interface IDiagnostic
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/IDiagnosticConfiguration.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/IDiagnosticConfiguration.cs
new file mode 100644
index 0000000..198f25f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/IDiagnosticConfiguration.cs
@@ -0,0 +1,35 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Diagnostic;
+
+namespace Db4objects.Db4o.Diagnostic
+{
+	/// <summary>provides methods to configure the behaviour of db4o
+	/// diagnostics.</summary>
+	/// <remarks>
+	/// provides methods to configure the behaviour of db4o diagnostics.
+	/// <br/>
+	/// <br/>
+	/// Diagnostic system can be enabled on a running db4o database to
+	/// notify a user about possible problems or misconfigurations.
+	/// Diagnostic listeners can be be added and removed with calls to this
+	/// interface. To install the most basic listener call:
+	/// <br/>
+	/// <code>commonConfig.Diagnostic.AddListener(new
+	/// DiagnosticToConsole());</code>
+	/// </remarks>
+	/// <seealso cref="IConfiguration.Diagnostic">IConfiguration.Diagnostic
+	/// </seealso>
+	/// <seealso cref="IDiagnosticListener">IDiagnosticListener
+	/// </seealso>
+	public interface IDiagnosticConfiguration
+	{
+		/// <summary>adds a DiagnosticListener to listen to Diagnostic messages.</summary>
+		/// <remarks>adds a DiagnosticListener to listen to Diagnostic messages.</remarks>
+		void AddListener(IDiagnosticListener listener);
+
+		/// <summary>removes all DiagnosticListeners.</summary>
+		/// <remarks>removes all DiagnosticListeners.</remarks>
+		void RemoveAllListeners();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/IDiagnosticListener.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/IDiagnosticListener.cs
new file mode 100644
index 0000000..b76a2e9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/IDiagnosticListener.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Diagnostic;
+
+namespace Db4objects.Db4o.Diagnostic
+{
+	/// <summary>listens to Diagnostic messages.</summary>
+	/// <remarks>
+	/// listens to Diagnostic messages.
+	/// <br/><br/>Create a class that implements this listener interface and add
+	/// the listener by calling <code>commonConfig.Diagnostic.AddListener()</code>.
+	/// </remarks>
+	/// <seealso cref="Db4objects.Db4o.Diagnostic.IDiagnosticConfiguration">Db4objects.Db4o.Diagnostic.IDiagnosticConfiguration
+	/// </seealso>
+	public interface IDiagnosticListener
+	{
+		/// <summary>this method will be called with Diagnostic messages.</summary>
+		/// <remarks>this method will be called with Diagnostic messages.</remarks>
+		void OnDiagnostic(IDiagnostic d);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/LoadedFromClassIndex.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/LoadedFromClassIndex.cs
new file mode 100644
index 0000000..2f9102d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/LoadedFromClassIndex.cs
@@ -0,0 +1,35 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Diagnostic;
+
+namespace Db4objects.Db4o.Diagnostic
+{
+	/// <summary>Diagnostic, if query was required to load candidate set from class index.
+	/// 	</summary>
+	/// <remarks>Diagnostic, if query was required to load candidate set from class index.
+	/// 	</remarks>
+	public class LoadedFromClassIndex : DiagnosticBase
+	{
+		private readonly string _className;
+
+		public LoadedFromClassIndex(string className)
+		{
+			_className = className;
+		}
+
+		public override object Reason()
+		{
+			return _className;
+		}
+
+		public override string Problem()
+		{
+			return "Query candidate set could not be loaded from a field index";
+		}
+
+		public override string Solution()
+		{
+			return "Consider indexing fields that you query for: " + "Db4o.configure().objectClass([class]).objectField([fieldName]).indexed(true)";
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/MissingClass.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/MissingClass.cs
new file mode 100644
index 0000000..0e2db39
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/MissingClass.cs
@@ -0,0 +1,32 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Diagnostic;
+
+namespace Db4objects.Db4o.Diagnostic
+{
+	/// <summary>Diagnostic if class not found</summary>
+	public class MissingClass : DiagnosticBase
+	{
+		public readonly string _className;
+
+		public MissingClass(string className)
+		{
+			_className = className;
+		}
+
+		public override string Problem()
+		{
+			return "Class not found in classpath.";
+		}
+
+		public override object Reason()
+		{
+			return _className;
+		}
+
+		public override string Solution()
+		{
+			return "Check your classpath.";
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/NativeQueryNotOptimized.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/NativeQueryNotOptimized.cs
new file mode 100644
index 0000000..4d50dd2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/NativeQueryNotOptimized.cs
@@ -0,0 +1,46 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Diagnostic;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Diagnostic
+{
+	/// <summary>Diagnostic, if Native Query can not be run optimized.</summary>
+	/// <remarks>Diagnostic, if Native Query can not be run optimized.</remarks>
+	public class NativeQueryNotOptimized : DiagnosticBase
+	{
+		private readonly Predicate _predicate;
+
+		private readonly Exception _details;
+
+		public NativeQueryNotOptimized(Predicate predicate, Exception details)
+		{
+			_predicate = predicate;
+			_details = details;
+		}
+
+		public override object Reason()
+		{
+			if (_details == null)
+			{
+				return _predicate;
+			}
+			return _predicate != null ? _predicate.ToString() : string.Empty + "\n" + _details
+				.Message;
+		}
+
+		public override string Problem()
+		{
+			return "Native Query Predicate could not be run optimized";
+		}
+
+		public override string Solution()
+		{
+			return "This Native Query was run by instantiating all objects of the candidate class. "
+				 + "Consider simplifying the expression in the Native Query method. If you feel that "
+				 + "the Native Query processor should understand your code better, you are invited to "
+				 + "post yout query code to db4o forums at http://developer.db4o.com/forums";
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/NativeQueryOptimizerNotLoaded.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/NativeQueryOptimizerNotLoaded.cs
new file mode 100644
index 0000000..23271ef
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/NativeQueryOptimizerNotLoaded.cs
@@ -0,0 +1,65 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Diagnostic;
+
+namespace Db4objects.Db4o.Diagnostic
+{
+	public class NativeQueryOptimizerNotLoaded : DiagnosticBase
+	{
+		private int _reason;
+
+		private readonly Exception _details;
+
+		public const int NqNotPresent = 1;
+
+		public const int NqConstructionFailed = 2;
+
+		public NativeQueryOptimizerNotLoaded(int reason, Exception details)
+		{
+			_reason = reason;
+			_details = details;
+		}
+
+		public override string Problem()
+		{
+			return "Native Query Optimizer could not be loaded";
+		}
+
+		public override object Reason()
+		{
+			switch (_reason)
+			{
+				case NqNotPresent:
+				{
+					return AppendDetails("Native query not present.");
+				}
+
+				case NqConstructionFailed:
+				{
+					return AppendDetails("Native query couldn't be instantiated.");
+				}
+
+				default:
+				{
+					return AppendDetails("Reason not specified.");
+					break;
+				}
+			}
+		}
+
+		public override string Solution()
+		{
+			return "If you to have the native queries optimized, please check that the native query jar is present in the class-path.";
+		}
+
+		private object AppendDetails(string reason)
+		{
+			if (_details == null)
+			{
+				return reason;
+			}
+			return reason + "\n" + _details.ToString();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/ObjectFieldDoesNotExist.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/ObjectFieldDoesNotExist.cs
new file mode 100644
index 0000000..9815e86
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/ObjectFieldDoesNotExist.cs
@@ -0,0 +1,41 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Diagnostic;
+
+namespace Db4objects.Db4o.Diagnostic
+{
+	/// <summary>
+	/// Diagnostic if
+	/// <see cref="Db4objects.Db4o.Config.IObjectClass.ObjectField(string)">Db4objects.Db4o.Config.IObjectClass.ObjectField(string)
+	/// 	</see>
+	/// was called on a
+	/// field that does not exist.
+	/// </summary>
+	public class ObjectFieldDoesNotExist : DiagnosticBase
+	{
+		public readonly string _className;
+
+		public readonly string _fieldName;
+
+		public ObjectFieldDoesNotExist(string className, string fieldName)
+		{
+			_className = className;
+			_fieldName = fieldName;
+		}
+
+		public override string Problem()
+		{
+			return "ObjectField was configured but does not exist.";
+		}
+
+		public override object Reason()
+		{
+			return _className + "." + _fieldName;
+		}
+
+		public override string Solution()
+		{
+			return "Check your configuration.";
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/UpdateDepthGreaterOne.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/UpdateDepthGreaterOne.cs
new file mode 100644
index 0000000..f35e38d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Diagnostic/UpdateDepthGreaterOne.cs
@@ -0,0 +1,35 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Diagnostic;
+
+namespace Db4objects.Db4o.Diagnostic
+{
+	/// <summary>Diagnostic, if update depth greater than 1.</summary>
+	/// <remarks>Diagnostic, if update depth greater than 1.</remarks>
+	public class UpdateDepthGreaterOne : DiagnosticBase
+	{
+		private readonly int _depth;
+
+		public UpdateDepthGreaterOne(int depth)
+		{
+			_depth = depth;
+		}
+
+		public override object Reason()
+		{
+			return "Db4o.configure().updateDepth(" + _depth + ")";
+		}
+
+		public override string Problem()
+		{
+			return "A global update depth greater than 1 is not recommended";
+		}
+
+		public override string Solution()
+		{
+			return "Increasing the global update depth to a value greater than 1 is only recommended for"
+				 + " testing, not for production use. If individual deep updates are needed, consider using"
+				 + " ExtObjectContainer#set(object, depth) and make sure to profile the performance of each call.";
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/CancellableObjectEventArgs.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/CancellableObjectEventArgs.cs
new file mode 100644
index 0000000..29a79fe
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/CancellableObjectEventArgs.cs
@@ -0,0 +1,65 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Events;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Events
+{
+	/// <summary>Argument for object related events which can be cancelled.</summary>
+	/// <remarks>Argument for object related events which can be cancelled.</remarks>
+	/// <seealso cref="IEventRegistry">IEventRegistry</seealso>
+	/// <seealso cref="ICancellableEventArgs">ICancellableEventArgs</seealso>
+	public class CancellableObjectEventArgs : ObjectInfoEventArgs, ICancellableEventArgs
+	{
+		private bool _cancelled;
+
+		private object _object;
+
+		/// <summary>Creates a new instance for the specified object.</summary>
+		/// <remarks>Creates a new instance for the specified object.</remarks>
+		public CancellableObjectEventArgs(Transaction transaction, IObjectInfo objectInfo
+			, object obj) : base(transaction, objectInfo)
+		{
+			_object = obj;
+		}
+
+		/// <seealso cref="ICancellableEventArgs.Cancel()">ICancellableEventArgs.Cancel()</seealso>
+		public virtual void Cancel()
+		{
+			_cancelled = true;
+		}
+
+		/// <seealso cref="ICancellableEventArgs.IsCancelled()">ICancellableEventArgs.IsCancelled()
+		/// 	</seealso>
+		public virtual bool IsCancelled
+		{
+			get
+			{
+				return _cancelled;
+			}
+		}
+
+		public override object Object
+		{
+			get
+			{
+				return _object;
+			}
+		}
+
+		public override IObjectInfo Info
+		{
+			get
+			{
+				IObjectInfo info = base.Info;
+				if (null == info)
+				{
+					throw new InvalidOperationException();
+				}
+				return info;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/ClassEventArgs.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/ClassEventArgs.cs
new file mode 100644
index 0000000..9c2d567
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/ClassEventArgs.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Events
+{
+	public class ClassEventArgs : EventArgs
+	{
+		private Db4objects.Db4o.Internal.ClassMetadata _clazz;
+
+		public ClassEventArgs(Db4objects.Db4o.Internal.ClassMetadata clazz)
+		{
+			_clazz = clazz;
+		}
+
+		public virtual Db4objects.Db4o.Internal.ClassMetadata ClassMetadata()
+		{
+			return _clazz;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/CommitEventArgs.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/CommitEventArgs.cs
new file mode 100644
index 0000000..9a6e567
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/CommitEventArgs.cs
@@ -0,0 +1,55 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Events;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Events
+{
+	/// <summary>Arguments for commit time related events.</summary>
+	/// <remarks>Arguments for commit time related events.</remarks>
+	/// <seealso cref="IEventRegistry">IEventRegistry</seealso>
+	public class CommitEventArgs : TransactionalEventArgs
+	{
+		private readonly CallbackObjectInfoCollections _collections;
+
+		private readonly bool _isOwnCommit;
+
+		public CommitEventArgs(Transaction transaction, CallbackObjectInfoCollections collections
+			, bool isOwnCommit) : base(transaction)
+		{
+			_collections = collections;
+			_isOwnCommit = isOwnCommit;
+		}
+
+		/// <summary>Returns a iteration</summary>
+		public virtual IObjectInfoCollection Added
+		{
+			get
+			{
+				return _collections.added;
+			}
+		}
+
+		public virtual IObjectInfoCollection Deleted
+		{
+			get
+			{
+				return _collections.deleted;
+			}
+		}
+
+		public virtual IObjectInfoCollection Updated
+		{
+			get
+			{
+				return _collections.updated;
+			}
+		}
+
+		public virtual bool IsOwnCommit()
+		{
+			return _isOwnCommit;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/EventException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/EventException.cs
new file mode 100644
index 0000000..d874b79
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/EventException.cs
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Events
+{
+	/// <summary>
+	/// db4o-specific exception.<br/><br/>
+	/// Exception thrown during event dispatching if a client
+	/// provided event handler throws.<br/><br/>
+	/// The exception thrown by the client can be retrieved by
+	/// calling EventException.InnerException.
+	/// </summary>
+	/// <remarks>
+	/// db4o-specific exception.<br/><br/>
+	/// Exception thrown during event dispatching if a client
+	/// provided event handler throws.<br/><br/>
+	/// The exception thrown by the client can be retrieved by
+	/// calling EventException.InnerException.
+	/// </remarks>
+	[System.Serializable]
+	public class EventException : Db4oRecoverableException
+	{
+		public EventException(Exception exc) : base(exc)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/EventRegistryFactory.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/EventRegistryFactory.cs
new file mode 100644
index 0000000..5160065
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/EventRegistryFactory.cs
@@ -0,0 +1,49 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Events;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Callbacks;
+using Db4objects.Db4o.Internal.Events;
+
+namespace Db4objects.Db4o.Events
+{
+	/// <summary>
+	/// Provides an interface for getting an
+	/// <see cref="IEventRegistry">IEventRegistry</see>
+	/// from an
+	/// <see cref="Db4objects.Db4o.IObjectContainer">Db4objects.Db4o.IObjectContainer</see>
+	/// .
+	/// </summary>
+	public class EventRegistryFactory
+	{
+		/// <summary>
+		/// Returns an
+		/// <see cref="IEventRegistry">IEventRegistry</see>
+		/// for registering events with the specified container.
+		/// </summary>
+		public static IEventRegistry ForObjectContainer(IObjectContainer objectContainer)
+		{
+			if (null == objectContainer)
+			{
+				throw new ArgumentNullException();
+			}
+			IInternalObjectContainer container = ((IInternalObjectContainer)objectContainer);
+			ICallbacks callbacks = container.Callbacks();
+			if (callbacks is IEventRegistry)
+			{
+				return (IEventRegistry)callbacks;
+			}
+			if (callbacks is NullCallbacks)
+			{
+				EventRegistryImpl impl = container.NewEventRegistry();
+				container.Callbacks(impl);
+				return impl;
+			}
+			// TODO: create a MulticastingCallbacks and register both
+			// the current one and the new one
+			throw new ArgumentException();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/ICancellableEventArgs.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/ICancellableEventArgs.cs
new file mode 100644
index 0000000..48df77d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/ICancellableEventArgs.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Events
+{
+	/// <summary>Argument for events related to cancellable actions.</summary>
+	/// <remarks>Argument for events related to cancellable actions.</remarks>
+	/// <seealso cref="IEventRegistry">IEventRegistry</seealso>
+	public interface ICancellableEventArgs
+	{
+		/// <summary>Queries if the action was already cancelled by some event listener.</summary>
+		/// <remarks>Queries if the action was already cancelled by some event listener.</remarks>
+		bool IsCancelled
+		{
+			get;
+		}
+
+		/// <summary>Cancels the action related to this event.</summary>
+		/// <remarks>
+		/// Cancels the action related to this event.
+		/// Although the related action will be cancelled all the registered
+		/// listeners will still receive the event.
+		/// </remarks>
+		void Cancel();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/IEventRegistry.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/IEventRegistry.cs
new file mode 100644
index 0000000..fc8c555
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/IEventRegistry.cs
@@ -0,0 +1,284 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Events
+{
+	/// <summary>
+	/// Provides a way to register event handlers for specific <see cref="IObjectContainer">IObjectContainer</see> events.<br/>
+	/// EventRegistry methods represent events available for registering callbacks.
+	/// EventRegistry instance can be obtained from <see cref="EventRegistryFactory">EventRegistryFactory</see>.
+	/// <code>EventRegistry registry =  EventRegistryFactory.ForObjectContainer(container);</code>
+	/// A new callback can be registered for an event with the following code:
+	/// <code>
+	/// private static void OnCreated(object sender, ObjectInfoEventArgs args)
+	/// {
+	/// Object obj = args.Object;
+	/// if (obj is Pilot)
+	/// {
+	/// Console.WriteLine(obj.ToString());
+	/// }
+	/// }
+	/// registry.Created+=new System.EventHandler<ObjectInfoEventArgs>(OnCreated);
+	/// </code>
+	/// <seealso cref="EventRegistryFactory">EventRegistryFactory</seealso>
+	/// </summary>
+	public interface IEventRegistry
+	{
+		/// <summary>
+		/// This event is fired upon a query start and can be used to gather
+		/// query statistics.
+		/// </summary>
+		/// <remarks>
+		/// This event is fired upon a query start and can be used to gather
+		/// query statistics.
+		/// The query object is available from
+		/// <see cref="QueryEventArgs">QueryEventArgs</see>
+		/// event parameter.<br />
+		/// </remarks>
+		/// <returns>event</returns>
+		/// <seealso cref="QueryEventArgs">QueryEventArgs</seealso>
+		event System.EventHandler<Db4objects.Db4o.Events.QueryEventArgs> QueryStarted;
+
+		/// <summary>
+		/// This event is fired upon a query end and can be used to gather
+		/// query statistics.
+		/// </summary>
+		/// <remarks>
+		/// This event is fired upon a query end and can be used to gather
+		/// query statistics.
+		/// The query object is available from
+		/// <see cref="QueryEventArgs">QueryEventArgs</see>
+		/// event parameter.<br />
+		/// </remarks>
+		/// <returns>event</returns>
+		/// <seealso cref="QueryEventArgs">QueryEventArgs</seealso>
+		event System.EventHandler<Db4objects.Db4o.Events.QueryEventArgs> QueryFinished;
+
+		/// <summary>This event is fired before an object is saved for the first time.</summary>
+		/// <remarks>
+		/// This event is fired before an object is saved for the first time.
+		/// The object can be obtained from
+		/// <see cref="CancellableObjectEventArgs">CancellableObjectEventArgs</see>
+		/// event parameter. The action can be cancelled using
+		/// <see cref="CancellableObjectEventArgs.Cancel()">CancellableObjectEventArgs.Cancel()
+		/// 	</see>
+		/// </remarks>
+		/// <returns>event</returns>
+		/// <seealso cref="CancellableObjectEventArgs">CancellableObjectEventArgs</seealso>
+		/// <seealso cref="Db4objects.Db4o.IObjectContainer.Store(object)">Db4objects.Db4o.IObjectContainer.Store(object)
+		/// 	</seealso>
+		event System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs> Creating;
+
+		/// <summary>This event is fired before an object is activated.</summary>
+		/// <remarks>
+		/// This event is fired before an object is activated.
+		/// The object can be obtained from
+		/// <see cref="CancellableObjectEventArgs">CancellableObjectEventArgs</see>
+		/// event parameter. The action can be cancelled using
+		/// <see cref="CancellableObjectEventArgs.Cancel()">CancellableObjectEventArgs.Cancel()
+		/// 	</see>
+		/// </remarks>
+		/// <returns>event</returns>
+		/// <seealso cref="CancellableObjectEventArgs">CancellableObjectEventArgs</seealso>
+		/// <seealso cref="Db4objects.Db4o.IObjectContainer.Activate(object, int)">Db4objects.Db4o.IObjectContainer.Activate(object, int)
+		/// 	</seealso>
+		event System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs> Activating;
+
+		/// <summary>This event is fired before an object is updated.</summary>
+		/// <remarks>
+		/// This event is fired before an object is updated.
+		/// The object can be obtained from
+		/// <see cref="CancellableObjectEventArgs">CancellableObjectEventArgs</see>
+		/// event parameter. The action can be cancelled using
+		/// <see cref="CancellableObjectEventArgs.Cancel()">CancellableObjectEventArgs.Cancel()
+		/// 	</see>
+		/// </remarks>
+		/// <returns>event</returns>
+		/// <seealso cref="CancellableObjectEventArgs">CancellableObjectEventArgs</seealso>
+		/// <seealso cref="Db4objects.Db4o.IObjectContainer.Store(object)">Db4objects.Db4o.IObjectContainer.Store(object)
+		/// 	</seealso>
+		event System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs> Updating;
+
+		/// <summary>This event is fired before an object is deleted.</summary>
+		/// <remarks>
+		/// This event is fired before an object is deleted.
+		/// The object can be obtained from
+		/// <see cref="CancellableObjectEventArgs">CancellableObjectEventArgs</see>
+		/// event parameter. The action can be cancelled using
+		/// <see cref="CancellableObjectEventArgs.Cancel()">CancellableObjectEventArgs.Cancel()
+		/// 	</see>
+		/// <br /><br />
+		/// Note, that this event is not available in networked client/server
+		/// mode and will throw an exception when attached to a client ObjectContainer.
+		/// </remarks>
+		/// <returns>event</returns>
+		/// <seealso cref="CancellableObjectEventArgs">CancellableObjectEventArgs</seealso>
+		/// <seealso cref="Db4objects.Db4o.IObjectContainer.Delete(object)">Db4objects.Db4o.IObjectContainer.Delete(object)
+		/// 	</seealso>
+		event System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs> Deleting;
+
+		/// <summary>This event is fired before an object is deactivated.</summary>
+		/// <remarks>
+		/// This event is fired before an object is deactivated.
+		/// The object can be obtained from
+		/// <see cref="CancellableObjectEventArgs">CancellableObjectEventArgs</see>
+		/// event parameter. The action can be cancelled using
+		/// <see cref="CancellableObjectEventArgs.Cancel()">CancellableObjectEventArgs.Cancel()
+		/// 	</see>
+		/// </remarks>
+		/// <returns>event</returns>
+		/// <seealso cref="CancellableObjectEventArgs">CancellableObjectEventArgs</seealso>
+		/// <seealso cref="Db4objects.Db4o.IObjectContainer.Deactivate(object, int)">Db4objects.Db4o.IObjectContainer.Deactivate(object, int)
+		/// 	</seealso>
+		event System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs> Deactivating;
+
+		/// <summary>This event is fired after an object is activated.</summary>
+		/// <remarks>
+		/// This event is fired after an object is activated.
+		/// The object can be obtained from the
+		/// <see cref="ObjectInfoEventArgs">ObjectInfoEventArgs</see>
+		/// event parameter. <br /><br />
+		/// The event can be used to trigger some post-activation
+		/// functionality.
+		/// </remarks>
+		/// <returns>event</returns>
+		/// <seealso cref="ObjectInfoEventArgs">ObjectInfoEventArgs</seealso>
+		/// <seealso cref="Db4objects.Db4o.IObjectContainer.Activate(object, int)">Db4objects.Db4o.IObjectContainer.Activate(object, int)
+		/// 	</seealso>
+		event System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs> Activated;
+
+		/// <summary>This event is fired after an object is created (saved for the first time).
+		/// 	</summary>
+		/// <remarks>
+		/// This event is fired after an object is created (saved for the first time).
+		/// The object can be obtained from the
+		/// <see cref="ObjectInfoEventArgs">ObjectInfoEventArgs</see>
+		/// event parameter.<br /><br />
+		/// The event can be used to trigger some post-creation
+		/// functionality.
+		/// </remarks>
+		/// <returns>event</returns>
+		/// <seealso cref="ObjectEventArgs">ObjectEventArgs</seealso>
+		/// <seealso cref="Db4objects.Db4o.IObjectContainer.Store(object)">Db4objects.Db4o.IObjectContainer.Store(object)
+		/// 	</seealso>
+		event System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs> Created;
+
+		/// <summary>This event is fired after an object is updated.</summary>
+		/// <remarks>
+		/// This event is fired after an object is updated.
+		/// The object can be obtained from the
+		/// <see cref="ObjectInfoEventArgs">ObjectInfoEventArgs</see>
+		/// event parameter.<br /><br />
+		/// The event can be used to trigger some post-update
+		/// functionality.
+		/// </remarks>
+		/// <returns>event</returns>
+		/// <seealso cref="ObjectInfoEventArgs">ObjectInfoEventArgs</seealso>
+		/// <seealso cref="Db4objects.Db4o.IObjectContainer.Store(object)">Db4objects.Db4o.IObjectContainer.Store(object)
+		/// 	</seealso>
+		event System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs> Updated;
+
+		/// <summary>This event is fired after an object is deleted.</summary>
+		/// <remarks>
+		/// This event is fired after an object is deleted.
+		/// The object can be obtained from the
+		/// <see cref="ObjectInfoEventArgs">ObjectInfoEventArgs</see>
+		/// event parameter.<br /><br />
+		/// The event can be used to trigger some post-deletion
+		/// functionality.<br /><br />
+		/// Note, that this event is not available in networked client/server
+		/// mode and will throw an exception when attached to a client ObjectContainer.
+		/// </remarks>
+		/// <returns>event</returns>
+		/// <seealso cref="ObjectEventArgs">ObjectEventArgs</seealso>
+		/// <seealso cref="Db4objects.Db4o.IObjectContainer.Delete(object)">Db4objects.Db4o.IObjectContainer.Delete(object)
+		/// 	</seealso>
+		event System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs> Deleted;
+
+		/// <summary>This event is fired after an object is deactivated.</summary>
+		/// <remarks>
+		/// This event is fired after an object is deactivated.
+		/// The object can be obtained from the
+		/// <see cref="ObjectInfoEventArgs">ObjectInfoEventArgs</see>
+		/// event parameter.<br /><br />
+		/// The event can be used to trigger some post-deactivation
+		/// functionality.
+		/// </remarks>
+		/// <returns>event</returns>
+		/// <seealso cref="ObjectEventArgs">ObjectEventArgs</seealso>
+		/// <seealso cref="Db4objects.Db4o.IObjectContainer.Delete(object)">Db4objects.Db4o.IObjectContainer.Delete(object)
+		/// 	</seealso>
+		event System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs> Deactivated;
+
+		/// <summary>This event is fired just before a transaction is committed.</summary>
+		/// <remarks>
+		/// This event is fired just before a transaction is committed.
+		/// The transaction and a list of the modified objects can
+		/// be obtained from the
+		/// <see cref="CommitEventArgs">CommitEventArgs</see>
+		/// event parameter.<br /><br />
+		/// Committing event gives a user a chance to interrupt the commit
+		/// and rollback the transaction.
+		/// </remarks>
+		/// <returns>event</returns>
+		/// <seealso cref="CommitEventArgs">CommitEventArgs</seealso>
+		/// <seealso cref="Db4objects.Db4o.IObjectContainer.Commit()">Db4objects.Db4o.IObjectContainer.Commit()
+		/// 	</seealso>
+		event System.EventHandler<Db4objects.Db4o.Events.CommitEventArgs> Committing;
+
+		/// <summary>This event is fired after a transaction has been committed.</summary>
+		/// <remarks>
+		/// This event is fired after a transaction has been committed.
+		/// The transaction and a list of the modified objects can
+		/// be obtained from the
+		/// <see cref="CommitEventArgs">CommitEventArgs</see>
+		/// event parameter.<br /><br />
+		/// The event can be used to trigger some post-commit functionality.
+		/// </remarks>
+		/// <returns>event</returns>
+		/// <seealso cref="CommitEventArgs">CommitEventArgs</seealso>
+		/// <seealso cref="Db4objects.Db4o.IObjectContainer.Commit()">Db4objects.Db4o.IObjectContainer.Commit()
+		/// 	</seealso>
+		event System.EventHandler<Db4objects.Db4o.Events.CommitEventArgs> Committed;
+
+		/// <summary>This event is fired when a persistent object is instantiated.</summary>
+		/// <remarks>
+		/// This event is fired when a persistent object is instantiated.
+		/// The object can be obtained from the
+		/// <see cref="ObjectInfoEventArgs">ObjectInfoEventArgs</see>
+		/// event parameter.
+		/// </remarks>
+		/// <returns>event</returns>
+		/// <seealso cref="ObjectInfoEventArgs">ObjectInfoEventArgs</seealso>
+		event System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs> Instantiated;
+
+		/// <summary>This event is fired when a new class is registered with metadata.</summary>
+		/// <remarks>
+		/// This event is fired when a new class is registered with metadata.
+		/// The class information can be obtained from
+		/// <see cref="ClassEventArgs">ClassEventArgs</see>
+		/// event parameter.
+		/// </remarks>
+		/// <returns>event</returns>
+		/// <seealso cref="ClassEventArgs">ClassEventArgs</seealso>
+		event System.EventHandler<Db4objects.Db4o.Events.ClassEventArgs> ClassRegistered;
+
+		/// <summary>
+		/// This event is fired when the
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Close()">Db4objects.Db4o.IObjectContainer.Close()
+		/// 	</see>
+		/// is
+		/// called.
+		/// </summary>
+		/// <returns>event</returns>
+		event System.EventHandler<Db4objects.Db4o.Events.ObjectContainerEventArgs> Closing;
+
+		/// <summary>
+		/// This event is fired when the
+		/// <see cref="Db4objects.Db4o.IObjectContainer">Db4objects.Db4o.IObjectContainer</see>
+		/// has
+		/// finished its startup procedure.
+		/// </summary>
+		/// <returns>event</returns>
+		event System.EventHandler<Db4objects.Db4o.Events.ObjectContainerEventArgs> Opened;
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/ObjectContainerEventArgs.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/ObjectContainerEventArgs.cs
new file mode 100644
index 0000000..dd31e64
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/ObjectContainerEventArgs.cs
@@ -0,0 +1,28 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.Events
+{
+	/// <summary>Arguments for container related events.</summary>
+	/// <remarks>Arguments for container related events.</remarks>
+	/// <seealso cref="IEventRegistry">IEventRegistry</seealso>
+	public class ObjectContainerEventArgs : EventArgs
+	{
+		private readonly IObjectContainer _container;
+
+		public ObjectContainerEventArgs(IObjectContainer container)
+		{
+			_container = container;
+		}
+
+		public virtual IObjectContainer ObjectContainer
+		{
+			get
+			{
+				return _container;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/ObjectEventArgs.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/ObjectEventArgs.cs
new file mode 100644
index 0000000..5afc9e0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/ObjectEventArgs.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Events;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Events
+{
+	/// <summary>Arguments for object related events.</summary>
+	/// <remarks>Arguments for object related events.</remarks>
+	/// <seealso cref="IEventRegistry">IEventRegistry</seealso>
+	public abstract class ObjectEventArgs : TransactionalEventArgs
+	{
+		/// <summary>Creates a new instance for the specified object.</summary>
+		/// <remarks>Creates a new instance for the specified object.</remarks>
+		protected ObjectEventArgs(Transaction transaction) : base(transaction)
+		{
+		}
+
+		/// <summary>The object that triggered this event.</summary>
+		/// <remarks>The object that triggered this event.</remarks>
+		public abstract object Object
+		{
+			get;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/ObjectInfoEventArgs.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/ObjectInfoEventArgs.cs
new file mode 100644
index 0000000..f4554bc
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/ObjectInfoEventArgs.cs
@@ -0,0 +1,35 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Events;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Events
+{
+	public class ObjectInfoEventArgs : ObjectEventArgs
+	{
+		private readonly IObjectInfo _info;
+
+		public ObjectInfoEventArgs(Transaction transaction, IObjectInfo info) : base(transaction
+			)
+		{
+			_info = info;
+		}
+
+		public override object Object
+		{
+			get
+			{
+				return _info.GetObject();
+			}
+		}
+
+		public virtual IObjectInfo Info
+		{
+			get
+			{
+				return _info;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/QueryEventArgs.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/QueryEventArgs.cs
new file mode 100644
index 0000000..312fc3a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/QueryEventArgs.cs
@@ -0,0 +1,42 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Events;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Events
+{
+	/// <summary>
+	/// Arguments for
+	/// <see cref="Db4objects.Db4o.Query.IQuery">Db4objects.Db4o.Query.IQuery</see>
+	/// related events.
+	/// </summary>
+	/// <seealso cref="IEventRegistry">IEventRegistry</seealso>
+	public class QueryEventArgs : TransactionalEventArgs
+	{
+		private IQuery _query;
+
+		/// <summary>
+		/// Creates a new instance for the specified
+		/// <see cref="Db4objects.Db4o.Query.IQuery">Db4objects.Db4o.Query.IQuery</see>
+		/// instance.
+		/// </summary>
+		public QueryEventArgs(Transaction transaction, IQuery q) : base(transaction)
+		{
+			_query = q;
+		}
+
+		/// <summary>
+		/// The
+		/// <see cref="Db4objects.Db4o.Query.IQuery">Db4objects.Db4o.Query.IQuery</see>
+		/// which triggered the event.
+		/// </summary>
+		public virtual IQuery Query
+		{
+			get
+			{
+				return _query;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/StringEventArgs.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/StringEventArgs.cs
new file mode 100644
index 0000000..5a725e7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/StringEventArgs.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Events
+{
+	/// <since>7.12</since>
+	public class StringEventArgs : EventArgs
+	{
+		public StringEventArgs(string message)
+		{
+			_message = message;
+		}
+
+		public virtual string Message
+		{
+			get
+			{
+				return _message;
+			}
+		}
+
+		private readonly string _message;
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/TransactionalEventArgs.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/TransactionalEventArgs.cs
new file mode 100644
index 0000000..60efdbb
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Events/TransactionalEventArgs.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.Events
+{
+	public class TransactionalEventArgs : EventArgs
+	{
+		private readonly Db4objects.Db4o.Internal.Transaction _transaction;
+
+		public TransactionalEventArgs(Db4objects.Db4o.Internal.Transaction transaction)
+		{
+			_transaction = transaction;
+		}
+
+		public virtual object Transaction()
+		{
+			return _transaction;
+		}
+
+		public virtual IObjectContainer ObjectContainer()
+		{
+			return _transaction.ObjectContainer();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/BackupInProgressException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/BackupInProgressException.cs
new file mode 100644
index 0000000..fb5b8a1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/BackupInProgressException.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>db4o-specific exception.</summary>
+	/// <remarks>
+	/// db4o-specific exception. <br /><br />
+	/// This exception is thrown when the current
+	/// <see cref="IExtObjectContainer.Backup(string)">backup</see>
+	/// process encounters another backup process already running.
+	/// </remarks>
+	[System.Serializable]
+	public class BackupInProgressException : Db4oRecoverableException
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/CompositeDb4oException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/CompositeDb4oException.cs
new file mode 100644
index 0000000..3e561a3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/CompositeDb4oException.cs
@@ -0,0 +1,17 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Ext
+{
+	[System.Serializable]
+	public partial class CompositeDb4oException : Exception
+	{
+		public readonly Exception[] _exceptions;
+
+		public CompositeDb4oException(Exception[] exceptions)
+		{
+			_exceptions = exceptions;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/DatabaseClosedException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/DatabaseClosedException.cs
new file mode 100644
index 0000000..31bec51
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/DatabaseClosedException.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>db4o-specific exception.</summary>
+	/// <remarks>
+	/// db4o-specific exception. <br /><br />
+	/// This exception is thrown when the object container required for
+	/// the current operation was closed or failed to open.
+	/// </remarks>
+	/// <seealso cref="Db4objects.Db4o.Db4oFactory.OpenFile(string)">Db4objects.Db4o.Db4oFactory.OpenFile(string)
+	/// 	</seealso>
+	/// <seealso cref="Db4objects.Db4o.IObjectContainer.Close()">Db4objects.Db4o.IObjectContainer.Close()
+	/// 	</seealso>
+	[System.Serializable]
+	public class DatabaseClosedException : Db4oFatalException
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/DatabaseFileLockedException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/DatabaseFileLockedException.cs
new file mode 100644
index 0000000..194b7e2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/DatabaseFileLockedException.cs
@@ -0,0 +1,39 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// db4o-specific exception.<br /><br />
+	/// this Exception is thrown during any of the db4o open calls
+	/// if the database file is locked by another process.
+	/// </summary>
+	/// <remarks>
+	/// db4o-specific exception.<br /><br />
+	/// this Exception is thrown during any of the db4o open calls
+	/// if the database file is locked by another process.
+	/// </remarks>
+	/// <seealso cref="Db4objects.Db4o.Db4oFactory.OpenFile(string)">Db4objects.Db4o.Db4oFactory.OpenFile(string)
+	/// 	</seealso>
+	[System.Serializable]
+	public class DatabaseFileLockedException : Db4oFatalException
+	{
+		/// <summary>Constructor with a database description message</summary>
+		/// <param name="databaseDescription">message, which can help to identify the database
+		/// 	</param>
+		public DatabaseFileLockedException(string databaseDescription) : base(databaseDescription
+			)
+		{
+		}
+
+		/// <summary>Constructor with a database description and cause exception</summary>
+		/// <param name="databaseDescription">database description</param>
+		/// <param name="cause">previous exception caused DatabaseFileLockedException</param>
+		public DatabaseFileLockedException(string databaseDescription, Exception cause) : 
+			base(databaseDescription, cause)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/DatabaseMaximumSizeReachedException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/DatabaseMaximumSizeReachedException.cs
new file mode 100644
index 0000000..35b2801
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/DatabaseMaximumSizeReachedException.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when the database file reaches the
+	/// maximum allowed size.
+	/// </summary>
+	/// <remarks>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when the database file reaches the
+	/// maximum allowed size. Upon throwing the exception the database is
+	/// switched to the read-only mode. <br />
+	/// The maximum database size is configurable
+	/// and can reach up to 254GB.
+	/// </remarks>
+	/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.BlockSize(int)">Db4objects.Db4o.Config.IConfiguration.BlockSize(int)
+	/// 	</seealso>
+	[System.Serializable]
+	public class DatabaseMaximumSizeReachedException : Db4oRecoverableException
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/DatabaseReadOnlyException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/DatabaseReadOnlyException.cs
new file mode 100644
index 0000000..0cc6def
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/DatabaseReadOnlyException.cs
@@ -0,0 +1,22 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when a write operation is attempted
+	/// on a database in a read-only mode.
+	/// </summary>
+	/// <remarks>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when a write operation is attempted
+	/// on a database in a read-only mode.
+	/// </remarks>
+	/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.ReadOnly(bool)"></seealso>
+	[System.Serializable]
+	public class DatabaseReadOnlyException : Db4oRecoverableException
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oDatabase.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oDatabase.cs
new file mode 100644
index 0000000..ae475ce
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oDatabase.cs
@@ -0,0 +1,255 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Query;
+using Db4objects.Db4o.Types;
+using Sharpen;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>Class to identify a database by it's signature.</summary>
+	/// <remarks>
+	/// Class to identify a database by it's signature.
+	/// <br /><br />db4o UUID handling uses a reference to the Db4oDatabase object, that
+	/// represents the database an object was created on.
+	/// </remarks>
+	/// <persistent></persistent>
+	/// <exclude></exclude>
+	public class Db4oDatabase : IDb4oType, IInternal4
+	{
+		public static readonly Db4objects.Db4o.Ext.Db4oDatabase StaticIdentity = Debug4.staticIdentity
+			 ? new Db4objects.Db4o.Ext.Db4oDatabase(new byte[] { (byte)'d', (byte)'e', (byte
+			)'b', (byte)'u', (byte)'g' }, 1) : null;
+
+		public const int StaticId = -1;
+
+		/// <summary>Field is public for implementation reasons, DO NOT TOUCH!</summary>
+		public byte[] i_signature;
+
+		/// <summary>
+		/// Field is public for implementation reasons, DO NOT TOUCH!
+		/// This field is badly named, it really is the creation time.
+		/// </summary>
+		/// <remarks>
+		/// Field is public for implementation reasons, DO NOT TOUCH!
+		/// This field is badly named, it really is the creation time.
+		/// </remarks>
+		public long i_uuid;
+
+		private static readonly string CreationtimeField = "i_uuid";
+
+		/// <summary>cached ObjectContainer for getting the own ID.</summary>
+		/// <remarks>cached ObjectContainer for getting the own ID.</remarks>
+		[System.NonSerialized]
+		private ObjectContainerBase i_stream;
+
+		/// <summary>cached ID, only valid in combination with i_objectContainer</summary>
+		[System.NonSerialized]
+		private int i_id;
+
+		/// <summary>constructor for persistence</summary>
+		public Db4oDatabase()
+		{
+		}
+
+		/// <summary>constructor for comparison and to store new ones</summary>
+		public Db4oDatabase(byte[] signature, long creationTime)
+		{
+			// TODO: change to _creationTime with PersistentFormatUpdater
+			// FIXME: make sure signature is null
+			i_signature = signature;
+			i_uuid = creationTime;
+		}
+
+		/// <summary>generates a new Db4oDatabase object with a unique signature.</summary>
+		/// <remarks>generates a new Db4oDatabase object with a unique signature.</remarks>
+		public static Db4objects.Db4o.Ext.Db4oDatabase Generate()
+		{
+			StatefulBuffer writer = new StatefulBuffer(null, 300);
+			new LatinStringIO().Write(writer, SignatureGenerator.GenerateSignature());
+			return new Db4objects.Db4o.Ext.Db4oDatabase(writer.GetWrittenBytes(), Runtime.CurrentTimeMillis
+				());
+		}
+
+		/// <summary>comparison by signature.</summary>
+		/// <remarks>comparison by signature.</remarks>
+		public override bool Equals(object obj)
+		{
+			if (obj == this)
+			{
+				return true;
+			}
+			if (obj == null || this.GetType() != obj.GetType())
+			{
+				return false;
+			}
+			Db4objects.Db4o.Ext.Db4oDatabase other = (Db4objects.Db4o.Ext.Db4oDatabase)obj;
+			if (null == other.i_signature || null == this.i_signature)
+			{
+				return false;
+			}
+			return Arrays4.Equals(other.i_signature, this.i_signature);
+		}
+
+		public override int GetHashCode()
+		{
+			return i_signature.GetHashCode();
+		}
+
+		/// <summary>gets the db4o ID, and may cache it for performance reasons.</summary>
+		/// <remarks>gets the db4o ID, and may cache it for performance reasons.</remarks>
+		/// <returns>the db4o ID for the ObjectContainer</returns>
+		public virtual int GetID(Transaction trans)
+		{
+			ObjectContainerBase stream = trans.Container();
+			if (stream != i_stream)
+			{
+				i_stream = stream;
+				i_id = Bind(trans);
+			}
+			return i_id;
+		}
+
+		public virtual long GetCreationTime()
+		{
+			return i_uuid;
+		}
+
+		/// <summary>returns the unique signature</summary>
+		public virtual byte[] GetSignature()
+		{
+			return i_signature;
+		}
+
+		public override string ToString()
+		{
+			return "db " + i_signature;
+		}
+
+		public virtual bool IsOlderThan(Db4objects.Db4o.Ext.Db4oDatabase peer)
+		{
+			if (peer == this)
+			{
+				throw new ArgumentException();
+			}
+			if (i_uuid != peer.i_uuid)
+			{
+				return i_uuid < peer.i_uuid;
+			}
+			// the above logic has failed, both are the same
+			// age but we still want to distinguish in some 
+			// way, to have an order in the ReplicationRecord
+			// The following is arbitrary, it only needs to
+			// be repeatable.
+			// Let's distinguish by signature length 
+			if (i_signature.Length != peer.i_signature.Length)
+			{
+				return i_signature.Length < peer.i_signature.Length;
+			}
+			for (int i = 0; i < i_signature.Length; i++)
+			{
+				if (i_signature[i] != peer.i_signature[i])
+				{
+					return i_signature[i] < peer.i_signature[i];
+				}
+			}
+			// This should never happen.
+			// FIXME: Add a message and move to Messages.
+			// 
+			throw new Exception();
+		}
+
+		/// <summary>make sure this Db4oDatabase is stored.</summary>
+		/// <remarks>make sure this Db4oDatabase is stored. Return the ID.</remarks>
+		public virtual int Bind(Transaction trans)
+		{
+			ObjectContainerBase stream = trans.Container();
+			Db4objects.Db4o.Ext.Db4oDatabase stored = (Db4objects.Db4o.Ext.Db4oDatabase)stream
+				.Db4oTypeStored(trans, this);
+			if (stored == null)
+			{
+				return StoreAndGetId(trans);
+			}
+			if (stored == this)
+			{
+				return stream.GetID(trans, this);
+			}
+			if (i_uuid == 0)
+			{
+				i_uuid = stored.i_uuid;
+			}
+			stream.ShowInternalClasses(true);
+			try
+			{
+				int id = stream.GetID(trans, stored);
+				stream.Bind(trans, this, id);
+				return id;
+			}
+			finally
+			{
+				stream.ShowInternalClasses(false);
+			}
+		}
+
+		private int StoreAndGetId(Transaction trans)
+		{
+			ObjectContainerBase stream = trans.Container();
+			stream.ShowInternalClasses(true);
+			try
+			{
+				stream.Store2(trans, this, stream.UpdateDepthProvider().ForDepth(2), false);
+				return stream.GetID(trans, this);
+			}
+			finally
+			{
+				stream.ShowInternalClasses(false);
+			}
+		}
+
+		/// <summary>find a Db4oDatabase with the same signature as this one</summary>
+		public virtual Db4objects.Db4o.Ext.Db4oDatabase Query(Transaction trans)
+		{
+			// showInternalClasses(true);  has to be set for this method to be successful
+			if (i_uuid > 0)
+			{
+				// try fast query over uuid (creation time) first
+				Db4objects.Db4o.Ext.Db4oDatabase res = Query(trans, true);
+				if (res != null)
+				{
+					return res;
+				}
+			}
+			// if not found, try to find with signature
+			return Query(trans, false);
+		}
+
+		private Db4objects.Db4o.Ext.Db4oDatabase Query(Transaction trans, bool constrainByUUID
+			)
+		{
+			ObjectContainerBase stream = trans.Container();
+			IQuery q = stream.Query(trans);
+			q.Constrain(GetType());
+			if (constrainByUUID)
+			{
+				q.Descend(CreationtimeField).Constrain(i_uuid);
+			}
+			IObjectSet objectSet = q.Execute();
+			while (objectSet.HasNext())
+			{
+				Db4objects.Db4o.Ext.Db4oDatabase storedDatabase = (Db4objects.Db4o.Ext.Db4oDatabase
+					)objectSet.Next();
+				stream.Activate(null, storedDatabase, new FixedActivationDepth(4));
+				if (storedDatabase.Equals(this))
+				{
+					return storedDatabase;
+				}
+			}
+			return null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oException.cs
new file mode 100644
index 0000000..842886d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oException.cs
@@ -0,0 +1,59 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// db4o exception wrapper: Exceptions occurring during internal processing
+	/// will be proliferated to the client calling code encapsulated in an exception
+	/// of this type.
+	/// </summary>
+	/// <remarks>
+	/// db4o exception wrapper: Exceptions occurring during internal processing
+	/// will be proliferated to the client calling code encapsulated in an exception
+	/// of this type. The original exception, if any, is available through
+	/// Db4oException#getCause().
+	/// </remarks>
+	[System.Serializable]
+	public class Db4oException : Exception
+	{
+		/// <summary>Simple constructor</summary>
+		public Db4oException() : this(null, null)
+		{
+		}
+
+		/// <summary>Constructor with an exception message specified</summary>
+		/// <param name="msg">exception message</param>
+		public Db4oException(string msg) : this(msg, null)
+		{
+		}
+
+		/// <summary>Constructor with an exception cause specified</summary>
+		/// <param name="cause">exception cause</param>
+		public Db4oException(Exception cause) : this(null, cause)
+		{
+		}
+
+		/// <summary>
+		/// Constructor with an exception message selected
+		/// from the internal message collection.
+		/// </summary>
+		/// <remarks>
+		/// Constructor with an exception message selected
+		/// from the internal message collection.
+		/// </remarks>
+		/// <param name="messageConstant">internal db4o message number</param>
+		public Db4oException(int messageConstant) : this(Db4objects.Db4o.Internal.Messages
+			.Get(messageConstant))
+		{
+		}
+
+		/// <summary>Constructor with an exception message and cause specified</summary>
+		/// <param name="msg">exception message</param>
+		/// <param name="cause">exception cause</param>
+		public Db4oException(string msg, Exception cause) : base(msg, cause)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oFatalException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oFatalException.cs
new file mode 100644
index 0000000..524e299
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oFatalException.cs
@@ -0,0 +1,31 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	[System.Serializable]
+	public class Db4oFatalException : Db4oException
+	{
+		public Db4oFatalException() : base()
+		{
+		}
+
+		public Db4oFatalException(int messageConstant) : base(messageConstant)
+		{
+		}
+
+		public Db4oFatalException(string msg, Exception cause) : base(msg, cause)
+		{
+		}
+
+		public Db4oFatalException(string msg) : base(msg)
+		{
+		}
+
+		public Db4oFatalException(Exception cause) : base(cause)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oFileHeaderCorruptionException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oFileHeaderCorruptionException.cs
new file mode 100644
index 0000000..caf94a0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oFileHeaderCorruptionException.cs
@@ -0,0 +1,11 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	[System.Serializable]
+	public class Db4oFileHeaderCorruptionException : Db4oFatalException
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oIOException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oIOException.cs
new file mode 100644
index 0000000..d5acdcd
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oIOException.cs
@@ -0,0 +1,37 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when a system IO exception
+	/// is encounted by db4o process.
+	/// </summary>
+	/// <remarks>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when a system IO exception
+	/// is encounted by db4o process.
+	/// </remarks>
+	[System.Serializable]
+	public class Db4oIOException : Db4oFatalException
+	{
+		/// <summary>Constructor.</summary>
+		/// <remarks>Constructor.</remarks>
+		public Db4oIOException() : base()
+		{
+		}
+
+		public Db4oIOException(string message) : base(message)
+		{
+		}
+
+		/// <summary>Constructor allowing to specify the causing exception</summary>
+		/// <param name="cause">exception cause</param>
+		public Db4oIOException(Exception cause) : base(cause.Message, cause)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oIllegalStateException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oIllegalStateException.cs
new file mode 100644
index 0000000..203257b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oIllegalStateException.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// The requested operation is not valid in the current state but the database
+	/// continues to operate.
+	/// </summary>
+	/// <remarks>
+	/// The requested operation is not valid in the current state but the database
+	/// continues to operate.
+	/// </remarks>
+	[System.Serializable]
+	public class Db4oIllegalStateException : Db4oRecoverableException
+	{
+		public Db4oIllegalStateException(string message) : base(message)
+		{
+		}
+
+		public Db4oIllegalStateException(Exception cause) : base(cause)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oRecoverableException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oRecoverableException.cs
new file mode 100644
index 0000000..a977402
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oRecoverableException.cs
@@ -0,0 +1,31 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	[System.Serializable]
+	public class Db4oRecoverableException : Db4oException
+	{
+		public Db4oRecoverableException() : base()
+		{
+		}
+
+		public Db4oRecoverableException(int messageConstant) : base(messageConstant)
+		{
+		}
+
+		public Db4oRecoverableException(string msg, Exception cause) : base(msg, cause)
+		{
+		}
+
+		public Db4oRecoverableException(string msg) : base(msg)
+		{
+		}
+
+		public Db4oRecoverableException(Exception cause) : base(cause)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oUUID.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oUUID.cs
new file mode 100644
index 0000000..a994fe9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oUUID.cs
@@ -0,0 +1,112 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Text;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>a unique universal identify for an object.</summary>
+	/// <remarks>
+	/// a unique universal identify for an object. <br /><br />The db4o UUID consists of
+	/// two parts:<br /> - an indexed long for fast access,<br /> - the signature of the
+	/// <see cref="Db4objects.Db4o.IObjectContainer">IObjectContainer</see>
+	/// the object was created with.
+	/// <br /><br />Db4oUUIDs are valid representations of objects over multiple
+	/// ObjectContainers
+	/// </remarks>
+	public class Db4oUUID
+	{
+		private readonly long longPart;
+
+		private readonly byte[] signaturePart;
+
+		/// <summary>constructs a Db4oUUID from a long part and a signature part</summary>
+		/// <param name="longPart_">the long part</param>
+		/// <param name="signaturePart_">the signature part</param>
+		public Db4oUUID(long longPart_, byte[] signaturePart_)
+		{
+			longPart = longPart_;
+			signaturePart = signaturePart_;
+		}
+
+		/// <summary>returns the long part of this UUID.</summary>
+		/// <remarks>
+		/// returns the long part of this UUID. <br /><br />To uniquely identify an object
+		/// universally, db4o uses an indexed long and a reference to the
+		/// Db4oDatabase object it was created on.
+		/// </remarks>
+		/// <returns>the long part of this UUID.</returns>
+		public virtual long GetLongPart()
+		{
+			return longPart;
+		}
+
+		/// <summary>returns the signature part of this UUID.</summary>
+		/// <remarks>
+		/// returns the signature part of this UUID. <br /><br /> <br /><br />To uniquely
+		/// identify an object universally, db4o uses an indexed long and a reference to
+		/// the Db4oDatabase singleton object of the
+		/// <see cref="Db4objects.Db4o.IObjectContainer">IObjectContainer</see>
+		/// it was created on. This method
+		/// returns the signature of the Db4oDatabase object of the ObjectContainer: the
+		/// signature of the origin ObjectContainer.
+		/// </remarks>
+		/// <returns>the signature of the Db4oDatabase for this UUID.</returns>
+		public virtual byte[] GetSignaturePart()
+		{
+			return signaturePart;
+		}
+
+		public override bool Equals(object o)
+		{
+			if (this == o)
+			{
+				return true;
+			}
+			if (o == null || GetType() != o.GetType())
+			{
+				return false;
+			}
+			Db4objects.Db4o.Ext.Db4oUUID other = (Db4objects.Db4o.Ext.Db4oUUID)o;
+			if (longPart != other.longPart)
+			{
+				return false;
+			}
+			if (signaturePart == null)
+			{
+				return other.signaturePart == null;
+			}
+			if (signaturePart.Length != other.signaturePart.Length)
+			{
+				return false;
+			}
+			for (int i = 0; i < signaturePart.Length; i++)
+			{
+				if (signaturePart[i] != other.signaturePart[i])
+				{
+					return false;
+				}
+			}
+			return true;
+		}
+
+		public override int GetHashCode()
+		{
+			return (int)(longPart ^ ((longPart) >> (32 & 0x1f)));
+		}
+
+		public override string ToString()
+		{
+			StringBuilder sb = new StringBuilder();
+			sb.Append(GetType().FullName);
+			sb.Append(" sig: ");
+			for (int i = 0; i < signaturePart.Length; i++)
+			{
+				char c = (char)signaturePart[i];
+				sb.Append(c);
+			}
+			sb.Append(" long: ");
+			sb.Append(longPart);
+			return sb.ToString();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oUnexpectedException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oUnexpectedException.cs
new file mode 100644
index 0000000..b9afff8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Db4oUnexpectedException.cs
@@ -0,0 +1,16 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>Unexpected fatal error is encountered.</summary>
+	/// <remarks>Unexpected fatal error is encountered.</remarks>
+	[System.Serializable]
+	public class Db4oUnexpectedException : Exception
+	{
+		public Db4oUnexpectedException(Exception cause) : base(cause.Message, cause)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/EmergencyShutdownReadOnlyException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/EmergencyShutdownReadOnlyException.cs
new file mode 100644
index 0000000..581b1df
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/EmergencyShutdownReadOnlyException.cs
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// A previous IO exception has switched the database file
+	/// to read-only mode for controlled shutdown.
+	/// </summary>
+	/// <remarks>
+	/// A previous IO exception has switched the database file
+	/// to read-only mode for controlled shutdown.
+	/// </remarks>
+	[System.Serializable]
+	public class EmergencyShutdownReadOnlyException : Db4oIOException
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IDb4oCallback.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IDb4oCallback.cs
new file mode 100644
index 0000000..a6f27f4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IDb4oCallback.cs
@@ -0,0 +1,13 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>generic callback interface.</summary>
+	/// <remarks>generic callback interface.</remarks>
+	public interface IDb4oCallback
+	{
+		/// <summary>the callback method</summary>
+		/// <param name="obj">the object passed to the callback method</param>
+		void Callback(object obj);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IExtClient.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IExtClient.cs
new file mode 100644
index 0000000..a77bfb8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IExtClient.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// extended client functionality for the
+	/// <see cref="IExtObjectContainer">IExtObjectContainer</see>
+	/// interface.
+	/// <br /><br />Both
+	/// <see cref="Db4objects.Db4o.Db4oFactory.OpenClient(string, int, string, string)">Db4o.openClient()
+	/// 	</see>
+	/// methods always
+	/// return an <code>ExtClient</code> object so a cast is possible.<br /><br />
+	/// The ObjectContainer functionality is split into multiple interfaces to allow newcomers to
+	/// focus on the essential methods.
+	/// </summary>
+	public interface IExtClient : IExtObjectContainer
+	{
+		/// <summary>checks if the client is currently connected to a server.</summary>
+		/// <remarks>checks if the client is currently connected to a server.</remarks>
+		/// <returns>true if the client is alive.</returns>
+		bool IsAlive();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IExtObjectContainer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IExtObjectContainer.cs
new file mode 100644
index 0000000..b3ab189
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IExtObjectContainer.cs
@@ -0,0 +1,572 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Generic;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// extended functionality for the
+	/// <see cref="Db4objects.Db4o.IObjectContainer">IObjectContainer</see>
+	/// interface.
+	/// <br /><br />Every db4o
+	/// <see cref="Db4objects.Db4o.IObjectContainer">IObjectContainer</see>
+	/// always is an <code>ExtObjectContainer</code> so a cast is possible.<br /><br />
+	/// <see cref="Db4objects.Db4o.IObjectContainer.Ext()">ObjectContainer.ext()</see>
+	/// is a convenient method to perform the cast.<br /><br />
+	/// The ObjectContainer functionality is split to two interfaces to allow newcomers to
+	/// focus on the essential methods.
+	/// </summary>
+	public partial interface IExtObjectContainer : IObjectContainer
+	{
+		/// <summary>activates an object with the current activation strategy.</summary>
+		/// <remarks>
+		/// activates an object with the current activation strategy.
+		/// In regular activation mode the object will be activated to the
+		/// global activation depth, ( see
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration.ActivationDepth()">Db4objects.Db4o.Config.IConfiguration.ActivationDepth()
+		/// 	</see>
+		/// )
+		/// and all configured settings for
+		/// <see cref="Db4objects.Db4o.Config.IObjectClass.MaximumActivationDepth(int)">Db4objects.Db4o.Config.IObjectClass.MaximumActivationDepth(int)
+		/// 	</see>
+		/// 
+		/// and
+		/// <see cref="Db4objects.Db4o.Config.IObjectClass.MaximumActivationDepth(int)">Db4objects.Db4o.Config.IObjectClass.MaximumActivationDepth(int)
+		/// 	</see>
+		/// will be respected.<br /><br />
+		/// In Transparent Activation Mode ( see
+		/// <see cref="Db4objects.Db4o.TA.TransparentActivationSupport">Db4objects.Db4o.TA.TransparentActivationSupport
+		/// 	</see>
+		/// )
+		/// the parameter object will only be activated, if it does not implement
+		/// <see cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable</see>
+		/// . All referenced members that do not implement
+		/// <see cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable</see>
+		/// will also be activated. Any
+		/// <see cref="Db4objects.Db4o.TA.IActivatable">Db4objects.Db4o.TA.IActivatable</see>
+		/// objects
+		/// along the referenced graph will break cascading activation.
+		/// </remarks>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		void Activate(object obj);
+
+		/// <summary>deactivates an object.</summary>
+		/// <remarks>
+		/// deactivates an object.
+		/// Only the passed object will be deactivated, i.e, no object referenced by this
+		/// object will be deactivated.
+		/// </remarks>
+		/// <param name="obj">the object to be deactivated.</param>
+		void Deactivate(object obj);
+
+		/// <summary>backs up a database file of an open ObjectContainer.</summary>
+		/// <remarks>
+		/// backs up a database file of an open ObjectContainer.
+		/// <br /><br />While the backup is running, the ObjectContainer can continue to be
+		/// used. Changes that are made while the backup is in progress, will be applied to
+		/// the open ObjectContainer and to the backup.<br /><br />
+		/// While the backup is running, the ObjectContainer should not be closed.<br /><br />
+		/// If a file already exists at the specified path, it will be overwritten.<br /><br />
+		/// The
+		/// <see cref="Db4objects.Db4o.IO.IStorage">Db4objects.Db4o.IO.IStorage</see>
+		/// used for backup is the one configured for this container.
+		/// </remarks>
+		/// <param name="path">a fully qualified path</param>
+		/// <exception cref="DatabaseClosedException">db4o database file was closed or failed to open.
+		/// 	</exception>
+		/// <exception cref="System.NotSupportedException">
+		/// is thrown when the operation is not supported in current
+		/// configuration/environment
+		/// </exception>
+		/// <exception cref="Db4oIOException">I/O operation failed or was unexpectedly interrupted.
+		/// 	</exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		void Backup(string path);
+
+		/// <summary>backs up a database file of an open ObjectContainer.</summary>
+		/// <remarks>
+		/// backs up a database file of an open ObjectContainer.
+		/// <br /><br />While the backup is running, the ObjectContainer can continue to be
+		/// used. Changes that are made while the backup is in progress, will be applied to
+		/// the open ObjectContainer and to the backup.<br /><br />
+		/// While the backup is running, the ObjectContainer should not be closed.<br /><br />
+		/// If a file already exists at the specified path, it will be overwritten.<br /><br />
+		/// This method is intended for cross-storage backups, i.e. backup from an in-memory
+		/// database to a file.
+		/// </remarks>
+		/// <param name="targetStorage">
+		/// the
+		/// <see cref="Db4objects.Db4o.IO.IStorage">Db4objects.Db4o.IO.IStorage</see>
+		/// to be used for backup
+		/// </param>
+		/// <param name="path">a fully qualified path</param>
+		/// <exception cref="DatabaseClosedException">db4o database file was closed or failed to open.
+		/// 	</exception>
+		/// <exception cref="System.NotSupportedException">
+		/// is thrown when the operation is not supported in current
+		/// configuration/environment
+		/// </exception>
+		/// <exception cref="Db4oIOException">I/O operation failed or was unexpectedly interrupted.
+		/// 	</exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		void Backup(IStorage targetStorage, string path);
+
+		/// <summary>binds an object to an internal object ID.</summary>
+		/// <remarks>
+		/// binds an object to an internal object ID.
+		/// <br /><br />This method uses the ID parameter to load the
+		/// corresponding stored object into memory and replaces this memory
+		/// reference with the object parameter. The method may be used to replace
+		/// objects or to reassociate an object with it's stored instance
+		/// after closing and opening a database file. A subsequent call to
+		/// <see cref="com.db4o.ObjectContainer#set">set(Object)</see>
+		/// is
+		/// necessary to update the stored object.<br /><br />
+		/// <b>Requirements:</b><br />- The ID needs to be a valid internal object ID,
+		/// previously retrieved with
+		/// <see cref="GetID(object)">getID(Object)</see>
+		/// .<br />
+		/// - The object parameter needs to be of the same class as the stored object.<br /><br />
+		/// </remarks>
+		/// <seealso cref="GetID(object)">GetID(object)</seealso>
+		/// <param name="obj">the object that is to be bound</param>
+		/// <param name="id">the internal id the object is to be bound to</param>
+		/// <exception cref="DatabaseClosedException">db4o database file was closed or failed to open.
+		/// 	</exception>
+		/// <exception cref="InvalidIDException">
+		/// when the provided id is outside the scope of the
+		/// database IDs.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.InvalidIDException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		void Bind(object obj, long id);
+
+		/// <summary>returns the Configuration context for this ObjectContainer.</summary>
+		/// <remarks>
+		/// returns the Configuration context for this ObjectContainer.
+		/// <br /><br />
+		/// Upon opening an ObjectContainer with any of the factory methods in the
+		/// <see cref="Db4objects.Db4o.Db4oFactory">Db4o class</see>
+		/// , the global
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">IConfiguration</see>
+		/// context
+		/// is copied into the ObjectContainer. The
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">IConfiguration</see>
+		/// can be modified individually for
+		/// each ObjectContainer without any effects on the global settings.<br /><br />
+		/// </remarks>
+		/// <returns>
+		/// 
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">IConfiguration</see>
+		/// the Configuration
+		/// context for this ObjectContainer
+		/// </returns>
+		/// <seealso cref="Db4objects.Db4o.Db4oFactory.Configure()">Db4objects.Db4o.Db4oFactory.Configure()
+		/// 	</seealso>
+		IConfiguration Configure();
+
+		/// <summary>returns a member at the specific path without activating intermediate objects.
+		/// 	</summary>
+		/// <remarks>
+		/// returns a member at the specific path without activating intermediate objects.
+		/// <br /><br />
+		/// This method allows navigating from a persistent object to it's members in a
+		/// performant way without activating or instantiating intermediate objects.
+		/// </remarks>
+		/// <param name="obj">the parent object that is to be used as the starting point.</param>
+		/// <param name="path">an array of field names to navigate by</param>
+		/// <returns>the object at the specified path or null if no object is found</returns>
+		object Descend(object obj, string[] path);
+
+		/// <summary>returns the stored object for an internal ID.</summary>
+		/// <remarks>
+		/// returns the stored object for an internal ID.
+		/// <br /><br />This is the fastest method for direct access to objects. Internal
+		/// IDs can be obtained with
+		/// <see cref="GetID(object)">getID(Object)</see>
+		/// .
+		/// Objects will not be activated by this method. They will be returned in the
+		/// activation state they are currently in, in the local cache.<br /><br />
+		/// Passing invalid id values to this method may result in all kinds of
+		/// exceptions being thrown. OutOfMemoryError and arithmetic exceptions
+		/// may occur. If an application is known to use invalid IDs, it is
+		/// recommended to call this method within a catch-all block.
+		/// </remarks>
+		/// <param name="Id">the internal ID</param>
+		/// <returns>
+		/// the object associated with the passed ID or <code>null</code>,
+		/// if no object is associated with this ID in this <code>ObjectContainer</code>.
+		/// </returns>
+		/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.ActivationDepth()">Why activation?
+		/// 	</seealso>
+		/// <exception cref="DatabaseClosedException">db4o database file was closed or failed to open.
+		/// 	</exception>
+		/// <exception cref="InvalidIDException">
+		/// when the provided id is outside the scope of the
+		/// file length.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.InvalidIDException"></exception>
+		object GetByID(long Id);
+
+		/// <summary>
+		/// returns a stored object for a
+		/// <see cref="Db4oUUID">Db4oUUID</see>
+		/// .
+		/// <br /><br />
+		/// This method is intended for replication and for long-term
+		/// external references to objects. To get a
+		/// <see cref="Db4oUUID">Db4oUUID</see>
+		/// for an
+		/// object use
+		/// <see cref="GetObjectInfo(object)">GetObjectInfo(object)</see>
+		/// and
+		/// <see cref="IObjectInfo.GetUUID()">IObjectInfo.GetUUID()</see>
+		/// .<br /><br />
+		/// Objects will not be activated by this method. They will be returned in the
+		/// activation state they are currently in, in the local cache.<br /><br />
+		/// </summary>
+		/// <param name="uuid">the UUID</param>
+		/// <returns>the object for the UUID</returns>
+		/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.ActivationDepth()">Why activation?
+		/// 	</seealso>
+		/// <exception cref="Db4oIOException">I/O operation failed or was unexpectedly interrupted.
+		/// 	</exception>
+		/// <exception cref="DatabaseClosedException">db4o database file was closed or failed to open.
+		/// 	</exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		object GetByUUID(Db4oUUID uuid);
+
+		/// <summary>returns the internal unique object ID.</summary>
+		/// <remarks>
+		/// returns the internal unique object ID.
+		/// <br /><br />db4o assigns an internal ID to every object that is stored. IDs are
+		/// guaranteed to be unique within one <code>ObjectContainer</code>.
+		/// An object carries the same ID in every db4o session. Internal IDs can
+		/// be used to look up objects with the very fast
+		/// <see cref="GetByID(long)">getByID</see>
+		/// method.<br /><br />
+		/// Internal IDs will change when a database is defragmented. Use
+		/// <see cref="GetObjectInfo(object)">GetObjectInfo(object)</see>
+		/// ,
+		/// <see cref="IObjectInfo.GetUUID()">IObjectInfo.GetUUID()</see>
+		/// and
+		/// <see cref="GetByUUID(Db4oUUID)">GetByUUID(Db4oUUID)</see>
+		/// for long-term external references to
+		/// objects.<br /><br />
+		/// </remarks>
+		/// <param name="obj">any object</param>
+		/// <returns>
+		/// the associated internal ID or <code>0</code>, if the passed
+		/// object is not stored in this <code>ObjectContainer</code>.
+		/// </returns>
+		long GetID(object obj);
+
+		/// <summary>
+		/// returns the
+		/// <see cref="IObjectInfo">IObjectInfo</see>
+		/// for a stored object.
+		/// <br /><br />This method will return null, if the passed
+		/// object is not stored to this <code>ObjectContainer</code>.<br /><br />
+		/// </summary>
+		/// <param name="obj">the stored object</param>
+		/// <returns>
+		/// the
+		/// <see cref="IObjectInfo">IObjectInfo</see>
+		/// 
+		/// </returns>
+		IObjectInfo GetObjectInfo(object obj);
+
+		/// <summary>returns the Db4oDatabase object for this ObjectContainer.</summary>
+		/// <remarks>returns the Db4oDatabase object for this ObjectContainer.</remarks>
+		/// <returns>the Db4oDatabase identity object for this ObjectContainer.</returns>
+		Db4oDatabase Identity();
+
+		/// <summary>tests if an object is activated.</summary>
+		/// <remarks>
+		/// tests if an object is activated.
+		/// <br /><br /><code>isActive</code> returns <code>false</code> if an object is not
+		/// stored within the <code>ObjectContainer</code>.<br /><br />
+		/// </remarks>
+		/// <param name="obj">to be tested<br /><br /></param>
+		/// <returns><code>true</code> if the passed object is active.</returns>
+		bool IsActive(object obj);
+
+		/// <summary>tests if an object with this ID is currently cached.</summary>
+		/// <remarks>
+		/// tests if an object with this ID is currently cached.
+		/// <br /><br />
+		/// </remarks>
+		/// <param name="Id">the internal ID</param>
+		bool IsCached(long Id);
+
+		/// <summary>tests if this <code>ObjectContainer</code> is closed.</summary>
+		/// <remarks>
+		/// tests if this <code>ObjectContainer</code> is closed.
+		/// <br /><br />
+		/// </remarks>
+		/// <returns><code>true</code> if this <code>ObjectContainer</code> is closed.</returns>
+		bool IsClosed();
+
+		/// <summary>tests if an object is stored in this <code>ObjectContainer</code>.</summary>
+		/// <remarks>
+		/// tests if an object is stored in this <code>ObjectContainer</code>.
+		/// <br /><br />
+		/// </remarks>
+		/// <param name="obj">to be tested<br /><br /></param>
+		/// <returns><code>true</code> if the passed object is stored.</returns>
+		/// <exception cref="DatabaseClosedException">db4o database file was closed or failed to open.
+		/// 	</exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		bool IsStored(object obj);
+
+		/// <summary>
+		/// returns all class representations that are known to this
+		/// ObjectContainer because they have been used or stored.
+		/// </summary>
+		/// <remarks>
+		/// returns all class representations that are known to this
+		/// ObjectContainer because they have been used or stored.
+		/// </remarks>
+		/// <returns>
+		/// all class representations that are known to this
+		/// ObjectContainer because they have been used or stored.
+		/// </returns>
+		IReflectClass[] KnownClasses();
+
+		/// <summary>returns the main synchronization lock.</summary>
+		/// <remarks>
+		/// returns the main synchronization lock.
+		/// <br /><br />
+		/// Synchronize over this object to ensure exclusive access to
+		/// the ObjectContainer.<br /><br />
+		/// Handle the use of this functionality with extreme care,
+		/// since deadlocks can be produced with just two lines of code.
+		/// </remarks>
+		/// <returns>Object the ObjectContainer lock object</returns>
+		object Lock();
+
+		/// <summary>opens a new ObjectContainer on top of this ObjectContainer.</summary>
+		/// <remarks>
+		/// opens a new ObjectContainer on top of this ObjectContainer.
+		/// The ObjectContainer will have it's own transaction and
+		/// it's own reference system.
+		/// </remarks>
+		/// <returns>the new ObjectContainer session.</returns>
+		/// <since>8.0</since>
+		IObjectContainer OpenSession();
+
+		/// <summary>
+		/// returns a transient copy of a persistent object with all members set
+		/// to the values that are currently stored to the database.
+		/// </summary>
+		/// <remarks>
+		/// returns a transient copy of a persistent object with all members set
+		/// to the values that are currently stored to the database.
+		/// <br /><br />
+		/// The returned objects have no connection to the database.<br /><br />
+		/// With the <code>committed</code> parameter it is possible to specify,
+		/// whether the desired object should contain the committed values or the
+		/// values that were set by the running transaction with
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Store(object)">Db4objects.Db4o.IObjectContainer.Store(object)
+		/// 	</see>
+		/// .
+		/// <br /><br />A possible use case for this feature:<br />
+		/// An application might want to check all changes applied to an object
+		/// by the running transaction.<br /><br />
+		/// </remarks>
+		/// <param name="object">the object that is to be cloned</param>
+		/// <param name="depth">the member depth to which the object is to be instantiated</param>
+		/// <param name="committed">whether committed or set values are to be returned</param>
+		/// <returns>the object</returns>
+		object PeekPersisted(object @object, int depth, bool committed);
+
+		/// <summary>unloads all clean indices from memory and frees unused objects.</summary>
+		/// <remarks>
+		/// unloads all clean indices from memory and frees unused objects.
+		/// <br /><br />Call commit() and purge() consecutively to achieve the best
+		/// result possible. This method can have a negative impact
+		/// on performance since indices will have to be reread before further
+		/// inserts, updates or queries can take place.
+		/// </remarks>
+		void Purge();
+
+		/// <summary>unloads a specific object from the db4o reference mechanism.</summary>
+		/// <remarks>
+		/// unloads a specific object from the db4o reference mechanism.
+		/// <br /><br />db4o keeps references to all newly stored and
+		/// instantiated objects in memory, to be able to manage object identities.
+		/// <br /><br />With calls to this method it is possible to remove an object from the
+		/// reference mechanism, to allow it to be garbage collected. You are not required to
+		/// call this method in the .NET and JDK 1.2 versions, since objects are
+		/// referred to by weak references and garbage collection happens
+		/// automatically.<br /><br />An object removed with  <code>purge(Object)</code> is not
+		/// "known" to the <code>ObjectContainer</code> afterwards, so this method may also be
+		/// used to create multiple copies of  objects.<br /><br /> <code>purge(Object)</code> has
+		/// no influence on the persistence state of objects. "Purged" objects can be
+		/// reretrieved with queries.<br /><br />
+		/// </remarks>
+		/// <param name="obj">the object to be removed from the reference mechanism.</param>
+		void Purge(object obj);
+
+		/// <summary>Return the reflector currently being used by db4objects.</summary>
+		/// <remarks>Return the reflector currently being used by db4objects.</remarks>
+		/// <returns>the current Reflector.</returns>
+		GenericReflector Reflector();
+
+		/// <summary>refreshs all members on a stored object to the specified depth.</summary>
+		/// <remarks>
+		/// refreshs all members on a stored object to the specified depth.
+		/// <br /><br />If a member object is not activated, it will be activated by this method.
+		/// <br /><br />The isolation used is READ COMMITTED. This method will read all objects
+		/// and values that have been committed by other transactions.<br /><br />
+		/// </remarks>
+		/// <param name="obj">the object to be refreshed.</param>
+		/// <param name="depth">
+		/// the member
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration.ActivationDepth(int)">depth</see>
+		/// to which refresh is to cascade.
+		/// </param>
+		void Refresh(object obj, int depth);
+
+		/// <summary>releases a semaphore, if the calling transaction is the owner.</summary>
+		/// <remarks>releases a semaphore, if the calling transaction is the owner.</remarks>
+		/// <param name="name">the name of the semaphore to be released.</param>
+		void ReleaseSemaphore(string name);
+
+		/// <summary>deep update interface to store or update objects.</summary>
+		/// <remarks>
+		/// deep update interface to store or update objects.
+		/// <br /><br />In addition to the normal storage interface,
+		/// <see cref="com.db4o.ObjectContainer#set">ObjectContainer#set(Object)</see>
+		/// ,
+		/// this method allows a manual specification of the depth, the passed object is to be updated.<br /><br />
+		/// </remarks>
+		/// <param name="obj">the object to be stored or updated.</param>
+		/// <param name="depth">the depth to which the object is to be updated</param>
+		/// <seealso cref="com.db4o.ObjectContainer#set">com.db4o.ObjectContainer#set</seealso>
+		void Store(object obj, int depth);
+
+		/// <summary>attempts to set a semaphore.</summary>
+		/// <remarks>
+		/// attempts to set a semaphore.
+		/// <br /><br />
+		/// Semaphores are transient multi-purpose named flags for
+		/// <see cref="Db4objects.Db4o.IObjectContainer">ObjectContainers</see>
+		/// .
+		/// <br /><br />
+		/// A transaction that successfully sets a semaphore becomes
+		/// the owner of the semaphore. Semaphores can only be owned
+		/// by a single transaction at one point in time.<br /><br />
+		/// This method returns true, if the transaction already owned
+		/// the semaphore before the method call or if it successfully
+		/// acquires ownership of the semaphore.<br /><br />
+		/// The waitForAvailability parameter allows to specify a time
+		/// in milliseconds to wait for other transactions to release
+		/// the semaphore, in case the semaphore is already owned by
+		/// another transaction.<br /><br />
+		/// Semaphores are released by the first occurrence of one of the
+		/// following:<br />
+		/// - the transaction releases the semaphore with
+		/// <see cref="ReleaseSemaphore(string)">ReleaseSemaphore(string)</see>
+		/// <br /> - the transaction is closed with
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Close()">Db4objects.Db4o.IObjectContainer.Close()
+		/// 	</see>
+		/// <br /> - C/S only: the corresponding
+		/// <see cref="Db4objects.Db4o.IObjectServer">Db4objects.Db4o.IObjectServer</see>
+		/// is
+		/// closed.<br /> - C/S only: the client
+		/// <see cref="Db4objects.Db4o.IObjectContainer">Db4objects.Db4o.IObjectContainer</see>
+		/// looses the connection and is timed
+		/// out.<br /><br /> Semaphores are set immediately. They are independant of calling
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Commit()">Db4objects.Db4o.IObjectContainer.Commit()
+		/// 	</see>
+		/// or
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Rollback()">Db4objects.Db4o.IObjectContainer.Rollback()
+		/// 	</see>
+		/// .<br /><br /> <b>Possible use cases
+		/// for semaphores:</b><br /> - prevent other clients from inserting a singleton at the same time.
+		/// A suggested name for the semaphore:  "SINGLETON_" + Object#getClass().getName().<br />  - lock
+		/// objects. A suggested name:   "LOCK_" +
+		/// <see cref="GetID(object)">getID(Object)</see>
+		/// <br /> -
+		/// generate a unique client ID. A suggested name:  "CLIENT_" +
+		/// System.currentTimeMillis().<br /><br />
+		/// </remarks>
+		/// <param name="name">the name of the semaphore to be set</param>
+		/// <param name="waitForAvailability">
+		/// the time in milliseconds to wait for other
+		/// transactions to release the semaphore. The parameter may be zero, if
+		/// the method is to return immediately.
+		/// </param>
+		/// <returns>
+		/// boolean flag
+		/// <br /><code>true</code>, if the semaphore could be set or if the
+		/// calling transaction already owned the semaphore.
+		/// <br /><code>false</code>, if the semaphore is owned by another
+		/// transaction.
+		/// </returns>
+		bool SetSemaphore(string name, int waitForAvailability);
+
+		/// <summary>
+		/// returns a
+		/// <see cref="IStoredClass">IStoredClass</see>
+		/// meta information object.
+		/// <br /><br />
+		/// There are three options how to use this method.<br />
+		/// Any of the following parameters are possible:<br />
+		/// - a fully qualified class name.<br />
+		/// - a Class object.<br />
+		/// - any object to be used as a template.<br /><br />
+		/// </summary>
+		/// <param name="clazz">class name, Class object, or example object.<br /><br /></param>
+		/// <returns>
+		/// an instance of an
+		/// <see cref="IStoredClass">IStoredClass</see>
+		/// meta information object.
+		/// </returns>
+		IStoredClass StoredClass(object clazz);
+
+		/// <summary>
+		/// returns an array of all
+		/// <see cref="IStoredClass">IStoredClass</see>
+		/// meta information objects.
+		/// </summary>
+		IStoredClass[] StoredClasses();
+
+		/// <summary>
+		/// returns the
+		/// <see cref="ISystemInfo">ISystemInfo</see>
+		/// for this ObjectContainer.
+		/// <br /><br />The
+		/// <see cref="ISystemInfo">ISystemInfo</see>
+		/// supplies methods that provide
+		/// information about system state and system settings of this
+		/// ObjectContainer.
+		/// </summary>
+		/// <returns>
+		/// the
+		/// <see cref="ISystemInfo">ISystemInfo</see>
+		/// for this ObjectContainer.
+		/// </returns>
+		ISystemInfo SystemInfo();
+
+		/// <summary>returns the current transaction serial number.</summary>
+		/// <remarks>
+		/// returns the current transaction serial number.
+		/// <br /><br />This serial number can be used to query for modified objects
+		/// and for replication purposes.
+		/// </remarks>
+		/// <returns>the current transaction serial number.</returns>
+		long Version();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IExtObjectServer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IExtObjectServer.cs
new file mode 100644
index 0000000..c3cf515
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IExtObjectServer.cs
@@ -0,0 +1,80 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>extended functionality for the ObjectServer interface.</summary>
+	/// <remarks>
+	/// extended functionality for the ObjectServer interface.
+	/// <br /><br />Every ObjectServer also always is an ExtObjectServer
+	/// so a cast is possible.<br /><br />
+	/// <see cref="Db4objects.Db4o.IObjectServer.Ext()">Db4objects.Db4o.IObjectServer.Ext()
+	/// 	</see>
+	/// is a convenient method to perform the cast.<br /><br />
+	/// The functionality is split to two interfaces to allow newcomers to
+	/// focus on the essential methods.
+	/// </remarks>
+	public interface IExtObjectServer : IObjectServer
+	{
+		/// <summary>backs up the database file used by the ObjectServer.</summary>
+		/// <remarks>
+		/// backs up the database file used by the ObjectServer.
+		/// <br /><br />While the backup is running, the ObjectServer can continue to be
+		/// used. Changes that are made while the backup is in progress, will be applied to
+		/// the open ObjectServer and to the backup.<br /><br />
+		/// While the backup is running, the ObjectContainer should not be closed.<br /><br />
+		/// If a file already exists at the specified path, it will be overwritten.<br /><br />
+		/// </remarks>
+		/// <param name="path">a fully qualified path</param>
+		/// <exception cref="System.IO.IOException"></exception>
+		void Backup(string path);
+
+		/// <summary>returns the number of connected clients.</summary>
+		/// <remarks>returns the number of connected clients.</remarks>
+		int ClientCount();
+
+		/// <summary>
+		/// returns the
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">Db4objects.Db4o.Config.IConfiguration
+		/// 	</see>
+		/// context for this ObjectServer.
+		/// <br /><br />
+		/// Upon opening an ObjectServer with any of the factory methods in the
+		/// <see cref="Db4objects.Db4o.Db4oFactory">Db4objects.Db4o.Db4oFactory</see>
+		/// class, the global
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">Db4objects.Db4o.Config.IConfiguration
+		/// 	</see>
+		/// context
+		/// is copied into the ObjectServer. The
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration">Db4objects.Db4o.Config.IConfiguration
+		/// 	</see>
+		/// can be modified individually for
+		/// each ObjectServer without any effects on the global settings.<br /><br />
+		/// </summary>
+		/// <returns>the Configuration context for this ObjectServer</returns>
+		/// <seealso cref="Db4objects.Db4o.Db4oFactory.Configure()">Db4objects.Db4o.Db4oFactory.Configure()
+		/// 	</seealso>
+		IConfiguration Configure();
+
+		/// <summary>returns the ObjectContainer used by the server.</summary>
+		/// <remarks>
+		/// returns the ObjectContainer used by the server.
+		/// <br /><br />
+		/// </remarks>
+		/// <returns>the ObjectContainer used by the server</returns>
+		IObjectContainer ObjectContainer();
+
+		/// <summary>removes client access permissions for the specified user.</summary>
+		/// <remarks>
+		/// removes client access permissions for the specified user.
+		/// <br /><br />
+		/// </remarks>
+		/// <param name="userName">the name of the user</param>
+		void RevokeAccess(string userName);
+
+		/// <returns>The local port this server uses, 0 if disconnected or in embedded mode</returns>
+		int Port();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IExtObjectSet.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IExtObjectSet.cs
new file mode 100644
index 0000000..30121b9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IExtObjectSet.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// extended functionality for the
+	/// <see cref="Db4objects.Db4o.IObjectSet">IObjectSet</see>
+	/// interface.
+	/// <br /><br />Every db4o
+	/// <see cref="Db4objects.Db4o.IObjectSet">IObjectSet</see>
+	/// always is an ExtObjectSet so a cast is possible.<br /><br />
+	/// <see cref="Db4objects.Db4o.IObjectSet.Ext()">Db4objects.Db4o.IObjectSet.Ext()</see>
+	/// is a convenient method to perform the cast.<br /><br />
+	/// The ObjectSet functionality is split to two interfaces to allow newcomers to
+	/// focus on the essential methods.
+	/// </summary>
+	public interface IExtObjectSet : IObjectSet
+	{
+		/// <summary>returns an array of internal IDs that correspond to the contained objects.
+		/// 	</summary>
+		/// <remarks>
+		/// returns an array of internal IDs that correspond to the contained objects.
+		/// <br /><br />
+		/// </remarks>
+		/// <seealso cref="IExtObjectContainer.GetID(object)">IExtObjectContainer.GetID(object)
+		/// 	</seealso>
+		/// <seealso cref="IExtObjectContainer.GetByID(long)">IExtObjectContainer.GetByID(long)
+		/// 	</seealso>
+		long[] GetIDs();
+
+		/// <summary>returns the item at position [index] in this ObjectSet.</summary>
+		/// <remarks>
+		/// returns the item at position [index] in this ObjectSet.
+		/// <br /><br />
+		/// The object will be activated.
+		/// </remarks>
+		/// <param name="index">the index position in this ObjectSet.</param>
+		/// <returns>the activated object.</returns>
+		object Get(int index);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IObjectCallbacks.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IObjectCallbacks.cs
new file mode 100644
index 0000000..7e2c508
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IObjectCallbacks.cs
@@ -0,0 +1,101 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>callback methods.</summary>
+	/// <remarks>
+	/// callback methods.
+	/// <br /><br />
+	/// This interface only serves as a list of all available callback methods.
+	/// Every method is called individually, independantly of implementing this interface.<br /><br />
+	/// <b>Using callbacks</b><br />
+	/// Simply implement one or more of the listed methods in your application classes to
+	/// do tasks before activation, deactivation, delete, new or update, to cancel the
+	/// action about to be performed and to respond to the performed task.
+	/// <br /><br />Callback methods are typically used for:
+	/// <br />- cascaded delete
+	/// <br />- cascaded update
+	/// <br />- cascaded activation
+	/// <br />- restoring transient members on instantiation
+	/// <br /><br />Callback methods follow regular calling conventions. Methods in superclasses
+	/// need to be called explicitely.
+	/// <br /><br />All method calls are implemented to occur only once, upon one event.
+	/// </remarks>
+	public interface IObjectCallbacks
+	{
+		/// <summary>called before an Object is activated.</summary>
+		/// <remarks>called before an Object is activated.</remarks>
+		/// <param name="container">the <code>ObjectContainer</code> the object is stored in.
+		/// 	</param>
+		/// <returns>false to prevent activation.</returns>
+		bool ObjectCanActivate(IObjectContainer container);
+
+		/// <summary>called before an Object is deactivated.</summary>
+		/// <remarks>called before an Object is deactivated.</remarks>
+		/// <param name="container">the <code>ObjectContainer</code> the object is stored in.
+		/// 	</param>
+		/// <returns>false to prevent deactivation.</returns>
+		bool ObjectCanDeactivate(IObjectContainer container);
+
+		/// <summary>called before an Object is deleted.</summary>
+		/// <remarks>
+		/// called before an Object is deleted.
+		/// <br /><br />In a client/server setup this callback method will be executed on
+		/// the server.
+		/// </remarks>
+		/// <param name="container">the <code>ObjectContainer</code> the object is stored in.
+		/// 	</param>
+		/// <returns>false to prevent the object from being deleted.</returns>
+		bool ObjectCanDelete(IObjectContainer container);
+
+		/// <summary>called before an Object is stored the first time.</summary>
+		/// <remarks>called before an Object is stored the first time.</remarks>
+		/// <param name="container">the <code>ObjectContainer</code> is about to be stored to.
+		/// 	</param>
+		/// <returns>false to prevent the object from being stored.</returns>
+		bool ObjectCanNew(IObjectContainer container);
+
+		/// <summary>called before a persisted Object is updated.</summary>
+		/// <remarks>called before a persisted Object is updated.</remarks>
+		/// <param name="container">the <code>ObjectContainer</code> the object is stored in.
+		/// 	</param>
+		/// <returns>false to prevent the object from being updated.</returns>
+		bool ObjectCanUpdate(IObjectContainer container);
+
+		/// <summary>called upon activation of an object.</summary>
+		/// <remarks>called upon activation of an object.</remarks>
+		/// <param name="container">the <code>ObjectContainer</code> the object is stored in.
+		/// 	</param>
+		void ObjectOnActivate(IObjectContainer container);
+
+		/// <summary>called upon deactivation of an object.</summary>
+		/// <remarks>called upon deactivation of an object.</remarks>
+		/// <param name="container">the <code>ObjectContainer</code> the object is stored in.
+		/// 	</param>
+		void ObjectOnDeactivate(IObjectContainer container);
+
+		/// <summary>called after an object was deleted.</summary>
+		/// <remarks>
+		/// called after an object was deleted.
+		/// <br /><br />In a client/server setup this callback method will be executed on
+		/// the server.
+		/// </remarks>
+		/// <param name="container">the <code>ObjectContainer</code> the object was stored in.
+		/// 	</param>
+		void ObjectOnDelete(IObjectContainer container);
+
+		/// <summary>called after a new object was stored.</summary>
+		/// <remarks>called after a new object was stored.</remarks>
+		/// <param name="container">the <code>ObjectContainer</code> the object is stored to.
+		/// 	</param>
+		void ObjectOnNew(IObjectContainer container);
+
+		/// <summary>called after an object was updated.</summary>
+		/// <remarks>called after an object was updated.</remarks>
+		/// <param name="container">the <code>ObjectContainer</code> the object is stored in.
+		/// 	</param>
+		void ObjectOnUpdate(IObjectContainer container);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IObjectInfo.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IObjectInfo.cs
new file mode 100644
index 0000000..c1fa44a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IObjectInfo.cs
@@ -0,0 +1,87 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// interface to the internal reference that an ObjectContainer
+	/// holds for a stored object.
+	/// </summary>
+	/// <remarks>
+	/// interface to the internal reference that an ObjectContainer
+	/// holds for a stored object.
+	/// </remarks>
+	public interface IObjectInfo
+	{
+		/// <summary>returns the internal db4o ID.</summary>
+		/// <remarks>returns the internal db4o ID.</remarks>
+		long GetInternalID();
+
+		/// <summary>returns the object that is referenced.</summary>
+		/// <remarks>
+		/// returns the object that is referenced.
+		/// <br /><br />This method may return null, if the object has
+		/// been garbage collected.
+		/// </remarks>
+		/// <returns>
+		/// the referenced object or null, if the object has
+		/// been garbage collected.
+		/// </returns>
+		object GetObject();
+
+		/// <summary>returns a UUID representation of the referenced object.</summary>
+		/// <remarks>
+		/// returns a UUID representation of the referenced object.
+		/// UUID generation has to be turned on, in order to be able
+		/// to use this feature:
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration.GenerateUUIDs(Db4objects.Db4o.Config.ConfigScope)
+		/// 	">Db4objects.Db4o.Config.IConfiguration.GenerateUUIDs(Db4objects.Db4o.Config.ConfigScope)
+		/// 	</see>
+		/// </remarks>
+		/// <returns>the UUID of the referenced object.</returns>
+		Db4oUUID GetUUID();
+
+		/// <summary>
+		/// returns the transaction serial number ("version") the referenced object
+		/// was stored with last.
+		/// </summary>
+		/// <remarks>
+		/// returns the transaction serial number ("version") the referenced object
+		/// was stored with last. Version number generation has to be turned on, in
+		/// order to be able to use this feature:
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration.GenerateVersionNumbers(Db4objects.Db4o.Config.ConfigScope)
+		/// 	">Db4objects.Db4o.Config.IConfiguration.GenerateVersionNumbers(Db4objects.Db4o.Config.ConfigScope)
+		/// 	</see>
+		/// <br />
+		/// This feature was replaced by
+		/// <see cref="GetCommitTimestamp()">GetCommitTimestamp()</see>
+		/// . The main
+		/// difference is that the old version mechamism used to assign a serial
+		/// timestamp to the object upon storing time, and the new commiTimestamp
+		/// approach, assigns it upon commit time.<br />
+		/// </remarks>
+		/// <returns>the version number.</returns>
+		[System.ObsoleteAttribute(@"As of version 8.0 please use GetCommitTimestamp() instead."
+			)]
+		long GetVersion();
+
+		/// <summary>
+		/// The serial timestamp the object is assigned to when it is commited.<br />
+		/// <br />
+		/// You need to enable this feature before using it in
+		/// <see cref="Db4objects.Db4o.Config.IFileConfiguration.GenerateCommitTimestamps(bool)
+		/// 	">Db4objects.Db4o.Config.IFileConfiguration.GenerateCommitTimestamps(bool)</see>
+		/// .<br />
+		/// <br />
+		/// All the objects commited within the same transaction will receive the same commitTimestamp.<br />
+		/// <br />
+		/// db4o replication system (dRS) relies on this feature.<br />
+		/// </summary>
+		/// <returns>the serial timestamp that was given to the object upon commit.</returns>
+		/// <seealso cref="Db4objects.Db4o.Config.IFileConfiguration.GenerateCommitTimestamps(bool)
+		/// 	">Db4objects.Db4o.Config.IFileConfiguration.GenerateCommitTimestamps(bool)</seealso>
+		/// <since>8.0</since>
+		long GetCommitTimestamp();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IObjectInfoCollection.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IObjectInfoCollection.cs
new file mode 100644
index 0000000..e4051f0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IObjectInfoCollection.cs
@@ -0,0 +1,17 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// Interface to an iterable collection
+	/// <see cref="IObjectInfo">IObjectInfo</see>
+	/// objects.<br /><br />
+	/// ObjectInfoCollection is used reference a number of stored objects.
+	/// </summary>
+	/// <seealso cref="IObjectInfo">IObjectInfo</seealso>
+	public interface IObjectInfoCollection : IEnumerable
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IStoredClass.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IStoredClass.cs
new file mode 100644
index 0000000..fa64706
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IStoredClass.cs
@@ -0,0 +1,76 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>the internal representation of a stored class.</summary>
+	/// <remarks>the internal representation of a stored class.</remarks>
+	public interface IStoredClass
+	{
+		/// <summary>returns the name of this stored class.</summary>
+		/// <remarks>returns the name of this stored class.</remarks>
+		string GetName();
+
+		/// <summary>returns an array of IDs of all stored object instances of this stored class.
+		/// 	</summary>
+		/// <remarks>returns an array of IDs of all stored object instances of this stored class.
+		/// 	</remarks>
+		long[] GetIDs();
+
+		/// <summary>returns the StoredClass for the parent of the class, this StoredClass represents.
+		/// 	</summary>
+		/// <remarks>returns the StoredClass for the parent of the class, this StoredClass represents.
+		/// 	</remarks>
+		IStoredClass GetParentStoredClass();
+
+		/// <summary>returns all stored fields of this stored class.</summary>
+		/// <remarks>returns all stored fields of this stored class.</remarks>
+		IStoredField[] GetStoredFields();
+
+		/// <summary>returns true if this StoredClass has a class index.</summary>
+		/// <remarks>returns true if this StoredClass has a class index.</remarks>
+		bool HasClassIndex();
+
+		/// <summary>renames this stored class.</summary>
+		/// <remarks>
+		/// renames this stored class.
+		/// <br /><br />After renaming one or multiple classes the ObjectContainer has
+		/// to be closed and reopened to allow internal caches to be refreshed.
+		/// <br /><br />.NET: As the name you should provide [Classname, Assemblyname]<br /><br />
+		/// </remarks>
+		/// <param name="name">the new name</param>
+		void Rename(string name);
+
+		// TODO: add field creation
+		/// <summary>returns an existing stored field of this stored class.</summary>
+		/// <remarks>returns an existing stored field of this stored class.</remarks>
+		/// <param name="name">the name of the field</param>
+		/// <param name="type">
+		/// the type of the field.
+		/// There are four possibilities how to supply the type:<br />
+		/// - a Class object.  (.NET: a Type object)<br />
+		/// - a fully qualified classname.<br />
+		/// - any object to be used as a template.<br /><br />
+		/// - null, if the first found field should be returned.
+		/// </param>
+		/// <returns>
+		/// the
+		/// <see cref="IStoredField">IStoredField</see>
+		/// </returns>
+		IStoredField StoredField(string name, object type);
+
+		/// <summary>
+		/// Returns the number of instances of this class that have been persisted to the
+		/// database, as seen by the transaction (container) that produces this StoredClass
+		/// instance.
+		/// </summary>
+		/// <remarks>
+		/// Returns the number of instances of this class that have been persisted to the
+		/// database, as seen by the transaction (container) that produces this StoredClass
+		/// instance.
+		/// </remarks>
+		/// <returns>The number of instances</returns>
+		int InstanceCount();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IStoredField.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IStoredField.cs
new file mode 100644
index 0000000..c92e484
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IStoredField.cs
@@ -0,0 +1,86 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>the internal representation of a field on a stored class.</summary>
+	/// <remarks>the internal representation of a field on a stored class.</remarks>
+	public interface IStoredField
+	{
+		/// <summary>creates an index on this field at runtime.</summary>
+		/// <remarks>creates an index on this field at runtime.</remarks>
+		void CreateIndex();
+
+		/// <summary>drops an existing index on this field at runtime.</summary>
+		/// <remarks>drops an existing index on this field at runtime.</remarks>
+		void DropIndex();
+
+		/// <summary>returns the field value on the passed object.</summary>
+		/// <remarks>
+		/// returns the field value on the passed object.
+		/// <br /><br />This method will also work, if the field is not present in the current
+		/// version of the class.
+		/// <br /><br />It is recommended to use this method for refactoring purposes, if fields
+		/// are removed and the field values need to be copied to other fields.
+		/// </remarks>
+		object Get(object onObject);
+
+		/// <summary>returns the name of the field.</summary>
+		/// <remarks>returns the name of the field.</remarks>
+		string GetName();
+
+		/// <summary>returns the Class (Java) / Type (.NET) of the field.</summary>
+		/// <remarks>
+		/// returns the Class (Java) / Type (.NET) of the field.
+		/// <br /><br />For array fields this method will return the type of the array.
+		/// Use
+		/// <see cref="IsArray()">IsArray()</see>
+		/// to detect arrays.
+		/// </remarks>
+		IReflectClass GetStoredType();
+
+		/// <summary>returns true if the field is an array.</summary>
+		/// <remarks>returns true if the field is an array.</remarks>
+		bool IsArray();
+
+		/// <summary>modifies the name of this stored field.</summary>
+		/// <remarks>
+		/// modifies the name of this stored field.
+		/// <br /><br />After renaming one or multiple fields the ObjectContainer has
+		/// to be closed and reopened to allow internal caches to be refreshed.<br /><br />
+		/// </remarks>
+		/// <param name="name">the new name</param>
+		void Rename(string name);
+
+		/// <summary>
+		/// specialized highspeed API to collect all values of a field for all instances
+		/// of a class, if the field is indexed.
+		/// </summary>
+		/// <remarks>
+		/// specialized highspeed API to collect all values of a field for all instances
+		/// of a class, if the field is indexed.
+		/// <br /><br />The field values will be taken directly from the index without the
+		/// detour through class indexes or object instantiation.
+		/// <br /><br />
+		/// If this method is used to get the values of a first class object index,
+		/// deactivated objects will be passed to the visitor.
+		/// </remarks>
+		/// <param name="visitor">the visitor to be called with each index value.</param>
+		void TraverseValues(IVisitor4 visitor);
+
+		/// <summary>Returns whether this field has an index or not.</summary>
+		/// <remarks>Returns whether this field has an index or not.</remarks>
+		/// <returns>true if this field has an index.</returns>
+		bool HasIndex();
+		//  will need for replication. Requested for 3.0 
+		//	
+		//	/**
+		//	 * sets the field value on the passed object.
+		//	 * @param onObject
+		//	 * @param fieldValue
+		//	 */
+		//	public void set(Object onObject, Object fieldValue);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/ISystemInfo.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/ISystemInfo.cs
new file mode 100644
index 0000000..ff3bfc9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/ISystemInfo.cs
@@ -0,0 +1,38 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>provides information about system state and system settings.</summary>
+	/// <remarks>provides information about system state and system settings.</remarks>
+	public interface ISystemInfo
+	{
+		/// <summary>returns the number of entries in the Freespace Manager.</summary>
+		/// <remarks>
+		/// returns the number of entries in the Freespace Manager.
+		/// <br /><br />A high value for the number of freespace entries
+		/// is an indication that the database is fragmented and
+		/// that defragment should be run.
+		/// </remarks>
+		/// <returns>the number of entries in the Freespace Manager.</returns>
+		int FreespaceEntryCount();
+
+		/// <summary>returns the freespace size in the database in bytes.</summary>
+		/// <remarks>
+		/// returns the freespace size in the database in bytes.
+		/// <br /><br />When db4o stores modified objects, it allocates
+		/// a new slot for it. During commit the old slot is freed.
+		/// Free slots are collected in the freespace manager, so
+		/// they can be reused for other objects.
+		/// <br /><br />This method returns a sum of the size of all
+		/// free slots in the database file.
+		/// <br /><br />To reclaim freespace run defragment.
+		/// </remarks>
+		/// <returns>the freespace size in the database in bytes.</returns>
+		long FreespaceSize();
+
+		/// <summary>Returns the total size of the database on disk.</summary>
+		/// <remarks>Returns the total size of the database on disk.</remarks>
+		/// <returns>total size of database on disk</returns>
+		long TotalSize();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IncompatibleFileFormatException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IncompatibleFileFormatException.cs
new file mode 100644
index 0000000..0efca8b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/IncompatibleFileFormatException.cs
@@ -0,0 +1,28 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when the database file format
+	/// is not compatible with the applied configuration.
+	/// </summary>
+	/// <remarks>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when the database file format
+	/// is not compatible with the applied configuration.
+	/// </remarks>
+	[System.Serializable]
+	public class IncompatibleFileFormatException : Db4oFatalException
+	{
+		public IncompatibleFileFormatException() : base()
+		{
+		}
+
+		public IncompatibleFileFormatException(string message) : base(message)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/InvalidIDException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/InvalidIDException.cs
new file mode 100644
index 0000000..9a4a82c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/InvalidIDException.cs
@@ -0,0 +1,37 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when the supplied object ID
+	/// is incorrect (outside the scope of the database IDs).
+	/// </summary>
+	/// <remarks>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when the supplied object ID
+	/// is incorrect (outside the scope of the database IDs).
+	/// </remarks>
+	/// <seealso cref="IExtObjectContainer.Bind(object, long)">IExtObjectContainer.Bind(object, long)
+	/// 	</seealso>
+	/// <seealso cref="IExtObjectContainer.GetByID(long)">IExtObjectContainer.GetByID(long)
+	/// 	</seealso>
+	[System.Serializable]
+	public class InvalidIDException : Db4oRecoverableException
+	{
+		/// <summary>Constructor allowing to specify the exception cause</summary>
+		/// <param name="cause">cause exception</param>
+		public InvalidIDException(Exception cause) : base(cause)
+		{
+		}
+
+		/// <summary>Constructor allowing to specify the offending id</summary>
+		/// <param name="id">the offending id</param>
+		public InvalidIDException(int id) : base("id: " + id)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/InvalidPasswordException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/InvalidPasswordException.cs
new file mode 100644
index 0000000..f552fe9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/InvalidPasswordException.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when a client tries to connect
+	/// to a server with a wrong password or null password.
+	/// </summary>
+	/// <remarks>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when a client tries to connect
+	/// to a server with a wrong password or null password.
+	/// </remarks>
+	[System.Serializable]
+	public class InvalidPasswordException : Db4oRecoverableException
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/InvalidSlotException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/InvalidSlotException.cs
new file mode 100644
index 0000000..2d3a6cc
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/InvalidSlotException.cs
@@ -0,0 +1,37 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when db4o reads slot
+	/// information which is not valid (length or address).
+	/// </summary>
+	/// <remarks>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when db4o reads slot
+	/// information which is not valid (length or address).
+	/// </remarks>
+	[System.Serializable]
+	public class InvalidSlotException : Db4oRecoverableException
+	{
+		/// <summary>Constructor allowing to specify a detailed message.</summary>
+		/// <remarks>Constructor allowing to specify a detailed message.</remarks>
+		/// <param name="msg">message</param>
+		public InvalidSlotException(string msg) : base(msg)
+		{
+		}
+
+		/// <summary>Constructor allowing to specify the address, length and id.</summary>
+		/// <remarks>Constructor allowing to specify the address, length and id.</remarks>
+		/// <param name="address">offending address</param>
+		/// <param name="length">offending length</param>
+		/// <param name="id">id where the address and length were read.</param>
+		public InvalidSlotException(int address, int length, int id) : base("address: " +
+			 address + ", length : " + length + ", id : " + id)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/ObjectNotStorableException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/ObjectNotStorableException.cs
new file mode 100644
index 0000000..65aa3f0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/ObjectNotStorableException.cs
@@ -0,0 +1,30 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// this Exception is thrown, if objects can not be stored and if
+	/// db4o is configured to throw Exceptions on storage failures.
+	/// </summary>
+	/// <remarks>
+	/// this Exception is thrown, if objects can not be stored and if
+	/// db4o is configured to throw Exceptions on storage failures.
+	/// </remarks>
+	/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.ExceptionsOnNotStorable(bool)
+	/// 	">Db4objects.Db4o.Config.IConfiguration.ExceptionsOnNotStorable(bool)</seealso>
+	[System.Serializable]
+	public class ObjectNotStorableException : Db4oRecoverableException
+	{
+		public ObjectNotStorableException(IReflectClass a_class) : base(Db4objects.Db4o.Internal.Messages
+			.Get(a_class.IsPrimitive() ? 59 : 45, a_class.GetName()))
+		{
+		}
+
+		public ObjectNotStorableException(string message) : base(message)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/OldFormatException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/OldFormatException.cs
new file mode 100644
index 0000000..7800e67
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/OldFormatException.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// db4o-specific exception.<br /><br />
+	/// This exception is thrown when an old file format was detected
+	/// and
+	/// <see cref="Db4objects.Db4o.Config.IConfiguration.AllowVersionUpdates(bool)">Db4objects.Db4o.Config.IConfiguration.AllowVersionUpdates(bool)
+	/// 	</see>
+	/// is set to false.
+	/// </summary>
+	[System.Serializable]
+	public class OldFormatException : Db4oFatalException
+	{
+		/// <summary>Constructor with the default message.</summary>
+		/// <remarks>Constructor with the default message.</remarks>
+		public OldFormatException() : base(Db4objects.Db4o.Internal.Messages.OldDatabaseFormat
+			)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Status.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Status.cs
new file mode 100644
index 0000000..121bdeb
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/Status.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>Static constants to describe the status of objects.</summary>
+	/// <remarks>Static constants to describe the status of objects.</remarks>
+	public class Status
+	{
+		public const double Unused = -1.0;
+
+		public const double Available = -2.0;
+
+		public const double Queued = -3.0;
+
+		public const double Completed = -4.0;
+
+		public const double Processing = -5.0;
+
+		public const double Error = -99.0;
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/UnsupportedOldFormatException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/UnsupportedOldFormatException.cs
new file mode 100644
index 0000000..bc39ba0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/UnsupportedOldFormatException.cs
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>
+	/// This exception is thrown while reading old database
+	/// files for which support has been dropped.
+	/// </summary>
+	/// <remarks>
+	/// This exception is thrown while reading old database
+	/// files for which support has been dropped.
+	/// </remarks>
+	[System.Serializable]
+	public class UnsupportedOldFormatException : Db4oFatalException
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/VirtualField.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/VirtualField.cs
new file mode 100644
index 0000000..1cce610
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Ext/VirtualField.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Ext
+{
+	/// <summary>intended for future virtual fields on classes.</summary>
+	/// <remarks>
+	/// intended for future virtual fields on classes. Currently only
+	/// the constant for the virtual version field is found here.
+	/// </remarks>
+	/// <exclude></exclude>
+	public class VirtualField
+	{
+		/// <summary>
+		/// the field name of the virtual version field, to be used
+		/// for querying.
+		/// </summary>
+		/// <remarks>
+		/// the field name of the virtual version field, to be used
+		/// for querying.
+		/// </remarks>
+		public static readonly string Version = Const4.VirtualFieldPrefix + "version";
+
+		public static readonly string CommitTimestamp = Const4.VirtualFieldPrefix + "commitTimestamp";
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/AbstractTreeIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/AbstractTreeIterator.cs
new file mode 100644
index 0000000..15a7bdd
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/AbstractTreeIterator.cs
@@ -0,0 +1,106 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public abstract class AbstractTreeIterator : IEnumerator
+	{
+		private readonly Tree _tree;
+
+		private Stack4 _stack;
+
+		public AbstractTreeIterator(Tree tree)
+		{
+			_tree = tree;
+		}
+
+		public virtual object Current
+		{
+			get
+			{
+				if (_stack == null)
+				{
+					throw new InvalidOperationException();
+				}
+				Tree tree = Peek();
+				if (tree == null)
+				{
+					return null;
+				}
+				return CurrentValue(tree);
+			}
+		}
+
+		private Tree Peek()
+		{
+			return (Tree)_stack.Peek();
+		}
+
+		public virtual void Reset()
+		{
+			_stack = null;
+		}
+
+		public virtual bool MoveNext()
+		{
+			if (_stack == null)
+			{
+				InitStack();
+				return _stack != null;
+			}
+			Tree current = Peek();
+			if (current == null)
+			{
+				return false;
+			}
+			if (PushPreceding(((Tree)current._subsequent)))
+			{
+				return true;
+			}
+			while (true)
+			{
+				_stack.Pop();
+				Tree parent = Peek();
+				if (parent == null)
+				{
+					return false;
+				}
+				if (current == ((Tree)parent._preceding))
+				{
+					return true;
+				}
+				current = parent;
+			}
+		}
+
+		private void InitStack()
+		{
+			if (_tree == null)
+			{
+				return;
+			}
+			_stack = new Stack4();
+			PushPreceding(_tree);
+		}
+
+		private bool PushPreceding(Tree node)
+		{
+			if (node == null)
+			{
+				return false;
+			}
+			while (node != null)
+			{
+				_stack.Push(node);
+				node = ((Tree)node._preceding);
+			}
+			return true;
+		}
+
+		protected abstract object CurrentValue(Tree tree);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Algorithms4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Algorithms4.cs
new file mode 100644
index 0000000..aefe19f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Algorithms4.cs
@@ -0,0 +1,181 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class Algorithms4
+	{
+		private const int QsortLengthThreshold = 7;
+
+		public static void Sort(ISortable4 sortable)
+		{
+			Sort(sortable, 0, sortable.Size());
+		}
+
+		public static void Sort(ISortable4 sortable, int start, int end)
+		{
+			int length = end - start;
+			if (length < QsortLengthThreshold)
+			{
+				InsertionSort(sortable, start, end);
+				return;
+			}
+			Qsort(sortable, start, end);
+		}
+
+		public static void Qsort(ISortable4 sortable, int start, int end)
+		{
+			int length = end - start;
+			int middle = start + length / 2;
+			if (length > 7)
+			{
+				int bottom = start;
+				int top = end - 1;
+				if (length > 40)
+				{
+					length /= 8;
+					bottom = MiddleValueIndex(sortable, bottom, bottom + length, bottom + (2 * length
+						));
+					middle = MiddleValueIndex(sortable, middle - length, middle, middle + length);
+					top = MiddleValueIndex(sortable, top - (2 * length), top - length, top);
+				}
+				middle = MiddleValueIndex(sortable, bottom, middle, top);
+			}
+			int a;
+			int b;
+			int c;
+			int d;
+			a = b = start;
+			c = d = end - 1;
+			while (true)
+			{
+				while (b <= c && sortable.Compare(b, middle) <= 0)
+				{
+					if (sortable.Compare(b, middle) == 0)
+					{
+						middle = NewPartionIndex(middle, a, b);
+						Swap(sortable, a++, b);
+					}
+					b++;
+				}
+				while (c >= b && sortable.Compare(c, middle) >= 0)
+				{
+					if (sortable.Compare(c, middle) == 0)
+					{
+						middle = NewPartionIndex(middle, c, d);
+						Swap(sortable, c, d--);
+					}
+					c--;
+				}
+				if (b > c)
+				{
+					break;
+				}
+				middle = NewPartionIndex(middle, b, c);
+				Swap(sortable, b++, c--);
+			}
+			length = Math.Min(a - start, b - a);
+			Swap(sortable, start, b - length, length);
+			length = Math.Min(d - c, end - 1 - d);
+			Swap(sortable, b, end - length, length);
+			length = b - a;
+			if (length > 0)
+			{
+				Sort(sortable, start, start + length);
+			}
+			length = d - c;
+			if (length > 0)
+			{
+				Sort(sortable, end - length, end);
+			}
+		}
+
+		public static void InsertionSort(ISortable4 sortable, int start, int end)
+		{
+			for (int i = start + 1; i < end; i++)
+			{
+				for (int j = i; j > start && sortable.Compare(j - 1, j) > 0; j--)
+				{
+					Swap(sortable, j - 1, j);
+				}
+			}
+		}
+
+		private static int NewPartionIndex(int oldPartionIndex, int leftSwapIndex, int rightSwapIndex
+			)
+		{
+			if (leftSwapIndex == oldPartionIndex)
+			{
+				return rightSwapIndex;
+			}
+			else
+			{
+				if (rightSwapIndex == oldPartionIndex)
+				{
+					return leftSwapIndex;
+				}
+			}
+			return oldPartionIndex;
+		}
+
+		private static int MiddleValueIndex(ISortable4 sortable, int a, int b, int c)
+		{
+			if (sortable.Compare(a, b) < 0)
+			{
+				if (sortable.Compare(b, c) < 0)
+				{
+					return b;
+				}
+				else
+				{
+					if (sortable.Compare(a, c) < 0)
+					{
+						return c;
+					}
+					else
+					{
+						return a;
+					}
+				}
+			}
+			else
+			{
+				if (sortable.Compare(b, c) > 0)
+				{
+					return b;
+				}
+				else
+				{
+					if (sortable.Compare(a, c) > 0)
+					{
+						return c;
+					}
+					else
+					{
+						return a;
+					}
+				}
+			}
+		}
+
+		private static void Swap(ISortable4 sortable, int left, int right)
+		{
+			if (left == right)
+			{
+				return;
+			}
+			sortable.Swap(left, right);
+		}
+
+		private static void Swap(ISortable4 sortable, int from, int to, int length)
+		{
+			while (length-- > 0)
+			{
+				Swap(sortable, from++, to++);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ArrayIterator4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ArrayIterator4.cs
new file mode 100644
index 0000000..9ca9725
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ArrayIterator4.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class ArrayIterator4 : IndexedIterator
+	{
+		private readonly object[] _elements;
+
+		public ArrayIterator4(object[] elements) : base(elements.Length)
+		{
+			_elements = elements;
+		}
+
+		protected override object Get(int index)
+		{
+			return _elements[index];
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Arrays4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Arrays4.cs
new file mode 100644
index 0000000..4b8b4aa
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Arrays4.cs
@@ -0,0 +1,150 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Sharpen;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class Arrays4
+	{
+		public static int[] CopyOf(int[] src, int newLength)
+		{
+			int[] copy = new int[newLength];
+			System.Array.Copy(src, 0, copy, 0, Math.Min(src.Length, newLength));
+			return copy;
+		}
+
+		public static int IndexOfIdentity(object[] array, object element)
+		{
+			for (int i = 0; i < array.Length; i++)
+			{
+				if (array[i] == element)
+				{
+					return i;
+				}
+			}
+			return -1;
+		}
+
+		public static int IndexOfEquals(object[] array, object expected)
+		{
+			for (int i = 0; i < array.Length; ++i)
+			{
+				if (expected.Equals(array[i]))
+				{
+					return i;
+				}
+			}
+			return -1;
+		}
+
+		public static int IndexOf(int[] array, int element)
+		{
+			for (int i = 0; i < array.Length; i++)
+			{
+				if (array[i] == element)
+				{
+					return i;
+				}
+			}
+			return -1;
+		}
+
+		public static bool Equals(byte[] x, byte[] y)
+		{
+			if (x == y)
+			{
+				return true;
+			}
+			if (x == null)
+			{
+				return false;
+			}
+			if (x.Length != y.Length)
+			{
+				return false;
+			}
+			for (int i = 0; i < x.Length; i++)
+			{
+				if (y[i] != x[i])
+				{
+					return false;
+				}
+			}
+			return true;
+		}
+
+		public static bool Equals(object[] x, object[] y)
+		{
+			if (x == y)
+			{
+				return true;
+			}
+			if (x == null)
+			{
+				return false;
+			}
+			if (x.Length != y.Length)
+			{
+				return false;
+			}
+			for (int i = 0; i < x.Length; i++)
+			{
+				if (!ObjectsAreEqual(y[i], x[i]))
+				{
+					return false;
+				}
+			}
+			return true;
+		}
+
+		private static bool ObjectsAreEqual(object x, object y)
+		{
+			if (x == y)
+			{
+				return true;
+			}
+			if (x == null || y == null)
+			{
+				return false;
+			}
+			return x.Equals(y);
+		}
+
+		public static bool ContainsInstanceOf(object[] array, Type klass)
+		{
+			if (array == null)
+			{
+				return false;
+			}
+			for (int i = 0; i < array.Length; ++i)
+			{
+				if (klass.IsInstanceOfType(array[i]))
+				{
+					return true;
+				}
+			}
+			return false;
+		}
+
+		public static void Fill(object[] array, object value)
+		{
+			for (int i = 0; i < array.Length; ++i)
+			{
+				array[i] = value;
+			}
+		}
+
+		public static Collection4 AsList(object[] arr)
+		{
+			Collection4 coll = new Collection4();
+			for (int arrIdx = 0; arrIdx < arr.Length; arrIdx++)
+			{
+				coll.Add(arr[arrIdx]);
+			}
+			return coll;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/AutoStopWatch.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/AutoStopWatch.cs
new file mode 100644
index 0000000..6ae62cf
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/AutoStopWatch.cs
@@ -0,0 +1,14 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class AutoStopWatch : StopWatch
+	{
+		public AutoStopWatch()
+		{
+			Start();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/BitMap4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/BitMap4.cs
new file mode 100644
index 0000000..608e7de
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/BitMap4.cs
@@ -0,0 +1,100 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Sharpen;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public sealed class BitMap4
+	{
+		private readonly byte[] _bits;
+
+		public BitMap4(int numBits)
+		{
+			_bits = new byte[ByteCount(numBits)];
+		}
+
+		/// <summary>"readFrom  buffer" constructor</summary>
+		public BitMap4(byte[] buffer, int pos, int numBits) : this(numBits)
+		{
+			System.Array.Copy(buffer, pos, _bits, 0, _bits.Length);
+		}
+
+		public BitMap4(byte singleByte)
+		{
+			_bits = new byte[] { singleByte };
+		}
+
+		public bool IsTrue(int bit)
+		{
+			return (((_bits[ArrayOffset(bit)]) >> (ByteOffset(bit) & 0x1f)) & 1) != 0;
+		}
+
+		public bool IsFalse(int bit)
+		{
+			return !IsTrue(bit);
+		}
+
+		public int MarshalledLength()
+		{
+			return _bits.Length;
+		}
+
+		public void SetFalse(int bit)
+		{
+			_bits[ArrayOffset(bit)] &= (byte)~BitMask(bit);
+		}
+
+		public void Set(int bit, bool val)
+		{
+			if (val)
+			{
+				SetTrue(bit);
+			}
+			else
+			{
+				SetFalse(bit);
+			}
+		}
+
+		public void SetTrue(int bit)
+		{
+			_bits[ArrayOffset(bit)] |= BitMask(bit);
+		}
+
+		public void WriteTo(byte[] bytes, int pos)
+		{
+			System.Array.Copy(_bits, 0, bytes, pos, _bits.Length);
+		}
+
+		private byte ByteOffset(int bit)
+		{
+			return (byte)(bit % 8);
+		}
+
+		private int ArrayOffset(int bit)
+		{
+			return bit / 8;
+		}
+
+		private byte BitMask(int bit)
+		{
+			return (byte)(1 << ByteOffset(bit));
+		}
+
+		private int ByteCount(int numBits)
+		{
+			return (numBits + 7) / 8;
+		}
+
+		public byte GetByte(int index)
+		{
+			return _bits[index];
+		}
+
+		public byte[] Bytes()
+		{
+			return _bits;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/BlockingQueue.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/BlockingQueue.cs
new file mode 100644
index 0000000..c018c7c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/BlockingQueue.cs
@@ -0,0 +1,290 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Sharpen;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class BlockingQueue : IBlockingQueue4
+	{
+		protected NonblockingQueue _queue = new NonblockingQueue();
+
+		protected Lock4 _lock = new Lock4();
+
+		protected bool _stopped;
+
+		public virtual void Add(object obj)
+		{
+			if (obj == null)
+			{
+				throw new ArgumentException();
+			}
+			_lock.Run(new _IClosure4_20(this, obj));
+		}
+
+		private sealed class _IClosure4_20 : IClosure4
+		{
+			public _IClosure4_20(BlockingQueue _enclosing, object obj)
+			{
+				this._enclosing = _enclosing;
+				this.obj = obj;
+			}
+
+			public object Run()
+			{
+				this._enclosing._queue.Add(obj);
+				this._enclosing._lock.Awake();
+				return null;
+			}
+
+			private readonly BlockingQueue _enclosing;
+
+			private readonly object obj;
+		}
+
+		public virtual bool HasNext()
+		{
+			return (((bool)_lock.Run(new _IClosure4_30(this))));
+		}
+
+		private sealed class _IClosure4_30 : IClosure4
+		{
+			public _IClosure4_30(BlockingQueue _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Run()
+			{
+				return this._enclosing._queue.HasNext();
+			}
+
+			private readonly BlockingQueue _enclosing;
+		}
+
+		public virtual IEnumerator Iterator()
+		{
+			return ((IEnumerator)_lock.Run(new _IClosure4_38(this)));
+		}
+
+		private sealed class _IClosure4_38 : IClosure4
+		{
+			public _IClosure4_38(BlockingQueue _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Run()
+			{
+				return this._enclosing._queue.Iterator();
+			}
+
+			private readonly BlockingQueue _enclosing;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Foundation.BlockingQueueStoppedException"></exception>
+		public virtual object Next(long timeout)
+		{
+			return (object)_lock.Run(new _IClosure4_46(this, timeout));
+		}
+
+		private sealed class _IClosure4_46 : IClosure4
+		{
+			public _IClosure4_46(BlockingQueue _enclosing, long timeout)
+			{
+				this._enclosing = _enclosing;
+				this.timeout = timeout;
+			}
+
+			public object Run()
+			{
+				return this._enclosing.UnsafeWaitForNext(timeout) ? this._enclosing.UnsafeNext() : 
+					null;
+			}
+
+			private readonly BlockingQueue _enclosing;
+
+			private readonly long timeout;
+		}
+
+		public virtual int DrainTo(Collection4 target)
+		{
+			return (((int)_lock.Run(new _IClosure4_54(this, target))));
+		}
+
+		private sealed class _IClosure4_54 : IClosure4
+		{
+			public _IClosure4_54(BlockingQueue _enclosing, Collection4 target)
+			{
+				this._enclosing = _enclosing;
+				this.target = target;
+			}
+
+			public object Run()
+			{
+				this._enclosing.UnsafeWaitForNext();
+				int i = 0;
+				while (this._enclosing.HasNext())
+				{
+					i++;
+					target.Add(this._enclosing.UnsafeNext());
+				}
+				return i;
+			}
+
+			private readonly BlockingQueue _enclosing;
+
+			private readonly Collection4 target;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Foundation.BlockingQueueStoppedException"></exception>
+		public virtual bool WaitForNext(long timeout)
+		{
+			return (((bool)_lock.Run(new _IClosure4_68(this, timeout))));
+		}
+
+		private sealed class _IClosure4_68 : IClosure4
+		{
+			public _IClosure4_68(BlockingQueue _enclosing, long timeout)
+			{
+				this._enclosing = _enclosing;
+				this.timeout = timeout;
+			}
+
+			public object Run()
+			{
+				return this._enclosing.UnsafeWaitForNext(timeout);
+			}
+
+			private readonly BlockingQueue _enclosing;
+
+			private readonly long timeout;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Foundation.BlockingQueueStoppedException"></exception>
+		public virtual object Next()
+		{
+			return (object)_lock.Run(new _IClosure4_76(this));
+		}
+
+		private sealed class _IClosure4_76 : IClosure4
+		{
+			public _IClosure4_76(BlockingQueue _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Run()
+			{
+				this._enclosing.UnsafeWaitForNext();
+				return this._enclosing.UnsafeNext();
+			}
+
+			private readonly BlockingQueue _enclosing;
+		}
+
+		public virtual void Stop()
+		{
+			_lock.Run(new _IClosure4_85(this));
+		}
+
+		private sealed class _IClosure4_85 : IClosure4
+		{
+			public _IClosure4_85(BlockingQueue _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Run()
+			{
+				this._enclosing._stopped = true;
+				this._enclosing._lock.Awake();
+				return null;
+			}
+
+			private readonly BlockingQueue _enclosing;
+		}
+
+		public virtual object NextMatching(IPredicate4 condition)
+		{
+			return _lock.Run(new _IClosure4_95(this, condition));
+		}
+
+		private sealed class _IClosure4_95 : IClosure4
+		{
+			public _IClosure4_95(BlockingQueue _enclosing, IPredicate4 condition)
+			{
+				this._enclosing = _enclosing;
+				this.condition = condition;
+			}
+
+			public object Run()
+			{
+				return this._enclosing._queue.NextMatching(condition);
+			}
+
+			private readonly BlockingQueue _enclosing;
+
+			private readonly IPredicate4 condition;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Foundation.BlockingQueueStoppedException"></exception>
+		public virtual void WaitForNext()
+		{
+			_lock.Run(new _IClosure4_103(this));
+		}
+
+		private sealed class _IClosure4_103 : IClosure4
+		{
+			public _IClosure4_103(BlockingQueue _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Run()
+			{
+				this._enclosing.UnsafeWaitForNext();
+				return null;
+			}
+
+			private readonly BlockingQueue _enclosing;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Foundation.BlockingQueueStoppedException"></exception>
+		protected virtual void UnsafeWaitForNext()
+		{
+			UnsafeWaitForNext(long.MaxValue);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Foundation.BlockingQueueStoppedException"></exception>
+		protected virtual bool UnsafeWaitForNext(long timeout)
+		{
+			long timeLeft = timeout;
+			long now = Runtime.CurrentTimeMillis();
+			while (timeLeft > 0)
+			{
+				if (_queue.HasNext())
+				{
+					return true;
+				}
+				if (_stopped)
+				{
+					throw new BlockingQueueStoppedException();
+				}
+				_lock.Snooze(timeLeft);
+				long l = now;
+				now = Runtime.CurrentTimeMillis();
+				timeLeft -= now - l;
+			}
+			return false;
+		}
+
+		private object UnsafeNext()
+		{
+			return _queue.Next();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/BlockingQueueStoppedException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/BlockingQueueStoppedException.cs
new file mode 100644
index 0000000..b546fe0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/BlockingQueueStoppedException.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	[System.Serializable]
+	public class BlockingQueueStoppedException : Exception
+	{
+		public BlockingQueueStoppedException() : base()
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.BlockingQueueStoppedException.Log();
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/BooleanByRef.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/BooleanByRef.cs
new file mode 100755
index 0000000..db108f3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/BooleanByRef.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>Useful as "out" or "by ref" function parameter.</summary>
+	/// <remarks>Useful as "out" or "by ref" function parameter.</remarks>
+	public class BooleanByRef
+	{
+		public bool value;
+
+		public BooleanByRef() : this(false)
+		{
+		}
+
+		public BooleanByRef(bool value_)
+		{
+			value = value_;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ByRef.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ByRef.cs
new file mode 100644
index 0000000..ef4d09d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ByRef.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>Useful as "out" or "by reference" function parameter.</summary>
+	/// <remarks>Useful as "out" or "by reference" function parameter.</remarks>
+	public class ByRef
+	{
+		public static ByRef NewInstance(object initialValue)
+		{
+			ByRef instance = new ByRef();
+			instance.value = initialValue;
+			return instance;
+		}
+
+		public static ByRef NewInstance()
+		{
+			return new ByRef();
+		}
+
+		public object value;
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/CircularBuffer4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/CircularBuffer4.cs
new file mode 100644
index 0000000..2a6bcc5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/CircularBuffer4.cs
@@ -0,0 +1,205 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>A fixed size double ended queue with O(1) complexity for addFirst, removeFirst and removeLast operations.
+	/// 	</summary>
+	/// <remarks>A fixed size double ended queue with O(1) complexity for addFirst, removeFirst and removeLast operations.
+	/// 	</remarks>
+	public class CircularBuffer4 : IEnumerable
+	{
+		private readonly object[] _buffer;
+
+		private int _head;
+
+		private int _tail;
+
+		public CircularBuffer4(int size)
+		{
+			_buffer = (object[])new object[size + 1];
+		}
+
+		public virtual int Size()
+		{
+			return Index(_tail - _head);
+		}
+
+		public virtual void AddFirst(object value)
+		{
+			int newHead = CircularIndex(_head - 1);
+			if (newHead == _tail)
+			{
+				throw new InvalidOperationException();
+			}
+			_head = newHead;
+			_buffer[Index(_head)] = value;
+		}
+
+		private int CircularIndex(int index)
+		{
+			return index % _buffer.Length;
+		}
+
+		private int Index(int i)
+		{
+			return i < 0 ? _buffer.Length + i : i;
+		}
+
+		public virtual object RemoveLast()
+		{
+			AssertNotEmpty();
+			_tail = CircularIndex(_tail - 1);
+			return Erase(_tail);
+		}
+
+		private void AssertNotEmpty()
+		{
+			if (IsEmpty())
+			{
+				throw new InvalidOperationException();
+			}
+		}
+
+		public virtual bool IsEmpty()
+		{
+			return Index(_head) == Index(_tail);
+		}
+
+		public virtual bool IsFull()
+		{
+			return CircularIndex(_head - 1) == _tail;
+		}
+
+		public virtual object RemoveFirst()
+		{
+			AssertNotEmpty();
+			object erased = Erase(_head);
+			_head = CircularIndex(_head + 1);
+			return erased;
+		}
+
+		private object Erase(int index)
+		{
+			int bufferIndex = Index(index);
+			object erasedValue = _buffer[bufferIndex];
+			_buffer[bufferIndex] = null;
+			return erasedValue;
+		}
+
+		public virtual bool Remove(object value)
+		{
+			int idx = IndexOf(value);
+			if (idx >= 0)
+			{
+				RemoveAt(idx);
+				return true;
+			}
+			return false;
+		}
+
+		public virtual bool Contains(object value)
+		{
+			return IndexOf(value) >= 0;
+		}
+
+		private int IndexOf(object value)
+		{
+			int current = Index(_head);
+			int tail = Index(_tail);
+			while (current != tail)
+			{
+				if (((object)value).Equals(_buffer[current]))
+				{
+					break;
+				}
+				current = CircularIndex(current + 1);
+			}
+			return (current == tail ? -1 : current);
+		}
+
+		private void RemoveAt(int index)
+		{
+			if (Index(_tail - 1) == index)
+			{
+				RemoveLast();
+				return;
+			}
+			if (index == Index(_head))
+			{
+				RemoveFirst();
+				return;
+			}
+			int current = index;
+			int tail = Index(_tail);
+			while (current != tail)
+			{
+				int next = CircularIndex(current + 1);
+				_buffer[current] = _buffer[next];
+				current = next;
+			}
+			_tail = CircularIndex(_tail - 1);
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			int tail = Index(_tail);
+			int head = Index(_head);
+			// TODO: detect concurrent modification and throw IllegalStateException
+			return new _IEnumerator_121(this, head, tail);
+		}
+
+		private sealed class _IEnumerator_121 : IEnumerator
+		{
+			public _IEnumerator_121(CircularBuffer4 _enclosing, int head, int tail)
+			{
+				this._enclosing = _enclosing;
+				this.head = head;
+				this.tail = tail;
+				this._index = head;
+				this._current = Iterators.NoElement;
+			}
+
+			private int _index;
+
+			private object _current;
+
+			public object Current
+			{
+				get
+				{
+					if (this._current == Iterators.NoElement)
+					{
+						throw new InvalidOperationException();
+					}
+					return this._current;
+				}
+			}
+
+			public bool MoveNext()
+			{
+				if (this._index == tail)
+				{
+					return false;
+				}
+				this._current = this._enclosing._buffer[this._index];
+				this._index = this._enclosing.CircularIndex(this._index + 1);
+				return true;
+			}
+
+			public void Reset()
+			{
+				throw new NotImplementedException();
+			}
+
+			private readonly CircularBuffer4 _enclosing;
+
+			private readonly int head;
+
+			private readonly int tail;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/CircularIntBuffer4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/CircularIntBuffer4.cs
new file mode 100644
index 0000000..e95bd26
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/CircularIntBuffer4.cs
@@ -0,0 +1,207 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>A fixed size double ended queue with O(1) complexity for addFirst, removeFirst and removeLast operations.
+	/// 	</summary>
+	/// <remarks>A fixed size double ended queue with O(1) complexity for addFirst, removeFirst and removeLast operations.
+	/// 	</remarks>
+	public class CircularIntBuffer4 : IEnumerable
+	{
+		private const int Empty = -1;
+
+		private readonly int[] _buffer;
+
+		private int _head;
+
+		private int _tail;
+
+		public CircularIntBuffer4(int size)
+		{
+			_buffer = new int[size + 1];
+		}
+
+		public virtual int Size()
+		{
+			return Index(_tail - _head);
+		}
+
+		public virtual void AddFirst(int value)
+		{
+			int newHead = CircularIndex(_head - 1);
+			if (newHead == _tail)
+			{
+				throw new InvalidOperationException();
+			}
+			_head = newHead;
+			_buffer[Index(_head)] = value;
+		}
+
+		private int CircularIndex(int index)
+		{
+			return index % _buffer.Length;
+		}
+
+		private int Index(int i)
+		{
+			return i < 0 ? _buffer.Length + i : i;
+		}
+
+		public virtual int RemoveLast()
+		{
+			AssertNotEmpty();
+			_tail = CircularIndex(_tail - 1);
+			return Erase(_tail);
+		}
+
+		private void AssertNotEmpty()
+		{
+			if (IsEmpty())
+			{
+				throw new InvalidOperationException();
+			}
+		}
+
+		public virtual bool IsEmpty()
+		{
+			return Index(_head) == Index(_tail);
+		}
+
+		public virtual bool IsFull()
+		{
+			return CircularIndex(_head - 1) == _tail;
+		}
+
+		public virtual int RemoveFirst()
+		{
+			AssertNotEmpty();
+			int erased = Erase(_head);
+			_head = CircularIndex(_head + 1);
+			return erased;
+		}
+
+		private int Erase(int index)
+		{
+			int bufferIndex = Index(index);
+			int erasedValue = _buffer[bufferIndex];
+			_buffer[bufferIndex] = Empty;
+			return erasedValue;
+		}
+
+		public virtual bool Remove(int value)
+		{
+			int idx = IndexOf(value);
+			if (idx >= 0)
+			{
+				RemoveAt(idx);
+				return true;
+			}
+			return false;
+		}
+
+		public virtual bool Contains(int value)
+		{
+			return IndexOf(value) >= 0;
+		}
+
+		private int IndexOf(int value)
+		{
+			int current = Index(_head);
+			int tail = Index(_tail);
+			while (current != tail)
+			{
+				if (value == _buffer[current])
+				{
+					break;
+				}
+				current = CircularIndex(current + 1);
+			}
+			return (current == tail ? -1 : current);
+		}
+
+		private void RemoveAt(int index)
+		{
+			if (Index(_tail - 1) == index)
+			{
+				RemoveLast();
+				return;
+			}
+			if (index == Index(_head))
+			{
+				RemoveFirst();
+				return;
+			}
+			int current = index;
+			int tail = Index(_tail);
+			while (current != tail)
+			{
+				int next = CircularIndex(current + 1);
+				_buffer[current] = _buffer[next];
+				current = next;
+			}
+			_tail = CircularIndex(_tail - 1);
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			int tail = Index(_tail);
+			int head = Index(_head);
+			// TODO: detect concurrent modification and throw IllegalStateException
+			return new _IEnumerator_123(this, head, tail);
+		}
+
+		private sealed class _IEnumerator_123 : IEnumerator
+		{
+			public _IEnumerator_123(CircularIntBuffer4 _enclosing, int head, int tail)
+			{
+				this._enclosing = _enclosing;
+				this.head = head;
+				this.tail = tail;
+				this._index = head;
+				this._current = Iterators.NoElement;
+			}
+
+			private int _index;
+
+			private object _current;
+
+			public object Current
+			{
+				get
+				{
+					if (this._current == Iterators.NoElement)
+					{
+						throw new InvalidOperationException();
+					}
+					return this._current;
+				}
+			}
+
+			public bool MoveNext()
+			{
+				if (this._index == tail)
+				{
+					return false;
+				}
+				this._current = this._enclosing._buffer[this._index];
+				this._index = this._enclosing.CircularIndex(this._index + 1);
+				return true;
+			}
+
+			public void Reset()
+			{
+				throw new NotImplementedException();
+			}
+
+			private readonly CircularIntBuffer4 _enclosing;
+
+			private readonly int head;
+
+			private readonly int tail;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/CircularLongBuffer4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/CircularLongBuffer4.cs
new file mode 100644
index 0000000..2b9d8ef
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/CircularLongBuffer4.cs
@@ -0,0 +1,207 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>A fixed size double ended queue with O(1) complexity for addFirst, removeFirst and removeLast operations.
+	/// 	</summary>
+	/// <remarks>A fixed size double ended queue with O(1) complexity for addFirst, removeFirst and removeLast operations.
+	/// 	</remarks>
+	public class CircularLongBuffer4 : IEnumerable
+	{
+		private const int Empty = -1;
+
+		private readonly long[] _buffer;
+
+		private int _head;
+
+		private int _tail;
+
+		public CircularLongBuffer4(int size)
+		{
+			_buffer = new long[size + 1];
+		}
+
+		public virtual int Size()
+		{
+			return Index(_tail - _head);
+		}
+
+		public virtual void AddFirst(long value)
+		{
+			int newHead = CircularIndex(_head - 1);
+			if (newHead == _tail)
+			{
+				throw new InvalidOperationException();
+			}
+			_head = newHead;
+			_buffer[Index(_head)] = value;
+		}
+
+		private int CircularIndex(int index)
+		{
+			return index % _buffer.Length;
+		}
+
+		private int Index(int i)
+		{
+			return i < 0 ? _buffer.Length + i : i;
+		}
+
+		public virtual long RemoveLast()
+		{
+			AssertNotEmpty();
+			_tail = CircularIndex(_tail - 1);
+			return Erase(_tail);
+		}
+
+		private void AssertNotEmpty()
+		{
+			if (IsEmpty())
+			{
+				throw new InvalidOperationException();
+			}
+		}
+
+		public virtual bool IsEmpty()
+		{
+			return Index(_head) == Index(_tail);
+		}
+
+		public virtual bool IsFull()
+		{
+			return CircularIndex(_head - 1) == _tail;
+		}
+
+		public virtual long RemoveFirst()
+		{
+			AssertNotEmpty();
+			long erased = Erase(_head);
+			_head = CircularIndex(_head + 1);
+			return erased;
+		}
+
+		private long Erase(int index)
+		{
+			int bufferIndex = Index(index);
+			long erasedValue = _buffer[bufferIndex];
+			_buffer[bufferIndex] = Empty;
+			return erasedValue;
+		}
+
+		public virtual bool Remove(long value)
+		{
+			int idx = IndexOf(value);
+			if (idx >= 0)
+			{
+				RemoveAt(idx);
+				return true;
+			}
+			return false;
+		}
+
+		public virtual bool Contains(long value)
+		{
+			return IndexOf(value) >= 0;
+		}
+
+		private int IndexOf(long value)
+		{
+			int current = Index(_head);
+			int tail = Index(_tail);
+			while (current != tail)
+			{
+				if (value == _buffer[current])
+				{
+					break;
+				}
+				current = CircularIndex(current + 1);
+			}
+			return (current == tail ? -1 : current);
+		}
+
+		private void RemoveAt(int index)
+		{
+			if (Index(_tail - 1) == index)
+			{
+				RemoveLast();
+				return;
+			}
+			if (index == Index(_head))
+			{
+				RemoveFirst();
+				return;
+			}
+			int current = index;
+			int tail = Index(_tail);
+			while (current != tail)
+			{
+				int next = CircularIndex(current + 1);
+				_buffer[current] = _buffer[next];
+				current = next;
+			}
+			_tail = CircularIndex(_tail - 1);
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			int tail = Index(_tail);
+			int head = Index(_head);
+			// TODO: detect concurrent modification and throw IllegalStateException
+			return new _IEnumerator_122(this, head, tail);
+		}
+
+		private sealed class _IEnumerator_122 : IEnumerator
+		{
+			public _IEnumerator_122(CircularLongBuffer4 _enclosing, int head, int tail)
+			{
+				this._enclosing = _enclosing;
+				this.head = head;
+				this.tail = tail;
+				this._index = head;
+				this._current = Iterators.NoElement;
+			}
+
+			private int _index;
+
+			private object _current;
+
+			public object Current
+			{
+				get
+				{
+					if (this._current == Iterators.NoElement)
+					{
+						throw new InvalidOperationException();
+					}
+					return this._current;
+				}
+			}
+
+			public bool MoveNext()
+			{
+				if (this._index == tail)
+				{
+					return false;
+				}
+				this._current = this._enclosing._buffer[this._index];
+				this._index = this._enclosing.CircularIndex(this._index + 1);
+				return true;
+			}
+
+			public void Reset()
+			{
+				throw new NotImplementedException();
+			}
+
+			private readonly CircularLongBuffer4 _enclosing;
+
+			private readonly int head;
+
+			private readonly int tail;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Collection4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Collection4.cs
new file mode 100644
index 0000000..a1bea2b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Collection4.cs
@@ -0,0 +1,450 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Types;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>Fast linked list for all usecases.</summary>
+	/// <remarks>Fast linked list for all usecases.</remarks>
+	/// <exclude></exclude>
+	public class Collection4 : ISequence4, IEnumerable, IDeepClone, IUnversioned
+	{
+		private List4 _first;
+
+		private List4 _last;
+
+		private int _size;
+
+		private int _version;
+
+		public Collection4()
+		{
+		}
+
+		public Collection4(object[] elements)
+		{
+			AddAll(elements);
+		}
+
+		public Collection4(IEnumerable other)
+		{
+			AddAll(other);
+		}
+
+		public Collection4(IEnumerator iterator)
+		{
+			AddAll(iterator);
+		}
+
+		public virtual object SingleElement()
+		{
+			if (Size() != 1)
+			{
+				throw new InvalidOperationException();
+			}
+			return ((object)_first._element);
+		}
+
+		/// <summary>Adds an element to the end of this collection.</summary>
+		/// <remarks>Adds an element to the end of this collection.</remarks>
+		/// <param name="element"></param>
+		public bool Add(object element)
+		{
+			DoAdd(element);
+			Changed();
+			return true;
+		}
+
+		public void Prepend(object element)
+		{
+			DoPrepend(element);
+			Changed();
+		}
+
+		private void DoPrepend(object element)
+		{
+			if (_first == null)
+			{
+				DoAdd(element);
+			}
+			else
+			{
+				_first = new List4(_first, element);
+				_size++;
+			}
+		}
+
+		private void DoAdd(object element)
+		{
+			if (_last == null)
+			{
+				_first = new List4(element);
+				_last = _first;
+			}
+			else
+			{
+				_last._next = new List4(element);
+				_last = ((List4)_last._next);
+			}
+			_size++;
+		}
+
+		public void AddAll(object[] elements)
+		{
+			AssertNotNull(elements);
+			for (int i = 0; i < elements.Length; i++)
+			{
+				Add(elements[i]);
+			}
+		}
+
+		public void AddAll(IEnumerable other)
+		{
+			AssertNotNull(other);
+			AddAll(other.GetEnumerator());
+		}
+
+		public void AddAll(IEnumerator iterator)
+		{
+			AssertNotNull(iterator);
+			while (iterator.MoveNext())
+			{
+				Add(iterator.Current);
+			}
+		}
+
+		public void Clear()
+		{
+			_first = null;
+			_last = null;
+			_size = 0;
+			Changed();
+		}
+
+		public bool Contains(object element)
+		{
+			return Find(element) != null;
+		}
+
+		public virtual bool ContainsAll(IEnumerable iter)
+		{
+			return ContainsAll(iter.GetEnumerator());
+		}
+
+		public virtual bool ContainsAll(IEnumerator iter)
+		{
+			AssertNotNull(iter);
+			while (iter.MoveNext())
+			{
+				if (!Contains(iter.Current))
+				{
+					return false;
+				}
+			}
+			return true;
+		}
+
+		/// <summary>tests if the object is in the Collection.</summary>
+		/// <remarks>tests if the object is in the Collection. == comparison.</remarks>
+		public bool ContainsByIdentity(object element)
+		{
+			IEnumerator i = InternalIterator();
+			while (i.MoveNext())
+			{
+				object current = i.Current;
+				if (current == element)
+				{
+					return true;
+				}
+			}
+			return false;
+		}
+
+		private List4 Find(object obj)
+		{
+			List4 current = _first;
+			while (current != null)
+			{
+				if (current.Holds(obj))
+				{
+					return current;
+				}
+				current = ((List4)current._next);
+			}
+			return null;
+		}
+
+		private List4 FindByIdentity(object obj)
+		{
+			List4 current = _first;
+			while (current != null)
+			{
+				if (((object)current._element) == obj)
+				{
+					return current;
+				}
+				current = ((List4)current._next);
+			}
+			return null;
+		}
+
+		/// <summary>
+		/// returns the first object found in the Collections that equals() the
+		/// passed object
+		/// </summary>
+		public object Get(object element)
+		{
+			List4 holder = Find(element);
+			return holder == null ? null : ((object)holder._element);
+		}
+
+		public virtual object DeepClone(object newParent)
+		{
+			Db4objects.Db4o.Foundation.Collection4 col = new Db4objects.Db4o.Foundation.Collection4
+				();
+			object element = null;
+			IEnumerator i = InternalIterator();
+			while (i.MoveNext())
+			{
+				element = i.Current;
+				if (element is IDeepClone)
+				{
+					col.Add(((IDeepClone)element).DeepClone(newParent));
+				}
+				else
+				{
+					col.Add(element);
+				}
+			}
+			return col;
+		}
+
+		/// <summary>makes sure the passed object is in the Collection.</summary>
+		/// <remarks>makes sure the passed object is in the Collection. equals() comparison.</remarks>
+		public object Ensure(object element)
+		{
+			List4 list = Find(element);
+			if (list == null)
+			{
+				Add(element);
+				return element;
+			}
+			return ((object)list._element);
+		}
+
+		/// <summary>
+		/// Iterates through the collection in reversed insertion order which happens
+		/// to be the fastest.
+		/// </summary>
+		/// <remarks>
+		/// Iterates through the collection in reversed insertion order which happens
+		/// to be the fastest.
+		/// </remarks>
+		/// <returns></returns>
+		public IEnumerator GetEnumerator()
+		{
+			return _first == null ? Iterators.EmptyIterator : new Collection4Iterator(this, _first
+				);
+		}
+
+		public virtual object Get(int index)
+		{
+			if (index < 0)
+			{
+				throw new ArgumentException();
+			}
+			List4 cur = _first;
+			while (index > 0 && cur != null)
+			{
+				cur = ((List4)cur._next);
+				index--;
+			}
+			if (cur == null)
+			{
+				throw new ArgumentException();
+			}
+			return ((object)cur._element);
+		}
+
+		/// <summary>
+		/// Removes all the elements from this collection that are returned by
+		/// iterable.
+		/// </summary>
+		/// <remarks>
+		/// Removes all the elements from this collection that are returned by
+		/// iterable.
+		/// </remarks>
+		/// <param name="iterable"></param>
+		public virtual void RemoveAll(IEnumerable iterable)
+		{
+			RemoveAll(iterable.GetEnumerator());
+		}
+
+		/// <summary>
+		/// Removes all the elements from this collection that are returned by
+		/// iterator.
+		/// </summary>
+		/// <remarks>
+		/// Removes all the elements from this collection that are returned by
+		/// iterator.
+		/// </remarks>
+		public virtual void RemoveAll(IEnumerator iterator)
+		{
+			while (iterator.MoveNext())
+			{
+				Remove(iterator.Current);
+			}
+		}
+
+		/// <summary>
+		/// removes an object from the Collection equals() comparison returns the
+		/// removed object or null, if none found
+		/// </summary>
+		public virtual bool Remove(object a_object)
+		{
+			List4 previous = null;
+			List4 current = _first;
+			while (current != null)
+			{
+				if (current.Holds(a_object))
+				{
+					_size--;
+					AdjustOnRemoval(previous, current);
+					Changed();
+					return true;
+				}
+				previous = current;
+				current = ((List4)current._next);
+			}
+			return false;
+		}
+
+		public virtual void Replace(object oldObject, object newObject)
+		{
+			List4 list = Find(oldObject);
+			if (list != null)
+			{
+				list._element = newObject;
+			}
+		}
+
+		public virtual void ReplaceByIdentity(object oldObject, object newObject)
+		{
+			List4 list = FindByIdentity(oldObject);
+			if (list != null)
+			{
+				list._element = newObject;
+			}
+		}
+
+		private void AdjustOnRemoval(List4 previous, List4 removed)
+		{
+			if (removed == _first)
+			{
+				_first = ((List4)removed._next);
+			}
+			else
+			{
+				previous._next = ((List4)removed._next);
+			}
+			if (removed == _last)
+			{
+				_last = previous;
+			}
+		}
+
+		public int Size()
+		{
+			return _size;
+		}
+
+		public virtual int IndexOf(object obj)
+		{
+			int index = 0;
+			List4 current = _first;
+			while (current != null)
+			{
+				if (current.Holds(obj))
+				{
+					return index;
+				}
+				index++;
+				current = ((List4)current._next);
+			}
+			return -1;
+		}
+
+		public bool IsEmpty()
+		{
+			return _size == 0;
+		}
+
+		/// <summary>This is a non reflection implementation for more speed.</summary>
+		/// <remarks>
+		/// This is a non reflection implementation for more speed. In contrast to
+		/// the JDK behaviour, the passed array has to be initialized to the right
+		/// length.
+		/// </remarks>
+		public object[] ToArray(object[] array)
+		{
+			int j = 0;
+			IEnumerator i = InternalIterator();
+			while (i.MoveNext())
+			{
+				array[j++] = i.Current;
+			}
+			return array;
+		}
+
+		public object[] ToArray()
+		{
+			int j = 0;
+			object[] array = new object[Size()];
+			IEnumerator i = InternalIterator();
+			while (i.MoveNext())
+			{
+				array[j++] = i.Current;
+			}
+			return array;
+		}
+
+		public override string ToString()
+		{
+			return Iterators.ToString(InternalIterator());
+		}
+
+		private void Changed()
+		{
+			++_version;
+		}
+
+		internal virtual int Version()
+		{
+			return _version;
+		}
+
+		private void AssertNotNull(object element)
+		{
+			if (element == null)
+			{
+				throw new ArgumentNullException();
+			}
+		}
+
+		/// <summary>
+		/// Leaner iterator for faster iteration (but unprotected against
+		/// concurrent modifications).
+		/// </summary>
+		/// <remarks>
+		/// Leaner iterator for faster iteration (but unprotected against
+		/// concurrent modifications).
+		/// </remarks>
+		private IEnumerator InternalIterator()
+		{
+			return new Iterator4Impl(_first);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Collection4Iterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Collection4Iterator.cs
new file mode 100644
index 0000000..9db7d29
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Collection4Iterator.cs
@@ -0,0 +1,49 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class Collection4Iterator : Iterator4Impl
+	{
+		private readonly Collection4 _collection;
+
+		private readonly int _initialVersion;
+
+		public Collection4Iterator(Collection4 collection, List4 first) : base(first)
+		{
+			_collection = collection;
+			_initialVersion = CurrentVersion();
+		}
+
+		public override bool MoveNext()
+		{
+			Validate();
+			return base.MoveNext();
+		}
+
+		public override object Current
+		{
+			get
+			{
+				Validate();
+				return base.Current;
+			}
+		}
+
+		private void Validate()
+		{
+			if (_initialVersion != CurrentVersion())
+			{
+				// FIXME: change to ConcurrentModificationException
+				throw new InvalidIteratorException();
+			}
+		}
+
+		private int CurrentVersion()
+		{
+			return _collection.Version();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Collections4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Collections4.cs
new file mode 100644
index 0000000..a0c61ca
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Collections4.cs
@@ -0,0 +1,86 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class Collections4
+	{
+		public static ISequence4 UnmodifiableList(ISequence4 orig)
+		{
+			return new Collections4.UnmodifiableSequence4(orig);
+		}
+
+		private class UnmodifiableSequence4 : ISequence4
+		{
+			private ISequence4 _sequence;
+
+			public UnmodifiableSequence4(ISequence4 sequence)
+			{
+				_sequence = sequence;
+			}
+
+			public virtual bool Add(object element)
+			{
+				throw new NotSupportedException();
+			}
+
+			public virtual void AddAll(IEnumerable iterable)
+			{
+				throw new NotSupportedException();
+			}
+
+			public virtual bool IsEmpty()
+			{
+				return _sequence.IsEmpty();
+			}
+
+			public virtual IEnumerator GetEnumerator()
+			{
+				return _sequence.GetEnumerator();
+			}
+
+			public virtual object Get(int index)
+			{
+				return _sequence.Get(index);
+			}
+
+			public virtual int Size()
+			{
+				return _sequence.Size();
+			}
+
+			public virtual void Clear()
+			{
+				throw new NotSupportedException();
+			}
+
+			public virtual bool Remove(object obj)
+			{
+				throw new NotSupportedException();
+			}
+
+			public virtual bool Contains(object obj)
+			{
+				return _sequence.Contains(obj);
+			}
+
+			public virtual bool ContainsAll(IEnumerable iter)
+			{
+				return _sequence.ContainsAll(iter);
+			}
+
+			public virtual object[] ToArray()
+			{
+				return _sequence.ToArray();
+			}
+
+			public virtual object[] ToArray(object[] array)
+			{
+				return _sequence.ToArray(array);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/CompositeIterable4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/CompositeIterable4.cs
new file mode 100644
index 0000000..7e1d154
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/CompositeIterable4.cs
@@ -0,0 +1,34 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class CompositeIterable4 : IEnumerable
+	{
+		private readonly IEnumerable _iterables;
+
+		public CompositeIterable4(IEnumerable iterables)
+		{
+			_iterables = iterables;
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			return new _CompositeIterator4_15(_iterables.GetEnumerator());
+		}
+
+		private sealed class _CompositeIterator4_15 : CompositeIterator4
+		{
+			public _CompositeIterator4_15(IEnumerator baseArg1) : base(baseArg1)
+			{
+			}
+
+			protected override IEnumerator NextIterator(object current)
+			{
+				return ((IEnumerable)current).GetEnumerator();
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/CompositeIterator4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/CompositeIterator4.cs
new file mode 100644
index 0000000..85e13cf
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/CompositeIterator4.cs
@@ -0,0 +1,81 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class CompositeIterator4 : IEnumerator
+	{
+		protected readonly IEnumerator _iterators;
+
+		protected IEnumerator _currentIterator;
+
+		public CompositeIterator4(IEnumerator[] iterators) : this(new ArrayIterator4(iterators
+			))
+		{
+		}
+
+		public CompositeIterator4(IEnumerator iterators)
+		{
+			if (null == iterators)
+			{
+				throw new ArgumentNullException();
+			}
+			_iterators = iterators;
+		}
+
+		public virtual bool MoveNext()
+		{
+			if (null == _currentIterator)
+			{
+				if (!_iterators.MoveNext())
+				{
+					return false;
+				}
+				_currentIterator = NextIterator(_iterators.Current);
+			}
+			if (!_currentIterator.MoveNext())
+			{
+				_currentIterator = null;
+				return MoveNext();
+			}
+			return true;
+		}
+
+		public virtual void Reset()
+		{
+			ResetIterators();
+			_currentIterator = null;
+			_iterators.Reset();
+		}
+
+		private void ResetIterators()
+		{
+			_iterators.Reset();
+			while (_iterators.MoveNext())
+			{
+				NextIterator(_iterators.Current).Reset();
+			}
+		}
+
+		public virtual IEnumerator CurrentIterator()
+		{
+			return _currentIterator;
+		}
+
+		public virtual object Current
+		{
+			get
+			{
+				return _currentIterator.Current;
+			}
+		}
+
+		protected virtual IEnumerator NextIterator(object current)
+		{
+			return (IEnumerator)current;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/DelegatingBlockingQueue.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/DelegatingBlockingQueue.cs
new file mode 100644
index 0000000..8049180
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/DelegatingBlockingQueue.cs
@@ -0,0 +1,58 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class DelegatingBlockingQueue : IBlockingQueue4
+	{
+		private IBlockingQueue4 queue;
+
+		/// <exception cref="Db4objects.Db4o.Foundation.BlockingQueueStoppedException"></exception>
+		public virtual object Next(long timeout)
+		{
+			return queue.Next(timeout);
+		}
+
+		public virtual object Next()
+		{
+			return queue.Next();
+		}
+
+		public virtual void Add(object obj)
+		{
+			queue.Add(obj);
+		}
+
+		public virtual bool HasNext()
+		{
+			return queue.HasNext();
+		}
+
+		public virtual object NextMatching(IPredicate4 condition)
+		{
+			return queue.NextMatching(condition);
+		}
+
+		public virtual IEnumerator Iterator()
+		{
+			return queue.Iterator();
+		}
+
+		public DelegatingBlockingQueue(IBlockingQueue4 queue)
+		{
+			this.queue = queue;
+		}
+
+		public virtual void Stop()
+		{
+			queue.Stop();
+		}
+
+		public virtual int DrainTo(Collection4 list)
+		{
+			return queue.DrainTo(list);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/DynamicVariable.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/DynamicVariable.cs
new file mode 100644
index 0000000..d5e0099
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/DynamicVariable.cs
@@ -0,0 +1,71 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>A dynamic variable is a value associated to a specific thread and scope.
+	/// 	</summary>
+	/// <remarks>
+	/// A dynamic variable is a value associated to a specific thread and scope.
+	/// The value is brought into scope with the
+	/// <see cref="With(object, IClosure4)">With(object, IClosure4)</see>
+	/// method.
+	/// </remarks>
+	public class DynamicVariable
+	{
+		public static DynamicVariable NewInstance()
+		{
+			return new DynamicVariable();
+		}
+
+		private readonly ThreadLocal _value = new ThreadLocal();
+
+		public virtual object Value
+		{
+			get
+			{
+				object value = _value.Get();
+				return value == null ? DefaultValue() : value;
+			}
+			set
+			{
+				_value.Set(value);
+			}
+		}
+
+		protected virtual object DefaultValue()
+		{
+			return null;
+		}
+
+		public virtual object With(object value, IClosure4 block)
+		{
+			object previous = _value.Get();
+			_value.Set(value);
+			try
+			{
+				return block.Run();
+			}
+			finally
+			{
+				_value.Set(previous);
+			}
+		}
+
+		public virtual void With(object value, IRunnable block)
+		{
+			object previous = _value.Get();
+			_value.Set(value);
+			try
+			{
+				block.Run();
+			}
+			finally
+			{
+				_value.Set(previous);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/EnumerateIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/EnumerateIterator.cs
new file mode 100644
index 0000000..c12f435
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/EnumerateIterator.cs
@@ -0,0 +1,45 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class EnumerateIterator : MappingIterator
+	{
+		public sealed class Tuple
+		{
+			public readonly int index;
+
+			public readonly object value;
+
+			public Tuple(int index_, object value_)
+			{
+				index = index_;
+				value = value_;
+			}
+		}
+
+		private int _index;
+
+		public EnumerateIterator(IEnumerator iterator) : base(iterator)
+		{
+			_index = 0;
+		}
+
+		public override bool MoveNext()
+		{
+			if (base.MoveNext())
+			{
+				++_index;
+				return true;
+			}
+			return false;
+		}
+
+		protected override object Map(object current)
+		{
+			return new EnumerateIterator.Tuple(_index, current);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Environments.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Environments.cs
new file mode 100644
index 0000000..6dbadc0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Environments.cs
@@ -0,0 +1,165 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public partial class Environments
+	{
+		private static readonly DynamicVariable _current = DynamicVariable.NewInstance();
+
+		public static object My(Type service)
+		{
+			IEnvironment environment = Current();
+			if (null == environment)
+			{
+				throw new InvalidOperationException();
+			}
+			return environment.Provide(service);
+		}
+
+		private static IEnvironment Current()
+		{
+			return ((IEnvironment)_current.Value);
+		}
+
+		public static void RunWith(IEnvironment environment, IRunnable runnable)
+		{
+			_current.With(environment, runnable);
+		}
+
+		public static IEnvironment NewClosedEnvironment(object[] bindings)
+		{
+			return new _IEnvironment_32(bindings);
+		}
+
+		private sealed class _IEnvironment_32 : IEnvironment
+		{
+			public _IEnvironment_32(object[] bindings)
+			{
+				this.bindings = bindings;
+			}
+
+			public object Provide(Type service)
+			{
+				for (int bindingIndex = 0; bindingIndex < bindings.Length; ++bindingIndex)
+				{
+					object binding = bindings[bindingIndex];
+					if (service.IsInstanceOfType(binding))
+					{
+						return (object)binding;
+					}
+				}
+				return null;
+			}
+
+			private readonly object[] bindings;
+		}
+
+		public static IEnvironment NewCachingEnvironmentFor(IEnvironment environment)
+		{
+			return new _IEnvironment_48(environment);
+		}
+
+		private sealed class _IEnvironment_48 : IEnvironment
+		{
+			public _IEnvironment_48(IEnvironment environment)
+			{
+				this.environment = environment;
+				this._bindings = new Hashtable();
+			}
+
+			private readonly IDictionary _bindings;
+
+			public object Provide(Type service)
+			{
+				object existing = this._bindings[service];
+				if (null != existing)
+				{
+					return (object)existing;
+				}
+				object binding = environment.Provide(service);
+				if (null == binding)
+				{
+					return null;
+				}
+				this._bindings[service] = binding;
+				return binding;
+			}
+
+			private readonly IEnvironment environment;
+		}
+
+		public static IEnvironment NewConventionBasedEnvironment(object[] bindings)
+		{
+			return NewCachingEnvironmentFor(Compose(new IEnvironment[] { NewClosedEnvironment
+				(bindings), new Environments.ConventionBasedEnvironment() }));
+		}
+
+		public static IEnvironment NewConventionBasedEnvironment()
+		{
+			return NewCachingEnvironmentFor(new Environments.ConventionBasedEnvironment());
+		}
+
+		public static IEnvironment Compose(IEnvironment[] environments)
+		{
+			return new _IEnvironment_75(environments);
+		}
+
+		private sealed class _IEnvironment_75 : IEnvironment
+		{
+			public _IEnvironment_75(IEnvironment[] environments)
+			{
+				this.environments = environments;
+			}
+
+			public object Provide(Type service)
+			{
+				for (int eIndex = 0; eIndex < environments.Length; ++eIndex)
+				{
+					IEnvironment e = environments[eIndex];
+					object binding = e.Provide(service);
+					if (null != binding)
+					{
+						return binding;
+					}
+				}
+				return null;
+			}
+
+			private readonly IEnvironment[] environments;
+		}
+
+		private sealed class ConventionBasedEnvironment : IEnvironment
+		{
+			public object Provide(Type service)
+			{
+				return Resolve(service);
+			}
+
+			/// <summary>
+			/// Resolves a service interface to its default implementation using the
+			/// db4o namespace convention:
+			/// interface foo.bar.Baz
+			/// default implementation foo.internal.bar.BazImpl
+			/// </summary>
+			/// <returns>the convention based type name for the requested service</returns>
+			private object Resolve(Type service)
+			{
+				string className = DefaultImplementationFor(service);
+				object binding = ReflectPlatform.CreateInstance(className);
+				if (null == binding)
+				{
+					throw new ArgumentException("Cant find default implementation for " + service.ToString
+						() + ": " + className);
+				}
+				return (object)binding;
+			}
+		}
+		// ignore convention for internal types
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/FilteredIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/FilteredIterator.cs
new file mode 100644
index 0000000..72d55c3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/FilteredIterator.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class FilteredIterator : MappingIterator
+	{
+		private readonly IPredicate4 _filter;
+
+		public FilteredIterator(IEnumerator iterator, IPredicate4 filter) : base(iterator
+			)
+		{
+			_filter = filter;
+		}
+
+		protected override object Map(object current)
+		{
+			return _filter.Match(current) ? current : Iterators.Skip;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/FlatteningIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/FlatteningIterator.cs
new file mode 100644
index 0000000..a5a4aa6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/FlatteningIterator.cs
@@ -0,0 +1,74 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class FlatteningIterator : CompositeIterator4
+	{
+		private class IteratorStack
+		{
+			public readonly IEnumerator iterator;
+
+			public readonly FlatteningIterator.IteratorStack next;
+
+			public IteratorStack(IEnumerator iterator_, FlatteningIterator.IteratorStack next_
+				)
+			{
+				iterator = iterator_;
+				next = next_;
+			}
+		}
+
+		private FlatteningIterator.IteratorStack _stack;
+
+		public FlatteningIterator(IEnumerator iterators) : base(iterators)
+		{
+		}
+
+		public override bool MoveNext()
+		{
+			if (null == _currentIterator)
+			{
+				if (null == _stack)
+				{
+					_currentIterator = _iterators;
+				}
+				else
+				{
+					_currentIterator = Pop();
+				}
+			}
+			if (!_currentIterator.MoveNext())
+			{
+				if (_currentIterator == _iterators)
+				{
+					return false;
+				}
+				_currentIterator = null;
+				return MoveNext();
+			}
+			object current = _currentIterator.Current;
+			if (current is IEnumerator)
+			{
+				Push(_currentIterator);
+				_currentIterator = NextIterator(current);
+				return MoveNext();
+			}
+			return true;
+		}
+
+		private void Push(IEnumerator currentIterator)
+		{
+			_stack = new FlatteningIterator.IteratorStack(currentIterator, _stack);
+		}
+
+		private IEnumerator Pop()
+		{
+			IEnumerator iterator = _stack.iterator;
+			_stack = _stack.next;
+			return iterator;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/FunctionApplicationIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/FunctionApplicationIterator.cs
new file mode 100644
index 0000000..ea8dd95
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/FunctionApplicationIterator.cs
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class FunctionApplicationIterator : MappingIterator
+	{
+		private readonly IFunction4 _function;
+
+		public FunctionApplicationIterator(IEnumerator iterator, IFunction4 function) : base
+			(iterator)
+		{
+			if (null == function)
+			{
+				throw new ArgumentNullException();
+			}
+			_function = function;
+		}
+
+		protected override object Map(object current)
+		{
+			return _function.Apply(current);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashSet4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashSet4.cs
new file mode 100644
index 0000000..f44ed97
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashSet4.cs
@@ -0,0 +1,66 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class HashSet4 : ISet4
+	{
+		private Hashtable4 _map;
+
+		public HashSet4() : this(1)
+		{
+		}
+
+		public HashSet4(int count)
+		{
+			_map = new Hashtable4(count);
+		}
+
+		public virtual bool Add(object obj)
+		{
+			if (_map.ContainsKey(obj))
+			{
+				return false;
+			}
+			_map.Put(obj, obj);
+			return true;
+		}
+
+		public virtual void Clear()
+		{
+			_map.Clear();
+		}
+
+		public virtual bool Contains(object obj)
+		{
+			return _map.ContainsKey(obj);
+		}
+
+		public virtual bool IsEmpty()
+		{
+			return _map.Size() == 0;
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			return _map.Values().GetEnumerator();
+		}
+
+		public virtual bool Remove(object obj)
+		{
+			return _map.Remove(obj) != null;
+		}
+
+		public virtual int Size()
+		{
+			return _map.Size();
+		}
+
+		public override string ToString()
+		{
+			return Iterators.Join(_map.Keys(), "{", "}", ", ");
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Hashtable4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Hashtable4.cs
new file mode 100644
index 0000000..7f36dae
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Hashtable4.cs
@@ -0,0 +1,231 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class Hashtable4 : HashtableBase, IDeepClone, IMap4
+	{
+		public Hashtable4(int size) : base(size)
+		{
+		}
+
+		public Hashtable4() : this(1)
+		{
+		}
+
+		/// <param name="cloneOnlyCtor"></param>
+		protected Hashtable4(IDeepClone cloneOnlyCtor) : base(cloneOnlyCtor)
+		{
+		}
+
+		public virtual object DeepClone(object obj)
+		{
+			return DeepCloneInternal(new Db4objects.Db4o.Foundation.Hashtable4((IDeepClone)null
+				), obj);
+		}
+
+		public virtual void ForEachKeyForIdentity(IVisitor4 visitor, object obj)
+		{
+			for (int i = 0; i < _table.Length; i++)
+			{
+				HashtableIntEntry entry = _table[i];
+				while (entry != null)
+				{
+					if (entry._object == obj)
+					{
+						visitor.Visit(entry.Key());
+					}
+					entry = entry._next;
+				}
+			}
+		}
+
+		public virtual object Get(byte[] key)
+		{
+			int intKey = HashtableByteArrayEntry.Hash(key);
+			return GetFromObjectEntry(intKey, key);
+		}
+
+		public virtual object Get(int key)
+		{
+			HashtableIntEntry entry = _table[key & _mask];
+			while (entry != null)
+			{
+				if (entry._key == key)
+				{
+					return entry._object;
+				}
+				entry = entry._next;
+			}
+			return null;
+		}
+
+		public virtual object Get(object key)
+		{
+			if (key == null)
+			{
+				return null;
+			}
+			return GetFromObjectEntry(key.GetHashCode(), key);
+		}
+
+		public virtual object Get(long key)
+		{
+			return GetFromLongEntry((int)key, key);
+		}
+
+		public virtual bool ContainsKey(object key)
+		{
+			if (null == key)
+			{
+				return false;
+			}
+			return null != GetObjectEntry(key.GetHashCode(), key);
+		}
+
+		public virtual bool ContainsAllKeys(IEnumerable collection)
+		{
+			return ContainsAllKeys(collection.GetEnumerator());
+		}
+
+		public virtual bool ContainsAllKeys(IEnumerator iterator)
+		{
+			while (iterator.MoveNext())
+			{
+				if (!ContainsKey(iterator.Current))
+				{
+					return false;
+				}
+			}
+			return true;
+		}
+
+		public virtual void Put(byte[] key, object value)
+		{
+			PutEntry(new HashtableByteArrayEntry(key, value));
+		}
+
+		public virtual void Put(int key, object value)
+		{
+			PutEntry(new HashtableIntEntry(key, value));
+		}
+
+		public virtual void Put(long key, object value)
+		{
+			PutEntry(new HashtableLongEntry(key, value));
+		}
+
+		public virtual void Put(object key, object value)
+		{
+			if (null == key)
+			{
+				throw new ArgumentNullException();
+			}
+			PutEntry(new HashtableObjectEntry(key, value));
+		}
+
+		public virtual object Remove(object objectKey)
+		{
+			int intKey = objectKey.GetHashCode();
+			return RemoveObjectEntry(intKey, objectKey);
+		}
+
+		public virtual object Remove(long longKey)
+		{
+			return RemoveLongEntry((int)longKey, longKey);
+		}
+
+		public virtual object Remove(byte[] key)
+		{
+			int intKey = HashtableByteArrayEntry.Hash(key);
+			return RemoveObjectEntry(intKey, key);
+		}
+
+		public virtual object Remove(int key)
+		{
+			return RemoveIntEntry(key);
+		}
+
+		/// <summary>
+		/// Iterates through all the
+		/// <see cref="IEntry4">entries</see>
+		/// .
+		/// </summary>
+		/// <returns>
+		/// 
+		/// <see cref="IEntry4">IEntry4</see>
+		/// iterator
+		/// </returns>
+		/// <seealso cref="HashtableBase.Values()">HashtableBase.Values()</seealso>
+		/// <seealso cref="HashtableBase.Keys()">
+		/// #see
+		/// <see cref="HashtableBase.ValuesIterator()">HashtableBase.ValuesIterator()</see>
+		/// </seealso>
+		public virtual IEnumerator Iterator()
+		{
+			return HashtableIterator();
+		}
+
+		protected virtual Db4objects.Db4o.Foundation.Hashtable4 DeepCloneInternal(Db4objects.Db4o.Foundation.Hashtable4
+			 ret, object obj)
+		{
+			ret._mask = _mask;
+			ret._maximumSize = _maximumSize;
+			ret._size = _size;
+			ret._tableSize = _tableSize;
+			ret._table = new HashtableIntEntry[_tableSize];
+			for (int i = 0; i < _tableSize; i++)
+			{
+				if (_table[i] != null)
+				{
+					ret._table[i] = (HashtableIntEntry)_table[i].DeepClone(obj);
+				}
+			}
+			return ret;
+		}
+
+		private object GetFromObjectEntry(int intKey, object objectKey)
+		{
+			HashtableObjectEntry entry = GetObjectEntry(intKey, objectKey);
+			return entry == null ? null : entry._object;
+		}
+
+		private HashtableObjectEntry GetObjectEntry(int intKey, object objectKey)
+		{
+			HashtableObjectEntry entry = (HashtableObjectEntry)_table[intKey & _mask];
+			while (entry != null)
+			{
+				if (entry._key == intKey && entry.HasKey(objectKey))
+				{
+					return entry;
+				}
+				entry = (HashtableObjectEntry)entry._next;
+			}
+			return null;
+		}
+
+		private object GetFromLongEntry(int intKey, long longKey)
+		{
+			HashtableLongEntry entry = GetLongEntry(intKey, longKey);
+			return entry == null ? null : entry._object;
+		}
+
+		private HashtableLongEntry GetLongEntry(int intKey, long longKey)
+		{
+			HashtableLongEntry entry = (HashtableLongEntry)_table[intKey & _mask];
+			while (entry != null)
+			{
+				if (entry._key == intKey && entry._longKey == longKey)
+				{
+					return entry;
+				}
+				entry = (HashtableLongEntry)entry._next;
+			}
+			return null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableBase.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableBase.cs
new file mode 100644
index 0000000..b134af0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableBase.cs
@@ -0,0 +1,284 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class HashtableBase
+	{
+		private const float Fill = 0.5F;
+
+		public int _tableSize;
+
+		public int _mask;
+
+		public int _maximumSize;
+
+		public int _size;
+
+		public HashtableIntEntry[] _table;
+
+		public HashtableBase(int size)
+		{
+			// FIELDS ARE PUBLIC SO THEY CAN BE REFLECTED ON IN JDKs <= 1.1
+			size = NewSize(size);
+			// legacy for .NET conversion
+			_tableSize = 1;
+			while (_tableSize < size)
+			{
+				_tableSize = _tableSize << 1;
+			}
+			_mask = _tableSize - 1;
+			_maximumSize = (int)(_tableSize * Fill);
+			_table = new HashtableIntEntry[_tableSize];
+		}
+
+		public HashtableBase() : this(1)
+		{
+		}
+
+		/// <param name="cloneOnlyCtor"></param>
+		protected HashtableBase(IDeepClone cloneOnlyCtor)
+		{
+		}
+
+		public virtual void Clear()
+		{
+			_size = 0;
+			Arrays4.Fill(_table, null);
+		}
+
+		private int NewSize(int size)
+		{
+			return (int)(size / Fill);
+		}
+
+		public virtual int Size()
+		{
+			return _size;
+		}
+
+		protected virtual HashtableIntEntry FindWithSameKey(HashtableIntEntry newEntry)
+		{
+			HashtableIntEntry existing = _table[EntryIndex(newEntry)];
+			while (null != existing)
+			{
+				if (existing.SameKeyAs(newEntry))
+				{
+					return existing;
+				}
+				existing = existing._next;
+			}
+			return null;
+		}
+
+		protected virtual int EntryIndex(HashtableIntEntry entry)
+		{
+			return entry._key & _mask;
+		}
+
+		protected virtual void PutEntry(HashtableIntEntry newEntry)
+		{
+			HashtableIntEntry existing = FindWithSameKey(newEntry);
+			if (null != existing)
+			{
+				Replace(existing, newEntry);
+			}
+			else
+			{
+				Insert(newEntry);
+			}
+		}
+
+		private void Insert(HashtableIntEntry newEntry)
+		{
+			_size++;
+			if (_size > _maximumSize)
+			{
+				IncreaseSize();
+			}
+			int index = EntryIndex(newEntry);
+			newEntry._next = _table[index];
+			_table[index] = newEntry;
+		}
+
+		private void Replace(HashtableIntEntry existing, HashtableIntEntry newEntry)
+		{
+			newEntry._next = existing._next;
+			HashtableIntEntry entry = _table[EntryIndex(existing)];
+			if (entry == existing)
+			{
+				_table[EntryIndex(existing)] = newEntry;
+			}
+			else
+			{
+				while (entry._next != existing)
+				{
+					entry = entry._next;
+				}
+				entry._next = newEntry;
+			}
+		}
+
+		private void IncreaseSize()
+		{
+			_tableSize = _tableSize << 1;
+			_maximumSize = _maximumSize << 1;
+			_mask = _tableSize - 1;
+			HashtableIntEntry[] temp = _table;
+			_table = new HashtableIntEntry[_tableSize];
+			for (int i = 0; i < temp.Length; i++)
+			{
+				Reposition(temp[i]);
+			}
+		}
+
+		protected virtual Db4objects.Db4o.Foundation.HashtableIterator HashtableIterator(
+			)
+		{
+			return new Db4objects.Db4o.Foundation.HashtableIterator(_table);
+		}
+
+		private void Reposition(HashtableIntEntry entry)
+		{
+			HashtableIntEntry currentEntry = entry;
+			HashtableIntEntry nextEntry = null;
+			while (currentEntry != null)
+			{
+				nextEntry = currentEntry._next;
+				currentEntry._next = _table[EntryIndex(currentEntry)];
+				_table[EntryIndex(currentEntry)] = currentEntry;
+				currentEntry = nextEntry;
+			}
+		}
+
+		public virtual IEnumerator Keys()
+		{
+			return Iterators.Map(HashtableIterator(), new _IFunction4_133());
+		}
+
+		private sealed class _IFunction4_133 : IFunction4
+		{
+			public _IFunction4_133()
+			{
+			}
+
+			public object Apply(object current)
+			{
+				return ((IEntry4)current).Key();
+			}
+		}
+
+		public virtual IEnumerable Values()
+		{
+			return new _IEnumerable_141(this);
+		}
+
+		private sealed class _IEnumerable_141 : IEnumerable
+		{
+			public _IEnumerable_141(HashtableBase _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public IEnumerator GetEnumerator()
+			{
+				return this._enclosing.ValuesIterator();
+			}
+
+			private readonly HashtableBase _enclosing;
+		}
+
+		/// <summary>Iterates through all the values.</summary>
+		/// <remarks>Iterates through all the values.</remarks>
+		/// <returns>value iterator</returns>
+		public virtual IEnumerator ValuesIterator()
+		{
+			return Iterators.Map(HashtableIterator(), new _IFunction4_154());
+		}
+
+		private sealed class _IFunction4_154 : IFunction4
+		{
+			public _IFunction4_154()
+			{
+			}
+
+			public object Apply(object current)
+			{
+				return ((IEntry4)current).Value();
+			}
+		}
+
+		public override string ToString()
+		{
+			return Iterators.Join(HashtableIterator(), "{", "}", ", ");
+		}
+
+		protected virtual void RemoveEntry(HashtableIntEntry predecessor, HashtableIntEntry
+			 entry)
+		{
+			if (predecessor != null)
+			{
+				predecessor._next = entry._next;
+			}
+			else
+			{
+				_table[EntryIndex(entry)] = entry._next;
+			}
+			_size--;
+		}
+
+		protected virtual object RemoveObjectEntry(int intKey, object objectKey)
+		{
+			HashtableObjectEntry entry = (HashtableObjectEntry)_table[intKey & _mask];
+			HashtableObjectEntry predecessor = null;
+			while (entry != null)
+			{
+				if (entry._key == intKey && entry.HasKey(objectKey))
+				{
+					RemoveEntry(predecessor, entry);
+					return entry._object;
+				}
+				predecessor = entry;
+				entry = (HashtableObjectEntry)entry._next;
+			}
+			return null;
+		}
+
+		protected virtual object RemoveLongEntry(int intKey, long longKey)
+		{
+			HashtableLongEntry entry = (HashtableLongEntry)_table[intKey & _mask];
+			HashtableLongEntry predecessor = null;
+			while (entry != null)
+			{
+				if (entry._key == intKey && entry._longKey == longKey)
+				{
+					RemoveEntry(predecessor, entry);
+					return entry._object;
+				}
+				predecessor = entry;
+				entry = (HashtableLongEntry)entry._next;
+			}
+			return null;
+		}
+
+		protected virtual object RemoveIntEntry(int key)
+		{
+			HashtableIntEntry entry = _table[key & _mask];
+			HashtableIntEntry predecessor = null;
+			while (entry != null)
+			{
+				if (entry._key == key)
+				{
+					RemoveEntry(predecessor, entry);
+					return entry._object;
+				}
+				predecessor = entry;
+				entry = entry._next;
+			}
+			return null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableByteArrayEntry.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableByteArrayEntry.cs
new file mode 100644
index 0000000..95b2b25
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableByteArrayEntry.cs
@@ -0,0 +1,59 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	internal class HashtableByteArrayEntry : HashtableObjectEntry
+	{
+		public HashtableByteArrayEntry(byte[] bytes, object value) : base(Hash(bytes), bytes
+			, value)
+		{
+		}
+
+		public HashtableByteArrayEntry() : base()
+		{
+		}
+
+		public override object DeepClone(object obj)
+		{
+			return DeepCloneInternal(new Db4objects.Db4o.Foundation.HashtableByteArrayEntry()
+				, obj);
+		}
+
+		public override bool HasKey(object key)
+		{
+			if (key is byte[])
+			{
+				return AreEqual((byte[])Key(), (byte[])key);
+			}
+			return false;
+		}
+
+		internal static int Hash(byte[] bytes)
+		{
+			int ret = 0;
+			for (int i = 0; i < bytes.Length; i++)
+			{
+				ret = ret * 31 + bytes[i];
+			}
+			return ret;
+		}
+
+		internal static bool AreEqual(byte[] lhs, byte[] rhs)
+		{
+			if (rhs.Length != lhs.Length)
+			{
+				return false;
+			}
+			for (int i = 0; i < rhs.Length; i++)
+			{
+				if (rhs[i] != lhs[i])
+				{
+					return false;
+				}
+			}
+			return true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableIdentityEntry.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableIdentityEntry.cs
new file mode 100644
index 0000000..6b4bc3e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableIdentityEntry.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Sharpen;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class HashtableIdentityEntry : HashtableIntEntry
+	{
+		public HashtableIdentityEntry(object obj) : base(Runtime.IdentityHashCode(obj), obj
+			)
+		{
+		}
+
+		public override bool SameKeyAs(HashtableIntEntry other)
+		{
+			if (!base.SameKeyAs(other))
+			{
+				return false;
+			}
+			return other._object == _object;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableIntEntry.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableIntEntry.cs
new file mode 100644
index 0000000..d378f13
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableIntEntry.cs
@@ -0,0 +1,72 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class HashtableIntEntry : IEntry4, IDeepClone
+	{
+		public int _key;
+
+		public object _object;
+
+		public Db4objects.Db4o.Foundation.HashtableIntEntry _next;
+
+		internal HashtableIntEntry(int key, object obj)
+		{
+			// FIELDS ARE PUBLIC SO THEY CAN BE REFLECTED ON IN JDKs <= 1.1
+			_key = key;
+			_object = obj;
+		}
+
+		public HashtableIntEntry()
+		{
+		}
+
+		public virtual object Key()
+		{
+			return _key;
+		}
+
+		public virtual object Value()
+		{
+			return _object;
+		}
+
+		public virtual object DeepClone(object obj)
+		{
+			return DeepCloneInternal(new Db4objects.Db4o.Foundation.HashtableIntEntry(), obj);
+		}
+
+		public virtual bool SameKeyAs(Db4objects.Db4o.Foundation.HashtableIntEntry other)
+		{
+			return _key == other._key;
+		}
+
+		protected virtual Db4objects.Db4o.Foundation.HashtableIntEntry DeepCloneInternal(
+			Db4objects.Db4o.Foundation.HashtableIntEntry entry, object obj)
+		{
+			entry._key = _key;
+			entry._next = _next;
+			if (_object is IDeepClone)
+			{
+				entry._object = ((IDeepClone)_object).DeepClone(obj);
+			}
+			else
+			{
+				entry._object = _object;
+			}
+			if (_next != null)
+			{
+				entry._next = (Db4objects.Db4o.Foundation.HashtableIntEntry)_next.DeepClone(obj);
+			}
+			return entry;
+		}
+
+		public override string ToString()
+		{
+			return string.Empty + _key + ": " + _object;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableIterator.cs
new file mode 100644
index 0000000..708e9ff
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableIterator.cs
@@ -0,0 +1,83 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class HashtableIterator : IEnumerator
+	{
+		private readonly HashtableIntEntry[] _table;
+
+		private HashtableIntEntry _currentEntry;
+
+		private int _currentIndex;
+
+		public HashtableIterator(HashtableIntEntry[] table)
+		{
+			_table = table;
+			Reset();
+		}
+
+		private void CheckInvalidTable()
+		{
+			if (_table == null || _table.Length == 0)
+			{
+				PositionBeyondLast();
+			}
+		}
+
+		public virtual object Current
+		{
+			get
+			{
+				if (_currentEntry == null)
+				{
+					throw new InvalidOperationException();
+				}
+				return _currentEntry;
+			}
+		}
+
+		public virtual bool MoveNext()
+		{
+			if (IsBeyondLast())
+			{
+				return false;
+			}
+			if (_currentEntry != null)
+			{
+				_currentEntry = _currentEntry._next;
+			}
+			while (_currentEntry == null)
+			{
+				if (_currentIndex >= _table.Length)
+				{
+					PositionBeyondLast();
+					return false;
+				}
+				_currentEntry = _table[_currentIndex++];
+			}
+			return true;
+		}
+
+		public virtual void Reset()
+		{
+			_currentEntry = null;
+			_currentIndex = 0;
+			CheckInvalidTable();
+		}
+
+		private bool IsBeyondLast()
+		{
+			return _currentIndex == -1;
+		}
+
+		private void PositionBeyondLast()
+		{
+			_currentIndex = -1;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableLongEntry.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableLongEntry.cs
new file mode 100644
index 0000000..a3ea415
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableLongEntry.cs
@@ -0,0 +1,51 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class HashtableLongEntry : HashtableIntEntry
+	{
+		public long _longKey;
+
+		internal HashtableLongEntry(long key, object obj) : base((int)key, obj)
+		{
+			// FIELDS ARE PUBLIC SO THEY CAN BE REFLECTED ON IN JDKs <= 1.1
+			_longKey = key;
+		}
+
+		public HashtableLongEntry() : base()
+		{
+		}
+
+		public override object Key()
+		{
+			return _longKey;
+		}
+
+		public override object DeepClone(object obj)
+		{
+			return DeepCloneInternal(new Db4objects.Db4o.Foundation.HashtableLongEntry(), obj
+				);
+		}
+
+		protected override HashtableIntEntry DeepCloneInternal(HashtableIntEntry entry, object
+			 obj)
+		{
+			((Db4objects.Db4o.Foundation.HashtableLongEntry)entry)._longKey = _longKey;
+			return base.DeepCloneInternal(entry, obj);
+		}
+
+		public override bool SameKeyAs(HashtableIntEntry other)
+		{
+			return other is Db4objects.Db4o.Foundation.HashtableLongEntry ? ((Db4objects.Db4o.Foundation.HashtableLongEntry
+				)other)._longKey == _longKey : false;
+		}
+
+		public override string ToString()
+		{
+			return string.Empty + _longKey + ": " + _object;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableObjectEntry.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableObjectEntry.cs
new file mode 100644
index 0000000..acdb717
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/HashtableObjectEntry.cs
@@ -0,0 +1,63 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class HashtableObjectEntry : HashtableIntEntry
+	{
+		public object _objectKey;
+
+		internal HashtableObjectEntry(int a_hash, object a_key, object a_object) : base(a_hash
+			, a_object)
+		{
+			// FIELDS ARE PUBLIC SO THEY CAN BE REFLECTED ON IN JDKs <= 1.1
+			_objectKey = a_key;
+		}
+
+		internal HashtableObjectEntry(object a_key, object a_object) : base(a_key.GetHashCode
+			(), a_object)
+		{
+			_objectKey = a_key;
+		}
+
+		public HashtableObjectEntry() : base()
+		{
+		}
+
+		public override object Key()
+		{
+			return _objectKey;
+		}
+
+		public override object DeepClone(object obj)
+		{
+			return DeepCloneInternal(new Db4objects.Db4o.Foundation.HashtableObjectEntry(), obj
+				);
+		}
+
+		protected override HashtableIntEntry DeepCloneInternal(HashtableIntEntry entry, object
+			 obj)
+		{
+			((Db4objects.Db4o.Foundation.HashtableObjectEntry)entry)._objectKey = _objectKey;
+			return base.DeepCloneInternal(entry, obj);
+		}
+
+		public virtual bool HasKey(object key)
+		{
+			return _objectKey.Equals(key);
+		}
+
+		public override bool SameKeyAs(HashtableIntEntry other)
+		{
+			return other is Db4objects.Db4o.Foundation.HashtableObjectEntry ? HasKey(((Db4objects.Db4o.Foundation.HashtableObjectEntry
+				)other)._objectKey) : false;
+		}
+
+		public override string ToString()
+		{
+			return string.Empty + _objectKey + ": " + _object;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IArrayFactory.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IArrayFactory.cs
new file mode 100644
index 0000000..66fd62b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IArrayFactory.cs
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	public interface IArrayFactory
+	{
+		object[] NewArray(int size);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IBlock4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IBlock4.cs
new file mode 100644
index 0000000..09f4b6b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IBlock4.cs
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	public interface IBlock4
+	{
+		void Run();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IBlockingQueue4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IBlockingQueue4.cs
new file mode 100644
index 0000000..f3de098
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IBlockingQueue4.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public interface IBlockingQueue4 : IQueue4
+	{
+		/// <summary>
+		/// <p>
+		/// Returns the next queued item or waits for it to be available for the
+		/// maximum of <code>timeout</code> miliseconds.
+		/// </summary>
+		/// <remarks>
+		/// <p>
+		/// Returns the next queued item or waits for it to be available for the
+		/// maximum of <code>timeout</code> miliseconds.
+		/// </remarks>
+		/// <param name="timeout">maximum time to wait for the next avilable item in miliseconds
+		/// 	</param>
+		/// <returns>
+		/// the next item or <code>null</code> if <code>timeout</code> is
+		/// reached
+		/// </returns>
+		/// <exception cref="BlockingQueueStoppedException">
+		/// if the
+		/// <see cref="Stop()">Stop()</see>
+		/// is called.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Foundation.BlockingQueueStoppedException"></exception>
+		object Next(long timeout);
+
+		void Stop();
+
+		/// <summary>
+		/// <p>
+		/// Removes all the available elements in the queue to the colletion passed
+		/// as argument.
+		/// </summary>
+		/// <remarks>
+		/// <p>
+		/// Removes all the available elements in the queue to the colletion passed
+		/// as argument.
+		/// <p>
+		/// It will block until at least one element is available.
+		/// </remarks>
+		/// <param name="list"></param>
+		/// <returns>the number of elements added to the list.</returns>
+		/// <exception cref="BlockingQueueStoppedException">
+		/// if the
+		/// <see cref="Stop()">Stop()</see>
+		/// is called.
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Foundation.BlockingQueueStoppedException"></exception>
+		int DrainTo(Collection4 list);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ICancellableVisitor4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ICancellableVisitor4.cs
new file mode 100644
index 0000000..e933927
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ICancellableVisitor4.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	public interface ICancellableVisitor4
+	{
+		/// <returns>true to continue traversal, false otherwise</returns>
+		bool Visit(object obj);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IClosure4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IClosure4.cs
new file mode 100644
index 0000000..ba0b4f2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IClosure4.cs
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	public interface IClosure4
+	{
+		object Run();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IComparison4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IComparison4.cs
new file mode 100644
index 0000000..5aa84f3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IComparison4.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public interface IComparison4
+	{
+		/// <summary>
+		/// Returns negative number if x < y
+		/// Returns zero if x == y
+		/// Returns positive number if x > y
+		/// </summary>
+		int Compare(object x, object y);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IDeepClone.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IDeepClone.cs
new file mode 100644
index 0000000..7f8f4fa
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IDeepClone.cs
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>Deep clone</summary>
+	/// <exclude></exclude>
+	public interface IDeepClone
+	{
+		/// <summary>
+		/// The parameter allows passing one new object so parent
+		/// references can be corrected on children.
+		/// </summary>
+		/// <remarks>
+		/// The parameter allows passing one new object so parent
+		/// references can be corrected on children.
+		/// </remarks>
+		object DeepClone(object context);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IEntry4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IEntry4.cs
new file mode 100644
index 0000000..5160f23
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IEntry4.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public interface IEntry4
+	{
+		object Key();
+
+		object Value();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IEnvironment.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IEnvironment.cs
new file mode 100644
index 0000000..6c787d4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IEnvironment.cs
@@ -0,0 +1,11 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public interface IEnvironment
+	{
+		object Provide(Type service);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IFixedSizeIntIterator4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IFixedSizeIntIterator4.cs
new file mode 100644
index 0000000..9263a41
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IFixedSizeIntIterator4.cs
@@ -0,0 +1,11 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public interface IFixedSizeIntIterator4 : IIntIterator4
+	{
+		int Size();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IFunction4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IFunction4.cs
new file mode 100644
index 0000000..606c2ac
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IFunction4.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public interface IFunction4
+	{
+		object Apply(object arg);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IIntComparator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IIntComparator.cs
new file mode 100644
index 0000000..055b3b8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IIntComparator.cs
@@ -0,0 +1,16 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>
+	/// Non boxing/unboxing version of
+	/// <see cref="System.Collections.IComparer{T}">System.Collections.IComparer<T>
+	/// 	</see>
+	/// for
+	/// faster id comparisons.
+	/// </summary>
+	public interface IIntComparator
+	{
+		int Compare(int x, int y);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IIntIterator4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IIntIterator4.cs
new file mode 100644
index 0000000..8f5984d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IIntIterator4.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public interface IIntIterator4 : IEnumerator
+	{
+		int CurrentInt();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IIntObjectVisitor.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IIntObjectVisitor.cs
new file mode 100644
index 0000000..15a3f60
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IIntObjectVisitor.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public interface IIntObjectVisitor
+	{
+		void Visit(int anInt, object anObject);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IListener4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IListener4.cs
new file mode 100644
index 0000000..117ca39
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IListener4.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public interface IListener4
+	{
+		void OnEvent(object @event);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IMap4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IMap4.cs
new file mode 100644
index 0000000..01e35c8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IMap4.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public interface IMap4
+	{
+		int Size();
+
+		object Get(object key);
+
+		void Put(object key, object value);
+
+		bool ContainsKey(object key);
+
+		object Remove(object key);
+
+		IEnumerable Values();
+
+		void Clear();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IObjectPool.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IObjectPool.cs
new file mode 100644
index 0000000..acb0cfa
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IObjectPool.cs
@@ -0,0 +1,11 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	public interface IObjectPool
+	{
+		object BorrowObject();
+
+		void ReturnObject(object o);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IPausableBlockingQueue4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IPausableBlockingQueue4.cs
new file mode 100644
index 0000000..302d1bd
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IPausableBlockingQueue4.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public interface IPausableBlockingQueue4 : IBlockingQueue4
+	{
+		/// <summary>
+		/// <p>
+		/// Pauses the queue, making calls to
+		/// <see cref="IQueue4.Next()">IQueue4.Next()</see>
+		/// block
+		/// until
+		/// <see cref="Resume()">Resume()</see>
+		/// is called.
+		/// </summary>
+		/// <returns>whether or not this call changed the state of the queue.</returns>
+		bool Pause();
+
+		/// <summary>
+		/// <p>
+		/// Resumes the queue, releasing blocked calls to
+		/// <see cref="IQueue4.Next()">IQueue4.Next()</see>
+		/// that can reach a next queue item..
+		/// </summary>
+		/// <returns>whether or not this call changed the state of the queue.</returns>
+		bool Resume();
+
+		bool IsPaused();
+
+		/// <summary>
+		/// <p>
+		/// Returns the next element in queue if there is one available, returns null
+		/// otherwise.
+		/// </summary>
+		/// <remarks>
+		/// <p>
+		/// Returns the next element in queue if there is one available, returns null
+		/// otherwise.
+		/// <p>
+		/// This method will not never block, regardless of the queue being paused or
+		/// no elements are available.
+		/// </remarks>
+		/// <returns>next element, if available and queue not paused.</returns>
+		object TryNext();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IPredicate4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IPredicate4.cs
new file mode 100644
index 0000000..42bbe4d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IPredicate4.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public interface IPredicate4
+	{
+		bool Match(object candidate);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IPreparedComparison.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IPreparedComparison.cs
new file mode 100644
index 0000000..5687836
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IPreparedComparison.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>
+	/// a prepared comparison, to compare multiple objects
+	/// with one single object.
+	/// </summary>
+	/// <remarks>
+	/// a prepared comparison, to compare multiple objects
+	/// with one single object.
+	/// </remarks>
+	public interface IPreparedComparison
+	{
+		/// <summary>
+		/// return a negative int, zero or a positive int if
+		/// the object being held in 'this' is smaller, equal
+		/// or greater than the passed object.<br /><br />
+		/// Typical implementation: return this.object - obj;
+		/// </summary>
+		int CompareTo(object obj);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IProcedure4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IProcedure4.cs
new file mode 100644
index 0000000..51066e9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IProcedure4.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public interface IProcedure4
+	{
+		void Apply(object value);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IQueue4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IQueue4.cs
new file mode 100644
index 0000000..fe2a8b3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IQueue4.cs
@@ -0,0 +1,28 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public interface IQueue4
+	{
+		void Add(object obj);
+
+		object Next();
+
+		bool HasNext();
+
+		/// <summary>Returns the next object in the queue that matches the specified condition.
+		/// 	</summary>
+		/// <remarks>
+		/// Returns the next object in the queue that matches the specified condition.
+		/// The operation is always NON-BLOCKING.
+		/// </remarks>
+		/// <param name="condition">the object must satisfy to be returned</param>
+		/// <returns>the object satisfying the condition or null if none does</returns>
+		object NextMatching(IPredicate4 condition);
+
+		IEnumerator Iterator();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ISequence4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ISequence4.cs
new file mode 100644
index 0000000..d9b03fd
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ISequence4.cs
@@ -0,0 +1,32 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public interface ISequence4 : IEnumerable
+	{
+		bool Add(object element);
+
+		void AddAll(IEnumerable iterable);
+
+		bool IsEmpty();
+
+		object Get(int index);
+
+		int Size();
+
+		void Clear();
+
+		bool Remove(object obj);
+
+		bool Contains(object obj);
+
+		bool ContainsAll(IEnumerable iter);
+
+		object[] ToArray();
+
+		object[] ToArray(object[] array);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ISet4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ISet4.cs
new file mode 100644
index 0000000..7fec4b7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ISet4.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public interface ISet4 : IEnumerable
+	{
+		bool Add(object obj);
+
+		void Clear();
+
+		bool Contains(object obj);
+
+		bool IsEmpty();
+
+		IEnumerator GetEnumerator();
+
+		bool Remove(object obj);
+
+		int Size();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IShallowClone.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IShallowClone.cs
new file mode 100644
index 0000000..4379f2b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IShallowClone.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public interface IShallowClone
+	{
+		object ShallowClone();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ISortable4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ISortable4.cs
new file mode 100644
index 0000000..813244e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ISortable4.cs
@@ -0,0 +1,14 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public interface ISortable4
+	{
+		int Size();
+
+		int Compare(int leftIndex, int rightIndex);
+
+		void Swap(int leftIndex, int rightIndex);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ITimeoutBlockingQueue4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ITimeoutBlockingQueue4.cs
new file mode 100644
index 0000000..b54c63f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ITimeoutBlockingQueue4.cs
@@ -0,0 +1,13 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public interface ITimeoutBlockingQueue4 : IPausableBlockingQueue4
+	{
+		void Check();
+
+		void Reset();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IVisitable.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IVisitable.cs
new file mode 100644
index 0000000..611ea5a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IVisitable.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public interface IVisitable
+	{
+		void Accept(IVisitor4 visitor);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IVisitor4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IVisitor4.cs
new file mode 100644
index 0000000..ac75c86
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IVisitor4.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public interface IVisitor4
+	{
+		void Visit(object obj);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IdentityHashtable4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IdentityHashtable4.cs
new file mode 100644
index 0000000..a839bd4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IdentityHashtable4.cs
@@ -0,0 +1,75 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Sharpen;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class IdentityHashtable4 : HashtableBase, IMap4
+	{
+		public IdentityHashtable4()
+		{
+		}
+
+		public IdentityHashtable4(int size) : base(size)
+		{
+		}
+
+		public virtual bool Contains(object obj)
+		{
+			return GetEntry(obj) != null;
+		}
+
+		public virtual object Remove(object obj)
+		{
+			if (null == obj)
+			{
+				throw new ArgumentNullException();
+			}
+			return RemoveIntEntry(Runtime.IdentityHashCode(obj));
+		}
+
+		public virtual bool ContainsKey(object key)
+		{
+			return GetEntry(key) != null;
+		}
+
+		public virtual object Get(object key)
+		{
+			HashtableIntEntry entry = GetEntry(key);
+			return (entry == null ? null : entry._object);
+		}
+
+		private HashtableIntEntry GetEntry(object key)
+		{
+			return FindWithSameKey(new IdentityHashtable4.IdentityEntry(key));
+		}
+
+		public virtual void Put(object key, object value)
+		{
+			if (null == key)
+			{
+				throw new ArgumentNullException();
+			}
+			PutEntry(new IdentityHashtable4.IdentityEntry(key, value));
+		}
+
+		public class IdentityEntry : HashtableObjectEntry
+		{
+			public IdentityEntry(object obj) : this(obj, null)
+			{
+			}
+
+			public IdentityEntry(object key, object value) : base(Runtime.IdentityHashCode(key
+				), key, value)
+			{
+			}
+
+			public override bool HasKey(object key)
+			{
+				return _objectKey == key;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IdentitySet4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IdentitySet4.cs
new file mode 100644
index 0000000..519b40b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IdentitySet4.cs
@@ -0,0 +1,49 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Sharpen;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class IdentitySet4 : HashtableBase, IEnumerable
+	{
+		public IdentitySet4()
+		{
+		}
+
+		public IdentitySet4(int size) : base(size)
+		{
+		}
+
+		public virtual bool Contains(object obj)
+		{
+			return FindWithSameKey(new HashtableIdentityEntry(obj)) != null;
+		}
+
+		public virtual void Add(object obj)
+		{
+			if (null == obj)
+			{
+				throw new ArgumentNullException();
+			}
+			PutEntry(new HashtableIdentityEntry(obj));
+		}
+
+		public virtual void Remove(object obj)
+		{
+			if (null == obj)
+			{
+				throw new ArgumentNullException();
+			}
+			RemoveIntEntry(Runtime.IdentityHashCode(obj));
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			return ValuesIterator();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IndexedIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IndexedIterator.cs
new file mode 100644
index 0000000..6c2b31f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IndexedIterator.cs
@@ -0,0 +1,61 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>
+	/// Basic functionality for implementing iterators for
+	/// fixed length structures whose elements can be efficiently
+	/// accessed by a numeric index.
+	/// </summary>
+	/// <remarks>
+	/// Basic functionality for implementing iterators for
+	/// fixed length structures whose elements can be efficiently
+	/// accessed by a numeric index.
+	/// </remarks>
+	public abstract class IndexedIterator : IEnumerator
+	{
+		private readonly int _length;
+
+		private int _next;
+
+		public IndexedIterator(int length)
+		{
+			_length = length;
+			_next = -1;
+		}
+
+		public virtual bool MoveNext()
+		{
+			if (_next < LastIndex())
+			{
+				++_next;
+				return true;
+			}
+			// force exception on unexpected call to current
+			_next = _length;
+			return false;
+		}
+
+		public virtual object Current
+		{
+			get
+			{
+				return Get(_next);
+			}
+		}
+
+		public virtual void Reset()
+		{
+			_next = -1;
+		}
+
+		protected abstract object Get(int index);
+
+		private int LastIndex()
+		{
+			return _length - 1;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntArrayByRef.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntArrayByRef.cs
new file mode 100644
index 0000000..05caf38
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntArrayByRef.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class IntArrayByRef
+	{
+		public int[] value;
+
+		public IntArrayByRef(int[] initialValue)
+		{
+			value = initialValue;
+		}
+
+		public IntArrayByRef()
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntArrayList.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntArrayList.cs
new file mode 100644
index 0000000..701b88d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntArrayList.cs
@@ -0,0 +1,106 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Sharpen;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class IntArrayList : IEnumerable
+	{
+		protected int[] i_content;
+
+		private int i_count;
+
+		public IntArrayList() : this(10)
+		{
+		}
+
+		public IntArrayList(int initialSize)
+		{
+			i_content = new int[initialSize];
+		}
+
+		public virtual void Add(int a_value)
+		{
+			EnsureCapacity();
+			i_content[i_count++] = a_value;
+		}
+
+		public virtual void Add(int index, int a_value)
+		{
+			EnsureCapacity();
+			System.Array.Copy(i_content, index, i_content, index + 1, i_count - index);
+			i_content[index] = a_value;
+			i_count++;
+		}
+
+		private void EnsureCapacity()
+		{
+			if (i_count >= i_content.Length)
+			{
+				int inc = i_content.Length / 2;
+				if (inc < 10)
+				{
+					inc = 10;
+				}
+				int[] temp = new int[i_content.Length + inc];
+				System.Array.Copy(i_content, 0, temp, 0, i_content.Length);
+				i_content = temp;
+			}
+		}
+
+		public virtual int IndexOf(int a_value)
+		{
+			for (int i = 0; i < i_count; i++)
+			{
+				if (i_content[i] == a_value)
+				{
+					return i;
+				}
+			}
+			return -1;
+		}
+
+		public virtual int Size()
+		{
+			return i_count;
+		}
+
+		public virtual long[] AsLong()
+		{
+			long[] longs = new long[i_count];
+			for (int i = 0; i < i_count; i++)
+			{
+				longs[i] = i_content[i];
+			}
+			return longs;
+		}
+
+		public virtual IIntIterator4 IntIterator()
+		{
+			return IntIterators.ForInts(i_content, i_count);
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			return IntIterator();
+		}
+
+		public virtual int Get(int index)
+		{
+			return i_content[index];
+		}
+
+		public virtual void Swap(int left, int right)
+		{
+			if (left != right)
+			{
+				int swap = i_content[left];
+				i_content[left] = i_content[right];
+				i_content[right] = swap;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntByRef.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntByRef.cs
new file mode 100644
index 0000000..2228da9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntByRef.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>Useful as "out" or "by ref" function parameter.</summary>
+	/// <remarks>Useful as "out" or "by ref" function parameter.</remarks>
+	public sealed class IntByRef
+	{
+		public int value;
+
+		public IntByRef(int initialValue)
+		{
+			value = initialValue;
+		}
+
+		public IntByRef()
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntIdGenerator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntIdGenerator.cs
new file mode 100644
index 0000000..766b058
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntIdGenerator.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class IntIdGenerator
+	{
+		private int _current = 1;
+
+		public virtual int Next()
+		{
+			_current++;
+			if (_current < 0)
+			{
+				_current = 1;
+			}
+			return _current;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntIterator4Adaptor.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntIterator4Adaptor.cs
new file mode 100644
index 0000000..5b1113e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntIterator4Adaptor.cs
@@ -0,0 +1,45 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class IntIterator4Adaptor : IIntIterator4
+	{
+		private readonly IEnumerator _iterator;
+
+		public IntIterator4Adaptor(IEnumerator iterator)
+		{
+			_iterator = iterator;
+		}
+
+		public IntIterator4Adaptor(IEnumerable iterable) : this(iterable.GetEnumerator())
+		{
+		}
+
+		public virtual int CurrentInt()
+		{
+			return ((int)Current);
+		}
+
+		public virtual object Current
+		{
+			get
+			{
+				return _iterator.Current;
+			}
+		}
+
+		public virtual bool MoveNext()
+		{
+			return _iterator.MoveNext();
+		}
+
+		public virtual void Reset()
+		{
+			_iterator.Reset();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntIterator4Impl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntIterator4Impl.cs
new file mode 100644
index 0000000..cbe572f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntIterator4Impl.cs
@@ -0,0 +1,62 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class IntIterator4Impl : IFixedSizeIntIterator4
+	{
+		private readonly int _count;
+
+		private int[] _content;
+
+		private int _current;
+
+		public IntIterator4Impl(int[] content, int count)
+		{
+			_content = content;
+			_count = count;
+			Reset();
+		}
+
+		public virtual int CurrentInt()
+		{
+			if (_content == null || _current == _count)
+			{
+				throw new InvalidOperationException();
+			}
+			return _content[_current];
+		}
+
+		public virtual object Current
+		{
+			get
+			{
+				return CurrentInt();
+			}
+		}
+
+		public virtual bool MoveNext()
+		{
+			if (_current < _count - 1)
+			{
+				_current++;
+				return true;
+			}
+			_content = null;
+			return false;
+		}
+
+		public virtual void Reset()
+		{
+			_current = -1;
+		}
+
+		public virtual int Size()
+		{
+			return _count;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntIterators.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntIterators.cs
new file mode 100644
index 0000000..9812982
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/IntIterators.cs
@@ -0,0 +1,64 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class IntIterators
+	{
+		public static IFixedSizeIntIterator4 ForInts(int[] array, int count)
+		{
+			return new IntIterator4Impl(array, count);
+		}
+
+		public static IIntIterator4 ForLongs(long[] ids)
+		{
+			return new _IIntIterator4_10(ids);
+		}
+
+		private sealed class _IIntIterator4_10 : IIntIterator4
+		{
+			public _IIntIterator4_10(long[] ids)
+			{
+				this.ids = ids;
+				this._next = 0;
+			}
+
+			internal int _next;
+
+			internal int _current;
+
+			public int CurrentInt()
+			{
+				return this._current;
+			}
+
+			public object Current
+			{
+				get
+				{
+					return this._current;
+				}
+			}
+
+			public bool MoveNext()
+			{
+				if (this._next < ids.Length)
+				{
+					this._current = (int)ids[this._next];
+					++this._next;
+					return true;
+				}
+				return false;
+			}
+
+			public void Reset()
+			{
+				throw new NotImplementedException();
+			}
+
+			private readonly long[] ids;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/InvalidIteratorException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/InvalidIteratorException.cs
new file mode 100644
index 0000000..fc09977
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/InvalidIteratorException.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	[System.Serializable]
+	public class InvalidIteratorException : InvalidOperationException
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Iterable4Adaptor.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Iterable4Adaptor.cs
new file mode 100644
index 0000000..c6262d5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Iterable4Adaptor.cs
@@ -0,0 +1,75 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>
+	/// Adapts Iterable4/Iterator4 iteration model (moveNext, current) to the old db4o
+	/// and jdk model (hasNext, next).
+	/// </summary>
+	/// <remarks>
+	/// Adapts Iterable4/Iterator4 iteration model (moveNext, current) to the old db4o
+	/// and jdk model (hasNext, next).
+	/// </remarks>
+	/// <exclude></exclude>
+	public class Iterable4Adaptor
+	{
+		private static readonly object EofMarker = new object();
+
+		private static readonly object MoveNextMarker = new object();
+
+		private readonly IEnumerable _delegate;
+
+		private IEnumerator _iterator;
+
+		private object _current = MoveNextMarker;
+
+		public Iterable4Adaptor(IEnumerable delegate_)
+		{
+			_delegate = delegate_;
+		}
+
+		public virtual bool HasNext()
+		{
+			if (_current == MoveNextMarker)
+			{
+				return MoveNext();
+			}
+			return _current != EofMarker;
+		}
+
+		public virtual object Next()
+		{
+			if (!HasNext())
+			{
+				throw new InvalidOperationException();
+			}
+			object returnValue = _current;
+			_current = MoveNextMarker;
+			return returnValue;
+		}
+
+		protected virtual bool MoveNext()
+		{
+			if (null == _iterator)
+			{
+				_iterator = _delegate.GetEnumerator();
+			}
+			if (_iterator.MoveNext())
+			{
+				_current = _iterator.Current;
+				return true;
+			}
+			_current = EofMarker;
+			return false;
+		}
+
+		public virtual void Reset()
+		{
+			_iterator = null;
+			_current = MoveNextMarker;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Iterator4Impl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Iterator4Impl.cs
new file mode 100644
index 0000000..c2d5f0a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Iterator4Impl.cs
@@ -0,0 +1,55 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class Iterator4Impl : IEnumerator
+	{
+		private readonly List4 _first;
+
+		private List4 _next;
+
+		private object _current;
+
+		public Iterator4Impl(List4 first)
+		{
+			_first = first;
+			_next = first;
+			_current = Iterators.NoElement;
+		}
+
+		public virtual bool MoveNext()
+		{
+			if (_next == null)
+			{
+				_current = Iterators.NoElement;
+				return false;
+			}
+			_current = ((object)_next._element);
+			_next = ((List4)_next._next);
+			return true;
+		}
+
+		public virtual object Current
+		{
+			get
+			{
+				if (Iterators.NoElement == _current)
+				{
+					throw new InvalidOperationException();
+				}
+				return (object)_current;
+			}
+		}
+
+		public virtual void Reset()
+		{
+			_next = _first;
+			_current = Iterators.NoElement;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Iterators.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Iterators.cs
new file mode 100644
index 0000000..d150fa5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Iterators.cs
@@ -0,0 +1,626 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using System.Text;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>Iterator primitives (concat, map, reduce, filter, etc...).</summary>
+	/// <remarks>Iterator primitives (concat, map, reduce, filter, etc...).</remarks>
+	/// <exclude></exclude>
+	public partial class Iterators
+	{
+		/// <summary>
+		/// Constant indicating that the current element in a
+		/// <see cref="Map(IEnumerator, IFunction4)">Map(IEnumerator, IFunction4)</see>
+		/// operation
+		/// should be skipped.
+		/// </summary>
+		public static readonly object Skip = new object();
+
+		private sealed class _IEnumerator_20 : IEnumerator
+		{
+			public _IEnumerator_20()
+			{
+			}
+
+			public object Current
+			{
+				get
+				{
+					throw new InvalidOperationException();
+				}
+			}
+
+			public bool MoveNext()
+			{
+				return false;
+			}
+
+			public void Reset()
+			{
+			}
+		}
+
+		public static readonly IEnumerator EmptyIterator = new _IEnumerator_20();
+
+		private sealed class _IEnumerable_34 : IEnumerable
+		{
+			public _IEnumerable_34()
+			{
+			}
+
+			// do nothing
+			public IEnumerator GetEnumerator()
+			{
+				return Iterators.EmptyIterator;
+			}
+		}
+
+		public static readonly IEnumerable EmptyIterable = new _IEnumerable_34();
+
+		internal static readonly object NoElement = new object();
+
+		/// <summary>
+		/// Generates
+		/// <see cref="Tuple">Tuple</see>
+		/// items with indexes starting at 0.
+		/// </summary>
+		/// <param name="iterable">the iterable to be enumerated</param>
+		public static IEnumerable Enumerate(IEnumerable iterable)
+		{
+			return new _IEnumerable_48(iterable);
+		}
+
+		private sealed class _IEnumerable_48 : IEnumerable
+		{
+			public _IEnumerable_48(IEnumerable iterable)
+			{
+				this.iterable = iterable;
+			}
+
+			public IEnumerator GetEnumerator()
+			{
+				return new EnumerateIterator(iterable.GetEnumerator());
+			}
+
+			private readonly IEnumerable iterable;
+		}
+
+		public static bool Any(IEnumerator iterator, IPredicate4 condition)
+		{
+			while (iterator.MoveNext())
+			{
+				if (condition.Match(iterator.Current))
+				{
+					return true;
+				}
+			}
+			return false;
+		}
+
+		public static IEnumerator Concat(IEnumerator[] array)
+		{
+			return Concat(Iterate((object[])array));
+		}
+
+		public static IEnumerator Concat(IEnumerator iterators)
+		{
+			return new CompositeIterator4(iterators);
+		}
+
+		public static IEnumerable Concat(IEnumerable[] iterables)
+		{
+			return Concat(Iterable(iterables));
+		}
+
+		public static IEnumerable Concat(IEnumerable iterables)
+		{
+			return new CompositeIterable4(iterables);
+		}
+
+		public static IEnumerator Concat(IEnumerator first, IEnumerator second)
+		{
+			return Concat(new IEnumerator[] { first, second });
+		}
+
+		public static IEnumerable ConcatMap(IEnumerable iterable, IFunction4 function)
+		{
+			return Concat(Map(iterable, function));
+		}
+
+		/// <summary>
+		/// Returns a new iterator which yields the result of applying the function
+		/// to every element in the original iterator.
+		/// </summary>
+		/// <remarks>
+		/// Returns a new iterator which yields the result of applying the function
+		/// to every element in the original iterator.
+		/// <see cref="Skip">Skip</see>
+		/// can be returned from function to indicate the current
+		/// element should be skipped.
+		/// </remarks>
+		/// <param name="iterator"></param>
+		/// <param name="function"></param>
+		/// <returns></returns>
+		public static IEnumerator Map(IEnumerator iterator, IFunction4 function)
+		{
+			return new FunctionApplicationIterator(iterator, function);
+		}
+
+		public static IEnumerator Map(object[] array, IFunction4 function)
+		{
+			return Map(new ArrayIterator4(array), function);
+		}
+
+		public static IEnumerator Filter(object[] array, IPredicate4 predicate)
+		{
+			return Filter(new ArrayIterator4(array), predicate);
+		}
+
+		public static IEnumerable Filter(IEnumerable source, IPredicate4 predicate)
+		{
+			return new _IEnumerable_112(source, predicate);
+		}
+
+		private sealed class _IEnumerable_112 : IEnumerable
+		{
+			public _IEnumerable_112(IEnumerable source, IPredicate4 predicate)
+			{
+				this.source = source;
+				this.predicate = predicate;
+			}
+
+			public IEnumerator GetEnumerator()
+			{
+				return Iterators.Filter(source.GetEnumerator(), predicate);
+			}
+
+			private readonly IEnumerable source;
+
+			private readonly IPredicate4 predicate;
+		}
+
+		public static IEnumerator Filter(IEnumerator iterator, IPredicate4 predicate)
+		{
+			return new FilteredIterator(iterator, predicate);
+		}
+
+		public static IEnumerable SingletonIterable(object element)
+		{
+			return new _IEnumerable_124(element);
+		}
+
+		private sealed class _IEnumerable_124 : IEnumerable
+		{
+			public _IEnumerable_124(object element)
+			{
+				this.element = element;
+			}
+
+			public IEnumerator GetEnumerator()
+			{
+				return Iterators.SingletonIterator(element);
+			}
+
+			private readonly object element;
+		}
+
+		public static IEnumerable Append(IEnumerable front, object last)
+		{
+			return Concat(Iterable(new object[] { front, SingletonIterable(last) }));
+		}
+
+		public static IEnumerator Iterator(IEnumerable iterable)
+		{
+			return iterable.GetEnumerator();
+		}
+
+		public static IEnumerator Iterate(object[] array)
+		{
+			return new ArrayIterator4(array);
+		}
+
+		public static IEnumerator Revert(IEnumerator iterator)
+		{
+			iterator.Reset();
+			List4 tail = null;
+			while (iterator.MoveNext())
+			{
+				tail = new List4(tail, iterator.Current);
+			}
+			return Iterate(tail);
+		}
+
+		public static IEnumerator Iterate(List4 list)
+		{
+			if (list == null)
+			{
+				return EmptyIterator;
+			}
+			Collection4 collection = new Collection4();
+			while (list != null)
+			{
+				collection.Add(list._element);
+				list = ((List4)list._next);
+			}
+			return collection.GetEnumerator();
+		}
+
+		public static int Size(IEnumerable iterable)
+		{
+			return Size(iterable.GetEnumerator());
+		}
+
+		public static object Next(IEnumerator iterator)
+		{
+			if (!iterator.MoveNext())
+			{
+				throw new InvalidOperationException();
+			}
+			return iterator.Current;
+		}
+
+		public static int Size(IEnumerator iterator)
+		{
+			int count = 0;
+			while (iterator.MoveNext())
+			{
+				++count;
+			}
+			return count;
+		}
+
+		public static string ToString(IEnumerable i)
+		{
+			return ToString(i.GetEnumerator());
+		}
+
+		public static string ToString(IEnumerator i)
+		{
+			return Join(i, "[", "]", ", ");
+		}
+
+		public static string Join(IEnumerable i, string separator)
+		{
+			return Join(i.GetEnumerator(), separator);
+		}
+
+		public static string Join(IEnumerator i, string separator)
+		{
+			return Join(i, string.Empty, string.Empty, separator);
+		}
+
+		public static string Join(IEnumerator i, string prefix, string suffix, string separator
+			)
+		{
+			StringBuilder sb = new StringBuilder();
+			sb.Append(prefix);
+			if (i.MoveNext())
+			{
+				sb.Append(i.Current);
+				while (i.MoveNext())
+				{
+					sb.Append(separator);
+					sb.Append(i.Current);
+				}
+			}
+			sb.Append(suffix);
+			return sb.ToString();
+		}
+
+		public static object[] ToArray(IEnumerator tests)
+		{
+			return ToArray(tests, new _IArrayFactory_230());
+		}
+
+		private sealed class _IArrayFactory_230 : IArrayFactory
+		{
+			public _IArrayFactory_230()
+			{
+			}
+
+			public object[] NewArray(int size)
+			{
+				return new object[size];
+			}
+		}
+
+		public static object[] ToArray(IEnumerator tests, IArrayFactory factory)
+		{
+			Collection4 elements = new Collection4(tests);
+			return elements.ToArray(factory.NewArray(elements.Size()));
+		}
+
+		/// <summary>Yields a flat sequence of elements.</summary>
+		/// <remarks>
+		/// Yields a flat sequence of elements. Any
+		/// <see cref="IEnumerable">IEnumerable</see>
+		/// or
+		/// <see cref="IEnumerator">IEnumerator</see>
+		/// found in the original sequence is recursively flattened.
+		/// </remarks>
+		/// <param name="iterator">original sequence</param>
+		public static IEnumerator Flatten(IEnumerator iterator)
+		{
+			return new FlatteningIterator(iterator);
+		}
+
+		public static IEnumerable Map(IEnumerable iterable, IFunction4 function)
+		{
+			return new _IEnumerable_253(iterable, function);
+		}
+
+		private sealed class _IEnumerable_253 : IEnumerable
+		{
+			public _IEnumerable_253(IEnumerable iterable, IFunction4 function)
+			{
+				this.iterable = iterable;
+				this.function = function;
+			}
+
+			public IEnumerator GetEnumerator()
+			{
+				return Iterators.Map(iterable.GetEnumerator(), function);
+			}
+
+			private readonly IEnumerable iterable;
+
+			private readonly IFunction4 function;
+		}
+
+		public static IEnumerable CrossProduct(IEnumerable iterables)
+		{
+			return CrossProduct((IEnumerable[])ToArray(iterables.GetEnumerator(), new _IArrayFactory_261
+				()));
+		}
+
+		private sealed class _IArrayFactory_261 : IArrayFactory
+		{
+			public _IArrayFactory_261()
+			{
+			}
+
+			public object[] NewArray(int size)
+			{
+				return new IEnumerable[size];
+			}
+		}
+
+		public static IEnumerable CrossProduct(IEnumerable[] iterables)
+		{
+			return CrossProduct(iterables, 0, Iterators.EmptyIterable);
+		}
+
+		private static IEnumerable CrossProduct(IEnumerable[] iterables, int level, IEnumerable
+			 row)
+		{
+			if (level == iterables.Length - 1)
+			{
+				return Map(iterables[level], new _IFunction4_276(row));
+			}
+			return ConcatMap(iterables[level], new _IFunction4_284(iterables, level, row));
+		}
+
+		private sealed class _IFunction4_276 : IFunction4
+		{
+			public _IFunction4_276(IEnumerable row)
+			{
+				this.row = row;
+			}
+
+			public object Apply(object arg)
+			{
+				return Iterators.Append(row, arg);
+			}
+
+			private readonly IEnumerable row;
+		}
+
+		private sealed class _IFunction4_284 : IFunction4
+		{
+			public _IFunction4_284(IEnumerable[] iterables, int level, IEnumerable row)
+			{
+				this.iterables = iterables;
+				this.level = level;
+				this.row = row;
+			}
+
+			public object Apply(object arg)
+			{
+				return Iterators.CrossProduct(iterables, level + 1, Iterators.Append(row, arg));
+			}
+
+			private readonly IEnumerable[] iterables;
+
+			private readonly int level;
+
+			private readonly IEnumerable row;
+		}
+
+		public static IEnumerable Iterable(object[] objects)
+		{
+			return new _IEnumerable_292(objects);
+		}
+
+		private sealed class _IEnumerable_292 : IEnumerable
+		{
+			public _IEnumerable_292(object[] objects)
+			{
+				this.objects = objects;
+			}
+
+			public IEnumerator GetEnumerator()
+			{
+				return Iterators.Iterate(objects);
+			}
+
+			private readonly object[] objects;
+		}
+
+		public static IEnumerator SingletonIterator(object element)
+		{
+			return new SingleValueIterator(element);
+		}
+
+		public static IEnumerable Iterable(IEnumerator iterator)
+		{
+			return new _IEnumerable_304(iterator);
+		}
+
+		private sealed class _IEnumerable_304 : IEnumerable
+		{
+			public _IEnumerable_304(IEnumerator iterator)
+			{
+				this.iterator = iterator;
+			}
+
+			public IEnumerator GetEnumerator()
+			{
+				return iterator;
+			}
+
+			private readonly IEnumerator iterator;
+		}
+
+		public static IEnumerator Copy(IEnumerator iterator)
+		{
+			return new Collection4(iterator).GetEnumerator();
+		}
+
+		public static IEnumerator Take(int count, IEnumerator iterator)
+		{
+			return new _IEnumerator_316(count, iterator);
+		}
+
+		private sealed class _IEnumerator_316 : IEnumerator
+		{
+			public _IEnumerator_316(int count, IEnumerator iterator)
+			{
+				this.count = count;
+				this.iterator = iterator;
+				this._taken = 0;
+			}
+
+			private int _taken;
+
+			public object Current
+			{
+				get
+				{
+					if (this._taken > count)
+					{
+						throw new InvalidOperationException();
+					}
+					return iterator.Current;
+				}
+			}
+
+			public bool MoveNext()
+			{
+				if (this._taken < count)
+				{
+					if (!iterator.MoveNext())
+					{
+						this._taken = count;
+						return false;
+					}
+					++this._taken;
+					return true;
+				}
+				return false;
+			}
+
+			public void Reset()
+			{
+				throw new NotImplementedException();
+			}
+
+			private readonly int count;
+
+			private readonly IEnumerator iterator;
+		}
+
+		public static IEnumerator Range(int fromInclusive, int toExclusive)
+		{
+			if (toExclusive < fromInclusive)
+			{
+				throw new ArgumentException();
+			}
+			return Take(toExclusive - fromInclusive, Series(fromInclusive - 1, new _IFunction4_350
+				()).GetEnumerator());
+		}
+
+		private sealed class _IFunction4_350 : IFunction4
+		{
+			public _IFunction4_350()
+			{
+			}
+
+			public object Apply(object i)
+			{
+				return (((int)i)) + 1;
+			}
+		}
+
+		public static IEnumerable Series(object seed, IFunction4 function)
+		{
+			return new _IEnumerable_356(seed, function);
+		}
+
+		private sealed class _IEnumerable_356 : IEnumerable
+		{
+			public _IEnumerable_356(object seed, IFunction4 function)
+			{
+				this.seed = seed;
+				this.function = function;
+			}
+
+			public IEnumerator GetEnumerator()
+			{
+				return new _IEnumerator_358(seed, function);
+			}
+
+			private sealed class _IEnumerator_358 : IEnumerator
+			{
+				public _IEnumerator_358(object seed, IFunction4 function)
+				{
+					this.seed = seed;
+					this.function = function;
+					this._current = seed;
+				}
+
+				private object _current;
+
+				public object Current
+				{
+					get
+					{
+						return this._current;
+					}
+				}
+
+				public bool MoveNext()
+				{
+					this._current = function.Apply(this._current);
+					return true;
+				}
+
+				public void Reset()
+				{
+					this._current = seed;
+				}
+
+				private readonly object seed;
+
+				private readonly IFunction4 function;
+			}
+
+			private readonly object seed;
+
+			private readonly IFunction4 function;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/KeySpec.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/KeySpec.cs
new file mode 100644
index 0000000..6d2ae80
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/KeySpec.cs
@@ -0,0 +1,46 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class KeySpec
+	{
+		public interface IDeferred
+		{
+			object Evaluate();
+		}
+
+		private object _defaultValue;
+
+		public KeySpec(byte defaultValue)
+		{
+			_defaultValue = defaultValue;
+		}
+
+		public KeySpec(int defaultValue)
+		{
+			_defaultValue = defaultValue;
+		}
+
+		public KeySpec(bool defaultValue)
+		{
+			_defaultValue = defaultValue;
+		}
+
+		public KeySpec(object defaultValue)
+		{
+			_defaultValue = defaultValue;
+		}
+
+		public virtual object DefaultValue()
+		{
+			if (_defaultValue is KeySpec.IDeferred)
+			{
+				return ((KeySpec.IDeferred)_defaultValue).Evaluate();
+			}
+			return _defaultValue;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/KeySpecHashtable4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/KeySpecHashtable4.cs
new file mode 100644
index 0000000..bfd1c8f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/KeySpecHashtable4.cs
@@ -0,0 +1,89 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class KeySpecHashtable4 : IDeepClone
+	{
+		private SynchronizedHashtable4 _delegate;
+
+		private KeySpecHashtable4(SynchronizedHashtable4 delegate_)
+		{
+			_delegate = delegate_;
+		}
+
+		public KeySpecHashtable4(int size) : this(new SynchronizedHashtable4(size))
+		{
+		}
+
+		public virtual void Put(KeySpec spec, byte value)
+		{
+			_delegate.Put(spec, value);
+		}
+
+		public virtual void Put(KeySpec spec, bool value)
+		{
+			_delegate.Put(spec, value);
+		}
+
+		public virtual void Put(KeySpec spec, int value)
+		{
+			_delegate.Put(spec, value);
+		}
+
+		public virtual void Put(KeySpec spec, object value)
+		{
+			_delegate.Put(spec, value);
+		}
+
+		public virtual byte GetAsByte(KeySpec spec)
+		{
+			return ((byte)Get(spec));
+		}
+
+		public virtual bool GetAsBoolean(KeySpec spec)
+		{
+			return ((bool)Get(spec));
+		}
+
+		public virtual int GetAsInt(KeySpec spec)
+		{
+			return ((int)Get(spec));
+		}
+
+		public virtual TernaryBool GetAsTernaryBool(KeySpec spec)
+		{
+			return (TernaryBool)Get(spec);
+		}
+
+		public virtual string GetAsString(KeySpec spec)
+		{
+			return (string)Get(spec);
+		}
+
+		public virtual object Get(KeySpec spec)
+		{
+			lock (this)
+			{
+				object value = _delegate.Get(spec);
+				if (value == null)
+				{
+					value = spec.DefaultValue();
+					if (value != null)
+					{
+						_delegate.Put(spec, value);
+					}
+				}
+				return value;
+			}
+		}
+
+		public virtual object DeepClone(object obj)
+		{
+			return new Db4objects.Db4o.Foundation.KeySpecHashtable4((SynchronizedHashtable4)_delegate
+				.DeepClone(obj));
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/List4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/List4.cs
new file mode 100644
index 0000000..bfefb99
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/List4.cs
@@ -0,0 +1,55 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Types;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>simplest possible linked list</summary>
+	/// <exclude></exclude>
+	public sealed class List4 : IUnversioned
+	{
+		/// <summary>next element in list</summary>
+		public Db4objects.Db4o.Foundation.List4 _next;
+
+		/// <summary>carried object</summary>
+		public object _element;
+
+		/// <summary>db4o constructor to be able to store objects of this class</summary>
+		public List4()
+		{
+		}
+
+		public List4(object element)
+		{
+			// TODO: encapsulate field access
+			_element = element;
+		}
+
+		public List4(Db4objects.Db4o.Foundation.List4 next, object element)
+		{
+			_next = next;
+			_element = element;
+		}
+
+		internal bool Holds(object obj)
+		{
+			if (obj == null)
+			{
+				return _element == null;
+			}
+			return ((object)obj).Equals(_element);
+		}
+
+		public static int Size(Db4objects.Db4o.Foundation.List4 list)
+		{
+			int counter = 0;
+			Db4objects.Db4o.Foundation.List4 nextList = list;
+			while (nextList != null)
+			{
+				counter++;
+				nextList = ((Db4objects.Db4o.Foundation.List4)nextList._next);
+			}
+			return counter;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ListenerRegistry.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ListenerRegistry.cs
new file mode 100644
index 0000000..02f2666
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ListenerRegistry.cs
@@ -0,0 +1,49 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class ListenerRegistry
+	{
+		public static ListenerRegistry NewInstance()
+		{
+			return new ListenerRegistry();
+		}
+
+		private IdentitySet4 _listeners;
+
+		public virtual void Register(IListener4 listener)
+		{
+			if (_listeners == null)
+			{
+				_listeners = new IdentitySet4();
+			}
+			_listeners.Add(listener);
+		}
+
+		public virtual void NotifyListeners(object @event)
+		{
+			if (_listeners == null)
+			{
+				return;
+			}
+			IEnumerator i = _listeners.GetEnumerator();
+			while (i.MoveNext())
+			{
+				((IListener4)i.Current).OnEvent(@event);
+			}
+		}
+
+		public virtual void Remove(IListener4 listener)
+		{
+			if (_listeners == null)
+			{
+				return;
+			}
+			_listeners.Remove(listener);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/LongByRef.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/LongByRef.cs
new file mode 100644
index 0000000..42ba9db
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/LongByRef.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>Useful as "out" or "by ref" function parameter.</summary>
+	/// <remarks>Useful as "out" or "by ref" function parameter.</remarks>
+	public sealed class LongByRef
+	{
+		public long value;
+
+		public LongByRef(long initialValue)
+		{
+			value = initialValue;
+		}
+
+		public LongByRef()
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/MappingIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/MappingIterator.cs
new file mode 100644
index 0000000..74454ae
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/MappingIterator.cs
@@ -0,0 +1,61 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public abstract class MappingIterator : IEnumerator
+	{
+		private readonly IEnumerator _iterator;
+
+		private object _current;
+
+		public MappingIterator(IEnumerator iterator)
+		{
+			if (null == iterator)
+			{
+				throw new ArgumentNullException();
+			}
+			_iterator = iterator;
+			_current = Iterators.NoElement;
+		}
+
+		protected abstract object Map(object current);
+
+		public virtual bool MoveNext()
+		{
+			do
+			{
+				if (!_iterator.MoveNext())
+				{
+					_current = Iterators.NoElement;
+					return false;
+				}
+				_current = Map(_iterator.Current);
+			}
+			while (_current == Iterators.Skip);
+			return true;
+		}
+
+		public virtual void Reset()
+		{
+			_current = Iterators.NoElement;
+			_iterator.Reset();
+		}
+
+		public virtual object Current
+		{
+			get
+			{
+				if (Iterators.NoElement == _current)
+				{
+					throw new InvalidOperationException();
+				}
+				return _current;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/NativeCollections.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/NativeCollections.cs
new file mode 100644
index 0000000..845bda0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/NativeCollections.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class NativeCollections
+	{
+		public static IList Filter(IList items, IPredicate4 predicate)
+		{
+			IList filtered = new ArrayList();
+			for (IEnumerator itemIter = items.GetEnumerator(); itemIter.MoveNext(); )
+			{
+				object item = itemIter.Current;
+				if (predicate.Match(item))
+				{
+					filtered.Add(item);
+				}
+			}
+			return filtered;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/No4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/No4.cs
new file mode 100644
index 0000000..76845ab
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/No4.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class No4 : IInternal4
+	{
+		public static readonly No4 Instance = new No4();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/NoDuplicatesQueue.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/NoDuplicatesQueue.cs
new file mode 100644
index 0000000..1ab00c8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/NoDuplicatesQueue.cs
@@ -0,0 +1,50 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class NoDuplicatesQueue : IQueue4
+	{
+		private IQueue4 _queue;
+
+		private Hashtable4 _seen;
+
+		public NoDuplicatesQueue(IQueue4 queue)
+		{
+			_queue = queue;
+			_seen = new Hashtable4();
+		}
+
+		public virtual void Add(object obj)
+		{
+			if (_seen.ContainsKey(obj))
+			{
+				return;
+			}
+			_queue.Add(obj);
+			_seen.Put(obj, obj);
+		}
+
+		public virtual bool HasNext()
+		{
+			return _queue.HasNext();
+		}
+
+		public virtual IEnumerator Iterator()
+		{
+			return _queue.Iterator();
+		}
+
+		public virtual object Next()
+		{
+			return _queue.Next();
+		}
+
+		public virtual object NextMatching(IPredicate4 condition)
+		{
+			return _queue.NextMatching(condition);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/NonblockingQueue.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/NonblockingQueue.cs
new file mode 100644
index 0000000..e891786
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/NonblockingQueue.cs
@@ -0,0 +1,120 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>Unbounded queue.</summary>
+	/// <remarks>Unbounded queue.</remarks>
+	/// <exclude></exclude>
+	public class NonblockingQueue : IQueue4
+	{
+		private List4 _insertionPoint;
+
+		private List4 _next;
+
+		public void Add(object obj)
+		{
+			List4 newNode = new List4(null, obj);
+			if (_insertionPoint == null)
+			{
+				_next = newNode;
+			}
+			else
+			{
+				_insertionPoint._next = newNode;
+			}
+			_insertionPoint = newNode;
+		}
+
+		public object Next()
+		{
+			if (_next == null)
+			{
+				return null;
+			}
+			object ret = ((object)_next._element);
+			RemoveNext();
+			return ret;
+		}
+
+		private void RemoveNext()
+		{
+			_next = ((List4)_next._next);
+			if (_next == null)
+			{
+				_insertionPoint = null;
+			}
+		}
+
+		public virtual object NextMatching(IPredicate4 condition)
+		{
+			if (null == condition)
+			{
+				throw new ArgumentNullException();
+			}
+			List4 current = _next;
+			List4 previous = null;
+			while (null != current)
+			{
+				object element = ((object)current._element);
+				if (condition.Match(element))
+				{
+					if (previous == null)
+					{
+						RemoveNext();
+					}
+					else
+					{
+						previous._next = ((List4)current._next);
+					}
+					return element;
+				}
+				previous = current;
+				current = ((List4)current._next);
+			}
+			return null;
+		}
+
+		public bool HasNext()
+		{
+			return _next != null;
+		}
+
+		public virtual IEnumerator Iterator()
+		{
+			List4 origInsertionPoint = _insertionPoint;
+			List4 origNext = _next;
+			return new _Iterator4Impl_82(this, origInsertionPoint, origNext, _next);
+		}
+
+		private sealed class _Iterator4Impl_82 : Iterator4Impl
+		{
+			public _Iterator4Impl_82(NonblockingQueue _enclosing, List4 origInsertionPoint, List4
+				 origNext, List4 baseArg1) : base(baseArg1)
+			{
+				this._enclosing = _enclosing;
+				this.origInsertionPoint = origInsertionPoint;
+				this.origNext = origNext;
+			}
+
+			public override bool MoveNext()
+			{
+				if (origInsertionPoint != this._enclosing._insertionPoint || origNext != this._enclosing
+					._next)
+				{
+					throw new InvalidOperationException();
+				}
+				return base.MoveNext();
+			}
+
+			private readonly NonblockingQueue _enclosing;
+
+			private readonly List4 origInsertionPoint;
+
+			private readonly List4 origNext;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ObjectByRef.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ObjectByRef.cs
new file mode 100755
index 0000000..9348a1b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ObjectByRef.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>Useful as "out" or "by ref" function parameter.</summary>
+	/// <remarks>Useful as "out" or "by ref" function parameter.</remarks>
+	public sealed class ObjectByRef
+	{
+		public object value;
+
+		public ObjectByRef()
+		{
+		}
+
+		public ObjectByRef(object value_)
+		{
+			value = value_;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Pair.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Pair.cs
new file mode 100644
index 0000000..df29af9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Pair.cs
@@ -0,0 +1,82 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class Pair
+	{
+		public static Db4objects.Db4o.Foundation.Pair Of(object first, object second)
+		{
+			return new Db4objects.Db4o.Foundation.Pair(first, second);
+		}
+
+		public object first;
+
+		public object second;
+
+		public Pair(object first, object second)
+		{
+			this.first = first;
+			this.second = second;
+		}
+
+		public override string ToString()
+		{
+			return "Pair.of(" + first + ", " + second + ")";
+		}
+
+		public override int GetHashCode()
+		{
+			int prime = 31;
+			int result = 1;
+			result = prime * result + ((first == null) ? 0 : first.GetHashCode());
+			result = prime * result + ((second == null) ? 0 : second.GetHashCode());
+			return result;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj)
+			{
+				return true;
+			}
+			if (obj == null)
+			{
+				return false;
+			}
+			if (GetType() != obj.GetType())
+			{
+				return false;
+			}
+			Db4objects.Db4o.Foundation.Pair other = (Db4objects.Db4o.Foundation.Pair)obj;
+			if (first == null)
+			{
+				if (other.first != null)
+				{
+					return false;
+				}
+			}
+			else
+			{
+				if (!first.Equals(other.first))
+				{
+					return false;
+				}
+			}
+			if (second == null)
+			{
+				if (other.second != null)
+				{
+					return false;
+				}
+			}
+			else
+			{
+				if (!second.Equals(other.second))
+				{
+					return false;
+				}
+			}
+			return true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/PausableBlockingQueue.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/PausableBlockingQueue.cs
new file mode 100644
index 0000000..7e76005
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/PausableBlockingQueue.cs
@@ -0,0 +1,88 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class PausableBlockingQueue : BlockingQueue, IPausableBlockingQueue4
+	{
+		private volatile bool _paused = false;
+
+		public virtual bool Pause()
+		{
+			if (_paused)
+			{
+				return false;
+			}
+			_paused = true;
+			return true;
+		}
+
+		public virtual bool Resume()
+		{
+			return (((bool)_lock.Run(new _IClosure4_17(this))));
+		}
+
+		private sealed class _IClosure4_17 : IClosure4
+		{
+			public _IClosure4_17(PausableBlockingQueue _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Run()
+			{
+				if (!this._enclosing._paused)
+				{
+					return false;
+				}
+				this._enclosing._paused = false;
+				this._enclosing._lock.Awake();
+				return true;
+			}
+
+			private readonly PausableBlockingQueue _enclosing;
+		}
+
+		public virtual bool IsPaused()
+		{
+			return _paused;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Foundation.BlockingQueueStoppedException"></exception>
+		protected override bool UnsafeWaitForNext(long timeout)
+		{
+			bool hasNext = base.UnsafeWaitForNext(timeout);
+			while (_paused && !_stopped)
+			{
+				_lock.Snooze(timeout);
+			}
+			if (_stopped)
+			{
+				throw new BlockingQueueStoppedException();
+			}
+			return hasNext;
+		}
+
+		public virtual object TryNext()
+		{
+			return _lock.Run(new _IClosure4_46(this));
+		}
+
+		private sealed class _IClosure4_46 : IClosure4
+		{
+			public _IClosure4_46(PausableBlockingQueue _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Run()
+			{
+				return this._enclosing.IsPaused() ? null : this._enclosing.HasNext() ? this._enclosing
+					.Next() : null;
+			}
+
+			private readonly PausableBlockingQueue _enclosing;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/PrimitiveCodec.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/PrimitiveCodec.cs
new file mode 100644
index 0000000..6e14eb4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/PrimitiveCodec.cs
@@ -0,0 +1,84 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Sharpen.IO;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public sealed class PrimitiveCodec
+	{
+		public const int IntLength = 4;
+
+		public const int LongLength = 8;
+
+		public static int ReadInt(byte[] buffer, int offset)
+		{
+			offset += 3;
+			return (buffer[offset] & 255) | (buffer[--offset] & 255) << 8 | (buffer[--offset]
+				 & 255) << 16 | buffer[--offset] << 24;
+		}
+
+		public static int ReadInt(ByteArrayInputStream @in)
+		{
+			return (@in.Read() << 24) | ((@in.Read() & 255) << 16) | ((@in.Read() & 255) << 8
+				) | (@in.Read() & 255);
+		}
+
+		public static void WriteInt(byte[] buffer, int offset, int val)
+		{
+			offset += 3;
+			buffer[offset] = (byte)val;
+			buffer[--offset] = (byte)(val >>= 8);
+			buffer[--offset] = (byte)(val >>= 8);
+			buffer[--offset] = (byte)(val >> 8);
+		}
+
+		public static void WriteInt(ByteArrayOutputStream @out, int val)
+		{
+			@out.Write((byte)(val >> 24));
+			@out.Write((byte)(val >> 16));
+			@out.Write((byte)(val >> 8));
+			@out.Write((byte)val);
+		}
+
+		public static void WriteLong(byte[] buffer, long val)
+		{
+			WriteLong(buffer, 0, val);
+		}
+
+		public static void WriteLong(byte[] buffer, int offset, long val)
+		{
+			for (int i = 0; i < LongLength; i++)
+			{
+				buffer[offset++] = (byte)(val >> ((7 - i) * 8));
+			}
+		}
+
+		public static void WriteLong(ByteArrayOutputStream @out, long val)
+		{
+			for (int i = 0; i < LongLength; i++)
+			{
+				@out.Write((byte)(val >> ((7 - i) * 8)));
+			}
+		}
+
+		public static long ReadLong(byte[] buffer, int offset)
+		{
+			long ret = 0;
+			for (int i = 0; i < LongLength; i++)
+			{
+				ret = (ret << 8) + (buffer[offset++] & unchecked((int)(0xff)));
+			}
+			return ret;
+		}
+
+		public static long ReadLong(ByteArrayInputStream @in)
+		{
+			long ret = 0;
+			for (int i = 0; i < LongLength; i++)
+			{
+				ret = (ret << 8) + ((byte)@in.Read() & unchecked((int)(0xff)));
+			}
+			return ret;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Runnable4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Runnable4.cs
new file mode 100644
index 0000000..4229183
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Runnable4.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class Runnable4
+	{
+		private sealed class _IRunnable_10 : IRunnable
+		{
+			public _IRunnable_10()
+			{
+			}
+
+			public void Run()
+			{
+			}
+		}
+
+		public static readonly IRunnable DoNothing = new _IRunnable_10();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Runtime4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Runtime4.cs
new file mode 100644
index 0000000..36bce65
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Runtime4.cs
@@ -0,0 +1,71 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>A collection of static methods that should be part of the runtime environment but are not.
+	/// 	</summary>
+	/// <remarks>A collection of static methods that should be part of the runtime environment but are not.
+	/// 	</remarks>
+	/// <exclude></exclude>
+	public class Runtime4
+	{
+		/// <summary>sleeps without checked exceptions</summary>
+		public static void Sleep(long millis)
+		{
+			try
+			{
+				Thread.Sleep(millis);
+			}
+			catch (Exception)
+			{
+			}
+		}
+
+		/// <summary>sleeps with implicit exception</summary>
+		/// <exception cref="Db4objects.Db4o.Foundation.RuntimeInterruptedException"></exception>
+		public static void SleepThrowsOnInterrupt(long millis)
+		{
+			try
+			{
+				Thread.Sleep(millis);
+			}
+			catch (Exception e)
+			{
+				throw new RuntimeInterruptedException(e.ToString());
+			}
+		}
+
+		/// <summary>
+		/// Keeps executing a block of code until it either returns true or millisecondsTimeout
+		/// elapses.
+		/// </summary>
+		/// <remarks>
+		/// Keeps executing a block of code until it either returns true or millisecondsTimeout
+		/// elapses.
+		/// </remarks>
+		public static bool Retry(long millisecondsTimeout, IClosure4 block)
+		{
+			return Retry(millisecondsTimeout, 1, block);
+		}
+
+		public static bool Retry(long millisecondsTimeout, int millisecondsBetweenRetries
+			, IClosure4 block)
+		{
+			StopWatch watch = new AutoStopWatch();
+			do
+			{
+				if ((((bool)block.Run())))
+				{
+					return true;
+				}
+				Sleep(millisecondsBetweenRetries);
+			}
+			while (watch.Peek() < millisecondsTimeout);
+			return false;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/RuntimeInterruptedException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/RuntimeInterruptedException.cs
new file mode 100644
index 0000000..5db3071
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/RuntimeInterruptedException.cs
@@ -0,0 +1,14 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Foundation
+{
+	[System.Serializable]
+	public class RuntimeInterruptedException : Exception
+	{
+		public RuntimeInterruptedException(string msg) : base(msg)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SimpleObjectPool.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SimpleObjectPool.cs
new file mode 100644
index 0000000..75dcc32
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SimpleObjectPool.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class SimpleObjectPool : IObjectPool
+	{
+		private readonly object[] _objects;
+
+		private int _available;
+
+		public SimpleObjectPool(object[] objects)
+		{
+			int length = objects.Length;
+			_objects = new object[length];
+			for (int i = 0; i < length; ++i)
+			{
+				_objects[length - i - 1] = objects[i];
+			}
+			_available = length;
+		}
+
+		public virtual object BorrowObject()
+		{
+			if (_available == 0)
+			{
+				throw new InvalidOperationException();
+			}
+			return (object)_objects[--_available];
+		}
+
+		public virtual void ReturnObject(object o)
+		{
+			if (_available == _objects.Length)
+			{
+				throw new InvalidOperationException();
+			}
+			_objects[_available++] = o;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SimpleTimer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SimpleTimer.cs
new file mode 100644
index 0000000..bcea0b6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SimpleTimer.cs
@@ -0,0 +1,76 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public sealed class SimpleTimer : IRunnable
+	{
+		private readonly IRunnable _runnable;
+
+		private readonly long _interval;
+
+		private Lock4 _lock;
+
+		public volatile bool stopped = false;
+
+		public SimpleTimer(IRunnable runnable, long interval)
+		{
+			_runnable = runnable;
+			_interval = interval;
+			_lock = new Lock4();
+		}
+
+		public void Stop()
+		{
+			stopped = true;
+			_lock.Run(new _IClosure4_27(this));
+		}
+
+		private sealed class _IClosure4_27 : IClosure4
+		{
+			public _IClosure4_27(SimpleTimer _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Run()
+			{
+				this._enclosing._lock.Awake();
+				return null;
+			}
+
+			private readonly SimpleTimer _enclosing;
+		}
+
+		public void Run()
+		{
+			while (!stopped)
+			{
+				_lock.Run(new _IClosure4_37(this));
+				if (!stopped)
+				{
+					_runnable.Run();
+				}
+			}
+		}
+
+		private sealed class _IClosure4_37 : IClosure4
+		{
+			public _IClosure4_37(SimpleTimer _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Run()
+			{
+				this._enclosing._lock.Snooze(this._enclosing._interval);
+				return null;
+			}
+
+			private readonly SimpleTimer _enclosing;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SingleValueIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SingleValueIterator.cs
new file mode 100644
index 0000000..888d782
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SingleValueIterator.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class SingleValueIterator : IEnumerator
+	{
+		private object _value;
+
+		private bool _moved;
+
+		public SingleValueIterator(object value)
+		{
+			_value = value;
+		}
+
+		public virtual object Current
+		{
+			get
+			{
+				if (!_moved || _value == Iterators.NoElement)
+				{
+					throw new InvalidOperationException();
+				}
+				return _value;
+			}
+		}
+
+		public virtual bool MoveNext()
+		{
+			if (!_moved)
+			{
+				_moved = true;
+				return true;
+			}
+			_value = Iterators.NoElement;
+			return false;
+		}
+
+		public virtual void Reset()
+		{
+			throw new NotImplementedException();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SortedCollection4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SortedCollection4.cs
new file mode 100644
index 0000000..83f1ce8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SortedCollection4.cs
@@ -0,0 +1,82 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class SortedCollection4
+	{
+		private readonly IComparison4 _comparison;
+
+		private Tree _tree;
+
+		public SortedCollection4(IComparison4 comparison)
+		{
+			if (null == comparison)
+			{
+				throw new ArgumentNullException();
+			}
+			_comparison = comparison;
+			_tree = null;
+		}
+
+		public virtual object SingleElement()
+		{
+			if (1 != Size())
+			{
+				throw new InvalidOperationException();
+			}
+			return _tree.Key();
+		}
+
+		public virtual void AddAll(IEnumerator iterator)
+		{
+			while (iterator.MoveNext())
+			{
+				Add(iterator.Current);
+			}
+		}
+
+		public virtual void Add(object element)
+		{
+			_tree = Tree.Add(_tree, new TreeObject(element, _comparison));
+		}
+
+		public virtual void Remove(object element)
+		{
+			_tree = Tree.RemoveLike(_tree, new TreeObject(element, _comparison));
+		}
+
+		public virtual object[] ToArray(object[] array)
+		{
+			Tree.Traverse(_tree, new _IVisitor4_43(array));
+			return array;
+		}
+
+		private sealed class _IVisitor4_43 : IVisitor4
+		{
+			public _IVisitor4_43(object[] array)
+			{
+				this.array = array;
+				this.i = 0;
+			}
+
+			internal int i;
+
+			public void Visit(object obj)
+			{
+				array[this.i++] = ((TreeObject)obj).Key();
+			}
+
+			private readonly object[] array;
+		}
+
+		public virtual int Size()
+		{
+			return Tree.Size(_tree);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Stack4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Stack4.cs
new file mode 100644
index 0000000..a0f7ce4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Stack4.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class Stack4
+	{
+		private List4 _tail;
+
+		public virtual void Push(object obj)
+		{
+			_tail = new List4(_tail, obj);
+		}
+
+		public virtual object Peek()
+		{
+			if (_tail == null)
+			{
+				return null;
+			}
+			return _tail._element;
+		}
+
+		public virtual object Pop()
+		{
+			if (_tail == null)
+			{
+				throw new InvalidOperationException();
+			}
+			object res = _tail._element;
+			_tail = ((List4)_tail._next);
+			return res;
+		}
+
+		public virtual bool IsEmpty()
+		{
+			return _tail == null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/StopWatch.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/StopWatch.cs
new file mode 100644
index 0000000..8069212
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/StopWatch.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Sharpen;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class StopWatch
+	{
+		private long _started;
+
+		private long _elapsed;
+
+		public StopWatch()
+		{
+		}
+
+		public virtual void Start()
+		{
+			_started = Runtime.CurrentTimeMillis();
+		}
+
+		public virtual void Stop()
+		{
+			_elapsed = Peek();
+		}
+
+		public virtual long Peek()
+		{
+			return Runtime.CurrentTimeMillis() - _started;
+		}
+
+		public virtual long Elapsed()
+		{
+			return _elapsed;
+		}
+
+		public static long Time(IBlock4 block)
+		{
+			Db4objects.Db4o.Foundation.StopWatch stopWatch = new Db4objects.Db4o.Foundation.StopWatch
+				();
+			stopWatch.Start();
+			block.Run();
+			stopWatch.Stop();
+			return stopWatch.Elapsed();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SubTypePredicate.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SubTypePredicate.cs
new file mode 100644
index 0000000..59dca7a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SubTypePredicate.cs
@@ -0,0 +1,22 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class SubTypePredicate : IPredicate4
+	{
+		private readonly Type _class;
+
+		public SubTypePredicate(Type clazz)
+		{
+			_class = clazz;
+		}
+
+		public virtual bool Match(object candidate)
+		{
+			return _class.IsInstanceOfType(candidate);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SynchronizedHashtable4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SynchronizedHashtable4.cs
new file mode 100644
index 0000000..5a8bbe4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SynchronizedHashtable4.cs
@@ -0,0 +1,46 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class SynchronizedHashtable4 : IDeepClone
+	{
+		private readonly Hashtable4 _delegate;
+
+		private SynchronizedHashtable4(Hashtable4 delegate_)
+		{
+			_delegate = delegate_;
+		}
+
+		public SynchronizedHashtable4(int size) : this(new Hashtable4(size))
+		{
+		}
+
+		public virtual object DeepClone(object obj)
+		{
+			lock (this)
+			{
+				return new Db4objects.Db4o.Foundation.SynchronizedHashtable4((Hashtable4)_delegate
+					.DeepClone(obj));
+			}
+		}
+
+		public virtual void Put(object key, object value)
+		{
+			lock (this)
+			{
+				_delegate.Put(key, value);
+			}
+		}
+
+		public virtual object Get(object key)
+		{
+			lock (this)
+			{
+				return _delegate.Get(key);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SynchronizedIterator4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SynchronizedIterator4.cs
new file mode 100644
index 0000000..180392a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/SynchronizedIterator4.cs
@@ -0,0 +1,46 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class SynchronizedIterator4 : IEnumerator
+	{
+		private readonly IEnumerator _delegate;
+
+		private readonly object _lock;
+
+		public SynchronizedIterator4(IEnumerator delegate_, object Lock)
+		{
+			_delegate = delegate_;
+			_lock = Lock;
+		}
+
+		public virtual object Current
+		{
+			get
+			{
+				lock (_lock)
+				{
+					return _delegate.Current;
+				}
+			}
+		}
+
+		public virtual bool MoveNext()
+		{
+			lock (_lock)
+			{
+				return _delegate.MoveNext();
+			}
+		}
+
+		public virtual void Reset()
+		{
+			lock (_lock)
+			{
+				_delegate.Reset();
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TernaryBool.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TernaryBool.cs
new file mode 100644
index 0000000..171a043
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TernaryBool.cs
@@ -0,0 +1,138 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>yes/no/dontknow data type</summary>
+	/// <exclude></exclude>
+	[System.Serializable]
+	public sealed class TernaryBool
+	{
+		private const int NoId = -1;
+
+		private const int YesId = 1;
+
+		private const int UnspecifiedId = 0;
+
+		public static readonly Db4objects.Db4o.Foundation.TernaryBool No = new Db4objects.Db4o.Foundation.TernaryBool
+			(NoId);
+
+		public static readonly Db4objects.Db4o.Foundation.TernaryBool Yes = new Db4objects.Db4o.Foundation.TernaryBool
+			(YesId);
+
+		public static readonly Db4objects.Db4o.Foundation.TernaryBool Unspecified = new Db4objects.Db4o.Foundation.TernaryBool
+			(UnspecifiedId);
+
+		private readonly int _value;
+
+		private TernaryBool(int value)
+		{
+			_value = value;
+		}
+
+		public bool BooleanValue(bool defaultValue)
+		{
+			switch (_value)
+			{
+				case NoId:
+				{
+					return false;
+				}
+
+				case YesId:
+				{
+					return true;
+				}
+
+				default:
+				{
+					return defaultValue;
+					break;
+				}
+			}
+		}
+
+		public bool IsUnspecified()
+		{
+			return this == Unspecified;
+		}
+
+		public bool DefiniteYes()
+		{
+			return this == Yes;
+		}
+
+		public bool DefiniteNo()
+		{
+			return this == No;
+		}
+
+		public static Db4objects.Db4o.Foundation.TernaryBool ForBoolean(bool value)
+		{
+			return (value ? Yes : No);
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj)
+			{
+				return true;
+			}
+			if (obj == null || GetType() != obj.GetType())
+			{
+				return false;
+			}
+			Db4objects.Db4o.Foundation.TernaryBool tb = (Db4objects.Db4o.Foundation.TernaryBool
+				)obj;
+			return _value == tb._value;
+		}
+
+		public override int GetHashCode()
+		{
+			return _value;
+		}
+
+		private object ReadResolve()
+		{
+			switch (_value)
+			{
+				case NoId:
+				{
+					return No;
+				}
+
+				case YesId:
+				{
+					return Yes;
+				}
+
+				default:
+				{
+					return Unspecified;
+					break;
+				}
+			}
+		}
+
+		public override string ToString()
+		{
+			switch (_value)
+			{
+				case NoId:
+				{
+					return "NO";
+				}
+
+				case YesId:
+				{
+					return "YES";
+				}
+
+				default:
+				{
+					return "UNSPECIFIED";
+					break;
+				}
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ThreadLocal4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ThreadLocal4.cs
new file mode 100644
index 0000000..4cc05a6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/ThreadLocal4.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <summary>
+	/// ThreadLocal implementation for less capable platforms such as JRE 1.1 and
+	/// Silverlight.
+	/// </summary>
+	/// <remarks>
+	/// ThreadLocal implementation for less capable platforms such as JRE 1.1 and
+	/// Silverlight.
+	/// This class is not intended to be used directly, use
+	/// <see cref="DynamicVariable">DynamicVariable</see>
+	/// .
+	/// WARNING: This implementation might leak Thread references unless
+	/// <see cref="Set(object)">Set(object)</see>
+	/// is called with null on the right thread to clean it up. This
+	/// behavior is currently guaranteed by
+	/// <see cref="DynamicVariable">DynamicVariable</see>
+	/// .
+	/// </remarks>
+	public class ThreadLocal4
+	{
+		private readonly IDictionary _values = new Hashtable();
+
+		public virtual void Set(object value)
+		{
+			lock (this)
+			{
+				if (value == null)
+				{
+					Sharpen.Collections.Remove(_values, Thread.CurrentThread());
+				}
+				else
+				{
+					_values[Thread.CurrentThread()] = value;
+				}
+			}
+		}
+
+		public virtual object Get()
+		{
+			lock (this)
+			{
+				return _values[Thread.CurrentThread()];
+			}
+		}
+
+		protected object InitialValue()
+		{
+			return null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TimeStampIdGenerator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TimeStampIdGenerator.cs
new file mode 100644
index 0000000..4dadc85
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TimeStampIdGenerator.cs
@@ -0,0 +1,91 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Sharpen;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class TimeStampIdGenerator
+	{
+		public const int BitsReservedForCounter = 15;
+
+		public const int CounterLimit = 64;
+
+		private long _counter;
+
+		private long _lastTime;
+
+		public static long IdToMilliseconds(long id)
+		{
+			return id >> BitsReservedForCounter;
+		}
+
+		public static long MillisecondsToId(long milliseconds)
+		{
+			return milliseconds << BitsReservedForCounter;
+		}
+
+		public TimeStampIdGenerator(long minimumNext)
+		{
+			InternalSetMinimumNext(minimumNext);
+		}
+
+		public TimeStampIdGenerator() : this(0)
+		{
+		}
+
+		public virtual long Generate()
+		{
+			long t = Now();
+			if (t > _lastTime)
+			{
+				_lastTime = t;
+				_counter = 0;
+				return MillisecondsToId(t);
+			}
+			UpdateTimeOnCounterLimitOverflow();
+			_counter++;
+			UpdateTimeOnCounterLimitOverflow();
+			return Last();
+		}
+
+		protected virtual long Now()
+		{
+			return Runtime.CurrentTimeMillis();
+		}
+
+		private void UpdateTimeOnCounterLimitOverflow()
+		{
+			if (_counter < CounterLimit)
+			{
+				return;
+			}
+			long timeIncrement = _counter / CounterLimit;
+			_lastTime += timeIncrement;
+			_counter -= (timeIncrement * CounterLimit);
+		}
+
+		public virtual long Last()
+		{
+			return MillisecondsToId(_lastTime) + _counter;
+		}
+
+		public virtual bool SetMinimumNext(long newMinimum)
+		{
+			if (newMinimum <= Last())
+			{
+				return false;
+			}
+			InternalSetMinimumNext(newMinimum);
+			return true;
+		}
+
+		private void InternalSetMinimumNext(long newNext)
+		{
+			_lastTime = IdToMilliseconds(newNext);
+			long timePart = MillisecondsToId(_lastTime);
+			_counter = newNext - timePart;
+			UpdateTimeOnCounterLimitOverflow();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TimeoutBlockingQueue.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TimeoutBlockingQueue.cs
new file mode 100644
index 0000000..ffcb454
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TimeoutBlockingQueue.cs
@@ -0,0 +1,39 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Sharpen;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class TimeoutBlockingQueue : PausableBlockingQueue, ITimeoutBlockingQueue4
+	{
+		private long expirationDate;
+
+		private readonly long maxTimeToRemainPaused;
+
+		public TimeoutBlockingQueue(long maxTimeToRemainPaused)
+		{
+			this.maxTimeToRemainPaused = maxTimeToRemainPaused;
+		}
+
+		public override bool Pause()
+		{
+			Reset();
+			return base.Pause();
+		}
+
+		public virtual void Check()
+		{
+			long now = Runtime.CurrentTimeMillis();
+			if (now > expirationDate)
+			{
+				Resume();
+			}
+		}
+
+		public virtual void Reset()
+		{
+			expirationDate = Runtime.CurrentTimeMillis() + maxTimeToRemainPaused;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Tree.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Tree.cs
new file mode 100644
index 0000000..1a62b7b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/Tree.cs
@@ -0,0 +1,694 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public abstract class Tree : IShallowClone, IDeepClone, IVisitable
+	{
+		public Tree _preceding;
+
+		public int _size = 1;
+
+		public Tree _subsequent;
+
+		public static Tree Add(Tree oldTree, Tree newTree)
+		{
+			if (oldTree == null)
+			{
+				return newTree;
+			}
+			return (Tree)((Tree)oldTree).Add(newTree);
+		}
+
+		public Tree Add(Tree newNode)
+		{
+			return Add(newNode, Compare(newNode));
+		}
+
+		/// <summary>
+		/// On adding a node to a tree, if it already exists, and if
+		/// Tree#duplicates() returns false, #isDuplicateOf() will be
+		/// called.
+		/// </summary>
+		/// <remarks>
+		/// On adding a node to a tree, if it already exists, and if
+		/// Tree#duplicates() returns false, #isDuplicateOf() will be
+		/// called. The added node can then be asked for the node that
+		/// prevails in the tree using #duplicateOrThis(). This mechanism
+		/// allows doing find() and add() in one run.
+		/// </remarks>
+		public virtual Tree Add(Tree newNode, int cmp)
+		{
+			if (cmp < 0)
+			{
+				if (_subsequent == null)
+				{
+					_subsequent = newNode;
+					_size++;
+				}
+				else
+				{
+					_subsequent = _subsequent.Add(newNode);
+					if (_preceding == null)
+					{
+						return (Tree)RotateLeft();
+					}
+					return (Tree)Balance();
+				}
+			}
+			else
+			{
+				if (cmp > 0 || ((Tree)newNode).Duplicates())
+				{
+					if (_preceding == null)
+					{
+						_preceding = newNode;
+						_size++;
+					}
+					else
+					{
+						_preceding = _preceding.Add(newNode);
+						if (_subsequent == null)
+						{
+							return (Tree)RotateRight();
+						}
+						return (Tree)Balance();
+					}
+				}
+				else
+				{
+					return (Tree)((Tree)newNode).OnAttemptToAddDuplicate(this);
+				}
+			}
+			return (Tree)this;
+		}
+
+		/// <summary>
+		/// On adding a node to a tree, if it already exists, and if
+		/// Tree#duplicates() returns false, #onAttemptToAddDuplicate()
+		/// will be called and the existing node will be stored in
+		/// this._preceding.
+		/// </summary>
+		/// <remarks>
+		/// On adding a node to a tree, if it already exists, and if
+		/// Tree#duplicates() returns false, #onAttemptToAddDuplicate()
+		/// will be called and the existing node will be stored in
+		/// this._preceding.
+		/// This node node can then be asked for the node that prevails
+		/// in the tree on adding, using the #addedOrExisting() method.
+		/// This mechanism allows doing find() and add() in one run.
+		/// </remarks>
+		public virtual Tree AddedOrExisting()
+		{
+			if (WasAddedToTree())
+			{
+				return this;
+			}
+			return _preceding;
+		}
+
+		public virtual bool WasAddedToTree()
+		{
+			return _size != 0;
+		}
+
+		public Tree Balance()
+		{
+			int cmp = _subsequent.Nodes() - _preceding.Nodes();
+			if (cmp < -2)
+			{
+				return RotateRight();
+			}
+			else
+			{
+				if (cmp > 2)
+				{
+					return RotateLeft();
+				}
+				else
+				{
+					SetSizeOwnPrecedingSubsequent();
+					return this;
+				}
+			}
+		}
+
+		public virtual Tree BalanceCheckNulls()
+		{
+			if (_subsequent == null)
+			{
+				if (_preceding == null)
+				{
+					SetSizeOwn();
+					return this;
+				}
+				return RotateRight();
+			}
+			else
+			{
+				if (_preceding == null)
+				{
+					return RotateLeft();
+				}
+			}
+			return Balance();
+		}
+
+		public virtual void CalculateSize()
+		{
+			if (_preceding == null)
+			{
+				if (_subsequent == null)
+				{
+					SetSizeOwn();
+				}
+				else
+				{
+					SetSizeOwnSubsequent();
+				}
+			}
+			else
+			{
+				if (_subsequent == null)
+				{
+					SetSizeOwnPreceding();
+				}
+				else
+				{
+					SetSizeOwnPrecedingSubsequent();
+				}
+			}
+		}
+
+		/// <summary>
+		/// returns 0, if keys are equal
+		/// uses this - other
+		/// returns positive if this is greater than a_to
+		/// returns negative if this is smaller than a_to
+		/// </summary>
+		public abstract int Compare(Tree a_to);
+
+		public static Tree DeepClone(Tree a_tree, object a_param)
+		{
+			if (a_tree == null)
+			{
+				return null;
+			}
+			Tree newNode = (Tree)a_tree.DeepClone(a_param);
+			newNode._size = a_tree._size;
+			newNode._preceding = Tree.DeepClone(((Tree)a_tree._preceding), a_param);
+			newNode._subsequent = Tree.DeepClone(((Tree)a_tree._subsequent), a_param);
+			return newNode;
+		}
+
+		public virtual object DeepClone(object a_param)
+		{
+			return ShallowClone();
+		}
+
+		public virtual bool Duplicates()
+		{
+			return true;
+		}
+
+		public Tree Filter(IPredicate4 a_filter)
+		{
+			if (_preceding != null)
+			{
+				_preceding = _preceding.Filter(a_filter);
+			}
+			if (_subsequent != null)
+			{
+				_subsequent = _subsequent.Filter(a_filter);
+			}
+			if (!a_filter.Match(this))
+			{
+				return Remove();
+			}
+			return this;
+		}
+
+		public static Tree Find(Tree inTree, Tree template)
+		{
+			if (inTree == null)
+			{
+				return null;
+			}
+			return inTree.Find(template);
+		}
+
+		public Tree Find(Tree template)
+		{
+			Tree current = this;
+			while (true)
+			{
+				int comparisonResult = current.Compare(template);
+				if (comparisonResult == 0)
+				{
+					return current;
+				}
+				if (comparisonResult < 0)
+				{
+					current = ((Tree)current._subsequent);
+				}
+				else
+				{
+					current = ((Tree)current._preceding);
+				}
+				if (current == null)
+				{
+					return null;
+				}
+			}
+		}
+
+		public static Tree FindGreaterOrEqual(Tree a_in, Tree a_finder)
+		{
+			if (a_in == null)
+			{
+				return null;
+			}
+			int cmp = a_in.Compare(a_finder);
+			if (cmp == 0)
+			{
+				return a_in;
+			}
+			// the highest node in the hierarchy !!!
+			if (cmp > 0)
+			{
+				Tree node = FindGreaterOrEqual(((Tree)a_in._preceding), a_finder);
+				if (node != null)
+				{
+					return node;
+				}
+				return a_in;
+			}
+			return FindGreaterOrEqual(((Tree)a_in._subsequent), a_finder);
+		}
+
+		public static Tree FindSmaller(Tree a_in, Tree a_node)
+		{
+			if (a_in == null)
+			{
+				return null;
+			}
+			int cmp = a_in.Compare(a_node);
+			if (cmp < 0)
+			{
+				Tree node = FindSmaller(((Tree)a_in._subsequent), a_node);
+				if (node != null)
+				{
+					return node;
+				}
+				return a_in;
+			}
+			return FindSmaller(((Tree)a_in._preceding), a_node);
+		}
+
+		public Tree First()
+		{
+			if (_preceding == null)
+			{
+				return this;
+			}
+			return _preceding.First();
+		}
+
+		public static Tree Last(Tree tree)
+		{
+			if (tree == null)
+			{
+				return null;
+			}
+			return tree.Last();
+		}
+
+		public Tree Last()
+		{
+			if (_subsequent == null)
+			{
+				return this;
+			}
+			return _subsequent.Last();
+		}
+
+		public virtual Tree OnAttemptToAddDuplicate(Tree oldNode)
+		{
+			_size = 0;
+			_preceding = oldNode;
+			return oldNode;
+		}
+
+		/// <returns>the number of nodes in this tree for balancing</returns>
+		public virtual int Nodes()
+		{
+			return _size;
+		}
+
+		public virtual int OwnSize()
+		{
+			return 1;
+		}
+
+		public virtual Tree Remove()
+		{
+			if (_subsequent != null && _preceding != null)
+			{
+				_subsequent = _subsequent.RotateSmallestUp();
+				_subsequent._preceding = _preceding;
+				_subsequent.CalculateSize();
+				return _subsequent;
+			}
+			if (_subsequent != null)
+			{
+				return _subsequent;
+			}
+			return _preceding;
+		}
+
+		public virtual void RemoveChildren()
+		{
+			_preceding = null;
+			_subsequent = null;
+			SetSizeOwn();
+		}
+
+		public virtual Tree RemoveFirst()
+		{
+			if (_preceding == null)
+			{
+				return _subsequent;
+			}
+			_preceding = _preceding.RemoveFirst();
+			CalculateSize();
+			return this;
+		}
+
+		public static Tree RemoveLike(Tree from, Tree a_find)
+		{
+			if (from == null)
+			{
+				return null;
+			}
+			return from.RemoveLike(a_find);
+		}
+
+		public Tree RemoveLike(Tree a_find)
+		{
+			int cmp = Compare(a_find);
+			if (cmp == 0)
+			{
+				return (Tree)Remove();
+			}
+			if (cmp > 0)
+			{
+				if (_preceding != null)
+				{
+					_preceding = _preceding.RemoveLike(a_find);
+				}
+			}
+			else
+			{
+				if (_subsequent != null)
+				{
+					_subsequent = _subsequent.RemoveLike(a_find);
+				}
+			}
+			CalculateSize();
+			return (Tree)this;
+		}
+
+		public Tree RemoveNode(Tree a_tree)
+		{
+			if (this == a_tree)
+			{
+				return Remove();
+			}
+			int cmp = Compare(a_tree);
+			if (cmp >= 0)
+			{
+				if (_preceding != null)
+				{
+					_preceding = _preceding.RemoveNode(a_tree);
+				}
+			}
+			if (cmp <= 0)
+			{
+				if (_subsequent != null)
+				{
+					_subsequent = _subsequent.RemoveNode(a_tree);
+				}
+			}
+			CalculateSize();
+			return this;
+		}
+
+		public Tree RotateLeft()
+		{
+			Tree tree = _subsequent;
+			_subsequent = ((Tree)tree._preceding);
+			CalculateSize();
+			tree._preceding = this;
+			if (((Tree)tree._subsequent) == null)
+			{
+				tree.SetSizeOwnPlus(this);
+			}
+			else
+			{
+				tree.SetSizeOwnPlus(this, ((Tree)tree._subsequent));
+			}
+			return tree;
+		}
+
+		public Tree RotateRight()
+		{
+			Tree tree = _preceding;
+			_preceding = ((Tree)tree._subsequent);
+			CalculateSize();
+			tree._subsequent = this;
+			if (((Tree)tree._preceding) == null)
+			{
+				tree.SetSizeOwnPlus(this);
+			}
+			else
+			{
+				tree.SetSizeOwnPlus(this, ((Tree)tree._preceding));
+			}
+			return tree;
+		}
+
+		private Tree RotateSmallestUp()
+		{
+			if (_preceding != null)
+			{
+				_preceding = _preceding.RotateSmallestUp();
+				return RotateRight();
+			}
+			return this;
+		}
+
+		public void SetSizeOwn()
+		{
+			_size = OwnSize();
+		}
+
+		public void SetSizeOwnPrecedingSubsequent()
+		{
+			_size = OwnSize() + _preceding._size + _subsequent._size;
+		}
+
+		public void SetSizeOwnPreceding()
+		{
+			_size = OwnSize() + _preceding._size;
+		}
+
+		public void SetSizeOwnSubsequent()
+		{
+			_size = OwnSize() + _subsequent._size;
+		}
+
+		public void SetSizeOwnPlus(Tree tree)
+		{
+			_size = OwnSize() + tree._size;
+		}
+
+		public void SetSizeOwnPlus(Tree tree1, Tree tree2)
+		{
+			_size = OwnSize() + tree1._size + tree2._size;
+		}
+
+		public static int Size(Tree a_tree)
+		{
+			if (a_tree == null)
+			{
+				return 0;
+			}
+			return a_tree.Size();
+		}
+
+		/// <returns>the number of objects represented.</returns>
+		public virtual int Size()
+		{
+			return _size;
+		}
+
+		public static void Traverse(Tree tree, IVisitor4 visitor)
+		{
+			if (tree == null)
+			{
+				return;
+			}
+			tree.Traverse(visitor);
+		}
+
+		/// <summary>Traverses a tree with a starting point node.</summary>
+		/// <remarks>
+		/// Traverses a tree with a starting point node.
+		/// If there is no exact match for the starting node, the next higher will be taken.
+		/// </remarks>
+		public static void Traverse(Tree tree, Tree startingNode, ICancellableVisitor4 visitor
+			)
+		{
+			if (tree == null)
+			{
+				return;
+			}
+			tree.Traverse(startingNode, visitor);
+		}
+
+		private bool Traverse(Tree startingNode, ICancellableVisitor4 visitor)
+		{
+			if (startingNode != null)
+			{
+				int cmp = Compare(startingNode);
+				if (cmp < 0)
+				{
+					if (_subsequent != null)
+					{
+						return _subsequent.Traverse(startingNode, visitor);
+					}
+					return true;
+				}
+				else
+				{
+					if (cmp > 0)
+					{
+						if (_preceding != null)
+						{
+							if (!_preceding.Traverse(startingNode, visitor))
+							{
+								return false;
+							}
+						}
+					}
+				}
+			}
+			else
+			{
+				if (_preceding != null)
+				{
+					if (!_preceding.Traverse(null, visitor))
+					{
+						return false;
+					}
+				}
+			}
+			if (!visitor.Visit(this))
+			{
+				return false;
+			}
+			if (_subsequent != null)
+			{
+				if (!_subsequent.Traverse(null, visitor))
+				{
+					return false;
+				}
+			}
+			return true;
+		}
+
+		public void Traverse(IVisitor4 visitor)
+		{
+			if (_preceding != null)
+			{
+				_preceding.Traverse(visitor);
+			}
+			visitor.Visit((Tree)this);
+			if (_subsequent != null)
+			{
+				_subsequent.Traverse(visitor);
+			}
+		}
+
+		public void TraverseFromLeaves(IVisitor4 a_visitor)
+		{
+			if (_preceding != null)
+			{
+				_preceding.TraverseFromLeaves(a_visitor);
+			}
+			if (_subsequent != null)
+			{
+				_subsequent.TraverseFromLeaves(a_visitor);
+			}
+			a_visitor.Visit(this);
+		}
+
+		// Keep the debug method to debug the depth
+		//	public final void debugLeafDepth(int currentDepth){
+		//		currentDepth++;
+		//		if(_preceding == null && _subsequent == null){
+		//			System.out.println("" + currentDepth + " tree leaf depth.");
+		//			return;
+		//		}
+		//	    if (_preceding != null){
+		//	    	_preceding.debugLeafDepth(currentDepth);
+		//	    }
+		//	    if(_subsequent != null){
+		//	    	_subsequent.debugLeafDepth(currentDepth);
+		//	    }
+		//	}
+		protected virtual Tree ShallowCloneInternal(Tree tree)
+		{
+			tree._preceding = _preceding;
+			tree._size = _size;
+			tree._subsequent = _subsequent;
+			return tree;
+		}
+
+		public virtual object ShallowClone()
+		{
+			throw new NotImplementedException();
+		}
+
+		public abstract object Key();
+
+		public virtual object Root()
+		{
+			return this;
+		}
+
+		public virtual void Accept(IVisitor4 visitor)
+		{
+			Traverse(new _IVisitor4_513(visitor));
+		}
+
+		private sealed class _IVisitor4_513 : IVisitor4
+		{
+			public _IVisitor4_513(IVisitor4 visitor)
+			{
+				this.visitor = visitor;
+			}
+
+			public void Visit(object obj)
+			{
+				Tree tree = (Tree)obj;
+				visitor.Visit(tree.Key());
+			}
+
+			private readonly IVisitor4 visitor;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TreeKeyIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TreeKeyIterator.cs
new file mode 100644
index 0000000..21f977f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TreeKeyIterator.cs
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class TreeKeyIterator : AbstractTreeIterator
+	{
+		public TreeKeyIterator(Tree tree) : base(tree)
+		{
+		}
+
+		protected override object CurrentValue(Tree tree)
+		{
+			return tree.Key();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TreeNodeIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TreeNodeIterator.cs
new file mode 100644
index 0000000..c6aec0f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TreeNodeIterator.cs
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class TreeNodeIterator : AbstractTreeIterator
+	{
+		public TreeNodeIterator(Tree tree) : base(tree)
+		{
+		}
+
+		protected override object CurrentValue(Tree tree)
+		{
+			return tree.Root();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TreeObject.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TreeObject.cs
new file mode 100644
index 0000000..4afc5e4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Foundation/TreeObject.cs
@@ -0,0 +1,30 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Foundation
+{
+	/// <exclude></exclude>
+	public class TreeObject : Tree
+	{
+		private readonly object _object;
+
+		private readonly IComparison4 _function;
+
+		public TreeObject(object @object, IComparison4 function)
+		{
+			_object = @object;
+			_function = function;
+		}
+
+		public override int Compare(Tree tree)
+		{
+			return _function.Compare(_object, tree.Key());
+		}
+
+		public override object Key()
+		{
+			return _object;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IBlobStatus.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IBlobStatus.cs
new file mode 100644
index 0000000..10417b2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IBlobStatus.cs
@@ -0,0 +1,11 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o
+{
+	/// <exclude></exclude>
+	/// <moveto>com.db4o.internal.blobs</moveto>
+	public interface IBlobStatus
+	{
+		double GetStatus();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IBlobTransport.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IBlobTransport.cs
new file mode 100644
index 0000000..0a1a83a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IBlobTransport.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+#if !SILVERLIGHT
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o
+{
+	/// <exclude></exclude>
+	public interface IBlobTransport
+	{
+		/// <exception cref="System.IO.IOException"></exception>
+		void WriteBlobTo(Transaction trans, BlobImpl blob);
+
+		/// <exception cref="System.IO.IOException"></exception>
+		void ReadBlobFrom(Transaction trans, BlobImpl blob);
+
+		void DeleteBlobFile(Transaction trans, BlobImpl blob);
+	}
+}
+#endif // !SILVERLIGHT
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IEmbeddedObjectContainer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IEmbeddedObjectContainer.cs
new file mode 100644
index 0000000..664fe08
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IEmbeddedObjectContainer.cs
@@ -0,0 +1,41 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o
+{
+	/// <summary>
+	/// Represents a local ObjectContainer attached to a
+	/// database file.
+	/// </summary>
+	/// <remarks>
+	/// Represents a local ObjectContainer attached to a
+	/// database file.
+	/// </remarks>
+	/// <since>7.10</since>
+	public interface IEmbeddedObjectContainer : IObjectContainer
+	{
+		/// <summary>backs up a database file of an open ObjectContainer.</summary>
+		/// <remarks>
+		/// backs up a database file of an open ObjectContainer.
+		/// <br /><br />While the backup is running, the ObjectContainer can continue to be
+		/// used. Changes that are made while the backup is in progress, will be applied to
+		/// the open ObjectContainer and to the backup.<br /><br />
+		/// While the backup is running, the ObjectContainer should not be closed.<br /><br />
+		/// If a file already exists at the specified path, it will be overwritten.<br /><br />
+		/// The
+		/// <see cref="Db4objects.Db4o.IO.IStorage">Db4objects.Db4o.IO.IStorage</see>
+		/// used for backup is the one configured for this container.
+		/// </remarks>
+		/// <param name="path">a fully qualified path</param>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException">db4o database file was closed or failed to open.
+		/// 	</exception>
+		/// <exception cref="System.NotSupportedException">
+		/// is thrown when the operation is not supported in current
+		/// configuration/environment
+		/// </exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException">I/O operation failed or was unexpectedly interrupted.
+		/// 	</exception>
+		void Backup(string path);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IInternal4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IInternal4.cs
new file mode 100644
index 0000000..7095ce8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IInternal4.cs
@@ -0,0 +1,11 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o
+{
+	/// <summary>Marker interface to denote that a class is used for db4o internals.</summary>
+	/// <remarks>Marker interface to denote that a class is used for db4o internals.</remarks>
+	/// <exclude></exclude>
+	public interface IInternal4
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/BinConfiguration.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/BinConfiguration.cs
new file mode 100644
index 0000000..cda0536
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/BinConfiguration.cs
@@ -0,0 +1,64 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.IO
+{
+	/// <exclude></exclude>
+	public class BinConfiguration
+	{
+		private readonly string _uri;
+
+		private readonly bool _lockFile;
+
+		private readonly long _initialLength;
+
+		private readonly bool _readOnly;
+
+		private readonly int _blockSize;
+
+		public BinConfiguration(string uri, bool lockFile, long initialLength, bool readOnly
+			) : this(uri, lockFile, initialLength, readOnly, 1)
+		{
+		}
+
+		public BinConfiguration(string uri, bool lockFile, long initialLength, bool readOnly
+			, int blockSize)
+		{
+			_uri = uri;
+			_lockFile = lockFile;
+			_initialLength = initialLength;
+			_readOnly = readOnly;
+			_blockSize = blockSize;
+		}
+
+		public virtual string Uri()
+		{
+			return _uri;
+		}
+
+		public virtual bool LockFile()
+		{
+			return _lockFile;
+		}
+
+		public virtual long InitialLength()
+		{
+			return _initialLength;
+		}
+
+		public virtual bool ReadOnly()
+		{
+			return _readOnly;
+		}
+
+		public virtual int BlockSize()
+		{
+			return _blockSize;
+		}
+
+		public override string ToString()
+		{
+			return "BinConfiguration(Uri: " + _uri + ", Locked: " + _lockFile + ", ReadOnly: "
+				 + _readOnly + ", BlockSize: " + _blockSize + ")";
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/BinDecorator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/BinDecorator.cs
new file mode 100644
index 0000000..0ba3c98
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/BinDecorator.cs
@@ -0,0 +1,80 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.IO;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>Wrapper baseclass for all classes that wrap Bin.</summary>
+	/// <remarks>
+	/// Wrapper baseclass for all classes that wrap Bin.
+	/// Each class that adds functionality to a Bin must
+	/// extend this class to allow db4o to access the
+	/// delegate instance with
+	/// <see cref="StorageDecorator.Decorate(BinConfiguration, IBin)">StorageDecorator.Decorate(BinConfiguration, IBin)
+	/// 	</see>
+	/// .
+	/// </remarks>
+	public class BinDecorator : IBin
+	{
+		protected readonly IBin _bin;
+
+		/// <summary>Default constructor.</summary>
+		/// <remarks>Default constructor.</remarks>
+		/// <param name="bin">
+		/// the
+		/// <see cref="IBin">IBin</see>
+		/// that is to be wrapped.
+		/// </param>
+		public BinDecorator(IBin bin)
+		{
+			_bin = bin;
+		}
+
+		/// <summary>
+		/// closes the BinDecorator and the underlying
+		/// <see cref="IBin">IBin</see>
+		/// .
+		/// </summary>
+		public virtual void Close()
+		{
+			_bin.Close();
+		}
+
+		/// <seealso cref="IBin.Length()"></seealso>
+		public virtual long Length()
+		{
+			return _bin.Length();
+		}
+
+		/// <seealso cref="IBin.Read(long, byte[], int)">IBin.Read(long, byte[], int)</seealso>
+		public virtual int Read(long position, byte[] bytes, int bytesToRead)
+		{
+			return _bin.Read(position, bytes, bytesToRead);
+		}
+
+		/// <seealso cref="IBin.Sync()">IBin.Sync()</seealso>
+		public virtual void Sync()
+		{
+			_bin.Sync();
+		}
+
+		/// <seealso cref="IBin.SyncRead(long, byte[], int)">IBin.SyncRead(long, byte[], int)
+		/// 	</seealso>
+		public virtual int SyncRead(long position, byte[] bytes, int bytesToRead)
+		{
+			return _bin.SyncRead(position, bytes, bytesToRead);
+		}
+
+		/// <seealso cref="IBin.Write(long, byte[], int)">IBin.Write(long, byte[], int)</seealso>
+		public virtual void Write(long position, byte[] bytes, int bytesToWrite)
+		{
+			_bin.Write(position, bytes, bytesToWrite);
+		}
+
+		public virtual void Sync(IRunnable runnable)
+		{
+			_bin.Sync(runnable);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/BlockAwareBin.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/BlockAwareBin.cs
new file mode 100644
index 0000000..b65f414
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/BlockAwareBin.cs
@@ -0,0 +1,212 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.IO;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <exclude></exclude>
+	public class BlockAwareBin : BinDecorator
+	{
+		private const int CopySize = 4096;
+
+		private bool _readOnly;
+
+		private readonly IBlockSize _blockSize = ((IBlockSize)Environments.My(typeof(IBlockSize
+			)));
+
+		public BlockAwareBin(IBin bin) : base(bin)
+		{
+		}
+
+		/// <summary>converts address and address offset to an absolute address</summary>
+		protected long RegularAddress(int blockAddress, int blockAddressOffset)
+		{
+			if (0 == BlockSize())
+			{
+				throw new InvalidOperationException();
+			}
+			return (long)blockAddress * BlockSize() + blockAddressOffset;
+		}
+
+		/// <summary>copies a block within a file in block mode</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void BlockCopy(int oldAddress, int oldAddressOffset, int newAddress
+			, int newAddressOffset, int length)
+		{
+			Copy(RegularAddress(oldAddress, oldAddressOffset), RegularAddress(newAddress, newAddressOffset
+				), length);
+		}
+
+		/// <summary>copies a block within a file in absolute mode</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Copy(long oldAddress, long newAddress, int length)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.IoCopy.LogLength(newAddress, length);
+			}
+			if (length > CopySize)
+			{
+				byte[] buffer = new byte[CopySize];
+				int pos = 0;
+				while (pos + CopySize < length)
+				{
+					Copy(buffer, oldAddress + pos, newAddress + pos);
+					pos += CopySize;
+				}
+				oldAddress += pos;
+				newAddress += pos;
+				length -= pos;
+			}
+			Copy(new byte[length], oldAddress, newAddress);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private void Copy(byte[] buffer, long oldAddress, long newAddress)
+		{
+			Read(oldAddress, buffer);
+			Write(oldAddress, buffer);
+		}
+
+		/// <summary>reads a buffer at the seeked address</summary>
+		/// <returns>the number of bytes read and returned</returns>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual int BlockRead(int address, int offset, byte[] buffer)
+		{
+			return BlockRead(address, offset, buffer, buffer.Length);
+		}
+
+		/// <summary>implement to read a buffer at the seeked address</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual int BlockRead(int address, int offset, byte[] bytes, int length)
+		{
+			return Read(RegularAddress(address, offset), bytes, length);
+		}
+
+		/// <summary>reads a buffer at the seeked address</summary>
+		/// <returns>the number of bytes read and returned</returns>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual int BlockRead(int address, byte[] buffer)
+		{
+			return BlockRead(address, 0, buffer, buffer.Length);
+		}
+
+		/// <summary>implement to read a buffer at the seeked address</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual int BlockRead(int address, byte[] bytes, int length)
+		{
+			return BlockRead(address, 0, bytes, length);
+		}
+
+		/// <summary>reads a buffer at the seeked address</summary>
+		/// <returns>the number of bytes read and returned</returns>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual int Read(long pos, byte[] buffer)
+		{
+			return Read(pos, buffer, buffer.Length);
+		}
+
+		/// <summary>reads a buffer at the seeked address</summary>
+		/// <returns>the number of bytes read and returned</returns>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void BlockWrite(int address, int offset, byte[] buffer)
+		{
+			BlockWrite(address, offset, buffer, buffer.Length);
+		}
+
+		/// <summary>implement to read a buffer at the seeked address</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void BlockWrite(int address, int offset, byte[] bytes, int length)
+		{
+			Write(RegularAddress(address, offset), bytes, length);
+		}
+
+		/// <summary>reads a buffer at the seeked address</summary>
+		/// <returns>the number of bytes read and returned</returns>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void BlockWrite(int address, byte[] buffer)
+		{
+			BlockWrite(address, 0, buffer, buffer.Length);
+		}
+
+		/// <summary>implement to read a buffer at the seeked address</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void BlockWrite(int address, byte[] bytes, int length)
+		{
+			BlockWrite(address, 0, bytes, length);
+		}
+
+		public override void Sync()
+		{
+			ValidateReadOnly();
+			try
+			{
+				base.Sync();
+			}
+			catch (Db4oIOException e)
+			{
+				_readOnly = true;
+				throw;
+			}
+		}
+
+		public override void Sync(IRunnable runnable)
+		{
+			ValidateReadOnly();
+			try
+			{
+				base.Sync(runnable);
+			}
+			catch (Db4oIOException e)
+			{
+				_readOnly = true;
+				throw;
+			}
+		}
+
+		/// <summary>writes a buffer to the seeked address</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Write(long pos, byte[] bytes)
+		{
+			ValidateReadOnly();
+			try
+			{
+				Write(pos, bytes, bytes.Length);
+			}
+			catch (Db4oIOException e)
+			{
+				_readOnly = true;
+				throw;
+			}
+		}
+
+		private void ValidateReadOnly()
+		{
+			if (_readOnly)
+			{
+				throw new EmergencyShutdownReadOnlyException();
+			}
+		}
+
+		/// <summary>returns the block size currently used</summary>
+		public virtual int BlockSize()
+		{
+			return _blockSize.Value();
+		}
+
+		/// <summary>outside call to set the block size of this adapter</summary>
+		public virtual void BlockSize(int blockSize)
+		{
+			if (blockSize < 1)
+			{
+				throw new ArgumentException();
+			}
+			_blockSize.Set(blockSize);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/BlockAwareBinWindow.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/BlockAwareBinWindow.cs
new file mode 100644
index 0000000..77219fe
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/BlockAwareBinWindow.cs
@@ -0,0 +1,87 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.IO;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>Bounded handle into an IoAdapter: Can only access a restricted area.</summary>
+	/// <remarks>Bounded handle into an IoAdapter: Can only access a restricted area.</remarks>
+	/// <exclude></exclude>
+	public class BlockAwareBinWindow
+	{
+		private BlockAwareBin _bin;
+
+		private int _blockOff;
+
+		private int _len;
+
+		private bool _disabled;
+
+		/// <param name="io">The delegate I/O adapter</param>
+		/// <param name="blockOff">The block offset address into the I/O adapter that maps to the start index (0) of this window
+		/// 	</param>
+		/// <param name="len">The size of this window in bytes</param>
+		public BlockAwareBinWindow(BlockAwareBin io, int blockOff, int len)
+		{
+			_bin = io;
+			_blockOff = blockOff;
+			_len = len;
+			_disabled = false;
+		}
+
+		/// <returns>Size of this I/O adapter window in bytes.</returns>
+		public virtual int Length()
+		{
+			return _len;
+		}
+
+		/// <param name="off">Offset in bytes relative to the window start</param>
+		/// <param name="data">Data to write into the window starting from the given offset</param>
+		/// <exception cref="System.ArgumentException"></exception>
+		/// <exception cref="System.InvalidOperationException"></exception>
+		public virtual void Write(int off, byte[] data)
+		{
+			CheckBounds(off, data);
+			_bin.BlockWrite(_blockOff + off, data);
+		}
+
+		/// <param name="off">Offset in bytes relative to the window start</param>
+		/// <param name="data">Data buffer to read from the window starting from the given offset
+		/// 	</param>
+		/// <exception cref="System.ArgumentException"></exception>
+		/// <exception cref="System.InvalidOperationException"></exception>
+		public virtual int Read(int off, byte[] data)
+		{
+			CheckBounds(off, data);
+			return _bin.BlockRead(_blockOff + off, data);
+		}
+
+		/// <summary>Disable IO Adapter Window</summary>
+		public virtual void Disable()
+		{
+			_disabled = true;
+		}
+
+		/// <summary>Flush IO Adapter Window</summary>
+		public virtual void Flush()
+		{
+			if (!_disabled)
+			{
+				_bin.Sync();
+			}
+		}
+
+		private void CheckBounds(int off, byte[] data)
+		{
+			if (_disabled)
+			{
+				throw new InvalidOperationException();
+			}
+			if (data == null || off < 0 || off + data.Length > _len)
+			{
+				throw new ArgumentException();
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/CachedIoAdapter.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/CachedIoAdapter.cs
new file mode 100644
index 0000000..7bb24be
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/CachedIoAdapter.cs
@@ -0,0 +1,547 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal.Fileheader;
+using Sharpen;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>
+	/// CachedIoAdapter is an IOAdapter for random access files, which caches data
+	/// for IO access.
+	/// </summary>
+	/// <remarks>
+	/// CachedIoAdapter is an IOAdapter for random access files, which caches data
+	/// for IO access. Its functionality is similar to OS cache.<br/>
+	/// Example:<br/>
+	/// <code>delegateAdapter = new RandomAccessFileAdapter();</code><br/>
+	/// <code>config.Io(new CachedIoAdapter(delegateAdapter));</code><br/>
+	/// </remarks>
+	public class CachedIoAdapter : IoAdapter
+	{
+		private CachedIoAdapter.Page _head;
+
+		private CachedIoAdapter.Page _tail;
+
+		private long _position;
+
+		private int _pageSize;
+
+		private int _pageCount;
+
+		private long _fileLength;
+
+		private long _filePointer;
+
+		private IoAdapter _io;
+
+		private bool _readOnly;
+
+		private static int DefaultPageSize = 1024;
+
+		private static int DefaultPageCount = 64;
+
+		/// <summary>
+		/// Creates an instance of CachedIoAdapter with the default page size and
+		/// page count.
+		/// </summary>
+		/// <remarks>
+		/// Creates an instance of CachedIoAdapter with the default page size and
+		/// page count.
+		/// </remarks>
+		/// <param name="ioAdapter">delegate IO adapter (RandomAccessFileAdapter by default)</param>
+		public CachedIoAdapter(IoAdapter ioAdapter) : this(ioAdapter, DefaultPageSize, DefaultPageCount
+			)
+		{
+		}
+
+		/// <summary>
+		/// Creates an instance of CachedIoAdapter with a custom page size and page
+		/// count.<br />
+		/// </summary>
+		/// <param name="ioAdapter">delegate IO adapter (RandomAccessFileAdapter by default)</param>
+		/// <param name="pageSize">cache page size</param>
+		/// <param name="pageCount">allocated amount of pages</param>
+		public CachedIoAdapter(IoAdapter ioAdapter, int pageSize, int pageCount)
+		{
+			// private Hashtable4 _posPageMap = new Hashtable4(PAGE_COUNT);
+			_io = ioAdapter;
+			_pageSize = pageSize;
+			_pageCount = pageCount;
+		}
+
+		/// <summary>Creates an instance of CachedIoAdapter with extended parameters.<br /></summary>
+		/// <param name="path">database file path</param>
+		/// <param name="lockFile">determines if the file should be locked</param>
+		/// <param name="initialLength">initial file length, new writes will start from this point
+		/// 	</param>
+		/// <param name="readOnly">
+		/// 
+		/// if the file should be used in read-onlyt mode.
+		/// </param>
+		/// <param name="io">delegate IO adapter (RandomAccessFileAdapter by default)</param>
+		/// <param name="pageSize">cache page size</param>
+		/// <param name="pageCount">allocated amount of pages</param>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public CachedIoAdapter(string path, bool lockFile, long initialLength, bool readOnly
+			, IoAdapter io, int pageSize, int pageCount)
+		{
+			_readOnly = readOnly;
+			_pageSize = pageSize;
+			_pageCount = pageCount;
+			InitCache();
+			InitIOAdaptor(path, lockFile, initialLength, readOnly, io);
+			_position = initialLength;
+			_filePointer = initialLength;
+			_fileLength = _io.GetLength();
+		}
+
+		/// <summary>Creates and returns a new CachedIoAdapter <br /></summary>
+		/// <param name="path">database file path</param>
+		/// <param name="lockFile">determines if the file should be locked</param>
+		/// <param name="initialLength">initial file length, new writes will start from this point
+		/// 	</param>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override IoAdapter Open(string path, bool lockFile, long initialLength, bool
+			 readOnly)
+		{
+			return new Db4objects.Db4o.IO.CachedIoAdapter(path, lockFile, initialLength, readOnly
+				, _io, _pageSize, _pageCount);
+		}
+
+		/// <summary>Deletes the database file</summary>
+		/// <param name="path">file path</param>
+		public override void Delete(string path)
+		{
+			_io.Delete(path);
+		}
+
+		/// <summary>Checks if the file exists</summary>
+		/// <param name="path">file path</param>
+		public override bool Exists(string path)
+		{
+			return _io.Exists(path);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private void InitIOAdaptor(string path, bool lockFile, long initialLength, bool readOnly
+			, IoAdapter io)
+		{
+			_io = io.Open(path, lockFile, initialLength, readOnly);
+		}
+
+		private void InitCache()
+		{
+			_head = new CachedIoAdapter.Page(_pageSize);
+			_head._prev = null;
+			CachedIoAdapter.Page page = _head;
+			CachedIoAdapter.Page next = _head;
+			for (int i = 0; i < _pageCount - 1; ++i)
+			{
+				next = new CachedIoAdapter.Page(_pageSize);
+				page._next = next;
+				next._prev = page;
+				page = next;
+			}
+			_tail = next;
+		}
+
+		/// <summary>Reads the file into the buffer using pages from cache.</summary>
+		/// <remarks>
+		/// Reads the file into the buffer using pages from cache. If the next page
+		/// is not cached it will be read from the file.
+		/// </remarks>
+		/// <param name="buffer">destination buffer</param>
+		/// <param name="length">how many bytes to read</param>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override int Read(byte[] buffer, int length)
+		{
+			long startAddress = _position;
+			int bytesToRead = length;
+			int totalRead = 0;
+			while (bytesToRead > 0)
+			{
+				CachedIoAdapter.Page page = GetPage(startAddress, true);
+				int readBytes = page.Read(buffer, totalRead, startAddress, bytesToRead);
+				MovePageToHead(page);
+				if (readBytes <= 0)
+				{
+					break;
+				}
+				bytesToRead -= readBytes;
+				startAddress += readBytes;
+				totalRead += readBytes;
+			}
+			_position = startAddress;
+			return totalRead == 0 ? -1 : totalRead;
+		}
+
+		/// <summary>Writes the buffer to cache using pages</summary>
+		/// <param name="buffer">source buffer</param>
+		/// <param name="length">how many bytes to write</param>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Write(byte[] buffer, int length)
+		{
+			ValidateReadOnly();
+			long startAddress = _position;
+			int bytesToWrite = length;
+			int bufferOffset = 0;
+			while (bytesToWrite > 0)
+			{
+				// page doesn't need to loadFromDisk if the whole page is dirty
+				bool loadFromDisk = (bytesToWrite < _pageSize) || (startAddress % _pageSize != 0);
+				CachedIoAdapter.Page page = GetPage(startAddress, loadFromDisk);
+				page.EnsureEndAddress(GetLength());
+				int writtenBytes = page.Write(buffer, bufferOffset, startAddress, bytesToWrite);
+				FlushIfHeaderBlockPage(page);
+				MovePageToHead(page);
+				bytesToWrite -= writtenBytes;
+				startAddress += writtenBytes;
+				bufferOffset += writtenBytes;
+			}
+			long endAddress = startAddress;
+			_position = endAddress;
+			_fileLength = Math.Max(endAddress, _fileLength);
+		}
+
+		private void FlushIfHeaderBlockPage(CachedIoAdapter.Page page)
+		{
+			if (ContainsHeaderBlock(page))
+			{
+				FlushPage(page);
+			}
+		}
+
+		private void ValidateReadOnly()
+		{
+			if (_readOnly)
+			{
+				throw new Db4oIOException();
+			}
+		}
+
+		/// <summary>Flushes cache to a physical storage</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Sync()
+		{
+			ValidateReadOnly();
+			FlushAllPages();
+			_io.Sync();
+		}
+
+		/// <summary>Returns the file length</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override long GetLength()
+		{
+			return _fileLength;
+		}
+
+		/// <summary>Flushes and closes the file</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Close()
+		{
+			try
+			{
+				FlushAllPages();
+			}
+			finally
+			{
+				_io.Close();
+			}
+		}
+
+		public override IoAdapter DelegatedIoAdapter()
+		{
+			return _io.DelegatedIoAdapter();
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private CachedIoAdapter.Page GetPage(long startAddress, bool loadFromDisk)
+		{
+			CachedIoAdapter.Page page = GetPageFromCache(startAddress);
+			if (page != null)
+			{
+				if (ContainsHeaderBlock(page))
+				{
+					GetPageFromDisk(page, startAddress);
+				}
+				page.EnsureEndAddress(_fileLength);
+				return page;
+			}
+			// in case that page is not found in the cache
+			page = GetFreePageFromCache();
+			if (loadFromDisk)
+			{
+				GetPageFromDisk(page, startAddress);
+			}
+			else
+			{
+				ResetPageAddress(page, startAddress);
+			}
+			return page;
+		}
+
+		private bool ContainsHeaderBlock(CachedIoAdapter.Page page)
+		{
+			return page.StartAddress() <= FileHeader1.HeaderLength;
+		}
+
+		private void ResetPageAddress(CachedIoAdapter.Page page, long startAddress)
+		{
+			page.StartAddress(startAddress);
+			page.EndAddress(startAddress + _pageSize);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private CachedIoAdapter.Page GetFreePageFromCache()
+		{
+			if (!_tail.IsFree())
+			{
+				FlushPage(_tail);
+			}
+			// _posPageMap.remove(new Long(tail.startPosition / PAGE_SIZE));
+			return _tail;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private CachedIoAdapter.Page GetPageFromCache(long pos)
+		{
+			CachedIoAdapter.Page page = _head;
+			while (page != null)
+			{
+				if (page.Contains(pos))
+				{
+					return page;
+				}
+				page = page._next;
+			}
+			return null;
+		}
+
+		// Page page = (Page) _posPageMap.get(new Long(pos/PAGE_SIZE));
+		// return page;
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private void FlushAllPages()
+		{
+			CachedIoAdapter.Page node = _head;
+			while (node != null)
+			{
+				FlushPage(node);
+				node = node._next;
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private void FlushPage(CachedIoAdapter.Page page)
+		{
+			if (!page._dirty)
+			{
+				return;
+			}
+			IoSeek(page.StartAddress());
+			WritePageToDisk(page);
+			return;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private void GetPageFromDisk(CachedIoAdapter.Page page, long pos)
+		{
+			long startAddress = pos - pos % _pageSize;
+			page.StartAddress(startAddress);
+			IoSeek(page._startAddress);
+			int count = IoRead(page);
+			if (count > 0)
+			{
+				page.EndAddress(startAddress + count);
+			}
+			else
+			{
+				page.EndAddress(startAddress);
+			}
+		}
+
+		// _posPageMap.put(new Long(page.startPosition / PAGE_SIZE), page);
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private int IoRead(CachedIoAdapter.Page page)
+		{
+			int count = _io.Read(page._buffer);
+			if (count > 0)
+			{
+				_filePointer = page._startAddress + count;
+			}
+			return count;
+		}
+
+		private void MovePageToHead(CachedIoAdapter.Page page)
+		{
+			if (page == _head)
+			{
+				return;
+			}
+			if (page == _tail)
+			{
+				CachedIoAdapter.Page tempTail = _tail._prev;
+				tempTail._next = null;
+				_tail._next = _head;
+				_tail._prev = null;
+				_head._prev = page;
+				_head = _tail;
+				_tail = tempTail;
+			}
+			else
+			{
+				page._prev._next = page._next;
+				page._next._prev = page._prev;
+				page._next = _head;
+				_head._prev = page;
+				page._prev = null;
+				_head = page;
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private void WritePageToDisk(CachedIoAdapter.Page page)
+		{
+			ValidateReadOnly();
+			try
+			{
+				_io.Write(page._buffer, page.Size());
+				_filePointer = page.EndAddress();
+				page._dirty = false;
+			}
+			catch (Db4oIOException e)
+			{
+				_readOnly = true;
+				throw;
+			}
+		}
+
+		/// <summary>Moves the pointer to the specified file position</summary>
+		/// <param name="pos">position within the file</param>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Seek(long pos)
+		{
+			_position = pos;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private void IoSeek(long pos)
+		{
+			if (_filePointer != pos)
+			{
+				_io.Seek(pos);
+				_filePointer = pos;
+			}
+		}
+
+		private class Page
+		{
+			internal byte[] _buffer;
+
+			internal long _startAddress = -1;
+
+			internal long _endAddress;
+
+			internal readonly int _bufferSize;
+
+			internal bool _dirty;
+
+			internal CachedIoAdapter.Page _prev;
+
+			internal CachedIoAdapter.Page _next;
+
+			private byte[] zeroBytes;
+
+			public Page(int size)
+			{
+				_bufferSize = size;
+				_buffer = new byte[_bufferSize];
+			}
+
+			internal virtual void EnsureEndAddress(long fileLength)
+			{
+				long bufferEndAddress = _startAddress + _bufferSize;
+				if (_endAddress < bufferEndAddress && fileLength > _endAddress)
+				{
+					long newEndAddress = Math.Min(fileLength, bufferEndAddress);
+					if (zeroBytes == null)
+					{
+						zeroBytes = new byte[_bufferSize];
+					}
+					System.Array.Copy(zeroBytes, 0, _buffer, (int)(_endAddress - _startAddress), (int
+						)(newEndAddress - _endAddress));
+					_endAddress = newEndAddress;
+				}
+			}
+
+			internal virtual long EndAddress()
+			{
+				return _endAddress;
+			}
+
+			internal virtual void StartAddress(long address)
+			{
+				_startAddress = address;
+			}
+
+			internal virtual long StartAddress()
+			{
+				return _startAddress;
+			}
+
+			internal virtual void EndAddress(long address)
+			{
+				_endAddress = address;
+			}
+
+			internal virtual int Size()
+			{
+				return (int)(_endAddress - _startAddress);
+			}
+
+			internal virtual int Read(byte[] @out, int outOffset, long startAddress, int length
+				)
+			{
+				int bufferOffset = (int)(startAddress - _startAddress);
+				int pageAvailbeDataSize = (int)(_endAddress - startAddress);
+				int readBytes = Math.Min(pageAvailbeDataSize, length);
+				if (readBytes <= 0)
+				{
+					// meaning reach EOF
+					return -1;
+				}
+				System.Array.Copy(_buffer, bufferOffset, @out, outOffset, readBytes);
+				return readBytes;
+			}
+
+			internal virtual int Write(byte[] data, int dataOffset, long startAddress, int length
+				)
+			{
+				int bufferOffset = (int)(startAddress - _startAddress);
+				int pageAvailabeBufferSize = _bufferSize - bufferOffset;
+				int writtenBytes = Math.Min(pageAvailabeBufferSize, length);
+				System.Array.Copy(data, dataOffset, _buffer, bufferOffset, writtenBytes);
+				long endAddress = startAddress + writtenBytes;
+				if (endAddress > _endAddress)
+				{
+					_endAddress = endAddress;
+				}
+				_dirty = true;
+				return writtenBytes;
+			}
+
+			internal virtual bool Contains(long address)
+			{
+				return (_startAddress != -1 && address >= _startAddress && address < _startAddress
+					 + _bufferSize);
+			}
+
+			internal virtual bool IsFree()
+			{
+				return _startAddress == -1;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/CachingBin.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/CachingBin.cs
new file mode 100644
index 0000000..f480b66
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/CachingBin.cs
@@ -0,0 +1,364 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal.Caching;
+using Sharpen;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <exclude></exclude>
+	internal class CachingBin : BinDecorator
+	{
+		private readonly int _pageSize;
+
+		private readonly ICache4 _cache;
+
+		private readonly IObjectPool _pagePool;
+
+		private long _fileLength;
+
+		private sealed class _IProcedure4_22 : IProcedure4
+		{
+			public _IProcedure4_22(CachingBin _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Apply(object discardedPage)
+			{
+				this._enclosing.FlushPage(((CachingBin.Page)discardedPage));
+				this._enclosing._pagePool.ReturnObject(((CachingBin.Page)discardedPage));
+			}
+
+			private readonly CachingBin _enclosing;
+		}
+
+		private IProcedure4 _onDiscardPage;
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public CachingBin(IBin bin, ICache4 cache, int pageCount, int pageSize) : base(bin
+			)
+		{
+			_onDiscardPage = new _IProcedure4_22(this);
+			_producerFromDisk = new _IFunction4_138(this);
+			_producerFromPool = new _IFunction4_147(this);
+			_pageSize = pageSize;
+			_pagePool = new SimpleObjectPool(NewPagePool(pageCount));
+			_cache = cache;
+			_fileLength = _bin.Length();
+		}
+
+		private CachingBin.Page[] NewPagePool(int pageCount)
+		{
+			CachingBin.Page[] pages = new CachingBin.Page[pageCount];
+			for (int i = 0; i < pages.Length; ++i)
+			{
+				pages[i] = new CachingBin.Page(_pageSize);
+			}
+			return pages;
+		}
+
+		/// <summary>Reads the file into the buffer using pages from cache.</summary>
+		/// <remarks>
+		/// Reads the file into the buffer using pages from cache. If the next page
+		/// is not cached it will be read from the file.
+		/// </remarks>
+		/// <param name="pos">
+		/// 
+		/// start position to read
+		/// </param>
+		/// <param name="buffer">destination buffer</param>
+		/// <param name="length">how many bytes to read</param>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override int Read(long pos, byte[] buffer, int length)
+		{
+			return ReadInternal(pos, buffer, length, false);
+		}
+
+		private int ReadInternal(long pos, byte[] buffer, int length, bool syncRead)
+		{
+			long startAddress = pos;
+			int bytesToRead = length;
+			int totalRead = 0;
+			while (bytesToRead > 0)
+			{
+				CachingBin.Page page = syncRead ? SyncReadPage(startAddress) : GetPage(startAddress
+					, _producerFromDisk);
+				int readBytes = page.Read(buffer, totalRead, startAddress, bytesToRead);
+				if (readBytes <= 0)
+				{
+					break;
+				}
+				bytesToRead -= readBytes;
+				startAddress += readBytes;
+				totalRead += readBytes;
+			}
+			return totalRead == 0 ? -1 : totalRead;
+		}
+
+		/// <summary>Writes the buffer to cache using pages</summary>
+		/// <param name="pos">start position to write</param>
+		/// <param name="buffer">source buffer</param>
+		/// <param name="length">how many bytes to write</param>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Write(long pos, byte[] buffer, int length)
+		{
+			long startAddress = pos;
+			int bytesToWrite = length;
+			int bufferOffset = 0;
+			while (bytesToWrite > 0)
+			{
+				// page doesn't need to loadFromDisk if the whole page is dirty
+				bool loadFromDisk = (bytesToWrite < _pageSize) || (startAddress % _pageSize != 0);
+				CachingBin.Page page = GetPage(startAddress, loadFromDisk);
+				int writtenBytes = page.Write(buffer, bufferOffset, startAddress, bytesToWrite);
+				bytesToWrite -= writtenBytes;
+				startAddress += writtenBytes;
+				bufferOffset += writtenBytes;
+			}
+			long endAddress = startAddress;
+			_fileLength = Math.Max(endAddress, _fileLength);
+		}
+
+		/// <summary>Flushes cache to a physical storage</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Sync()
+		{
+			FlushAllPages();
+			base.Sync();
+		}
+
+		public override void Sync(IRunnable runnable)
+		{
+			FlushAllPages();
+			base.Sync(new _IRunnable_119(this, runnable));
+		}
+
+		private sealed class _IRunnable_119 : IRunnable
+		{
+			public _IRunnable_119(CachingBin _enclosing, IRunnable runnable)
+			{
+				this._enclosing = _enclosing;
+				this.runnable = runnable;
+			}
+
+			public void Run()
+			{
+				runnable.Run();
+				this._enclosing.FlushAllPages();
+			}
+
+			private readonly CachingBin _enclosing;
+
+			private readonly IRunnable runnable;
+		}
+
+		public override int SyncRead(long position, byte[] bytes, int bytesToRead)
+		{
+			return ReadInternal(position, bytes, bytesToRead, true);
+		}
+
+		/// <summary>Returns the file length</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override long Length()
+		{
+			return _fileLength;
+		}
+
+		private sealed class _IFunction4_138 : IFunction4
+		{
+			public _IFunction4_138(CachingBin _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Apply(object pageAddress)
+			{
+				// in case that page is not found in the cache
+				CachingBin.Page newPage = ((CachingBin.Page)this._enclosing._pagePool.BorrowObject
+					());
+				this._enclosing.LoadPage(newPage, ((long)pageAddress));
+				return newPage;
+			}
+
+			private readonly CachingBin _enclosing;
+		}
+
+		internal readonly IFunction4 _producerFromDisk;
+
+		private sealed class _IFunction4_147 : IFunction4
+		{
+			public _IFunction4_147(CachingBin _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Apply(object pageAddress)
+			{
+				// in case that page is not found in the cache
+				CachingBin.Page newPage = ((CachingBin.Page)this._enclosing._pagePool.BorrowObject
+					());
+				this._enclosing.ResetPageAddress(newPage, ((long)pageAddress));
+				return newPage;
+			}
+
+			private readonly CachingBin _enclosing;
+		}
+
+		internal readonly IFunction4 _producerFromPool;
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private CachingBin.Page GetPage(long startAddress, bool loadFromDisk)
+		{
+			IFunction4 producer = loadFromDisk ? _producerFromDisk : _producerFromPool;
+			return GetPage(startAddress, producer);
+		}
+
+		private CachingBin.Page GetPage(long startAddress, IFunction4 producer)
+		{
+			CachingBin.Page page = ((CachingBin.Page)_cache.Produce(PageAddressFor(startAddress
+				), producer, _onDiscardPage));
+			page.EnsureEndAddress(_fileLength);
+			return page;
+		}
+
+		private CachingBin.Page SyncReadPage(long startAddress)
+		{
+			CachingBin.Page page = new CachingBin.Page(_pageSize);
+			LoadPage(page, startAddress);
+			page.EnsureEndAddress(_fileLength);
+			return page;
+		}
+
+		private long PageAddressFor(long startAddress)
+		{
+			return (startAddress / _pageSize) * _pageSize;
+		}
+
+		private void ResetPageAddress(CachingBin.Page page, long startAddress)
+		{
+			page._startAddress = startAddress;
+			page._endAddress = startAddress + _pageSize;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		protected virtual void FlushAllPages()
+		{
+			for (IEnumerator pIter = _cache.GetEnumerator(); pIter.MoveNext(); )
+			{
+				CachingBin.Page p = ((CachingBin.Page)pIter.Current);
+				FlushPage(p);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private void FlushPage(CachingBin.Page page)
+		{
+			if (!page._dirty)
+			{
+				return;
+			}
+			WritePageToDisk(page);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private void LoadPage(CachingBin.Page page, long pos)
+		{
+			long startAddress = pos - pos % _pageSize;
+			page._startAddress = startAddress;
+			int count = _bin.Read(page._startAddress, page._buffer, page._bufferSize);
+			if (count > 0)
+			{
+				page._endAddress = startAddress + count;
+			}
+			else
+			{
+				page._endAddress = startAddress;
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private void WritePageToDisk(CachingBin.Page page)
+		{
+			base.Write(page._startAddress, page._buffer, page.Size());
+			page._dirty = false;
+		}
+
+		private class Page
+		{
+			public readonly byte[] _buffer;
+
+			public long _startAddress = -1;
+
+			public long _endAddress;
+
+			public readonly int _bufferSize;
+
+			public bool _dirty;
+
+			private byte[] zeroBytes;
+
+			public Page(int size)
+			{
+				_bufferSize = size;
+				_buffer = new byte[_bufferSize];
+			}
+
+			internal virtual void EnsureEndAddress(long fileLength)
+			{
+				long bufferEndAddress = _startAddress + _bufferSize;
+				if (_endAddress < bufferEndAddress && fileLength > _endAddress)
+				{
+					long newEndAddress = Math.Min(fileLength, bufferEndAddress);
+					if (zeroBytes == null)
+					{
+						zeroBytes = new byte[_bufferSize];
+					}
+					System.Array.Copy(zeroBytes, 0, _buffer, (int)(_endAddress - _startAddress), (int
+						)(newEndAddress - _endAddress));
+					_endAddress = newEndAddress;
+				}
+			}
+
+			internal virtual int Size()
+			{
+				return (int)(_endAddress - _startAddress);
+			}
+
+			internal virtual int Read(byte[] @out, int outOffset, long startAddress, int length
+				)
+			{
+				int bufferOffset = (int)(startAddress - _startAddress);
+				int pageAvailbeDataSize = (int)(_endAddress - startAddress);
+				int readBytes = Math.Min(pageAvailbeDataSize, length);
+				if (readBytes <= 0)
+				{
+					// meaning reach EOF
+					return -1;
+				}
+				System.Array.Copy(_buffer, bufferOffset, @out, outOffset, readBytes);
+				return readBytes;
+			}
+
+			internal virtual int Write(byte[] data, int dataOffset, long startAddress, int length
+				)
+			{
+				int bufferOffset = (int)(startAddress - _startAddress);
+				int pageAvailabeBufferSize = _bufferSize - bufferOffset;
+				int writtenBytes = Math.Min(pageAvailabeBufferSize, length);
+				System.Array.Copy(data, dataOffset, _buffer, bufferOffset, writtenBytes);
+				long endAddress = startAddress + writtenBytes;
+				if (endAddress > _endAddress)
+				{
+					_endAddress = endAddress;
+				}
+				_dirty = true;
+				return writtenBytes;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/CachingStorage.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/CachingStorage.cs
new file mode 100644
index 0000000..5ea40be
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/CachingStorage.cs
@@ -0,0 +1,107 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal.Caching;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>
+	/// Caching storage adapter to cache db4o database data in memory
+	/// until the underlying
+	/// <see cref="IBin">IBin</see>
+	/// is instructed to flush its
+	/// data when
+	/// <see cref="IBin.Sync()">IBin.Sync()</see>
+	/// is called.<br /><br />
+	/// You can override the
+	/// <see cref="NewCache()">NewCache()</see>
+	/// method if you want to
+	/// work with a different caching strategy.
+	/// </summary>
+	public class CachingStorage : StorageDecorator
+	{
+		private static int DefaultPageCount = 64;
+
+		private static int DefaultPageSize = 1024;
+
+		private int _pageCount;
+
+		private int _pageSize;
+
+		/// <summary>
+		/// default constructor to create a Caching storage with the default
+		/// page count of 64 and the default page size of 1024.
+		/// </summary>
+		/// <remarks>
+		/// default constructor to create a Caching storage with the default
+		/// page count of 64 and the default page size of 1024.
+		/// </remarks>
+		/// <param name="storage">
+		/// the
+		/// <see cref="IStorage">IStorage</see>
+		/// to be cached.
+		/// </param>
+		public CachingStorage(IStorage storage) : this(storage, DefaultPageCount, DefaultPageSize
+			)
+		{
+		}
+
+		/// <summary>
+		/// constructor to set up a CachingStorage with a configured page count
+		/// and page size
+		/// </summary>
+		/// <param name="storage">
+		/// the
+		/// <see cref="IStorage">IStorage</see>
+		/// to be cached.
+		/// </param>
+		/// <param name="pageCount">the number of pages the cache should use.</param>
+		/// <param name="pageSize">the size of the pages the cache should use.</param>
+		public CachingStorage(IStorage storage, int pageCount, int pageSize) : base(storage
+			)
+		{
+			_pageCount = pageCount;
+			_pageSize = pageSize;
+		}
+
+		/// <summary>opens a Bin for the given URI.</summary>
+		/// <remarks>opens a Bin for the given URI.</remarks>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override IBin Open(BinConfiguration config)
+		{
+			IBin storage = base.Open(config);
+			if (config.ReadOnly())
+			{
+				return new ReadOnlyBin(new CachingStorage.NonFlushingCachingBin(storage, NewCache
+					(), _pageCount, _pageSize));
+			}
+			return new CachingBin(storage, NewCache(), _pageCount, _pageSize);
+		}
+
+		/// <summary>
+		/// override this method if you want to work with a different caching
+		/// strategy than the default LRU2Q cache.
+		/// </summary>
+		/// <remarks>
+		/// override this method if you want to work with a different caching
+		/// strategy than the default LRU2Q cache.
+		/// </remarks>
+		protected virtual ICache4 NewCache()
+		{
+			return CacheFactory.NewLRULongCache(_pageCount);
+		}
+
+		private sealed class NonFlushingCachingBin : CachingBin
+		{
+			/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+			public NonFlushingCachingBin(IBin bin, ICache4 cache, int pageCount, int pageSize
+				) : base(bin, cache, pageCount, pageSize)
+			{
+			}
+
+			protected override void FlushAllPages()
+			{
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/ConstantGrowthStrategy.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/ConstantGrowthStrategy.cs
new file mode 100644
index 0000000..3dbe8f0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/ConstantGrowthStrategy.cs
@@ -0,0 +1,34 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.IO;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>Strategy for file/byte array growth by a constant factor</summary>
+	public class ConstantGrowthStrategy : IGrowthStrategy
+	{
+		private readonly int _growth;
+
+		/// <param name="growth">The constant growth size</param>
+		public ConstantGrowthStrategy(int growth)
+		{
+			_growth = growth;
+		}
+
+		/// <summary>
+		/// returns the incremented size after the growth
+		/// strategy has been applied
+		/// </summary>
+		/// <param name="curSize">the original size</param>
+		/// <returns>the new size</returns>
+		public virtual long NewSize(long curSize, long requiredSize)
+		{
+			long newSize = curSize;
+			while (newSize < requiredSize)
+			{
+				newSize += _growth;
+			}
+			return newSize;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/DoublingGrowthStrategy.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/DoublingGrowthStrategy.cs
new file mode 100644
index 0000000..ab5442b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/DoublingGrowthStrategy.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.IO;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>Strategy for file/byte array growth that will always double the current size
+	/// 	</summary>
+	public class DoublingGrowthStrategy : IGrowthStrategy
+	{
+		public virtual long NewSize(long curSize, long requiredSize)
+		{
+			if (curSize == 0)
+			{
+				return requiredSize;
+			}
+			long newSize = curSize;
+			while (newSize < requiredSize)
+			{
+				newSize *= 2;
+			}
+			return newSize;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/FileStorage.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/FileStorage.cs
new file mode 100644
index 0000000..dabc2af
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/FileStorage.cs
@@ -0,0 +1,209 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.IO;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation.IO;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal;
+using Sharpen.IO;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>
+	/// Storage adapter to store db4o database data to physical
+	/// files on hard disc.
+	/// </summary>
+	/// <remarks>
+	/// Storage adapter to store db4o database data to physical
+	/// files on hard disc.
+	/// </remarks>
+	public class FileStorage : IStorage
+	{
+		/// <summary>
+		/// opens a
+		/// <see cref="IBin">IBin</see>
+		/// on the specified URI (file system path).
+		/// </summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual IBin Open(BinConfiguration config)
+		{
+			return new FileStorage.FileBin(config);
+		}
+
+		/// <summary>returns true if the specified file system path already exists.</summary>
+		/// <remarks>returns true if the specified file system path already exists.</remarks>
+		public virtual bool Exists(string uri)
+		{
+			Sharpen.IO.File file = new Sharpen.IO.File(uri);
+			return file.Exists() && file.Length() > 0;
+		}
+
+		public class FileBin : IBin
+		{
+			private readonly string _path;
+
+			private RandomAccessFile _file;
+
+			/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+			public FileBin(BinConfiguration config)
+			{
+				bool ok = false;
+				try
+				{
+					_path = new Sharpen.IO.File(config.Uri()).GetCanonicalPath();
+					_file = RandomAccessFileFactory.NewRandomAccessFile(_path, config.ReadOnly(), config
+						.LockFile());
+					if (config.InitialLength() > 0)
+					{
+						Write(config.InitialLength() - 1, new byte[] { 0 }, 1);
+					}
+					ok = true;
+				}
+				catch (IOException e)
+				{
+					throw new Db4oIOException(e);
+				}
+				finally
+				{
+					if (!ok)
+					{
+						Close();
+					}
+				}
+			}
+
+			/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+			public virtual void Close()
+			{
+				Platform4.UnlockFile(_path, _file);
+				try
+				{
+					if (!IsClosed())
+					{
+						_file.Close();
+					}
+				}
+				catch (IOException e)
+				{
+					throw new Db4oIOException(e);
+				}
+				finally
+				{
+					_file = null;
+				}
+			}
+
+			internal virtual bool IsClosed()
+			{
+				return _file == null;
+			}
+
+			/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+			public virtual long Length()
+			{
+				try
+				{
+					return _file.Length();
+				}
+				catch (IOException e)
+				{
+					throw new Db4oIOException(e);
+				}
+			}
+
+			/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+			public virtual int Read(long pos, byte[] bytes, int length)
+			{
+				try
+				{
+					Seek(pos);
+					if (DTrace.enabled)
+					{
+						DTrace.FileRead.LogLength(pos, length);
+					}
+					return _file.Read(bytes, 0, length);
+				}
+				catch (IOException e)
+				{
+					throw new Db4oIOException(e);
+				}
+			}
+
+			/// <exception cref="System.IO.IOException"></exception>
+			internal virtual void Seek(long pos)
+			{
+				if (DTrace.enabled)
+				{
+					DTrace.RegularSeek.Log(pos);
+				}
+				_file.Seek(pos);
+			}
+
+			/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+			public virtual void Sync()
+			{
+				try
+				{
+					_file.GetFD().Sync();
+				}
+				catch (IOException e)
+				{
+					throw new Db4oIOException(e);
+				}
+			}
+
+			public virtual int SyncRead(long position, byte[] bytes, int bytesToRead)
+			{
+				return Read(position, bytes, bytesToRead);
+			}
+
+			/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+			public virtual void Write(long pos, byte[] buffer, int length)
+			{
+				CheckClosed();
+				try
+				{
+					Seek(pos);
+					if (DTrace.enabled)
+					{
+						DTrace.FileWrite.LogLength(pos, length);
+					}
+					_file.Write(buffer, 0, length);
+				}
+				catch (IOException e)
+				{
+					throw new Db4oIOException(e);
+				}
+			}
+
+			private void CheckClosed()
+			{
+				if (IsClosed())
+				{
+					throw new Db4oIOException();
+				}
+			}
+
+			public virtual void Sync(IRunnable runnable)
+			{
+				Sync();
+				runnable.Run();
+				Sync();
+			}
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual void Delete(string uri)
+		{
+			File4.Delete(uri);
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual void Rename(string oldUri, string newUri)
+		{
+			System.IO.File.Move(oldUri, newUri);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IBin.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IBin.cs
new file mode 100644
index 0000000..cd1885b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IBin.cs
@@ -0,0 +1,78 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>
+	/// Representation of a container for storage of db4o
+	/// database data (to file, to memory).
+	/// </summary>
+	/// <remarks>
+	/// Representation of a container for storage of db4o
+	/// database data (to file, to memory).
+	/// </remarks>
+	public interface IBin
+	{
+		/// <summary>returns the length of the Bin (on disc, in memory).</summary>
+		/// <remarks>returns the length of the Bin (on disc, in memory).</remarks>
+		long Length();
+
+		/// <summary>
+		/// reads a given number of bytes into an array of bytes at an
+		/// offset position.
+		/// </summary>
+		/// <remarks>
+		/// reads a given number of bytes into an array of bytes at an
+		/// offset position.
+		/// </remarks>
+		/// <param name="position">the offset position to read at</param>
+		/// <param name="bytes">the byte array to read bytes into</param>
+		/// <param name="bytesToRead">the number of bytes to be read</param>
+		/// <returns></returns>
+		int Read(long position, byte[] bytes, int bytesToRead);
+
+		/// <summary>
+		/// writes a given number of bytes from an array of bytes at
+		/// an offset position
+		/// </summary>
+		/// <param name="position">the offset position to write at</param>
+		/// <param name="bytes">the array of bytes to write</param>
+		/// <param name="bytesToWrite">the number of bytes to write</param>
+		void Write(long position, byte[] bytes, int bytesToWrite);
+
+		/// <summary>
+		/// flushes the buffer content to the physical storage
+		/// media.
+		/// </summary>
+		/// <remarks>
+		/// flushes the buffer content to the physical storage
+		/// media.
+		/// </remarks>
+		void Sync();
+
+		/// <summary>runs the Runnable between two calls to sync();</summary>
+		void Sync(IRunnable runnable);
+
+		/// <summary>
+		/// reads a given number of bytes into an array of bytes at an
+		/// offset position.
+		/// </summary>
+		/// <remarks>
+		/// reads a given number of bytes into an array of bytes at an
+		/// offset position. In contrast to the normal
+		/// <see cref="Read(long, byte[], int)">Read(long, byte[], int)</see>
+		/// method, the Bin should ensure direct access to the raw storage medium.
+		/// No caching should take place.
+		/// </remarks>
+		/// <param name="position">the offset position to read at</param>
+		/// <param name="bytes">the byte array to read bytes into</param>
+		/// <param name="bytesToRead">the number of bytes to be read</param>
+		/// <returns></returns>
+		int SyncRead(long position, byte[] bytes, int bytesToRead);
+
+		/// <summary>closes the Bin.</summary>
+		/// <remarks>closes the Bin.</remarks>
+		void Close();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IBlockSize.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IBlockSize.cs
new file mode 100644
index 0000000..5af1955
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IBlockSize.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>Block size registry.</summary>
+	/// <remarks>
+	/// Block size registry.
+	/// Accessible through the environment.
+	/// </remarks>
+	/// <seealso cref="Db4objects.Db4o.Foundation.Environments.My(System.Type{T})">Db4objects.Db4o.Foundation.Environments.My(System.Type<T>)
+	/// 	</seealso>
+	/// <since>7.7</since>
+	public interface IBlockSize
+	{
+		void Register(IListener4 listener);
+
+		void Set(int newValue);
+
+		int Value();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IGrowthStrategy.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IGrowthStrategy.cs
new file mode 100644
index 0000000..298d204
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IGrowthStrategy.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>Strategy for file/byte array growth.</summary>
+	/// <remarks>Strategy for file/byte array growth.</remarks>
+	public interface IGrowthStrategy
+	{
+		/// <summary>
+		/// returns the incremented size after the growth
+		/// strategy has been applied
+		/// </summary>
+		/// <param name="curSize">the original size</param>
+		/// <returns>
+		/// the new size, after the growth strategy has been
+		/// applied, must be bigger than curSize
+		/// </returns>
+		long NewSize(long curSize, long requiredSize);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IStorage.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IStorage.cs
new file mode 100644
index 0000000..75ba538
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IStorage.cs
@@ -0,0 +1,45 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.IO;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>
+	/// Base interface for Storage adapters that open a
+	/// <see cref="IBin">IBin</see>
+	/// to store db4o database data to.
+	/// </summary>
+	/// <seealso cref="Db4objects.Db4o.Config.IFileConfiguration.Storage(IStorage)"></seealso>
+	public interface IStorage
+	{
+		/// <summary>
+		/// opens a
+		/// <see cref="IBin">IBin</see>
+		/// to store db4o database data.
+		/// </summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		IBin Open(BinConfiguration config);
+
+		/// <summary>returns true if a Bin (file or memory) exists with the passed name.</summary>
+		/// <remarks>returns true if a Bin (file or memory) exists with the passed name.</remarks>
+		bool Exists(string uri);
+
+		/// <summary>Deletes the bin for the given URI from the storage.</summary>
+		/// <remarks>Deletes the bin for the given URI from the storage.</remarks>
+		/// <since>7.9</since>
+		/// <param name="uri">bin URI</param>
+		/// <exception cref="System.IO.IOException">if the bin could not be deleted</exception>
+		void Delete(string uri);
+
+		/// <summary>Renames the bin for the given old URI to the new URI.</summary>
+		/// <remarks>
+		/// Renames the bin for the given old URI to the new URI. If a bin for the new URI
+		/// exists, it will be overwritten.
+		/// </remarks>
+		/// <since>7.9</since>
+		/// <param name="oldUri">URI of the existing bin</param>
+		/// <param name="newUri">future URI of the bin</param>
+		/// <exception cref="System.IO.IOException">if the bin could not be deleted</exception>
+		void Rename(string oldUri, string newUri);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IoAdapter.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IoAdapter.cs
new file mode 100644
index 0000000..d77a28a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IoAdapter.cs
@@ -0,0 +1,160 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.IO;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>Base class for database file adapters, both for file and memory databases.
+	/// 	</summary>
+	/// <remarks>Base class for database file adapters, both for file and memory databases.
+	/// 	</remarks>
+	[System.ObsoleteAttribute(@"Use classes that implement  instead. The new functionality has been split:  is the factory class to open  adapters.   is the actual implementation of IO access."
+		)]
+	public abstract class IoAdapter
+	{
+		private const int CopySize = 4096;
+
+		private int _blockSize;
+
+		/// <summary>converts address and address offset to an absolute address</summary>
+		protected long RegularAddress(int blockAddress, int blockAddressOffset)
+		{
+			if (0 == _blockSize)
+			{
+				throw new InvalidOperationException();
+			}
+			return (long)blockAddress * _blockSize + blockAddressOffset;
+		}
+
+		/// <summary>copies a block within a file in block mode</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void BlockCopy(int oldAddress, int oldAddressOffset, int newAddress
+			, int newAddressOffset, int length)
+		{
+			Copy(RegularAddress(oldAddress, oldAddressOffset), RegularAddress(newAddress, newAddressOffset
+				), length);
+		}
+
+		/// <summary>sets the read/write pointer in the file using block mode</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void BlockSeek(int address)
+		{
+			BlockSeek(address, 0);
+		}
+
+		/// <summary>sets the read/write pointer in the file using block mode</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void BlockSeek(int address, int offset)
+		{
+			Seek(RegularAddress(address, offset));
+		}
+
+		/// <summary>outside call to set the block size of this adapter</summary>
+		public virtual void BlockSize(int blockSize)
+		{
+			if (blockSize < 1)
+			{
+				throw new ArgumentException();
+			}
+			_blockSize = blockSize;
+		}
+
+		/// <summary>implement to close the adapter</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public abstract void Close();
+
+		/// <summary>copies a block within a file in absolute mode</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Copy(long oldAddress, long newAddress, int length)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.IoCopy.LogLength(newAddress, length);
+			}
+			if (length > CopySize)
+			{
+				byte[] buffer = new byte[CopySize];
+				int pos = 0;
+				while (pos + CopySize < length)
+				{
+					Copy(buffer, oldAddress + pos, newAddress + pos);
+					pos += CopySize;
+				}
+				oldAddress += pos;
+				newAddress += pos;
+				length -= pos;
+			}
+			Copy(new byte[length], oldAddress, newAddress);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private void Copy(byte[] buffer, long oldAddress, long newAddress)
+		{
+			Seek(oldAddress);
+			Read(buffer);
+			Seek(newAddress);
+			Write(buffer);
+		}
+
+		/// <summary>deletes the given path from whatever 'file system' is addressed</summary>
+		public abstract void Delete(string path);
+
+		/// <summary>checks whether a file exists</summary>
+		public abstract bool Exists(string path);
+
+		/// <summary>implement to return the absolute length of the file</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public abstract long GetLength();
+
+		/// <summary>implement to open the file</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public abstract IoAdapter Open(string path, bool lockFile, long initialLength, bool
+			 readOnly);
+
+		/// <summary>reads a buffer at the seeked address</summary>
+		/// <returns>the number of bytes read and returned</returns>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual int Read(byte[] buffer)
+		{
+			return Read(buffer, buffer.Length);
+		}
+
+		/// <summary>implement to read a buffer at the seeked address</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public abstract int Read(byte[] bytes, int length);
+
+		/// <summary>implement to set the read/write pointer in the file, absolute mode</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public abstract void Seek(long pos);
+
+		/// <summary>implement to flush the file contents to storage</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public abstract void Sync();
+
+		/// <summary>writes a buffer to the seeked address</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Write(byte[] bytes)
+		{
+			Write(bytes, bytes.Length);
+		}
+
+		/// <summary>implement to write a buffer at the seeked address</summary>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public abstract void Write(byte[] buffer, int length);
+
+		/// <summary>returns the block size currently used</summary>
+		public virtual int BlockSize()
+		{
+			return _blockSize;
+		}
+
+		/// <summary>Delegated IO Adapter</summary>
+		/// <returns>reference to itself</returns>
+		public virtual IoAdapter DelegatedIoAdapter()
+		{
+			return this;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IoAdapterStorage.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IoAdapterStorage.cs
new file mode 100644
index 0000000..22eecae
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/IoAdapterStorage.cs
@@ -0,0 +1,105 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.IO;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <exclude></exclude>
+	public class IoAdapterStorage : IStorage
+	{
+		private readonly IoAdapter _io;
+
+		public IoAdapterStorage(IoAdapter io)
+		{
+			_io = io;
+		}
+
+		public virtual bool Exists(string uri)
+		{
+			return _io.Exists(uri);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual IBin Open(BinConfiguration config)
+		{
+			IoAdapterStorage.IoAdapterBin bin = new IoAdapterStorage.IoAdapterBin(_io.Open(config
+				.Uri(), config.LockFile(), config.InitialLength(), config.ReadOnly()));
+			((IBlockSize)Environments.My(typeof(IBlockSize))).Register(bin);
+			return bin;
+		}
+
+		internal class IoAdapterBin : IBin, IListener4
+		{
+			private readonly IoAdapter _io;
+
+			public IoAdapterBin(IoAdapter io)
+			{
+				_io = io;
+			}
+
+			public virtual void Close()
+			{
+				_io.Close();
+			}
+
+			public virtual long Length()
+			{
+				return _io.GetLength();
+			}
+
+			public virtual int Read(long position, byte[] buffer, int bytesToRead)
+			{
+				_io.Seek(position);
+				return _io.Read(buffer, bytesToRead);
+			}
+
+			public virtual void Sync()
+			{
+				_io.Sync();
+			}
+
+			public virtual int SyncRead(long position, byte[] bytes, int bytesToRead)
+			{
+				return Read(position, bytes, bytesToRead);
+			}
+
+			public virtual void Write(long position, byte[] bytes, int bytesToWrite)
+			{
+				_io.Seek(position);
+				_io.Write(bytes, bytesToWrite);
+			}
+
+			public virtual void BlockSize(int blockSize)
+			{
+				_io.BlockSize(blockSize);
+			}
+
+			public virtual void OnEvent(object @event)
+			{
+				BlockSize((((int)@event)));
+			}
+
+			public virtual void Sync(IRunnable runnable)
+			{
+				Sync();
+				runnable.Run();
+				Sync();
+			}
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual void Delete(string uri)
+		{
+			_io.Delete(uri);
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual void Rename(string oldUri, string newUri)
+		{
+			throw new NotImplementedException();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/MemoryBin.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/MemoryBin.cs
new file mode 100644
index 0000000..dbb6ff6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/MemoryBin.cs
@@ -0,0 +1,110 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.IO;
+using Sharpen;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.IO
+{
+	public class MemoryBin : IBin
+	{
+		private byte[] _bytes;
+
+		private int _length;
+
+		private IGrowthStrategy _growthStrategy;
+
+		public MemoryBin(int initialSize, IGrowthStrategy growthStrategy) : this(new byte
+			[initialSize], growthStrategy)
+		{
+		}
+
+		public MemoryBin(byte[] bytes, IGrowthStrategy growthStrategy)
+		{
+			_bytes = bytes;
+			_length = bytes.Length;
+			_growthStrategy = growthStrategy;
+		}
+
+		public virtual long Length()
+		{
+			return _length;
+		}
+
+		public virtual long BufferSize()
+		{
+			return _bytes.Length;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual int Read(long pos, byte[] bytes, int length)
+		{
+			long avail = _length - pos;
+			if (avail <= 0)
+			{
+				return -1;
+			}
+			int read = Math.Min((int)avail, length);
+			System.Array.Copy(_bytes, (int)pos, bytes, 0, read);
+			return read;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Sync()
+		{
+		}
+
+		public virtual int SyncRead(long position, byte[] bytes, int bytesToRead)
+		{
+			return Read(position, bytes, bytesToRead);
+		}
+
+		public virtual void Close()
+		{
+		}
+
+		/// <summary>Returns a copy of the raw data contained in this bin for external processing.
+		/// 	</summary>
+		/// <remarks>
+		/// Returns a copy of the raw data contained in this bin for external processing.
+		/// Access to the data is not guarded by synchronisation. If this method is called
+		/// while the MemoryBin is in use, it is possible that the returned byte array is
+		/// not consistent.
+		/// </remarks>
+		public virtual byte[] Data()
+		{
+			byte[] data = new byte[_length];
+			System.Array.Copy(_bytes, 0, data, 0, _length);
+			return data;
+		}
+
+		/// <summary>for internal processing only.</summary>
+		/// <remarks>for internal processing only.</remarks>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Write(long pos, byte[] buffer, int length)
+		{
+			if (pos + length > _bytes.Length)
+			{
+				long newSize = _growthStrategy.NewSize(_bytes.Length, pos + length);
+				//			if (pos + length > newSize) {
+				//				newSize = pos + length;
+				//			}
+				byte[] temp = new byte[(int)newSize];
+				System.Array.Copy(_bytes, 0, temp, 0, _length);
+				_bytes = temp;
+			}
+			System.Array.Copy(buffer, 0, _bytes, (int)pos, length);
+			pos += length;
+			if (pos > _length)
+			{
+				_length = (int)pos;
+			}
+		}
+
+		public virtual void Sync(IRunnable runnable)
+		{
+			runnable.Run();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/MemoryStorage.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/MemoryStorage.cs
new file mode 100644
index 0000000..96818ed
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/MemoryStorage.cs
@@ -0,0 +1,100 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using System.IO;
+using Db4objects.Db4o.IO;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>
+	/// <see cref="IStorage">IStorage</see>
+	/// implementation that produces
+	/// <see cref="IBin">IBin</see>
+	/// instances
+	/// that operate in memory.
+	/// Use this
+	/// <see cref="IStorage">IStorage</see>
+	/// to work with db4o as an in-memory database.
+	/// </summary>
+	public class MemoryStorage : IStorage
+	{
+		private readonly IDictionary _bins = new Hashtable();
+
+		private readonly IGrowthStrategy _growthStrategy;
+
+		public MemoryStorage() : this(new DoublingGrowthStrategy())
+		{
+		}
+
+		public MemoryStorage(IGrowthStrategy growthStrategy)
+		{
+			_growthStrategy = growthStrategy;
+		}
+
+		/// <summary>
+		/// returns true if a MemoryBin with the given URI name already exists
+		/// in this Storage.
+		/// </summary>
+		/// <remarks>
+		/// returns true if a MemoryBin with the given URI name already exists
+		/// in this Storage.
+		/// </remarks>
+		public virtual bool Exists(string uri)
+		{
+			return _bins.Contains(uri);
+		}
+
+		/// <summary>opens a MemoryBin for the given URI (name can be freely chosen).</summary>
+		/// <remarks>opens a MemoryBin for the given URI (name can be freely chosen).</remarks>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual IBin Open(BinConfiguration config)
+		{
+			IBin storage = ProduceStorage(config);
+			return config.ReadOnly() ? new ReadOnlyBin(storage) : storage;
+		}
+
+		/// <summary>Returns the memory bin for the given URI for external use.</summary>
+		/// <remarks>Returns the memory bin for the given URI for external use.</remarks>
+		public virtual MemoryBin Bin(string uri)
+		{
+			return ((MemoryBin)_bins[uri]);
+		}
+
+		/// <summary>Registers the given bin for this storage with the given URI.</summary>
+		/// <remarks>Registers the given bin for this storage with the given URI.</remarks>
+		public virtual void Bin(string uri, MemoryBin bin)
+		{
+			_bins[uri] = bin;
+		}
+
+		private IBin ProduceStorage(BinConfiguration config)
+		{
+			IBin storage = Bin(config.Uri());
+			if (null != storage)
+			{
+				return storage;
+			}
+			MemoryBin newStorage = new MemoryBin(new byte[(int)config.InitialLength()], _growthStrategy
+				);
+			_bins[config.Uri()] = newStorage;
+			return newStorage;
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual void Delete(string uri)
+		{
+			Sharpen.Collections.Remove(_bins, uri);
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual void Rename(string oldUri, string newUri)
+		{
+			MemoryBin bin = ((MemoryBin)Sharpen.Collections.Remove(_bins, oldUri));
+			if (bin == null)
+			{
+				throw new IOException("Bin not found: " + oldUri);
+			}
+			_bins[newUri] = bin;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/NonFlushingStorage.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/NonFlushingStorage.cs
new file mode 100644
index 0000000..d645e33
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/NonFlushingStorage.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.IO;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>
+	/// Storage adapter that does not pass flush calls
+	/// on to its delegate.
+	/// </summary>
+	/// <remarks>
+	/// Storage adapter that does not pass flush calls
+	/// on to its delegate.
+	/// You can use this
+	/// <see cref="IStorage">IStorage</see>
+	/// for improved db4o
+	/// speed at the risk of corrupted database files in
+	/// case of system failure.
+	/// </remarks>
+	public class NonFlushingStorage : StorageDecorator
+	{
+		public NonFlushingStorage(IStorage storage) : base(storage)
+		{
+		}
+
+		protected override IBin Decorate(BinConfiguration config, IBin storage)
+		{
+			return new NonFlushingStorage.NonFlushingBin(storage);
+		}
+
+		private class NonFlushingBin : BinDecorator
+		{
+			public NonFlushingBin(IBin storage) : base(storage)
+			{
+			}
+
+			public override void Sync()
+			{
+			}
+
+			public override void Sync(IRunnable runnable)
+			{
+				runnable.Run();
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/PagingMemoryBin.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/PagingMemoryBin.cs
new file mode 100644
index 0000000..dbe3681
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/PagingMemoryBin.cs
@@ -0,0 +1,135 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.IO;
+using Sharpen;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <exclude></exclude>
+	internal class PagingMemoryBin : IBin
+	{
+		private readonly int _pageSize;
+
+		private IList _pages = new ArrayList();
+
+		private int _lastPageLength;
+
+		public PagingMemoryBin(int pageSize) : this(pageSize, 0)
+		{
+		}
+
+		public PagingMemoryBin(int pageSize, long initialLength)
+		{
+			_pageSize = pageSize;
+			EnsureLength(initialLength);
+		}
+
+		public virtual long Length()
+		{
+			if (_pages.Count == 0)
+			{
+				return 0;
+			}
+			return (_pages.Count - 1) * _pageSize + _lastPageLength;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual int Read(long pos, byte[] buffer, int length)
+		{
+			long avail = Length() - pos;
+			if (avail <= 0)
+			{
+				return -1;
+			}
+			int bytesToRead = Math.Min((int)avail, length);
+			int offset = PageOffset(pos);
+			int pageIdx = PageIdx(pos);
+			int bytesRead = 0;
+			while (bytesRead < bytesToRead)
+			{
+				byte[] curPage = ((byte[])_pages[pageIdx]);
+				int chunkLength = Math.Min(length - bytesRead, _pageSize - offset);
+				System.Array.Copy(curPage, offset, buffer, bytesRead, chunkLength);
+				bytesRead += chunkLength;
+				pageIdx++;
+				offset = 0;
+			}
+			return bytesToRead;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Sync()
+		{
+		}
+
+		public virtual int SyncRead(long position, byte[] bytes, int bytesToRead)
+		{
+			return Read(position, bytes, bytesToRead);
+		}
+
+		public virtual void Close()
+		{
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Write(long pos, byte[] buffer, int length)
+		{
+			EnsureLength(pos + length);
+			int offset = PageOffset(pos);
+			int pageIdx = PageIdx(pos);
+			int bytesWritten = 0;
+			while (bytesWritten < length)
+			{
+				byte[] curPage = ((byte[])_pages[pageIdx]);
+				int chunkLength = Math.Min(length - bytesWritten, _pageSize - offset);
+				System.Array.Copy(buffer, bytesWritten, curPage, offset, chunkLength);
+				bytesWritten += chunkLength;
+				pageIdx++;
+				offset = 0;
+			}
+		}
+
+		private void EnsureLength(long length)
+		{
+			if (length <= 0)
+			{
+				return;
+			}
+			long lastPos = length - 1;
+			int lastPosPageIdx = PageIdx(lastPos);
+			int lastPosPageLength = PageOffset(lastPos) + 1;
+			if (lastPosPageIdx == _pages.Count - 1)
+			{
+				_lastPageLength = Math.Max(lastPosPageLength, _lastPageLength);
+				return;
+			}
+			if (lastPosPageIdx < _pages.Count)
+			{
+				return;
+			}
+			for (int newPageIdx = _pages.Count; newPageIdx <= lastPosPageIdx; newPageIdx++)
+			{
+				_pages.Add(new byte[_pageSize]);
+			}
+			_lastPageLength = lastPosPageLength;
+		}
+
+		private int PageIdx(long pos)
+		{
+			return (int)(pos / _pageSize);
+		}
+
+		private int PageOffset(long pos)
+		{
+			return (int)(pos % _pageSize);
+		}
+
+		public virtual void Sync(IRunnable runnable)
+		{
+			runnable.Run();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/PagingMemoryStorage.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/PagingMemoryStorage.cs
new file mode 100644
index 0000000..10d6255
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/PagingMemoryStorage.cs
@@ -0,0 +1,101 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using System.IO;
+using Db4objects.Db4o.IO;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>
+	/// <see cref="IStorage">IStorage</see>
+	/// implementation that produces
+	/// <see cref="IBin">IBin</see>
+	/// instances
+	/// that operate in memory.
+	/// Use this
+	/// <see cref="IStorage">IStorage</see>
+	/// to work with db4o as an in-memory database.
+	/// </summary>
+	public class PagingMemoryStorage : IStorage
+	{
+		private const int DefaultPagesize = 4096;
+
+		private readonly IDictionary _binsByUri = new Hashtable();
+
+		private readonly int _pageSize;
+
+		public PagingMemoryStorage() : this(DefaultPagesize)
+		{
+		}
+
+		public PagingMemoryStorage(int pageSize)
+		{
+			_pageSize = pageSize;
+		}
+
+		/// <summary>
+		/// returns true if a MemoryBin with the given URI name already exists
+		/// in this Storage.
+		/// </summary>
+		/// <remarks>
+		/// returns true if a MemoryBin with the given URI name already exists
+		/// in this Storage.
+		/// </remarks>
+		public virtual bool Exists(string uri)
+		{
+			return _binsByUri.Contains(uri);
+		}
+
+		/// <summary>opens a MemoryBin for the given URI (name can be freely chosen).</summary>
+		/// <remarks>opens a MemoryBin for the given URI (name can be freely chosen).</remarks>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual IBin Open(BinConfiguration config)
+		{
+			IBin bin = ProduceBin(config);
+			return config.ReadOnly() ? new ReadOnlyBin(bin) : bin;
+		}
+
+		/// <summary>Returns the memory bin for the given URI for external use.</summary>
+		/// <remarks>Returns the memory bin for the given URI for external use.</remarks>
+		public virtual IBin Bin(string uri)
+		{
+			return ((IBin)_binsByUri[uri]);
+		}
+
+		/// <summary>Registers the given bin for this storage with the given URI.</summary>
+		/// <remarks>Registers the given bin for this storage with the given URI.</remarks>
+		public virtual void Bin(string uri, IBin bin)
+		{
+			_binsByUri[uri] = bin;
+		}
+
+		private IBin ProduceBin(BinConfiguration config)
+		{
+			IBin storage = Bin(config.Uri());
+			if (null != storage)
+			{
+				return storage;
+			}
+			IBin newStorage = new PagingMemoryBin(_pageSize, config.InitialLength());
+			_binsByUri[config.Uri()] = newStorage;
+			return newStorage;
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual void Delete(string uri)
+		{
+			Sharpen.Collections.Remove(_binsByUri, uri);
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual void Rename(string oldUri, string newUri)
+		{
+			IBin bin = ((IBin)Sharpen.Collections.Remove(_binsByUri, oldUri));
+			if (bin == null)
+			{
+				throw new IOException("Bin not found: " + oldUri);
+			}
+			_binsByUri[newUri] = bin;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/RandomAccessFileAdapter.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/RandomAccessFileAdapter.cs
new file mode 100644
index 0000000..2143ab9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/RandomAccessFileAdapter.cs
@@ -0,0 +1,173 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.IO;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal;
+using Sharpen.IO;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>IO adapter for random access files.</summary>
+	/// <remarks>IO adapter for random access files.</remarks>
+	[System.ObsoleteAttribute(@"Use  instead.")]
+	public class RandomAccessFileAdapter : IoAdapter
+	{
+		private string _path;
+
+		private RandomAccessFile _delegate;
+
+		public RandomAccessFileAdapter()
+		{
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		protected RandomAccessFileAdapter(string path, bool lockFile, long initialLength, 
+			bool readOnly)
+		{
+			bool ok = false;
+			try
+			{
+				_path = new Sharpen.IO.File(path).GetCanonicalPath();
+				_delegate = RandomAccessFileFactory.NewRandomAccessFile(_path, readOnly, lockFile
+					);
+				if (initialLength > 0)
+				{
+					_delegate.Seek(initialLength - 1);
+					_delegate.Write(new byte[] { 0 });
+				}
+				ok = true;
+			}
+			catch (IOException e)
+			{
+				throw new Db4oIOException(e);
+			}
+			finally
+			{
+				if (!ok)
+				{
+					Close();
+				}
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Close()
+		{
+			// FIXME: This is a temporary quickfix for a bug in Android.
+			//        Remove after Android has been fixed.
+			try
+			{
+				if (_delegate != null)
+				{
+					_delegate.Seek(0);
+				}
+			}
+			catch (IOException)
+			{
+			}
+			// ignore
+			Platform4.UnlockFile(_path, _delegate);
+			try
+			{
+				if (_delegate != null)
+				{
+					_delegate.Close();
+				}
+			}
+			catch (IOException e)
+			{
+				throw new Db4oIOException(e);
+			}
+		}
+
+		public override void Delete(string path)
+		{
+			new Sharpen.IO.File(path).Delete();
+		}
+
+		public override bool Exists(string path)
+		{
+			Sharpen.IO.File existingFile = new Sharpen.IO.File(path);
+			return existingFile.Exists() && existingFile.Length() > 0;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override long GetLength()
+		{
+			try
+			{
+				return _delegate.Length();
+			}
+			catch (IOException e)
+			{
+				throw new Db4oIOException(e);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override IoAdapter Open(string path, bool lockFile, long initialLength, bool
+			 readOnly)
+		{
+			return new Db4objects.Db4o.IO.RandomAccessFileAdapter(path, lockFile, initialLength
+				, readOnly);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override int Read(byte[] bytes, int length)
+		{
+			try
+			{
+				return _delegate.Read(bytes, 0, length);
+			}
+			catch (IOException e)
+			{
+				throw new Db4oIOException(e);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Seek(long pos)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.RegularSeek.Log(pos);
+			}
+			try
+			{
+				_delegate.Seek(pos);
+			}
+			catch (IOException e)
+			{
+				throw new Db4oIOException(e);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Sync()
+		{
+			try
+			{
+				_delegate.GetFD().Sync();
+			}
+			catch (IOException e)
+			{
+				throw new Db4oIOException(e);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Write(byte[] buffer, int length)
+		{
+			try
+			{
+				_delegate.Write(buffer, 0, length);
+			}
+			catch (IOException e)
+			{
+				throw new Db4oIOException(e);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/ReadOnlyBin.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/ReadOnlyBin.cs
new file mode 100644
index 0000000..ed56fb5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/ReadOnlyBin.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.IO;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <exclude></exclude>
+	public class ReadOnlyBin : BinDecorator
+	{
+		public ReadOnlyBin(IBin storage) : base(storage)
+		{
+		}
+
+		public override void Write(long position, byte[] bytes, int bytesToWrite)
+		{
+			throw new Db4oIOException();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/StorageDecorator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/StorageDecorator.cs
new file mode 100644
index 0000000..17a4d69
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/StorageDecorator.cs
@@ -0,0 +1,51 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.IO;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>Wrapper base class for all classes that wrap Storage.</summary>
+	/// <remarks>
+	/// Wrapper base class for all classes that wrap Storage.
+	/// Each class that adds functionality to a Storage must
+	/// extend this class.
+	/// </remarks>
+	/// <seealso cref="BinDecorator"></seealso>
+	public class StorageDecorator : IStorage
+	{
+		protected readonly IStorage _storage;
+
+		public StorageDecorator(IStorage storage)
+		{
+			_storage = storage;
+		}
+
+		public virtual bool Exists(string uri)
+		{
+			return _storage.Exists(uri);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual IBin Open(BinConfiguration config)
+		{
+			return Decorate(config, _storage.Open(config));
+		}
+
+		protected virtual IBin Decorate(BinConfiguration config, IBin bin)
+		{
+			return bin;
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual void Delete(string uri)
+		{
+			_storage.Delete(uri);
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual void Rename(string oldUri, string newUri)
+		{
+			_storage.Rename(oldUri, newUri);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/SynchronizedBin.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/SynchronizedBin.cs
new file mode 100644
index 0000000..e537342
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/SynchronizedBin.cs
@@ -0,0 +1,63 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.IO;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <exclude></exclude>
+	public class SynchronizedBin : BinDecorator
+	{
+		public SynchronizedBin(IBin bin) : base(bin)
+		{
+		}
+
+		public override void Close()
+		{
+			lock (_bin)
+			{
+				base.Close();
+			}
+		}
+
+		public override long Length()
+		{
+			lock (_bin)
+			{
+				return base.Length();
+			}
+		}
+
+		public override int Read(long position, byte[] buffer, int bytesToRead)
+		{
+			lock (_bin)
+			{
+				return base.Read(position, buffer, bytesToRead);
+			}
+		}
+
+		public override void Write(long position, byte[] bytes, int bytesToWrite)
+		{
+			lock (_bin)
+			{
+				base.Write(position, bytes, bytesToWrite);
+			}
+		}
+
+		public override void Sync()
+		{
+			lock (_bin)
+			{
+				base.Sync();
+			}
+		}
+
+		public override void Sync(IRunnable runnable)
+		{
+			lock (_bin)
+			{
+				base.Sync(runnable);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/ThreadedSyncBin.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/ThreadedSyncBin.cs
new file mode 100644
index 0000000..29b4a3e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/ThreadedSyncBin.cs
@@ -0,0 +1,165 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.IO;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.IO
+{
+	public class ThreadedSyncBin : BinDecorator
+	{
+		private const int OneSecond = 1000;
+
+		private volatile IRunnable _syncRunnable;
+
+		private volatile bool _closed;
+
+		private readonly Thread _thread;
+
+		private readonly Lock4 _lock = new Lock4();
+
+		public ThreadedSyncBin(IBin bin) : base(bin)
+		{
+			_thread = new Thread(new _IRunnable_23(this), "ThreadedSyncBin");
+			_thread.Start();
+		}
+
+		private sealed class _IRunnable_23 : IRunnable
+		{
+			public _IRunnable_23(ThreadedSyncBin _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Run()
+			{
+				IClosure4 closure = new _IClosure4_25(this);
+				while (true)
+				{
+					this._enclosing._lock.Run(closure);
+					if (this._enclosing._closed)
+					{
+						return;
+					}
+				}
+			}
+
+			private sealed class _IClosure4_25 : IClosure4
+			{
+				public _IClosure4_25(_IRunnable_23 _enclosing)
+				{
+					this._enclosing = _enclosing;
+				}
+
+				public object Run()
+				{
+					this._enclosing._enclosing.RunSyncRunnable();
+					this._enclosing._enclosing._lock.Snooze(Db4objects.Db4o.IO.ThreadedSyncBin.OneSecond
+						);
+					return null;
+				}
+
+				private readonly _IRunnable_23 _enclosing;
+			}
+
+			private readonly ThreadedSyncBin _enclosing;
+		}
+
+		public override void Close()
+		{
+			WaitForPendingSync();
+			_closed = true;
+			_lock.Run(new _IClosure4_46(this));
+			base.Close();
+		}
+
+		private sealed class _IClosure4_46 : IClosure4
+		{
+			public _IClosure4_46(ThreadedSyncBin _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Run()
+			{
+				this._enclosing._lock.Awake();
+				return null;
+			}
+
+			private readonly ThreadedSyncBin _enclosing;
+		}
+
+		private void WaitForPendingSync()
+		{
+			while (_syncRunnable != null)
+			{
+				if (Thread.CurrentThread() == _thread)
+				{
+					return;
+				}
+			}
+		}
+
+		public override long Length()
+		{
+			WaitForPendingSync();
+			return base.Length();
+		}
+
+		public override int Read(long position, byte[] buffer, int bytesToRead)
+		{
+			WaitForPendingSync();
+			return base.Read(position, buffer, bytesToRead);
+		}
+
+		public override void Write(long position, byte[] bytes, int bytesToWrite)
+		{
+			WaitForPendingSync();
+			base.Write(position, bytes, bytesToWrite);
+		}
+
+		public override void Sync()
+		{
+			WaitForPendingSync();
+			base.Sync();
+		}
+
+		public override void Sync(IRunnable runnable)
+		{
+			WaitForPendingSync();
+			_lock.Run(new _IClosure4_85(this, runnable));
+		}
+
+		private sealed class _IClosure4_85 : IClosure4
+		{
+			public _IClosure4_85(ThreadedSyncBin _enclosing, IRunnable runnable)
+			{
+				this._enclosing = _enclosing;
+				this.runnable = runnable;
+			}
+
+			public object Run()
+			{
+				this._enclosing._syncRunnable = runnable;
+				this._enclosing._lock.Awake();
+				return null;
+			}
+
+			private readonly ThreadedSyncBin _enclosing;
+
+			private readonly IRunnable runnable;
+		}
+
+		internal void RunSyncRunnable()
+		{
+			IRunnable runnable = _syncRunnable;
+			if (runnable != null)
+			{
+				base.Sync();
+				runnable.Run();
+				base.Sync();
+				_syncRunnable = null;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/VanillaIoAdapter.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/VanillaIoAdapter.cs
new file mode 100644
index 0000000..b8da1f4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IO/VanillaIoAdapter.cs
@@ -0,0 +1,72 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.IO;
+
+namespace Db4objects.Db4o.IO
+{
+	/// <summary>base class for IoAdapters that delegate to other IoAdapters (decorator pattern)
+	/// 	</summary>
+	[System.ObsoleteAttribute(@"use  /  instead.")]
+	public abstract class VanillaIoAdapter : IoAdapter
+	{
+		protected IoAdapter _delegate;
+
+		public VanillaIoAdapter(IoAdapter delegateAdapter)
+		{
+			_delegate = delegateAdapter;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		protected VanillaIoAdapter(IoAdapter delegateAdapter, string path, bool lockFile, 
+			long initialLength, bool readOnly) : this(delegateAdapter.Open(path, lockFile, initialLength
+			, readOnly))
+		{
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Close()
+		{
+			_delegate.Close();
+		}
+
+		public override void Delete(string path)
+		{
+			_delegate.Delete(path);
+		}
+
+		public override bool Exists(string path)
+		{
+			return _delegate.Exists(path);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override long GetLength()
+		{
+			return _delegate.GetLength();
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override int Read(byte[] bytes, int length)
+		{
+			return _delegate.Read(bytes, length);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Seek(long pos)
+		{
+			_delegate.Seek(pos);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Sync()
+		{
+			_delegate.Sync();
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Write(byte[] buffer, int length)
+		{
+			_delegate.Write(buffer, length);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IObjectServer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IObjectServer.cs
new file mode 100644
index 0000000..59d0e19
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IObjectServer.cs
@@ -0,0 +1,84 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o
+{
+	/// <summary>the db4o server interface.</summary>
+	/// <remarks>
+	/// the db4o server interface.
+	/// <br /><br />- db4o servers can be opened with
+	/// <see cref="Db4oFactory.OpenServer(string, int)">Db4oFactory.OpenServer(string, int)
+	/// 	</see>
+	/// .<br />
+	/// - Direct in-memory connections to servers can be made with
+	/// <see cref="OpenClient()">OpenClient()</see>
+	/// <br />
+	/// - TCP connections are available through
+	/// <see cref="Db4oFactory.OpenClient(string, int, string, string)">Db4oFactory.OpenClient(string, int, string, string)
+	/// 	</see>
+	/// .
+	/// <br /><br />Before connecting clients over TCP, you have to
+	/// <see cref="GrantAccess(string, string)">GrantAccess(string, string)</see>
+	/// to the username and password combination
+	/// that you want to use.
+	/// </remarks>
+	/// <seealso cref="Db4oFactory.OpenServer(string, int)">Db4o.openServer</seealso>
+	/// <seealso cref="Db4objects.Db4o.Ext.IExtObjectServer">ExtObjectServer for extended functionality
+	/// 	</seealso>
+	public interface IObjectServer : System.IDisposable
+	{
+		/// <summary>
+		/// closes the
+		/// <see cref="IObjectServer"></see>
+		/// and writes all cached data.
+		/// <br /><br />
+		/// </summary>
+		/// <returns>
+		/// true - denotes that the last instance connected to the
+		/// used database file was closed.
+		/// </returns>
+		bool Close();
+
+		/// <summary>
+		/// returns an
+		/// <see cref="IObjectServer"></see>
+		/// with extended functionality.
+		/// <br /><br />Use this method as a convenient accessor to extended methods.
+		/// Every
+		/// <see cref="IObjectServer"></see>
+		/// can be casted to an
+		/// <see cref="Db4objects.Db4o.Ext.IExtObjectServer">Db4objects.Db4o.Ext.IExtObjectServer
+		/// 	</see>
+		/// .
+		/// <br /><br />The functionality is split to two interfaces to allow newcomers to
+		/// focus on the essential methods.
+		/// </summary>
+		IExtObjectServer Ext();
+
+		/// <summary>grants client access to the specified user with the specified password.</summary>
+		/// <remarks>
+		/// grants client access to the specified user with the specified password.
+		/// <br /><br />If the user already exists, the password is changed to
+		/// the specified password.<br /><br />
+		/// </remarks>
+		/// <param name="userName">the name of the user</param>
+		/// <param name="password">the password to be used</param>
+		void GrantAccess(string userName, string password);
+
+		/// <summary>opens a client against this server.</summary>
+		/// <remarks>
+		/// opens a client against this server.
+		/// <br /><br />A client opened with this method operates within the same VM
+		/// as the server. Since an embedded client can use direct communication, without
+		/// an in-between socket connection, performance will be better than a client
+		/// opened with
+		/// <see cref="Db4oFactory.OpenClient(string, int, string, string)">Db4oFactory.OpenClient(string, int, string, string)
+		/// 	</see>
+		/// <br /><br />Every client has it's own transaction and uses it's own cache
+		/// for it's own version of all peristent objects.
+		/// </remarks>
+		IObjectContainer OpenClient();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IObjectSet.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IObjectSet.cs
new file mode 100644
index 0000000..82c219b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/IObjectSet.cs
@@ -0,0 +1,72 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o
+{
+	/// <summary>
+	/// An ObjectSet is a representation for a set of objects returned
+	/// by a query.
+	/// </summary>
+	/// <remarks>
+	/// An ObjectSet is a representation for a set of objects returned
+	/// by a query.
+	/// <br /><br />ObjectSet extends the system collection interfaces
+	/// java.util.List/System.Collections.IList where they are available. It is
+	/// recommended, never to reference ObjectSet directly in code but to use
+	/// List / IList instead.
+	/// <br /><br />Note that the underlying
+	/// <see cref="IObjectContainer">IObjectContainer</see>
+	/// of an ObjectSet
+	/// needs to remain open as long as an ObjectSet is used. This is necessary
+	/// for lazy instantiation. The objects in an ObjectSet are only instantiated
+	/// when they are actually being used by the application.
+	/// </remarks>
+	/// <seealso cref="Db4objects.Db4o.Ext.IExtObjectSet">for extended functionality.</seealso>
+	public interface IObjectSet : IList, IEnumerable
+	{
+		/// <summary>returns an ObjectSet with extended functionality.</summary>
+		/// <remarks>
+		/// returns an ObjectSet with extended functionality.
+		/// <br /><br />Every ObjectSet that db4o provides can be casted to
+		/// an ExtObjectSet. This method is supplied for your convenience
+		/// to work without a cast.
+		/// <br /><br />The ObjectSet functionality is split to two interfaces
+		/// to allow newcomers to focus on the essential methods.
+		/// </remarks>
+		IExtObjectSet Ext();
+
+		/// <summary>returns <code>true</code> if the <code>ObjectSet</code> has more elements.
+		/// 	</summary>
+		/// <remarks>returns <code>true</code> if the <code>ObjectSet</code> has more elements.
+		/// 	</remarks>
+		/// <returns>
+		/// boolean - <code>true</code> if the <code>ObjectSet</code> has more
+		/// elements.
+		/// </returns>
+		bool HasNext();
+
+		/// <summary>returns the next object in the <code>ObjectSet</code>.</summary>
+		/// <remarks>
+		/// returns the next object in the <code>ObjectSet</code>.
+		/// <br /><br />
+		/// Before returning the Object, next() triggers automatic activation of the
+		/// Object with the respective
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration.ActivationDepth()">global</see>
+		/// or
+		/// <see cref="Db4objects.Db4o.Config.IObjectClass.MaximumActivationDepth(int)">class specific
+		/// 	</see>
+		/// setting.<br /><br />
+		/// </remarks>
+		/// <returns>the next object in the <code>ObjectSet</code>.</returns>
+		object Next();
+
+		/// <summary>resets the <code>ObjectSet</code> cursor before the first element.</summary>
+		/// <remarks>
+		/// resets the <code>ObjectSet</code> cursor before the first element.
+		/// <br /><br />A subsequent call to <code>next()</code> will return the first element.
+		/// </remarks>
+		void Reset();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/ITransactionAware.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/ITransactionAware.cs
new file mode 100644
index 0000000..45410f9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/ITransactionAware.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o
+{
+	/// <exclude></exclude>
+	public interface ITransactionAware
+	{
+		void SetTrans(Transaction a_trans);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/ITransactionListener.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/ITransactionListener.cs
new file mode 100644
index 0000000..87d8c78
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/ITransactionListener.cs
@@ -0,0 +1,16 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o
+{
+	/// <summary>
+	/// allows registration with a transaction to be notified of
+	/// commit and rollback
+	/// </summary>
+	/// <exclude></exclude>
+	public interface ITransactionListener
+	{
+		void PreCommit();
+
+		void PostRollback();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/AbstractBufferContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/AbstractBufferContext.cs
new file mode 100644
index 0000000..f5a5b2c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/AbstractBufferContext.cs
@@ -0,0 +1,100 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public abstract class AbstractBufferContext : IBufferContext, IHandlerVersionContext
+	{
+		private IReadBuffer _buffer;
+
+		private readonly Db4objects.Db4o.Internal.Transaction _transaction;
+
+		public AbstractBufferContext(Db4objects.Db4o.Internal.Transaction transaction, IReadBuffer
+			 buffer)
+		{
+			_transaction = transaction;
+			_buffer = buffer;
+		}
+
+		public virtual IReadBuffer Buffer(IReadBuffer buffer)
+		{
+			IReadBuffer temp = _buffer;
+			_buffer = buffer;
+			return temp;
+		}
+
+		public virtual IReadBuffer Buffer()
+		{
+			return _buffer;
+		}
+
+		public virtual byte ReadByte()
+		{
+			return _buffer.ReadByte();
+		}
+
+		public virtual void ReadBytes(byte[] bytes)
+		{
+			_buffer.ReadBytes(bytes);
+		}
+
+		public virtual int ReadInt()
+		{
+			return _buffer.ReadInt();
+		}
+
+		public virtual long ReadLong()
+		{
+			return _buffer.ReadLong();
+		}
+
+		public virtual int Offset()
+		{
+			return _buffer.Offset();
+		}
+
+		public virtual void Seek(int offset)
+		{
+			_buffer.Seek(offset);
+		}
+
+		public virtual ObjectContainerBase Container()
+		{
+			return _transaction.Container();
+		}
+
+		public virtual IObjectContainer ObjectContainer()
+		{
+			return Container();
+		}
+
+		public virtual Db4objects.Db4o.Internal.Transaction Transaction()
+		{
+			return _transaction;
+		}
+
+		public abstract int HandlerVersion();
+
+		public virtual bool IsLegacyHandlerVersion()
+		{
+			return HandlerVersion() == 0;
+		}
+
+		public virtual BitMap4 ReadBitMap(int bitCount)
+		{
+			return _buffer.ReadBitMap(bitCount);
+		}
+
+		public virtual Db4objects.Db4o.Internal.Marshall.SlotFormat SlotFormat()
+		{
+			return Db4objects.Db4o.Internal.Marshall.SlotFormat.ForHandlerVersion(HandlerVersion
+				());
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/ActivatableBase.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/ActivatableBase.cs
new file mode 100644
index 0000000..9d49736
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/ActivatableBase.cs
@@ -0,0 +1,46 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Activation;
+using Db4objects.Db4o.TA;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public abstract class ActivatableBase : IActivatable
+	{
+		[System.NonSerialized]
+		private IActivator _activator;
+
+		public virtual void Bind(IActivator activator)
+		{
+			if (_activator == activator)
+			{
+				return;
+			}
+			if (activator != null && _activator != null)
+			{
+				throw new InvalidOperationException();
+			}
+			_activator = activator;
+		}
+
+		public virtual void Activate(ActivationPurpose purpose)
+		{
+			if (_activator == null)
+			{
+				return;
+			}
+			_activator.Activate(purpose);
+		}
+
+		protected virtual void ActivateForRead()
+		{
+			Activate(ActivationPurpose.Read);
+		}
+
+		protected virtual void ActivateForWrite()
+		{
+			Activate(ActivationPurpose.Write);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/ActivationContext4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/ActivationContext4.cs
new file mode 100644
index 0000000..8a528db
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/ActivationContext4.cs
@@ -0,0 +1,123 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	/// <exclude></exclude>
+	public class ActivationContext4 : IActivationContext
+	{
+		private readonly Db4objects.Db4o.Internal.Transaction _transaction;
+
+		private readonly object _targetObject;
+
+		private readonly IActivationDepth _depth;
+
+		public ActivationContext4(Db4objects.Db4o.Internal.Transaction transaction, object
+			 obj, IActivationDepth depth)
+		{
+			if (null == obj)
+			{
+				throw new ArgumentNullException();
+			}
+			_transaction = transaction;
+			_targetObject = obj;
+			_depth = depth;
+		}
+
+		public virtual void CascadeActivationToTarget()
+		{
+			IActivationContext context = ClassMetadata().DescendOnCascadingActivation() ? Descend
+				() : this;
+			CascadeActivation(context);
+		}
+
+		public virtual void CascadeActivationToChild(object obj)
+		{
+			if (obj == null)
+			{
+				return;
+			}
+			IActivationContext cascadingContext = ForObject(obj);
+			Db4objects.Db4o.Internal.ClassMetadata classMetadata = cascadingContext.ClassMetadata
+				();
+			if (classMetadata == null || !classMetadata.HasIdentity())
+			{
+				return;
+			}
+			CascadeActivation(cascadingContext.Descend());
+		}
+
+		private void CascadeActivation(IActivationContext context)
+		{
+			IActivationDepth depth = context.Depth();
+			if (!depth.RequiresActivation())
+			{
+				return;
+			}
+			if (depth.Mode().IsDeactivate())
+			{
+				Container().StillToDeactivate(_transaction, context.TargetObject(), depth, false);
+			}
+			else
+			{
+				// FIXME: [TA] do we really need to check for isValueType here?
+				Db4objects.Db4o.Internal.ClassMetadata classMetadata = context.ClassMetadata();
+				if (classMetadata.IsStruct())
+				{
+					classMetadata.CascadeActivation(context);
+				}
+				else
+				{
+					Container().StillToActivate(context);
+				}
+			}
+		}
+
+		public virtual ObjectContainerBase Container()
+		{
+			return _transaction.Container();
+		}
+
+		public virtual object TargetObject()
+		{
+			return _targetObject;
+		}
+
+		public virtual Db4objects.Db4o.Internal.ClassMetadata ClassMetadata()
+		{
+			return Container().ClassMetadataForObject(_targetObject);
+		}
+
+		public virtual IActivationDepth Depth()
+		{
+			return _depth;
+		}
+
+		public virtual IObjectContainer ObjectContainer()
+		{
+			return Container();
+		}
+
+		public virtual Db4objects.Db4o.Internal.Transaction Transaction()
+		{
+			return _transaction;
+		}
+
+		public virtual IActivationContext ForObject(object newTargetObject)
+		{
+			return new Db4objects.Db4o.Internal.Activation.ActivationContext4(Transaction(), 
+				newTargetObject, Depth());
+		}
+
+		public virtual IActivationContext Descend()
+		{
+			return new Db4objects.Db4o.Internal.Activation.ActivationContext4(Transaction(), 
+				TargetObject(), Depth().Descend(ClassMetadata()));
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/ActivationDepthImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/ActivationDepthImpl.cs
new file mode 100644
index 0000000..a1a6303
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/ActivationDepthImpl.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public abstract class ActivationDepthImpl : IActivationDepth
+	{
+		protected readonly ActivationMode _mode;
+
+		protected ActivationDepthImpl(ActivationMode mode)
+		{
+			_mode = mode;
+		}
+
+		public virtual ActivationMode Mode()
+		{
+			return _mode;
+		}
+
+		public abstract IActivationDepth Descend(ClassMetadata arg1);
+
+		public abstract bool RequiresActivation();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/ActivationMode.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/ActivationMode.cs
new file mode 100644
index 0000000..4376fbe
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/ActivationMode.cs
@@ -0,0 +1,72 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public sealed class ActivationMode
+	{
+		public static readonly Db4objects.Db4o.Internal.Activation.ActivationMode Activate
+			 = new Db4objects.Db4o.Internal.Activation.ActivationMode();
+
+		public static readonly Db4objects.Db4o.Internal.Activation.ActivationMode Deactivate
+			 = new Db4objects.Db4o.Internal.Activation.ActivationMode();
+
+		public static readonly Db4objects.Db4o.Internal.Activation.ActivationMode Peek = 
+			new Db4objects.Db4o.Internal.Activation.ActivationMode();
+
+		public static readonly Db4objects.Db4o.Internal.Activation.ActivationMode Prefetch
+			 = new Db4objects.Db4o.Internal.Activation.ActivationMode();
+
+		public static readonly Db4objects.Db4o.Internal.Activation.ActivationMode Refresh
+			 = new Db4objects.Db4o.Internal.Activation.ActivationMode();
+
+		private ActivationMode()
+		{
+		}
+
+		public override string ToString()
+		{
+			if (IsActivate())
+			{
+				return "ACTIVATE";
+			}
+			if (IsDeactivate())
+			{
+				return "DEACTIVATE";
+			}
+			if (IsPrefetch())
+			{
+				return "PREFETCH";
+			}
+			if (IsRefresh())
+			{
+				return "REFRESH";
+			}
+			return "PEEK";
+		}
+
+		public bool IsDeactivate()
+		{
+			return this == Deactivate;
+		}
+
+		public bool IsActivate()
+		{
+			return this == Activate;
+		}
+
+		public bool IsPeek()
+		{
+			return this == Peek;
+		}
+
+		public bool IsPrefetch()
+		{
+			return this == Prefetch;
+		}
+
+		public bool IsRefresh()
+		{
+			return this == Refresh;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/DepthUtil.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/DepthUtil.cs
new file mode 100644
index 0000000..61acd24
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/DepthUtil.cs
@@ -0,0 +1,22 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public sealed class DepthUtil
+	{
+		public static int AdjustDepthToBorders(int depth)
+		{
+			int depthBorder = 2;
+			// TODO when can min value actually occur?
+			if (depth > int.MinValue && depth < depthBorder)
+			{
+				return depthBorder;
+			}
+			return depth;
+		}
+
+		private DepthUtil()
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/DescendingActivationDepth.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/DescendingActivationDepth.cs
new file mode 100644
index 0000000..6b7fca5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/DescendingActivationDepth.cs
@@ -0,0 +1,28 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public class DescendingActivationDepth : ActivationDepthImpl
+	{
+		private readonly IActivationDepthProvider _provider;
+
+		public DescendingActivationDepth(IActivationDepthProvider provider, ActivationMode
+			 mode) : base(mode)
+		{
+			_provider = provider;
+		}
+
+		public override IActivationDepth Descend(ClassMetadata metadata)
+		{
+			return _provider.ActivationDepthFor(metadata, _mode);
+		}
+
+		public override bool RequiresActivation()
+		{
+			return true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/FixedActivationDepth.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/FixedActivationDepth.cs
new file mode 100644
index 0000000..6a5373d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/FixedActivationDepth.cs
@@ -0,0 +1,52 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	/// <summary>
+	/// Activates a fixed depth of the object graph regardless of
+	/// any existing activation depth configuration settings.
+	/// </summary>
+	/// <remarks>
+	/// Activates a fixed depth of the object graph regardless of
+	/// any existing activation depth configuration settings.
+	/// </remarks>
+	public class FixedActivationDepth : ActivationDepthImpl
+	{
+		private readonly int _depth;
+
+		public FixedActivationDepth(int depth, ActivationMode mode) : base(mode)
+		{
+			_depth = depth;
+		}
+
+		public FixedActivationDepth(int depth) : this(depth, ActivationMode.Activate)
+		{
+		}
+
+		public override bool RequiresActivation()
+		{
+			return _depth > 0;
+		}
+
+		public override IActivationDepth Descend(ClassMetadata metadata)
+		{
+			if (_depth < 1)
+			{
+				return this;
+			}
+			return new Db4objects.Db4o.Internal.Activation.FixedActivationDepth(_depth - 1, _mode
+				);
+		}
+
+		// TODO code duplication in fixed activation/update depth
+		public virtual Db4objects.Db4o.Internal.Activation.FixedActivationDepth AdjustDepthToBorders
+			()
+		{
+			return new Db4objects.Db4o.Internal.Activation.FixedActivationDepth(DepthUtil.AdjustDepthToBorders
+				(_depth));
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/FixedUpdateDepth.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/FixedUpdateDepth.cs
new file mode 100644
index 0000000..76f79c9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/FixedUpdateDepth.cs
@@ -0,0 +1,105 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public abstract class FixedUpdateDepth : IUpdateDepth
+	{
+		private int _depth;
+
+		private bool _tpMode = false;
+
+		public FixedUpdateDepth(int depth)
+		{
+			_depth = depth;
+		}
+
+		public virtual void TpMode(bool tpMode)
+		{
+			_tpMode = tpMode;
+		}
+
+		public virtual bool TpMode()
+		{
+			return _tpMode;
+		}
+
+		public virtual bool SufficientDepth()
+		{
+			return _depth > 0;
+		}
+
+		public virtual bool Negative()
+		{
+			// should never happen?
+			return _depth < 0;
+		}
+
+		public override string ToString()
+		{
+			return GetType().FullName + ": " + _depth;
+		}
+
+		public virtual IUpdateDepth Adjust(ClassMetadata clazz)
+		{
+			if (clazz.CascadesOnDeleteOrUpdate())
+			{
+				return AdjustDepthToBorders().Descend();
+			}
+			return Descend();
+		}
+
+		public virtual bool IsBroaderThan(Db4objects.Db4o.Internal.Activation.FixedUpdateDepth
+			 other)
+		{
+			return _depth > other._depth;
+		}
+
+		// TODO code duplication in fixed activation/update depth
+		public virtual Db4objects.Db4o.Internal.Activation.FixedUpdateDepth AdjustDepthToBorders
+			()
+		{
+			return ForDepth(DepthUtil.AdjustDepthToBorders(_depth));
+		}
+
+		public virtual IUpdateDepth AdjustUpdateDepthForCascade(bool isCollection)
+		{
+			int minimumUpdateDepth = isCollection ? 2 : 1;
+			if (_depth < minimumUpdateDepth)
+			{
+				return ForDepth(minimumUpdateDepth);
+			}
+			return this;
+		}
+
+		public virtual IUpdateDepth Descend()
+		{
+			return ForDepth(_depth - 1);
+		}
+
+		public override bool Equals(object other)
+		{
+			if (this == other)
+			{
+				return true;
+			}
+			if (other == null || GetType() != other.GetType())
+			{
+				return false;
+			}
+			return _depth == ((Db4objects.Db4o.Internal.Activation.FixedUpdateDepth)other)._depth;
+		}
+
+		public override int GetHashCode()
+		{
+			return _depth;
+		}
+
+		protected abstract Db4objects.Db4o.Internal.Activation.FixedUpdateDepth ForDepth(
+			int depth);
+
+		public abstract bool CanSkip(ObjectReference arg1);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/FullActivationDepth.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/FullActivationDepth.cs
new file mode 100644
index 0000000..bf9a9b5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/FullActivationDepth.cs
@@ -0,0 +1,30 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	/// <summary>Activates the full object graph.</summary>
+	/// <remarks>Activates the full object graph.</remarks>
+	public class FullActivationDepth : ActivationDepthImpl
+	{
+		public FullActivationDepth(ActivationMode mode) : base(mode)
+		{
+		}
+
+		public FullActivationDepth() : this(ActivationMode.Activate)
+		{
+		}
+
+		public override IActivationDepth Descend(ClassMetadata metadata)
+		{
+			return this;
+		}
+
+		public override bool RequiresActivation()
+		{
+			return true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IActivationDepth.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IActivationDepth.cs
new file mode 100644
index 0000000..4f13375
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IActivationDepth.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	/// <summary>Controls how deep an object graph is activated.</summary>
+	/// <remarks>Controls how deep an object graph is activated.</remarks>
+	public interface IActivationDepth
+	{
+		ActivationMode Mode();
+
+		bool RequiresActivation();
+
+		IActivationDepth Descend(ClassMetadata metadata);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IActivationDepthProvider.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IActivationDepthProvider.cs
new file mode 100644
index 0000000..ef8e167
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IActivationDepthProvider.cs
@@ -0,0 +1,33 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	/// <summary>Factory for ActivationDepth strategies.</summary>
+	/// <remarks>Factory for ActivationDepth strategies.</remarks>
+	public interface IActivationDepthProvider
+	{
+		/// <summary>Returns an ActivationDepth suitable for the specified class and activation mode.
+		/// 	</summary>
+		/// <remarks>Returns an ActivationDepth suitable for the specified class and activation mode.
+		/// 	</remarks>
+		/// <param name="classMetadata">root class that's being activated</param>
+		/// <param name="mode">activation mode</param>
+		/// <returns>an appropriate ActivationDepth for the class and activation mode</returns>
+		IActivationDepth ActivationDepthFor(ClassMetadata classMetadata, ActivationMode mode
+			);
+
+		/// <summary>Returns an ActivationDepth that will activate at most *depth* levels.</summary>
+		/// <remarks>
+		/// Returns an ActivationDepth that will activate at most *depth* levels.
+		/// A special case is Integer.MAX_VALUE (int.MaxValue for .net) for which a
+		/// FullActivationDepth object must be returned.
+		/// </remarks>
+		/// <param name="depth"></param>
+		/// <param name="mode"></param>
+		/// <returns></returns>
+		IActivationDepth ActivationDepth(int depth, ActivationMode mode);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IFixedDepth.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IFixedDepth.cs
new file mode 100644
index 0000000..4a9524f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IFixedDepth.cs
@@ -0,0 +1,11 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public interface IFixedDepth
+	{
+		IFixedDepth AdjustDepthToBorders();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IModifiedObjectQuery.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IModifiedObjectQuery.cs
new file mode 100644
index 0000000..d536c10
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IModifiedObjectQuery.cs
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public interface IModifiedObjectQuery
+	{
+		bool IsModified(object obj);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/ITransparentActivationDepthProvider.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/ITransparentActivationDepthProvider.cs
new file mode 100644
index 0000000..aca1d1b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/ITransparentActivationDepthProvider.cs
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.TA;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	/// <exclude></exclude>
+	public interface ITransparentActivationDepthProvider : IActivationDepthProvider
+	{
+		void EnableTransparentPersistenceSupportFor(IInternalObjectContainer container, IRollbackStrategy
+			 withRollbackStrategy);
+
+		void AddModified(object @object, Transaction inTransaction);
+
+		void RemoveModified(object @object, Transaction inTransaction);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IUpdateDepth.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IUpdateDepth.cs
new file mode 100644
index 0000000..13eb91b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IUpdateDepth.cs
@@ -0,0 +1,22 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public interface IUpdateDepth
+	{
+		bool SufficientDepth();
+
+		bool Negative();
+
+		IUpdateDepth Adjust(ClassMetadata clazz);
+
+		IUpdateDepth AdjustUpdateDepthForCascade(bool isCollection);
+
+		IUpdateDepth Descend();
+
+		bool CanSkip(ObjectReference @ref);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IUpdateDepthProvider.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IUpdateDepthProvider.cs
new file mode 100644
index 0000000..fbb74e0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/IUpdateDepthProvider.cs
@@ -0,0 +1,13 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public interface IUpdateDepthProvider
+	{
+		UnspecifiedUpdateDepth Unspecified(IModifiedObjectQuery query);
+
+		FixedUpdateDepth ForDepth(int depth);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/LegacyActivationDepth.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/LegacyActivationDepth.cs
new file mode 100644
index 0000000..cc638b6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/LegacyActivationDepth.cs
@@ -0,0 +1,67 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	/// <summary>
+	/// Activates an object graph to a specific depth respecting any
+	/// activation configuration settings that might be in effect.
+	/// </summary>
+	/// <remarks>
+	/// Activates an object graph to a specific depth respecting any
+	/// activation configuration settings that might be in effect.
+	/// </remarks>
+	public class LegacyActivationDepth : ActivationDepthImpl
+	{
+		private readonly int _depth;
+
+		public LegacyActivationDepth(int depth) : this(depth, ActivationMode.Activate)
+		{
+		}
+
+		public LegacyActivationDepth(int depth, ActivationMode mode) : base(mode)
+		{
+			_depth = depth;
+		}
+
+		public override IActivationDepth Descend(ClassMetadata metadata)
+		{
+			if (null == metadata)
+			{
+				return new Db4objects.Db4o.Internal.Activation.LegacyActivationDepth(_depth - 1, 
+					_mode);
+			}
+			return new Db4objects.Db4o.Internal.Activation.LegacyActivationDepth(DescendDepth
+				(metadata), _mode);
+		}
+
+		private int DescendDepth(ClassMetadata metadata)
+		{
+			int depth = ConfiguredActivationDepth(metadata) - 1;
+			if (metadata.IsStruct())
+			{
+				// 	We also have to instantiate structs completely every time.
+				return Math.Max(1, depth);
+			}
+			return depth;
+		}
+
+		private int ConfiguredActivationDepth(ClassMetadata metadata)
+		{
+			Config4Class config = metadata.ConfigOrAncestorConfig();
+			if (config != null && _mode.IsActivate())
+			{
+				return config.AdjustActivationDepth(_depth);
+			}
+			return _depth;
+		}
+
+		public override bool RequiresActivation()
+		{
+			return _depth > 0;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/LegacyActivationDepthProvider.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/LegacyActivationDepthProvider.cs
new file mode 100644
index 0000000..7c8104d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/LegacyActivationDepthProvider.cs
@@ -0,0 +1,37 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public class LegacyActivationDepthProvider : IActivationDepthProvider
+	{
+		public static readonly IActivationDepthProvider Instance = new LegacyActivationDepthProvider
+			();
+
+		public virtual IActivationDepth ActivationDepthFor(ClassMetadata classMetadata, ActivationMode
+			 mode)
+		{
+			if (mode.IsPrefetch())
+			{
+				return new LegacyActivationDepth(1, mode);
+			}
+			int globalLegacyActivationDepth = ConfigImpl(classMetadata).ActivationDepth();
+			Config4Class config = classMetadata.ConfigOrAncestorConfig();
+			int defaultDepth = null == config ? globalLegacyActivationDepth : config.AdjustActivationDepth
+				(globalLegacyActivationDepth);
+			return new LegacyActivationDepth(defaultDepth, mode);
+		}
+
+		public virtual IActivationDepth ActivationDepth(int depth, ActivationMode mode)
+		{
+			return new LegacyActivationDepth(depth, mode);
+		}
+
+		private Config4Impl ConfigImpl(ClassMetadata classMetadata)
+		{
+			return classMetadata.Container().ConfigImpl;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/LegacyFixedUpdateDepth.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/LegacyFixedUpdateDepth.cs
new file mode 100644
index 0000000..20f747c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/LegacyFixedUpdateDepth.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public class LegacyFixedUpdateDepth : FixedUpdateDepth
+	{
+		public LegacyFixedUpdateDepth(int depth) : base(depth)
+		{
+		}
+
+		public override bool CanSkip(ObjectReference @ref)
+		{
+			return false;
+		}
+
+		protected override FixedUpdateDepth ForDepth(int depth)
+		{
+			return new Db4objects.Db4o.Internal.Activation.LegacyFixedUpdateDepth(depth);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/LegacyUnspecifiedUpdateDepth.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/LegacyUnspecifiedUpdateDepth.cs
new file mode 100644
index 0000000..61ae45f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/LegacyUnspecifiedUpdateDepth.cs
@@ -0,0 +1,28 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public class LegacyUnspecifiedUpdateDepth : UnspecifiedUpdateDepth
+	{
+		public static readonly Db4objects.Db4o.Internal.Activation.LegacyUnspecifiedUpdateDepth
+			 Instance = new Db4objects.Db4o.Internal.Activation.LegacyUnspecifiedUpdateDepth
+			();
+
+		private LegacyUnspecifiedUpdateDepth()
+		{
+		}
+
+		public override bool CanSkip(ObjectReference @ref)
+		{
+			return false;
+		}
+
+		protected override FixedUpdateDepth ForDepth(int depth)
+		{
+			return new LegacyFixedUpdateDepth(depth);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/LegacyUpdateDepthProvider.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/LegacyUpdateDepthProvider.cs
new file mode 100644
index 0000000..feda293
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/LegacyUpdateDepthProvider.cs
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public class LegacyUpdateDepthProvider : IUpdateDepthProvider
+	{
+		public virtual FixedUpdateDepth ForDepth(int depth)
+		{
+			return new LegacyFixedUpdateDepth(depth);
+		}
+
+		public virtual UnspecifiedUpdateDepth Unspecified(IModifiedObjectQuery query)
+		{
+			return LegacyUnspecifiedUpdateDepth.Instance;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/NonDescendingActivationDepth.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/NonDescendingActivationDepth.cs
new file mode 100644
index 0000000..480fcb8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/NonDescendingActivationDepth.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	/// <summary>Transparent Activation strategy.</summary>
+	/// <remarks>Transparent Activation strategy.</remarks>
+	public class NonDescendingActivationDepth : ActivationDepthImpl
+	{
+		public NonDescendingActivationDepth(ActivationMode mode) : base(mode)
+		{
+		}
+
+		public override IActivationDepth Descend(ClassMetadata metadata)
+		{
+			return this;
+		}
+
+		public override bool RequiresActivation()
+		{
+			return false;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/NullModifiedObjectQuery.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/NullModifiedObjectQuery.cs
new file mode 100644
index 0000000..cb631a6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/NullModifiedObjectQuery.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public class NullModifiedObjectQuery : IModifiedObjectQuery
+	{
+		public static readonly IModifiedObjectQuery Instance = new Db4objects.Db4o.Internal.Activation.NullModifiedObjectQuery
+			();
+
+		private NullModifiedObjectQuery()
+		{
+		}
+
+		public virtual bool IsModified(object @ref)
+		{
+			return false;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/TPFixedUpdateDepth.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/TPFixedUpdateDepth.cs
new file mode 100644
index 0000000..3f8abd9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/TPFixedUpdateDepth.cs
@@ -0,0 +1,30 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.TA;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public class TPFixedUpdateDepth : FixedUpdateDepth
+	{
+		private IModifiedObjectQuery _query;
+
+		public TPFixedUpdateDepth(int depth, IModifiedObjectQuery query) : base(depth)
+		{
+			_query = query;
+		}
+
+		public override bool CanSkip(ObjectReference @ref)
+		{
+			ClassMetadata clazz = @ref.ClassMetadata();
+			return clazz.Reflector().ForClass(typeof(IActivatable)).IsAssignableFrom(clazz.ClassReflector
+				()) && !_query.IsModified(@ref.GetObject());
+		}
+
+		protected override FixedUpdateDepth ForDepth(int depth)
+		{
+			return new Db4objects.Db4o.Internal.Activation.TPFixedUpdateDepth(depth, _query);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/TPUnspecifiedUpdateDepth.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/TPUnspecifiedUpdateDepth.cs
new file mode 100644
index 0000000..247dc6d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/TPUnspecifiedUpdateDepth.cs
@@ -0,0 +1,30 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.TA;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public class TPUnspecifiedUpdateDepth : UnspecifiedUpdateDepth
+	{
+		private readonly IModifiedObjectQuery _query;
+
+		internal TPUnspecifiedUpdateDepth(IModifiedObjectQuery query)
+		{
+			_query = query;
+		}
+
+		public override bool CanSkip(ObjectReference @ref)
+		{
+			ClassMetadata clazz = @ref.ClassMetadata();
+			return clazz.Reflector().ForClass(typeof(IActivatable)).IsAssignableFrom(clazz.ClassReflector
+				()) && !_query.IsModified(@ref.GetObject());
+		}
+
+		protected override FixedUpdateDepth ForDepth(int depth)
+		{
+			return new TPFixedUpdateDepth(depth, _query);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/TPUpdateDepthProvider.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/TPUpdateDepthProvider.cs
new file mode 100644
index 0000000..52c849f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/TPUpdateDepthProvider.cs
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public class TPUpdateDepthProvider : IUpdateDepthProvider
+	{
+		public virtual FixedUpdateDepth ForDepth(int depth)
+		{
+			return new TPFixedUpdateDepth(depth, NullModifiedObjectQuery.Instance);
+		}
+
+		public virtual UnspecifiedUpdateDepth Unspecified(IModifiedObjectQuery query)
+		{
+			return new TPUnspecifiedUpdateDepth(query);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/TransparentActivationDepthProviderImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/TransparentActivationDepthProviderImpl.cs
new file mode 100644
index 0000000..c41e95e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/TransparentActivationDepthProviderImpl.cs
@@ -0,0 +1,257 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Events;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Reflect.Generic;
+using Db4objects.Db4o.TA;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public class TransparentActivationDepthProviderImpl : IActivationDepthProvider, ITransparentActivationDepthProvider
+	{
+		public virtual IActivationDepth ActivationDepth(int depth, ActivationMode mode)
+		{
+			if (int.MaxValue == depth)
+			{
+				return new FullActivationDepth(mode);
+			}
+			return new FixedActivationDepth(depth, mode);
+		}
+
+		public virtual IActivationDepth ActivationDepthFor(ClassMetadata classMetadata, ActivationMode
+			 mode)
+		{
+			if (IsTAAware(classMetadata))
+			{
+				return new NonDescendingActivationDepth(mode);
+			}
+			if (mode.IsPrefetch())
+			{
+				return new FixedActivationDepth(1, mode);
+			}
+			return new DescendingActivationDepth(this, mode);
+		}
+
+		private bool IsTAAware(ClassMetadata classMetadata)
+		{
+			GenericReflector reflector = classMetadata.Reflector();
+			return reflector.ForClass(typeof(IActivatable)).IsAssignableFrom(classMetadata.ClassReflector
+				());
+		}
+
+		private IRollbackStrategy _rollbackStrategy;
+
+		public bool _transparentPersistenceIsEnabled;
+
+		public virtual void EnableTransparentPersistenceSupportFor(IInternalObjectContainer
+			 container, IRollbackStrategy rollbackStrategy)
+		{
+			FlushOnQueryStarted(container);
+			_rollbackStrategy = rollbackStrategy;
+			_transparentPersistenceIsEnabled = true;
+		}
+
+		private void FlushOnQueryStarted(IInternalObjectContainer container)
+		{
+			IEventRegistry registry = EventRegistryFactory.ForObjectContainer(container);
+			registry.QueryStarted += new System.EventHandler<Db4objects.Db4o.Events.QueryEventArgs>
+				(new _IEventListener4_46(this).OnEvent);
+		}
+
+		private sealed class _IEventListener4_46
+		{
+			public _IEventListener4_46(TransparentActivationDepthProviderImpl _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void OnEvent(object sender, Db4objects.Db4o.Events.QueryEventArgs args)
+			{
+				this._enclosing.ObjectsModifiedIn(this._enclosing.TransactionFrom(args)).Flush();
+			}
+
+			private readonly TransparentActivationDepthProviderImpl _enclosing;
+		}
+
+		protected virtual Transaction TransactionFrom(EventArgs args)
+		{
+			return (Transaction)((TransactionalEventArgs)args).Transaction();
+		}
+
+		public virtual void AddModified(object @object, Transaction transaction)
+		{
+			if (!_transparentPersistenceIsEnabled)
+			{
+				return;
+			}
+			ObjectsModifiedIn(transaction).Add(@object);
+		}
+
+		public virtual void RemoveModified(object @object, Transaction transaction)
+		{
+			if (!_transparentPersistenceIsEnabled)
+			{
+				return;
+			}
+			ObjectsModifiedIn(transaction).Remove(@object);
+		}
+
+		private sealed class _TransactionLocal_73 : TransactionLocal
+		{
+			public _TransactionLocal_73(TransparentActivationDepthProviderImpl _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public override object InitialValueFor(Transaction transaction)
+			{
+				TransparentActivationDepthProviderImpl.ObjectsModifiedInTransaction objectsModifiedInTransaction
+					 = new TransparentActivationDepthProviderImpl.ObjectsModifiedInTransaction(transaction
+					);
+				transaction.AddTransactionListener(new _ITransactionListener_77(this, objectsModifiedInTransaction
+					));
+				return objectsModifiedInTransaction;
+			}
+
+			private sealed class _ITransactionListener_77 : ITransactionListener
+			{
+				public _ITransactionListener_77(_TransactionLocal_73 _enclosing, TransparentActivationDepthProviderImpl.ObjectsModifiedInTransaction
+					 objectsModifiedInTransaction)
+				{
+					this._enclosing = _enclosing;
+					this.objectsModifiedInTransaction = objectsModifiedInTransaction;
+				}
+
+				public void PostRollback()
+				{
+					objectsModifiedInTransaction.Rollback(this._enclosing._enclosing._rollbackStrategy
+						);
+				}
+
+				public void PreCommit()
+				{
+					objectsModifiedInTransaction.Flush();
+				}
+
+				private readonly _TransactionLocal_73 _enclosing;
+
+				private readonly TransparentActivationDepthProviderImpl.ObjectsModifiedInTransaction
+					 objectsModifiedInTransaction;
+			}
+
+			private readonly TransparentActivationDepthProviderImpl _enclosing;
+		}
+
+		private readonly TransactionLocal _objectsModifiedInTransaction;
+
+		private TransparentActivationDepthProviderImpl.ObjectsModifiedInTransaction ObjectsModifiedIn
+			(Transaction transaction)
+		{
+			return ((TransparentActivationDepthProviderImpl.ObjectsModifiedInTransaction)transaction
+				.Get(_objectsModifiedInTransaction).value);
+		}
+
+		private sealed class ObjectsModifiedInTransaction
+		{
+			private readonly IdentitySet4 _removedAfterModified = new IdentitySet4();
+
+			private readonly IdentitySet4 _modified = new IdentitySet4();
+
+			private readonly Transaction _transaction;
+
+			public ObjectsModifiedInTransaction(Transaction transaction)
+			{
+				_transaction = transaction;
+			}
+
+			public void Add(object @object)
+			{
+				if (Contains(@object))
+				{
+					return;
+				}
+				_modified.Add(@object);
+			}
+
+			public void Remove(object @object)
+			{
+				if (!Contains(@object))
+				{
+					return;
+				}
+				_modified.Remove(@object);
+				_removedAfterModified.Add(@object);
+			}
+
+			private bool Contains(object @object)
+			{
+				return _modified.Contains(@object);
+			}
+
+			public void Flush()
+			{
+				StoreModifiedObjects();
+				_modified.Clear();
+			}
+
+			private void StoreModifiedObjects()
+			{
+				ObjectContainerBase container = _transaction.Container();
+				container.StoreAll(_transaction, _modified.ValuesIterator(), container.UpdateDepthProvider
+					().Unspecified(new _IModifiedObjectQuery_132(this)));
+				_transaction.ProcessDeletes();
+			}
+
+			private sealed class _IModifiedObjectQuery_132 : IModifiedObjectQuery
+			{
+				public _IModifiedObjectQuery_132(ObjectsModifiedInTransaction _enclosing)
+				{
+					this._enclosing = _enclosing;
+				}
+
+				public bool IsModified(object obj)
+				{
+					return this._enclosing.Contains(obj);
+				}
+
+				private readonly ObjectsModifiedInTransaction _enclosing;
+			}
+
+			public void Rollback(IRollbackStrategy rollbackStrategy)
+			{
+				ApplyRollbackStrategy(rollbackStrategy);
+				_modified.Clear();
+			}
+
+			private void ApplyRollbackStrategy(IRollbackStrategy rollbackStrategy)
+			{
+				if (null == rollbackStrategy)
+				{
+					return;
+				}
+				ApplyRollbackStrategy(rollbackStrategy, _modified.ValuesIterator());
+				ApplyRollbackStrategy(rollbackStrategy, _removedAfterModified.ValuesIterator());
+			}
+
+			private void ApplyRollbackStrategy(IRollbackStrategy rollbackStrategy, IEnumerator
+				 values)
+			{
+				IObjectContainer objectContainer = _transaction.ObjectContainer();
+				while (values.MoveNext())
+				{
+					rollbackStrategy.Rollback(objectContainer, values.Current);
+				}
+			}
+		}
+
+		public TransparentActivationDepthProviderImpl()
+		{
+			_objectsModifiedInTransaction = new _TransactionLocal_73(this);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/UnknownActivationDepth.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/UnknownActivationDepth.cs
new file mode 100644
index 0000000..96867d1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/UnknownActivationDepth.cs
@@ -0,0 +1,33 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public class UnknownActivationDepth : IActivationDepth
+	{
+		public static readonly IActivationDepth Instance = new Db4objects.Db4o.Internal.Activation.UnknownActivationDepth
+			();
+
+		private UnknownActivationDepth()
+		{
+		}
+
+		public virtual ActivationMode Mode()
+		{
+			throw new InvalidOperationException();
+		}
+
+		public virtual IActivationDepth Descend(ClassMetadata metadata)
+		{
+			throw new InvalidOperationException();
+		}
+
+		public virtual bool RequiresActivation()
+		{
+			throw new InvalidOperationException();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/UnspecifiedUpdateDepth.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/UnspecifiedUpdateDepth.cs
new file mode 100644
index 0000000..cce372a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Activation/UnspecifiedUpdateDepth.cs
@@ -0,0 +1,51 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal.Activation
+{
+	public abstract class UnspecifiedUpdateDepth : IUpdateDepth
+	{
+		protected UnspecifiedUpdateDepth()
+		{
+		}
+
+		public virtual bool SufficientDepth()
+		{
+			return true;
+		}
+
+		public virtual bool Negative()
+		{
+			return true;
+		}
+
+		public override string ToString()
+		{
+			return GetType().FullName;
+		}
+
+		public virtual IUpdateDepth Adjust(ClassMetadata clazz)
+		{
+			FixedUpdateDepth depth = (FixedUpdateDepth)ForDepth(clazz.UpdateDepthFromConfig()
+				).Descend();
+			return depth;
+		}
+
+		public virtual IUpdateDepth AdjustUpdateDepthForCascade(bool isCollection)
+		{
+			throw new InvalidOperationException();
+		}
+
+		public virtual IUpdateDepth Descend()
+		{
+			throw new InvalidOperationException();
+		}
+
+		protected abstract FixedUpdateDepth ForDepth(int depth);
+
+		public abstract bool CanSkip(ObjectReference arg1);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ArrayType.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ArrayType.cs
new file mode 100644
index 0000000..a75dfc4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ArrayType.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class ArrayType
+	{
+		public static readonly Db4objects.Db4o.Internal.ArrayType None = new Db4objects.Db4o.Internal.ArrayType
+			(0);
+
+		public static readonly Db4objects.Db4o.Internal.ArrayType PlainArray = new Db4objects.Db4o.Internal.ArrayType
+			(3);
+
+		public static readonly Db4objects.Db4o.Internal.ArrayType MultidimensionalArray = 
+			new Db4objects.Db4o.Internal.ArrayType(4);
+
+		private ArrayType(int value)
+		{
+			_value = value;
+		}
+
+		private readonly int _value;
+
+		public virtual int Value()
+		{
+			return _value;
+		}
+
+		public static Db4objects.Db4o.Internal.ArrayType ForValue(int value)
+		{
+			switch (value)
+			{
+				case 0:
+				{
+					return None;
+				}
+
+				case 3:
+				{
+					return PlainArray;
+				}
+
+				case 4:
+				{
+					return MultidimensionalArray;
+				}
+
+				default:
+				{
+					throw new ArgumentException();
+				}
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/BlobImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/BlobImpl.cs
new file mode 100644
index 0000000..ad539ce
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/BlobImpl.cs
@@ -0,0 +1,321 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+#if !SILVERLIGHT
+using System.IO;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation.IO;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Types;
+using Sharpen;
+using Sharpen.IO;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <summary>
+	/// Transfer of blobs to and from the db4o system,
+	/// if users use the Blob Db4oType.
+	/// </summary>
+	/// <remarks>
+	/// Transfer of blobs to and from the db4o system,
+	/// if users use the Blob Db4oType.
+	/// </remarks>
+	/// <moveto>com.db4o.internal.blobs</moveto>
+	/// <exclude></exclude>
+	public class BlobImpl : IBlob, System.ICloneable, IDb4oTypeImpl
+	{
+		public const int CopybufferLength = 4096;
+
+		public string fileName;
+
+		public string i_ext;
+
+		[System.NonSerialized]
+		private Sharpen.IO.File i_file;
+
+		[System.NonSerialized]
+		private IBlobStatus i_getStatusFrom;
+
+		public int i_length;
+
+		[System.NonSerialized]
+		private double i_status = Status.Unused;
+
+		[System.NonSerialized]
+		private ObjectContainerBase i_stream;
+
+		[System.NonSerialized]
+		private Transaction i_trans;
+
+		/// <param name="depth"></param>
+		public virtual int AdjustReadDepth(int depth)
+		{
+			return 1;
+		}
+
+		private string CheckExt(Sharpen.IO.File file)
+		{
+			string name = file.GetName();
+			int pos = name.LastIndexOf(".");
+			if (pos > 0)
+			{
+				i_ext = Sharpen.Runtime.Substring(name, pos);
+				return Sharpen.Runtime.Substring(name, 0, pos);
+			}
+			i_ext = string.Empty;
+			return name;
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		private static void Copy(Sharpen.IO.File from, Sharpen.IO.File to)
+		{
+			System.IO.File.Copy(from, to);
+		}
+
+		public virtual object CreateDefault(Transaction a_trans)
+		{
+			BlobImpl bi = null;
+			bi = (BlobImpl)this.MemberwiseClone();
+			bi.SetTrans(a_trans);
+			return bi;
+		}
+
+		/// <exception cref="System.Exception"></exception>
+		public virtual FileInputStream GetClientInputStream()
+		{
+			return new FileInputStream(i_file);
+		}
+
+		/// <exception cref="System.Exception"></exception>
+		public virtual FileOutputStream GetClientOutputStream()
+		{
+			return new FileOutputStream(i_file);
+		}
+
+		public virtual string GetFileName()
+		{
+			return fileName;
+		}
+
+		public virtual int GetLength()
+		{
+			return i_length;
+		}
+
+		public virtual double GetStatus()
+		{
+			if (i_status == Status.Processing && i_getStatusFrom != null)
+			{
+				return i_getStatusFrom.GetStatus();
+			}
+			if (i_status == Status.Unused)
+			{
+				if (i_length > 0)
+				{
+					i_status = Status.Available;
+				}
+			}
+			return i_status;
+		}
+
+		public virtual void GetStatusFrom(IBlobStatus from)
+		{
+			i_getStatusFrom = from;
+		}
+
+		public virtual bool HasClassIndex()
+		{
+			return false;
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual void ReadFrom(Sharpen.IO.File file)
+		{
+			if (!file.Exists())
+			{
+				throw new IOException(Db4objects.Db4o.Internal.Messages.Get(41, file.GetAbsolutePath
+					()));
+			}
+			i_length = (int)file.Length();
+			CheckExt(file);
+			if (i_stream.IsClient)
+			{
+				i_file = file;
+				((IBlobTransport)i_stream).ReadBlobFrom(i_trans, this);
+			}
+			else
+			{
+				ReadLocal(file);
+			}
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual void ReadLocal(Sharpen.IO.File file)
+		{
+			bool copied = false;
+			if (fileName == null)
+			{
+				Sharpen.IO.File newFile = new Sharpen.IO.File(ServerPath(), file.GetName());
+				if (!newFile.Exists())
+				{
+					Copy(file, newFile);
+					copied = true;
+					fileName = newFile.GetName();
+				}
+			}
+			if (!copied)
+			{
+				Copy(file, ServerFile(CheckExt(file), true));
+			}
+			lock (i_stream.Lock())
+			{
+				i_stream.StoreInternal(i_trans, this, false);
+			}
+			i_status = Status.Completed;
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual Sharpen.IO.File ServerFile(string promptName, bool writeToServer)
+		{
+			lock (i_stream.Lock())
+			{
+				i_stream.Activate(i_trans, this, new FixedActivationDepth(2));
+			}
+			string path = ServerPath();
+			i_stream.ConfigImpl.EnsureDirExists(path);
+			if (writeToServer)
+			{
+				if (fileName == null)
+				{
+					if (promptName != null)
+					{
+						fileName = promptName;
+					}
+					else
+					{
+						fileName = "b_" + Runtime.CurrentTimeMillis();
+					}
+					string tryPath = fileName + i_ext;
+					int i = 0;
+					while (new Sharpen.IO.File(path, tryPath).Exists())
+					{
+						tryPath = fileName + "_" + i++ + i_ext;
+						if (i == 99)
+						{
+							// should never happen
+							i_status = Status.Error;
+							throw new IOException(Db4objects.Db4o.Internal.Messages.Get(40));
+						}
+					}
+					fileName = tryPath;
+					lock (i_stream.Lock())
+					{
+						i_stream.StoreInternal(i_trans, this, false);
+					}
+				}
+			}
+			else
+			{
+				if (fileName == null)
+				{
+					throw new IOException(Db4objects.Db4o.Internal.Messages.Get(38));
+				}
+			}
+			string lastTryPath = path + Sharpen.IO.File.separator + fileName;
+			if (!writeToServer)
+			{
+				if (!(new Sharpen.IO.File(lastTryPath).Exists()))
+				{
+					throw new IOException(Db4objects.Db4o.Internal.Messages.Get(39));
+				}
+			}
+			return new Sharpen.IO.File(lastTryPath);
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		private string ServerPath()
+		{
+			string path = i_stream.ConfigImpl.BlobPath();
+			if (path == null)
+			{
+				path = "blobs";
+			}
+			i_stream.ConfigImpl.EnsureDirExists(path);
+			return path;
+		}
+
+		public virtual void SetStatus(double status)
+		{
+			i_status = status;
+		}
+
+		public virtual void SetTrans(Transaction a_trans)
+		{
+			i_trans = a_trans;
+			i_stream = a_trans.Container();
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual void WriteLocal(Sharpen.IO.File file)
+		{
+			Copy(ServerFile(null, false), file);
+			i_status = Status.Completed;
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual void WriteTo(Sharpen.IO.File file)
+		{
+			if (GetStatus() == Status.Unused)
+			{
+				throw new IOException(Db4objects.Db4o.Internal.Messages.Get(43));
+			}
+			if (i_stream.IsClient)
+			{
+				i_file = file;
+				i_status = Status.Queued;
+				((IBlobTransport)i_stream).WriteBlobTo(i_trans, this);
+			}
+			else
+			{
+				WriteLocal(file);
+			}
+		}
+
+		public virtual void SetObjectReference(ObjectReference objectReference)
+		{
+		}
+
+		// not necessary
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual void DeleteFile()
+		{
+			if (GetStatus() == Status.Unused)
+			{
+				throw new IOException(Db4objects.Db4o.Internal.Messages.Get(43));
+			}
+			if (i_stream.IsClient)
+			{
+				((IBlobTransport)i_stream).DeleteBlobFile(i_trans, this);
+			}
+			else
+			{
+				ServerFile(null, false).Delete();
+			}
+			fileName = null;
+			i_ext = null;
+			i_length = 0;
+			SetStatus(Status.Unused);
+			lock (i_stream.Lock())
+			{
+				i_stream.StoreInternal(i_trans, this, false);
+			}
+		}
+
+		object System.ICloneable.Clone()
+		{
+			return MemberwiseClone();
+		}
+	}
+}
+#endif // !SILVERLIGHT
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/BlockSizeBlockConverter.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/BlockSizeBlockConverter.cs
new file mode 100644
index 0000000..8146180
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/BlockSizeBlockConverter.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public sealed class BlockSizeBlockConverter : IBlockConverter
+	{
+		private readonly int _blockSize;
+
+		public BlockSizeBlockConverter(int blockSize)
+		{
+			_blockSize = blockSize;
+		}
+
+		public int BytesToBlocks(long bytes)
+		{
+			return (int)((bytes + _blockSize - 1) / _blockSize);
+		}
+
+		public int BlockAlignedBytes(int bytes)
+		{
+			return BytesToBlocks(bytes) * _blockSize;
+		}
+
+		public int BlocksToBytes(int blocks)
+		{
+			return blocks * _blockSize;
+		}
+
+		public Slot ToBlockedLength(Slot slot)
+		{
+			return new Slot(slot.Address(), BytesToBlocks(slot.Length()));
+		}
+
+		public Slot ToNonBlockedLength(Slot slot)
+		{
+			return new Slot(slot.Address(), BlocksToBytes(slot.Length()));
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/AbstractBTreeRangeIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/AbstractBTreeRangeIterator.cs
new file mode 100644
index 0000000..a0cd814
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/AbstractBTreeRangeIterator.cs
@@ -0,0 +1,67 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	public abstract class AbstractBTreeRangeIterator : IEnumerator
+	{
+		private readonly BTreeRangeSingle _range;
+
+		private BTreePointer _cursor;
+
+		private BTreePointer _current;
+
+		public AbstractBTreeRangeIterator(BTreeRangeSingle range)
+		{
+			_range = range;
+			_cursor = range.First();
+		}
+
+		public virtual bool MoveNext()
+		{
+			if (ReachedEnd(_cursor))
+			{
+				_current = null;
+				return false;
+			}
+			_current = _cursor;
+			_cursor = _cursor.Next();
+			return true;
+		}
+
+		public virtual void Reset()
+		{
+			_cursor = _range.First();
+		}
+
+		protected virtual BTreePointer CurrentPointer()
+		{
+			if (null == _current)
+			{
+				throw new InvalidOperationException();
+			}
+			return _current;
+		}
+
+		private bool ReachedEnd(BTreePointer cursor)
+		{
+			if (cursor == null)
+			{
+				return true;
+			}
+			if (_range.End() == null)
+			{
+				return false;
+			}
+			return _range.End().Equals(cursor);
+		}
+
+		public abstract object Current
+		{
+			get;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeAlgebra.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeAlgebra.cs
new file mode 100644
index 0000000..cc5fac7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeAlgebra.cs
@@ -0,0 +1,137 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree.Algebra
+{
+	/// <exclude></exclude>
+	internal class BTreeAlgebra
+	{
+		public static IBTreeRange Intersect(BTreeRangeUnion union, BTreeRangeSingle single
+			)
+		{
+			SortedCollection4 collection = NewBTreeRangeSingleCollection();
+			CollectIntersections(collection, union, single);
+			return ToRange(collection);
+		}
+
+		public static IBTreeRange Intersect(BTreeRangeUnion union1, BTreeRangeUnion union2
+			)
+		{
+			SortedCollection4 collection = NewBTreeRangeSingleCollection();
+			IEnumerator ranges = union1.Ranges();
+			while (ranges.MoveNext())
+			{
+				BTreeRangeSingle current = (BTreeRangeSingle)ranges.Current;
+				CollectIntersections(collection, union2, current);
+			}
+			return ToRange(collection);
+		}
+
+		private static void CollectIntersections(SortedCollection4 collection, BTreeRangeUnion
+			 union, BTreeRangeSingle single)
+		{
+			IEnumerator ranges = union.Ranges();
+			while (ranges.MoveNext())
+			{
+				BTreeRangeSingle current = (BTreeRangeSingle)ranges.Current;
+				if (single.Overlaps(current))
+				{
+					collection.Add(single.Intersect(current));
+				}
+			}
+		}
+
+		public static IBTreeRange Intersect(BTreeRangeSingle single1, BTreeRangeSingle single2
+			)
+		{
+			BTreePointer first = BTreePointer.Max(single1.First(), single2.First());
+			BTreePointer end = BTreePointer.Min(single1.End(), single2.End());
+			return single1.NewBTreeRangeSingle(first, end);
+		}
+
+		public static IBTreeRange Union(BTreeRangeUnion union1, BTreeRangeUnion union2)
+		{
+			IEnumerator ranges = union1.Ranges();
+			IBTreeRange merged = union2;
+			while (ranges.MoveNext())
+			{
+				merged = merged.Union((IBTreeRange)ranges.Current);
+			}
+			return merged;
+		}
+
+		public static IBTreeRange Union(BTreeRangeUnion union, BTreeRangeSingle single)
+		{
+			if (single.IsEmpty())
+			{
+				return union;
+			}
+			SortedCollection4 sorted = NewBTreeRangeSingleCollection();
+			sorted.Add(single);
+			BTreeRangeSingle range = single;
+			IEnumerator ranges = union.Ranges();
+			while (ranges.MoveNext())
+			{
+				BTreeRangeSingle current = (BTreeRangeSingle)ranges.Current;
+				if (CanBeMerged(current, range))
+				{
+					sorted.Remove(range);
+					range = Merge(current, range);
+					sorted.Add(range);
+				}
+				else
+				{
+					sorted.Add(current);
+				}
+			}
+			return ToRange(sorted);
+		}
+
+		private static IBTreeRange ToRange(SortedCollection4 sorted)
+		{
+			if (1 == sorted.Size())
+			{
+				return (IBTreeRange)sorted.SingleElement();
+			}
+			return new BTreeRangeUnion(sorted);
+		}
+
+		private static SortedCollection4 NewBTreeRangeSingleCollection()
+		{
+			return new SortedCollection4(BTreeRangeSingle.Comparison);
+		}
+
+		public static IBTreeRange Union(BTreeRangeSingle single1, BTreeRangeSingle single2
+			)
+		{
+			if (single1.IsEmpty())
+			{
+				return single2;
+			}
+			if (single2.IsEmpty())
+			{
+				return single1;
+			}
+			if (CanBeMerged(single1, single2))
+			{
+				return Merge(single1, single2);
+			}
+			return new BTreeRangeUnion(new BTreeRangeSingle[] { single1, single2 });
+		}
+
+		private static BTreeRangeSingle Merge(BTreeRangeSingle range1, BTreeRangeSingle range2
+			)
+		{
+			return range1.NewBTreeRangeSingle(BTreePointer.Min(range1.First(), range2.First()
+				), BTreePointer.Max(range1.End(), range2.End()));
+		}
+
+		private static bool CanBeMerged(BTreeRangeSingle range1, BTreeRangeSingle range2)
+		{
+			return range1.Overlaps(range2) || range1.Adjacent(range2);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeOperation.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeOperation.cs
new file mode 100644
index 0000000..96ca6a6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeOperation.cs
@@ -0,0 +1,36 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree.Algebra
+{
+	/// <exclude></exclude>
+	public abstract class BTreeRangeOperation : IBTreeRangeVisitor
+	{
+		private IBTreeRange _resultingRange;
+
+		public BTreeRangeOperation() : base()
+		{
+		}
+
+		public virtual IBTreeRange Dispatch(IBTreeRange range)
+		{
+			range.Accept(this);
+			return _resultingRange;
+		}
+
+		public void Visit(BTreeRangeSingle single)
+		{
+			_resultingRange = Execute(single);
+		}
+
+		public void Visit(BTreeRangeUnion union)
+		{
+			_resultingRange = Execute(union);
+		}
+
+		protected abstract IBTreeRange Execute(BTreeRangeUnion union);
+
+		protected abstract IBTreeRange Execute(BTreeRangeSingle single);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeSingleIntersect.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeSingleIntersect.cs
new file mode 100644
index 0000000..318c2b5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeSingleIntersect.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Btree.Algebra;
+
+namespace Db4objects.Db4o.Internal.Btree.Algebra
+{
+	/// <exclude></exclude>
+	public class BTreeRangeSingleIntersect : BTreeRangeSingleOperation
+	{
+		public BTreeRangeSingleIntersect(BTreeRangeSingle single) : base(single)
+		{
+		}
+
+		protected override IBTreeRange Execute(BTreeRangeSingle single)
+		{
+			return BTreeAlgebra.Intersect(_single, single);
+		}
+
+		protected override IBTreeRange Execute(BTreeRangeUnion union)
+		{
+			return BTreeAlgebra.Intersect(union, _single);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeSingleOperation.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeSingleOperation.cs
new file mode 100644
index 0000000..8f9e996
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeSingleOperation.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Btree.Algebra;
+
+namespace Db4objects.Db4o.Internal.Btree.Algebra
+{
+	/// <exclude></exclude>
+	public abstract class BTreeRangeSingleOperation : BTreeRangeOperation
+	{
+		protected readonly BTreeRangeSingle _single;
+
+		public BTreeRangeSingleOperation(BTreeRangeSingle single)
+		{
+			_single = single;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeSingleUnion.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeSingleUnion.cs
new file mode 100644
index 0000000..04106da
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeSingleUnion.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Btree.Algebra;
+
+namespace Db4objects.Db4o.Internal.Btree.Algebra
+{
+	/// <exclude></exclude>
+	public class BTreeRangeSingleUnion : BTreeRangeSingleOperation
+	{
+		public BTreeRangeSingleUnion(BTreeRangeSingle single) : base(single)
+		{
+		}
+
+		protected override IBTreeRange Execute(BTreeRangeSingle single)
+		{
+			return BTreeAlgebra.Union(_single, single);
+		}
+
+		protected override IBTreeRange Execute(BTreeRangeUnion union)
+		{
+			return BTreeAlgebra.Union(union, _single);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeUnionIntersect.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeUnionIntersect.cs
new file mode 100644
index 0000000..6a53767
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeUnionIntersect.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Btree.Algebra;
+
+namespace Db4objects.Db4o.Internal.Btree.Algebra
+{
+	/// <exclude></exclude>
+	public class BTreeRangeUnionIntersect : BTreeRangeUnionOperation
+	{
+		public BTreeRangeUnionIntersect(BTreeRangeUnion union) : base(union)
+		{
+		}
+
+		protected override IBTreeRange Execute(BTreeRangeSingle range)
+		{
+			return BTreeAlgebra.Intersect(_union, range);
+		}
+
+		protected override IBTreeRange Execute(BTreeRangeUnion union)
+		{
+			return BTreeAlgebra.Intersect(_union, union);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeUnionOperation.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeUnionOperation.cs
new file mode 100644
index 0000000..4a160f3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeUnionOperation.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Btree.Algebra;
+
+namespace Db4objects.Db4o.Internal.Btree.Algebra
+{
+	/// <exclude></exclude>
+	public abstract class BTreeRangeUnionOperation : BTreeRangeOperation
+	{
+		protected readonly BTreeRangeUnion _union;
+
+		public BTreeRangeUnionOperation(BTreeRangeUnion union)
+		{
+			_union = union;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeUnionUnion.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeUnionUnion.cs
new file mode 100644
index 0000000..62b6c57
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Algebra/BTreeRangeUnionUnion.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Btree.Algebra;
+
+namespace Db4objects.Db4o.Internal.Btree.Algebra
+{
+	/// <exclude></exclude>
+	public class BTreeRangeUnionUnion : BTreeRangeUnionOperation
+	{
+		public BTreeRangeUnionUnion(BTreeRangeUnion union) : base(union)
+		{
+		}
+
+		protected override IBTreeRange Execute(BTreeRangeUnion union)
+		{
+			return BTreeAlgebra.Union(_union, union);
+		}
+
+		protected override IBTreeRange Execute(BTreeRangeSingle single)
+		{
+			return BTreeAlgebra.Union(_union, single);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTree.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTree.cs
new file mode 100644
index 0000000..7d70e34
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTree.cs
@@ -0,0 +1,909 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using System.Text;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Defragment;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Caching;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <exclude></exclude>
+	public class BTree : LocalPersistentBase, ITransactionParticipant, IBTreeStructureListener
+	{
+		private readonly BTreeConfiguration _config;
+
+		private const byte BtreeVersion = (byte)1;
+
+		private const int DefragmentIncrementOffset = 1 + Const4.IntLength * 2;
+
+		private readonly IIndexable4 _keyHandler;
+
+		private BTreeNode _root;
+
+		/// <summary>All instantiated nodes are held in this tree.</summary>
+		/// <remarks>All instantiated nodes are held in this tree.</remarks>
+		private TreeIntObject _nodes;
+
+		private int _size;
+
+		private IVisitor4 _removeListener;
+
+		private sealed class _TransactionLocal_40 : TransactionLocal
+		{
+			public _TransactionLocal_40()
+			{
+			}
+
+			// version byte
+			// size, node size  
+			public override object InitialValueFor(Transaction transaction)
+			{
+				return 0;
+			}
+		}
+
+		private readonly TransactionLocal _sizeDeltaInTransaction = new _TransactionLocal_40
+			();
+
+		protected IQueue4 _processing;
+
+		private int _nodeSize;
+
+		internal int _halfNodeSize;
+
+		private IBTreeStructureListener _structureListener;
+
+		private readonly ICache4 _nodeCache;
+
+		private TreeIntObject _evictedFromCache;
+
+		private bool _disposed;
+
+		public BTree(Transaction trans, BTreeConfiguration config, int id, IIndexable4 keyHandler
+			, int treeNodeSize) : base(config._idSystem)
+		{
+			_config = config;
+			if (null == keyHandler)
+			{
+				throw new ArgumentNullException();
+			}
+			_nodeSize = treeNodeSize;
+			_nodeCache = CacheFactory.NewLRUIntCache(config._cacheSize);
+			_halfNodeSize = _nodeSize / 2;
+			_nodeSize = _halfNodeSize * 2;
+			_keyHandler = keyHandler;
+			SetID(id);
+			if (IsNew())
+			{
+				SetStateDirty();
+				_root = new BTreeNode(this, 0, true, 0, 0, 0);
+				_root.Write(trans.SystemTransaction());
+				AddNode(_root);
+				Write(trans.SystemTransaction());
+			}
+			else
+			{
+				SetStateDeactivated();
+			}
+		}
+
+		public BTree(Transaction trans, BTreeConfiguration config, IIndexable4 keyHandler
+			) : this(trans, config, 0, keyHandler)
+		{
+		}
+
+		public BTree(Transaction trans, BTreeConfiguration config, int id, IIndexable4 keyHandler
+			) : this(trans, config, id, keyHandler, Config(trans).BTreeNodeSize())
+		{
+		}
+
+		public BTree(Transaction trans, int id, IIndexable4 keyHandler) : this(trans, BTreeConfiguration
+			.Default, id, keyHandler)
+		{
+		}
+
+		public BTree(Transaction trans, int id, IIndexable4 keyHandler, int nodeSize) : this
+			(trans, BTreeConfiguration.Default, id, keyHandler, nodeSize)
+		{
+		}
+
+		public virtual BTreeNode Root()
+		{
+			return _root;
+		}
+
+		public virtual int NodeSize()
+		{
+			return _nodeSize;
+		}
+
+		public virtual void Add(Transaction trans, object key)
+		{
+			KeyCantBeNull(key);
+			IPreparedComparison preparedComparison = _keyHandler.PrepareComparison(trans.Context
+				(), key);
+			Add(trans, preparedComparison, key);
+		}
+
+		public virtual void Add(Transaction trans, IPreparedComparison preparedComparison
+			, object key)
+		{
+			EnsureActive(trans);
+			Enlist(trans);
+			BTreeNode rootOrSplit = _root.Add(trans, preparedComparison, key);
+			if (rootOrSplit != null && rootOrSplit != _root)
+			{
+				EnsureDirty(trans);
+				_root = new BTreeNode(trans, _root, rootOrSplit);
+				_root.Write(trans.SystemTransaction());
+				AddNode(_root);
+			}
+			ConvertCacheEvictedNodesToReadMode();
+		}
+
+		public virtual object Remove(Transaction trans, object key)
+		{
+			BTreePointer bTreePointer = SearchPointer(trans, key);
+			if (bTreePointer == null)
+			{
+				return null;
+			}
+			object result = bTreePointer.Key();
+			Enlist(trans);
+			IPreparedComparison preparedComparison = KeyHandler().PrepareComparison(trans.Context
+				(), key);
+			BTreeNode node = bTreePointer.Node();
+			node.Remove(trans, preparedComparison, key, bTreePointer.Index());
+			ConvertCacheEvictedNodesToReadMode();
+			return result;
+		}
+
+		public virtual IBTreeRange SearchRange(Transaction trans, object key)
+		{
+			KeyCantBeNull(key);
+			return SearchRange(trans, KeyHandler().PrepareComparison(trans.Context(), key));
+		}
+
+		public virtual BTreePointer SearchPointer(Transaction trans, object key)
+		{
+			EnsureActive(trans);
+			KeyCantBeNull(key);
+			IPreparedComparison preparedComparison = KeyHandler().PrepareComparison(trans.Context
+				(), key);
+			BTreeNodeSearchResult start = SearchLeaf(trans, preparedComparison, SearchTarget.
+				Lowest);
+			BTreePointer bTreePointer = start.FirstValidPointer();
+			if (bTreePointer == null)
+			{
+				ConvertCacheEvictedNodesToReadMode();
+				return null;
+			}
+			object found = bTreePointer.Key();
+			ConvertCacheEvictedNodesToReadMode();
+			if (preparedComparison.CompareTo(found) == 0)
+			{
+				return bTreePointer;
+			}
+			return null;
+		}
+
+		public virtual object Search(Transaction trans, object key)
+		{
+			BTreePointer bTreePointer = SearchPointer(trans, key);
+			if (bTreePointer != null)
+			{
+				return bTreePointer.Key();
+			}
+			return null;
+		}
+
+		private IBTreeRange SearchRange(Transaction trans, IPreparedComparison preparedComparison
+			)
+		{
+			EnsureActive(trans);
+			// TODO: Optimize the following.
+			//       Part of the search operates against the same nodes.
+			//       As long as the bounds are on one node, the search
+			//       should walk the nodes in one go.
+			BTreeNodeSearchResult start = SearchLeaf(trans, preparedComparison, SearchTarget.
+				Lowest);
+			BTreeNodeSearchResult end = SearchLeaf(trans, preparedComparison, SearchTarget.Highest
+				);
+			IBTreeRange range = start.CreateIncludingRange(end);
+			ConvertCacheEvictedNodesToReadMode();
+			return range;
+		}
+
+		private void KeyCantBeNull(object key)
+		{
+			if (null == key)
+			{
+				throw new ArgumentNullException();
+			}
+		}
+
+		public virtual IIndexable4 KeyHandler()
+		{
+			return _keyHandler;
+		}
+
+		public virtual BTreeNodeSearchResult SearchLeaf(Transaction trans, object key, SearchTarget
+			 target)
+		{
+			return SearchLeaf(trans, _keyHandler.PrepareComparison(trans.Context(), key), target
+				);
+		}
+
+		public virtual BTreeNodeSearchResult SearchLeaf(Transaction trans, IPreparedComparison
+			 preparedComparison, SearchTarget target)
+		{
+			EnsureActive(trans);
+			BTreeNodeSearchResult result = _root.SearchLeaf(trans, preparedComparison, target
+				);
+			ConvertCacheEvictedNodesToReadMode();
+			return result;
+		}
+
+		public virtual void Commit(Transaction transaction)
+		{
+			if (_disposed)
+			{
+				return;
+			}
+			UpdateSize(transaction);
+			CommitNodes(transaction);
+			FinishTransaction(transaction);
+			ConvertCacheEvictedNodesToReadMode();
+		}
+
+		private void UpdateSize(Transaction transaction)
+		{
+			ByRef sizeInTransaction = SizeIn(transaction);
+			int sizeModification = (((int)sizeInTransaction.value));
+			if (sizeModification == 0)
+			{
+				return;
+			}
+			EnsureDirty(transaction);
+			_size += sizeModification;
+			sizeInTransaction.value = 0;
+		}
+
+		private ByRef SizeIn(Transaction trans)
+		{
+			return trans.Get(_sizeDeltaInTransaction);
+		}
+
+		private void CommitNodes(Transaction trans)
+		{
+			ProcessEachNode(new _IProcedure4_237(trans));
+		}
+
+		private sealed class _IProcedure4_237 : IProcedure4
+		{
+			public _IProcedure4_237(Transaction trans)
+			{
+				this.trans = trans;
+			}
+
+			public void Apply(object node)
+			{
+				((BTreeNode)node).Commit(trans);
+			}
+
+			private readonly Transaction trans;
+		}
+
+		private void ProcessEachNode(IProcedure4 action)
+		{
+			if (_nodes == null)
+			{
+				return;
+			}
+			ProcessAllNodes();
+			while (_processing.HasNext())
+			{
+				action.Apply((BTreeNode)_processing.Next());
+			}
+			_processing = null;
+		}
+
+		public virtual void Rollback(Transaction trans)
+		{
+			RollbackNodes(trans);
+			FinishTransaction(trans);
+			ConvertCacheEvictedNodesToReadMode();
+		}
+
+		private void FinishTransaction(Transaction trans)
+		{
+			Transaction systemTransaction = trans.SystemTransaction();
+			WriteAllNodes(systemTransaction);
+			Write(systemTransaction);
+			Purge();
+		}
+
+		private void RollbackNodes(Transaction trans)
+		{
+			ProcessEachNode(new _IProcedure4_266(trans));
+		}
+
+		private sealed class _IProcedure4_266 : IProcedure4
+		{
+			public _IProcedure4_266(Transaction trans)
+			{
+				this.trans = trans;
+			}
+
+			public void Apply(object node)
+			{
+				((BTreeNode)node).Rollback(trans);
+			}
+
+			private readonly Transaction trans;
+		}
+
+		private void WriteAllNodes(Transaction systemTransaction)
+		{
+			if (_nodes == null)
+			{
+				return;
+			}
+			_nodes.Traverse(new _IVisitor4_275(systemTransaction));
+		}
+
+		private sealed class _IVisitor4_275 : IVisitor4
+		{
+			public _IVisitor4_275(Transaction systemTransaction)
+			{
+				this.systemTransaction = systemTransaction;
+			}
+
+			public void Visit(object obj)
+			{
+				((BTreeNode)((TreeIntObject)obj).GetObject()).Write(systemTransaction);
+			}
+
+			private readonly Transaction systemTransaction;
+		}
+
+		private void Purge()
+		{
+			if (_nodes == null)
+			{
+				return;
+			}
+			Tree temp = _nodes;
+			_nodes = null;
+			_root.HoldChildrenAsIDs();
+			AddNode(_root);
+			temp.Traverse(new _IVisitor4_294());
+			for (IEnumerator entryIter = _nodeCache.GetEnumerator(); entryIter.MoveNext(); )
+			{
+				BTreeNodeCacheEntry entry = ((BTreeNodeCacheEntry)entryIter.Current);
+				entry._node.HoldChildrenAsIDs();
+			}
+		}
+
+		private sealed class _IVisitor4_294 : IVisitor4
+		{
+			public _IVisitor4_294()
+			{
+			}
+
+			public void Visit(object obj)
+			{
+				BTreeNode node = (BTreeNode)((TreeIntObject)obj).GetObject();
+				node.Purge();
+			}
+		}
+
+		private void ProcessAllNodes()
+		{
+			_processing = new NonblockingQueue();
+			_nodes.Traverse(new _IVisitor4_311(this));
+		}
+
+		private sealed class _IVisitor4_311 : IVisitor4
+		{
+			public _IVisitor4_311(BTree _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Visit(object node)
+			{
+				this._enclosing._processing.Add(((TreeIntObject)node).GetObject());
+			}
+
+			private readonly BTree _enclosing;
+		}
+
+		private void EnsureActive(Transaction trans)
+		{
+			if (!IsActive())
+			{
+				Read(trans.SystemTransaction());
+			}
+		}
+
+		private void EnsureDirty(Transaction trans)
+		{
+			EnsureActive(trans);
+			Enlist(trans);
+			SetStateDirty();
+		}
+
+		private void Enlist(Transaction trans)
+		{
+			if (CanEnlistWithTransaction())
+			{
+				((LocalTransaction)trans).Enlist(this);
+			}
+		}
+
+		protected virtual bool CanEnlistWithTransaction()
+		{
+			return _config._canEnlistWithTransaction;
+		}
+
+		public override byte GetIdentifier()
+		{
+			return Const4.Btree;
+		}
+
+		public virtual void SetRemoveListener(IVisitor4 vis)
+		{
+			_removeListener = vis;
+		}
+
+		public override int OwnLength()
+		{
+			return 1 + Const4.ObjectLength + (Const4.IntLength * 2) + Const4.IdLength;
+		}
+
+		public virtual BTreeNode ProduceNode(int id)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.BtreeProduceNode.Log(id);
+			}
+			TreeIntObject addtio = new TreeIntObject(id);
+			_nodes = (TreeIntObject)((TreeIntObject)Tree.Add(_nodes, addtio));
+			TreeIntObject tio = (TreeIntObject)addtio.AddedOrExisting();
+			BTreeNode node = (BTreeNode)tio.GetObject();
+			if (node == null)
+			{
+				node = CacheEntry(new BTreeNode(id, this))._node;
+				tio.SetObject(node);
+				AddToProcessing(node);
+			}
+			return node;
+		}
+
+		internal virtual void AddNode(BTreeNode node)
+		{
+			_nodes = (TreeIntObject)((TreeIntObject)Tree.Add(_nodes, new TreeIntObject(node.GetID
+				(), node)));
+			AddToProcessing(node);
+		}
+
+		internal virtual void AddToProcessing(BTreeNode node)
+		{
+			if (_processing != null)
+			{
+				_processing.Add(node);
+			}
+		}
+
+		internal virtual void RemoveNode(BTreeNode node)
+		{
+			_nodes = (TreeIntObject)((TreeInt)_nodes.RemoveLike(new TreeInt(node.GetID())));
+		}
+
+		internal virtual void NotifyRemoveListener(object obj)
+		{
+			if (_removeListener != null)
+			{
+				_removeListener.Visit(obj);
+			}
+		}
+
+		public override void ReadThis(Transaction a_trans, ByteArrayBuffer a_reader)
+		{
+			a_reader.IncrementOffset(1);
+			// first byte is version, for possible future format changes
+			_size = a_reader.ReadInt();
+			_nodeSize = a_reader.ReadInt();
+			_halfNodeSize = NodeSize() / 2;
+			_root = ProduceNode(a_reader.ReadInt());
+		}
+
+		public override void WriteThis(Transaction trans, ByteArrayBuffer a_writer)
+		{
+			a_writer.WriteByte(BtreeVersion);
+			a_writer.WriteInt(_size);
+			a_writer.WriteInt(NodeSize());
+			a_writer.WriteIDOf(trans, _root);
+		}
+
+		public virtual int Size(Transaction trans)
+		{
+			// This implementation of size will not work accurately for multiple
+			// transactions. If two transactions call clear and both commit, _size
+			// can end up negative.
+			// For multiple transactions the size patches only are an estimate.
+			EnsureActive(trans);
+			return _size + (((int)SizeIn(trans).value));
+		}
+
+		public virtual void TraverseKeys(Transaction trans, IVisitor4 visitor)
+		{
+			EnsureActive(trans);
+			if (_root == null)
+			{
+				return;
+			}
+			_root.TraverseKeys(trans, visitor);
+			ConvertCacheEvictedNodesToReadMode();
+		}
+
+		public virtual void SizeChanged(Transaction transaction, BTreeNode node, int changeBy
+			)
+		{
+			NotifyCountChanged(transaction, node, changeBy);
+			ByRef sizeInTransaction = SizeIn(transaction);
+			sizeInTransaction.value = (((int)sizeInTransaction.value)) + changeBy;
+		}
+
+		public virtual void Dispose(Transaction transaction)
+		{
+		}
+
+		public virtual BTreePointer FirstPointer(Transaction trans)
+		{
+			EnsureActive(trans);
+			if (null == _root)
+			{
+				return null;
+			}
+			BTreePointer pointer = _root.FirstPointer(trans);
+			ConvertCacheEvictedNodesToReadMode();
+			return pointer;
+		}
+
+		public virtual BTreePointer LastPointer(Transaction trans)
+		{
+			EnsureActive(trans);
+			if (null == _root)
+			{
+				return null;
+			}
+			BTreePointer pointer = _root.LastPointer(trans);
+			ConvertCacheEvictedNodesToReadMode();
+			return pointer;
+		}
+
+		public virtual Db4objects.Db4o.Internal.Btree.BTree DebugLoadFully(Transaction trans
+			)
+		{
+			EnsureActive(trans);
+			_root.DebugLoadFully(trans);
+			return this;
+		}
+
+		private void TraverseAllNodes(Transaction trans, IVisitor4 command)
+		{
+			EnsureActive(trans);
+			_root.TraverseAllNodes(trans, command);
+		}
+
+		public virtual void DefragIndex(DefragmentContextImpl context)
+		{
+			context.IncrementOffset(DefragmentIncrementOffset);
+			context.CopyID();
+		}
+
+		public virtual void DefragIndexNode(DefragmentContextImpl context)
+		{
+			BTreeNode.DefragIndex(context, _keyHandler);
+		}
+
+		public virtual void DefragBTree(IDefragmentServices services)
+		{
+			DefragmentContextImpl.ProcessCopy(services, GetID(), new _ISlotCopyHandler_481(this
+				));
+			services.TraverseAllIndexSlots(this, new _IVisitor4_486(this, services));
+			ConvertCacheEvictedNodesToReadMode();
+		}
+
+		private sealed class _ISlotCopyHandler_481 : ISlotCopyHandler
+		{
+			public _ISlotCopyHandler_481(BTree _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void ProcessCopy(DefragmentContextImpl context)
+			{
+				this._enclosing.DefragIndex(context);
+			}
+
+			private readonly BTree _enclosing;
+		}
+
+		private sealed class _IVisitor4_486 : IVisitor4
+		{
+			public _IVisitor4_486(BTree _enclosing, IDefragmentServices services)
+			{
+				this._enclosing = _enclosing;
+				this.services = services;
+			}
+
+			public void Visit(object obj)
+			{
+				int id = ((int)obj);
+				DefragmentContextImpl.ProcessCopy(services, id, new _ISlotCopyHandler_489(this));
+			}
+
+			private sealed class _ISlotCopyHandler_489 : ISlotCopyHandler
+			{
+				public _ISlotCopyHandler_489(_IVisitor4_486 _enclosing)
+				{
+					this._enclosing = _enclosing;
+				}
+
+				public void ProcessCopy(DefragmentContextImpl context)
+				{
+					this._enclosing._enclosing.DefragIndexNode(context);
+				}
+
+				private readonly _IVisitor4_486 _enclosing;
+			}
+
+			private readonly BTree _enclosing;
+
+			private readonly IDefragmentServices services;
+		}
+
+		internal virtual int CompareKeys(IContext context, object key1, object key2)
+		{
+			IPreparedComparison preparedComparison = _keyHandler.PrepareComparison(context, key1
+				);
+			return preparedComparison.CompareTo(key2);
+		}
+
+		private static Config4Impl Config(Transaction trans)
+		{
+			if (null == trans)
+			{
+				throw new ArgumentNullException();
+			}
+			return trans.Container().ConfigImpl;
+		}
+
+		public override void Free(LocalTransaction systemTrans)
+		{
+			_disposed = true;
+			FreeAllNodeIds(systemTrans, AllNodeIds(systemTrans));
+			base.Free((LocalTransaction)systemTrans);
+		}
+
+		private void FreeAllNodeIds(LocalTransaction systemTrans, IEnumerator allNodeIDs)
+		{
+			ITransactionalIdSystem idSystem = IdSystem(systemTrans);
+			while (allNodeIDs.MoveNext())
+			{
+				int id = ((int)allNodeIDs.Current);
+				idSystem.NotifySlotDeleted(id, SlotChangeFactory());
+			}
+		}
+
+		public virtual IEnumerator AllNodeIds(Transaction systemTrans)
+		{
+			Collection4 allNodeIDs = new Collection4();
+			TraverseAllNodes(systemTrans, new _IVisitor4_527(allNodeIDs));
+			return allNodeIDs.GetEnumerator();
+		}
+
+		private sealed class _IVisitor4_527 : IVisitor4
+		{
+			public _IVisitor4_527(Collection4 allNodeIDs)
+			{
+				this.allNodeIDs = allNodeIDs;
+			}
+
+			public void Visit(object node)
+			{
+				allNodeIDs.Add(((BTreeNode)node).GetID());
+			}
+
+			private readonly Collection4 allNodeIDs;
+		}
+
+		public virtual IBTreeRange AsRange(Transaction trans)
+		{
+			return new BTreeRangeSingle(trans, this, FirstPointer(trans), null);
+		}
+
+		private void TraverseAllNodes(IVisitor4 visitor)
+		{
+			if (_nodes == null)
+			{
+				return;
+			}
+			_nodes.Traverse(new _IVisitor4_543(visitor));
+		}
+
+		private sealed class _IVisitor4_543 : IVisitor4
+		{
+			public _IVisitor4_543(IVisitor4 visitor)
+			{
+				this.visitor = visitor;
+			}
+
+			public void Visit(object obj)
+			{
+				visitor.Visit(((TreeIntObject)obj).GetObject());
+			}
+
+			private readonly IVisitor4 visitor;
+		}
+
+		public override string ToString()
+		{
+			StringBuilder sb = new StringBuilder();
+			sb.Append("BTree ");
+			sb.Append(GetID());
+			sb.Append(" Active Nodes: \n");
+			TraverseAllNodes(new _IVisitor4_555(sb));
+			return sb.ToString();
+		}
+
+		private sealed class _IVisitor4_555 : IVisitor4
+		{
+			public _IVisitor4_555(StringBuilder sb)
+			{
+				this.sb = sb;
+			}
+
+			public void Visit(object obj)
+			{
+				sb.Append(obj);
+				sb.Append("\n");
+			}
+
+			private readonly StringBuilder sb;
+		}
+
+		public virtual void StructureListener(IBTreeStructureListener listener)
+		{
+			_structureListener = listener;
+		}
+
+		public virtual void NotifySplit(Transaction trans, BTreeNode originalNode, BTreeNode
+			 newRightNode)
+		{
+			if (_structureListener != null)
+			{
+				_structureListener.NotifySplit(trans, originalNode, newRightNode);
+			}
+		}
+
+		public virtual void NotifyDeleted(Transaction trans, BTreeNode node)
+		{
+			if (_structureListener != null)
+			{
+				_structureListener.NotifyDeleted(trans, node);
+			}
+		}
+
+		public virtual void NotifyCountChanged(Transaction trans, BTreeNode node, int diff
+			)
+		{
+			if (_structureListener != null)
+			{
+				_structureListener.NotifyCountChanged(trans, node, diff);
+			}
+		}
+
+		public virtual IEnumerator Iterator(Transaction trans)
+		{
+			return new BTreeIterator(trans, this);
+		}
+
+		public virtual void Clear(Transaction transaction)
+		{
+			BTreePointer currentPointer = FirstPointer(transaction);
+			while (currentPointer != null && currentPointer.IsValid())
+			{
+				BTreeNode node = currentPointer.Node();
+				int index = currentPointer.Index();
+				node.Remove(transaction, index);
+				currentPointer = currentPointer.Next();
+			}
+		}
+
+		public virtual ICache4 NodeCache()
+		{
+			return _nodeCache;
+		}
+
+		internal virtual BTreeNodeCacheEntry CacheEntry(BTreeNode node)
+		{
+			return ((BTreeNodeCacheEntry)_nodeCache.Produce(node.GetID(), new _IFunction4_605
+				(node), new _IProcedure4_609(this)));
+		}
+
+		private sealed class _IFunction4_605 : IFunction4
+		{
+			public _IFunction4_605(BTreeNode node)
+			{
+				this.node = node;
+			}
+
+			public object Apply(object id)
+			{
+				return new BTreeNodeCacheEntry(node);
+			}
+
+			private readonly BTreeNode node;
+		}
+
+		private sealed class _IProcedure4_609 : IProcedure4
+		{
+			public _IProcedure4_609(BTree _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Apply(object entry)
+			{
+				this._enclosing.EvictedFromCache(((BTreeNodeCacheEntry)entry)._node);
+			}
+
+			private readonly BTree _enclosing;
+		}
+
+		public override Db4objects.Db4o.Internal.Slots.SlotChangeFactory SlotChangeFactory
+			()
+		{
+			return _config._slotChangeFactory;
+		}
+
+		public virtual void EvictedFromCache(BTreeNode node)
+		{
+			_evictedFromCache = ((TreeIntObject)Tree.Add(_evictedFromCache, new TreeIntObject
+				(node.GetID(), node)));
+		}
+
+		public virtual void ConvertCacheEvictedNodesToReadMode()
+		{
+			if (_evictedFromCache == null)
+			{
+				return;
+			}
+			Tree.Traverse(_evictedFromCache, new _IVisitor4_628());
+			_evictedFromCache = null;
+		}
+
+		private sealed class _IVisitor4_628 : IVisitor4
+		{
+			public _IVisitor4_628()
+			{
+			}
+
+			public void Visit(object treeIntObject)
+			{
+				((BTreeNode)((TreeIntObject)treeIntObject)._object).ToReadMode();
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeAdd.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeAdd.cs
new file mode 100644
index 0000000..66d4129
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeAdd.cs
@@ -0,0 +1,73 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <exclude></exclude>
+	public class BTreeAdd : BTreePatch
+	{
+		public BTreeAdd(Transaction transaction, object obj) : base(transaction, obj)
+		{
+		}
+
+		protected virtual object RolledBack(BTree btree)
+		{
+			btree.NotifyRemoveListener(new TransactionContext(_transaction, GetObject()));
+			return No4.Instance;
+		}
+
+		public override string ToString()
+		{
+			return "(+) " + base.ToString();
+		}
+
+		public override object Commit(Transaction trans, BTree btree, BTreeNode node)
+		{
+			if (_transaction == trans)
+			{
+				return GetObject();
+			}
+			return this;
+		}
+
+		public override BTreePatch ForTransaction(Transaction trans)
+		{
+			if (_transaction == trans)
+			{
+				return this;
+			}
+			return null;
+		}
+
+		public override object Key(Transaction trans)
+		{
+			if (_transaction != trans)
+			{
+				return No4.Instance;
+			}
+			return GetObject();
+		}
+
+		public override object Rollback(Transaction trans, BTree btree)
+		{
+			if (_transaction == trans)
+			{
+				return RolledBack(btree);
+			}
+			return this;
+		}
+
+		public override bool IsAdd()
+		{
+			return true;
+		}
+
+		public override int SizeDiff(Transaction trans)
+		{
+			return _transaction == trans ? 1 : 0;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeCancelledRemoval.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeCancelledRemoval.cs
new file mode 100644
index 0000000..20c8ba8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeCancelledRemoval.cs
@@ -0,0 +1,54 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <exclude></exclude>
+	public class BTreeCancelledRemoval : BTreeUpdate
+	{
+		private readonly object _newKey;
+
+		public BTreeCancelledRemoval(Transaction transaction, object originalKey, object 
+			newKey, BTreeUpdate existingPatches) : base(transaction, originalKey)
+		{
+			_newKey = newKey;
+			if (null != existingPatches)
+			{
+				Append(existingPatches);
+			}
+		}
+
+		protected override void Committed(BTree btree)
+		{
+		}
+
+		// do nothing
+		public override bool IsCancelledRemoval()
+		{
+			return true;
+		}
+
+		public override string ToString()
+		{
+			return "(u) " + base.ToString();
+		}
+
+		protected override object GetCommittedObject()
+		{
+			return _newKey;
+		}
+
+		protected override void AdjustSizeOnRemovalByOtherTransaction(BTree btree, BTreeNode
+			 node)
+		{
+		}
+
+		// The other transaction reduces the size, this entry ignores.
+		protected override int SizeDiff()
+		{
+			return 1;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeConfiguration.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeConfiguration.cs
new file mode 100644
index 0000000..8b0450d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeConfiguration.cs
@@ -0,0 +1,37 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <exclude></exclude>
+	public class BTreeConfiguration
+	{
+		public static readonly Db4objects.Db4o.Internal.Btree.BTreeConfiguration Default = 
+			new Db4objects.Db4o.Internal.Btree.BTreeConfiguration(null, 20, true);
+
+		public readonly ITransactionalIdSystem _idSystem;
+
+		public readonly SlotChangeFactory _slotChangeFactory;
+
+		public readonly bool _canEnlistWithTransaction;
+
+		public readonly int _cacheSize;
+
+		public BTreeConfiguration(ITransactionalIdSystem idSystem, SlotChangeFactory slotChangeFactory
+			, int cacheSize, bool canEnlistWithTransaction)
+		{
+			_idSystem = idSystem;
+			_slotChangeFactory = slotChangeFactory;
+			_canEnlistWithTransaction = canEnlistWithTransaction;
+			_cacheSize = cacheSize;
+		}
+
+		public BTreeConfiguration(ITransactionalIdSystem idSystem, int cacheSize, bool canEnlistWithTransaction
+			) : this(idSystem, SlotChangeFactory.SystemObjects, cacheSize, canEnlistWithTransaction
+			)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeIterator.cs
new file mode 100644
index 0000000..48215bc
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeIterator.cs
@@ -0,0 +1,67 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <exclude></exclude>
+	public class BTreeIterator : IEnumerator
+	{
+		private readonly Transaction _transaction;
+
+		private readonly BTree _bTree;
+
+		private BTreePointer _currentPointer;
+
+		private bool _beyondEnd;
+
+		public BTreeIterator(Transaction trans, BTree bTree)
+		{
+			_transaction = trans;
+			_bTree = bTree;
+		}
+
+		public virtual object Current
+		{
+			get
+			{
+				if (_currentPointer == null)
+				{
+					throw new InvalidOperationException();
+				}
+				return _currentPointer.Key();
+			}
+		}
+
+		public virtual bool MoveNext()
+		{
+			if (_beyondEnd)
+			{
+				return false;
+			}
+			if (BeforeFirst())
+			{
+				_currentPointer = _bTree.FirstPointer(_transaction);
+			}
+			else
+			{
+				_currentPointer = _currentPointer.Next();
+			}
+			_beyondEnd = (_currentPointer == null);
+			return !_beyondEnd;
+		}
+
+		private bool BeforeFirst()
+		{
+			return _currentPointer == null;
+		}
+
+		public virtual void Reset()
+		{
+			throw new NotSupportedException();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeNode.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeNode.cs
new file mode 100644
index 0000000..61b334d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeNode.cs
@@ -0,0 +1,1458 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Marshall;
+using Sharpen;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <summary>
+	/// We work with BTreeNode in two states:
+	/// - deactivated: never read, no valid members, ID correct or 0 if new
+	/// - write: real representation of keys, values and children in arrays
+	/// The write state can be detected with canWrite().
+	/// </summary>
+	/// <remarks>
+	/// We work with BTreeNode in two states:
+	/// - deactivated: never read, no valid members, ID correct or 0 if new
+	/// - write: real representation of keys, values and children in arrays
+	/// The write state can be detected with canWrite(). States can be changed
+	/// as needed with prepareRead() and prepareWrite().
+	/// </remarks>
+	/// <exclude></exclude>
+	public sealed class BTreeNode : LocalPersistentBase
+	{
+		private const int CountLeafAnd3LinkLength = (Const4.IntLength * 4) + 1;
+
+		private const int SlotLeadingLength = Const4.LeadingLength + CountLeafAnd3LinkLength;
+
+		internal readonly BTree _btree;
+
+		private int _count;
+
+		private bool _isLeaf;
+
+		private object[] _keys;
+
+		/// <summary>Can contain BTreeNode or Integer for ID of BTreeNode</summary>
+		private object[] _children;
+
+		private int _parentID;
+
+		private int _previousID;
+
+		private int _nextID;
+
+		private bool _dead;
+
+		public BTreeNode(BTree btree, int count, bool isLeaf, int parentID, int previousID
+			, int nextID)
+		{
+			_btree = btree;
+			_parentID = parentID;
+			_previousID = previousID;
+			_nextID = nextID;
+			_count = count;
+			_isLeaf = isLeaf;
+			PrepareArrays();
+		}
+
+		public BTreeNode(int id, BTree btree)
+		{
+			_btree = btree;
+			SetID(id);
+			SetStateDeactivated();
+		}
+
+		public BTreeNode(Transaction trans, Db4objects.Db4o.Internal.Btree.BTreeNode firstChild
+			, Db4objects.Db4o.Internal.Btree.BTreeNode secondChild) : this(firstChild._btree
+			, 2, false, 0, 0, 0)
+		{
+			_keys[0] = firstChild._keys[0];
+			_children[0] = firstChild;
+			_keys[1] = secondChild._keys[0];
+			_children[1] = secondChild;
+			Write(trans.SystemTransaction());
+			firstChild.SetParentID(trans, GetID());
+			secondChild.SetParentID(trans, GetID());
+		}
+
+		public BTree Btree()
+		{
+			return _btree;
+		}
+
+		/// <returns>
+		/// the split node if this node is split
+		/// or this if the first key has changed
+		/// </returns>
+		public Db4objects.Db4o.Internal.Btree.BTreeNode Add(Transaction trans, IPreparedComparison
+			 preparedComparison, object obj)
+		{
+			ByteArrayBuffer reader = PrepareRead(trans);
+			Searcher s = Search(trans, preparedComparison, reader);
+			if (_isLeaf)
+			{
+				PrepareWrite(trans);
+				SetStateDirty();
+				if (WasRemoved(trans, s))
+				{
+					CancelRemoval(trans, obj, s.Cursor());
+					return null;
+				}
+				if (s.Count() > 0 && !s.BeforeFirst())
+				{
+					s.MoveForward();
+				}
+				PrepareInsert(s.Cursor());
+				_keys[s.Cursor()] = ApplyNewAddPatch(trans, obj);
+			}
+			else
+			{
+				Db4objects.Db4o.Internal.Btree.BTreeNode childNode = Child(reader, s.Cursor());
+				Db4objects.Db4o.Internal.Btree.BTreeNode childNodeOrSplit = childNode.Add(trans, 
+					preparedComparison, obj);
+				if (childNodeOrSplit == null)
+				{
+					return null;
+				}
+				PrepareWrite(trans);
+				SetStateDirty();
+				_keys[s.Cursor()] = childNode._keys[0];
+				if (childNode != childNodeOrSplit)
+				{
+					int splitCursor = s.Cursor() + 1;
+					PrepareInsert(splitCursor);
+					_keys[splitCursor] = childNodeOrSplit._keys[0];
+					_children[splitCursor] = childNodeOrSplit;
+				}
+			}
+			if (MustSplit())
+			{
+				return Split(trans);
+			}
+			if (s.Cursor() == 0)
+			{
+				return this;
+			}
+			return null;
+		}
+
+		private bool MustSplit()
+		{
+			return _count >= _btree.NodeSize();
+		}
+
+		private BTreeAdd ApplyNewAddPatch(Transaction trans, object obj)
+		{
+			SizeIncrement(trans);
+			return new BTreeAdd(trans, obj);
+		}
+
+		private void CancelRemoval(Transaction trans, object obj, int index)
+		{
+			BTreeUpdate patch = (BTreeUpdate)KeyPatch(index);
+			BTreeUpdate nextPatch = patch.RemoveFor(trans);
+			_keys[index] = NewCancelledRemoval(trans, patch.GetObject(), obj, nextPatch);
+			SizeIncrement(trans);
+		}
+
+		private BTreePatch NewCancelledRemoval(Transaction trans, object originalObject, 
+			object currentObject, BTreeUpdate existingPatches)
+		{
+			return new BTreeCancelledRemoval(trans, originalObject, currentObject, existingPatches
+				);
+		}
+
+		private void SizeIncrement(Transaction trans)
+		{
+			_btree.SizeChanged(trans, this, 1);
+		}
+
+		private bool WasRemoved(Transaction trans, Searcher s)
+		{
+			if (!s.FoundMatch())
+			{
+				return false;
+			}
+			BTreePatch patch = KeyPatch(trans, s.Cursor());
+			return patch != null && patch.IsRemove();
+		}
+
+		internal BTreeNodeSearchResult SearchLeaf(Transaction trans, IPreparedComparison 
+			preparedComparison, SearchTarget target)
+		{
+			ByteArrayBuffer reader = PrepareRead(trans);
+			Searcher s = Search(trans, preparedComparison, reader, target);
+			if (!_isLeaf)
+			{
+				return Child(reader, s.Cursor()).SearchLeaf(trans, preparedComparison, target);
+			}
+			if (!s.FoundMatch() || target == SearchTarget.Any || target == SearchTarget.Highest)
+			{
+				return new BTreeNodeSearchResult(trans, reader, Btree(), s, this);
+			}
+			if (target == SearchTarget.Lowest)
+			{
+				BTreeNodeSearchResult res = FindLowestLeafMatch(trans, preparedComparison, s.Cursor
+					() - 1);
+				if (res != null)
+				{
+					return res;
+				}
+				return CreateMatchingSearchResult(trans, reader, s.Cursor());
+			}
+			throw new InvalidOperationException();
+		}
+
+		private BTreeNodeSearchResult FindLowestLeafMatch(Transaction trans, IPreparedComparison
+			 preparedComparison, int index)
+		{
+			return FindLowestLeafMatch(trans, preparedComparison, PrepareRead(trans), index);
+		}
+
+		private BTreeNodeSearchResult FindLowestLeafMatch(Transaction trans, IPreparedComparison
+			 preparedComparison, ByteArrayBuffer reader, int index)
+		{
+			if (index >= 0)
+			{
+				if (!CompareEquals(preparedComparison, trans, reader, index))
+				{
+					return null;
+				}
+				if (index > 0)
+				{
+					BTreeNodeSearchResult res = FindLowestLeafMatch(trans, preparedComparison, reader
+						, index - 1);
+					if (res != null)
+					{
+						return res;
+					}
+					return CreateMatchingSearchResult(trans, reader, index);
+				}
+			}
+			Db4objects.Db4o.Internal.Btree.BTreeNode node = PreviousNode();
+			if (node != null)
+			{
+				ByteArrayBuffer nodeReader = node.PrepareRead(trans);
+				BTreeNodeSearchResult res = node.FindLowestLeafMatch(trans, preparedComparison, nodeReader
+					, node.LastIndex());
+				if (res != null)
+				{
+					return res;
+				}
+			}
+			if (index < 0)
+			{
+				return null;
+			}
+			return CreateMatchingSearchResult(trans, reader, index);
+		}
+
+		private bool CompareEquals(IPreparedComparison preparedComparison, Transaction trans
+			, ByteArrayBuffer reader, int index)
+		{
+			if (CanWrite())
+			{
+				return CompareInWriteMode(preparedComparison, index) == 0;
+			}
+			return CompareInReadMode(trans, preparedComparison, reader, index) == 0;
+		}
+
+		private BTreeNodeSearchResult CreateMatchingSearchResult(Transaction trans, ByteArrayBuffer
+			 reader, int index)
+		{
+			return new BTreeNodeSearchResult(trans, reader, Btree(), this, index, true);
+		}
+
+		public bool CanWrite()
+		{
+			return _keys != null;
+		}
+
+		internal Db4objects.Db4o.Internal.Btree.BTreeNode Child(int index)
+		{
+			if (_children[index] is Db4objects.Db4o.Internal.Btree.BTreeNode)
+			{
+				return (Db4objects.Db4o.Internal.Btree.BTreeNode)_children[index];
+			}
+			return ProduceChild(index, ((int)_children[index]));
+		}
+
+		internal Db4objects.Db4o.Internal.Btree.BTreeNode Child(ByteArrayBuffer reader, int
+			 index)
+		{
+			if (ChildLoaded(index))
+			{
+				return (Db4objects.Db4o.Internal.Btree.BTreeNode)_children[index];
+			}
+			return ProduceChild(index, ChildID(reader, index));
+		}
+
+		private Db4objects.Db4o.Internal.Btree.BTreeNode ProduceChild(int index, int childID
+			)
+		{
+			Db4objects.Db4o.Internal.Btree.BTreeNode child = _btree.ProduceNode(childID);
+			if (_children != null)
+			{
+				_children[index] = child;
+			}
+			return child;
+		}
+
+		private int ChildID(ByteArrayBuffer reader, int index)
+		{
+			if (_children == null)
+			{
+				SeekChild(reader, index);
+				return reader.ReadInt();
+			}
+			return ChildID(index);
+		}
+
+		private int ChildID(int index)
+		{
+			if (ChildLoaded(index))
+			{
+				return ((Db4objects.Db4o.Internal.Btree.BTreeNode)_children[index]).GetID();
+			}
+			return ((int)_children[index]);
+		}
+
+		private bool ChildLoaded(int index)
+		{
+			if (_children == null)
+			{
+				return false;
+			}
+			return _children[index] is Db4objects.Db4o.Internal.Btree.BTreeNode;
+		}
+
+		private bool ChildCanSupplyFirstKey(int index)
+		{
+			if (!ChildLoaded(index))
+			{
+				return false;
+			}
+			return ((Db4objects.Db4o.Internal.Btree.BTreeNode)_children[index]).CanWrite();
+		}
+
+		public void Commit(Transaction trans)
+		{
+			CommitOrRollback(trans, true);
+		}
+
+		internal void CommitOrRollback(Transaction trans, bool isCommit)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.BtreeNodeCommitOrRollback.Log(GetID());
+			}
+			if (_dead)
+			{
+				return;
+			}
+			if (!_isLeaf)
+			{
+				return;
+			}
+			if (!IsDirty(trans))
+			{
+				return;
+			}
+			object keyZero = _keys[0];
+			object[] tempKeys = new object[_btree.NodeSize()];
+			int count = 0;
+			for (int i = 0; i < _count; i++)
+			{
+				object key = _keys[i];
+				BTreePatch patch = KeyPatch(i);
+				if (patch != null)
+				{
+					key = isCommit ? patch.Commit(trans, _btree, this) : patch.Rollback(trans, _btree
+						);
+				}
+				if (key != No4.Instance)
+				{
+					tempKeys[count] = key;
+					count++;
+				}
+			}
+			_keys = tempKeys;
+			_count = count;
+			if (FreeIfEmpty(trans))
+			{
+				return;
+			}
+			SetStateDirty();
+			// TODO: Merge nodes here on low _count value.
+			if (_keys[0] != keyZero)
+			{
+				TellParentAboutChangedKey(trans);
+			}
+		}
+
+		private bool FreeIfEmpty(Transaction trans)
+		{
+			return FreeIfEmpty(trans, _count);
+		}
+
+		private bool FreeIfEmpty(Transaction trans, int count)
+		{
+			if (count > 0)
+			{
+				return false;
+			}
+			if (IsRoot())
+			{
+				return false;
+			}
+			Free((LocalTransaction)trans);
+			return true;
+		}
+
+		private bool IsRoot()
+		{
+			return _btree.Root() == this;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj)
+			{
+				return true;
+			}
+			if (!(obj is Db4objects.Db4o.Internal.Btree.BTreeNode))
+			{
+				return false;
+			}
+			Db4objects.Db4o.Internal.Btree.BTreeNode other = (Db4objects.Db4o.Internal.Btree.BTreeNode
+				)obj;
+			return GetID() == other.GetID();
+		}
+
+		public override int GetHashCode()
+		{
+			return GetID();
+		}
+
+		public override void Free(LocalTransaction trans)
+		{
+			_dead = true;
+			if (!IsRoot())
+			{
+				Db4objects.Db4o.Internal.Btree.BTreeNode parent = _btree.ProduceNode(_parentID);
+				parent.RemoveChild(trans, this);
+			}
+			PointPreviousTo(trans, _nextID);
+			PointNextTo(trans, _previousID);
+			base.Free((LocalTransaction)trans);
+			_btree.RemoveNode(this);
+			_btree.NotifyDeleted(trans, this);
+		}
+
+		internal void HoldChildrenAsIDs()
+		{
+			if (_children == null)
+			{
+				return;
+			}
+			for (int i = 0; i < _count; i++)
+			{
+				if (_children[i] is Db4objects.Db4o.Internal.Btree.BTreeNode)
+				{
+					_children[i] = ((Db4objects.Db4o.Internal.Btree.BTreeNode)_children[i]).GetID();
+				}
+			}
+		}
+
+		private void RemoveChild(Transaction trans, Db4objects.Db4o.Internal.Btree.BTreeNode
+			 child)
+		{
+			PrepareWrite(trans);
+			SetStateDirty();
+			int id = child.GetID();
+			for (int i = 0; i < _count; i++)
+			{
+				if (ChildID(i) == id)
+				{
+					if (FreeIfEmpty(trans, _count - 1))
+					{
+						return;
+					}
+					Remove(i);
+					if (i < 1)
+					{
+						TellParentAboutChangedKey(trans);
+					}
+					if (_count == 0)
+					{
+						// root node empty case only, have to turn it into a leaf
+						_isLeaf = true;
+					}
+					return;
+				}
+			}
+			throw new InvalidOperationException("child not found");
+		}
+
+		private void KeyChanged(Transaction trans, Db4objects.Db4o.Internal.Btree.BTreeNode
+			 child)
+		{
+			PrepareWrite(trans);
+			SetStateDirty();
+			int id = child.GetID();
+			for (int i = 0; i < _count; i++)
+			{
+				if (ChildID(i) == id)
+				{
+					_keys[i] = child._keys[0];
+					_children[i] = child;
+					KeyChanged(trans, i);
+					return;
+				}
+			}
+			throw new InvalidOperationException("child not found");
+		}
+
+		private void TellParentAboutChangedKey(Transaction trans)
+		{
+			if (!IsRoot())
+			{
+				Db4objects.Db4o.Internal.Btree.BTreeNode parent = _btree.ProduceNode(_parentID);
+				parent.KeyChanged(trans, this);
+			}
+		}
+
+		private bool IsDirty(Transaction trans)
+		{
+			if (!CanWrite())
+			{
+				return false;
+			}
+			for (int i = 0; i < _count; i++)
+			{
+				if (KeyPatch(trans, i) != null)
+				{
+					return true;
+				}
+			}
+			return false;
+		}
+
+		private int CompareInWriteMode(IPreparedComparison preparedComparison, int index)
+		{
+			return -preparedComparison.CompareTo(Key(index));
+		}
+
+		private int CompareInReadMode(Transaction trans, IPreparedComparison preparedComparison
+			, ByteArrayBuffer reader, int index)
+		{
+			SeekKey(reader, index);
+			return -preparedComparison.CompareTo(KeyHandler().ReadIndexEntry(trans.Context(), 
+				reader));
+		}
+
+		public int Count()
+		{
+			return _count;
+		}
+
+		private int EntryLength()
+		{
+			int len = KeyHandler().LinkLength();
+			if (!_isLeaf)
+			{
+				len += Const4.IdLength;
+			}
+			return len;
+		}
+
+		public int FirstKeyIndex(Transaction trans)
+		{
+			for (int ix = 0; ix < _count; ix++)
+			{
+				if (IndexIsValid(trans, ix))
+				{
+					return ix;
+				}
+			}
+			return -1;
+		}
+
+		public int LastKeyIndex(Transaction trans)
+		{
+			for (int ix = _count - 1; ix >= 0; ix--)
+			{
+				if (IndexIsValid(trans, ix))
+				{
+					return ix;
+				}
+			}
+			return -1;
+		}
+
+		public bool IndexIsValid(Transaction trans, int index)
+		{
+			if (!CanWrite())
+			{
+				return true;
+			}
+			BTreePatch patch = KeyPatch(index);
+			if (patch == null)
+			{
+				return true;
+			}
+			return patch.Key(trans) != No4.Instance;
+		}
+
+		private object FirstKey(Transaction trans)
+		{
+			int index = FirstKeyIndex(trans);
+			if (-1 == index)
+			{
+				return No4.Instance;
+			}
+			return InternalKey(trans, index);
+		}
+
+		public override byte GetIdentifier()
+		{
+			return Const4.BtreeNode;
+		}
+
+		private void PrepareInsert(int pos)
+		{
+			if (pos > LastIndex())
+			{
+				_count++;
+				return;
+			}
+			int len = _count - pos;
+			System.Array.Copy(_keys, pos, _keys, pos + 1, len);
+			if (_children != null)
+			{
+				System.Array.Copy(_children, pos, _children, pos + 1, len);
+			}
+			_count++;
+		}
+
+		private void Remove(int pos)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.BtreeNodeRemove.Log(GetID());
+			}
+			int len = _count - pos;
+			_count--;
+			System.Array.Copy(_keys, pos + 1, _keys, pos, len);
+			_keys[_count] = null;
+			if (_children != null)
+			{
+				System.Array.Copy(_children, pos + 1, _children, pos, len);
+				_children[_count] = null;
+			}
+		}
+
+		internal object Key(int index)
+		{
+			object obj = _keys[index];
+			if (obj is BTreePatch)
+			{
+				return ((BTreePatch)obj).GetObject();
+			}
+			return obj;
+		}
+
+		public object Key(Transaction trans, int index)
+		{
+			return Key(trans, PrepareRead(trans), index);
+		}
+
+		internal object Key(Transaction trans, ByteArrayBuffer reader, int index)
+		{
+			if (CanWrite())
+			{
+				return InternalKey(trans, index);
+			}
+			if (reader == null)
+			{
+				reader = PrepareRead(trans);
+			}
+			if (CanWrite())
+			{
+				return InternalKey(trans, index);
+			}
+			SeekKey(reader, index);
+			return KeyHandler().ReadIndexEntry(trans.Context(), reader);
+		}
+
+		private object InternalKey(Transaction trans, int index)
+		{
+			BTreePatch patch = KeyPatch(index);
+			if (patch == null)
+			{
+				return _keys[index];
+			}
+			return patch.Key(trans);
+		}
+
+		private BTreePatch KeyPatch(int index)
+		{
+			object obj = _keys[index];
+			if (obj is BTreePatch)
+			{
+				return (BTreePatch)obj;
+			}
+			return null;
+		}
+
+		internal BTreePatch KeyPatch(Transaction trans, int index)
+		{
+			object obj = _keys[index];
+			if (obj is BTreePatch)
+			{
+				return ((BTreePatch)obj).ForTransaction(trans);
+			}
+			return null;
+		}
+
+		private IIndexable4 KeyHandler()
+		{
+			return _btree.KeyHandler();
+		}
+
+		public override int OwnLength()
+		{
+			return SlotLeadingLength + (_count * EntryLength()) + Const4.BracketsBytes;
+		}
+
+		internal ByteArrayBuffer PrepareRead(Transaction trans)
+		{
+			BTreeNodeCacheEntry cacheEntry = Btree().CacheEntry(this);
+			if (CanWrite())
+			{
+				return null;
+			}
+			if (IsNew())
+			{
+				return null;
+			}
+			Transaction systemTransaction = trans.SystemTransaction();
+			ByteArrayBuffer buffer = cacheEntry.Buffer();
+			if (buffer != null)
+			{
+				// Cache hit, still unread
+				buffer.Seek(0);
+				Read(systemTransaction, buffer);
+				cacheEntry.Buffer(null);
+				_btree.AddToProcessing(this);
+				return null;
+			}
+			buffer = ProduceReadBuffer(systemTransaction);
+			ReadNodeHeader(buffer);
+			cacheEntry.Buffer(buffer);
+			return buffer;
+		}
+
+		internal void PrepareWrite(Transaction trans)
+		{
+			if (_dead)
+			{
+				return;
+			}
+			BTreeNodeCacheEntry cacheEntry = Btree().CacheEntry(this);
+			if (CanWrite())
+			{
+				return;
+			}
+			ByteArrayBuffer buffer = cacheEntry.Buffer();
+			if (buffer != null)
+			{
+				buffer.Seek(0);
+				Read(trans.SystemTransaction(), buffer);
+				cacheEntry.Buffer(null);
+			}
+			else
+			{
+				Read(trans.SystemTransaction());
+			}
+			_btree.AddToProcessing(this);
+		}
+
+		private void PrepareArrays()
+		{
+			if (CanWrite())
+			{
+				return;
+			}
+			_keys = new object[_btree.NodeSize()];
+			if (!_isLeaf)
+			{
+				_children = new object[_btree.NodeSize()];
+			}
+		}
+
+		private void ReadNodeHeader(ByteArrayBuffer reader)
+		{
+			_count = reader.ReadInt();
+			byte leafByte = reader.ReadByte();
+			_isLeaf = (leafByte == 1);
+			_parentID = reader.ReadInt();
+			_previousID = reader.ReadInt();
+			_nextID = reader.ReadInt();
+		}
+
+		public override void ReadThis(Transaction trans, ByteArrayBuffer reader)
+		{
+			ReadNodeHeader(reader);
+			PrepareArrays();
+			bool isInner = !_isLeaf;
+			for (int i = 0; i < _count; i++)
+			{
+				_keys[i] = KeyHandler().ReadIndexEntry(trans.Context(), reader);
+				if (isInner)
+				{
+					_children[i] = reader.ReadInt();
+				}
+			}
+		}
+
+		public void Remove(Transaction trans, int index)
+		{
+			if (!_isLeaf)
+			{
+				throw new InvalidOperationException();
+			}
+			PrepareWrite(trans);
+			SetStateDirty();
+			object obj = null;
+			BTreePatch patch = KeyPatch(index);
+			if (patch == null)
+			{
+				obj = _keys[index];
+			}
+			else
+			{
+				BTreePatch transPatch = patch.ForTransaction(trans);
+				if (transPatch != null)
+				{
+					obj = transPatch.GetObject();
+				}
+				else
+				{
+					// There could be more than one patch with different object
+					// identities. We have no means to determine a "best" object 
+					// so we just take any one. Could be problematic.
+					obj = patch.GetObject();
+				}
+			}
+			Remove(trans, obj, index);
+		}
+
+		public bool Remove(Transaction trans, object obj, int index)
+		{
+			if (!_isLeaf)
+			{
+				throw new InvalidOperationException();
+			}
+			PrepareWrite(trans);
+			SetStateDirty();
+			BTreePatch patch = KeyPatch(index);
+			// no patch, no problem, can remove
+			if (patch == null)
+			{
+				_keys[index] = ApplyNewRemovePatch(trans, obj);
+				KeyChanged(trans, index);
+				return true;
+			}
+			BTreePatch transPatch = patch.ForTransaction(trans);
+			if (transPatch != null)
+			{
+				if (transPatch.IsAdd())
+				{
+					CancelAdding(trans, index);
+					return true;
+				}
+				if (transPatch.IsCancelledRemoval())
+				{
+					BTreeRemove removePatch = ApplyNewRemovePatch(trans, transPatch.GetObject());
+					_keys[index] = ((BTreeUpdate)patch).ReplacePatch(transPatch, removePatch);
+					KeyChanged(trans, index);
+					return true;
+				}
+			}
+			else
+			{
+				// If the patch is a removal of a cancelled removal for another
+				// transaction, we need one for this transaction also.
+				if (!patch.IsAdd())
+				{
+					((BTreeUpdate)patch).Append(ApplyNewRemovePatch(trans, obj));
+					return true;
+				}
+			}
+			return false;
+		}
+
+		public void Remove(Transaction trans, IPreparedComparison preparedComparison, object
+			 obj, int index)
+		{
+			if (Remove(trans, obj, index))
+			{
+				return;
+			}
+			// now we try if removal is OK for the next element in this node
+			if (index != LastIndex())
+			{
+				if (CompareInWriteMode(preparedComparison, index + 1) != 0)
+				{
+					return;
+				}
+				Remove(trans, preparedComparison, obj, index + 1);
+				return;
+			}
+			// nothing else worked so far, move on to the next node, try there
+			Db4objects.Db4o.Internal.Btree.BTreeNode node = NextNode();
+			if (node == null)
+			{
+				return;
+			}
+			node.PrepareWrite(trans);
+			if (node.CompareInWriteMode(preparedComparison, 0) != 0)
+			{
+				return;
+			}
+			node.Remove(trans, preparedComparison, obj, 0);
+		}
+
+		private void CancelAdding(Transaction trans, int index)
+		{
+			_btree.NotifyRemoveListener(new TransactionContext(trans, KeyPatch(index).GetObject
+				()));
+			if (FreeIfEmpty(trans, _count - 1))
+			{
+				SizeDecrement(trans);
+				return;
+			}
+			Remove(index);
+			KeyChanged(trans, index);
+			SizeDecrement(trans);
+		}
+
+		private void SizeDecrement(Transaction trans)
+		{
+			_btree.SizeChanged(trans, this, -1);
+		}
+
+		private int LastIndex()
+		{
+			return _count - 1;
+		}
+
+		private BTreeRemove ApplyNewRemovePatch(Transaction trans, object key)
+		{
+			SizeDecrement(trans);
+			return new BTreeRemove(trans, key);
+		}
+
+		private void KeyChanged(Transaction trans, int index)
+		{
+			if (index == 0)
+			{
+				TellParentAboutChangedKey(trans);
+			}
+		}
+
+		internal void Rollback(Transaction trans)
+		{
+			CommitOrRollback(trans, false);
+		}
+
+		private Searcher Search(Transaction trans, IPreparedComparison preparedComparison
+			, ByteArrayBuffer reader)
+		{
+			return Search(trans, preparedComparison, reader, SearchTarget.Any);
+		}
+
+		private Searcher Search(Transaction trans, IPreparedComparison preparedComparison
+			, ByteArrayBuffer reader, SearchTarget target)
+		{
+			Searcher s = new Searcher(target, _count);
+			if (CanWrite())
+			{
+				while (s.Incomplete())
+				{
+					s.ResultIs(CompareInWriteMode(preparedComparison, s.Cursor()));
+				}
+			}
+			else
+			{
+				while (s.Incomplete())
+				{
+					s.ResultIs(CompareInReadMode(trans, preparedComparison, reader, s.Cursor()));
+				}
+			}
+			return s;
+		}
+
+		private void SeekAfterKey(ByteArrayBuffer reader, int ix)
+		{
+			SeekKey(reader, ix);
+			reader._offset += KeyHandler().LinkLength();
+		}
+
+		private void SeekChild(ByteArrayBuffer reader, int ix)
+		{
+			SeekAfterKey(reader, ix);
+		}
+
+		private void SeekKey(ByteArrayBuffer reader, int ix)
+		{
+			reader._offset = SlotLeadingLength + (EntryLength() * ix);
+		}
+
+		private Db4objects.Db4o.Internal.Btree.BTreeNode Split(Transaction trans)
+		{
+			Db4objects.Db4o.Internal.Btree.BTreeNode res = new Db4objects.Db4o.Internal.Btree.BTreeNode
+				(_btree, _btree._halfNodeSize, _isLeaf, _parentID, GetID(), _nextID);
+			System.Array.Copy(_keys, _btree._halfNodeSize, res._keys, 0, _btree._halfNodeSize
+				);
+			for (int i = _btree._halfNodeSize; i < _keys.Length; i++)
+			{
+				_keys[i] = null;
+			}
+			if (_children != null)
+			{
+				res._children = new object[_btree.NodeSize()];
+				System.Array.Copy(_children, _btree._halfNodeSize, res._children, 0, _btree._halfNodeSize
+					);
+				for (int i = _btree._halfNodeSize; i < _children.Length; i++)
+				{
+					_children[i] = null;
+				}
+			}
+			_count = _btree._halfNodeSize;
+			res.Write(trans.SystemTransaction());
+			_btree.AddNode(res);
+			int splitID = res.GetID();
+			PointNextTo(trans, splitID);
+			SetNextID(trans, splitID);
+			if (_children != null)
+			{
+				for (int i = 0; i < _btree._halfNodeSize; i++)
+				{
+					if (res._children[i] == null)
+					{
+						break;
+					}
+					res.Child(i).SetParentID(trans, splitID);
+				}
+			}
+			_btree.NotifySplit(trans, this, res);
+			return res;
+		}
+
+		private void PointNextTo(Transaction trans, int id)
+		{
+			if (_nextID != 0)
+			{
+				NextNode().SetPreviousID(trans, id);
+			}
+		}
+
+		private void PointPreviousTo(Transaction trans, int id)
+		{
+			if (_previousID != 0)
+			{
+				PreviousNode().SetNextID(trans, id);
+			}
+		}
+
+		public Db4objects.Db4o.Internal.Btree.BTreeNode PreviousNode()
+		{
+			if (_previousID == 0)
+			{
+				return null;
+			}
+			return _btree.ProduceNode(_previousID);
+		}
+
+		public Db4objects.Db4o.Internal.Btree.BTreeNode NextNode()
+		{
+			if (_nextID == 0)
+			{
+				return null;
+			}
+			return _btree.ProduceNode(_nextID);
+		}
+
+		internal BTreePointer FirstPointer(Transaction trans)
+		{
+			ByteArrayBuffer reader = PrepareRead(trans);
+			if (_isLeaf)
+			{
+				return LeafFirstPointer(trans, reader);
+			}
+			return BranchFirstPointer(trans, reader);
+		}
+
+		private BTreePointer BranchFirstPointer(Transaction trans, ByteArrayBuffer reader
+			)
+		{
+			for (int i = 0; i < _count; i++)
+			{
+				BTreePointer childFirstPointer = Child(reader, i).FirstPointer(trans);
+				if (childFirstPointer != null)
+				{
+					return childFirstPointer;
+				}
+			}
+			return null;
+		}
+
+		private BTreePointer LeafFirstPointer(Transaction trans, ByteArrayBuffer reader)
+		{
+			int index = FirstKeyIndex(trans);
+			if (index == -1)
+			{
+				return null;
+			}
+			return new BTreePointer(trans, reader, this, index);
+		}
+
+		public BTreePointer LastPointer(Transaction trans)
+		{
+			ByteArrayBuffer reader = PrepareRead(trans);
+			if (_isLeaf)
+			{
+				return LeafLastPointer(trans, reader);
+			}
+			return BranchLastPointer(trans, reader);
+		}
+
+		private BTreePointer BranchLastPointer(Transaction trans, ByteArrayBuffer reader)
+		{
+			for (int i = _count - 1; i >= 0; i--)
+			{
+				BTreePointer childLastPointer = Child(reader, i).LastPointer(trans);
+				if (childLastPointer != null)
+				{
+					return childLastPointer;
+				}
+			}
+			return null;
+		}
+
+		private BTreePointer LeafLastPointer(Transaction trans, ByteArrayBuffer reader)
+		{
+			int index = LastKeyIndex(trans);
+			if (index == -1)
+			{
+				return null;
+			}
+			return new BTreePointer(trans, reader, this, index);
+		}
+
+		public void Purge()
+		{
+			if (_dead)
+			{
+				_keys = null;
+				_children = null;
+				return;
+			}
+			if (!IsPatched())
+			{
+				return;
+			}
+			HoldChildrenAsIDs();
+			_btree.AddNode(this);
+		}
+
+		private bool IsPatched()
+		{
+			if (_dead)
+			{
+				return false;
+			}
+			if (!CanWrite())
+			{
+				return false;
+			}
+			for (int i = 0; i < _count; i++)
+			{
+				if (_keys[i] is BTreePatch)
+				{
+					return true;
+				}
+			}
+			return false;
+		}
+
+		private void SetParentID(Transaction trans, int id)
+		{
+			PrepareWrite(trans);
+			SetStateDirty();
+			_parentID = id;
+		}
+
+		private void SetPreviousID(Transaction trans, int id)
+		{
+			PrepareWrite(trans);
+			SetStateDirty();
+			_previousID = id;
+		}
+
+		private void SetNextID(Transaction trans, int id)
+		{
+			PrepareWrite(trans);
+			SetStateDirty();
+			_nextID = id;
+		}
+
+		public void TraverseKeys(Transaction trans, IVisitor4 visitor)
+		{
+			ByteArrayBuffer reader = PrepareRead(trans);
+			if (_isLeaf)
+			{
+				for (int i = 0; i < _count; i++)
+				{
+					object obj = Key(trans, reader, i);
+					if (obj != No4.Instance)
+					{
+						visitor.Visit(obj);
+					}
+				}
+			}
+			else
+			{
+				for (int i = 0; i < _count; i++)
+				{
+					Child(reader, i).TraverseKeys(trans, visitor);
+				}
+			}
+		}
+
+		public override bool WriteObjectBegin()
+		{
+			if (_dead)
+			{
+				return false;
+			}
+			if (!CanWrite())
+			{
+				return false;
+			}
+			return base.WriteObjectBegin();
+		}
+
+		public override void WriteThis(Transaction trans, ByteArrayBuffer buffer)
+		{
+			int count = 0;
+			int startOffset = buffer._offset;
+			IContext context = trans.Context();
+			buffer.IncrementOffset(CountLeafAnd3LinkLength);
+			if (_isLeaf)
+			{
+				for (int i = 0; i < _count; i++)
+				{
+					object obj = InternalKey(trans, i);
+					if (obj != No4.Instance)
+					{
+						count++;
+						KeyHandler().WriteIndexEntry(context, buffer, obj);
+					}
+				}
+			}
+			else
+			{
+				for (int i = 0; i < _count; i++)
+				{
+					if (ChildCanSupplyFirstKey(i))
+					{
+						Db4objects.Db4o.Internal.Btree.BTreeNode child = (Db4objects.Db4o.Internal.Btree.BTreeNode
+							)_children[i];
+						object childKey = child.FirstKey(trans);
+						if (childKey != No4.Instance)
+						{
+							count++;
+							KeyHandler().WriteIndexEntry(context, buffer, childKey);
+							buffer.WriteIDOf(trans, child);
+						}
+					}
+					else
+					{
+						count++;
+						KeyHandler().WriteIndexEntry(context, buffer, Key(i));
+						buffer.WriteIDOf(trans, _children[i]);
+					}
+				}
+			}
+			int endOffset = buffer._offset;
+			buffer._offset = startOffset;
+			buffer.WriteInt(count);
+			buffer.WriteByte(_isLeaf ? (byte)1 : (byte)0);
+			buffer.WriteInt(_parentID);
+			buffer.WriteInt(_previousID);
+			buffer.WriteInt(_nextID);
+			buffer._offset = endOffset;
+		}
+
+		public override string ToString()
+		{
+			if (_count == 0)
+			{
+				return "Node " + GetID() + " not loaded";
+			}
+			string str = "\nBTreeNode";
+			str += "\nid: " + GetID();
+			str += "\nparent: " + _parentID;
+			str += "\nprevious: " + _previousID;
+			str += "\nnext: " + _nextID;
+			str += "\ncount:" + _count;
+			str += "\nleaf:" + _isLeaf + "\n";
+			if (CanWrite())
+			{
+				str += " { ";
+				bool first = true;
+				for (int i = 0; i < _count; i++)
+				{
+					if (_keys[i] != null)
+					{
+						if (!first)
+						{
+							str += ", ";
+						}
+						str += _keys[i].ToString();
+						first = false;
+					}
+				}
+				str += " }";
+			}
+			return str;
+		}
+
+		public void DebugLoadFully(Transaction trans)
+		{
+			PrepareWrite(trans);
+			if (_isLeaf)
+			{
+				return;
+			}
+			for (int i = 0; i < _count; ++i)
+			{
+				if (_children[i] is int)
+				{
+					_children[i] = Btree().ProduceNode(((int)_children[i]));
+				}
+				((Db4objects.Db4o.Internal.Btree.BTreeNode)_children[i]).DebugLoadFully(trans);
+			}
+		}
+
+		public static void DefragIndex(DefragmentContextImpl context, IIndexable4 keyHandler
+			)
+		{
+			// count
+			int count = context.ReadInt();
+			// leafByte
+			byte leafByte = context.ReadByte();
+			bool isLeaf = (leafByte == 1);
+			context.CopyID();
+			// parent ID
+			context.CopyID();
+			// previous ID
+			context.CopyID();
+			// next ID
+			for (int i = 0; i < count; i++)
+			{
+				keyHandler.DefragIndexEntry(context);
+				if (!isLeaf)
+				{
+					context.CopyID();
+				}
+			}
+		}
+
+		public bool IsLeaf()
+		{
+			return _isLeaf;
+		}
+
+		/// <summary>This traversal goes over all nodes, not just leafs</summary>
+		internal void TraverseAllNodes(Transaction trans, IVisitor4 command)
+		{
+			ByteArrayBuffer reader = PrepareRead(trans);
+			command.Visit(this);
+			if (_isLeaf)
+			{
+				return;
+			}
+			for (int childIdx = 0; childIdx < _count; childIdx++)
+			{
+				Child(reader, childIdx).TraverseAllNodes(trans, command);
+			}
+		}
+
+		public int Size(Transaction trans)
+		{
+			PrepareRead(trans);
+			if (!CanWrite())
+			{
+				return _count;
+			}
+			int size = 0;
+			for (int i = 0; i < _count; i++)
+			{
+				BTreePatch keyPatch = KeyPatch(i);
+				if (keyPatch != null)
+				{
+					size += keyPatch.SizeDiff(trans);
+				}
+				else
+				{
+					size++;
+				}
+			}
+			return size;
+		}
+
+		public override Db4objects.Db4o.Internal.Slots.SlotChangeFactory SlotChangeFactory
+			()
+		{
+			return _btree.SlotChangeFactory();
+		}
+
+		public override ITransactionalIdSystem IdSystem(Transaction trans)
+		{
+			return _btree.IdSystem(trans);
+		}
+
+		public void ToReadMode()
+		{
+			if (IsNew())
+			{
+				return;
+			}
+			if (!CanWrite())
+			{
+				return;
+			}
+			if (IsDirty())
+			{
+				return;
+			}
+			if (IsPatched())
+			{
+				return;
+			}
+			_keys = null;
+			_children = null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeNodeCacheEntry.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeNodeCacheEntry.cs
new file mode 100644
index 0000000..3b80338
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeNodeCacheEntry.cs
@@ -0,0 +1,30 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <exclude></exclude>
+	public class BTreeNodeCacheEntry
+	{
+		public readonly BTreeNode _node;
+
+		private ByteArrayBuffer _buffer;
+
+		public BTreeNodeCacheEntry(BTreeNode node)
+		{
+			_node = node;
+		}
+
+		public virtual ByteArrayBuffer Buffer()
+		{
+			return _buffer;
+		}
+
+		public virtual void Buffer(ByteArrayBuffer buffer)
+		{
+			_buffer = buffer;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeNodeSearchResult.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeNodeSearchResult.cs
new file mode 100644
index 0000000..8a3d55e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeNodeSearchResult.cs
@@ -0,0 +1,87 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <exclude></exclude>
+	public class BTreeNodeSearchResult
+	{
+		private readonly Transaction _transaction;
+
+		private readonly BTree _btree;
+
+		private readonly BTreePointer _pointer;
+
+		private readonly bool _foundMatch;
+
+		internal BTreeNodeSearchResult(Transaction transaction, BTree btree, BTreePointer
+			 pointer, bool foundMatch)
+		{
+			if (null == transaction || null == btree)
+			{
+				throw new ArgumentNullException();
+			}
+			_transaction = transaction;
+			_btree = btree;
+			_pointer = pointer;
+			_foundMatch = foundMatch;
+		}
+
+		internal BTreeNodeSearchResult(Transaction trans, ByteArrayBuffer nodeReader, BTree
+			 btree, BTreeNode node, int cursor, bool foundMatch) : this(trans, btree, PointerOrNull
+			(trans, nodeReader, node, cursor), foundMatch)
+		{
+		}
+
+		internal BTreeNodeSearchResult(Transaction trans, ByteArrayBuffer nodeReader, BTree
+			 btree, Searcher searcher, BTreeNode node) : this(trans, btree, NextPointerIf(PointerOrNull
+			(trans, nodeReader, node, searcher.Cursor()), searcher.IsGreater()), searcher.FoundMatch
+			())
+		{
+		}
+
+		private static BTreePointer NextPointerIf(BTreePointer pointer, bool condition)
+		{
+			if (null == pointer)
+			{
+				return null;
+			}
+			if (condition)
+			{
+				return pointer.Next();
+			}
+			return pointer;
+		}
+
+		private static BTreePointer PointerOrNull(Transaction trans, ByteArrayBuffer nodeReader
+			, BTreeNode node, int cursor)
+		{
+			return node == null ? null : new BTreePointer(trans, nodeReader, node, cursor);
+		}
+
+		public virtual IBTreeRange CreateIncludingRange(Db4objects.Db4o.Internal.Btree.BTreeNodeSearchResult
+			 end)
+		{
+			BTreePointer firstPointer = FirstValidPointer();
+			BTreePointer endPointer = end._foundMatch ? end._pointer.Next() : end.FirstValidPointer
+				();
+			return new BTreeRangeSingle(_transaction, _btree, firstPointer, endPointer);
+		}
+
+		public virtual BTreePointer FirstValidPointer()
+		{
+			if (null == _pointer)
+			{
+				return null;
+			}
+			if (_pointer.IsValid())
+			{
+				return _pointer;
+			}
+			return _pointer.Next();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreePatch.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreePatch.cs
new file mode 100644
index 0000000..8c94b55
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreePatch.cs
@@ -0,0 +1,60 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	public abstract class BTreePatch
+	{
+		protected readonly Transaction _transaction;
+
+		protected object _object;
+
+		public BTreePatch(Transaction transaction, object obj)
+		{
+			_transaction = transaction;
+			_object = obj;
+		}
+
+		public abstract object Commit(Transaction trans, BTree btree, BTreeNode node);
+
+		public abstract Db4objects.Db4o.Internal.Btree.BTreePatch ForTransaction(Transaction
+			 trans);
+
+		public virtual object GetObject()
+		{
+			return _object;
+		}
+
+		public virtual bool IsAdd()
+		{
+			return false;
+		}
+
+		public virtual bool IsCancelledRemoval()
+		{
+			return false;
+		}
+
+		public virtual bool IsRemove()
+		{
+			return false;
+		}
+
+		public abstract object Key(Transaction trans);
+
+		public abstract object Rollback(Transaction trans, BTree btree);
+
+		public override string ToString()
+		{
+			if (_object == null)
+			{
+				return "[NULL]";
+			}
+			return _object.ToString();
+		}
+
+		public abstract int SizeDiff(Transaction trans);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreePointer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreePointer.cs
new file mode 100644
index 0000000..567c025
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreePointer.cs
@@ -0,0 +1,212 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <exclude></exclude>
+	public sealed class BTreePointer
+	{
+		public static Db4objects.Db4o.Internal.Btree.BTreePointer Max(Db4objects.Db4o.Internal.Btree.BTreePointer
+			 x, Db4objects.Db4o.Internal.Btree.BTreePointer y)
+		{
+			if (x == null)
+			{
+				return x;
+			}
+			if (y == null)
+			{
+				return y;
+			}
+			if (x.CompareTo(y) > 0)
+			{
+				return x;
+			}
+			return y;
+		}
+
+		public static Db4objects.Db4o.Internal.Btree.BTreePointer Min(Db4objects.Db4o.Internal.Btree.BTreePointer
+			 x, Db4objects.Db4o.Internal.Btree.BTreePointer y)
+		{
+			if (x == null)
+			{
+				return y;
+			}
+			if (y == null)
+			{
+				return x;
+			}
+			if (x.CompareTo(y) < 0)
+			{
+				return x;
+			}
+			return y;
+		}
+
+		private readonly BTreeNode _node;
+
+		private readonly int _index;
+
+		private readonly Transaction _transaction;
+
+		private readonly ByteArrayBuffer _nodeReader;
+
+		public BTreePointer(Transaction transaction, ByteArrayBuffer nodeReader, BTreeNode
+			 node, int index)
+		{
+			if (transaction == null || node == null)
+			{
+				throw new ArgumentNullException();
+			}
+			_transaction = transaction;
+			_nodeReader = nodeReader;
+			_node = node;
+			_index = index;
+		}
+
+		public int Index()
+		{
+			return _index;
+		}
+
+		public BTreeNode Node()
+		{
+			return _node;
+		}
+
+		public object Key()
+		{
+			return _node.Key(_transaction, _nodeReader, _index);
+		}
+
+		public Db4objects.Db4o.Internal.Btree.BTreePointer Next()
+		{
+			int indexInMyNode = _index + 1;
+			while (indexInMyNode < _node.Count())
+			{
+				if (_node.IndexIsValid(_transaction, indexInMyNode))
+				{
+					return new Db4objects.Db4o.Internal.Btree.BTreePointer(_transaction, _nodeReader, 
+						_node, indexInMyNode);
+				}
+				indexInMyNode++;
+			}
+			int newIndex = -1;
+			BTreeNode nextNode = _node;
+			ByteArrayBuffer nextReader = null;
+			while (newIndex == -1)
+			{
+				nextNode = nextNode.NextNode();
+				if (nextNode == null)
+				{
+					return null;
+				}
+				nextReader = nextNode.PrepareRead(_transaction);
+				newIndex = nextNode.FirstKeyIndex(_transaction);
+			}
+			Btree().ConvertCacheEvictedNodesToReadMode();
+			return new Db4objects.Db4o.Internal.Btree.BTreePointer(_transaction, nextReader, 
+				nextNode, newIndex);
+		}
+
+		public Db4objects.Db4o.Internal.Btree.BTreePointer Previous()
+		{
+			int indexInMyNode = _index - 1;
+			while (indexInMyNode >= 0)
+			{
+				if (_node.IndexIsValid(_transaction, indexInMyNode))
+				{
+					return new Db4objects.Db4o.Internal.Btree.BTreePointer(_transaction, _nodeReader, 
+						_node, indexInMyNode);
+				}
+				indexInMyNode--;
+			}
+			int newIndex = -1;
+			BTreeNode previousNode = _node;
+			ByteArrayBuffer previousReader = null;
+			while (newIndex == -1)
+			{
+				previousNode = previousNode.PreviousNode();
+				if (previousNode == null)
+				{
+					return null;
+				}
+				previousReader = previousNode.PrepareRead(_transaction);
+				newIndex = previousNode.LastKeyIndex(_transaction);
+			}
+			return new Db4objects.Db4o.Internal.Btree.BTreePointer(_transaction, previousReader
+				, previousNode, newIndex);
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj)
+			{
+				return true;
+			}
+			if (!(obj is Db4objects.Db4o.Internal.Btree.BTreePointer))
+			{
+				return false;
+			}
+			Db4objects.Db4o.Internal.Btree.BTreePointer other = (Db4objects.Db4o.Internal.Btree.BTreePointer
+				)obj;
+			if (_index != other._index)
+			{
+				return false;
+			}
+			return _node.Equals(other._node);
+		}
+
+		public override int GetHashCode()
+		{
+			return _node.GetHashCode();
+		}
+
+		public override string ToString()
+		{
+			return "BTreePointer(index=" + _index + ", node=" + _node + ")";
+		}
+
+		public int CompareTo(Db4objects.Db4o.Internal.Btree.BTreePointer y)
+		{
+			if (null == y)
+			{
+				throw new ArgumentNullException();
+			}
+			if (Btree() != y.Btree())
+			{
+				throw new ArgumentException();
+			}
+			return Btree().CompareKeys(_transaction.Context(), Key(), y.Key());
+		}
+
+		private BTree Btree()
+		{
+			return _node.Btree();
+		}
+
+		public static bool LessThan(Db4objects.Db4o.Internal.Btree.BTreePointer x, Db4objects.Db4o.Internal.Btree.BTreePointer
+			 y)
+		{
+			return Db4objects.Db4o.Internal.Btree.BTreePointer.Min(x, y) == x && !Equals(x, y
+				);
+		}
+
+		public static bool Equals(Db4objects.Db4o.Internal.Btree.BTreePointer x, Db4objects.Db4o.Internal.Btree.BTreePointer
+			 y)
+		{
+			if (x == null)
+			{
+				return y == null;
+			}
+			return x.Equals(y);
+		}
+
+		public bool IsValid()
+		{
+			return _node.IndexIsValid(_transaction, _index);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeRangeKeyIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeRangeKeyIterator.cs
new file mode 100644
index 0000000..71ff380
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeRangeKeyIterator.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	internal class BTreeRangeKeyIterator : AbstractBTreeRangeIterator
+	{
+		public BTreeRangeKeyIterator(BTreeRangeSingle range) : base(range)
+		{
+		}
+
+		public override object Current
+		{
+			get
+			{
+				return CurrentPointer().Key();
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeRangePointerIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeRangePointerIterator.cs
new file mode 100644
index 0000000..91d19be
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeRangePointerIterator.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	public class BTreeRangePointerIterator : AbstractBTreeRangeIterator
+	{
+		public BTreeRangePointerIterator(BTreeRangeSingle range) : base(range)
+		{
+		}
+
+		public override object Current
+		{
+			get
+			{
+				return CurrentPointer();
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeRangeSingle.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeRangeSingle.cs
new file mode 100644
index 0000000..5b37aa7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeRangeSingle.cs
@@ -0,0 +1,239 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Btree.Algebra;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <exclude></exclude>
+	public class BTreeRangeSingle : IBTreeRange
+	{
+		private sealed class _IComparison4_14 : IComparison4
+		{
+			public _IComparison4_14()
+			{
+			}
+
+			public int Compare(object x, object y)
+			{
+				Db4objects.Db4o.Internal.Btree.BTreeRangeSingle xRange = (Db4objects.Db4o.Internal.Btree.BTreeRangeSingle
+					)x;
+				Db4objects.Db4o.Internal.Btree.BTreeRangeSingle yRange = (Db4objects.Db4o.Internal.Btree.BTreeRangeSingle
+					)y;
+				return xRange.First().CompareTo(yRange.First());
+			}
+		}
+
+		public static readonly IComparison4 Comparison = new _IComparison4_14();
+
+		private readonly Db4objects.Db4o.Internal.Transaction _transaction;
+
+		private readonly BTree _btree;
+
+		private readonly BTreePointer _first;
+
+		private readonly BTreePointer _end;
+
+		public BTreeRangeSingle(Db4objects.Db4o.Internal.Transaction transaction, BTree btree
+			, BTreePointer first, BTreePointer end)
+		{
+			if (transaction == null || btree == null)
+			{
+				throw new ArgumentNullException();
+			}
+			_transaction = transaction;
+			_btree = btree;
+			_first = first;
+			_end = end;
+		}
+
+		public virtual void Accept(IBTreeRangeVisitor visitor)
+		{
+			visitor.Visit(this);
+		}
+
+		public virtual bool IsEmpty()
+		{
+			return BTreePointer.Equals(_first, _end);
+		}
+
+		public virtual int Size()
+		{
+			if (IsEmpty())
+			{
+				return 0;
+			}
+			// TODO: This was an attempt to improve size calculation.
+			//       Since all nodes are read, there is no improvement.        
+			//        BTreeNode currentNode = _first.node();
+			//        int sizeOnFirst = currentNode.count() - _first.index();
+			//
+			//        BTreeNode endNode = _end == null ? null : _end.node();
+			//        int substractForEnd = 
+			//            (endNode == null) ? 0 : (endNode.count() -  _end.index());
+			//        
+			//        int size = sizeOnFirst - substractForEnd;
+			//        while(! currentNode.equals(endNode)){
+			//            currentNode = currentNode.nextNode();
+			//            if(currentNode == null){
+			//                break;
+			//            }
+			//            currentNode.prepareRead(transaction());
+			//            size += currentNode.count(); 
+			//        }
+			//        return size;
+			int size = 0;
+			IEnumerator i = Keys();
+			while (i.MoveNext())
+			{
+				++size;
+			}
+			return size;
+		}
+
+		public virtual IEnumerator Pointers()
+		{
+			return new BTreeRangePointerIterator(this);
+		}
+
+		public virtual IEnumerator Keys()
+		{
+			return new BTreeRangeKeyIterator(this);
+		}
+
+		public BTreePointer End()
+		{
+			return _end;
+		}
+
+		public virtual Db4objects.Db4o.Internal.Transaction Transaction()
+		{
+			return _transaction;
+		}
+
+		public virtual BTreePointer First()
+		{
+			return _first;
+		}
+
+		public virtual IBTreeRange Greater()
+		{
+			return NewBTreeRangeSingle(_end, null);
+		}
+
+		public virtual IBTreeRange Union(IBTreeRange other)
+		{
+			if (null == other)
+			{
+				throw new ArgumentNullException();
+			}
+			return new BTreeRangeSingleUnion(this).Dispatch(other);
+		}
+
+		public virtual bool Adjacent(Db4objects.Db4o.Internal.Btree.BTreeRangeSingle range
+			)
+		{
+			return BTreePointer.Equals(_end, range._first) || BTreePointer.Equals(range._end, 
+				_first);
+		}
+
+		public virtual bool Overlaps(Db4objects.Db4o.Internal.Btree.BTreeRangeSingle range
+			)
+		{
+			return FirstOverlaps(this, range) || FirstOverlaps(range, this);
+		}
+
+		private bool FirstOverlaps(Db4objects.Db4o.Internal.Btree.BTreeRangeSingle x, Db4objects.Db4o.Internal.Btree.BTreeRangeSingle
+			 y)
+		{
+			return BTreePointer.LessThan(y._first, x._end) && BTreePointer.LessThan(x._first, 
+				y._end);
+		}
+
+		public virtual IBTreeRange ExtendToFirst()
+		{
+			return NewBTreeRangeSingle(FirstBTreePointer(), _end);
+		}
+
+		public virtual IBTreeRange ExtendToLast()
+		{
+			return NewBTreeRangeSingle(_first, null);
+		}
+
+		public virtual IBTreeRange Smaller()
+		{
+			return NewBTreeRangeSingle(FirstBTreePointer(), _first);
+		}
+
+		public virtual Db4objects.Db4o.Internal.Btree.BTreeRangeSingle NewBTreeRangeSingle
+			(BTreePointer first, BTreePointer end)
+		{
+			return new Db4objects.Db4o.Internal.Btree.BTreeRangeSingle(Transaction(), _btree, 
+				first, end);
+		}
+
+		public virtual IBTreeRange NewEmptyRange()
+		{
+			return NewBTreeRangeSingle(null, null);
+		}
+
+		private BTreePointer FirstBTreePointer()
+		{
+			return Btree().FirstPointer(Transaction());
+		}
+
+		private BTree Btree()
+		{
+			return _btree;
+		}
+
+		public virtual IBTreeRange Intersect(IBTreeRange range)
+		{
+			if (null == range)
+			{
+				throw new ArgumentNullException();
+			}
+			return new BTreeRangeSingleIntersect(this).Dispatch(range);
+		}
+
+		public virtual IBTreeRange ExtendToLastOf(IBTreeRange range)
+		{
+			Db4objects.Db4o.Internal.Btree.BTreeRangeSingle rangeImpl = CheckRangeArgument(range
+				);
+			return NewBTreeRangeSingle(_first, rangeImpl._end);
+		}
+
+		public override string ToString()
+		{
+			return "BTreeRangeSingle(first=" + _first + ", end=" + _end + ")";
+		}
+
+		private Db4objects.Db4o.Internal.Btree.BTreeRangeSingle CheckRangeArgument(IBTreeRange
+			 range)
+		{
+			if (null == range)
+			{
+				throw new ArgumentNullException();
+			}
+			Db4objects.Db4o.Internal.Btree.BTreeRangeSingle rangeImpl = (Db4objects.Db4o.Internal.Btree.BTreeRangeSingle
+				)range;
+			if (Btree() != rangeImpl.Btree())
+			{
+				throw new ArgumentException();
+			}
+			return rangeImpl;
+		}
+
+		public virtual BTreePointer LastPointer()
+		{
+			if (_end == null)
+			{
+				return Btree().LastPointer(Transaction());
+			}
+			return _end.Previous();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeRangeUnion.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeRangeUnion.cs
new file mode 100644
index 0000000..7ba4d38
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeRangeUnion.cs
@@ -0,0 +1,167 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Btree.Algebra;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	public class BTreeRangeUnion : IBTreeRange
+	{
+		private readonly BTreeRangeSingle[] _ranges;
+
+		public BTreeRangeUnion(BTreeRangeSingle[] ranges) : this(ToSortedCollection(ranges
+			))
+		{
+		}
+
+		public BTreeRangeUnion(SortedCollection4 sorted)
+		{
+			if (null == sorted)
+			{
+				throw new ArgumentNullException();
+			}
+			_ranges = ToArray(sorted);
+		}
+
+		public virtual void Accept(IBTreeRangeVisitor visitor)
+		{
+			visitor.Visit(this);
+		}
+
+		public virtual bool IsEmpty()
+		{
+			for (int i = 0; i < _ranges.Length; i++)
+			{
+				if (!_ranges[i].IsEmpty())
+				{
+					return false;
+				}
+			}
+			return true;
+		}
+
+		private static SortedCollection4 ToSortedCollection(BTreeRangeSingle[] ranges)
+		{
+			if (null == ranges)
+			{
+				throw new ArgumentNullException();
+			}
+			SortedCollection4 collection = new SortedCollection4(BTreeRangeSingle.Comparison);
+			for (int i = 0; i < ranges.Length; i++)
+			{
+				BTreeRangeSingle range = ranges[i];
+				if (!range.IsEmpty())
+				{
+					collection.Add(range);
+				}
+			}
+			return collection;
+		}
+
+		private static BTreeRangeSingle[] ToArray(SortedCollection4 collection)
+		{
+			return (BTreeRangeSingle[])collection.ToArray(new BTreeRangeSingle[collection.Size
+				()]);
+		}
+
+		public virtual IBTreeRange ExtendToFirst()
+		{
+			throw new NotImplementedException();
+		}
+
+		public virtual IBTreeRange ExtendToLast()
+		{
+			throw new NotImplementedException();
+		}
+
+		public virtual IBTreeRange ExtendToLastOf(IBTreeRange upperRange)
+		{
+			throw new NotImplementedException();
+		}
+
+		public virtual IBTreeRange Greater()
+		{
+			throw new NotImplementedException();
+		}
+
+		public virtual IBTreeRange Intersect(IBTreeRange range)
+		{
+			if (null == range)
+			{
+				throw new ArgumentNullException();
+			}
+			return new BTreeRangeUnionIntersect(this).Dispatch(range);
+		}
+
+		public virtual IEnumerator Pointers()
+		{
+			return Iterators.Concat(Iterators.Map(_ranges, new _IFunction4_77()));
+		}
+
+		private sealed class _IFunction4_77 : IFunction4
+		{
+			public _IFunction4_77()
+			{
+			}
+
+			public object Apply(object range)
+			{
+				return ((IBTreeRange)range).Pointers();
+			}
+		}
+
+		public virtual IEnumerator Keys()
+		{
+			return Iterators.Concat(Iterators.Map(_ranges, new _IFunction4_85()));
+		}
+
+		private sealed class _IFunction4_85 : IFunction4
+		{
+			public _IFunction4_85()
+			{
+			}
+
+			public object Apply(object range)
+			{
+				return ((IBTreeRange)range).Keys();
+			}
+		}
+
+		public virtual int Size()
+		{
+			int size = 0;
+			for (int i = 0; i < _ranges.Length; i++)
+			{
+				size += _ranges[i].Size();
+			}
+			return size;
+		}
+
+		public virtual IBTreeRange Smaller()
+		{
+			throw new NotImplementedException();
+		}
+
+		public virtual IBTreeRange Union(IBTreeRange other)
+		{
+			if (null == other)
+			{
+				throw new ArgumentNullException();
+			}
+			return new BTreeRangeUnionUnion(this).Dispatch(other);
+		}
+
+		public virtual IEnumerator Ranges()
+		{
+			return new ArrayIterator4(_ranges);
+		}
+
+		public virtual BTreePointer LastPointer()
+		{
+			throw new NotImplementedException();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeRemove.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeRemove.cs
new file mode 100644
index 0000000..55b7289
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeRemove.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <exclude></exclude>
+	public class BTreeRemove : BTreeUpdate
+	{
+		public BTreeRemove(Transaction transaction, object obj) : base(transaction, obj)
+		{
+		}
+
+		protected override void Committed(BTree btree)
+		{
+			btree.NotifyRemoveListener(new TransactionContext(_transaction, GetObject()));
+		}
+
+		public override string ToString()
+		{
+			return "(-) " + base.ToString();
+		}
+
+		public override bool IsRemove()
+		{
+			return true;
+		}
+
+		protected override object GetCommittedObject()
+		{
+			return No4.Instance;
+		}
+
+		protected override void AdjustSizeOnRemovalByOtherTransaction(BTree btree, BTreeNode
+			 node)
+		{
+			// The size was reduced for this entry, let's change back.
+			btree.SizeChanged(_transaction, node, +1);
+		}
+
+		protected override int SizeDiff()
+		{
+			return 0;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeUpdate.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeUpdate.cs
new file mode 100644
index 0000000..98401f4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/BTreeUpdate.cs
@@ -0,0 +1,206 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	public abstract class BTreeUpdate : BTreePatch
+	{
+		protected Db4objects.Db4o.Internal.Btree.BTreeUpdate _next;
+
+		public BTreeUpdate(Transaction transaction, object obj) : base(transaction, obj)
+		{
+		}
+
+		protected virtual bool HasNext()
+		{
+			return _next != null;
+		}
+
+		public override BTreePatch ForTransaction(Transaction trans)
+		{
+			if (_transaction == trans)
+			{
+				return this;
+			}
+			if (_next == null)
+			{
+				return null;
+			}
+			return _next.ForTransaction(trans);
+		}
+
+		public virtual Db4objects.Db4o.Internal.Btree.BTreeUpdate RemoveFor(Transaction trans
+			)
+		{
+			if (_transaction == trans)
+			{
+				return _next;
+			}
+			if (_next == null)
+			{
+				return this;
+			}
+			return _next.RemoveFor(trans);
+		}
+
+		public virtual void Append(Db4objects.Db4o.Internal.Btree.BTreeUpdate patch)
+		{
+			if (_transaction == patch._transaction)
+			{
+				// don't allow two patches for the same transaction
+				throw new ArgumentException();
+			}
+			if (!HasNext())
+			{
+				_next = patch;
+			}
+			else
+			{
+				_next.Append(patch);
+			}
+		}
+
+		protected virtual void ApplyKeyChange(object obj)
+		{
+			_object = obj;
+			if (HasNext())
+			{
+				_next.ApplyKeyChange(obj);
+			}
+		}
+
+		protected abstract void Committed(BTree btree);
+
+		public override object Commit(Transaction trans, BTree btree, BTreeNode node)
+		{
+			Db4objects.Db4o.Internal.Btree.BTreeUpdate patch = (Db4objects.Db4o.Internal.Btree.BTreeUpdate
+				)ForTransaction(trans);
+			if (patch is BTreeCancelledRemoval)
+			{
+				object obj = patch.GetCommittedObject();
+				ApplyKeyChange(obj);
+			}
+			else
+			{
+				if (patch is BTreeRemove)
+				{
+					RemovedBy(trans, btree, node);
+					patch.Committed(btree);
+					return No4.Instance;
+				}
+			}
+			return InternalCommit(trans, btree);
+		}
+
+		protected object InternalCommit(Transaction trans, BTree btree)
+		{
+			if (_transaction == trans)
+			{
+				Committed(btree);
+				if (HasNext())
+				{
+					return _next;
+				}
+				return GetCommittedObject();
+			}
+			if (HasNext())
+			{
+				SetNextIfPatch(_next.InternalCommit(trans, btree));
+			}
+			return this;
+		}
+
+		private void SetNextIfPatch(object newNext)
+		{
+			if (newNext is Db4objects.Db4o.Internal.Btree.BTreeUpdate)
+			{
+				_next = (Db4objects.Db4o.Internal.Btree.BTreeUpdate)newNext;
+			}
+			else
+			{
+				_next = null;
+			}
+		}
+
+		protected abstract object GetCommittedObject();
+
+		public override object Rollback(Transaction trans, BTree btree)
+		{
+			if (_transaction == trans)
+			{
+				if (HasNext())
+				{
+					return _next;
+				}
+				return GetObject();
+			}
+			if (HasNext())
+			{
+				SetNextIfPatch(_next.Rollback(trans, btree));
+			}
+			return this;
+		}
+
+		public override object Key(Transaction trans)
+		{
+			BTreePatch patch = ForTransaction(trans);
+			if (patch == null)
+			{
+				return GetObject();
+			}
+			if (patch.IsRemove())
+			{
+				return No4.Instance;
+			}
+			return patch.GetObject();
+		}
+
+		public virtual Db4objects.Db4o.Internal.Btree.BTreeUpdate ReplacePatch(BTreePatch
+			 patch, Db4objects.Db4o.Internal.Btree.BTreeUpdate update)
+		{
+			if (patch == this)
+			{
+				update._next = _next;
+				return update;
+			}
+			if (_next == null)
+			{
+				throw new InvalidOperationException();
+			}
+			_next = _next.ReplacePatch(patch, update);
+			return this;
+		}
+
+		public virtual void RemovedBy(Transaction trans, BTree btree, BTreeNode node)
+		{
+			if (trans != _transaction)
+			{
+				AdjustSizeOnRemovalByOtherTransaction(btree, node);
+			}
+			if (HasNext())
+			{
+				_next.RemovedBy(trans, btree, node);
+			}
+		}
+
+		protected abstract void AdjustSizeOnRemovalByOtherTransaction(BTree btree, BTreeNode
+			 node);
+
+		public override int SizeDiff(Transaction trans)
+		{
+			Db4objects.Db4o.Internal.Btree.BTreeUpdate patchForTransaction = (Db4objects.Db4o.Internal.Btree.BTreeUpdate
+				)ForTransaction(trans);
+			if (patchForTransaction == null)
+			{
+				return 1;
+			}
+			return patchForTransaction.SizeDiff();
+		}
+
+		protected abstract int SizeDiff();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/FieldIndexKeyHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/FieldIndexKeyHandler.cs
new file mode 100644
index 0000000..b857f49
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/FieldIndexKeyHandler.cs
@@ -0,0 +1,115 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <exclude></exclude>
+	public class FieldIndexKeyHandler : IIndexable4
+	{
+		private readonly IIndexable4 _valueHandler;
+
+		private readonly IDHandler _parentIdHandler;
+
+		public FieldIndexKeyHandler(IIndexable4 delegate_)
+		{
+			_parentIdHandler = new IDHandler();
+			_valueHandler = delegate_;
+		}
+
+		public virtual int LinkLength()
+		{
+			return _valueHandler.LinkLength() + Const4.IntLength;
+		}
+
+		public virtual object ReadIndexEntry(IContext context, ByteArrayBuffer a_reader)
+		{
+			// TODO: could read int directly here with a_reader.readInt()
+			int parentID = ReadParentID(context, a_reader);
+			object objPart = _valueHandler.ReadIndexEntry(context, a_reader);
+			if (parentID < 0)
+			{
+				objPart = null;
+				parentID = -parentID;
+			}
+			return new FieldIndexKeyImpl(parentID, objPart);
+		}
+
+		private int ReadParentID(IContext context, ByteArrayBuffer a_reader)
+		{
+			return ((int)_parentIdHandler.ReadIndexEntry(context, a_reader));
+		}
+
+		public virtual void WriteIndexEntry(IContext context, ByteArrayBuffer writer, object
+			 obj)
+		{
+			IFieldIndexKey composite = (IFieldIndexKey)obj;
+			int parentID = composite.ParentID();
+			object value = composite.Value();
+			if (value == null)
+			{
+				parentID = -parentID;
+			}
+			_parentIdHandler.Write(parentID, writer);
+			_valueHandler.WriteIndexEntry(context, writer, composite.Value());
+		}
+
+		public virtual IIndexable4 ValueHandler()
+		{
+			return _valueHandler;
+		}
+
+		public virtual void DefragIndexEntry(DefragmentContextImpl context)
+		{
+			_parentIdHandler.DefragIndexEntry(context);
+			_valueHandler.DefragIndexEntry(context);
+		}
+
+		public virtual IPreparedComparison PrepareComparison(IContext context, object fieldIndexKey
+			)
+		{
+			IFieldIndexKey source = (IFieldIndexKey)fieldIndexKey;
+			IPreparedComparison preparedValueComparison = _valueHandler.PrepareComparison(context
+				, source.Value());
+			IPreparedComparison preparedParentIdComparison = _parentIdHandler.NewPrepareCompare
+				(source.ParentID());
+			return new _IPreparedComparison_67(preparedValueComparison, preparedParentIdComparison
+				);
+		}
+
+		private sealed class _IPreparedComparison_67 : IPreparedComparison
+		{
+			public _IPreparedComparison_67(IPreparedComparison preparedValueComparison, IPreparedComparison
+				 preparedParentIdComparison)
+			{
+				this.preparedValueComparison = preparedValueComparison;
+				this.preparedParentIdComparison = preparedParentIdComparison;
+			}
+
+			public int CompareTo(object obj)
+			{
+				IFieldIndexKey target = (IFieldIndexKey)obj;
+				try
+				{
+					int delegateResult = preparedValueComparison.CompareTo(target.Value());
+					if (delegateResult != 0)
+					{
+						return delegateResult;
+					}
+				}
+				catch (IllegalComparisonException)
+				{
+				}
+				// can happen, is expected
+				return preparedParentIdComparison.CompareTo(target.ParentID());
+			}
+
+			private readonly IPreparedComparison preparedValueComparison;
+
+			private readonly IPreparedComparison preparedParentIdComparison;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/FieldIndexKeyImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/FieldIndexKeyImpl.cs
new file mode 100644
index 0000000..fc1debc
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/FieldIndexKeyImpl.cs
@@ -0,0 +1,54 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <summary>
+	/// Composite key for field indexes, first compares on the actual
+	/// indexed field _value and then on the _parentID (which is a
+	/// reference to the containing object).
+	/// </summary>
+	/// <remarks>
+	/// Composite key for field indexes, first compares on the actual
+	/// indexed field _value and then on the _parentID (which is a
+	/// reference to the containing object).
+	/// </remarks>
+	/// <exclude></exclude>
+	public class FieldIndexKeyImpl : IFieldIndexKey
+	{
+		private readonly object _value;
+
+		private readonly int _parentID;
+
+		public FieldIndexKeyImpl(int parentID, object value)
+		{
+			_parentID = parentID;
+			_value = value;
+		}
+
+		public virtual int ParentID()
+		{
+			return _parentID;
+		}
+
+		public virtual object Value()
+		{
+			return _value;
+		}
+
+		public override string ToString()
+		{
+			return "FieldIndexKey(" + _parentID + ", " + SafeString(_value) + ")";
+		}
+
+		private string SafeString(object value)
+		{
+			if (null == value)
+			{
+				return "null";
+			}
+			return value.ToString();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/IBTreeRange.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/IBTreeRange.cs
new file mode 100644
index 0000000..1141d5c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/IBTreeRange.cs
@@ -0,0 +1,45 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	public interface IBTreeRange
+	{
+		/// <summary>
+		/// Iterates through all the valid pointers in
+		/// this range.
+		/// </summary>
+		/// <remarks>
+		/// Iterates through all the valid pointers in
+		/// this range.
+		/// </remarks>
+		/// <returns>an Iterator4 over BTreePointer value</returns>
+		IEnumerator Pointers();
+
+		IEnumerator Keys();
+
+		int Size();
+
+		IBTreeRange Greater();
+
+		IBTreeRange Union(IBTreeRange other);
+
+		IBTreeRange ExtendToLast();
+
+		IBTreeRange Smaller();
+
+		IBTreeRange ExtendToFirst();
+
+		IBTreeRange Intersect(IBTreeRange range);
+
+		IBTreeRange ExtendToLastOf(IBTreeRange upperRange);
+
+		bool IsEmpty();
+
+		void Accept(IBTreeRangeVisitor visitor);
+
+		BTreePointer LastPointer();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/IBTreeRangeVisitor.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/IBTreeRangeVisitor.cs
new file mode 100644
index 0000000..913abc3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/IBTreeRangeVisitor.cs
@@ -0,0 +1,14 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <exclude></exclude>
+	public interface IBTreeRangeVisitor
+	{
+		void Visit(BTreeRangeSingle range);
+
+		void Visit(BTreeRangeUnion union);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/IBTreeStructureListener.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/IBTreeStructureListener.cs
new file mode 100644
index 0000000..1ca060d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/IBTreeStructureListener.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <exclude></exclude>
+	public interface IBTreeStructureListener
+	{
+		void NotifySplit(Transaction trans, BTreeNode originalNode, BTreeNode newRightNode
+			);
+
+		void NotifyDeleted(Transaction trans, BTreeNode node);
+
+		void NotifyCountChanged(Transaction trans, BTreeNode node, int diff);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/IFieldIndexKey.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/IFieldIndexKey.cs
new file mode 100644
index 0000000..f2ca661
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/IFieldIndexKey.cs
@@ -0,0 +1,11 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	public interface IFieldIndexKey
+	{
+		int ParentID();
+
+		object Value();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/SearchTarget.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/SearchTarget.cs
new file mode 100644
index 0000000..523fce0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/SearchTarget.cs
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <exclude></exclude>
+	public sealed class SearchTarget
+	{
+		public static readonly Db4objects.Db4o.Internal.Btree.SearchTarget Lowest = new Db4objects.Db4o.Internal.Btree.SearchTarget
+			("Lowest");
+
+		public static readonly Db4objects.Db4o.Internal.Btree.SearchTarget Any = new Db4objects.Db4o.Internal.Btree.SearchTarget
+			("Any");
+
+		public static readonly Db4objects.Db4o.Internal.Btree.SearchTarget Highest = new 
+			Db4objects.Db4o.Internal.Btree.SearchTarget("Highest");
+
+		private readonly string _target;
+
+		public SearchTarget(string target)
+		{
+			_target = target;
+		}
+
+		public override string ToString()
+		{
+			return _target;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Searcher.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Searcher.cs
new file mode 100644
index 0000000..24ba504
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Btree/Searcher.cs
@@ -0,0 +1,171 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal.Btree;
+
+namespace Db4objects.Db4o.Internal.Btree
+{
+	/// <exclude></exclude>
+	public sealed class Searcher
+	{
+		private int _lower;
+
+		private int _upper;
+
+		private int _cursor;
+
+		private int _cmp;
+
+		private readonly SearchTarget _target;
+
+		private readonly int _count;
+
+		public Searcher(SearchTarget target, int count)
+		{
+			if (count < 0)
+			{
+				throw new ArgumentException();
+			}
+			_target = target;
+			_count = count;
+			_cmp = -1;
+			if (count == 0)
+			{
+				Complete();
+				return;
+			}
+			_cursor = -1;
+			_upper = count - 1;
+			AdjustCursor();
+		}
+
+		private void AdjustBounds()
+		{
+			if (_cmp > 0)
+			{
+				_upper = _cursor - 1;
+				if (_upper < _lower)
+				{
+					_upper = _lower;
+				}
+				return;
+			}
+			if (_cmp < 0)
+			{
+				if (_lower == _cursor && _lower < _upper)
+				{
+					_lower++;
+				}
+				else
+				{
+					_lower = _cursor;
+				}
+				return;
+			}
+			if (_target == SearchTarget.Any)
+			{
+				_lower = _cursor;
+				_upper = _cursor;
+			}
+			else
+			{
+				if (_target == SearchTarget.Highest)
+				{
+					_lower = _cursor;
+				}
+				else
+				{
+					if (_target == SearchTarget.Lowest)
+					{
+						_upper = _cursor;
+					}
+					else
+					{
+						throw new InvalidOperationException("Unknown target");
+					}
+				}
+			}
+		}
+
+		private void AdjustCursor()
+		{
+			int oldCursor = _cursor;
+			if (_upper - _lower <= 1)
+			{
+				if ((_target == SearchTarget.Lowest) && (_cmp == 0))
+				{
+					_cursor = _lower;
+				}
+				else
+				{
+					_cursor = _upper;
+				}
+			}
+			else
+			{
+				_cursor = _lower + ((_upper - _lower) / 2);
+			}
+			if (_cursor == oldCursor)
+			{
+				Complete();
+			}
+		}
+
+		public bool AfterLast()
+		{
+			if (_count == 0)
+			{
+				return false;
+			}
+			// _cursor is 0: not after last
+			return (_cursor == _count - 1) && _cmp < 0;
+		}
+
+		public bool BeforeFirst()
+		{
+			return (_cursor == 0) && (_cmp > 0);
+		}
+
+		private void Complete()
+		{
+			_upper = -2;
+		}
+
+		public int Count()
+		{
+			return _count;
+		}
+
+		public int Cursor()
+		{
+			return _cursor;
+		}
+
+		public bool FoundMatch()
+		{
+			return _cmp == 0;
+		}
+
+		public bool Incomplete()
+		{
+			return _upper >= _lower;
+		}
+
+		public void MoveForward()
+		{
+			_cursor++;
+		}
+
+		public void ResultIs(int cmp)
+		{
+			_cmp = cmp;
+			AdjustBounds();
+			AdjustCursor();
+		}
+
+		public bool IsGreater()
+		{
+			return _cmp < 0;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ByteArrayBuffer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ByteArrayBuffer.cs
new file mode 100644
index 0000000..20fbc2f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ByteArrayBuffer.cs
@@ -0,0 +1,305 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+using Sharpen;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class ByteArrayBuffer : IReadWriteBuffer
+	{
+		private static readonly ThreadLocal _checkXBytes = Debug4.xbytes ? new ThreadLocal
+			() : null;
+
+		public byte[] _buffer;
+
+		public int _offset;
+
+		internal ByteArrayBuffer()
+		{
+		}
+
+		public ByteArrayBuffer(int length) : this()
+		{
+			// for coding convenience, we allow objects to grab into the buffer
+			_buffer = new byte[length];
+		}
+
+		public ByteArrayBuffer(byte[] buffer) : this()
+		{
+			_buffer = buffer;
+		}
+
+		public virtual void Seek(int offset)
+		{
+			_offset = offset;
+		}
+
+		public virtual void WriteBytes(byte[] bytes)
+		{
+			System.Array.Copy(bytes, 0, _buffer, _offset, bytes.Length);
+			_offset += bytes.Length;
+		}
+
+		// TODO: Change all callers to call writeBytes directly.
+		public virtual void Append(byte[] bytes)
+		{
+			WriteBytes(bytes);
+		}
+
+		public bool ContainsTheSame(Db4objects.Db4o.Internal.ByteArrayBuffer other)
+		{
+			if (other != null)
+			{
+				return Arrays4.Equals(_buffer, other._buffer);
+			}
+			return false;
+		}
+
+		public virtual void CopyTo(Db4objects.Db4o.Internal.ByteArrayBuffer to, int fromOffset
+			, int toOffset, int length)
+		{
+			System.Array.Copy(_buffer, fromOffset, to._buffer, toOffset, length);
+		}
+
+		public virtual int Length()
+		{
+			return _buffer.Length;
+		}
+
+		public virtual void IncrementOffset(int a_by)
+		{
+			_offset += a_by;
+		}
+
+		/// <summary>non-encrypted read, used for indexes</summary>
+		public virtual void Read(ObjectContainerBase stream, int address, int addressOffset
+			)
+		{
+			stream.ReadBytes(_buffer, address, addressOffset, Length());
+		}
+
+		public void ReadBegin(byte identifier)
+		{
+		}
+
+		public virtual BitMap4 ReadBitMap(int bitCount)
+		{
+			BitMap4 map = new BitMap4(_buffer, _offset, bitCount);
+			_offset += map.MarshalledLength();
+			return map;
+		}
+
+		public virtual byte ReadByte()
+		{
+			return _buffer[_offset++];
+		}
+
+		public virtual byte[] ReadBytes(int a_length)
+		{
+			byte[] bytes = new byte[a_length];
+			ReadBytes(bytes);
+			return bytes;
+		}
+
+		public virtual void ReadBytes(byte[] bytes)
+		{
+			int length = bytes.Length;
+			System.Array.Copy(_buffer, _offset, bytes, 0, length);
+			_offset += length;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public Db4objects.Db4o.Internal.ByteArrayBuffer ReadEmbeddedObject(Transaction trans
+			)
+		{
+			int address = ReadInt();
+			int length = ReadInt();
+			if (address == 0)
+			{
+				return null;
+			}
+			return trans.Container().DecryptedBufferByAddress(address, length);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void ReadEncrypt(ObjectContainerBase stream, int address)
+		{
+			stream.ReadBytes(_buffer, address, Length());
+			stream._handlers.Decrypt(this);
+		}
+
+		public virtual void ReadEnd()
+		{
+		}
+
+		public int ReadInt()
+		{
+			int o = (_offset += 4) - 1;
+			return (_buffer[o] & 255) | (_buffer[--o] & 255) << 8 | (_buffer[--o] & 255) << 16
+				 | _buffer[--o] << 24;
+		}
+
+		public virtual long ReadLong()
+		{
+			return LongHandler.ReadLong(this);
+		}
+
+		public virtual Db4objects.Db4o.Internal.ByteArrayBuffer ReadPayloadReader(int offset
+			, int length)
+		{
+			Db4objects.Db4o.Internal.ByteArrayBuffer payLoad = new Db4objects.Db4o.Internal.ByteArrayBuffer
+				(length);
+			System.Array.Copy(_buffer, offset, payLoad._buffer, 0, length);
+			return payLoad;
+		}
+
+		internal virtual void ReplaceWith(byte[] a_bytes)
+		{
+			System.Array.Copy(a_bytes, 0, _buffer, 0, Length());
+		}
+
+		public override string ToString()
+		{
+			string str = string.Empty;
+			for (int i = 0; i < _buffer.Length; i++)
+			{
+				if (i > 0)
+				{
+					str += " , ";
+				}
+				str += _buffer[i];
+			}
+			return str;
+		}
+
+		public virtual void WriteBegin(byte a_identifier)
+		{
+		}
+
+		public void WriteBitMap(BitMap4 nullBitMap)
+		{
+			nullBitMap.WriteTo(_buffer, _offset);
+			_offset += nullBitMap.MarshalledLength();
+		}
+
+		public void WriteByte(byte a_byte)
+		{
+			_buffer[_offset++] = a_byte;
+		}
+
+		public virtual void WriteEnd()
+		{
+			if (Deploy.debug && Deploy.brackets)
+			{
+				WriteByte(Const4.Yapend);
+			}
+		}
+
+		public void WriteInt(int a_int)
+		{
+			int o = _offset + 4;
+			_offset = o;
+			byte[] b = _buffer;
+			b[--o] = (byte)a_int;
+			b[--o] = (byte)(a_int >>= 8);
+			b[--o] = (byte)(a_int >>= 8);
+			b[--o] = (byte)(a_int >> 8);
+		}
+
+		public virtual void WriteIDOf(Transaction trans, object obj)
+		{
+			if (obj == null)
+			{
+				WriteInt(0);
+				return;
+			}
+			if (obj is PersistentBase)
+			{
+				WriteIDOf(trans, (PersistentBase)obj);
+				return;
+			}
+			WriteInt(((int)obj));
+		}
+
+		public virtual void WriteIDOf(Transaction trans, PersistentBase persistent)
+		{
+			if (persistent == null)
+			{
+				WriteInt(0);
+				return;
+			}
+			if (CanWritePersistentBase())
+			{
+				persistent.WriteOwnID(trans, this);
+			}
+			else
+			{
+				WriteInt(persistent.GetID());
+			}
+		}
+
+		protected virtual bool CanWritePersistentBase()
+		{
+			return true;
+		}
+
+		public virtual void WriteShortString(Transaction trans, string a_string)
+		{
+			trans.Container()._handlers._stringHandler.WriteShort(trans, a_string, this);
+		}
+
+		public virtual void WriteLong(long l)
+		{
+			LongHandler.WriteLong(this, l);
+		}
+
+		public virtual void IncrementIntSize()
+		{
+			IncrementOffset(Const4.IntLength);
+		}
+
+		public virtual int Offset()
+		{
+			return _offset;
+		}
+
+		public virtual void EnsureSize(int size)
+		{
+			if (size == _buffer.Length)
+			{
+				return;
+			}
+			_buffer = new byte[size];
+		}
+
+		public virtual void Skip(int length)
+		{
+			Seek(_offset + length);
+		}
+
+		public virtual void CheckXBytes(bool flag)
+		{
+		}
+
+		public virtual bool CheckXBytes()
+		{
+			throw new InvalidOperationException();
+		}
+
+		public virtual bool Eof()
+		{
+			return _offset == _buffer.Length;
+		}
+
+		public virtual int RemainingByteCount()
+		{
+			return _buffer.Length - _offset;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/CacheFactory.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/CacheFactory.cs
new file mode 100644
index 0000000..7caa2d6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/CacheFactory.cs
@@ -0,0 +1,40 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Caching;
+
+namespace Db4objects.Db4o.Internal.Caching
+{
+	/// <exclude></exclude>
+	public class CacheFactory
+	{
+		public static ICache4 New2QCache(int size)
+		{
+			return new LRU2QCache(size);
+		}
+
+		public static ICache4 New2QLongCache(int size)
+		{
+			return new LRU2QLongCache(size);
+		}
+
+		public static ICache4 New2QXCache(int size)
+		{
+			return new LRU2QXCache(size);
+		}
+
+		public static IPurgeableCache4 NewLRUCache(int size)
+		{
+			return new LRUCache(size);
+		}
+
+		public static IPurgeableCache4 NewLRUIntCache(int size)
+		{
+			return new LRUIntCache(size);
+		}
+
+		public static IPurgeableCache4 NewLRULongCache(int size)
+		{
+			return new LRULongCache(size);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/CacheStatistics.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/CacheStatistics.cs
new file mode 100644
index 0000000..7d2ea49
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/CacheStatistics.cs
@@ -0,0 +1,70 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Caching;
+
+namespace Db4objects.Db4o.Internal.Caching
+{
+	/// <exclude></exclude>
+	public class CacheStatistics : ICache4
+	{
+		private readonly ICache4 _delegate;
+
+		private int _calls;
+
+		private int _misses;
+
+		public CacheStatistics(ICache4 delegate_)
+		{
+			_delegate = delegate_;
+		}
+
+		public virtual object Produce(object key, IFunction4 producer, IProcedure4 onDiscard
+			)
+		{
+			_calls++;
+			IFunction4 delegateProducer = new _IFunction4_26(this, producer);
+			return _delegate.Produce(key, delegateProducer, onDiscard);
+		}
+
+		private sealed class _IFunction4_26 : IFunction4
+		{
+			public _IFunction4_26(CacheStatistics _enclosing, IFunction4 producer)
+			{
+				this._enclosing = _enclosing;
+				this.producer = producer;
+			}
+
+			public object Apply(object arg)
+			{
+				this._enclosing._misses++;
+				return producer.Apply(arg);
+			}
+
+			private readonly CacheStatistics _enclosing;
+
+			private readonly IFunction4 producer;
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			return _delegate.GetEnumerator();
+		}
+
+		public virtual int Calls()
+		{
+			return _calls;
+		}
+
+		public virtual int Misses()
+		{
+			return _misses;
+		}
+
+		public override string ToString()
+		{
+			return "Cache statistics  Calls:" + _calls + " Misses:" + _misses;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/ICache4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/ICache4.cs
new file mode 100644
index 0000000..a70940a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/ICache4.cs
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Internal.Caching
+{
+	/// <exclude></exclude>
+	public interface ICache4 : IEnumerable
+	{
+		/// <summary>
+		/// Retrieves the value associated to the
+		/// <see cref="key">key</see>
+		/// from the cache. If the value is not yet
+		/// cached
+		/// <see cref="producer">producer</see>
+		/// will be called to produce it. If the cache needs to discard a value
+		/// <see cref="finalizer">finalizer</see>
+		/// will be given a chance to process it.
+		/// </summary>
+		/// <param name="key">the key for the value - must never change - cannot be null</param>
+		/// <param name="producer">will be called if value not yet in the cache - can only be null when the value is found in the cache
+		/// 	</param>
+		/// <param name="finalizer">will be called if a page needs to be discarded - can be null
+		/// 	</param>
+		/// <returns>the cached value</returns>
+		object Produce(object key, IFunction4 producer, IProcedure4 finalizer);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/IPurgeableCache4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/IPurgeableCache4.cs
new file mode 100644
index 0000000..4799e55
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/IPurgeableCache4.cs
@@ -0,0 +1,16 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Caching;
+
+namespace Db4objects.Db4o.Internal.Caching
+{
+	/// <exclude></exclude>
+	public interface IPurgeableCache4 : ICache4
+	{
+		/// <summary>Removes the cached value with the specified key from this cache.</summary>
+		/// <remarks>Removes the cached value with the specified key from this cache.</remarks>
+		/// <param name="key"></param>
+		/// <returns>the purged value or null</returns>
+		object Purge(object key);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRU2QCache.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRU2QCache.cs
new file mode 100644
index 0000000..76d29a8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRU2QCache.cs
@@ -0,0 +1,103 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Caching;
+
+namespace Db4objects.Db4o.Internal.Caching
+{
+	/// <exclude>
+	/// Simplified version of the algorithm taken from here:
+	/// http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.2641
+	/// </exclude>
+	internal class LRU2QCache : ICache4
+	{
+		private readonly CircularBuffer4 _am;
+
+		private readonly CircularBuffer4 _a1;
+
+		private readonly IDictionary _slots;
+
+		private readonly int _maxSize;
+
+		private readonly int _a1_threshold;
+
+		internal LRU2QCache(int maxSize)
+		{
+			_maxSize = maxSize;
+			_a1_threshold = _maxSize / 4;
+			_am = new CircularBuffer4(_maxSize);
+			_a1 = new CircularBuffer4(_maxSize);
+			_slots = new Hashtable(maxSize);
+		}
+
+		public virtual object Produce(object key, IFunction4 producer, IProcedure4 finalizer
+			)
+		{
+			if (key == null)
+			{
+				throw new ArgumentNullException();
+			}
+			if (_am.Remove(key))
+			{
+				_am.AddFirst(key);
+				return _slots[key];
+			}
+			if (_a1.Remove(key))
+			{
+				_am.AddFirst(key);
+				return _slots[key];
+			}
+			if (_slots.Count >= _maxSize)
+			{
+				DiscardPage(finalizer);
+			}
+			object value = producer.Apply(key);
+			_slots[key] = value;
+			_a1.AddFirst(key);
+			return value;
+		}
+
+		private void DiscardPage(IProcedure4 finalizer)
+		{
+			if (_a1.Size() >= _a1_threshold)
+			{
+				DiscardPageFrom(_a1, finalizer);
+			}
+			else
+			{
+				DiscardPageFrom(_am, finalizer);
+			}
+		}
+
+		private void DiscardPageFrom(CircularBuffer4 list, IProcedure4 finalizer)
+		{
+			Discard(list.RemoveLast(), finalizer);
+		}
+
+		private void Discard(object key, IProcedure4 finalizer)
+		{
+			if (null != finalizer)
+			{
+				finalizer.Apply(_slots[key]);
+			}
+			Sharpen.Collections.Remove(_slots, key);
+		}
+
+		public override string ToString()
+		{
+			return "LRU2QCache(am=" + ToString(_am) + ", a1=" + ToString(_a1) + ")";
+		}
+
+		private string ToString(IEnumerable buffer)
+		{
+			return Iterators.ToString(buffer);
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			return _slots.Values.GetEnumerator();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRU2QLongCache.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRU2QLongCache.cs
new file mode 100644
index 0000000..8e7a433
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRU2QLongCache.cs
@@ -0,0 +1,98 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Caching;
+
+namespace Db4objects.Db4o.Internal.Caching
+{
+	/// <exclude>
+	/// Simplified version of the algorithm taken from here:
+	/// http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.2641
+	/// </exclude>
+	internal class LRU2QLongCache : ICache4
+	{
+		private readonly CircularLongBuffer4 _am;
+
+		private readonly CircularLongBuffer4 _a1;
+
+		private readonly IDictionary _slots;
+
+		private readonly int _maxSize;
+
+		private readonly int _a1_threshold;
+
+		internal LRU2QLongCache(int maxSize)
+		{
+			_maxSize = maxSize;
+			_a1_threshold = _maxSize / 4;
+			_am = new CircularLongBuffer4(_maxSize);
+			_a1 = new CircularLongBuffer4(_maxSize);
+			_slots = new Hashtable(maxSize);
+		}
+
+		public virtual object Produce(object key, IFunction4 producer, IProcedure4 finalizer
+			)
+		{
+			if (_am.Remove((((long)key))))
+			{
+				_am.AddFirst((((long)key)));
+				return _slots[((long)key)];
+			}
+			if (_a1.Remove((((long)key))))
+			{
+				_am.AddFirst((((long)key)));
+				return _slots[((long)key)];
+			}
+			if (_slots.Count >= _maxSize)
+			{
+				DiscardPage(finalizer);
+			}
+			object value = producer.Apply(((long)key));
+			_slots[((long)key)] = value;
+			_a1.AddFirst((((long)key)));
+			return value;
+		}
+
+		private void DiscardPage(IProcedure4 finalizer)
+		{
+			if (_a1.Size() >= _a1_threshold)
+			{
+				DiscardPageFrom(_a1, finalizer);
+			}
+			else
+			{
+				DiscardPageFrom(_am, finalizer);
+			}
+		}
+
+		private void DiscardPageFrom(CircularLongBuffer4 list, IProcedure4 finalizer)
+		{
+			Discard(list.RemoveLast(), finalizer);
+		}
+
+		private void Discard(long key, IProcedure4 finalizer)
+		{
+			if (null != finalizer)
+			{
+				finalizer.Apply(_slots[key]);
+			}
+			Sharpen.Collections.Remove(_slots, key);
+		}
+
+		public override string ToString()
+		{
+			return "LRU2QCache(am=" + ToString(_am) + ", a1=" + ToString(_a1) + ")";
+		}
+
+		private string ToString(IEnumerable buffer)
+		{
+			return Iterators.ToString(buffer);
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			return _slots.Values.GetEnumerator();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRU2QXCache.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRU2QXCache.cs
new file mode 100644
index 0000000..a1b0894
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRU2QXCache.cs
@@ -0,0 +1,119 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Caching;
+
+namespace Db4objects.Db4o.Internal.Caching
+{
+	/// <exclude>
+	/// Full version of the algorithm taken from here:
+	/// http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.2641
+	/// </exclude>
+	internal class LRU2QXCache : ICache4
+	{
+		private readonly IDictionary _slots;
+
+		private readonly CircularBuffer4 _am;
+
+		private readonly CircularBuffer4 _a1in;
+
+		private readonly CircularBuffer4 _a1out;
+
+		private readonly int _maxSize;
+
+		private readonly int _inSize;
+
+		public LRU2QXCache(int maxSize)
+		{
+			// 'eden': long-term lru queue
+			// 'nursery': short-term fifo queue, entry point for all new items
+			// 'backlog': fifo queue, elements may not be backed in _slots or may overlap with _am
+			// invariant: |_slots| = |_am| + |_a1in| <= _maxSize
+			_maxSize = maxSize;
+			_inSize = _maxSize / 4;
+			_slots = new Hashtable(_maxSize);
+			_am = new CircularBuffer4(_maxSize);
+			_a1in = new CircularBuffer4(_maxSize);
+			_a1out = new CircularBuffer4(_maxSize / 2);
+		}
+
+		public virtual object Produce(object key, IFunction4 producer, IProcedure4 finalizer
+			)
+		{
+			if (key == null)
+			{
+				throw new ArgumentNullException();
+			}
+			if (_am.Remove(key))
+			{
+				_am.AddFirst(key);
+				return _slots[key];
+			}
+			if (_a1out.Contains(key))
+			{
+				ReclaimFor(key, producer, finalizer);
+				_am.AddFirst(key);
+				return _slots[key];
+			}
+			if (_a1in.Contains(key))
+			{
+				return _slots[key];
+			}
+			ReclaimFor(key, producer, finalizer);
+			_a1in.AddFirst(key);
+			return _slots[key];
+		}
+
+		private void ReclaimFor(object key, IFunction4 producer, IProcedure4 finalizer)
+		{
+			if (_slots.Count < _maxSize)
+			{
+				_slots[key] = producer.Apply(key);
+				return;
+			}
+			if (_a1in.Size() > _inSize)
+			{
+				object lastKey = _a1in.RemoveLast();
+				Discard(lastKey, finalizer);
+				if (_a1out.IsFull())
+				{
+					_a1out.RemoveLast();
+				}
+				_a1out.AddFirst(lastKey);
+			}
+			else
+			{
+				object lastKey = _am.RemoveLast();
+				Discard(lastKey, finalizer);
+			}
+			_slots[key] = producer.Apply(key);
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			return _slots.Values.GetEnumerator();
+		}
+
+		public override string ToString()
+		{
+			return "LRU2QXCache(am=" + ToString(_am) + ", a1in=" + ToString(_a1in) + ", a1out="
+				 + ToString(_a1out) + ")" + " - " + _slots.Count;
+		}
+
+		private void Discard(object key, IProcedure4 finalizer)
+		{
+			object removed = Sharpen.Collections.Remove(_slots, key);
+			if (finalizer != null)
+			{
+				finalizer.Apply(removed);
+			}
+		}
+
+		private string ToString(IEnumerable buffer)
+		{
+			return Iterators.ToString(buffer);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRUCache.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRUCache.cs
new file mode 100644
index 0000000..11a1e61
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRUCache.cs
@@ -0,0 +1,70 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Caching;
+
+namespace Db4objects.Db4o.Internal.Caching
+{
+	/// <exclude></exclude>
+	internal class LRUCache : IPurgeableCache4
+	{
+		private readonly IDictionary _slots;
+
+		private readonly CircularBuffer4 _lru;
+
+		private readonly int _maxSize;
+
+		internal LRUCache(int size)
+		{
+			_maxSize = size;
+			_slots = new Hashtable(size);
+			_lru = new CircularBuffer4(size);
+		}
+
+		public virtual object Produce(object key, IFunction4 producer, IProcedure4 finalizer
+			)
+		{
+			object value = _slots[key];
+			if (value == null)
+			{
+				object newValue = producer.Apply(key);
+				if (newValue == null)
+				{
+					return null;
+				}
+				if (_slots.Count >= _maxSize)
+				{
+					object discarded = Sharpen.Collections.Remove(_slots, _lru.RemoveLast());
+					if (null != finalizer)
+					{
+						finalizer.Apply(discarded);
+					}
+				}
+				_slots[key] = newValue;
+				_lru.AddFirst(key);
+				return newValue;
+			}
+			_lru.Remove(key);
+			// O(N) 
+			_lru.AddFirst(key);
+			return value;
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			return _slots.Values.GetEnumerator();
+		}
+
+		public virtual object Purge(object key)
+		{
+			object removed = Sharpen.Collections.Remove(_slots, key);
+			if (removed == null)
+			{
+				return null;
+			}
+			_lru.Remove(key);
+			return removed;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRUIntCache.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRUIntCache.cs
new file mode 100644
index 0000000..f503cee
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRUIntCache.cs
@@ -0,0 +1,191 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Caching;
+
+namespace Db4objects.Db4o.Internal.Caching
+{
+	/// <exclude></exclude>
+	internal class LRUIntCache : IPurgeableCache4
+	{
+		private class Entry
+		{
+			internal readonly int _key;
+
+			internal readonly object _value;
+
+			internal LRUIntCache.Entry _previous;
+
+			internal LRUIntCache.Entry _next;
+
+			public Entry(int key, object value)
+			{
+				_key = key;
+				_value = value;
+			}
+
+			public override string ToString()
+			{
+				return string.Empty + _key;
+			}
+		}
+
+		private readonly Hashtable4 _slots;
+
+		private readonly int _maxSize;
+
+		private int _size;
+
+		private LRUIntCache.Entry _first;
+
+		private LRUIntCache.Entry _last;
+
+		internal LRUIntCache(int size)
+		{
+			_maxSize = size;
+			_slots = new Hashtable4(size);
+		}
+
+		public virtual object Produce(object key, IFunction4 producer, IProcedure4 finalizer
+			)
+		{
+			int intKey = (((int)key));
+			if (_last == null)
+			{
+				object lastValue = producer.Apply(((int)key));
+				if (lastValue == null)
+				{
+					return null;
+				}
+				_size = 1;
+				LRUIntCache.Entry lastEntry = new LRUIntCache.Entry(intKey, lastValue);
+				_slots.Put(intKey, lastEntry);
+				_first = lastEntry;
+				_last = lastEntry;
+				return lastValue;
+			}
+			LRUIntCache.Entry entry = (LRUIntCache.Entry)_slots.Get(intKey);
+			if (entry == null)
+			{
+				if (_size >= _maxSize)
+				{
+					LRUIntCache.Entry oldEntry = (LRUIntCache.Entry)_slots.Remove(_last._key);
+					_last = oldEntry._previous;
+					_last._next = null;
+					if (null != finalizer)
+					{
+						finalizer.Apply((object)oldEntry._value);
+					}
+					_size--;
+				}
+				object newValue = producer.Apply(((int)key));
+				if (newValue == null)
+				{
+					return null;
+				}
+				_size++;
+				LRUIntCache.Entry newEntry = new LRUIntCache.Entry(intKey, newValue);
+				_slots.Put(intKey, newEntry);
+				_first._previous = newEntry;
+				newEntry._next = _first;
+				_first = newEntry;
+				return newValue;
+			}
+			if (_first == entry)
+			{
+				return ((object)entry._value);
+			}
+			LRUIntCache.Entry previous = entry._previous;
+			entry._previous = null;
+			if (_last == entry)
+			{
+				_last = previous;
+			}
+			previous._next = entry._next;
+			if (previous._next != null)
+			{
+				previous._next._previous = previous;
+			}
+			_first._previous = entry;
+			entry._next = _first;
+			_first = entry;
+			return ((object)entry._value);
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			IEnumerator i = new _IEnumerator_108(this);
+			return i;
+		}
+
+		private sealed class _IEnumerator_108 : IEnumerator
+		{
+			public _IEnumerator_108(LRUIntCache _enclosing)
+			{
+				this._enclosing = _enclosing;
+				this._cursor = this._enclosing._first;
+			}
+
+			private LRUIntCache.Entry _cursor;
+
+			private LRUIntCache.Entry _current;
+
+			public object Current
+			{
+				get
+				{
+					return this._current._value;
+				}
+			}
+
+			public bool MoveNext()
+			{
+				if (this._cursor == null)
+				{
+					this._current = null;
+					return false;
+				}
+				this._current = this._cursor;
+				this._cursor = this._cursor._next;
+				return true;
+			}
+
+			public void Reset()
+			{
+				this._cursor = this._enclosing._first;
+				this._current = null;
+			}
+
+			private readonly LRUIntCache _enclosing;
+		}
+
+		public virtual object Purge(object key)
+		{
+			int intKey = (((int)key));
+			LRUIntCache.Entry entry = (LRUIntCache.Entry)_slots.Remove(intKey);
+			if (entry == null)
+			{
+				return null;
+			}
+			_size--;
+			if (_first == entry)
+			{
+				_first = entry._next;
+			}
+			if (_last == entry)
+			{
+				_last = entry._previous;
+			}
+			if (entry._previous != null)
+			{
+				entry._previous._next = entry._next;
+			}
+			if (entry._next != null)
+			{
+				entry._next._previous = entry._previous;
+			}
+			return ((object)entry._value);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRULongCache.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRULongCache.cs
new file mode 100644
index 0000000..01c3363
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/LRULongCache.cs
@@ -0,0 +1,191 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Caching;
+
+namespace Db4objects.Db4o.Internal.Caching
+{
+	/// <exclude></exclude>
+	internal class LRULongCache : IPurgeableCache4
+	{
+		private class Entry
+		{
+			internal readonly long _key;
+
+			internal readonly object _value;
+
+			internal LRULongCache.Entry _previous;
+
+			internal LRULongCache.Entry _next;
+
+			public Entry(long key, object value)
+			{
+				_key = key;
+				_value = value;
+			}
+
+			public override string ToString()
+			{
+				return string.Empty + _key;
+			}
+		}
+
+		private readonly Hashtable4 _slots;
+
+		private readonly int _maxSize;
+
+		private int _size;
+
+		private LRULongCache.Entry _first;
+
+		private LRULongCache.Entry _last;
+
+		internal LRULongCache(int size)
+		{
+			_maxSize = size;
+			_slots = new Hashtable4(size);
+		}
+
+		public virtual object Produce(object key, IFunction4 producer, IProcedure4 finalizer
+			)
+		{
+			long longKey = (((long)key));
+			if (_last == null)
+			{
+				object lastValue = producer.Apply(((long)key));
+				if (lastValue == null)
+				{
+					return null;
+				}
+				_size = 1;
+				LRULongCache.Entry lastEntry = new LRULongCache.Entry(longKey, lastValue);
+				_slots.Put(longKey, lastEntry);
+				_first = lastEntry;
+				_last = lastEntry;
+				return lastValue;
+			}
+			LRULongCache.Entry entry = (LRULongCache.Entry)_slots.Get(longKey);
+			if (entry == null)
+			{
+				if (_size >= _maxSize)
+				{
+					LRULongCache.Entry oldEntry = (LRULongCache.Entry)_slots.Remove(_last._key);
+					_last = oldEntry._previous;
+					_last._next = null;
+					if (null != finalizer)
+					{
+						finalizer.Apply((object)oldEntry._value);
+					}
+					_size--;
+				}
+				object newValue = producer.Apply(((long)key));
+				if (newValue == null)
+				{
+					return null;
+				}
+				_size++;
+				LRULongCache.Entry newEntry = new LRULongCache.Entry(longKey, newValue);
+				_slots.Put(longKey, newEntry);
+				_first._previous = newEntry;
+				newEntry._next = _first;
+				_first = newEntry;
+				return newValue;
+			}
+			if (_first == entry)
+			{
+				return ((object)entry._value);
+			}
+			LRULongCache.Entry previous = entry._previous;
+			entry._previous = null;
+			if (_last == entry)
+			{
+				_last = previous;
+			}
+			previous._next = entry._next;
+			if (previous._next != null)
+			{
+				previous._next._previous = previous;
+			}
+			_first._previous = entry;
+			entry._next = _first;
+			_first = entry;
+			return ((object)entry._value);
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			IEnumerator i = new _IEnumerator_108(this);
+			return i;
+		}
+
+		private sealed class _IEnumerator_108 : IEnumerator
+		{
+			public _IEnumerator_108(LRULongCache _enclosing)
+			{
+				this._enclosing = _enclosing;
+				this._cursor = this._enclosing._first;
+			}
+
+			private LRULongCache.Entry _cursor;
+
+			private LRULongCache.Entry _current;
+
+			public object Current
+			{
+				get
+				{
+					return this._current._value;
+				}
+			}
+
+			public bool MoveNext()
+			{
+				if (this._cursor == null)
+				{
+					this._current = null;
+					return false;
+				}
+				this._current = this._cursor;
+				this._cursor = this._cursor._next;
+				return true;
+			}
+
+			public void Reset()
+			{
+				this._cursor = this._enclosing._first;
+				this._current = null;
+			}
+
+			private readonly LRULongCache _enclosing;
+		}
+
+		public virtual object Purge(object key)
+		{
+			long longKey = (((long)key));
+			LRULongCache.Entry entry = (LRULongCache.Entry)_slots.Remove(longKey);
+			if (entry == null)
+			{
+				return null;
+			}
+			_size--;
+			if (_first == entry)
+			{
+				_first = entry._next;
+			}
+			if (_last == entry)
+			{
+				_last = entry._previous;
+			}
+			if (entry._previous != null)
+			{
+				entry._previous._next = entry._next;
+			}
+			if (entry._next != null)
+			{
+				entry._next._previous = entry._previous;
+			}
+			return ((object)entry._value);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/NullCache4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/NullCache4.cs
new file mode 100644
index 0000000..363ca34
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Caching/NullCache4.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Caching;
+
+namespace Db4objects.Db4o.Internal.Caching
+{
+	/// <exclude></exclude>
+	public class NullCache4 : ICache4
+	{
+		public virtual object Produce(object key, IFunction4 producer, IProcedure4 onDiscard
+			)
+		{
+			return producer.Apply(key);
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			return Iterators.EmptyIterator;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/CallBackMode.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/CallBackMode.cs
new file mode 100644
index 0000000..d551d84
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/CallBackMode.cs
@@ -0,0 +1,28 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal
+{
+	public sealed class CallBackMode
+	{
+		public static readonly Db4objects.Db4o.Internal.CallBackMode All = new Db4objects.Db4o.Internal.CallBackMode
+			("ALL");
+
+		public static readonly Db4objects.Db4o.Internal.CallBackMode DeleteOnly = new Db4objects.Db4o.Internal.CallBackMode
+			("DELETE_ONLY");
+
+		public static readonly Db4objects.Db4o.Internal.CallBackMode None = new Db4objects.Db4o.Internal.CallBackMode
+			("NONE");
+
+		private string _desc;
+
+		private CallBackMode(string desc)
+		{
+			_desc = desc;
+		}
+
+		public override string ToString()
+		{
+			return _desc;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/CallbackObjectInfoCollections.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/CallbackObjectInfoCollections.cs
new file mode 100644
index 0000000..1163b99
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/CallbackObjectInfoCollections.cs
@@ -0,0 +1,34 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class CallbackObjectInfoCollections
+	{
+		public readonly IObjectInfoCollection added;
+
+		public readonly IObjectInfoCollection updated;
+
+		public readonly IObjectInfoCollection deleted;
+
+		public static readonly Db4objects.Db4o.Internal.CallbackObjectInfoCollections Emtpy
+			 = Empty();
+
+		public CallbackObjectInfoCollections(IObjectInfoCollection added_, IObjectInfoCollection
+			 updated_, IObjectInfoCollection deleted_)
+		{
+			added = added_;
+			updated = updated_;
+			deleted = deleted_;
+		}
+
+		private static Db4objects.Db4o.Internal.CallbackObjectInfoCollections Empty()
+		{
+			return new Db4objects.Db4o.Internal.CallbackObjectInfoCollections(ObjectInfoCollectionImpl
+				.Empty, ObjectInfoCollectionImpl.Empty, ObjectInfoCollectionImpl.Empty);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Callbacks/ICallbacks.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Callbacks/ICallbacks.cs
new file mode 100644
index 0000000..8f334ee
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Callbacks/ICallbacks.cs
@@ -0,0 +1,58 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Callbacks
+{
+	public interface ICallbacks
+	{
+		bool ObjectCanNew(Transaction transaction, object obj);
+
+		bool ObjectCanActivate(Transaction transaction, object obj);
+
+		bool ObjectCanUpdate(Transaction transaction, IObjectInfo objectInfo);
+
+		bool ObjectCanDelete(Transaction transaction, IObjectInfo objectInfo);
+
+		bool ObjectCanDeactivate(Transaction transaction, IObjectInfo objectInfo);
+
+		void ObjectOnActivate(Transaction transaction, IObjectInfo obj);
+
+		void ObjectOnNew(Transaction transaction, IObjectInfo obj);
+
+		void ObjectOnUpdate(Transaction transaction, IObjectInfo obj);
+
+		void ObjectOnDelete(Transaction transaction, IObjectInfo obj);
+
+		void ObjectOnDeactivate(Transaction transaction, IObjectInfo obj);
+
+		void ObjectOnInstantiate(Transaction transaction, IObjectInfo obj);
+
+		void QueryOnStarted(Transaction transaction, IQuery query);
+
+		void QueryOnFinished(Transaction transaction, IQuery query);
+
+		bool CaresAboutCommitting();
+
+		bool CaresAboutCommitted();
+
+		void ClassOnRegistered(ClassMetadata clazz);
+
+		void CommitOnStarted(Transaction transaction, CallbackObjectInfoCollections objectInfoCollections
+			);
+
+		void CommitOnCompleted(Transaction transaction, CallbackObjectInfoCollections objectInfoCollections
+			, bool isOwnCommit);
+
+		bool CaresAboutDeleting();
+
+		bool CaresAboutDeleted();
+
+		void OpenOnFinished(IObjectContainer container);
+
+		void CloseOnStarted(IObjectContainer container);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Callbacks/NullCallbacks.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Callbacks/NullCallbacks.cs
new file mode 100644
index 0000000..122ab29
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Callbacks/NullCallbacks.cs
@@ -0,0 +1,115 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Callbacks;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Callbacks
+{
+	public class NullCallbacks : ICallbacks
+	{
+		public virtual void QueryOnFinished(Transaction transaction, IQuery query)
+		{
+		}
+
+		public virtual void QueryOnStarted(Transaction transaction, IQuery query)
+		{
+		}
+
+		public virtual bool ObjectCanNew(Transaction transaction, object obj)
+		{
+			return true;
+		}
+
+		public virtual bool ObjectCanActivate(Transaction transaction, object obj)
+		{
+			return true;
+		}
+
+		public virtual bool ObjectCanUpdate(Transaction transaction, IObjectInfo objectInfo
+			)
+		{
+			return true;
+		}
+
+		public virtual bool ObjectCanDelete(Transaction transaction, IObjectInfo objectInfo
+			)
+		{
+			return true;
+		}
+
+		public virtual bool ObjectCanDeactivate(Transaction transaction, IObjectInfo objectInfo
+			)
+		{
+			return true;
+		}
+
+		public virtual void ObjectOnNew(Transaction transaction, IObjectInfo obj)
+		{
+		}
+
+		public virtual void ObjectOnActivate(Transaction transaction, IObjectInfo obj)
+		{
+		}
+
+		public virtual void ObjectOnUpdate(Transaction transaction, IObjectInfo obj)
+		{
+		}
+
+		public virtual void ObjectOnDelete(Transaction transaction, IObjectInfo obj)
+		{
+		}
+
+		public virtual void ObjectOnDeactivate(Transaction transaction, IObjectInfo obj)
+		{
+		}
+
+		public virtual void ObjectOnInstantiate(Transaction transaction, IObjectInfo obj)
+		{
+		}
+
+		public virtual void CommitOnStarted(Transaction transaction, CallbackObjectInfoCollections
+			 objectInfoCollections)
+		{
+		}
+
+		public virtual void CommitOnCompleted(Transaction transaction, CallbackObjectInfoCollections
+			 objectInfoCollections, bool isOwnCommit)
+		{
+		}
+
+		public virtual bool CaresAboutCommitting()
+		{
+			return false;
+		}
+
+		public virtual bool CaresAboutCommitted()
+		{
+			return false;
+		}
+
+		public virtual void ClassOnRegistered(ClassMetadata clazz)
+		{
+		}
+
+		public virtual bool CaresAboutDeleting()
+		{
+			return false;
+		}
+
+		public virtual bool CaresAboutDeleted()
+		{
+			return false;
+		}
+
+		public virtual void CloseOnStarted(IObjectContainer container)
+		{
+		}
+
+		public virtual void OpenOnFinished(IObjectContainer container)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ClassAspect.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ClassAspect.cs
new file mode 100644
index 0000000..143778a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ClassAspect.cs
@@ -0,0 +1,79 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public abstract class ClassAspect
+	{
+		protected int _handle;
+
+		private int _disabledFromAspectCountVersion = AspectVersionContextImpl.AlwaysEnabled
+			.DeclaredAspectCount();
+
+		// used for identification when sending in C/S mode 
+		public abstract Db4objects.Db4o.Internal.Marshall.AspectType AspectType();
+
+		public abstract string GetName();
+
+		public abstract void CascadeActivation(IActivationContext context);
+
+		public abstract int LinkLength();
+
+		public void IncrementOffset(IReadBuffer buffer)
+		{
+			buffer.Seek(buffer.Offset() + LinkLength());
+		}
+
+		public abstract void DefragAspect(IDefragmentContext context);
+
+		public abstract void Marshall(MarshallingContext context, object child);
+
+		public abstract void CollectIDs(CollectIdContext context);
+
+		public virtual void SetHandle(int handle)
+		{
+			_handle = handle;
+		}
+
+		public abstract void Activate(UnmarshallingContext context);
+
+		public abstract void Delete(DeleteContextImpl context, bool isUpdate);
+
+		public abstract bool CanBeDisabled();
+
+		protected virtual bool CheckEnabled(IAspectVersionContext context)
+		{
+			if (!IsEnabledOn(context))
+			{
+				IncrementOffset((IReadBuffer)context);
+				return false;
+			}
+			return true;
+		}
+
+		public virtual void DisableFromAspectCountVersion(int aspectCount)
+		{
+			if (!CanBeDisabled())
+			{
+				return;
+			}
+			if (aspectCount < _disabledFromAspectCountVersion)
+			{
+				_disabledFromAspectCountVersion = aspectCount;
+			}
+		}
+
+		public bool IsEnabledOn(IAspectVersionContext context)
+		{
+			return _disabledFromAspectCountVersion > context.DeclaredAspectCount();
+		}
+
+		public abstract void Deactivate(IActivationContext context);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ClassMetadata.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ClassMetadata.cs
new file mode 100644
index 0000000..c3c69cd
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ClassMetadata.cs
@@ -0,0 +1,2735 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Classindex;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Diagnostic;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Handlers.Array;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Metadata;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Internal.Reflect;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Query;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Core;
+using Db4objects.Db4o.Reflect.Generic;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class ClassMetadata : PersistentBase, IStoredClass
+	{
+		/// <summary>
+		/// For reference types, _typeHandler always holds a StandardReferenceTypeHandler
+		/// that will use the _aspects of this class to take care of its business.
+		/// </summary>
+		/// <remarks>
+		/// For reference types, _typeHandler always holds a StandardReferenceTypeHandler
+		/// that will use the _aspects of this class to take care of its business. A custom
+		/// type handler would appear as a TypeHandlerAspect in that case.
+		/// For value types, _typeHandler always holds the actual value type handler be it
+		/// a custom type handler or a builtin one.
+		/// </remarks>
+		protected ITypeHandler4 _typeHandler;
+
+		public Db4objects.Db4o.Internal.ClassMetadata _ancestor;
+
+		private Config4Class _config;
+
+		public ClassAspect[] _aspects;
+
+		private IClassIndexStrategy _index;
+
+		private string i_name;
+
+		private readonly ObjectContainerBase _container;
+
+		internal byte[] i_nameBytes;
+
+		private ByteArrayBuffer i_reader;
+
+		private bool _classIndexed;
+
+		private IReflectClass _classReflector;
+
+		private IEventDispatcher _eventDispatcher;
+
+		private bool _internal;
+
+		private bool _unversioned;
+
+		private TernaryBool _canUpdateFast = TernaryBool.Unspecified;
+
+		private TranslatedAspect _translator;
+
+		private IModificationAware _modificationChecker = ClassMetadata.AlwaysModified.Instance;
+
+		private IFieldAccessor _fieldAccessor;
+
+		private IFunction4 _constructor;
+
+		private TypeHandlerAspect _customTypeHandlerAspect;
+
+		private IAspectTraversalStrategy _aspectTraversalStrategy;
+
+		internal bool CanUpdateFast()
+		{
+			if (_canUpdateFast == TernaryBool.Unspecified)
+			{
+				_canUpdateFast = TernaryBool.ForBoolean(CheckCanUpdateFast());
+			}
+			return _canUpdateFast.BooleanValue(false);
+		}
+
+		private bool CheckCanUpdateFast()
+		{
+			if (_ancestor != null && !_ancestor.CanUpdateFast())
+			{
+				return false;
+			}
+			if (_config != null && _config.CascadeOnDelete() == TernaryBool.Yes)
+			{
+				return false;
+			}
+			BooleanByRef hasIndex = new BooleanByRef(false);
+			TraverseDeclaredFields(new _IProcedure4_101(hasIndex));
+			return !hasIndex.value;
+		}
+
+		private sealed class _IProcedure4_101 : IProcedure4
+		{
+			public _IProcedure4_101(BooleanByRef hasIndex)
+			{
+				this.hasIndex = hasIndex;
+			}
+
+			public void Apply(object arg)
+			{
+				if (((FieldMetadata)arg).HasIndex())
+				{
+					hasIndex.value = true;
+				}
+			}
+
+			private readonly BooleanByRef hasIndex;
+		}
+
+		public virtual bool IsInternal()
+		{
+			return _internal;
+		}
+
+		private IClassIndexStrategy CreateIndexStrategy()
+		{
+			return new BTreeClassIndexStrategy(this);
+		}
+
+		protected ClassMetadata(ObjectContainerBase container)
+		{
+			if (null == container)
+			{
+				throw new ArgumentNullException();
+			}
+			_container = container;
+			_index = CreateIndexStrategy();
+			_classIndexed = true;
+			_fieldAccessor = new StrictFieldAccessor();
+		}
+
+		public ClassMetadata(ObjectContainerBase container, IReflectClass classReflector)
+		{
+			if (null == container)
+			{
+				throw new ArgumentNullException();
+			}
+			_container = container;
+			ClassReflector(classReflector);
+			_index = CreateIndexStrategy();
+			_classIndexed = true;
+			if (_container.Config().ExceptionsOnNotStorable())
+			{
+				_fieldAccessor = new StrictFieldAccessor();
+			}
+			else
+			{
+				_fieldAccessor = new LenientFieldAccessor();
+			}
+		}
+
+		internal virtual IFieldAccessor FieldAccessor()
+		{
+			return _fieldAccessor;
+		}
+
+		private ITypeHandler4 CreateDefaultTypeHandler()
+		{
+			// TODO: make sure initializeAspects has been executed
+			// before the actual type handler is required
+			// and remove this method
+			return new StandardReferenceTypeHandler(this);
+		}
+
+		public virtual void CascadeActivation(IActivationContext context)
+		{
+			if (!ObjectCanActivate(context.Transaction(), context.TargetObject()))
+			{
+				return;
+			}
+			TraverseAllAspects(new _ITraverseAspectCommand_160(context));
+		}
+
+		private sealed class _ITraverseAspectCommand_160 : ITraverseAspectCommand
+		{
+			public _ITraverseAspectCommand_160(IActivationContext context)
+			{
+				this.context = context;
+			}
+
+			public void ProcessAspectOnMissingClass(ClassAspect aspect, int currentSlot)
+			{
+			}
+
+			// do nothing
+			public void ProcessAspect(ClassAspect aspect, int currentSlot)
+			{
+				aspect.CascadeActivation(context);
+			}
+
+			public int DeclaredAspectCount(Db4objects.Db4o.Internal.ClassMetadata classMetadata
+				)
+			{
+				return classMetadata.DeclaredAspectCount();
+			}
+
+			public bool Cancelled()
+			{
+				return false;
+			}
+
+			private readonly IActivationContext context;
+		}
+
+		public void AddFieldIndices(StatefulBuffer buffer)
+		{
+			if (!StandardReferenceTypeHandlerIsUsed())
+			{
+				return;
+			}
+			if (HasClassIndex() || HasVirtualAttributes())
+			{
+				ObjectHeader oh = new ObjectHeader(this, buffer);
+				ObjectIdContextImpl context = new ObjectIdContextImpl(buffer.Transaction(), buffer
+					, oh, buffer.GetID());
+				Handlers4.FieldAwareTypeHandler(CorrectHandlerVersion(context)).AddFieldIndices(context
+					);
+			}
+		}
+
+		// FIXME: This method wants to be removed.
+		private bool StandardReferenceTypeHandlerIsUsed()
+		{
+			return _typeHandler is StandardReferenceTypeHandler;
+		}
+
+		internal virtual void InitializeAspects()
+		{
+			BitTrue(Const4.CheckedChanges);
+			Collection4 aspects = new Collection4();
+			if (null != _aspects)
+			{
+				aspects.AddAll(_aspects);
+			}
+			ITypeHandler4 customTypeHandler = Container().Handlers.ConfiguredTypeHandler(ClassReflector
+				());
+			bool dirty = IsDirty();
+			if (InstallTranslator(aspects, customTypeHandler))
+			{
+				dirty = true;
+			}
+			if (Container().DetectSchemaChanges())
+			{
+				if (GenerateCommitTimestamps())
+				{
+					if (!HasCommitTimestampField())
+					{
+						aspects.Add(Container().CommitTimestampIndex());
+						dirty = true;
+					}
+				}
+				if (GenerateUUIDs())
+				{
+					if (!HasUUIDField())
+					{
+						aspects.Add(Container().UUIDIndex());
+						dirty = true;
+					}
+				}
+			}
+			if (InstallCustomTypehandler(aspects, customTypeHandler))
+			{
+				dirty = true;
+			}
+			bool defaultFieldBehaviour = _translator == null && customTypeHandler == null;
+			if (Container().DetectSchemaChanges())
+			{
+				if (defaultFieldBehaviour)
+				{
+					if (CollectReflectFields(aspects))
+					{
+						dirty = true;
+					}
+				}
+				if (dirty)
+				{
+					_container.SetDirtyInSystemTransaction(this);
+				}
+			}
+			if (dirty || !defaultFieldBehaviour)
+			{
+				_aspects = ToClassAspectArray(aspects);
+			}
+			DiagnosticProcessor dp = _container._handlers.DiagnosticProcessor();
+			if (dp.Enabled())
+			{
+				dp.CheckClassHasFields(this);
+			}
+			if (_aspects == null)
+			{
+				_aspects = new FieldMetadata[0];
+			}
+			InitializeConstructor(customTypeHandler);
+			if (StateDead())
+			{
+				return;
+			}
+			_container.Callbacks().ClassOnRegistered(this);
+			SetStateOK();
+		}
+
+		private ClassAspect[] ToClassAspectArray(Collection4 aspects)
+		{
+			ClassAspect[] array = new ClassAspect[aspects.Size()];
+			aspects.ToArray(array);
+			for (int i = 0; i < array.Length; i++)
+			{
+				array[i].SetHandle(i);
+			}
+			return array;
+		}
+
+		private bool InstallCustomTypehandler(Collection4 aspects, ITypeHandler4 customTypeHandler
+			)
+		{
+			if (customTypeHandler == null)
+			{
+				return false;
+			}
+			if (customTypeHandler is IModificationAware)
+			{
+				_modificationChecker = (IModificationAware)customTypeHandler;
+			}
+			if (Handlers4.IsStandaloneTypeHandler(customTypeHandler))
+			{
+				_typeHandler = customTypeHandler;
+				return false;
+			}
+			bool dirty = false;
+			TypeHandlerAspect typeHandlerAspect = new TypeHandlerAspect(this, customTypeHandler
+				);
+			if (!ReplaceAspectByName(aspects, typeHandlerAspect))
+			{
+				aspects.Add(typeHandlerAspect);
+				dirty = true;
+			}
+			DisableAspectsBefore(aspects, typeHandlerAspect);
+			_customTypeHandlerAspect = typeHandlerAspect;
+			return dirty;
+		}
+
+		private void DisableAspectsBefore(Collection4 aspects, TypeHandlerAspect typeHandlerAspect
+			)
+		{
+			int disableFromVersion = aspects.IndexOf(typeHandlerAspect) + 1;
+			IEnumerator i = aspects.GetEnumerator();
+			while (i.MoveNext())
+			{
+				ClassAspect aspect = (ClassAspect)i.Current;
+				if (aspect == typeHandlerAspect)
+				{
+					break;
+				}
+				aspect.DisableFromAspectCountVersion(disableFromVersion);
+			}
+		}
+
+		private bool InstallTranslator(Collection4 aspects, ITypeHandler4 customTypeHandler
+			)
+		{
+			if (_config == null)
+			{
+				return false;
+			}
+			IObjectTranslator translator = _config.GetTranslator();
+			if (translator == null)
+			{
+				return false;
+			}
+			ClassAspect existingAspect = AspectByName(aspects, TranslatedAspect.FieldNameFor(
+				translator));
+			if (null != existingAspect)
+			{
+				return InstallTranslatorOnExistingAspect(translator, existingAspect, aspects);
+			}
+			if (customTypeHandler == null)
+			{
+				return InstallTranslatorOnNewAspect(translator, aspects);
+			}
+			return false;
+		}
+
+		private bool InstallTranslatorOnNewAspect(IObjectTranslator translator, Collection4
+			 aspects)
+		{
+			TranslatedAspect translatedAspect = new TranslatedAspect(this, translator);
+			aspects.Add(translatedAspect);
+			_translator = translatedAspect;
+			return true;
+		}
+
+		private bool InstallTranslatorOnExistingAspect(IObjectTranslator translator, ClassAspect
+			 existingAspect, Collection4 aspects)
+		{
+			if (existingAspect is TranslatedAspect)
+			{
+				TranslatedAspect translatedAspect = (TranslatedAspect)existingAspect;
+				translatedAspect.InitializeTranslator(translator);
+				_translator = translatedAspect;
+				return false;
+			}
+			// older versions didn't store the aspect type properly
+			_translator = new TranslatedAspect(this, translator);
+			aspects.ReplaceByIdentity(existingAspect, _translator);
+			return true;
+		}
+
+		private bool ReplaceAspectByName(Collection4 aspects, ClassAspect aspect)
+		{
+			ClassAspect existing = AspectByName(aspects, aspect.GetName());
+			if (existing == null)
+			{
+				return false;
+			}
+			aspects.ReplaceByIdentity(existing, aspect);
+			return true;
+		}
+
+		private ClassAspect AspectByName(Collection4 aspects, string aspectName)
+		{
+			IEnumerator i = aspects.GetEnumerator();
+			while (i.MoveNext())
+			{
+				ClassAspect current = (ClassAspect)i.Current;
+				if (current.GetName().Equals(aspectName))
+				{
+					return current;
+				}
+			}
+			return null;
+		}
+
+		public virtual bool AspectsAreInitialized()
+		{
+			if (_aspects == null)
+			{
+				return false;
+			}
+			if (_ancestor != null)
+			{
+				return _ancestor.AspectsAreInitialized();
+			}
+			return true;
+		}
+
+		private bool CollectReflectFields(Collection4 collectedAspects)
+		{
+			bool dirty = false;
+			IReflectField[] reflectFieldArray = ReflectFields();
+			for (int reflectFieldIndex = 0; reflectFieldIndex < reflectFieldArray.Length; ++reflectFieldIndex)
+			{
+				IReflectField reflectField = reflectFieldArray[reflectFieldIndex];
+				if (!StoreField(reflectField))
+				{
+					continue;
+				}
+				Db4objects.Db4o.Internal.ClassMetadata classMetadata = Handlers4.ErasedFieldType(
+					Container(), reflectField.GetFieldType());
+				if (classMetadata == null)
+				{
+					continue;
+				}
+				FieldMetadata field = new FieldMetadata(this, reflectField, classMetadata);
+				if (Contains(collectedAspects, field))
+				{
+					continue;
+				}
+				dirty = true;
+				collectedAspects.Add(field);
+			}
+			return dirty;
+		}
+
+		private bool Contains(Collection4 collectedAspects, FieldMetadata field)
+		{
+			IEnumerator aspectIterator = collectedAspects.GetEnumerator();
+			while (aspectIterator.MoveNext())
+			{
+				if (((ClassAspect)aspectIterator.Current).Equals(field))
+				{
+					return true;
+				}
+			}
+			return false;
+		}
+
+		internal virtual void AddToIndex(Transaction trans, int id)
+		{
+			if (!trans.Container().MaintainsIndices())
+			{
+				return;
+			}
+			AddToIndex1(trans, id);
+		}
+
+		internal void AddToIndex1(Transaction a_trans, int a_id)
+		{
+			if (_ancestor != null)
+			{
+				_ancestor.AddToIndex1(a_trans, a_id);
+			}
+			if (HasClassIndex())
+			{
+				_index.Add(a_trans, a_id);
+			}
+		}
+
+		internal virtual bool AllowsQueries()
+		{
+			return HasClassIndex();
+		}
+
+		public virtual bool DescendOnCascadingActivation()
+		{
+			return true;
+		}
+
+		internal virtual void CheckChanges()
+		{
+			if (StateOK())
+			{
+				if (!BitIsTrue(Const4.CheckedChanges))
+				{
+					BitTrue(Const4.CheckedChanges);
+					if (_ancestor != null)
+					{
+						_ancestor.CheckChanges();
+					}
+					// Ancestor first, so the object length calculates
+					// correctly
+					if (_classReflector != null)
+					{
+						InitializeAspects();
+						if (!_container.IsClient && !IsReadOnlyContainer())
+						{
+							Write(_container.SystemTransaction());
+						}
+					}
+				}
+			}
+		}
+
+		public virtual void CheckType()
+		{
+			IReflectClass claxx = ClassReflector();
+			if (claxx == null)
+			{
+				return;
+			}
+			if (_container._handlers.IclassInternal.IsAssignableFrom(claxx))
+			{
+				_internal = true;
+			}
+			if (_container._handlers.IclassUnversioned.IsAssignableFrom(claxx))
+			{
+				_unversioned = true;
+			}
+			if (IsDb4oTypeImpl())
+			{
+				IDb4oTypeImpl db4oTypeImpl = (IDb4oTypeImpl)claxx.NewInstance();
+				_classIndexed = (db4oTypeImpl == null || db4oTypeImpl.HasClassIndex());
+			}
+			else
+			{
+				if (_config != null)
+				{
+					_classIndexed = _config.Indexed();
+				}
+			}
+		}
+
+		public virtual bool IsDb4oTypeImpl()
+		{
+			return _container._handlers.IclassDb4otypeimpl.IsAssignableFrom(ClassReflector());
+		}
+
+		public IUpdateDepth AdjustUpdateDepth(Transaction trans, IUpdateDepth depth)
+		{
+			return depth.Adjust(this);
+		}
+
+		public virtual bool CascadesOnDeleteOrUpdate()
+		{
+			Config4Class config = ConfigOrAncestorConfig();
+			if (config == null)
+			{
+				return false;
+			}
+			bool cascadeOnDelete = config.CascadeOnDelete() == TernaryBool.Yes;
+			bool cascadeOnUpdate = config.CascadeOnUpdate() == TernaryBool.Yes;
+			return cascadeOnDelete || cascadeOnUpdate;
+		}
+
+		public virtual FixedActivationDepth AdjustCollectionDepthToBorders(FixedActivationDepth
+			 depth)
+		{
+			if (!ClassReflector().IsCollection())
+			{
+				return depth;
+			}
+			return depth.AdjustDepthToBorders();
+		}
+
+		public int UpdateDepthFromConfig()
+		{
+			if (_config != null && _config.UpdateDepth() != Const4.Unspecified)
+			{
+				return _config.UpdateDepth();
+			}
+			Config4Impl config = ConfigImpl();
+			int depth = config.UpdateDepth();
+			if (_ancestor != null)
+			{
+				int ancestordepth = _ancestor.UpdateDepthFromConfig();
+				if (ancestordepth > depth)
+				{
+					return ancestordepth;
+				}
+			}
+			return depth;
+		}
+
+		public virtual void CollectConstraints(Transaction trans, QConObject parentConstraint
+			, object obj, IVisitor4 visitor)
+		{
+			TraverseAllAspects(new _TraverseFieldCommand_534(trans, parentConstraint, obj, visitor
+				));
+		}
+
+		private sealed class _TraverseFieldCommand_534 : TraverseFieldCommand
+		{
+			public _TraverseFieldCommand_534(Transaction trans, QConObject parentConstraint, 
+				object obj, IVisitor4 visitor)
+			{
+				this.trans = trans;
+				this.parentConstraint = parentConstraint;
+				this.obj = obj;
+				this.visitor = visitor;
+			}
+
+			protected override void Process(FieldMetadata field)
+			{
+				if (field.IsEnabledOn(AspectVersionContextImpl.CheckAlwaysEnabled))
+				{
+					field.CollectConstraints(trans, parentConstraint, obj, visitor);
+				}
+			}
+
+			private readonly Transaction trans;
+
+			private readonly QConObject parentConstraint;
+
+			private readonly object obj;
+
+			private readonly IVisitor4 visitor;
+		}
+
+		public void CollectIDs(CollectIdContext context, string fieldName)
+		{
+			CollectIDs(context, new _IPredicate4_544(fieldName));
+		}
+
+		private sealed class _IPredicate4_544 : IPredicate4
+		{
+			public _IPredicate4_544(string fieldName)
+			{
+				this.fieldName = fieldName;
+			}
+
+			public bool Match(object candidate)
+			{
+				return fieldName.Equals(((ClassAspect)candidate).GetName());
+			}
+
+			private readonly string fieldName;
+		}
+
+		public void CollectIDs(CollectIdContext context)
+		{
+			CollectIDs(context, new _IPredicate4_553());
+		}
+
+		private sealed class _IPredicate4_553 : IPredicate4
+		{
+			public _IPredicate4_553()
+			{
+			}
+
+			public bool Match(object candidate)
+			{
+				return true;
+			}
+		}
+
+		private void CollectIDs(CollectIdContext context, IPredicate4 predicate)
+		{
+			if (!StandardReferenceTypeHandlerIsUsed())
+			{
+				throw new InvalidOperationException();
+			}
+			((StandardReferenceTypeHandler)CorrectHandlerVersion(context)).CollectIDs(context
+				, predicate);
+		}
+
+		public virtual void CollectIDs(QueryingReadContext context)
+		{
+			if (!StandardReferenceTypeHandlerIsUsed())
+			{
+				throw new InvalidOperationException();
+			}
+			Handlers4.CollectIDs(context, CorrectHandlerVersion(context));
+		}
+
+		public virtual Config4Class Config()
+		{
+			return _config;
+		}
+
+		public virtual Config4Class ConfigOrAncestorConfig()
+		{
+			if (_config != null)
+			{
+				return _config;
+			}
+			if (_ancestor != null)
+			{
+				return _ancestor.ConfigOrAncestorConfig();
+			}
+			return null;
+		}
+
+		private void ResolveClassReflector(string className)
+		{
+			IReflectClass reflectClass = _container.Reflector().ForName(className);
+			if (null == reflectClass)
+			{
+				throw new InvalidOperationException("Cannot initialize ClassMetadata for '" + className
+					 + "'.");
+			}
+			ClassReflector(reflectClass);
+		}
+
+		private void InitializeConstructor(ITypeHandler4 customTypeHandler)
+		{
+			if (IsTransient())
+			{
+				_container.LogMsg(23, GetName());
+				SetStateDead();
+				return;
+			}
+			if (IsInterface() || IsAbstract())
+			{
+				return;
+			}
+			IFunction4 constructor = CreateConstructor(customTypeHandler);
+			if (constructor != null)
+			{
+				_constructor = constructor;
+				return;
+			}
+			NotStorable();
+		}
+
+		private bool IsAbstract()
+		{
+			return ClassReflector().IsAbstract();
+		}
+
+		private bool IsInterface()
+		{
+			return ClassReflector().IsInterface();
+		}
+
+		private IFunction4 CreateConstructor(ITypeHandler4 customTypeHandler)
+		{
+			if (customTypeHandler is IInstantiatingTypeHandler)
+			{
+				return new _IFunction4_632(this);
+			}
+			if (HasObjectConstructor())
+			{
+				return new _IFunction4_640(this);
+			}
+			if (ClassReflector().EnsureCanBeInstantiated())
+			{
+				return new _IFunction4_648(this);
+			}
+			return null;
+		}
+
+		private sealed class _IFunction4_632 : IFunction4
+		{
+			public _IFunction4_632(ClassMetadata _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Apply(object context)
+			{
+				return this._enclosing.InstantiateWithCustomTypeHandlerIfEnabled(((UnmarshallingContext
+					)context));
+			}
+
+			private readonly ClassMetadata _enclosing;
+		}
+
+		private sealed class _IFunction4_640 : IFunction4
+		{
+			public _IFunction4_640(ClassMetadata _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Apply(object context)
+			{
+				return this._enclosing._translator.Construct(((UnmarshallingContext)context));
+			}
+
+			private readonly ClassMetadata _enclosing;
+		}
+
+		private sealed class _IFunction4_648 : IFunction4
+		{
+			public _IFunction4_648(ClassMetadata _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Apply(object context)
+			{
+				return this._enclosing.InstantiateFromReflector(((UnmarshallingContext)context).Container
+					());
+			}
+
+			private readonly ClassMetadata _enclosing;
+		}
+
+		private void NotStorable()
+		{
+			_container.LogMsg(7, GetName());
+			SetStateDead();
+		}
+
+		private bool IsTransient()
+		{
+			return _container._handlers.IsTransient(ClassReflector());
+		}
+
+		private void ClassReflector(IReflectClass claxx)
+		{
+			_classReflector = claxx;
+			if (claxx == null)
+			{
+				_typeHandler = null;
+				return;
+			}
+			_typeHandler = CreateDefaultTypeHandler();
+		}
+
+		public virtual void Deactivate(Transaction trans, IObjectInfo reference, IActivationDepth
+			 depth)
+		{
+			object obj = reference.GetObject();
+			if (ObjectCanDeactivate(trans, reference))
+			{
+				ForceDeactivation(trans, depth, obj);
+				ObjectOnDeactivate(trans, reference);
+			}
+		}
+
+		public virtual void ForceDeactivation(Transaction trans, IActivationDepth depth, 
+			object obj)
+		{
+			DeactivateFields(trans.Container().ActivationContextFor(trans, obj, depth));
+		}
+
+		private void ObjectOnDeactivate(Transaction transaction, IObjectInfo obj)
+		{
+			ObjectContainerBase container = transaction.Container();
+			container.Callbacks().ObjectOnDeactivate(transaction, obj);
+			DispatchEvent(transaction, obj.GetObject(), EventDispatchers.Deactivate);
+		}
+
+		private bool ObjectCanDeactivate(Transaction transaction, IObjectInfo objectInfo)
+		{
+			ObjectContainerBase container = transaction.Container();
+			return container.Callbacks().ObjectCanDeactivate(transaction, objectInfo) && DispatchEvent
+				(transaction, objectInfo.GetObject(), EventDispatchers.CanDeactivate);
+		}
+
+		internal void DeactivateFields(IActivationContext context)
+		{
+			TraverseAllAspects(new _ITraverseAspectCommand_701(context));
+		}
+
+		private sealed class _ITraverseAspectCommand_701 : ITraverseAspectCommand
+		{
+			public _ITraverseAspectCommand_701(IActivationContext context)
+			{
+				this.context = context;
+			}
+
+			public void ProcessAspectOnMissingClass(ClassAspect aspect, int currentSlot)
+			{
+			}
+
+			// do nothing
+			public void ProcessAspect(ClassAspect aspect, int currentSlot)
+			{
+				if (aspect.IsEnabledOn(AspectVersionContextImpl.CheckAlwaysEnabled))
+				{
+					aspect.Deactivate(context);
+				}
+			}
+
+			public int DeclaredAspectCount(Db4objects.Db4o.Internal.ClassMetadata classMetadata
+				)
+			{
+				return classMetadata.DeclaredAspectCount();
+			}
+
+			public bool Cancelled()
+			{
+				return false;
+			}
+
+			private readonly IActivationContext context;
+		}
+
+		internal void Delete(StatefulBuffer buffer, object obj)
+		{
+			RemoveFromIndex(buffer.Transaction(), buffer.GetID());
+			CascadeDeletion(buffer, obj);
+		}
+
+		private void CascadeDeletion(StatefulBuffer buffer, object obj)
+		{
+			ObjectHeader oh = new ObjectHeader(this, buffer);
+			DeleteContextImpl context = new DeleteContextImpl(buffer, oh, ClassReflector(), null
+				);
+			DeleteMembers(context, ArrayTypeFor(buffer, obj), false);
+		}
+
+		private ArrayType ArrayTypeFor(StatefulBuffer buffer, object obj)
+		{
+			return buffer.Transaction().Container()._handlers.ArrayType(obj);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Delete(IDeleteContext context)
+		{
+			CorrectHandlerVersion(context).Delete(context);
+		}
+
+		internal virtual void DeleteMembers(DeleteContextImpl context, ArrayType arrayType
+			, bool isUpdate)
+		{
+			StatefulBuffer buffer = (StatefulBuffer)context.Buffer();
+			int preserveCascade = context.CascadeDeleteDepth();
+			try
+			{
+				if (CascadeOnDelete())
+				{
+					if (ClassReflector().IsCollection())
+					{
+						buffer.SetCascadeDeletes(CollectionDeleteDepth(context));
+					}
+					else
+					{
+						buffer.SetCascadeDeletes(1);
+					}
+				}
+				Handlers4.FieldAwareTypeHandler(CorrectHandlerVersion(context)).DeleteMembers(context
+					, isUpdate);
+			}
+			catch (Exception e)
+			{
+				// This a catch for changed class hierarchies.
+				// It's very ugly to catch all here but it does
+				// help to heal migration from earlier db4o
+				// versions.
+				DiagnosticProcessor dp = Container()._handlers.DiagnosticProcessor();
+				if (dp.Enabled())
+				{
+					dp.DeletionFailed();
+				}
+			}
+			buffer.SetCascadeDeletes(preserveCascade);
+		}
+
+		private int CollectionDeleteDepth(DeleteContextImpl context)
+		{
+			return 1;
+		}
+
+		public virtual TernaryBool CascadeOnDeleteTernary()
+		{
+			Config4Class config = Config();
+			TernaryBool cascadeOnDelete = TernaryBool.Unspecified;
+			if (config != null && (cascadeOnDelete = config.CascadeOnDelete()) != TernaryBool
+				.Unspecified)
+			{
+				return cascadeOnDelete;
+			}
+			if (_ancestor == null)
+			{
+				return cascadeOnDelete;
+			}
+			return _ancestor.CascadeOnDeleteTernary();
+		}
+
+		public virtual bool CascadeOnDelete()
+		{
+			return CascadeOnDeleteTernary() == TernaryBool.Yes;
+		}
+
+		public bool DispatchEvent(Transaction trans, object obj, int message)
+		{
+			return EventDispatcher().Dispatch(trans, obj, message);
+		}
+
+		public bool HasEventRegistered(Transaction trans, int eventID)
+		{
+			return EventDispatcher().HasEventRegistered(eventID);
+		}
+
+		private IEventDispatcher EventDispatcher()
+		{
+			if (null != _eventDispatcher)
+			{
+				return _eventDispatcher;
+			}
+			_eventDispatcher = EventDispatchers.ForClass(_container, ClassReflector());
+			return _eventDispatcher;
+		}
+
+		public int DeclaredAspectCount()
+		{
+			if (_aspects == null)
+			{
+				return 0;
+			}
+			return _aspects.Length;
+		}
+
+		public int AspectCount()
+		{
+			int count = DeclaredAspectCount();
+			if (_ancestor != null)
+			{
+				count += _ancestor.AspectCount();
+			}
+			return count;
+		}
+
+		// Scrolls offset in passed reader to the offset the passed field should
+		// be read at.
+		public HandlerVersion SeekToField(Transaction trans, ByteArrayBuffer buffer, FieldMetadata
+			 field)
+		{
+			if (buffer == null)
+			{
+				return HandlerVersion.Invalid;
+			}
+			if (!StandardReferenceTypeHandlerIsUsed())
+			{
+				return HandlerVersion.Invalid;
+			}
+			buffer.Seek(0);
+			ObjectHeader oh = new ObjectHeader(_container, buffer);
+			bool res = oh.ClassMetadata().SeekToField(new ObjectHeaderContext(trans, buffer, 
+				oh), field);
+			if (!res)
+			{
+				return HandlerVersion.Invalid;
+			}
+			return new HandlerVersion(oh.HandlerVersion());
+		}
+
+		public bool SeekToField(ObjectHeaderContext context, ClassAspect field)
+		{
+			if (!StandardReferenceTypeHandlerIsUsed())
+			{
+				return false;
+			}
+			return Handlers4.FieldAwareTypeHandler(CorrectHandlerVersion(context)).SeekToField
+				(context, field);
+		}
+
+		public virtual bool GenerateUUIDs()
+		{
+			if (!GenerateVirtual())
+			{
+				return false;
+			}
+			TernaryBool configValue = (_config == null) ? TernaryBool.Unspecified : _config.GenerateUUIDs
+				();
+			return Generate1(_container.Config().GenerateUUIDs(), configValue);
+		}
+
+		public virtual bool GenerateCommitTimestamps()
+		{
+			return _container.Config().GenerateCommitTimestamps().DefiniteYes();
+		}
+
+		private bool GenerateVirtual()
+		{
+			if (_unversioned)
+			{
+				return false;
+			}
+			if (_internal)
+			{
+				return false;
+			}
+			return true;
+		}
+
+		private bool Generate1(ConfigScope globalConfig, TernaryBool individualConfig)
+		{
+			return globalConfig.ApplyConfig(individualConfig);
+		}
+
+		public virtual Db4objects.Db4o.Internal.ClassMetadata GetAncestor()
+		{
+			return _ancestor;
+		}
+
+		public virtual object GetComparableObject(object forObject)
+		{
+			if (_config != null)
+			{
+				if (_config.QueryAttributeProvider() != null)
+				{
+					return _config.QueryAttributeProvider().Attribute(forObject);
+				}
+			}
+			return forObject;
+		}
+
+		public virtual Db4objects.Db4o.Internal.ClassMetadata GetHigherHierarchy(Db4objects.Db4o.Internal.ClassMetadata
+			 a_classMetadata)
+		{
+			Db4objects.Db4o.Internal.ClassMetadata yc = GetHigherHierarchy1(a_classMetadata);
+			if (yc != null)
+			{
+				return yc;
+			}
+			return a_classMetadata.GetHigherHierarchy1(this);
+		}
+
+		private Db4objects.Db4o.Internal.ClassMetadata GetHigherHierarchy1(Db4objects.Db4o.Internal.ClassMetadata
+			 a_classMetadata)
+		{
+			if (a_classMetadata == this)
+			{
+				return this;
+			}
+			if (_ancestor != null)
+			{
+				return _ancestor.GetHigherHierarchy1(a_classMetadata);
+			}
+			return null;
+		}
+
+		public virtual Db4objects.Db4o.Internal.ClassMetadata GetHigherOrCommonHierarchy(
+			Db4objects.Db4o.Internal.ClassMetadata a_classMetadata)
+		{
+			Db4objects.Db4o.Internal.ClassMetadata yc = GetHigherHierarchy1(a_classMetadata);
+			if (yc != null)
+			{
+				return yc;
+			}
+			if (_ancestor != null)
+			{
+				yc = _ancestor.GetHigherOrCommonHierarchy(a_classMetadata);
+				if (yc != null)
+				{
+					return yc;
+				}
+			}
+			return a_classMetadata.GetHigherHierarchy1(this);
+		}
+
+		public override byte GetIdentifier()
+		{
+			return Const4.Yapclass;
+		}
+
+		public virtual long[] GetIDs()
+		{
+			lock (Lock())
+			{
+				if (!StateOK())
+				{
+					return new long[0];
+				}
+				return GetIDs(_container.Transaction);
+			}
+		}
+
+		public virtual long[] GetIDs(Transaction trans)
+		{
+			lock (Lock())
+			{
+				if (!StateOK())
+				{
+					return new long[0];
+				}
+				if (!HasClassIndex())
+				{
+					return new long[0];
+				}
+				return trans.Container().GetIDsForClass(trans, this);
+			}
+		}
+
+		public virtual bool HasClassIndex()
+		{
+			if (!_classIndexed)
+			{
+				return false;
+			}
+			return StandardReferenceTypeHandlerIsUsed() || !(Handlers4.IsValueType(_typeHandler
+				));
+		}
+
+		private bool AncestorHasUUIDField()
+		{
+			if (_ancestor == null)
+			{
+				return false;
+			}
+			return _ancestor.HasUUIDField();
+		}
+
+		private bool HasUUIDField()
+		{
+			if (AncestorHasUUIDField())
+			{
+				return true;
+			}
+			return Arrays4.ContainsInstanceOf(_aspects, typeof(UUIDFieldMetadata));
+		}
+
+		private bool AncestorHasVersionField()
+		{
+			if (_ancestor == null)
+			{
+				return false;
+			}
+			return _ancestor.HasVersionField();
+		}
+
+		private bool AncestorHasCommitTimestampField()
+		{
+			if (_ancestor == null)
+			{
+				return false;
+			}
+			return _ancestor.HasCommitTimestampField();
+		}
+
+		public virtual bool HasVersionField()
+		{
+			if (AncestorHasVersionField())
+			{
+				return true;
+			}
+			return Arrays4.ContainsInstanceOf(_aspects, typeof(VersionFieldMetadata));
+		}
+
+		private bool HasCommitTimestampField()
+		{
+			if (AncestorHasCommitTimestampField())
+			{
+				return true;
+			}
+			return Arrays4.ContainsInstanceOf(_aspects, typeof(CommitTimestampFieldMetadata));
+		}
+
+		public virtual IClassIndexStrategy Index()
+		{
+			return _index;
+		}
+
+		public virtual int IndexEntryCount(Transaction ta)
+		{
+			if (!StateOK())
+			{
+				return 0;
+			}
+			return _index.EntryCount(ta);
+		}
+
+		public virtual IReflectClass ClassReflector()
+		{
+			return _classReflector;
+		}
+
+		public virtual string GetName()
+		{
+			if (i_name == null)
+			{
+				if (_classReflector != null)
+				{
+					SetName(_classReflector.GetName());
+				}
+			}
+			return i_name;
+		}
+
+		public virtual IStoredClass GetParentStoredClass()
+		{
+			return GetAncestor();
+		}
+
+		public virtual IStoredField[] GetStoredFields()
+		{
+			lock (Lock())
+			{
+				if (_aspects == null)
+				{
+					return new IStoredField[0];
+				}
+				Collection4 storedFields = new Collection4();
+				TraverseDeclaredFields(new _IProcedure4_1037(storedFields));
+				IStoredField[] fields = new IStoredField[storedFields.Size()];
+				storedFields.ToArray(fields);
+				return fields;
+			}
+		}
+
+		private sealed class _IProcedure4_1037 : IProcedure4
+		{
+			public _IProcedure4_1037(Collection4 storedFields)
+			{
+				this.storedFields = storedFields;
+			}
+
+			public void Apply(object field)
+			{
+				storedFields.Add(field);
+			}
+
+			private readonly Collection4 storedFields;
+		}
+
+		public ObjectContainerBase Container()
+		{
+			return _container;
+		}
+
+		public virtual FieldMetadata FieldMetadataForName(string name)
+		{
+			ByRef byReference = new ByRef();
+			TraverseAllAspects(new _TraverseFieldCommand_1054(name, byReference));
+			return (FieldMetadata)byReference.value;
+		}
+
+		private sealed class _TraverseFieldCommand_1054 : TraverseFieldCommand
+		{
+			public _TraverseFieldCommand_1054(string name, ByRef byReference)
+			{
+				this.name = name;
+				this.byReference = byReference;
+			}
+
+			protected override void Process(FieldMetadata field)
+			{
+				if (name.Equals(field.GetName()))
+				{
+					byReference.value = field;
+				}
+			}
+
+			private readonly string name;
+
+			private readonly ByRef byReference;
+		}
+
+		/// <param name="container"></param>
+		public virtual bool HasField(ObjectContainerBase container, string fieldName)
+		{
+			if (ClassReflector().IsCollection())
+			{
+				return true;
+			}
+			return FieldMetadataForName(fieldName) != null;
+		}
+
+		internal virtual bool HasVirtualAttributes()
+		{
+			if (_internal)
+			{
+				return false;
+			}
+			return HasVersionField() || HasUUIDField();
+		}
+
+		public virtual bool HoldsAnyClass()
+		{
+			return ClassReflector().IsCollection();
+		}
+
+		internal virtual void IncrementFieldsOffset1(ByteArrayBuffer a_bytes)
+		{
+			int length = ReadAspectCount(a_bytes);
+			for (int i = 0; i < length; i++)
+			{
+				_aspects[i].IncrementOffset(a_bytes);
+			}
+		}
+
+		internal bool Init(Db4objects.Db4o.Internal.ClassMetadata ancestor)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.ClassmetadataInit.Log(GetID());
+			}
+			SetConfig(ConfigImpl().ConfigClass(GetName()));
+			SetAncestor(ancestor);
+			CheckType();
+			if (AllowsQueries())
+			{
+				_index.Initialize(_container);
+			}
+			BitTrue(Const4.CheckedChanges);
+			return true;
+		}
+
+		internal void InitConfigOnUp(Transaction systemTrans)
+		{
+			Config4Class extendedConfig = Platform4.ExtendConfiguration(_classReflector, _container
+				.Configure(), _config);
+			if (extendedConfig != null)
+			{
+				_config = extendedConfig;
+			}
+			if (_config == null)
+			{
+				return;
+			}
+			if (!StateOK())
+			{
+				return;
+			}
+			InitializeFieldsConfiguration(systemTrans, extendedConfig);
+			CheckAllConfiguredFieldsExist(extendedConfig);
+		}
+
+		private void InitializeFieldsConfiguration(Transaction systemTrans, Config4Class 
+			extendedConfig)
+		{
+			if (_aspects == null)
+			{
+				return;
+			}
+			for (int i = 0; i < _aspects.Length; i++)
+			{
+				if (_aspects[i] is FieldMetadata)
+				{
+					FieldMetadata field = (FieldMetadata)_aspects[i];
+					string fieldName = field.GetName();
+					if (!field.HasConfig() && extendedConfig != null && extendedConfig.ConfigField(fieldName
+						) != null)
+					{
+						field.InitConfiguration(fieldName);
+					}
+					field.InitConfigOnUp(systemTrans);
+				}
+			}
+		}
+
+		private void CheckAllConfiguredFieldsExist(Config4Class config)
+		{
+			Hashtable4 exceptionalFields = config.ExceptionalFieldsOrNull();
+			if (exceptionalFields == null)
+			{
+				return;
+			}
+			IEnumerator i = exceptionalFields.ValuesIterator();
+			while (i.MoveNext())
+			{
+				Config4Field fieldConfig = (Config4Field)i.Current;
+				if (!fieldConfig.Used())
+				{
+					ConfigImpl().DiagnosticProcessor().ObjectFieldDoesNotExist(GetName(), fieldConfig
+						.GetName());
+				}
+			}
+		}
+
+		internal virtual void InitOnUp(Transaction systemTrans)
+		{
+			if (!StateOK())
+			{
+				return;
+			}
+			InitConfigOnUp(systemTrans);
+			StoreStaticFieldValues(systemTrans, false);
+		}
+
+		public virtual object Instantiate(UnmarshallingContext context)
+		{
+			// overridden in PrimitiveTypeMetadata
+			// never called for primitive YapAny
+			// FIXME: [TA] no longer necessary?
+			//        context.adjustInstantiationDepth();
+			object obj = context.PersistentObject();
+			bool instantiating = (obj == null);
+			if (instantiating)
+			{
+				obj = InstantiateObject(context);
+				if (obj == null)
+				{
+					return null;
+				}
+				ShareTransaction(obj, context.Transaction());
+				ShareObjectReference(obj, context.ObjectReference());
+				OnInstantiate(context, obj);
+				if (context.ActivationDepth().Mode().IsPrefetch())
+				{
+					context.ObjectReference().SetStateDeactivated();
+					return obj;
+				}
+				if (!context.ActivationDepth().RequiresActivation())
+				{
+					context.ObjectReference().SetStateDeactivated();
+					return obj;
+				}
+				return Activate(context);
+			}
+			if (ActivatingActiveObject(context.ActivationDepth().Mode(), context.ObjectReference
+				()))
+			{
+				IActivationDepth child = context.ActivationDepth().Descend(this);
+				if (child.RequiresActivation())
+				{
+					CascadeActivation(new ActivationContext4(context.Transaction(), obj, child));
+				}
+				return obj;
+			}
+			return Activate(context);
+		}
+
+		protected void OnInstantiate(UnmarshallingContext context, object obj)
+		{
+			context.SetObjectWeak(obj);
+			context.Transaction().ReferenceSystem().AddExistingReference(context.ObjectReference
+				());
+			ObjectOnInstantiate(context.Transaction(), context.ObjectReference());
+		}
+
+		public virtual object InstantiateTransient(UnmarshallingContext context)
+		{
+			// overridden in YapClassPrimitive
+			// never called for primitive YapAny
+			object obj = InstantiateObject(context);
+			if (obj == null)
+			{
+				return null;
+			}
+			context.Container().Peeked(context.ObjectId(), obj);
+			if (context.ActivationDepth().RequiresActivation())
+			{
+				InstantiateFields(context);
+			}
+			return obj;
+		}
+
+		private bool ActivatingActiveObject(ActivationMode mode, ObjectReference @ref)
+		{
+			return !mode.IsRefresh() && @ref.IsActive();
+		}
+
+		private object Activate(UnmarshallingContext context)
+		{
+			object obj = context.PersistentObject();
+			ObjectReference objectReference = context.ObjectReference();
+			if (!ObjectCanActivate(context.Transaction(), obj))
+			{
+				objectReference.SetStateDeactivated();
+				return obj;
+			}
+			objectReference.SetStateClean();
+			if (context.ActivationDepth().RequiresActivation())
+			{
+				InstantiateFields(context);
+			}
+			ObjectOnActivate(context.Transaction(), objectReference);
+			return obj;
+		}
+
+		public virtual bool HasObjectConstructor()
+		{
+			return _translator != null && _translator.IsObjectConstructor();
+		}
+
+		public virtual bool IsTranslated()
+		{
+			return _translator != null;
+		}
+
+		private object InstantiateObject(UnmarshallingContext context)
+		{
+			object obj = _constructor.Apply(context);
+			context.PersistentObject(obj);
+			return obj;
+		}
+
+		private void ObjectOnInstantiate(Transaction transaction, IObjectInfo reference)
+		{
+			transaction.Container().Callbacks().ObjectOnInstantiate(transaction, reference);
+		}
+
+		private object InstantiateFromReflector(ObjectContainerBase stream)
+		{
+			if (_classReflector == null)
+			{
+				throw new InvalidOperationException();
+			}
+			try
+			{
+				return _classReflector.NewInstance();
+			}
+			catch (MissingMethodException)
+			{
+				Container().LogMsg(7, ClassReflector().GetName());
+				return null;
+			}
+			catch (Exception)
+			{
+				// TODO: be more helpful here
+				return null;
+			}
+		}
+
+		private void ShareObjectReference(object obj, ObjectReference @ref)
+		{
+			if (obj is IDb4oTypeImpl)
+			{
+				((IDb4oTypeImpl)obj).SetObjectReference(@ref);
+			}
+		}
+
+		private void ShareTransaction(object obj, Transaction transaction)
+		{
+			if (obj is ITransactionAware)
+			{
+				((ITransactionAware)obj).SetTrans(transaction);
+			}
+		}
+
+		private void ObjectOnActivate(Transaction transaction, IObjectInfo obj)
+		{
+			ObjectContainerBase container = transaction.Container();
+			container.Callbacks().ObjectOnActivate(transaction, obj);
+			DispatchEvent(transaction, obj.GetObject(), EventDispatchers.Activate);
+		}
+
+		private bool ObjectCanActivate(Transaction transaction, object obj)
+		{
+			ObjectContainerBase container = transaction.Container();
+			return container.Callbacks().ObjectCanActivate(transaction, obj) && DispatchEvent
+				(transaction, obj, EventDispatchers.CanActivate);
+		}
+
+		internal virtual void InstantiateFields(UnmarshallingContext context)
+		{
+			ITypeHandler4 handler = CorrectHandlerVersion((IHandlerVersionContext)context);
+			Handlers4.Activate(context, handler);
+		}
+
+		public virtual bool IsArray()
+		{
+			return ClassReflector().IsCollection();
+		}
+
+		internal virtual bool IsCollection(object obj)
+		{
+			return Reflector().ForObject(obj).IsCollection();
+		}
+
+		public override bool IsDirty()
+		{
+			if (!StateOK())
+			{
+				return false;
+			}
+			return base.IsDirty();
+		}
+
+		internal virtual bool IsEnum()
+		{
+			return Platform4.IsJavaEnum(Reflector(), ClassReflector());
+		}
+
+		public virtual bool HasIdentity()
+		{
+			return true;
+		}
+
+		/// <summary>no any, primitive, array or other tricks.</summary>
+		/// <remarks>
+		/// no any, primitive, array or other tricks. overridden in YapClassAny and
+		/// YapClassPrimitive
+		/// </remarks>
+		public virtual bool IsStronglyTyped()
+		{
+			return true;
+		}
+
+		public virtual bool IsValueType()
+		{
+			return Handlers4.HoldsValueType(_typeHandler);
+		}
+
+		private object Lock()
+		{
+			return _container.Lock();
+		}
+
+		public virtual string NameToWrite()
+		{
+			if (_config != null && _config.WriteAs() != null)
+			{
+				return _config.WriteAs();
+			}
+			if (i_name == null)
+			{
+				return string.Empty;
+			}
+			return ConfigImpl().ResolveAliasRuntimeName(i_name);
+		}
+
+		public bool CallConstructor()
+		{
+			TernaryBool specialized = CallConstructorSpecialized();
+			// FIXME: If specified, return yes?!?
+			if (!specialized.IsUnspecified())
+			{
+				return specialized.DefiniteYes();
+			}
+			return ConfigImpl().CallConstructors().DefiniteYes();
+		}
+
+		private Config4Impl ConfigImpl()
+		{
+			return _container.ConfigImpl;
+		}
+
+		private TernaryBool CallConstructorSpecialized()
+		{
+			if (_config != null)
+			{
+				TernaryBool res = _config.CallConstructor();
+				if (!res.IsUnspecified())
+				{
+					return res;
+				}
+			}
+			if (IsEnum())
+			{
+				return TernaryBool.No;
+			}
+			if (_ancestor != null)
+			{
+				return _ancestor.CallConstructorSpecialized();
+			}
+			return TernaryBool.Unspecified;
+		}
+
+		public override int OwnLength()
+		{
+			return MarshallerFamily.Current()._class.MarshalledLength(_container, this);
+		}
+
+		internal virtual void Purge()
+		{
+			_index.Purge();
+		}
+
+		// TODO: may want to add manual purge to Btree
+		//       indexes here
+		public virtual ITypeHandler4 ReadCandidateHandler(QueryingReadContext context)
+		{
+			ITypeHandler4 typeHandler = CorrectHandlerVersion(context);
+			if (typeHandler is ICascadingTypeHandler)
+			{
+				return ((ICascadingTypeHandler)typeHandler).ReadCandidateHandler(context);
+			}
+			return null;
+		}
+
+		public virtual ITypeHandler4 SeekCandidateHandler(QueryingReadContext context)
+		{
+			if (IsArray())
+			{
+				if (Platform4.IsCollectionTranslator(this._config))
+				{
+					context.Seek(context.Offset() + Const4.IntLength);
+					return new ArrayHandler(null, false);
+				}
+				IncrementFieldsOffset1((ByteArrayBuffer)context.Buffer());
+				if (_ancestor != null)
+				{
+					return _ancestor.SeekCandidateHandler(context);
+				}
+			}
+			return null;
+		}
+
+		public int ReadAspectCount(IReadBuffer buffer)
+		{
+			int count = buffer.ReadInt();
+			if (count > _aspects.Length)
+			{
+				return _aspects.Length;
+			}
+			return count;
+		}
+
+		internal virtual byte[] ReadName(Transaction a_trans)
+		{
+			i_reader = a_trans.Container().ReadBufferById(a_trans, GetID());
+			return ReadName1(a_trans, i_reader);
+		}
+
+		public byte[] ReadName1(Transaction trans, ByteArrayBuffer reader)
+		{
+			if (reader == null)
+			{
+				return null;
+			}
+			i_reader = reader;
+			bool ok = false;
+			try
+			{
+				ClassMarshaller marshaller = MarshallerFamily.Current()._class;
+				i_nameBytes = marshaller.ReadName(trans, reader);
+				marshaller.ReadMetaClassID(reader);
+				// never used ???
+				SetStateUnread();
+				BitFalse(Const4.CheckedChanges);
+				BitFalse(Const4.StaticFieldsStored);
+				ok = true;
+				return i_nameBytes;
+			}
+			finally
+			{
+				if (!ok)
+				{
+					SetStateDead();
+				}
+			}
+		}
+
+		public virtual void ReadVirtualAttributes(Transaction trans, ObjectReference @ref
+			, bool lastCommitted)
+		{
+			int id = @ref.GetID();
+			ObjectContainerBase container = trans.Container();
+			ByteArrayBuffer buffer = container.ReadBufferById(trans, id, lastCommitted);
+			ObjectHeader oh = new ObjectHeader(this, buffer);
+			ObjectReferenceContext context = new ObjectReferenceContext(trans, buffer, oh, @ref
+				);
+			Handlers4.FieldAwareTypeHandler(CorrectHandlerVersion(context)).ReadVirtualAttributes
+				(context);
+		}
+
+		public virtual GenericReflector Reflector()
+		{
+			return _container.Reflector();
+		}
+
+		public virtual void Rename(string newName)
+		{
+			if (_container.IsClient)
+			{
+				Exceptions4.ThrowRuntimeException(58);
+			}
+			int tempState = _state;
+			SetStateOK();
+			SetName(newName);
+			i_nameBytes = AsBytes(i_name);
+			SetStateDirty();
+			Write(_container.SystemTransaction());
+			IReflectClass oldReflector = _classReflector;
+			ClassReflector(Container().Reflector().ForName(newName));
+			Container().ClassCollection().RefreshClassCache(this, oldReflector);
+			Refresh();
+			_state = tempState;
+		}
+
+		//TODO: duplicates ClassMetadataRepository#asBytes
+		private byte[] AsBytes(string str)
+		{
+			return Container().StringIO().Write(str);
+		}
+
+		internal void CreateConfigAndConstructor(Hashtable4 a_byteHashTable, IReflectClass
+			 claxx)
+		{
+			SetName(ResolveName(claxx));
+			SetConfig(ConfigImpl().ConfigClass(GetName()));
+			if (claxx == null)
+			{
+				ResolveClassReflector(GetName());
+			}
+			else
+			{
+				ClassReflector(claxx);
+			}
+			//            createConstructor(true);
+			if (i_nameBytes != null)
+			{
+				a_byteHashTable.Remove(i_nameBytes);
+				i_nameBytes = null;
+			}
+		}
+
+		internal virtual string ResolveName(IReflectClass claxx)
+		{
+			if (claxx != null)
+			{
+				return claxx.GetName();
+			}
+			if (i_nameBytes != null)
+			{
+				string name = _container.StringIO().Read(i_nameBytes);
+				return ConfigImpl().ResolveAliasStoredName(name);
+			}
+			throw new InvalidOperationException();
+		}
+
+		internal virtual bool ReadThis()
+		{
+			bool stateUnread = StateUnread();
+			if (stateUnread)
+			{
+				SetStateOK();
+				SetStateClean();
+			}
+			if (stateUnread || StateDead())
+			{
+				ForceRead();
+				return true;
+			}
+			return false;
+		}
+
+		internal void ForceRead()
+		{
+			if (i_reader == null || BitIsTrue(Const4.Reading))
+			{
+				return;
+			}
+			BitTrue(Const4.Reading);
+			try
+			{
+				MarshallerFamily.ForConverterVersion(_container.ConverterVersion())._class.Read(_container
+					, this, i_reader);
+				i_nameBytes = null;
+				i_reader = null;
+			}
+			finally
+			{
+				BitFalse(Const4.Reading);
+			}
+		}
+
+		public override void ReadThis(Transaction a_trans, ByteArrayBuffer a_reader)
+		{
+			throw Exceptions4.VirtualException();
+		}
+
+		public virtual void Refresh()
+		{
+			if (!StateUnread())
+			{
+				ResolveClassReflector(i_name);
+				BitFalse(Const4.CheckedChanges);
+				CheckChanges();
+				TraverseDeclaredFields(new _IProcedure4_1582());
+			}
+		}
+
+		private sealed class _IProcedure4_1582 : IProcedure4
+		{
+			public _IProcedure4_1582()
+			{
+			}
+
+			public void Apply(object arg)
+			{
+				((FieldMetadata)arg).Refresh();
+			}
+		}
+
+		internal virtual void RemoveFromIndex(Transaction ta, int id)
+		{
+			if (HasClassIndex())
+			{
+				_index.Remove(ta, id);
+			}
+			if (_ancestor != null)
+			{
+				_ancestor.RemoveFromIndex(ta, id);
+			}
+		}
+
+		internal virtual bool RenameField(string oldName, string newName)
+		{
+			BooleanByRef renamed = new BooleanByRef(false);
+			for (int i = 0; i < _aspects.Length; i++)
+			{
+				if (_aspects[i].GetName().Equals(newName))
+				{
+					_container.LogMsg(9, "class:" + GetName() + " field:" + newName);
+					return false;
+				}
+			}
+			TraverseDeclaredFields(new _IProcedure4_1607(oldName, newName, renamed));
+			return renamed.value;
+		}
+
+		private sealed class _IProcedure4_1607 : IProcedure4
+		{
+			public _IProcedure4_1607(string oldName, string newName, BooleanByRef renamed)
+			{
+				this.oldName = oldName;
+				this.newName = newName;
+				this.renamed = renamed;
+			}
+
+			public void Apply(object arg)
+			{
+				FieldMetadata field = (FieldMetadata)arg;
+				if (field.GetName().Equals(oldName))
+				{
+					field.SetName(newName);
+					renamed.value = true;
+				}
+			}
+
+			private readonly string oldName;
+
+			private readonly string newName;
+
+			private readonly BooleanByRef renamed;
+		}
+
+		internal virtual void SetConfig(Config4Class config)
+		{
+			if (config == null)
+			{
+				return;
+			}
+			// The configuration can be set by a ObjectClass#readAs setting
+			// from YapClassCollection, right after reading the meta information
+			// for the first time. In that case we never change the setting
+			if (_config == null)
+			{
+				_config = config;
+			}
+		}
+
+		internal virtual void SetName(string a_name)
+		{
+			i_name = a_name;
+		}
+
+		internal void SetStateDead()
+		{
+			BitTrue(Const4.Dead);
+			BitFalse(Const4.Continue);
+		}
+
+		private void SetStateUnread()
+		{
+			BitFalse(Const4.Dead);
+			BitTrue(Const4.Continue);
+		}
+
+		internal void SetStateOK()
+		{
+			BitFalse(Const4.Dead);
+			BitFalse(Const4.Continue);
+		}
+
+		internal virtual bool StateDead()
+		{
+			return BitIsTrue(Const4.Dead);
+		}
+
+		internal bool StateOK()
+		{
+			return BitIsFalse(Const4.Continue) && BitIsFalse(Const4.Dead) && BitIsFalse(Const4
+				.Reading);
+		}
+
+		internal virtual bool StateUnread()
+		{
+			return BitIsTrue(Const4.Continue) && BitIsFalse(Const4.Dead) && BitIsFalse(Const4
+				.Reading);
+		}
+
+		internal virtual bool StoreField(IReflectField field)
+		{
+			if (field.IsStatic())
+			{
+				return false;
+			}
+			if (IsTransient(field))
+			{
+				if (!ShouldStoreTransientFields())
+				{
+					return false;
+				}
+			}
+			return Platform4.CanSetAccessible() || field.IsPublic();
+		}
+
+		internal virtual bool ShouldStoreTransientFields()
+		{
+			Config4Class config = ConfigOrAncestorConfig();
+			if (config == null)
+			{
+				return false;
+			}
+			return config.StoreTransientFields();
+		}
+
+		private bool IsTransient(IReflectField field)
+		{
+			return field.IsTransient() || Platform4.IsTransient(field.GetFieldType());
+		}
+
+		public virtual IStoredField StoredField(string fieldName, object fieldType)
+		{
+			lock (Lock())
+			{
+				Db4objects.Db4o.Internal.ClassMetadata fieldTypeFilter = fieldType == null ? null
+					 : _container.ClassMetadataForReflectClass(ReflectorUtils.ReflectClassFor(Reflector
+					(), fieldType));
+				ByRef foundField = new ByRef();
+				TraverseAllAspects(new _TraverseFieldCommand_1701(foundField, fieldName, fieldTypeFilter
+					));
+				// TODO: implement field creation
+				return (IStoredField)foundField.value;
+			}
+		}
+
+		private sealed class _TraverseFieldCommand_1701 : TraverseFieldCommand
+		{
+			public _TraverseFieldCommand_1701(ByRef foundField, string fieldName, Db4objects.Db4o.Internal.ClassMetadata
+				 fieldTypeFilter)
+			{
+				this.foundField = foundField;
+				this.fieldName = fieldName;
+				this.fieldTypeFilter = fieldTypeFilter;
+			}
+
+			protected override void Process(FieldMetadata field)
+			{
+				if (foundField.value != null)
+				{
+					return;
+				}
+				if (field.GetName().Equals(fieldName))
+				{
+					if (fieldTypeFilter == null || fieldTypeFilter == field.FieldType())
+					{
+						foundField.value = field;
+					}
+				}
+			}
+
+			private readonly ByRef foundField;
+
+			private readonly string fieldName;
+
+			private readonly Db4objects.Db4o.Internal.ClassMetadata fieldTypeFilter;
+		}
+
+		internal virtual void StoreStaticFieldValues(Transaction trans, bool force)
+		{
+			if (BitIsTrue(Const4.StaticFieldsStored) && !force)
+			{
+				return;
+			}
+			BitTrue(Const4.StaticFieldsStored);
+			if (!ShouldStoreStaticFields(trans))
+			{
+				return;
+			}
+			ObjectContainerBase stream = trans.Container();
+			stream.ShowInternalClasses(true);
+			try
+			{
+				StaticClass sc = QueryStaticClass(trans);
+				if (sc == null)
+				{
+					CreateStaticClass(trans);
+				}
+				else
+				{
+					UpdateStaticClass(trans, sc);
+				}
+			}
+			finally
+			{
+				stream.ShowInternalClasses(false);
+			}
+		}
+
+		private bool ShouldStoreStaticFields(Transaction trans)
+		{
+			return !IsReadOnlyContainer() && (StaticFieldValuesArePersisted() || Platform4.StoreStaticFieldValues
+				(trans.Reflector(), ClassReflector()));
+		}
+
+		private bool IsReadOnlyContainer()
+		{
+			return Container().Config().IsReadOnly();
+		}
+
+		private void UpdateStaticClass(Transaction trans, StaticClass sc)
+		{
+			ObjectContainerBase stream = trans.Container();
+			stream.Activate(trans, sc, new FixedActivationDepth(4));
+			StaticField[] existingFields = sc.fields;
+			IEnumerator staticFields = Iterators.Map(StaticReflectFields(), new _IFunction4_1761
+				(this, existingFields, trans));
+			sc.fields = ToStaticFieldArray(staticFields);
+			if (!stream.IsClient)
+			{
+				SetStaticClass(trans, sc);
+			}
+		}
+
+		private sealed class _IFunction4_1761 : IFunction4
+		{
+			public _IFunction4_1761(ClassMetadata _enclosing, StaticField[] existingFields, Transaction
+				 trans)
+			{
+				this._enclosing = _enclosing;
+				this.existingFields = existingFields;
+				this.trans = trans;
+			}
+
+			public object Apply(object arg)
+			{
+				IReflectField reflectField = (IReflectField)arg;
+				StaticField existingField = this._enclosing.FieldByName(existingFields, reflectField
+					.GetName());
+				if (existingField != null)
+				{
+					this._enclosing.UpdateExistingStaticField(trans, existingField, reflectField);
+					return existingField;
+				}
+				return this._enclosing.ToStaticField(reflectField);
+			}
+
+			private readonly ClassMetadata _enclosing;
+
+			private readonly StaticField[] existingFields;
+
+			private readonly Transaction trans;
+		}
+
+		private void CreateStaticClass(Transaction trans)
+		{
+			if (trans.Container().IsClient)
+			{
+				return;
+			}
+			StaticClass sc = new StaticClass(GetName(), ToStaticFieldArray(StaticReflectFieldsToStaticFields
+				()));
+			SetStaticClass(trans, sc);
+		}
+
+		private IEnumerator StaticReflectFieldsToStaticFields()
+		{
+			return Iterators.Map(StaticReflectFields(), new _IFunction4_1789(this));
+		}
+
+		private sealed class _IFunction4_1789 : IFunction4
+		{
+			public _IFunction4_1789(ClassMetadata _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Apply(object arg)
+			{
+				return this._enclosing.ToStaticField((IReflectField)arg);
+			}
+
+			private readonly ClassMetadata _enclosing;
+		}
+
+		protected virtual StaticField ToStaticField(IReflectField reflectField)
+		{
+			return new StaticField(reflectField.GetName(), StaticReflectFieldValue(reflectField
+				));
+		}
+
+		private object StaticReflectFieldValue(IReflectField reflectField)
+		{
+			return _fieldAccessor.Get(reflectField, null);
+		}
+
+		private void SetStaticClass(Transaction trans, StaticClass sc)
+		{
+			// TODO: we should probably use a specific update depth here, 4?
+			trans.Container().StoreInternal(trans, sc, true);
+		}
+
+		private StaticField[] ToStaticFieldArray(IEnumerator iterator4)
+		{
+			return ToStaticFieldArray(new Collection4(iterator4));
+		}
+
+		private StaticField[] ToStaticFieldArray(Collection4 fields)
+		{
+			return (StaticField[])fields.ToArray(new StaticField[fields.Size()]);
+		}
+
+		private IEnumerator StaticReflectFields()
+		{
+			return Iterators.Filter(ReflectFields(), new _IPredicate4_1818());
+		}
+
+		private sealed class _IPredicate4_1818 : IPredicate4
+		{
+			public _IPredicate4_1818()
+			{
+			}
+
+			public bool Match(object candidate)
+			{
+				return ((IReflectField)candidate).IsStatic() && !((IReflectField)candidate).IsTransient
+					();
+			}
+		}
+
+		private IReflectField[] ReflectFields()
+		{
+			return ClassReflector().GetDeclaredFields();
+		}
+
+		protected virtual void UpdateExistingStaticField(Transaction trans, StaticField existingField
+			, IReflectField reflectField)
+		{
+			ObjectContainerBase stream = trans.Container();
+			object newValue = StaticReflectFieldValue(reflectField);
+			if (existingField.value != null && newValue != null && existingField.value.GetType
+				() == newValue.GetType())
+			{
+				int id = stream.GetID(trans, existingField.value);
+				if (id > 0)
+				{
+					if (existingField.value != newValue)
+					{
+						// This is the clue:
+						// Bind the current static member to it's old database identity,
+						// so constants and enums will work with '=='
+						stream.Bind(trans, newValue, id);
+						// This may produce unwanted side effects if the static field object
+						// was modified in the current session. TODO:Add documentation case.
+						stream.Refresh(trans, newValue, int.MaxValue);
+						existingField.value = newValue;
+					}
+					return;
+				}
+			}
+			if (newValue == null)
+			{
+				try
+				{
+					_fieldAccessor.Set(reflectField, null, existingField.value);
+				}
+				catch (Exception)
+				{
+				}
+				// fail silently
+				// TODO: why?
+				return;
+			}
+			existingField.value = newValue;
+		}
+
+		private bool StaticFieldValuesArePersisted()
+		{
+			return (_config != null && _config.StaticFieldValuesArePersisted());
+		}
+
+		protected virtual StaticField FieldByName(StaticField[] fields, string fieldName)
+		{
+			for (int i = 0; i < fields.Length; i++)
+			{
+				StaticField field = fields[i];
+				if (fieldName.Equals(field.name))
+				{
+					return field;
+				}
+			}
+			return null;
+		}
+
+		private StaticClass QueryStaticClass(Transaction trans)
+		{
+			IQuery q = trans.Container().Query(trans);
+			q.Constrain(Const4.ClassStaticclass);
+			q.Descend("name").Constrain(GetName());
+			IObjectSet os = q.Execute();
+			return os.Count > 0 ? (StaticClass)os.Next() : null;
+		}
+
+		public override string ToString()
+		{
+			if (i_name != null)
+			{
+				return i_name;
+			}
+			if (i_nameBytes == null)
+			{
+				return "*CLASS NAME UNKNOWN*";
+			}
+			LatinStringIO stringIO = _container == null ? Const4.stringIO : _container.StringIO
+				();
+			return stringIO.Read(i_nameBytes);
+		}
+
+		public override bool WriteObjectBegin()
+		{
+			if (!StateOK())
+			{
+				return false;
+			}
+			return base.WriteObjectBegin();
+		}
+
+		public sealed override void WriteThis(Transaction trans, ByteArrayBuffer writer)
+		{
+			MarshallerFamily.Current()._class.Write(trans, this, writer);
+		}
+
+		public virtual IPreparedComparison PrepareComparison(IContext context, object source
+			)
+		{
+			return Handlers4.PrepareComparisonFor(_typeHandler, context, source);
+		}
+
+		public static void DefragObject(DefragmentContextImpl context)
+		{
+			ObjectHeader header = ObjectHeader.Defrag(context);
+			DefragmentContextImpl childContext = new DefragmentContextImpl(context, header);
+			header.ClassMetadata().Defragment(childContext);
+		}
+
+		public virtual void Defragment(IDefragmentContext context)
+		{
+			CorrectHandlerVersion(context).Defragment(context);
+		}
+
+		public virtual void DefragClass(DefragmentContextImpl context, int classIndexID)
+		{
+			MarshallerFamily mf = MarshallerFamily.ForConverterVersion(Container().ConverterVersion
+				());
+			mf._class.Defrag(this, _container.StringIO(), context, classIndexID);
+		}
+
+		public static Db4objects.Db4o.Internal.ClassMetadata ReadClass(ObjectContainerBase
+			 stream, ByteArrayBuffer reader)
+		{
+			ObjectHeader oh = new ObjectHeader(stream, reader);
+			return oh.ClassMetadata();
+		}
+
+		public virtual bool IsAssignableFrom(Db4objects.Db4o.Internal.ClassMetadata other
+			)
+		{
+			return ClassReflector().IsAssignableFrom(other.ClassReflector());
+		}
+
+		public virtual void SetAncestor(Db4objects.Db4o.Internal.ClassMetadata ancestor)
+		{
+			if (ancestor == this)
+			{
+				throw new InvalidOperationException();
+			}
+			_ancestor = ancestor;
+		}
+
+		public virtual object WrapWithTransactionContext(Transaction transaction, object 
+			value)
+		{
+			if (value is int)
+			{
+				return value;
+			}
+			return new TransactionContext(transaction, value);
+		}
+
+		public virtual ITypeHandler4 TypeHandler()
+		{
+			return _typeHandler;
+		}
+
+		public virtual ITypeHandler4 DelegateTypeHandler(IContext context)
+		{
+			if (context is IHandlerVersionContext)
+			{
+				return CorrectHandlerVersion((IHandlerVersionContext)context);
+			}
+			return _typeHandler;
+		}
+
+		protected virtual ITypeHandler4 CorrectHandlerVersion(IHandlerVersionContext context
+			)
+		{
+			ITypeHandler4 typeHandler = HandlerRegistry.CorrectHandlerVersion(context, _typeHandler
+				);
+			if (typeHandler != _typeHandler)
+			{
+				if (typeHandler is StandardReferenceTypeHandler)
+				{
+					((StandardReferenceTypeHandler)typeHandler).ClassMetadata(this);
+				}
+			}
+			return typeHandler;
+		}
+
+		public virtual void TraverseDeclaredFields(IProcedure4 procedure)
+		{
+			if (_aspects == null)
+			{
+				return;
+			}
+			for (int i = 0; i < _aspects.Length; i++)
+			{
+				if (_aspects[i] is FieldMetadata)
+				{
+					procedure.Apply(_aspects[i]);
+				}
+			}
+		}
+
+		public virtual void TraverseDeclaredAspects(IProcedure4 procedure)
+		{
+			if (_aspects == null)
+			{
+				return;
+			}
+			for (int i = 0; i < _aspects.Length; i++)
+			{
+				procedure.Apply(_aspects[i]);
+			}
+		}
+
+		public virtual bool AspectsAreNull()
+		{
+			return _aspects == null;
+		}
+
+		private sealed class AlwaysModified : IModificationAware
+		{
+			internal static readonly ClassMetadata.AlwaysModified Instance = new ClassMetadata.AlwaysModified
+				();
+
+			public bool IsModified(object obj)
+			{
+				return true;
+			}
+		}
+
+		public virtual bool IsModified(object obj)
+		{
+			return _modificationChecker.IsModified(obj);
+		}
+
+		public virtual int InstanceCount()
+		{
+			return InstanceCount(_container.Transaction);
+		}
+
+		public virtual int InstanceCount(Transaction trans)
+		{
+			return _container.InstanceCount(this, trans);
+		}
+
+		public virtual bool IsStorable()
+		{
+			return !StateDead() && !IsTransient();
+		}
+
+		private object InstantiateWithCustomTypeHandlerIfEnabled(UnmarshallingContext context
+			)
+		{
+			if (!_customTypeHandlerAspect.IsEnabledOn(context))
+			{
+				return InstantiateForVersionWithoutCustomTypeHandler(context);
+			}
+			return InstantiateWithCustomTypeHandler(context);
+		}
+
+		private object InstantiateForVersionWithoutCustomTypeHandler(UnmarshallingContext
+			 context)
+		{
+			IFunction4 oldVersionConstructor = CreateConstructor(null);
+			if (null == oldVersionConstructor)
+			{
+				throw new InvalidOperationException();
+			}
+			return oldVersionConstructor.Apply(context);
+		}
+
+		private object InstantiateWithCustomTypeHandler(UnmarshallingContext context)
+		{
+			ContextState contextState = context.SaveState();
+			try
+			{
+				bool fieldHasValue = SeekToField(context, _customTypeHandlerAspect);
+				if (!fieldHasValue)
+				{
+					context.RestoreState(contextState);
+					return InstantiateForVersionWithoutCustomTypeHandler(context);
+				}
+				IInstantiatingTypeHandler customTypeHandler = (IInstantiatingTypeHandler)_customTypeHandlerAspect
+					._typeHandler;
+				return context.SlotFormat().DoWithSlotIndirection(context, new _IClosure4_2056(customTypeHandler
+					, context));
+			}
+			finally
+			{
+				context.RestoreState(contextState);
+			}
+		}
+
+		private sealed class _IClosure4_2056 : IClosure4
+		{
+			public _IClosure4_2056(IInstantiatingTypeHandler customTypeHandler, UnmarshallingContext
+				 context)
+			{
+				this.customTypeHandler = customTypeHandler;
+				this.context = context;
+			}
+
+			public object Run()
+			{
+				return customTypeHandler.Instantiate(context);
+			}
+
+			private readonly IInstantiatingTypeHandler customTypeHandler;
+
+			private readonly UnmarshallingContext context;
+		}
+
+		public virtual bool IsStruct()
+		{
+			return Platform4.IsStruct(ClassReflector());
+		}
+
+		public virtual void DropClassIndex()
+		{
+			if (Container().IsClient)
+			{
+				throw new InvalidOperationException();
+			}
+			_index = CreateIndexStrategy();
+			_index.Initialize(Container());
+			Container().SetDirtyInSystemTransaction(this);
+		}
+
+		public virtual void TraverseAllAspects(ITraverseAspectCommand command)
+		{
+			AspectTraversalStrategy().TraverseAllAspects(command);
+		}
+
+		private IAspectTraversalStrategy AspectTraversalStrategy()
+		{
+			if (_aspectTraversalStrategy == null)
+			{
+				_aspectTraversalStrategy = DetectAspectTraversalStrategy();
+			}
+			return _aspectTraversalStrategy;
+		}
+
+		protected virtual IAspectTraversalStrategy DetectAspectTraversalStrategy()
+		{
+			IList ancestors = CompareAncestorHierarchy();
+			for (IEnumerator diffIter = ancestors.GetEnumerator(); diffIter.MoveNext(); )
+			{
+				HierarchyAnalyzer.Diff diff = ((HierarchyAnalyzer.Diff)diffIter.Current);
+				if (diff.IsRemoved())
+				{
+					return CreateRemovedAspectTraversalStrategy(ancestors);
+				}
+			}
+			return new StandardAspectTraversalStrategy(this);
+		}
+
+		private IAspectTraversalStrategy CreateRemovedAspectTraversalStrategy(IList ancestors
+			)
+		{
+			return new ModifiedAspectTraversalStrategy(this, ancestors);
+		}
+
+		private IList CompareAncestorHierarchy()
+		{
+			return new HierarchyAnalyzer(this, ClassReflector()).Analyze();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ClassMetadataIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ClassMetadataIterator.cs
new file mode 100644
index 0000000..7d866e4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ClassMetadataIterator.cs
@@ -0,0 +1,30 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude>TODO: remove this class or make it private to ClassMetadataRepository</exclude>
+	public class ClassMetadataIterator : MappingIterator
+	{
+		private readonly ClassMetadataRepository i_collection;
+
+		internal ClassMetadataIterator(ClassMetadataRepository a_collection, IEnumerator 
+			iterator) : base(iterator)
+		{
+			i_collection = a_collection;
+		}
+
+		public virtual ClassMetadata CurrentClass()
+		{
+			return (ClassMetadata)Current;
+		}
+
+		protected override object Map(object current)
+		{
+			return i_collection.ReadClassMetadata((ClassMetadata)current, null);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ClassMetadataRepository.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ClassMetadataRepository.cs
new file mode 100644
index 0000000..3aae380
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ClassMetadataRepository.cs
@@ -0,0 +1,745 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Metadata;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public sealed class ClassMetadataRepository : PersistentBase
+	{
+		private Collection4 _classes;
+
+		private Hashtable4 _creating;
+
+		private readonly Transaction _systemTransaction;
+
+		private Hashtable4 _classMetadataByBytes;
+
+		private Hashtable4 _classMetadataByClass;
+
+		private Hashtable4 _classMetadataByName;
+
+		private Hashtable4 _classMetadataByID;
+
+		private int _classMetadataCreationDepth;
+
+		private IQueue4 _initClassMetadataOnUp;
+
+		private readonly PendingClassInits _classInits;
+
+		public ClassMetadataRepository(Transaction systemTransaction)
+		{
+			_systemTransaction = systemTransaction;
+			_initClassMetadataOnUp = new NonblockingQueue();
+			_classInits = new PendingClassInits(_systemTransaction);
+		}
+
+		public void AddClassMetadata(ClassMetadata clazz)
+		{
+			Container().SetDirtyInSystemTransaction(this);
+			_classes.Add(clazz);
+			if (clazz.StateUnread())
+			{
+				_classMetadataByBytes.Put(clazz.i_nameBytes, clazz);
+			}
+			else
+			{
+				_classMetadataByClass.Put(clazz.ClassReflector(), clazz);
+			}
+			RegisterClassMetadataById(clazz);
+		}
+
+		private void RegisterClassMetadataById(ClassMetadata clazz)
+		{
+			if (clazz.GetID() == 0)
+			{
+				clazz.Write(_systemTransaction);
+			}
+			_classMetadataByID.Put(clazz.GetID(), clazz);
+		}
+
+		private byte[] AsBytes(string str)
+		{
+			return Container().StringIO().Write(str);
+		}
+
+		public void AttachQueryNode(string fieldName, IVisitor4 visitor)
+		{
+			ClassMetadataIterator i = Iterator();
+			while (i.MoveNext())
+			{
+				ClassMetadata classMetadata = i.CurrentClass();
+				if (!classMetadata.IsInternal())
+				{
+					classMetadata.TraverseAllAspects(new _TraverseFieldCommand_65(fieldName, visitor, 
+						classMetadata));
+				}
+			}
+		}
+
+		private sealed class _TraverseFieldCommand_65 : TraverseFieldCommand
+		{
+			public _TraverseFieldCommand_65(string fieldName, IVisitor4 visitor, ClassMetadata
+				 classMetadata)
+			{
+				this.fieldName = fieldName;
+				this.visitor = visitor;
+				this.classMetadata = classMetadata;
+			}
+
+			protected override void Process(FieldMetadata field)
+			{
+				if (field.CanAddToQuery(fieldName))
+				{
+					visitor.Visit(new object[] { classMetadata, field });
+				}
+			}
+
+			private readonly string fieldName;
+
+			private readonly IVisitor4 visitor;
+
+			private readonly ClassMetadata classMetadata;
+		}
+
+		public void IterateTopLevelClasses(IVisitor4 visitor)
+		{
+			ClassMetadataIterator i = Iterator();
+			while (i.MoveNext())
+			{
+				ClassMetadata classMetadata = i.CurrentClass();
+				if (!classMetadata.IsInternal())
+				{
+					if (classMetadata.GetAncestor() == null)
+					{
+						visitor.Visit(classMetadata);
+					}
+				}
+			}
+		}
+
+		internal void CheckChanges()
+		{
+			IEnumerator i = _classes.GetEnumerator();
+			while (i.MoveNext())
+			{
+				((ClassMetadata)i.Current).CheckChanges();
+			}
+		}
+
+		internal bool CreateClassMetadata(ClassMetadata clazz, IReflectClass reflectClazz
+			)
+		{
+			bool result = false;
+			_classMetadataCreationDepth++;
+			try
+			{
+				IReflectClass parentReflectClazz = reflectClazz.GetSuperclass();
+				ClassMetadata parentClazz = null;
+				if (parentReflectClazz != null && !parentReflectClazz.Equals(Container()._handlers
+					.IclassObject))
+				{
+					parentClazz = ProduceClassMetadata(parentReflectClazz);
+				}
+				result = Container().CreateClassMetadata(clazz, reflectClazz, parentClazz);
+			}
+			finally
+			{
+				_classMetadataCreationDepth--;
+			}
+			InitClassMetadataOnUp();
+			return result;
+		}
+
+		private void EnsureAllClassesRead()
+		{
+			bool allClassesRead = false;
+			while (!allClassesRead)
+			{
+				Collection4 unreadClasses = new Collection4();
+				int numClasses = _classes.Size();
+				IEnumerator classIter = _classes.GetEnumerator();
+				while (classIter.MoveNext())
+				{
+					ClassMetadata clazz = (ClassMetadata)classIter.Current;
+					if (clazz.StateUnread())
+					{
+						unreadClasses.Add(clazz);
+					}
+				}
+				IEnumerator unreadIter = unreadClasses.GetEnumerator();
+				while (unreadIter.MoveNext())
+				{
+					ClassMetadata clazz = (ClassMetadata)unreadIter.Current;
+					clazz = ReadClassMetadata(clazz, null);
+					if (clazz.ClassReflector() == null)
+					{
+						clazz.ForceRead();
+					}
+				}
+				allClassesRead = (_classes.Size() == numClasses);
+			}
+			ApplyReadAs();
+		}
+
+		internal bool FieldExists(string field)
+		{
+			ClassMetadataIterator i = Iterator();
+			while (i.MoveNext())
+			{
+				if (i.CurrentClass().FieldMetadataForName(field) != null)
+				{
+					return true;
+				}
+			}
+			return false;
+		}
+
+		public Collection4 ForInterface(IReflectClass claxx)
+		{
+			Collection4 col = new Collection4();
+			ClassMetadataIterator i = Iterator();
+			while (i.MoveNext())
+			{
+				ClassMetadata clazz = i.CurrentClass();
+				IReflectClass candidate = clazz.ClassReflector();
+				if (!candidate.IsInterface())
+				{
+					if (claxx.IsAssignableFrom(candidate))
+					{
+						col.Add(clazz);
+						IEnumerator j = new Collection4(col).GetEnumerator();
+						while (j.MoveNext())
+						{
+							ClassMetadata existing = (ClassMetadata)j.Current;
+							if (existing != clazz)
+							{
+								ClassMetadata higher = clazz.GetHigherHierarchy(existing);
+								if (higher != null)
+								{
+									if (higher == clazz)
+									{
+										col.Remove(existing);
+									}
+									else
+									{
+										col.Remove(clazz);
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+			return col;
+		}
+
+		public override byte GetIdentifier()
+		{
+			return Const4.Yapclasscollection;
+		}
+
+		internal ClassMetadata GetActiveClassMetadata(IReflectClass reflectClazz)
+		{
+			return (ClassMetadata)_classMetadataByClass.Get(reflectClazz);
+		}
+
+		internal ClassMetadata ClassMetadataForReflectClass(IReflectClass reflectClazz)
+		{
+			ClassMetadata cached = (ClassMetadata)_classMetadataByClass.Get(reflectClazz);
+			if (cached != null)
+			{
+				return cached;
+			}
+			return ReadClassMetadata(reflectClazz);
+		}
+
+		private ClassMetadata ReadClassMetadata(IReflectClass reflectClazz)
+		{
+			ClassMetadata clazz = (ClassMetadata)_classMetadataByBytes.Remove(GetNameBytes(reflectClazz
+				.GetName()));
+			if (clazz == null)
+			{
+				return null;
+			}
+			return ReadClassMetadata(clazz, reflectClazz);
+		}
+
+		internal ClassMetadata ProduceClassMetadata(IReflectClass reflectClazz)
+		{
+			ClassMetadata classMetadata = ClassMetadataForReflectClass(reflectClazz);
+			if (classMetadata != null)
+			{
+				return classMetadata;
+			}
+			ClassMetadata classBeingCreated = (ClassMetadata)_creating.Get(reflectClazz);
+			if (classBeingCreated != null)
+			{
+				return classBeingCreated;
+			}
+			ClassMetadata newClassMetadata = new ClassMetadata(Container(), reflectClazz);
+			_creating.Put(reflectClazz, newClassMetadata);
+			try
+			{
+				if (!CreateClassMetadata(newClassMetadata, reflectClazz))
+				{
+					return null;
+				}
+				// ObjectContainerBase#createClassMetadata may add the ClassMetadata already,
+				// so we have to check again
+				if (!IsRegistered(reflectClazz))
+				{
+					AddClassMetadata(newClassMetadata);
+					_classInits.Process(newClassMetadata);
+				}
+				else
+				{
+					RegisterClassMetadataById(newClassMetadata);
+					if (newClassMetadata.AspectsAreNull())
+					{
+						_classInits.Process(newClassMetadata);
+					}
+				}
+				Container().SetDirtyInSystemTransaction(this);
+			}
+			finally
+			{
+				_creating.Remove(reflectClazz);
+			}
+			return newClassMetadata;
+		}
+
+		private bool IsRegistered(IReflectClass reflectClazz)
+		{
+			return _classMetadataByClass.Get(reflectClazz) != null;
+		}
+
+		internal ClassMetadata ClassMetadataForId(int id)
+		{
+			ClassMetadata classMetadata = (ClassMetadata)_classMetadataByID.Get(id);
+			if (null == classMetadata)
+			{
+				return null;
+			}
+			return ReadClassMetadata(classMetadata, null);
+		}
+
+		public int ClassMetadataIdForName(string name)
+		{
+			ClassMetadata classMetadata = (ClassMetadata)_classMetadataByBytes.Get(GetNameBytes
+				(name));
+			if (classMetadata == null)
+			{
+				classMetadata = FindInitializedClassByName(name);
+			}
+			if (classMetadata != null)
+			{
+				return classMetadata.GetID();
+			}
+			return 0;
+		}
+
+		public ClassMetadata GetClassMetadata(string name)
+		{
+			ClassMetadata classMetadata = (ClassMetadata)_classMetadataByBytes.Remove(GetNameBytes
+				(name));
+			if (classMetadata == null)
+			{
+				classMetadata = FindInitializedClassByName(name);
+			}
+			if (classMetadata != null)
+			{
+				classMetadata = ReadClassMetadata(classMetadata, null);
+			}
+			return classMetadata;
+		}
+
+		private ClassMetadata FindInitializedClassByName(string name)
+		{
+			ClassMetadata classMetadata = (ClassMetadata)_classMetadataByName.Get(name);
+			if (classMetadata != null)
+			{
+				return classMetadata;
+			}
+			ClassMetadataIterator i = Iterator();
+			while (i.MoveNext())
+			{
+				classMetadata = (ClassMetadata)i.Current;
+				if (name.Equals(classMetadata.GetName()))
+				{
+					_classMetadataByName.Put(name, classMetadata);
+					return classMetadata;
+				}
+			}
+			return null;
+		}
+
+		public int GetClassMetadataID(string name)
+		{
+			ClassMetadata clazz = (ClassMetadata)_classMetadataByBytes.Get(GetNameBytes(name)
+				);
+			if (clazz != null)
+			{
+				return clazz.GetID();
+			}
+			return 0;
+		}
+
+		internal byte[] GetNameBytes(string name)
+		{
+			return AsBytes(ResolveAliasRuntimeName(name));
+		}
+
+		private string ResolveAliasRuntimeName(string name)
+		{
+			return Container().ConfigImpl.ResolveAliasRuntimeName(name);
+		}
+
+		public void InitOnUp(Transaction systemTrans)
+		{
+			_classMetadataCreationDepth++;
+			systemTrans.Container().ShowInternalClasses(true);
+			try
+			{
+				IEnumerator i = _classes.GetEnumerator();
+				while (i.MoveNext())
+				{
+					((ClassMetadata)i.Current).InitOnUp(systemTrans);
+				}
+			}
+			finally
+			{
+				systemTrans.Container().ShowInternalClasses(false);
+				_classMetadataCreationDepth--;
+			}
+			InitClassMetadataOnUp();
+		}
+
+		internal void InitTables(int size)
+		{
+			_classes = new Collection4();
+			_classMetadataByBytes = new Hashtable4(size);
+			if (size < 16)
+			{
+				size = 16;
+			}
+			_classMetadataByClass = new Hashtable4(size);
+			_classMetadataByName = new Hashtable4(size);
+			_classMetadataByID = new Hashtable4(size);
+			_creating = new Hashtable4(1);
+		}
+
+		private void InitClassMetadataOnUp()
+		{
+			if (_classMetadataCreationDepth != 0)
+			{
+				return;
+			}
+			ClassMetadata clazz = (ClassMetadata)_initClassMetadataOnUp.Next();
+			while (clazz != null)
+			{
+				clazz.InitOnUp(_systemTransaction);
+				clazz = (ClassMetadata)_initClassMetadataOnUp.Next();
+			}
+		}
+
+		public ClassMetadataIterator Iterator()
+		{
+			return new ClassMetadataIterator(this, new ArrayIterator4(_classes.ToArray()));
+		}
+
+		private class ClassIDIterator : MappingIterator
+		{
+			public ClassIDIterator(Collection4 classes) : base(classes.GetEnumerator())
+			{
+			}
+
+			protected override object Map(object current)
+			{
+				return ((ClassMetadata)current).GetID();
+			}
+		}
+
+		public IEnumerator Ids()
+		{
+			return new ClassMetadataRepository.ClassIDIterator(_classes);
+		}
+
+		public override int OwnLength()
+		{
+			return Const4.ObjectLength + Const4.IntLength + (_classes.Size() * Const4.IdLength
+				);
+		}
+
+		internal void Purge()
+		{
+			IEnumerator i = _classes.GetEnumerator();
+			while (i.MoveNext())
+			{
+				((ClassMetadata)i.Current).Purge();
+			}
+		}
+
+		public sealed override void ReadThis(Transaction trans, ByteArrayBuffer buffer)
+		{
+			int classCount = buffer.ReadInt();
+			InitTables(classCount);
+			ObjectContainerBase container = Container();
+			int[] ids = ReadMetadataIds(buffer, classCount);
+			ByteArrayBuffer[] metadataSlots = container.ReadSlotBuffers(trans, ids);
+			for (int i = 0; i < classCount; ++i)
+			{
+				ClassMetadata classMetadata = new ClassMetadata(container, null);
+				classMetadata.SetID(ids[i]);
+				_classes.Add(classMetadata);
+				_classMetadataByID.Put(ids[i], classMetadata);
+				byte[] name = classMetadata.ReadName1(trans, metadataSlots[i]);
+				if (name != null)
+				{
+					_classMetadataByBytes.Put(name, classMetadata);
+				}
+			}
+			ApplyReadAs();
+		}
+
+		private int[] ReadMetadataIds(ByteArrayBuffer buffer, int classCount)
+		{
+			int[] ids = new int[classCount];
+			for (int i = 0; i < classCount; ++i)
+			{
+				ids[i] = buffer.ReadInt();
+			}
+			return ids;
+		}
+
+		internal Hashtable4 ClassByBytes()
+		{
+			return _classMetadataByBytes;
+		}
+
+		private void ApplyReadAs()
+		{
+			Hashtable4 readAs = Container().ConfigImpl.ReadAs();
+			IEnumerator i = readAs.Iterator();
+			while (i.MoveNext())
+			{
+				IEntry4 entry = (IEntry4)i.Current;
+				string dbName = (string)entry.Key();
+				string useName = (string)entry.Value();
+				byte[] dbbytes = GetNameBytes(dbName);
+				byte[] useBytes = GetNameBytes(useName);
+				if (ClassByBytes().Get(useBytes) == null)
+				{
+					ClassMetadata clazz = (ClassMetadata)ClassByBytes().Get(dbbytes);
+					if (clazz != null)
+					{
+						clazz.i_nameBytes = useBytes;
+						clazz.SetConfig(ConfigClass(dbName));
+						ClassByBytes().Remove(dbbytes);
+						ClassByBytes().Put(useBytes, clazz);
+					}
+				}
+			}
+		}
+
+		private Config4Class ConfigClass(string name)
+		{
+			return Container().ConfigImpl.ConfigClass(name);
+		}
+
+		public ClassMetadata ReadClassMetadata(ClassMetadata classMetadata, IReflectClass
+			 clazz)
+		{
+			if (classMetadata == null)
+			{
+				throw new ArgumentNullException();
+			}
+			if (!classMetadata.StateUnread())
+			{
+				return classMetadata;
+			}
+			_classMetadataCreationDepth++;
+			try
+			{
+				classMetadata.CreateConfigAndConstructor(_classMetadataByBytes, clazz);
+				IReflectClass claxx = classMetadata.ClassReflector();
+				if (claxx != null)
+				{
+					_classMetadataByClass.Put(claxx, classMetadata);
+					classMetadata.ReadThis();
+					classMetadata.CheckChanges();
+					_initClassMetadataOnUp.Add(classMetadata);
+				}
+			}
+			finally
+			{
+				_classMetadataCreationDepth--;
+			}
+			InitClassMetadataOnUp();
+			return classMetadata;
+		}
+
+		public void CheckAllClassChanges()
+		{
+			IEnumerator i = _classMetadataByID.Keys();
+			while (i.MoveNext())
+			{
+				int classMetadataID = ((int)i.Current);
+				ClassMetadataForId(classMetadataID);
+			}
+		}
+
+		public void RefreshClasses()
+		{
+			ClassMetadataRepository rereader = new ClassMetadataRepository(_systemTransaction
+				);
+			rereader._id = _id;
+			rereader.Read(Container().SystemTransaction());
+			IEnumerator i = rereader._classes.GetEnumerator();
+			while (i.MoveNext())
+			{
+				ClassMetadata clazz = (ClassMetadata)i.Current;
+				RefreshClass(clazz);
+			}
+			i = _classes.GetEnumerator();
+			while (i.MoveNext())
+			{
+				ClassMetadata clazz = (ClassMetadata)i.Current;
+				clazz.Refresh();
+			}
+		}
+
+		private void RefreshClass(ClassMetadata clazz)
+		{
+			if (_classMetadataByID.Get(clazz.GetID()) == null)
+			{
+				_classes.Add(clazz);
+				_classMetadataByID.Put(clazz.GetID(), clazz);
+				RefreshClassCache(clazz, null);
+			}
+		}
+
+		public void RefreshClassCache(ClassMetadata clazz, IReflectClass oldReflector)
+		{
+			if (clazz.StateUnread())
+			{
+				_classMetadataByBytes.Put(clazz.ReadName(_systemTransaction), clazz);
+			}
+			else
+			{
+				if (oldReflector != null)
+				{
+					_classMetadataByClass.Remove(oldReflector);
+				}
+				_classMetadataByClass.Put(clazz.ClassReflector(), clazz);
+			}
+		}
+
+		internal void ReReadClassMetadata(ClassMetadata clazz)
+		{
+			if (clazz != null)
+			{
+				ReReadClassMetadata(clazz._ancestor);
+				clazz.ReadName(_systemTransaction);
+				clazz.ForceRead();
+				clazz.SetStateClean();
+				clazz.BitFalse(Const4.CheckedChanges);
+				clazz.BitFalse(Const4.Reading);
+				clazz.BitFalse(Const4.Continue);
+				clazz.BitFalse(Const4.Dead);
+				clazz.CheckChanges();
+			}
+		}
+
+		public IStoredClass[] StoredClasses()
+		{
+			EnsureAllClassesRead();
+			IStoredClass[] sclasses = new IStoredClass[_classes.Size()];
+			_classes.ToArray(sclasses);
+			return sclasses;
+		}
+
+		public void WriteAllClasses()
+		{
+			Collection4 deadClasses = new Collection4();
+			IStoredClass[] storedClasses = StoredClasses();
+			for (int i = 0; i < storedClasses.Length; i++)
+			{
+				ClassMetadata clazz = (ClassMetadata)storedClasses[i];
+				clazz.SetStateDirty();
+				if (clazz.StateDead())
+				{
+					deadClasses.Add(clazz);
+					clazz.SetStateOK();
+				}
+			}
+			for (int i = 0; i < storedClasses.Length; i++)
+			{
+				ClassMetadata clazz = (ClassMetadata)storedClasses[i];
+				clazz.Write(_systemTransaction);
+			}
+			IEnumerator it = deadClasses.GetEnumerator();
+			while (it.MoveNext())
+			{
+				((ClassMetadata)it.Current).SetStateDead();
+			}
+		}
+
+		public override void WriteThis(Transaction trans, ByteArrayBuffer buffer)
+		{
+			buffer.WriteInt(_classes.Size());
+			IEnumerator i = _classes.GetEnumerator();
+			while (i.MoveNext())
+			{
+				buffer.WriteIDOf(trans, i.Current);
+			}
+		}
+
+		public override string ToString()
+		{
+			string str = "Active:\n";
+			IEnumerator i = _classes.GetEnumerator();
+			while (i.MoveNext())
+			{
+				ClassMetadata clazz = (ClassMetadata)i.Current;
+				str += clazz.GetID() + " " + clazz + "\n";
+			}
+			return str;
+		}
+
+		internal ObjectContainerBase Container()
+		{
+			return _systemTransaction.Container();
+		}
+
+		public override void SetID(int id)
+		{
+			if (Container().IsClient)
+			{
+				base.SetID(id);
+				return;
+			}
+			if (_id == 0)
+			{
+				SystemData().ClassCollectionID(id);
+			}
+			base.SetID(id);
+		}
+
+		private SystemData SystemData()
+		{
+			return LocalSystemTransaction().LocalContainer().SystemData();
+		}
+
+		private LocalTransaction LocalSystemTransaction()
+		{
+			return ((LocalTransaction)_systemTransaction);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Classindex/AbstractClassIndexStrategy.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Classindex/AbstractClassIndexStrategy.cs
new file mode 100644
index 0000000..0213e36
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Classindex/AbstractClassIndexStrategy.cs
@@ -0,0 +1,82 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Classindex;
+
+namespace Db4objects.Db4o.Internal.Classindex
+{
+	/// <exclude></exclude>
+	public abstract class AbstractClassIndexStrategy : IClassIndexStrategy
+	{
+		protected readonly ClassMetadata _classMetadata;
+
+		public AbstractClassIndexStrategy(ClassMetadata classMetadata)
+		{
+			_classMetadata = classMetadata;
+		}
+
+		protected virtual int ClassMetadataID()
+		{
+			return _classMetadata.GetID();
+		}
+
+		public virtual int OwnLength()
+		{
+			return Const4.IdLength;
+		}
+
+		protected abstract void InternalAdd(Transaction trans, int id);
+
+		public void Add(Transaction trans, int id)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.AddToClassIndex.Log(id);
+			}
+			CheckId(id);
+			InternalAdd(trans, id);
+		}
+
+		protected abstract void InternalRemove(Transaction ta, int id);
+
+		public void Remove(Transaction ta, int id)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.RemoveFromClassIndex.Log(id);
+			}
+			CheckId(id);
+			InternalRemove(ta, id);
+		}
+
+		private void CheckId(int id)
+		{
+		}
+
+		public abstract IEnumerator AllSlotIDs(Transaction arg1);
+
+		public abstract void DefragIndex(DefragmentContextImpl arg1);
+
+		public abstract void DefragReference(ClassMetadata arg1, DefragmentContextImpl arg2
+			, int arg3);
+
+		public abstract void DontDelete(Transaction arg1, int arg2);
+
+		public abstract int EntryCount(Transaction arg1);
+
+		public abstract int Id();
+
+		public abstract void Initialize(ObjectContainerBase arg1);
+
+		public abstract void Purge();
+
+		public abstract void Read(ObjectContainerBase arg1, int arg2);
+
+		public abstract void TraverseAll(Transaction arg1, IVisitor4 arg2);
+
+		public abstract int Write(Transaction arg1);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Classindex/BTreeClassIndexStrategy.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Classindex/BTreeClassIndexStrategy.cs
new file mode 100644
index 0000000..05aeff4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Classindex/BTreeClassIndexStrategy.cs
@@ -0,0 +1,160 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Classindex;
+using Db4objects.Db4o.Internal.References;
+
+namespace Db4objects.Db4o.Internal.Classindex
+{
+	/// <exclude></exclude>
+	public class BTreeClassIndexStrategy : AbstractClassIndexStrategy
+	{
+		private BTree _btreeIndex;
+
+		public BTreeClassIndexStrategy(ClassMetadata classMetadata) : base(classMetadata)
+		{
+		}
+
+		public virtual BTree Btree()
+		{
+			return _btreeIndex;
+		}
+
+		public override int EntryCount(Transaction ta)
+		{
+			return _btreeIndex != null ? _btreeIndex.Size(ta) : 0;
+		}
+
+		public override void Initialize(ObjectContainerBase stream)
+		{
+			CreateBTreeIndex(stream, 0);
+		}
+
+		public override void Purge()
+		{
+		}
+
+		public override void Read(ObjectContainerBase stream, int indexID)
+		{
+			ReadBTreeIndex(stream, indexID);
+		}
+
+		public override int Write(Transaction trans)
+		{
+			if (_btreeIndex == null)
+			{
+				return 0;
+			}
+			_btreeIndex.Write(trans);
+			return _btreeIndex.GetID();
+		}
+
+		public override void TraverseAll(Transaction ta, IVisitor4 command)
+		{
+			if (_btreeIndex != null)
+			{
+				_btreeIndex.TraverseKeys(ta, command);
+			}
+		}
+
+		private void CreateBTreeIndex(ObjectContainerBase stream, int btreeID)
+		{
+			if (stream.IsClient)
+			{
+				return;
+			}
+			_btreeIndex = ((LocalObjectContainer)stream).CreateBTreeClassIndex(btreeID);
+			_btreeIndex.SetRemoveListener(new _IVisitor4_61(this));
+		}
+
+		private sealed class _IVisitor4_61 : IVisitor4
+		{
+			public _IVisitor4_61(BTreeClassIndexStrategy _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Visit(object obj)
+			{
+				this._enclosing.RemoveId((TransactionContext)obj);
+			}
+
+			private readonly BTreeClassIndexStrategy _enclosing;
+		}
+
+		private void RemoveId(TransactionContext context)
+		{
+			IReferenceSystem referenceSystem = context._transaction.ReferenceSystem();
+			ObjectReference reference = referenceSystem.ReferenceForId(((int)context._object)
+				);
+			if (reference != null)
+			{
+				referenceSystem.RemoveReference(reference);
+			}
+		}
+
+		private void ReadBTreeIndex(ObjectContainerBase stream, int indexId)
+		{
+			if (!stream.IsClient && _btreeIndex == null)
+			{
+				CreateBTreeIndex(stream, indexId);
+			}
+		}
+
+		protected override void InternalAdd(Transaction trans, int id)
+		{
+			_btreeIndex.Add(trans, id);
+		}
+
+		protected override void InternalRemove(Transaction ta, int id)
+		{
+			_btreeIndex.Remove(ta, id);
+		}
+
+		public override void DontDelete(Transaction transaction, int id)
+		{
+		}
+
+		public override void DefragReference(ClassMetadata classMetadata, DefragmentContextImpl
+			 context, int classIndexID)
+		{
+			int newID = -classIndexID;
+			context.WriteInt(newID);
+		}
+
+		public override int Id()
+		{
+			return _btreeIndex.GetID();
+		}
+
+		public override IEnumerator AllSlotIDs(Transaction trans)
+		{
+			return _btreeIndex.AllNodeIds(trans);
+		}
+
+		public override void DefragIndex(DefragmentContextImpl context)
+		{
+			_btreeIndex.DefragIndex(context);
+		}
+
+		public static BTree Btree(ClassMetadata clazz)
+		{
+			IClassIndexStrategy index = clazz.Index();
+			if (!(index is Db4objects.Db4o.Internal.Classindex.BTreeClassIndexStrategy))
+			{
+				throw new InvalidOperationException();
+			}
+			return ((Db4objects.Db4o.Internal.Classindex.BTreeClassIndexStrategy)index).Btree
+				();
+		}
+
+		public static IEnumerator Iterate(ClassMetadata clazz, Transaction trans)
+		{
+			return Btree(clazz).AsRange(trans).Keys();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Classindex/IClassIndexStrategy.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Classindex/IClassIndexStrategy.cs
new file mode 100644
index 0000000..91fface
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Classindex/IClassIndexStrategy.cs
@@ -0,0 +1,45 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Classindex
+{
+	/// <exclude></exclude>
+	public interface IClassIndexStrategy
+	{
+		void Initialize(ObjectContainerBase stream);
+
+		void Read(ObjectContainerBase stream, int indexID);
+
+		int Write(Transaction transaction);
+
+		void Add(Transaction transaction, int id);
+
+		void Remove(Transaction transaction, int id);
+
+		int EntryCount(Transaction transaction);
+
+		int OwnLength();
+
+		void Purge();
+
+		/// <summary>Traverses all index entries (java.lang.Integer references).</summary>
+		/// <remarks>Traverses all index entries (java.lang.Integer references).</remarks>
+		void TraverseAll(Transaction transaction, IVisitor4 command);
+
+		void DontDelete(Transaction transaction, int id);
+
+		IEnumerator AllSlotIDs(Transaction trans);
+
+		// FIXME: Why is this never called?
+		void DefragReference(ClassMetadata classMetadata, DefragmentContextImpl context, 
+			int classIndexID);
+
+		int Id();
+
+		// FIXME: Why is this never called?
+		void DefragIndex(DefragmentContextImpl context);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Collections/BigSet.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Collections/BigSet.cs
new file mode 100644
index 0000000..6ce5606
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Collections/BigSet.cs
@@ -0,0 +1,238 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Collections;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Collections
+{
+	/// <exclude></exclude>
+	public partial class BigSet<E> : Db4objects.Db4o.Collections.ISet<E>, IBigSetPersistence
+	{
+		private Db4objects.Db4o.Internal.Btree.BTree _bTree;
+
+		private Db4objects.Db4o.Internal.Transaction _transaction;
+
+		public BigSet(LocalObjectContainer db)
+		{
+			if (db == null)
+			{
+				return;
+			}
+			_transaction = db.Transaction;
+			_bTree = BTreeManager().NewBTree();
+		}
+
+		private ObjectContainerBase Container()
+		{
+			return Transaction().Container();
+		}
+
+		public virtual bool Add(E obj)
+		{
+			lock (Lock())
+			{
+				int id = GetID(obj);
+				if (id == 0)
+				{
+					Add(Store(obj));
+					return true;
+				}
+				if (Contains(id))
+				{
+					return false;
+				}
+				Add(id);
+				return true;
+			}
+		}
+
+		private int Store(E obj)
+		{
+			return Container().Store(_transaction, obj, Container().UpdateDepthProvider().Unspecified
+				(NullModifiedObjectQuery.Instance));
+		}
+
+		private void Add(int id)
+		{
+			BTreeForUpdate().Add(_transaction, id);
+		}
+
+		private int GetID(object obj)
+		{
+			return (int)Container().GetID(obj);
+		}
+
+		public virtual bool AddAll(IEnumerable<E> iterable)
+		{
+			bool result = false;
+			foreach (E element in iterable)
+			{
+				if (Add(element))
+				{
+					result = true;
+				}
+			}
+			return result;
+		}
+
+		public virtual void Clear()
+		{
+			lock (Lock())
+			{
+				BTreeForUpdate().Clear(Transaction());
+			}
+		}
+
+		public virtual bool Contains(object obj)
+		{
+			int id = GetID(obj);
+			if (id == 0)
+			{
+				return false;
+			}
+			return Contains(id);
+		}
+
+		private bool Contains(int id)
+		{
+			lock (Lock())
+			{
+				IBTreeRange range = BTree().SearchRange(Transaction(), id);
+				return !range.IsEmpty();
+			}
+		}
+
+		public virtual bool IsEmpty
+		{
+			get
+			{
+				return Count == 0;
+			}
+		}
+
+		private IEnumerator BTreeIterator()
+		{
+			return new SynchronizedIterator4(BTree().Iterator(Transaction()), Lock());
+		}
+
+		public virtual bool Remove(object obj)
+		{
+			lock (Lock())
+			{
+				if (!Contains(obj))
+				{
+					return false;
+				}
+				int id = GetID(obj);
+				BTreeForUpdate().Remove(Transaction(), id);
+				return true;
+			}
+		}
+
+		public virtual int Count
+		{
+			get
+			{
+				lock (Lock())
+				{
+					return BTree().Size(Transaction());
+				}
+			}
+		}
+
+		public virtual object[] ToArray()
+		{
+			throw new NotSupportedException();
+		}
+
+		public virtual T[] ToArray<T>(T[] a)
+		{
+			throw new NotSupportedException();
+		}
+
+		public virtual void Write(IWriteContext context)
+		{
+			int id = BTree().GetID();
+			if (id == 0)
+			{
+				BTree().Write(SystemTransaction());
+			}
+			context.WriteInt(BTree().GetID());
+		}
+
+		public virtual void Read(IReadContext context)
+		{
+			int id = context.ReadInt();
+			if (_bTree != null)
+			{
+				AssertCurrentBTreeId(id);
+				return;
+			}
+			_transaction = context.Transaction();
+			_bTree = BTreeManager().ProduceBTree(id);
+		}
+
+		private BigSetBTreeManager BTreeManager()
+		{
+			return new BigSetBTreeManager(_transaction);
+		}
+
+		private void AssertCurrentBTreeId(int id)
+		{
+			if (id != _bTree.GetID())
+			{
+				throw new InvalidOperationException();
+			}
+		}
+
+		private Db4objects.Db4o.Internal.Transaction Transaction()
+		{
+			return _transaction;
+		}
+
+		private Db4objects.Db4o.Internal.Transaction SystemTransaction()
+		{
+			return Container().SystemTransaction();
+		}
+
+		public virtual void Invalidate()
+		{
+			_bTree = null;
+		}
+
+		private Db4objects.Db4o.Internal.Btree.BTree BTree()
+		{
+			if (_bTree == null)
+			{
+				throw new InvalidOperationException();
+			}
+			return _bTree;
+		}
+
+		private Db4objects.Db4o.Internal.Btree.BTree BTreeForUpdate()
+		{
+			Db4objects.Db4o.Internal.Btree.BTree bTree = BTree();
+			BTreeManager().EnsureIsManaged(bTree);
+			return bTree;
+		}
+
+		private object Element(int id)
+		{
+			object obj = Container().GetByID(Transaction(), id);
+			Container().Activate(obj);
+			return obj;
+		}
+
+		private object Lock()
+		{
+			return Container().Lock();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Collections/BigSetBTreeManager.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Collections/BigSetBTreeManager.cs
new file mode 100644
index 0000000..3a93176
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Collections/BigSetBTreeManager.cs
@@ -0,0 +1,100 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Handlers;
+
+namespace Db4objects.Db4o.Internal.Collections
+{
+	/// <exclude></exclude>
+	public class BigSetBTreeManager
+	{
+		private sealed class _TransactionLocal_14 : TransactionLocal
+		{
+			public _TransactionLocal_14()
+			{
+			}
+
+			public override object InitialValueFor(Transaction transaction)
+			{
+				return new Hashtable();
+			}
+		}
+
+		private static readonly TransactionLocal _bTreesInTransaction = new _TransactionLocal_14
+			();
+
+		private readonly Transaction _transaction;
+
+		internal BigSetBTreeManager(Transaction transaction)
+		{
+			_transaction = transaction;
+		}
+
+		internal virtual BTree ProduceBTree(int id)
+		{
+			AssertValidBTreeId(id);
+			BTree bTree = ExistingBTreeInTransactionWith(id);
+			if (null == bTree)
+			{
+				bTree = NewBTreeWithId(id);
+				RegisterBTreeInTransaction(bTree);
+			}
+			return bTree;
+		}
+
+		internal virtual BTree NewBTree()
+		{
+			BTree bTree = NewBTreeWithId(0);
+			bTree.Write(SystemTransaction());
+			RegisterBTreeInTransaction(bTree);
+			return bTree;
+		}
+
+		internal virtual void EnsureIsManaged(BTree tree)
+		{
+			RegisterBTreeInTransaction(tree);
+		}
+
+		private BTree NewBTreeWithId(int id)
+		{
+			return NewBTreeWithId(id, SystemTransaction());
+		}
+
+		private Transaction SystemTransaction()
+		{
+			return _transaction.SystemTransaction();
+		}
+
+		private static BTree NewBTreeWithId(int id, Transaction systemTransaction)
+		{
+			return new BTree(systemTransaction, id, new IntHandler());
+		}
+
+		private static void AssertValidBTreeId(int id)
+		{
+			if (id <= 0)
+			{
+				throw new ArgumentException();
+			}
+		}
+
+		private void RegisterBTreeInTransaction(BTree tree)
+		{
+			AssertValidBTreeId(tree.GetID());
+			BTreesIn(_transaction)[tree.GetID()] = tree;
+		}
+
+		private BTree ExistingBTreeInTransactionWith(int id)
+		{
+			return ((BTree)BTreesIn(_transaction)[id]);
+		}
+
+		private static IDictionary BTreesIn(Transaction transaction)
+		{
+			return ((IDictionary)transaction.Get(_bTreesInTransaction).value);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Collections/BigSetTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Collections/BigSetTypeHandler.cs
new file mode 100644
index 0000000..4f7c1a7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Collections/BigSetTypeHandler.cs
@@ -0,0 +1,102 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Defragment;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Collections;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Collections
+{
+	/// <exclude></exclude>
+	public class BigSetTypeHandler : IReferenceTypeHandler, ICascadingTypeHandler
+	{
+		public virtual void Defragment(IDefragmentContext context)
+		{
+			int pos = context.Offset();
+			int id = context.ReadInt();
+			BTree bTree = NewBTree(context, id);
+			DefragmentServicesImpl services = (DefragmentServicesImpl)context.Services();
+			IDMappingCollector collector = new IDMappingCollector();
+			services.RegisterBTreeIDs(bTree, collector);
+			collector.Flush(services);
+			context.Seek(pos);
+			context.CopyID();
+			bTree.DefragBTree(services);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Delete(IDeleteContext context)
+		{
+			InvalidBigSet(context);
+			int id = context.ReadInt();
+			FreeBTree(context, id);
+		}
+
+		private void InvalidBigSet(IDeleteContext context)
+		{
+			IBigSetPersistence bigSet = (IBigSetPersistence)context.Transaction().ObjectForIdFromCache
+				(context.ObjectId());
+			if (bigSet != null)
+			{
+				bigSet.Invalidate();
+			}
+		}
+
+		private void FreeBTree(IDeleteContext context, int id)
+		{
+			BTree bTree = NewBTree(context, id);
+			bTree.Free(SystemTransaction(context));
+			bTree = null;
+		}
+
+		private static LocalTransaction SystemTransaction(IContext context)
+		{
+			return (LocalTransaction)context.Transaction().SystemTransaction();
+		}
+
+		private BTree NewBTree(IContext context, int id)
+		{
+			return new BTree(SystemTransaction(context), id, new IDHandler());
+		}
+
+		public virtual void Write(IWriteContext context, object obj)
+		{
+			IBigSetPersistence bigSet = (IBigSetPersistence)obj;
+			bigSet.Write(context);
+		}
+
+		public virtual IPreparedComparison PrepareComparison(IContext context, object obj
+			)
+		{
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		public virtual void Activate(IReferenceActivationContext context)
+		{
+			IBigSetPersistence bigSet = (IBigSetPersistence)context.PersistentObject();
+			bigSet.Read(context);
+		}
+
+		public virtual void CascadeActivation(IActivationContext context)
+		{
+		}
+
+		// TODO Auto-generated method stub
+		public virtual void CollectIDs(QueryingReadContext context)
+		{
+		}
+
+		// TODO Auto-generated method stub
+		public virtual ITypeHandler4 ReadCandidateHandler(QueryingReadContext context)
+		{
+			// TODO Auto-generated method stub
+			return null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Collections/IBigSetPersistence.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Collections/IBigSetPersistence.cs
new file mode 100644
index 0000000..d4a16f1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Collections/IBigSetPersistence.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Collections
+{
+	public interface IBigSetPersistence
+	{
+		void Write(IWriteContext context);
+
+		void Read(IReadContext context);
+
+		void Invalidate();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/CommitTimestampFieldMetadata.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/CommitTimestampFieldMetadata.cs
new file mode 100644
index 0000000..c5e1bdc
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/CommitTimestampFieldMetadata.cs
@@ -0,0 +1,94 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class CommitTimestampFieldMetadata : VirtualFieldMetadata
+	{
+		internal CommitTimestampFieldMetadata() : base(Handlers4.LongId, new LongHandler(
+			))
+		{
+			SetName(VirtualField.CommitTimestamp);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.FieldIndexException"></exception>
+		public override void AddFieldIndex(ObjectIdContextImpl context)
+		{
+		}
+
+		public override void AddIndexEntry(Transaction trans, int parentID, object indexEntry
+			)
+		{
+		}
+
+		public override void RemoveIndexEntry(Transaction trans, int parentID, object indexEntry
+			)
+		{
+		}
+
+		public override void Delete(DeleteContextImpl context, bool isUpdate)
+		{
+		}
+
+		internal override void Instantiate1(ObjectReferenceContext context)
+		{
+		}
+
+		internal override void Marshall(Transaction trans, ObjectReference @ref, IWriteBuffer
+			 buffer, bool isMigrating, bool isNew)
+		{
+		}
+
+		public override int LinkLength()
+		{
+			return 0;
+		}
+
+		public override void DefragAspect(IDefragmentContext context)
+		{
+		}
+
+		internal override void MarshallIgnore(IWriteBuffer buffer)
+		{
+		}
+
+		public override void Activate(UnmarshallingContext context)
+		{
+		}
+
+		// do nothing.
+		public override BTree GetIndex(Transaction trans)
+		{
+			return ((LocalTransaction)trans.SystemTransaction()).CommitTimestampSupport().TimestampToId
+				();
+		}
+
+		public override bool HasIndex()
+		{
+			return true;
+		}
+
+		protected override IFieldIndexKey CreateFieldIndexKey(int parentID, object indexEntry
+			)
+		{
+			return new CommitTimestampSupport.TimestampEntry(parentID, ((long)indexEntry));
+		}
+
+		internal int counter = 0;
+
+		public override object Read(IObjectIdContext context)
+		{
+			int objectId = context.ObjectId();
+			long version = context.Transaction().SystemTransaction().VersionForId(objectId);
+			return version;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/CommitTimestampSupport.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/CommitTimestampSupport.cs
new file mode 100644
index 0000000..e26c7bb
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/CommitTimestampSupport.cs
@@ -0,0 +1,270 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Events;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal
+{
+	public class CommitTimestampSupport
+	{
+		private BTree _idToTimestamp;
+
+		private BTree _timestampToId;
+
+		private readonly LocalObjectContainer _container;
+
+		public CommitTimestampSupport(LocalObjectContainer container)
+		{
+			_container = container;
+		}
+
+		public virtual void EnsureInitialized()
+		{
+			IdToTimestamp();
+		}
+
+		public virtual BTree IdToTimestamp()
+		{
+			if (_idToTimestamp != null)
+			{
+				return _idToTimestamp;
+			}
+			if (!_container.Config().GenerateCommitTimestamps().DefiniteYes())
+			{
+				return null;
+			}
+			Initialize();
+			return _idToTimestamp;
+		}
+
+		public virtual BTree TimestampToId()
+		{
+			if (_timestampToId != null)
+			{
+				return _timestampToId;
+			}
+			if (!_container.Config().GenerateCommitTimestamps().DefiniteYes())
+			{
+				return null;
+			}
+			Initialize();
+			return _timestampToId;
+		}
+
+		private void Initialize()
+		{
+			int idToTimestampIndexId = _container.SystemData().IdToTimestampIndexId();
+			int timestampToIdIndexId = _container.SystemData().TimestampToIdIndexId();
+			_idToTimestamp = new BTree(_container.SystemTransaction(), idToTimestampIndexId, 
+				new CommitTimestampSupport.TimestampEntryById());
+			_timestampToId = new BTree(_container.SystemTransaction(), timestampToIdIndexId, 
+				new CommitTimestampSupport.IdEntryByTimestamp());
+			if (idToTimestampIndexId != _idToTimestamp.GetID())
+			{
+				StoreBtreesIds();
+			}
+			EventRegistryFactory.ForObjectContainer(_container).Committing += new System.EventHandler<Db4objects.Db4o.Events.CommitEventArgs>
+				(new _IEventListener4_69(this).OnEvent);
+		}
+
+		private sealed class _IEventListener4_69
+		{
+			public _IEventListener4_69(CommitTimestampSupport _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void OnEvent(object sender, Db4objects.Db4o.Events.CommitEventArgs args)
+			{
+				LocalTransaction trans = (LocalTransaction)((CommitEventArgs)args).Transaction();
+				long transactionTimestamp = trans.Timestamp();
+				long commitTimestamp = (transactionTimestamp > 0) ? transactionTimestamp : this._enclosing
+					._container.GenerateTimeStampId();
+				Transaction sysTrans = trans.SystemTransaction();
+				this.AddTimestamp(sysTrans, ((CommitEventArgs)args).Added.GetEnumerator(), commitTimestamp
+					);
+				this.AddTimestamp(sysTrans, ((CommitEventArgs)args).Updated.GetEnumerator(), commitTimestamp
+					);
+				this.AddTimestamp(sysTrans, ((CommitEventArgs)args).Deleted.GetEnumerator(), 0);
+			}
+
+			private void AddTimestamp(Transaction trans, IEnumerator it, long commitTimestamp
+				)
+			{
+				while (it.MoveNext())
+				{
+					IObjectInfo objInfo = (IObjectInfo)it.Current;
+					CommitTimestampSupport.TimestampEntry te = new CommitTimestampSupport.TimestampEntry
+						((int)objInfo.GetInternalID(), commitTimestamp);
+					CommitTimestampSupport.TimestampEntry oldEntry = (CommitTimestampSupport.TimestampEntry
+						)this._enclosing._idToTimestamp.Remove(trans, te);
+					if (oldEntry != null)
+					{
+						this._enclosing._timestampToId.Remove(trans, oldEntry);
+					}
+					if (commitTimestamp != 0)
+					{
+						this._enclosing._idToTimestamp.Add(trans, te);
+						this._enclosing._timestampToId.Add(trans, te);
+					}
+				}
+			}
+
+			private readonly CommitTimestampSupport _enclosing;
+		}
+
+		private void StoreBtreesIds()
+		{
+			_container.SystemData().IdToTimestampIndexId(_idToTimestamp.GetID());
+			_container.SystemData().TimestampToIdIndexId(_timestampToId.GetID());
+			_container.GetFileHeader().WriteVariablePart(_container);
+		}
+
+		public class TimestampEntry : IFieldIndexKey
+		{
+			public readonly int objectId;
+
+			public readonly long commitTimestamp;
+
+			public override string ToString()
+			{
+				return "TimestampEntry [objectId=" + objectId + ", commitTimestamp=" + commitTimestamp
+					 + "]";
+			}
+
+			public TimestampEntry(int objectId, long commitTimestamp)
+			{
+				this.objectId = objectId;
+				this.commitTimestamp = commitTimestamp;
+			}
+
+			public virtual int ParentID()
+			{
+				return objectId;
+			}
+
+			public virtual long GetCommitTimestamp()
+			{
+				return commitTimestamp;
+			}
+
+			public virtual object Value()
+			{
+				return commitTimestamp;
+			}
+		}
+
+		private class TimestampEntryById : IIndexable4
+		{
+			public virtual IPreparedComparison PrepareComparison(IContext context, object first
+				)
+			{
+				return new _IPreparedComparison_139(first);
+			}
+
+			private sealed class _IPreparedComparison_139 : IPreparedComparison
+			{
+				public _IPreparedComparison_139(object first)
+				{
+					this.first = first;
+				}
+
+				public int CompareTo(object second)
+				{
+					return IntHandler.Compare(((CommitTimestampSupport.TimestampEntry)first).objectId
+						, ((CommitTimestampSupport.TimestampEntry)second).objectId);
+				}
+
+				private readonly object first;
+			}
+
+			public virtual int LinkLength()
+			{
+				return Const4.IntLength + Const4.LongLength;
+			}
+
+			public virtual object ReadIndexEntry(IContext context, ByteArrayBuffer reader)
+			{
+				return new CommitTimestampSupport.TimestampEntry(reader.ReadInt(), reader.ReadLong
+					());
+			}
+
+			public virtual void WriteIndexEntry(IContext context, ByteArrayBuffer writer, object
+				 obj)
+			{
+				writer.WriteInt(((CommitTimestampSupport.TimestampEntry)obj).ParentID());
+				writer.WriteLong(((CommitTimestampSupport.TimestampEntry)obj).GetCommitTimestamp(
+					));
+			}
+
+			public virtual void DefragIndexEntry(DefragmentContextImpl context)
+			{
+				// we are storing ids in the btree, so the order will change when the ids change
+				// to properly defrag the btree we need to readd all the entries
+				throw new NotSupportedException();
+			}
+		}
+
+		private sealed class IdEntryByTimestamp : CommitTimestampSupport.TimestampEntryById
+		{
+			public override IPreparedComparison PrepareComparison(IContext context, object first
+				)
+			{
+				return new _IPreparedComparison_168(first);
+			}
+
+			private sealed class _IPreparedComparison_168 : IPreparedComparison
+			{
+				public _IPreparedComparison_168(object first)
+				{
+					this.first = first;
+				}
+
+				public int CompareTo(object second)
+				{
+					int result = LongHandler.Compare(((CommitTimestampSupport.TimestampEntry)first).commitTimestamp
+						, ((CommitTimestampSupport.TimestampEntry)second).commitTimestamp);
+					if (result != 0)
+					{
+						return result;
+					}
+					return IntHandler.Compare(((CommitTimestampSupport.TimestampEntry)first).objectId
+						, ((CommitTimestampSupport.TimestampEntry)second).objectId);
+				}
+
+				private readonly object first;
+			}
+		}
+
+		public virtual long VersionForId(int id)
+		{
+			if (IdToTimestamp() == null || id == 0)
+			{
+				return 0;
+			}
+			CommitTimestampSupport.TimestampEntry te = (CommitTimestampSupport.TimestampEntry
+				)IdToTimestamp().Search(_container.SystemTransaction(), new CommitTimestampSupport.TimestampEntry
+				(id, 0));
+			if (te == null)
+			{
+				return 0;
+			}
+			return te.GetCommitTimestamp();
+		}
+
+		public virtual void Put(Transaction trans, int objectId, long version)
+		{
+			CommitTimestampSupport.TimestampEntry te = new CommitTimestampSupport.TimestampEntry
+				(objectId, version);
+			IdToTimestamp().Add(trans, te);
+			TimestampToId().Add(trans, te);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/CacheConfigurationImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/CacheConfigurationImpl.cs
new file mode 100644
index 0000000..f2b9bee
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/CacheConfigurationImpl.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Config
+{
+	/// <exclude></exclude>
+	public class CacheConfigurationImpl : ICacheConfiguration
+	{
+		private readonly Config4Impl _config;
+
+		public CacheConfigurationImpl(Config4Impl config)
+		{
+			_config = config;
+		}
+
+		[System.ObsoleteAttribute(@"since 7.14 BTrees have their own LRU cache now.")]
+		public virtual int SlotCacheSize
+		{
+			set
+			{
+				int size = value;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/CommonConfigurationImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/CommonConfigurationImpl.cs
new file mode 100644
index 0000000..1dfbe90
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/CommonConfigurationImpl.cs
@@ -0,0 +1,281 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.IO;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Config.Encoding;
+using Db4objects.Db4o.Diagnostic;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Config
+{
+	public class CommonConfigurationImpl : ICommonConfiguration
+	{
+		private readonly Config4Impl _config;
+
+		public CommonConfigurationImpl(Config4Impl config)
+		{
+			_config = config;
+		}
+
+		public virtual int ActivationDepth
+		{
+			get
+			{
+				return _config.ActivationDepth();
+			}
+			set
+			{
+				int depth = value;
+				_config.ActivationDepth(depth);
+			}
+		}
+
+		public virtual void Add(IConfigurationItem configurationItem)
+		{
+			_config.Add(configurationItem);
+		}
+
+		public virtual void AddAlias(IAlias alias)
+		{
+			_config.AddAlias(alias);
+		}
+
+		public virtual void RemoveAlias(IAlias alias)
+		{
+			_config.RemoveAlias(alias);
+		}
+
+		public virtual bool AllowVersionUpdates
+		{
+			set
+			{
+				bool flag = value;
+				_config.AllowVersionUpdates(flag);
+			}
+		}
+
+		public virtual bool AutomaticShutDown
+		{
+			set
+			{
+				bool flag = value;
+				_config.AutomaticShutDown(flag);
+			}
+		}
+
+		public virtual int BTreeNodeSize
+		{
+			set
+			{
+				int size = value;
+				_config.BTreeNodeSize(size);
+			}
+		}
+
+		public virtual bool Callbacks
+		{
+			set
+			{
+				bool flag = value;
+				_config.Callbacks(flag);
+			}
+		}
+
+		public virtual void CallbackMode(CallBackMode mode)
+		{
+			_config.CallbackMode(mode);
+		}
+
+		public virtual bool CallConstructors
+		{
+			set
+			{
+				bool flag = value;
+				_config.CallConstructors(flag);
+			}
+		}
+
+		public virtual bool DetectSchemaChanges
+		{
+			set
+			{
+				bool flag = value;
+				_config.DetectSchemaChanges(flag);
+			}
+		}
+
+		public virtual IDiagnosticConfiguration Diagnostic
+		{
+			get
+			{
+				return _config.Diagnostic();
+			}
+		}
+
+		public virtual bool ExceptionsOnNotStorable
+		{
+			set
+			{
+				bool flag = value;
+				_config.ExceptionsOnNotStorable(flag);
+			}
+		}
+
+		public virtual bool InternStrings
+		{
+			set
+			{
+				bool flag = value;
+				_config.InternStrings(flag);
+			}
+		}
+
+		public virtual void MarkTransient(string attributeName)
+		{
+			_config.MarkTransient(attributeName);
+		}
+
+		public virtual int MessageLevel
+		{
+			set
+			{
+				int level = value;
+				_config.MessageLevel(level);
+			}
+		}
+
+		public virtual IObjectClass ObjectClass(object clazz)
+		{
+			return _config.ObjectClass(clazz);
+		}
+
+		public virtual bool OptimizeNativeQueries
+		{
+			get
+			{
+				return _config.OptimizeNativeQueries();
+			}
+			set
+			{
+				bool optimizeNQ = value;
+				_config.OptimizeNativeQueries(optimizeNQ);
+			}
+		}
+
+		public virtual IQueryConfiguration Queries
+		{
+			get
+			{
+				return _config.Queries();
+			}
+		}
+
+		public virtual void ReflectWith(IReflector reflector)
+		{
+			_config.ReflectWith(reflector);
+		}
+
+		public virtual TextWriter OutStream
+		{
+			set
+			{
+				TextWriter outStream = value;
+				_config.SetOut(outStream);
+			}
+		}
+
+		public virtual IStringEncoding StringEncoding
+		{
+			set
+			{
+				IStringEncoding encoding = value;
+				_config.StringEncoding(encoding);
+			}
+		}
+
+		public virtual bool TestConstructors
+		{
+			set
+			{
+				bool flag = value;
+				_config.TestConstructors(flag);
+			}
+		}
+
+		public virtual int UpdateDepth
+		{
+			set
+			{
+				int depth = value;
+				_config.UpdateDepth(depth);
+			}
+		}
+
+		public virtual bool WeakReferences
+		{
+			set
+			{
+				bool flag = value;
+				_config.WeakReferences(flag);
+			}
+		}
+
+		public virtual int WeakReferenceCollectionInterval
+		{
+			set
+			{
+				int milliseconds = value;
+				_config.WeakReferenceCollectionInterval(milliseconds);
+			}
+		}
+
+		public virtual void RegisterTypeHandler(ITypeHandlerPredicate predicate, ITypeHandler4
+			 typeHandler)
+		{
+			_config.RegisterTypeHandler(predicate, typeHandler);
+		}
+
+		public virtual IEnvironmentConfiguration Environment
+		{
+			get
+			{
+				return new _IEnvironmentConfiguration_139(this);
+			}
+		}
+
+		private sealed class _IEnvironmentConfiguration_139 : IEnvironmentConfiguration
+		{
+			public _IEnvironmentConfiguration_139(CommonConfigurationImpl _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Add(object service)
+			{
+				this._enclosing._config.EnvironmentContributions().Add(service);
+			}
+
+			private readonly CommonConfigurationImpl _enclosing;
+		}
+
+		public virtual void NameProvider(INameProvider provider)
+		{
+			_config.NameProvider(provider);
+		}
+
+		public virtual int MaxStackDepth
+		{
+			get
+			{
+				return _config.MaxStackDepth();
+			}
+			set
+			{
+				int maxStackDepth = value;
+				_config.MaxStackDepth(maxStackDepth);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/Db4oLegacyConfigurationBridge.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/Db4oLegacyConfigurationBridge.cs
new file mode 100644
index 0000000..1eb8082
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/Db4oLegacyConfigurationBridge.cs
@@ -0,0 +1,38 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Config;
+
+namespace Db4objects.Db4o.Internal.Config
+{
+	public class Db4oLegacyConfigurationBridge
+	{
+		public static IEmbeddedConfiguration AsEmbeddedConfiguration(IConfiguration legacy
+			)
+		{
+			return new EmbeddedConfigurationImpl(legacy);
+		}
+
+		public static ICommonConfiguration AsCommonConfiguration(IConfiguration config)
+		{
+			return new CommonConfigurationImpl((Config4Impl)config);
+		}
+
+		public static Config4Impl AsLegacy(object config)
+		{
+			return ((ILegacyConfigurationProvider)config).Legacy();
+		}
+
+		public static IFileConfiguration AsFileConfiguration(IConfiguration config)
+		{
+			return new FileConfigurationImpl((Config4Impl)config);
+		}
+
+		public static IIdSystemConfiguration AsIdSystemConfiguration(IConfiguration config
+			)
+		{
+			return new IdSystemConfigurationImpl((Config4Impl)config);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/EmbeddedConfigurationImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/EmbeddedConfigurationImpl.cs
new file mode 100644
index 0000000..7563fd6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/EmbeddedConfigurationImpl.cs
@@ -0,0 +1,88 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Config;
+
+namespace Db4objects.Db4o.Internal.Config
+{
+	public class EmbeddedConfigurationImpl : IEmbeddedConfiguration, ILegacyConfigurationProvider
+	{
+		private readonly Config4Impl _legacy;
+
+		private IList _configItems;
+
+		public EmbeddedConfigurationImpl(IConfiguration legacy)
+		{
+			_legacy = (Config4Impl)legacy;
+		}
+
+		public virtual ICacheConfiguration Cache
+		{
+			get
+			{
+				return new CacheConfigurationImpl(_legacy);
+			}
+		}
+
+		public virtual IFileConfiguration File
+		{
+			get
+			{
+				return new FileConfigurationImpl(_legacy);
+			}
+		}
+
+		public virtual ICommonConfiguration Common
+		{
+			get
+			{
+				return Db4oLegacyConfigurationBridge.AsCommonConfiguration(Legacy());
+			}
+		}
+
+		public virtual Config4Impl Legacy()
+		{
+			return _legacy;
+		}
+
+		public virtual void AddConfigurationItem(IEmbeddedConfigurationItem configItem)
+		{
+			if (_configItems != null && _configItems.Contains(configItem))
+			{
+				return;
+			}
+			configItem.Prepare(this);
+			if (_configItems == null)
+			{
+				_configItems = new ArrayList();
+			}
+			_configItems.Add(configItem);
+		}
+
+		public virtual void ApplyConfigurationItems(IEmbeddedObjectContainer container)
+		{
+			if (_configItems == null)
+			{
+				return;
+			}
+			for (IEnumerator configItemIter = _configItems.GetEnumerator(); configItemIter.MoveNext
+				(); )
+			{
+				IEmbeddedConfigurationItem configItem = ((IEmbeddedConfigurationItem)configItemIter
+					.Current);
+				configItem.Apply(container);
+			}
+		}
+
+		public virtual IIdSystemConfiguration IdSystem
+		{
+			get
+			{
+				return new IdSystemConfigurationImpl(_legacy);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/FileConfigurationImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/FileConfigurationImpl.cs
new file mode 100644
index 0000000..7c95520
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/FileConfigurationImpl.cs
@@ -0,0 +1,147 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Config
+{
+	internal class FileConfigurationImpl : IFileConfiguration
+	{
+		private readonly Config4Impl _config;
+
+		public FileConfigurationImpl(Config4Impl config)
+		{
+			_config = config;
+		}
+
+		public virtual int BlockSize
+		{
+			set
+			{
+				int bytes = value;
+				_config.BlockSize(bytes);
+			}
+		}
+
+		public virtual int DatabaseGrowthSize
+		{
+			set
+			{
+				int bytes = value;
+				_config.DatabaseGrowthSize(bytes);
+			}
+		}
+
+		public virtual void DisableCommitRecovery()
+		{
+			_config.DisableCommitRecovery();
+		}
+
+		public virtual IFreespaceConfiguration Freespace
+		{
+			get
+			{
+				return _config.Freespace();
+			}
+		}
+
+		public virtual ConfigScope GenerateUUIDs
+		{
+			set
+			{
+				ConfigScope setting = value;
+				_config.GenerateUUIDs(setting);
+			}
+		}
+
+		public virtual ConfigScope GenerateVersionNumbers
+		{
+			set
+			{
+				ConfigScope setting = value;
+				_config.GenerateVersionNumbers(setting);
+			}
+		}
+
+		public virtual bool GenerateCommitTimestamps
+		{
+			set
+			{
+				bool setting = value;
+				_config.GenerateCommitTimestamps(setting);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Config.GlobalOnlyConfigException"></exception>
+		public virtual IStorage Storage
+		{
+			get
+			{
+				return _config.Storage;
+			}
+			set
+			{
+				IStorage factory = value;
+				_config.Storage = factory;
+			}
+		}
+
+		public virtual bool LockDatabaseFile
+		{
+			set
+			{
+				bool flag = value;
+				_config.LockDatabaseFile(flag);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		/// <exception cref="System.NotSupportedException"></exception>
+		public virtual long ReserveStorageSpace
+		{
+			set
+			{
+				long byteCount = value;
+				_config.ReserveStorageSpace(byteCount);
+			}
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public virtual string BlobPath
+		{
+			set
+			{
+				string path = value;
+				_config.SetBlobPath(path);
+			}
+		}
+
+		public virtual bool ReadOnly
+		{
+			set
+			{
+				bool flag = value;
+				_config.ReadOnly(flag);
+			}
+		}
+
+		public virtual bool RecoveryMode
+		{
+			set
+			{
+				bool flag = value;
+				_config.RecoveryMode(flag);
+			}
+		}
+
+		public virtual bool AsynchronousSync
+		{
+			set
+			{
+				bool flag = value;
+				_config.AsynchronousSync(flag);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/ILegacyConfigurationProvider.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/ILegacyConfigurationProvider.cs
new file mode 100644
index 0000000..71a93c4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/ILegacyConfigurationProvider.cs
@@ -0,0 +1,11 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Config
+{
+	public interface ILegacyConfigurationProvider
+	{
+		Config4Impl Legacy();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/IdSystemConfigurationImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/IdSystemConfigurationImpl.cs
new file mode 100644
index 0000000..436d337
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config/IdSystemConfigurationImpl.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Config
+{
+	/// <exclude></exclude>
+	public class IdSystemConfigurationImpl : IIdSystemConfiguration
+	{
+		private readonly Config4Impl _config;
+
+		public IdSystemConfigurationImpl(Config4Impl config)
+		{
+			_config = config;
+		}
+
+		public virtual void UsePointerBasedSystem()
+		{
+			_config.UsePointerBasedIdSystem();
+		}
+
+		public virtual void UseStackedBTreeSystem()
+		{
+			_config.UseStackedBTreeIdSystem();
+		}
+
+		public virtual void UseInMemorySystem()
+		{
+			_config.UseInMemoryIdSystem();
+		}
+
+		public virtual void UseCustomSystem(IIdSystemFactory factory)
+		{
+			_config.UseCustomIdSystem(factory);
+		}
+
+		public virtual void UseSingleBTreeSystem()
+		{
+			_config.UseSingleBTreeIdSystem();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config4Abstract.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config4Abstract.cs
new file mode 100644
index 0000000..0234b65
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config4Abstract.cs
@@ -0,0 +1,117 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public abstract class Config4Abstract
+	{
+		protected KeySpecHashtable4 _config;
+
+		private static readonly KeySpec CascadeOnActivateKey = new KeySpec(TernaryBool.Unspecified
+			);
+
+		private static readonly KeySpec CascadeOnDeleteKey = new KeySpec(TernaryBool.Unspecified
+			);
+
+		private static readonly KeySpec CascadeOnUpdateKey = new KeySpec(TernaryBool.Unspecified
+			);
+
+		private static readonly KeySpec NameKey = new KeySpec(null);
+
+		public Config4Abstract() : this(new KeySpecHashtable4(10))
+		{
+		}
+
+		protected Config4Abstract(KeySpecHashtable4 config)
+		{
+			_config = (KeySpecHashtable4)config.DeepClone(this);
+		}
+
+		public virtual void CascadeOnActivate(bool flag)
+		{
+			PutThreeValued(CascadeOnActivateKey, flag);
+		}
+
+		public virtual void CascadeOnDelete(bool flag)
+		{
+			PutThreeValued(CascadeOnDeleteKey, flag);
+		}
+
+		public virtual void CascadeOnUpdate(bool flag)
+		{
+			PutThreeValued(CascadeOnUpdateKey, flag);
+		}
+
+		protected virtual void PutThreeValued(KeySpec spec, bool flag)
+		{
+			_config.Put(spec, TernaryBool.ForBoolean(flag));
+		}
+
+		protected virtual void PutThreeValuedInt(KeySpec spec, bool flag)
+		{
+			_config.Put(spec, flag ? 1 : -1);
+		}
+
+		public virtual TernaryBool CascadeOnActivate()
+		{
+			return Cascade(CascadeOnActivateKey);
+		}
+
+		public virtual TernaryBool CascadeOnDelete()
+		{
+			return Cascade(CascadeOnDeleteKey);
+		}
+
+		public virtual TernaryBool CascadeOnUpdate()
+		{
+			return Cascade(CascadeOnUpdateKey);
+		}
+
+		private TernaryBool Cascade(KeySpec spec)
+		{
+			return _config.GetAsTernaryBool(spec);
+		}
+
+		internal abstract string ClassName();
+
+		/// <summary>Will raise an exception if argument class doesn't match this class - violates equals() contract in favor of failing fast.
+		/// 	</summary>
+		/// <remarks>Will raise an exception if argument class doesn't match this class - violates equals() contract in favor of failing fast.
+		/// 	</remarks>
+		public override bool Equals(object obj)
+		{
+			if (this == obj)
+			{
+				return true;
+			}
+			if (null == obj)
+			{
+				return false;
+			}
+			if (GetType() != obj.GetType())
+			{
+				Exceptions4.ShouldNeverHappen();
+			}
+			return GetName().Equals(((Db4objects.Db4o.Internal.Config4Abstract)obj).GetName()
+				);
+		}
+
+		public override int GetHashCode()
+		{
+			return GetName().GetHashCode();
+		}
+
+		public virtual string GetName()
+		{
+			return _config.GetAsString(NameKey);
+		}
+
+		protected virtual void SetName(string name)
+		{
+			_config.Put(NameKey, name);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config4Class.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config4Class.cs
new file mode 100644
index 0000000..64f63e6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config4Class.cs
@@ -0,0 +1,344 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class Config4Class : Config4Abstract, IObjectClass, IDeepClone
+	{
+		private readonly Config4Impl _configImpl;
+
+		private static readonly KeySpec CallConstructorKey = new KeySpec(TernaryBool.Unspecified
+			);
+
+		private static readonly KeySpec ClassIndexedKey = new KeySpec(true);
+
+		private static readonly KeySpec ExceptionalFieldsKey = new KeySpec(null);
+
+		private static readonly KeySpec GenerateUuidsKey = new KeySpec(TernaryBool.Unspecified
+			);
+
+		/// <summary>
+		/// We are running into cyclic dependancies on reading the PBootRecord
+		/// object, if we maintain MetaClass information there
+		/// </summary>
+		private static readonly KeySpec MaintainMetaclassKey = new KeySpec(true);
+
+		private static readonly KeySpec MaximumActivationDepthKey = new KeySpec(0);
+
+		private static readonly KeySpec MinimumActivationDepthKey = new KeySpec(0);
+
+		private static readonly KeySpec PersistStaticFieldValuesKey = new KeySpec(false);
+
+		private static readonly KeySpec QueryAttributeProviderKey = new KeySpec(null);
+
+		private static readonly KeySpec StoreTransientFieldsKey = new KeySpec(false);
+
+		private static readonly KeySpec TranslatorKey = new KeySpec(null);
+
+		private static readonly KeySpec TranslatorNameKey = new KeySpec((string)null);
+
+		private static readonly KeySpec UpdateDepthKey = new KeySpec(Const4.Unspecified);
+
+		private static readonly KeySpec WriteAsKey = new KeySpec((string)null);
+
+		protected Config4Class(Config4Impl configuration, KeySpecHashtable4 config) : base
+			(config)
+		{
+			_configImpl = configuration;
+		}
+
+		internal Config4Class(Config4Impl a_configuration, string a_name)
+		{
+			_configImpl = a_configuration;
+			SetName(a_name);
+		}
+
+		public virtual int AdjustActivationDepth(int depth)
+		{
+			TernaryBool cascadeOnActivate = CascadeOnActivate();
+			if (cascadeOnActivate.DefiniteYes() && depth < 2)
+			{
+				depth = 2;
+			}
+			if (cascadeOnActivate.DefiniteNo() && depth > 1)
+			{
+				depth = 1;
+			}
+			if (Config().ClassActivationDepthConfigurable())
+			{
+				int minimumActivationDepth = MinimumActivationDepth();
+				if (minimumActivationDepth != 0 && depth < minimumActivationDepth)
+				{
+					depth = minimumActivationDepth;
+				}
+				int maximumActivationDepth = MaximumActivationDepth();
+				if (maximumActivationDepth != 0 && depth > maximumActivationDepth)
+				{
+					depth = maximumActivationDepth;
+				}
+			}
+			return depth;
+		}
+
+		public virtual void CallConstructor(bool flag)
+		{
+			PutThreeValued(CallConstructorKey, flag);
+		}
+
+		internal override string ClassName()
+		{
+			return GetName();
+		}
+
+		internal virtual IReflectClass ClassReflector()
+		{
+			return Config().Reflector().ForName(GetName());
+		}
+
+		[System.ObsoleteAttribute]
+		public virtual void Compare(IObjectAttribute comparator)
+		{
+			_config.Put(QueryAttributeProviderKey, comparator);
+		}
+
+		internal virtual Config4Field ConfigField(string fieldName)
+		{
+			Hashtable4 exceptionalFields = ExceptionalFieldsOrNull();
+			if (exceptionalFields == null)
+			{
+				return null;
+			}
+			Config4Field config4Field = (Config4Field)exceptionalFields.Get(fieldName);
+			if (config4Field == null)
+			{
+				return null;
+			}
+			config4Field.Used(true);
+			return config4Field;
+		}
+
+		public virtual object DeepClone(object param)
+		{
+			Config4Impl parentConfig = ((Config4Impl.ConfigDeepCloneContext)param)._cloned;
+			return new Db4objects.Db4o.Internal.Config4Class(parentConfig, _config);
+		}
+
+		public virtual void EnableReplication(bool setting)
+		{
+			throw new NotSupportedException("See documentation");
+		}
+
+		public virtual void GenerateUUIDs(bool setting)
+		{
+			_config.Put(GenerateUuidsKey, TernaryBool.ForBoolean(setting));
+		}
+
+		public virtual void GenerateVersionNumbers(bool setting)
+		{
+			throw new NotSupportedException("See documentation");
+		}
+
+		public virtual IObjectTranslator GetTranslator()
+		{
+			IObjectTranslator translator = (IObjectTranslator)_config.Get(TranslatorKey);
+			if (translator != null)
+			{
+				return translator;
+			}
+			string translatorName = _config.GetAsString(TranslatorNameKey);
+			if (translatorName == null)
+			{
+				return null;
+			}
+			try
+			{
+				translator = NewTranslatorFromReflector(translatorName);
+			}
+			catch (Exception)
+			{
+				try
+				{
+					translator = NewTranslatorFromPlatform(translatorName);
+				}
+				catch (Exception e)
+				{
+					throw new Db4oException(e);
+				}
+			}
+			Translate(translator);
+			return translator;
+		}
+
+		/// <exception cref="Sharpen.Lang.InstantiationException"></exception>
+		/// <exception cref="System.MemberAccessException"></exception>
+		private IObjectTranslator NewTranslatorFromPlatform(string translatorName)
+		{
+			return (IObjectTranslator)System.Activator.CreateInstance(ReflectPlatform.ForName
+				(translatorName));
+		}
+
+		private IObjectTranslator NewTranslatorFromReflector(string translatorName)
+		{
+			return (IObjectTranslator)Config().Reflector().ForName(translatorName).NewInstance
+				();
+		}
+
+		public virtual void Indexed(bool flag)
+		{
+			_config.Put(ClassIndexedKey, flag);
+		}
+
+		public virtual bool Indexed()
+		{
+			return _config.GetAsBoolean(ClassIndexedKey);
+		}
+
+		public virtual void MaximumActivationDepth(int depth)
+		{
+			_config.Put(MaximumActivationDepthKey, depth);
+		}
+
+		internal virtual int MaximumActivationDepth()
+		{
+			return _config.GetAsInt(MaximumActivationDepthKey);
+		}
+
+		public virtual void MinimumActivationDepth(int depth)
+		{
+			_config.Put(MinimumActivationDepthKey, depth);
+		}
+
+		public virtual int MinimumActivationDepth()
+		{
+			return _config.GetAsInt(MinimumActivationDepthKey);
+		}
+
+		public virtual TernaryBool CallConstructor()
+		{
+			if (_config.Get(TranslatorKey) != null)
+			{
+				return TernaryBool.Yes;
+			}
+			return _config.GetAsTernaryBool(CallConstructorKey);
+		}
+
+		internal virtual Hashtable4 ExceptionalFieldsOrNull()
+		{
+			return (Hashtable4)_config.Get(ExceptionalFieldsKey);
+		}
+
+		private Hashtable4 ExceptionalFields()
+		{
+			Hashtable4 exceptionalFieldsCollection = ExceptionalFieldsOrNull();
+			if (exceptionalFieldsCollection == null)
+			{
+				exceptionalFieldsCollection = new Hashtable4(16);
+				_config.Put(ExceptionalFieldsKey, exceptionalFieldsCollection);
+			}
+			return exceptionalFieldsCollection;
+		}
+
+		public virtual IObjectField ObjectField(string fieldName)
+		{
+			Hashtable4 exceptionalFieldsCollection = ExceptionalFields();
+			Config4Field c4f = (Config4Field)exceptionalFieldsCollection.Get(fieldName);
+			if (c4f == null)
+			{
+				c4f = new Config4Field(this, fieldName);
+				exceptionalFieldsCollection.Put(fieldName, c4f);
+			}
+			return c4f;
+		}
+
+		public virtual void PersistStaticFieldValues()
+		{
+			_config.Put(PersistStaticFieldValuesKey, true);
+		}
+
+		public virtual void Rename(string newName)
+		{
+			Config().Rename(Renames.ForClass(GetName(), newName));
+			SetName(newName);
+		}
+
+		public virtual void StoreTransientFields(bool flag)
+		{
+			_config.Put(StoreTransientFieldsKey, flag);
+		}
+
+		public virtual void Translate(IObjectTranslator translator)
+		{
+			if (translator == null)
+			{
+				_config.Put(TranslatorNameKey, null);
+			}
+			_config.Put(TranslatorKey, translator);
+		}
+
+		internal virtual void TranslateOnDemand(string a_translatorName)
+		{
+			_config.Put(TranslatorNameKey, a_translatorName);
+		}
+
+		public virtual void UpdateDepth(int depth)
+		{
+			if (depth < 0)
+			{
+				throw new ArgumentException("update depth must not be negative");
+			}
+			_config.Put(UpdateDepthKey, depth);
+		}
+
+		internal virtual Config4Impl Config()
+		{
+			return _configImpl;
+		}
+
+		internal virtual TernaryBool GenerateUUIDs()
+		{
+			return (TernaryBool)_config.Get(GenerateUuidsKey);
+		}
+
+		internal virtual TernaryBool GenerateVersionNumbers()
+		{
+			return TernaryBool.No;
+		}
+
+		internal virtual void MaintainMetaClass(bool flag)
+		{
+			_config.Put(MaintainMetaclassKey, flag);
+		}
+
+		internal virtual bool StaticFieldValuesArePersisted()
+		{
+			return _config.GetAsBoolean(PersistStaticFieldValuesKey);
+		}
+
+		public virtual IObjectAttribute QueryAttributeProvider()
+		{
+			return (IObjectAttribute)_config.Get(QueryAttributeProviderKey);
+		}
+
+		public virtual bool StoreTransientFields()
+		{
+			return _config.GetAsBoolean(StoreTransientFieldsKey);
+		}
+
+		internal virtual int UpdateDepth()
+		{
+			return _config.GetAsInt(UpdateDepthKey);
+		}
+
+		internal virtual string WriteAs()
+		{
+			return _config.GetAsString(WriteAsKey);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config4Field.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config4Field.cs
new file mode 100644
index 0000000..a3a527c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config4Field.cs
@@ -0,0 +1,100 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	public class Config4Field : Config4Abstract, IObjectField, IDeepClone
+	{
+		private readonly Config4Class _configClass;
+
+		private bool _used;
+
+		private static readonly KeySpec IndexedKey = new KeySpec(TernaryBool.Unspecified);
+
+		protected Config4Field(Config4Class a_class, KeySpecHashtable4 config) : base(config
+			)
+		{
+			_configClass = a_class;
+		}
+
+		internal Config4Field(Config4Class a_class, string a_name)
+		{
+			_configClass = a_class;
+			SetName(a_name);
+		}
+
+		private Config4Class ClassConfig()
+		{
+			return _configClass;
+		}
+
+		internal override string ClassName()
+		{
+			return ClassConfig().GetName();
+		}
+
+		public virtual object DeepClone(object param)
+		{
+			return new Db4objects.Db4o.Internal.Config4Field((Config4Class)param, _config);
+		}
+
+		public virtual void Rename(string newName)
+		{
+			ClassConfig().Config().Rename(Renames.ForField(ClassName(), GetName(), newName));
+			SetName(newName);
+		}
+
+		public virtual void Indexed(bool flag)
+		{
+			PutThreeValued(IndexedKey, flag);
+		}
+
+		public virtual void InitOnUp(Transaction systemTrans, FieldMetadata fieldMetadata
+			)
+		{
+			ObjectContainerBase anyStream = systemTrans.Container();
+			if (!anyStream.MaintainsIndices())
+			{
+				return;
+			}
+			if (!fieldMetadata.SupportsIndex())
+			{
+				Indexed(false);
+			}
+			TernaryBool indexedFlag = _config.GetAsTernaryBool(IndexedKey);
+			if (indexedFlag.DefiniteNo())
+			{
+				fieldMetadata.DropIndex((LocalTransaction)systemTrans);
+				return;
+			}
+			if (UseExistingIndex(systemTrans, fieldMetadata))
+			{
+				return;
+			}
+			if (!indexedFlag.DefiniteYes())
+			{
+				return;
+			}
+			fieldMetadata.CreateIndex();
+		}
+
+		private bool UseExistingIndex(Transaction systemTrans, FieldMetadata fieldMetadata
+			)
+		{
+			return fieldMetadata.GetIndex(systemTrans) != null;
+		}
+
+		public virtual void Used(bool flag)
+		{
+			_used = flag;
+		}
+
+		public virtual bool Used()
+		{
+			return _used;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config4Impl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config4Impl.cs
new file mode 100644
index 0000000..3898963
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Config4Impl.cs
@@ -0,0 +1,1450 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using System.IO;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Config.Encoding;
+using Db4objects.Db4o.Diagnostic;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Config;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.References;
+using Db4objects.Db4o.Messaging;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Core;
+using Db4objects.Db4o.Reflect.Generic;
+using Db4objects.Db4o.Typehandlers;
+using Sharpen;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <summary>Configuration template for creating new db4o files</summary>
+	/// <exclude></exclude>
+	public sealed partial class Config4Impl : IConfiguration, IDeepClone, IMessageSender
+		, IFreespaceConfiguration, IQueryConfiguration, IClientServerConfiguration
+	{
+		private KeySpecHashtable4 _config = new KeySpecHashtable4(50);
+
+		private static readonly KeySpec ActivationDepthKey = new KeySpec(5);
+
+		private static readonly KeySpec ActivationDepthProviderKey = new KeySpec(LegacyActivationDepthProvider
+			.Instance);
+
+		private static readonly KeySpec UpdateDepthProviderKey = new KeySpec(new LegacyUpdateDepthProvider
+			());
+
+		private static readonly KeySpec AllowVersionUpdatesKey = new KeySpec(false);
+
+		private static readonly KeySpec AsynchronousSyncKey = new KeySpec(false);
+
+		private static readonly KeySpec AutomaticShutdownKey = new KeySpec(true);
+
+		private static readonly KeySpec BlocksizeKey = new KeySpec((byte)1);
+
+		private static readonly KeySpec BlobPathKey = new KeySpec(null);
+
+		private static readonly KeySpec BtreeNodeSizeKey = new KeySpec(201);
+
+		private static readonly KeySpec CallbacksKey = new KeySpec(CallBackMode.All);
+
+		private static readonly KeySpec CallConstructorsKey = new KeySpec(TernaryBool.Unspecified
+			);
+
+		private static readonly KeySpec ConfigurationItemsKey = new KeySpec(null);
+
+		private static readonly KeySpec ConfiguredReflectorKey = new KeySpec(null);
+
+		private static readonly KeySpec ClassActivationDepthConfigurableKey = new KeySpec
+			(true);
+
+		private static readonly KeySpec ClassloaderKey = new KeySpec(null);
+
+		private sealed class _IDeferred_75 : KeySpec.IDeferred
+		{
+			public _IDeferred_75()
+			{
+			}
+
+			//  TODO: consider setting default to 8, it's more efficient with freespace.
+			public object Evaluate()
+			{
+				return Config4Impl.DefaultClientServerFactory();
+			}
+		}
+
+		private static readonly KeySpec ClientServerFactoryKey = new KeySpec(new _IDeferred_75
+			());
+
+		private static readonly KeySpec DatabaseGrowthSizeKey = new KeySpec(0);
+
+		private static readonly KeySpec DetectSchemaChangesKey = new KeySpec(true);
+
+		private sealed class _IDeferred_85 : KeySpec.IDeferred
+		{
+			public _IDeferred_85()
+			{
+			}
+
+			public object Evaluate()
+			{
+				return new Db4objects.Db4o.Internal.Diagnostic.DiagnosticProcessor();
+			}
+		}
+
+		private static readonly KeySpec DiagnosticKey = new KeySpec(new _IDeferred_85());
+
+		private static readonly KeySpec DisableCommitRecoveryKey = new KeySpec(false);
+
+		private static readonly KeySpec DiscardFreespaceKey = new KeySpec(0);
+
+		private static readonly IStringEncoding DefaultStringEncoding = StringEncodings.Unicode
+			();
+
+		private static readonly KeySpec StringEncodingKey = new KeySpec(DefaultStringEncoding
+			);
+
+		private static readonly KeySpec EncodingKey = new KeySpec(BuiltInStringEncoding.EncodingByteForEncoding
+			(DefaultStringEncoding));
+
+		private static readonly KeySpec EncryptKey = new KeySpec(false);
+
+		private sealed class _IDeferred_103 : KeySpec.IDeferred
+		{
+			public _IDeferred_103()
+			{
+			}
+
+			public object Evaluate()
+			{
+				return new ArrayList();
+			}
+		}
+
+		private static readonly KeySpec EnvironmentContributionsKey = new KeySpec(new _IDeferred_103
+			());
+
+		private static readonly KeySpec ExceptionalClassesKey = new KeySpec(null);
+
+		private static readonly KeySpec ExceptionsOnNotStorableKey = new KeySpec(true);
+
+		private static readonly KeySpec FileBasedTransactionLogKey = new KeySpec(false);
+
+		private static readonly KeySpec FreespaceFillerKey = new KeySpec(null);
+
+		private static readonly KeySpec FreespaceSystemKey = new KeySpec(AbstractFreespaceManager
+			.FmDefault);
+
+		private static readonly KeySpec GenerateUuidsKey = new KeySpec(ConfigScope.Individually
+			);
+
+		private static readonly KeySpec GenerateCommitTimestampsKey = new KeySpec(TernaryBool
+			.Unspecified);
+
+		private static readonly KeySpec IdSystemKey = new KeySpec(StandardIdSystemFactory
+			.Default);
+
+		private static readonly KeySpec IdSystemCustomFactoryKey = new KeySpec(null);
+
+		private static readonly KeySpec QueryEvaluationModeKey = new KeySpec(QueryEvaluationMode
+			.Immediate);
+
+		private static readonly KeySpec LockFileKey = new KeySpec(true);
+
+		private static readonly KeySpec MessageRecipientKey = new KeySpec(null);
+
+		private static readonly KeySpec OptimizeNqKey = new KeySpec(true);
+
+		private static readonly KeySpec OutstreamKey = new KeySpec(null);
+
+		private static readonly KeySpec PasswordKey = new KeySpec((string)null);
+
+		private static readonly KeySpec ClientQueryResultIteratorFactoryKey = new KeySpec
+			(null);
+
+		private static readonly KeySpec PrefetchIdCountKey = new KeySpec(10);
+
+		private static readonly KeySpec PrefetchObjectCountKey = new KeySpec(10);
+
+		private static readonly KeySpec PrefetchDepthKey = new KeySpec(0);
+
+		public const int PrefetchSlotCacheSizeFactor = 10;
+
+		private const int MaximumPrefetchSlotCacheSize = 10000;
+
+		private static readonly KeySpec PrefetchSlotCacheSizeKey = new KeySpec(0);
+
+		private sealed class _IDeferred_155 : KeySpec.IDeferred
+		{
+			public _IDeferred_155()
+			{
+			}
+
+			// for playing with different strategies of prefetching
+			// object
+			public object Evaluate()
+			{
+				return new Hashtable4(16);
+			}
+		}
+
+		private static readonly KeySpec ReadAsKey = new KeySpec(new _IDeferred_155());
+
+		private static readonly KeySpec RecoveryModeKey = new KeySpec(false);
+
+		private static readonly KeySpec ReflectorKey = new KeySpec(null);
+
+		private static readonly KeySpec RenameKey = new KeySpec(null);
+
+		private static readonly KeySpec ReservedStorageSpaceKey = new KeySpec(0);
+
+		private static readonly KeySpec SingleThreadedClientKey = new KeySpec(false);
+
+		private static readonly KeySpec TestConstructorsKey = new KeySpec(true);
+
+		private static readonly KeySpec TimeoutClientSocketKey = new KeySpec(Const4.ClientSocketTimeout
+			);
+
+		private static readonly KeySpec TimeoutServerSocketKey = new KeySpec(Const4.ServerSocketTimeout
+			);
+
+		private static readonly KeySpec UpdateDepthKey = new KeySpec(1);
+
+		private static readonly KeySpec WeakReferenceCollectionIntervalKey = new KeySpec(
+			1000);
+
+		private static readonly KeySpec WeakReferencesKey = new KeySpec(true);
+
+		private static readonly KeySpec StorageFactoryKey = new KeySpec(new CachingStorage
+			(new FileStorage()));
+
+		private static readonly KeySpec AliasesKey = new KeySpec(null);
+
+		private static readonly KeySpec BatchMessagesKey = new KeySpec(true);
+
+		private static readonly KeySpec MaxBatchQueueSizeKey = new KeySpec(int.MaxValue);
+
+		private static readonly KeySpec TaintedKey = new KeySpec(false);
+
+		private sealed class _IReferenceSystemFactory_193 : IReferenceSystemFactory
+		{
+			public _IReferenceSystemFactory_193()
+			{
+			}
+
+			public IReferenceSystem NewReferenceSystem(IInternalObjectContainer container)
+			{
+				return new TransactionalReferenceSystem();
+			}
+		}
+
+		private static readonly KeySpec ReferenceSystemFactoryKey = new KeySpec(new _IReferenceSystemFactory_193
+			());
+
+		private sealed class _INameProvider_199 : INameProvider
+		{
+			public _INameProvider_199()
+			{
+			}
+
+			public string Name(IObjectContainer db)
+			{
+				return null;
+			}
+		}
+
+		private static readonly KeySpec NameProviderKey = new KeySpec(new _INameProvider_199
+			());
+
+		private static readonly KeySpec MaxStackDepthKey = new KeySpec("Dalvik".Equals(Runtime
+			.GetProperty("java.vm.name")) ? 2 : Const4.DefaultMaxStackDepth);
+
+		private ObjectContainerBase _container;
+
+		private bool _internStrings;
+
+		private int _messageLevel;
+
+		private bool _readOnly;
+
+		private Collection4 _registeredTypeHandlers;
+
+		private System.EventHandler<EventArgs> _prefetchSettingsChanged;
+
+		private bool _prefetchSlotCacheSizeModifiedExternally;
+
+		// TODO find a better place to do this, and use AndroidConfiguration instead.
+		//  is null in the global configuration until deepClone is called
+		// The following are very frequently being asked for, so they show up in the profiler. 
+		// Let's keep them out of the Hashtable.
+		public int ActivationDepth()
+		{
+			return _config.GetAsInt(ActivationDepthKey);
+		}
+
+		// FIXME: circular cs dependancy. Improve.
+		public void ActivationDepth(int depth)
+		{
+			_config.Put(ActivationDepthKey, depth);
+		}
+
+		public void Add(IConfigurationItem item)
+		{
+			item.Prepare(this);
+			SafeConfigurationItems().Put(item, item);
+		}
+
+		/// <summary>
+		/// Returns an iterator for all
+		/// <see cref="Db4objects.Db4o.Config.IConfigurationItem">Db4objects.Db4o.Config.IConfigurationItem
+		/// 	</see>
+		/// instances
+		/// added.
+		/// </summary>
+		/// <seealso cref="Add(Db4objects.Db4o.Config.IConfigurationItem)">Add(Db4objects.Db4o.Config.IConfigurationItem)
+		/// 	</seealso>
+		/// <returns>the iterator</returns>
+		public IEnumerator ConfigurationItemsIterator()
+		{
+			Hashtable4 items = ConfigurationItems();
+			if (items == null)
+			{
+				return Iterators.EmptyIterator;
+			}
+			return items.Keys();
+		}
+
+		private Hashtable4 SafeConfigurationItems()
+		{
+			Hashtable4 items = ConfigurationItems();
+			if (items == null)
+			{
+				items = new Hashtable4(16);
+				_config.Put(ConfigurationItemsKey, items);
+			}
+			return items;
+		}
+
+		public void AllowVersionUpdates(bool flag)
+		{
+			_config.Put(AllowVersionUpdatesKey, flag);
+		}
+
+		private Hashtable4 ConfigurationItems()
+		{
+			return (Hashtable4)_config.Get(ConfigurationItemsKey);
+		}
+
+		public void ApplyConfigurationItems(IInternalObjectContainer container)
+		{
+			Hashtable4 items = ConfigurationItems();
+			if (items == null)
+			{
+				return;
+			}
+			IEnumerator i = items.Iterator();
+			while (i.MoveNext())
+			{
+				IEntry4 entry = (IEntry4)i.Current;
+				IConfigurationItem item = (IConfigurationItem)entry.Value();
+				item.Apply(container);
+			}
+		}
+
+		public void AutomaticShutDown(bool flag)
+		{
+			_config.Put(AutomaticShutdownKey, flag);
+		}
+
+		public void BlockSize(int bytes)
+		{
+			if (bytes < 1 || bytes > 127)
+			{
+				throw new ArgumentException();
+			}
+			GlobalSettingOnly();
+			_config.Put(BlocksizeKey, (byte)bytes);
+		}
+
+		public void BTreeNodeSize(int size)
+		{
+			_config.Put(BtreeNodeSizeKey, size);
+		}
+
+		public void BTreeCacheHeight(int height)
+		{
+		}
+
+		public void Callbacks(bool turnOn)
+		{
+			CallbackMode(turnOn ? CallBackMode.All : CallBackMode.None);
+		}
+
+		public void CallbackMode(CallBackMode mode)
+		{
+			_config.Put(CallbacksKey, mode);
+		}
+
+		public void CallConstructors(bool flag)
+		{
+			_config.Put(CallConstructorsKey, TernaryBool.ForBoolean(flag));
+		}
+
+		public void ClassActivationDepthConfigurable(bool turnOn)
+		{
+			_config.Put(ClassActivationDepthConfigurableKey, turnOn);
+		}
+
+		public Config4Class ConfigClass(string className)
+		{
+			Config4Class config = (Config4Class)ExceptionalClasses().Get(className);
+			return config;
+		}
+
+		private bool IsIgnoredClass(string className)
+		{
+			Type[] ignore = IgnoredClasses();
+			for (int i = 0; i < ignore.Length; i++)
+			{
+				if (ignore[i].FullName.Equals(className))
+				{
+					return true;
+				}
+			}
+			return false;
+		}
+
+		private Type[] IgnoredClasses()
+		{
+			return new Type[] { typeof(StaticClass), typeof(StaticField) };
+		}
+
+		public object DeepClone(object param)
+		{
+			Config4Impl ret = new Config4Impl();
+			Config4Impl.ConfigDeepCloneContext context = new Config4Impl.ConfigDeepCloneContext
+				(this, ret);
+			ret._config = (KeySpecHashtable4)_config.DeepClone(context);
+			ret._internStrings = _internStrings;
+			ret._messageLevel = _messageLevel;
+			ret._readOnly = _readOnly;
+			if (_registeredTypeHandlers != null)
+			{
+				ret._registeredTypeHandlers = (Collection4)_registeredTypeHandlers.DeepClone(context
+					);
+			}
+			return ret;
+		}
+
+		public void Container(ObjectContainerBase container)
+		{
+			_container = container;
+		}
+
+		public void DatabaseGrowthSize(int bytes)
+		{
+			_config.Put(DatabaseGrowthSizeKey, bytes);
+		}
+
+		public int DatabaseGrowthSize()
+		{
+			return _config.GetAsInt(DatabaseGrowthSizeKey);
+		}
+
+		public void DetectSchemaChanges(bool flag)
+		{
+			_config.Put(DetectSchemaChangesKey, flag);
+		}
+
+		public void DisableCommitRecovery()
+		{
+			_config.Put(DisableCommitRecoveryKey, true);
+		}
+
+		public void DiscardSmallerThan(int byteCount)
+		{
+			if (byteCount < 0)
+			{
+				throw new ArgumentException();
+			}
+			_config.Put(DiscardFreespaceKey, byteCount);
+		}
+
+		[System.ObsoleteAttribute]
+		public void Encrypt(bool flag)
+		{
+			GlobalSettingOnly();
+			_config.Put(EncryptKey, flag);
+		}
+
+		internal void OldEncryptionOff()
+		{
+			_config.Put(EncryptKey, false);
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		internal void EnsureDirExists(string path)
+		{
+			Sharpen.IO.File file = new Sharpen.IO.File(path);
+			if (!file.Exists())
+			{
+				file.Mkdirs();
+			}
+			if (file.Exists() && file.IsDirectory())
+			{
+			}
+			else
+			{
+				throw new IOException(Db4objects.Db4o.Internal.Messages.Get(37, path));
+			}
+		}
+
+		internal TextWriter ErrStream()
+		{
+			TextWriter outStream = OutStreamOrNull();
+			return outStream == null ? Sharpen.Runtime.Err : outStream;
+		}
+
+		public void ExceptionsOnNotStorable(bool flag)
+		{
+			_config.Put(ExceptionsOnNotStorableKey, flag);
+		}
+
+		public IFreespaceConfiguration Freespace()
+		{
+			return this;
+		}
+
+		public void FreespaceFiller(IFreespaceFiller freespaceFiller)
+		{
+			_config.Put(FreespaceFillerKey, freespaceFiller);
+		}
+
+		public IFreespaceFiller FreespaceFiller()
+		{
+			return (IFreespaceFiller)_config.Get(FreespaceFillerKey);
+		}
+
+		public void GenerateUUIDs(ConfigScope scope)
+		{
+			_config.Put(GenerateUuidsKey, scope);
+		}
+
+		public void GenerateVersionNumbers(ConfigScope scope)
+		{
+			if (scope == ConfigScope.Individually)
+			{
+				throw new NotSupportedException();
+			}
+			GenerateCommitTimestamps(scope == ConfigScope.Globally);
+		}
+
+		public void GenerateCommitTimestamps(bool flag)
+		{
+			_config.Put(GenerateCommitTimestampsKey, TernaryBool.ForBoolean(flag));
+		}
+
+		public IMessageSender GetMessageSender()
+		{
+			return this;
+		}
+
+		private void GlobalSettingOnly()
+		{
+			if (_container != null)
+			{
+				throw new GlobalOnlyConfigException();
+			}
+		}
+
+		public void InternStrings(bool doIntern)
+		{
+			_internStrings = doIntern;
+		}
+
+		public void Io(IoAdapter adapter)
+		{
+			GlobalSettingOnly();
+			Storage = new IoAdapterStorage(adapter);
+		}
+
+		public void LockDatabaseFile(bool flag)
+		{
+			_config.Put(LockFileKey, flag);
+		}
+
+		public void MarkTransient(string marker)
+		{
+			Platform4.MarkTransient(marker);
+		}
+
+		public void MessageLevel(int level)
+		{
+			_messageLevel = level;
+			if (OutStream() == null)
+			{
+				SetOut(Sharpen.Runtime.Out);
+			}
+		}
+
+		public void OptimizeNativeQueries(bool optimizeNQ)
+		{
+			_config.Put(OptimizeNqKey, optimizeNQ);
+		}
+
+		public bool OptimizeNativeQueries()
+		{
+			return _config.GetAsBoolean(OptimizeNqKey);
+		}
+
+		public IObjectClass ObjectClass(object clazz)
+		{
+			string className = null;
+			if (clazz is string)
+			{
+				className = (string)clazz;
+			}
+			else
+			{
+				IReflectClass claxx = ReflectorFor(clazz);
+				if (claxx == null)
+				{
+					return null;
+				}
+				className = claxx.GetName();
+			}
+			if (ReflectPlatform.FullyQualifiedName(typeof(object)).Equals(className))
+			{
+				throw new ArgumentException("Configuration of the Object class is not supported."
+					);
+			}
+			Hashtable4 xClasses = ExceptionalClasses();
+			Config4Class c4c = (Config4Class)xClasses.Get(className);
+			if (c4c == null)
+			{
+				c4c = new Config4Class(this, className);
+				xClasses.Put(className, c4c);
+			}
+			return c4c;
+		}
+
+		private TextWriter OutStreamOrNull()
+		{
+			return (TextWriter)_config.Get(OutstreamKey);
+		}
+
+		public TextWriter OutStream()
+		{
+			TextWriter outStream = OutStreamOrNull();
+			return outStream == null ? Sharpen.Runtime.Out : outStream;
+		}
+
+		[System.ObsoleteAttribute]
+		public void Password(string pw)
+		{
+			GlobalSettingOnly();
+			_config.Put(PasswordKey, pw);
+		}
+
+		public void ReadOnly(bool flag)
+		{
+			_readOnly = flag;
+		}
+
+		public GenericReflector Reflector()
+		{
+			GenericReflector reflector = (GenericReflector)_config.Get(ReflectorKey);
+			if (reflector == null)
+			{
+				IReflector configuredReflector = (IReflector)_config.Get(ConfiguredReflectorKey);
+				if (configuredReflector == null)
+				{
+					configuredReflector = Platform4.CreateReflector(ClassLoader());
+					_config.Put(ConfiguredReflectorKey, configuredReflector);
+				}
+				reflector = new GenericReflector(configuredReflector);
+				_config.Put(ReflectorKey, reflector);
+			}
+			// TODO: transaction assignment has been moved to YapStreamBase#initialize1().
+			// implement better, more generic solution as described in COR-288
+			//		if(! reflector.hasTransaction() && i_stream != null){
+			//			reflector.setTransaction(i_stream.getSystemTransaction());
+			//		}
+			return reflector;
+		}
+
+		public void ReflectWith(IReflector reflect)
+		{
+			if (_container != null)
+			{
+				Exceptions4.ThrowRuntimeException(46);
+			}
+			// see readable message for code in Messages.java
+			if (reflect == null)
+			{
+				throw new ArgumentNullException();
+			}
+			_config.Put(ConfiguredReflectorKey, reflect);
+			_config.Put(ReflectorKey, null);
+		}
+
+		public void RefreshClasses()
+		{
+			throw new NotImplementedException();
+		}
+
+		internal void Rename(Db4objects.Db4o.Rename a_rename)
+		{
+			Collection4 renameCollection = Rename();
+			if (renameCollection == null)
+			{
+				renameCollection = new Collection4();
+				_config.Put(RenameKey, renameCollection);
+			}
+			renameCollection.Add(a_rename);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		public void ReserveStorageSpace(long byteCount)
+		{
+			int reservedStorageSpace = (int)byteCount;
+			if (reservedStorageSpace < 0)
+			{
+				reservedStorageSpace = 0;
+			}
+			_config.Put(ReservedStorageSpaceKey, reservedStorageSpace);
+			if (_container != null)
+			{
+				_container.Reserve(reservedStorageSpace);
+			}
+		}
+
+		/// <summary>The ConfigImpl also is our messageSender</summary>
+		public void Send(object obj)
+		{
+			if (_container != null)
+			{
+				_container.Send(obj);
+			}
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public void SetBlobPath(string path)
+		{
+			EnsureDirExists(path);
+			_config.Put(BlobPathKey, path);
+		}
+
+		public void SetMessageRecipient(IMessageRecipient messageRecipient)
+		{
+			_config.Put(MessageRecipientKey, messageRecipient);
+		}
+
+		[System.ObsoleteAttribute]
+		public void SetOut(TextWriter outStream)
+		{
+			_config.Put(OutstreamKey, outStream);
+			if (_container != null)
+			{
+				_container.LogMsg(19, Db4oFactory.Version());
+			}
+			else
+			{
+				Db4objects.Db4o.Internal.Messages.LogMsg(this, 19, Db4oFactory.Version());
+			}
+		}
+
+		public void SingleThreadedClient(bool flag)
+		{
+			_config.Put(SingleThreadedClientKey, flag);
+		}
+
+		public IStringEncoding StringEncoding()
+		{
+			return (IStringEncoding)_config.Get(StringEncodingKey);
+		}
+
+		public void StringEncoding(IStringEncoding encoding)
+		{
+			_config.Put(StringEncodingKey, encoding);
+			_config.Put(EncodingKey, BuiltInStringEncoding.EncodingByteForEncoding(encoding));
+		}
+
+		public void TestConstructors(bool flag)
+		{
+			_config.Put(TestConstructorsKey, flag);
+		}
+
+		public void TimeoutClientSocket(int milliseconds)
+		{
+			_config.Put(TimeoutClientSocketKey, milliseconds);
+		}
+
+		public void TimeoutServerSocket(int milliseconds)
+		{
+			_config.Put(TimeoutServerSocketKey, milliseconds);
+		}
+
+		public void UpdateDepth(int depth)
+		{
+			if (depth < 0)
+			{
+				throw new ArgumentException("update depth must not be negative");
+			}
+			Db4objects.Db4o.Internal.Diagnostic.DiagnosticProcessor dp = DiagnosticProcessor(
+				);
+			if (dp.Enabled())
+			{
+				dp.CheckUpdateDepth(depth);
+			}
+			_config.Put(UpdateDepthKey, depth);
+		}
+
+		public void UseBTreeSystem()
+		{
+			_config.Put(FreespaceSystemKey, AbstractFreespaceManager.FmBtree);
+		}
+
+		public void UseRamSystem()
+		{
+			_config.Put(FreespaceSystemKey, AbstractFreespaceManager.FmRam);
+		}
+
+		[System.ObsoleteAttribute]
+		public void UseIndexSystem()
+		{
+			throw new NotSupportedException();
+		}
+
+		public void WeakReferenceCollectionInterval(int milliseconds)
+		{
+			_config.Put(WeakReferenceCollectionIntervalKey, milliseconds);
+		}
+
+		public void WeakReferences(bool flag)
+		{
+			_config.Put(WeakReferencesKey, flag);
+		}
+
+		private Collection4 Aliases()
+		{
+			Collection4 aliasesCollection = (Collection4)_config.Get(AliasesKey);
+			if (null == aliasesCollection)
+			{
+				aliasesCollection = new Collection4();
+				_config.Put(AliasesKey, aliasesCollection);
+			}
+			return aliasesCollection;
+		}
+
+		public void AddAlias(IAlias alias)
+		{
+			if (null == alias)
+			{
+				throw new ArgumentNullException("alias");
+			}
+			Aliases().Add(alias);
+		}
+
+		public void RemoveAlias(IAlias alias)
+		{
+			if (null == alias)
+			{
+				throw new ArgumentNullException("alias");
+			}
+			Aliases().Remove(alias);
+		}
+
+		public string ResolveAliasRuntimeName(string runtimeType)
+		{
+			Collection4 configuredAliases = Aliases();
+			if (null == configuredAliases)
+			{
+				return runtimeType;
+			}
+			IEnumerator i = configuredAliases.GetEnumerator();
+			while (i.MoveNext())
+			{
+				string resolved = ((IAlias)i.Current).ResolveRuntimeName(runtimeType);
+				if (null != resolved)
+				{
+					return resolved;
+				}
+			}
+			return runtimeType;
+		}
+
+		public string ResolveAliasStoredName(string storedType)
+		{
+			Collection4 configuredAliases = Aliases();
+			if (null == configuredAliases)
+			{
+				return storedType;
+			}
+			IEnumerator i = configuredAliases.GetEnumerator();
+			while (i.MoveNext())
+			{
+				string resolved = ((IAlias)i.Current).ResolveStoredName(storedType);
+				if (null != resolved)
+				{
+					return resolved;
+				}
+			}
+			return storedType;
+		}
+
+		internal IReflectClass ReflectorFor(object clazz)
+		{
+			return ReflectorUtils.ReflectClassFor(Reflector(), clazz);
+		}
+
+		public bool AllowVersionUpdates()
+		{
+			return _config.GetAsBoolean(AllowVersionUpdatesKey);
+		}
+
+		public bool AutomaticShutDown()
+		{
+			return _config.GetAsBoolean(AutomaticShutdownKey);
+		}
+
+		public byte BlockSize()
+		{
+			return _config.GetAsByte(BlocksizeKey);
+		}
+
+		public int BTreeNodeSize()
+		{
+			return _config.GetAsInt(BtreeNodeSizeKey);
+		}
+
+		public string BlobPath()
+		{
+			return _config.GetAsString(BlobPathKey);
+		}
+
+		public CallBackMode CallbackMode()
+		{
+			return (CallBackMode)_config.Get(CallbacksKey);
+		}
+
+		public TernaryBool CallConstructors()
+		{
+			return _config.GetAsTernaryBool(CallConstructorsKey);
+		}
+
+		internal bool ClassActivationDepthConfigurable()
+		{
+			return _config.GetAsBoolean(ClassActivationDepthConfigurableKey);
+		}
+
+		internal object ClassLoader()
+		{
+			return _config.Get(ClassloaderKey);
+		}
+
+		public bool DetectSchemaChanges()
+		{
+			return _config.GetAsBoolean(DetectSchemaChangesKey);
+		}
+
+		public bool CommitRecoveryDisabled()
+		{
+			return _config.GetAsBoolean(DisableCommitRecoveryKey);
+		}
+
+		public IDiagnosticConfiguration Diagnostic()
+		{
+			return (IDiagnosticConfiguration)_config.Get(DiagnosticKey);
+		}
+
+		public Db4objects.Db4o.Internal.Diagnostic.DiagnosticProcessor DiagnosticProcessor
+			()
+		{
+			return (Db4objects.Db4o.Internal.Diagnostic.DiagnosticProcessor)_config.Get(DiagnosticKey
+				);
+		}
+
+		public int DiscardFreeSpace()
+		{
+			return _config.GetAsInt(DiscardFreespaceKey);
+		}
+
+		internal byte Encoding()
+		{
+			return _config.GetAsByte(EncodingKey);
+		}
+
+		internal bool Encrypt()
+		{
+			return _config.GetAsBoolean(EncryptKey);
+		}
+
+		public Hashtable4 ExceptionalClasses()
+		{
+			Hashtable4 exceptionalClasses = (Hashtable4)_config.Get(ExceptionalClassesKey);
+			if (exceptionalClasses == null)
+			{
+				exceptionalClasses = new Hashtable4(16);
+				_config.Put(ExceptionalClassesKey, exceptionalClasses);
+			}
+			return exceptionalClasses;
+		}
+
+		public bool ExceptionsOnNotStorable()
+		{
+			return _config.GetAsBoolean(ExceptionsOnNotStorableKey);
+		}
+
+		internal byte FreespaceSystem()
+		{
+			return _config.GetAsByte(FreespaceSystemKey);
+		}
+
+		public ConfigScope GenerateUUIDs()
+		{
+			return (ConfigScope)_config.Get(GenerateUuidsKey);
+		}
+
+		public TernaryBool GenerateCommitTimestamps()
+		{
+			return (TernaryBool)_config.Get(GenerateCommitTimestampsKey);
+		}
+
+		public bool InternStrings()
+		{
+			return _internStrings;
+		}
+
+		public bool LockFile()
+		{
+			return _config.GetAsBoolean(LockFileKey);
+		}
+
+		public int MessageLevel()
+		{
+			return _messageLevel;
+		}
+
+		public IMessageRecipient MessageRecipient()
+		{
+			return (IMessageRecipient)_config.Get(MessageRecipientKey);
+		}
+
+		internal bool OptimizeNQ()
+		{
+			return _config.GetAsBoolean(OptimizeNqKey);
+		}
+
+		internal string Password()
+		{
+			return _config.GetAsString(PasswordKey);
+		}
+
+		public void PrefetchIDCount(int prefetchIDCount)
+		{
+			_config.Put(PrefetchIdCountKey, prefetchIDCount);
+		}
+
+		public int PrefetchIDCount()
+		{
+			return _config.GetAsInt(PrefetchIdCountKey);
+		}
+
+		public void PrefetchObjectCount(int prefetchObjectCount)
+		{
+			_config.Put(PrefetchObjectCountKey, prefetchObjectCount);
+			EnsurePrefetchSlotCacheSize();
+		}
+
+		public int PrefetchObjectCount()
+		{
+			return _config.GetAsInt(PrefetchObjectCountKey);
+		}
+
+		public Hashtable4 ReadAs()
+		{
+			return (Hashtable4)_config.Get(ReadAsKey);
+		}
+
+		public bool IsReadOnly()
+		{
+			return _readOnly;
+		}
+
+		public void RecoveryMode(bool flag)
+		{
+			_config.Put(RecoveryModeKey, flag);
+		}
+
+		public bool RecoveryMode()
+		{
+			return _config.GetAsBoolean(RecoveryModeKey);
+		}
+
+		internal Collection4 Rename()
+		{
+			return (Collection4)_config.Get(RenameKey);
+		}
+
+		public int ReservedStorageSpace()
+		{
+			return _config.GetAsInt(ReservedStorageSpaceKey);
+		}
+
+		public bool SingleThreadedClient()
+		{
+			return _config.GetAsBoolean(SingleThreadedClientKey);
+		}
+
+		public bool TestConstructors()
+		{
+			return _config.GetAsBoolean(TestConstructorsKey);
+		}
+
+		public int TimeoutClientSocket()
+		{
+			return _config.GetAsInt(TimeoutClientSocketKey);
+		}
+
+		public int TimeoutServerSocket()
+		{
+			return _config.GetAsInt(TimeoutServerSocketKey);
+		}
+
+		public int UpdateDepth()
+		{
+			return _config.GetAsInt(UpdateDepthKey);
+		}
+
+		public int WeakReferenceCollectionInterval()
+		{
+			return _config.GetAsInt(WeakReferenceCollectionIntervalKey);
+		}
+
+		public bool WeakReferences()
+		{
+			return _config.GetAsBoolean(WeakReferencesKey);
+		}
+
+		public IoAdapter Io()
+		{
+			throw new NotImplementedException();
+		}
+
+		public IStorage Storage
+		{
+			get
+			{
+				return (IStorage)_config.Get(StorageFactoryKey);
+			}
+			set
+			{
+				IStorage factory = value;
+				_config.Put(StorageFactoryKey, factory);
+			}
+		}
+
+		public IQueryConfiguration Queries()
+		{
+			return this;
+		}
+
+		public void EvaluationMode(QueryEvaluationMode mode)
+		{
+			_config.Put(QueryEvaluationModeKey, mode);
+		}
+
+		public QueryEvaluationMode EvaluationMode()
+		{
+			return (QueryEvaluationMode)_config.Get(QueryEvaluationModeKey);
+		}
+
+		public void QueryResultIteratorFactory(IQueryResultIteratorFactory factory)
+		{
+			_config.Put(ClientQueryResultIteratorFactoryKey, factory);
+		}
+
+		public IQueryResultIteratorFactory QueryResultIteratorFactory()
+		{
+			return (IQueryResultIteratorFactory)_config.Get(ClientQueryResultIteratorFactoryKey
+				);
+		}
+
+		public IClientServerConfiguration ClientServer()
+		{
+			return this;
+		}
+
+		public void BatchMessages(bool flag)
+		{
+			_config.Put(BatchMessagesKey, flag);
+		}
+
+		public bool BatchMessages()
+		{
+			return _config.GetAsBoolean(BatchMessagesKey);
+		}
+
+		public void MaxBatchQueueSize(int maxSize)
+		{
+			_config.Put(MaxBatchQueueSizeKey, maxSize);
+		}
+
+		public int MaxBatchQueueSize()
+		{
+			return _config.GetAsInt(MaxBatchQueueSizeKey);
+		}
+
+		public void ActivationDepthProvider(IActivationDepthProvider provider)
+		{
+			_config.Put(ActivationDepthProviderKey, provider);
+		}
+
+		public void UpdateDepthProvider(IUpdateDepthProvider provider)
+		{
+			_config.Put(UpdateDepthProviderKey, provider);
+		}
+
+		public IActivationDepthProvider ActivationDepthProvider()
+		{
+			return (IActivationDepthProvider)_config.Get(ActivationDepthProviderKey);
+		}
+
+		public IUpdateDepthProvider UpdateDepthProvider()
+		{
+			return (IUpdateDepthProvider)_config.Get(UpdateDepthProviderKey);
+		}
+
+		public void RegisterTypeHandler(ITypeHandlerPredicate predicate, ITypeHandler4 typeHandler
+			)
+		{
+			if (_registeredTypeHandlers == null)
+			{
+				_registeredTypeHandlers = new Collection4();
+			}
+			_registeredTypeHandlers.Add(new TypeHandlerPredicatePair(predicate, typeHandler));
+		}
+
+		public ITypeHandler4 TypeHandlerForClass(IReflectClass classReflector, byte handlerVersion
+			)
+		{
+			if (_registeredTypeHandlers == null)
+			{
+				return null;
+			}
+			IEnumerator i = _registeredTypeHandlers.GetEnumerator();
+			while (i.MoveNext())
+			{
+				TypeHandlerPredicatePair pair = (TypeHandlerPredicatePair)i.Current;
+				if (pair._predicate.Match(classReflector))
+				{
+					return pair._typeHandler;
+				}
+			}
+			return null;
+		}
+
+		public class ConfigDeepCloneContext
+		{
+			public readonly Config4Impl _orig;
+
+			public readonly Config4Impl _cloned;
+
+			public ConfigDeepCloneContext(Config4Impl orig, Config4Impl cloned)
+			{
+				_orig = orig;
+				_cloned = cloned;
+			}
+		}
+
+		public void Factory(ILegacyClientServerFactory factory)
+		{
+			_config.Put(ClientServerFactoryKey, factory);
+		}
+
+		public ILegacyClientServerFactory ClientServerFactory()
+		{
+			return (ILegacyClientServerFactory)_config.Get(ClientServerFactoryKey);
+		}
+
+		public ICacheConfiguration Cache()
+		{
+			return new CacheConfigurationImpl(this);
+		}
+
+		public bool FileBasedTransactionLog()
+		{
+			return _config.GetAsBoolean(FileBasedTransactionLogKey);
+		}
+
+		public void FileBasedTransactionLog(bool flag)
+		{
+			_config.Put(FileBasedTransactionLogKey, flag);
+		}
+
+		private bool IsTainted()
+		{
+			return _config.GetAsBoolean(TaintedKey);
+		}
+
+		public void Taint()
+		{
+			_config.Put(TaintedKey, true);
+		}
+
+		public static void AssertIsNotTainted(IConfiguration config)
+		{
+			if (((Config4Impl)config).IsTainted())
+			{
+				throw new ArgumentException("Configuration already used.");
+			}
+		}
+
+		public void PrefetchDepth(int prefetchDepth)
+		{
+			_config.Put(PrefetchDepthKey, prefetchDepth);
+			EnsurePrefetchSlotCacheSize();
+		}
+
+		private void EnsurePrefetchSlotCacheSize()
+		{
+			if (!_prefetchSlotCacheSizeModifiedExternally)
+			{
+				PrefetchSlotCacheSize(CalculatedPrefetchSlotcacheSize());
+				_prefetchSlotCacheSizeModifiedExternally = false;
+			}
+		}
+
+		public int PrefetchDepth()
+		{
+			return _config.GetAsInt(PrefetchDepthKey);
+		}
+
+		public IList EnvironmentContributions()
+		{
+			return (IList)_config.Get(EnvironmentContributionsKey);
+		}
+
+		public void PrefetchSlotCacheSize(int slotCacheSize)
+		{
+			_prefetchSlotCacheSizeModifiedExternally = true;
+			_config.Put(PrefetchSlotCacheSizeKey, slotCacheSize);
+			if (null != _prefetchSettingsChanged) _prefetchSettingsChanged(null, EventArgs.Empty
+				);
+		}
+
+		public int PrefetchSlotCacheSize()
+		{
+			return _config.GetAsInt(PrefetchSlotCacheSizeKey);
+		}
+
+		private int CalculatedPrefetchSlotcacheSize()
+		{
+			long calculated = (long)PrefetchDepth() * PrefetchObjectCount() * PrefetchSlotCacheSizeFactor;
+			if (calculated > MaximumPrefetchSlotCacheSize)
+			{
+				calculated = MaximumPrefetchSlotCacheSize;
+			}
+			return (int)calculated;
+		}
+
+		public event System.EventHandler<EventArgs> PrefetchSettingsChanged
+		{
+			add
+			{
+				_prefetchSettingsChanged = (System.EventHandler<EventArgs>)System.Delegate.Combine
+					(_prefetchSettingsChanged, value);
+			}
+			remove
+			{
+				_prefetchSettingsChanged = (System.EventHandler<EventArgs>)System.Delegate.Remove
+					(_prefetchSettingsChanged, value);
+			}
+		}
+
+		public void ReferenceSystemFactory(IReferenceSystemFactory referenceSystemFactory
+			)
+		{
+			_config.Put(ReferenceSystemFactoryKey, referenceSystemFactory);
+		}
+
+		public IReferenceSystemFactory ReferenceSystemFactory()
+		{
+			return (IReferenceSystemFactory)_config.Get(ReferenceSystemFactoryKey);
+		}
+
+		public void NameProvider(INameProvider provider)
+		{
+			_config.Put(NameProviderKey, provider);
+		}
+
+		public INameProvider NameProvider()
+		{
+			return (INameProvider)_config.Get(NameProviderKey);
+		}
+
+		public void UsePointerBasedIdSystem()
+		{
+			_config.Put(IdSystemKey, StandardIdSystemFactory.PointerBased);
+		}
+
+		public void UseStackedBTreeIdSystem()
+		{
+			_config.Put(IdSystemKey, StandardIdSystemFactory.StackedBtree);
+		}
+
+		public void UseSingleBTreeIdSystem()
+		{
+			_config.Put(IdSystemKey, StandardIdSystemFactory.SingleBtree);
+		}
+
+		public byte IdSystemType()
+		{
+			return _config.GetAsByte(IdSystemKey);
+		}
+
+		public void UseInMemoryIdSystem()
+		{
+			_config.Put(IdSystemKey, StandardIdSystemFactory.InMemory);
+		}
+
+		public void UseCustomIdSystem(IIdSystemFactory factory)
+		{
+			_config.Put(IdSystemKey, StandardIdSystemFactory.Custom);
+			_config.Put(IdSystemCustomFactoryKey, factory);
+		}
+
+		public IIdSystemFactory CustomIdSystemFactory()
+		{
+			return (IIdSystemFactory)_config.Get(IdSystemCustomFactoryKey);
+		}
+
+		public void AsynchronousSync(bool flag)
+		{
+			_config.Put(AsynchronousSyncKey, flag);
+		}
+
+		public bool AsynchronousSync()
+		{
+			return _config.GetAsBoolean(AsynchronousSyncKey);
+		}
+
+		public int MaxStackDepth()
+		{
+			return _config.GetAsInt(MaxStackDepthKey);
+		}
+
+		public void MaxStackDepth(int maxStackDepth)
+		{
+			_config.Put(MaxStackDepthKey, maxStackDepth);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Const4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Const4.cs
new file mode 100644
index 0000000..931f0cd
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Const4.cs
@@ -0,0 +1,227 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Types;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude>TODO: Split into separate enums with defined range and values.</exclude>
+	public sealed partial class Const4
+	{
+		public const byte Yapfileversion = 4;
+
+		public const byte Yapbegin = (byte)'{';
+
+		public const byte Yapfile = (byte)'Y';
+
+		public const byte Yapid = (byte)'#';
+
+		public const byte Yappointer = (byte)'>';
+
+		public const byte Yapclasscollection = (byte)'A';
+
+		public const byte Yapclass = (byte)'C';
+
+		public const byte Yapfield = (byte)'F';
+
+		public const byte Yapobject = (byte)'O';
+
+		public const byte Yaparray = (byte)'N';
+
+		public const byte Yaparrayn = (byte)'Z';
+
+		public const byte Yapindex = (byte)'X';
+
+		public const byte Yapstring = (byte)'S';
+
+		public const byte Yaplong = (byte)'l';
+
+		public const byte Yapinteger = (byte)'i';
+
+		public const byte Yapboolean = (byte)'=';
+
+		public const byte Yapdouble = (byte)'d';
+
+		public const byte Yapbyte = (byte)'b';
+
+		public const byte Yapshort = (byte)'s';
+
+		public const byte Yapchar = (byte)'c';
+
+		public const byte Yapfloat = (byte)'f';
+
+		public const byte Yapend = (byte)'}';
+
+		public const byte Yapnull = (byte)'0';
+
+		public const byte Btree = (byte)'T';
+
+		public const byte BtreeNode = (byte)'B';
+
+		public const byte Header = (byte)'H';
+
+		public const byte IntegerArray = (byte)'I';
+
+		public const byte BtreeList = (byte)'L';
+
+		public const int IdentifierLength = (Deploy.debug && Deploy.identifiers) ? 1 : 0;
+
+		public const int BracketsBytes = (Deploy.debug && Deploy.brackets) ? 1 : 0;
+
+		public const int BracketsLength = BracketsBytes * 2;
+
+		public const int LeadingLength = IdentifierLength + BracketsBytes;
+
+		public const int AddedLength = IdentifierLength + BracketsLength;
+
+		public const int ShortBytes = 2;
+
+		public const int IntegerBytes = (Deploy.debug && Deploy.debugLong) ? 11 : 4;
+
+		public const int LongBytes = (Deploy.debug && Deploy.debugLong) ? 20 : 8;
+
+		public const int CharBytes = 2;
+
+		public const int Unspecified = int.MinValue + 100;
+
+		public const int IntLength = IntegerBytes + AddedLength;
+
+		public const int IdLength = IntLength;
+
+		public const int LongLength = LongBytes + AddedLength;
+
+		public const int IndirectionLength = IntLength + IdLength;
+
+		public const int WriteLoop = (IntegerBytes - 1) * 8;
+
+		public const int ObjectLength = AddedLength;
+
+		public const int PointerLength = (IntLength * 2) + AddedLength;
+
+		public const int MessageLength = IntLength * 2 + 1;
+
+		public const byte SystemTrans = (byte)'s';
+
+		public const byte UserTrans = (byte)'u';
+
+		public const byte Xbyte = (byte)'X';
+
+		public const int IgnoreId = -99999;
+
+		public const int Primitive = -2000000000;
+
+		public const int TypeArray = 3;
+
+		public const int TypeNarray = 4;
+
+		public const int None = 0;
+
+		public const int State = 1;
+
+		public const int Activation = 2;
+
+		public const int Transient = -1;
+
+		public const int AddMembersToIdTreeOnly = 0;
+
+		public const int AddToIdTree = 1;
+
+		public const int LockTimeInterval = 1000;
+
+		public const int ServerSocketTimeout = Debug4.longTimeOuts ? 1000000 : 600000;
+
+		public const int ClientSocketTimeout = ServerSocketTimeout;
+
+		public const int MaximumBlockSize = 70000000;
+
+		public const int MaximumArrayEntries = 7000000;
+
+		public const int MaximumArrayEntriesPrimitive = MaximumArrayEntries * 100;
+
+		public static readonly Type ClassCompare = typeof(ICompare);
+
+		public static readonly Type ClassDb4otype = typeof(IDb4oType);
+
+		public static readonly Type ClassDb4otypeimpl = typeof(IDb4oTypeImpl);
+
+		public static readonly Type ClassInternal = typeof(IInternal4);
+
+		public static readonly Type ClassUnversioned = typeof(IUnversioned);
+
+		public static readonly Type ClassObject = new object().GetType();
+
+		public static readonly Type ClassObjectcontainer = typeof(IObjectContainer);
+
+		public static readonly Type ClassStaticfield = new StaticField().GetType();
+
+		public static readonly Type ClassStaticclass = new StaticClass().GetType();
+
+		public static readonly Type ClassTransientclass = typeof(ITransientClass);
+
+		public static readonly string EmbeddedClientUser = "embedded client";
+
+		public const int Clean = 0;
+
+		public const int Active = 1;
+
+		public const int Processing = 2;
+
+		public const int CachedDirty = 3;
+
+		public const int Continue = 4;
+
+		public const int StaticFieldsStored = 5;
+
+		public const int CheckedChanges = 6;
+
+		public const int Dead = 7;
+
+		public const int Reading = 8;
+
+		public const int Activating = 9;
+
+		public const int Old = -1;
+
+		public const int New = 1;
+
+		public static readonly UnicodeStringIO stringIO = new UnicodeStringIO();
+
+		public static readonly Type[] EssentialClasses = new Type[] { ClassStaticfield, ClassStaticclass
+			 };
+
+		public static readonly string VirtualFieldPrefix = "v4o";
+
+		public const int InvalidObjectId = 1;
+
+		public const int DefaultMaxStackDepth = 20;
+		// make sure we don't fall over the -1 cliff
+		// TODO: Is this the right place for the knowledge, that an indirection
+		//       within a slot is an address and a length?
+		// debug constants
+		// TODO: This one is a terrible low-frequency blunder in YapArray.writeClass!!!
+		// If YapClass-ID == 99999 (not very likely) then we will get IGNORE_ID. Change
+		// to -Integer.MAX_VALUE or protect 99999 in YapFile.getPointerSlot() 
+		// This is a hard coded 2 Gig-Limit for YapClass-IDs.
+		// TODO: get rid of magic numbers like this one
+		// array type information
+		// message levels
+		// Use if > NONE: normal messages
+		// if > STATE: state messages
+		// if > ACTIVATION: activation messages
+		// Timings
+		// 10 minutes until clients are disconnected, (5 minutes until they get pinged) 
+		// TODO: Consider to make configurable
+		// 70 MB   
+		// 7 Million 
+		// 70 MB for byte arrays
+		// bits in PersistentBase.i_state
+		// and reuse in other classes 
+		// system classes that need to get loaded first
+		// StaticClass should load Staticfield
+		// TODO: remove unnecessary
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversion.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversion.cs
new file mode 100644
index 0000000..a6813da
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversion.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Convert;
+
+namespace Db4objects.Db4o.Internal.Convert
+{
+	/// <exclude></exclude>
+	public abstract class Conversion
+	{
+		/// <param name="stage"></param>
+		public virtual void Convert(ConversionStage.ClassCollectionAvailableStage stage)
+		{
+		}
+
+		/// <param name="stage"></param>
+		public virtual void Convert(ConversionStage.SystemUpStage stage)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/ConversionStage.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/ConversionStage.cs
new file mode 100644
index 0000000..e3b9785
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/ConversionStage.cs
@@ -0,0 +1,54 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Convert;
+
+namespace Db4objects.Db4o.Internal.Convert
+{
+	/// <exclude></exclude>
+	public abstract class ConversionStage
+	{
+		public sealed class ClassCollectionAvailableStage : ConversionStage
+		{
+			public ClassCollectionAvailableStage(LocalObjectContainer file) : base(file)
+			{
+			}
+
+			public override void Accept(Conversion conversion)
+			{
+				conversion.Convert(this);
+			}
+		}
+
+		public sealed class SystemUpStage : ConversionStage
+		{
+			public SystemUpStage(LocalObjectContainer file) : base(file)
+			{
+			}
+
+			public override void Accept(Conversion conversion)
+			{
+				conversion.Convert(this);
+			}
+		}
+
+		private LocalObjectContainer _file;
+
+		protected ConversionStage(LocalObjectContainer file)
+		{
+			_file = file;
+		}
+
+		public virtual LocalObjectContainer File()
+		{
+			return _file;
+		}
+
+		public virtual int ConverterVersion()
+		{
+			return _file.SystemData().ConverterVersion();
+		}
+
+		public abstract void Accept(Conversion conversion);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/ClassAspects_7_4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/ClassAspects_7_4.cs
new file mode 100644
index 0000000..b657051
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/ClassAspects_7_4.cs
@@ -0,0 +1,17 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Convert;
+
+namespace Db4objects.Db4o.Internal.Convert.Conversions
+{
+	/// <exclude></exclude>
+	public class ClassAspects_7_4 : Conversion
+	{
+		public const int Version = 7;
+
+		public override void Convert(ConversionStage.SystemUpStage stage)
+		{
+			stage.File().ClassCollection().WriteAllClasses();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/ClassIndexesToBTrees_5_5.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/ClassIndexesToBTrees_5_5.cs
new file mode 100644
index 0000000..558a11a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/ClassIndexesToBTrees_5_5.cs
@@ -0,0 +1,38 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Convert;
+
+namespace Db4objects.Db4o.Internal.Convert.Conversions
+{
+	/// <exclude></exclude>
+	public class ClassIndexesToBTrees_5_5 : Conversion
+	{
+		public const int Version = 5;
+
+		public virtual void Convert(LocalObjectContainer container, int classIndexId, BTree
+			 bTree)
+		{
+			Transaction trans = container.SystemTransaction();
+			ByteArrayBuffer reader = container.ReadBufferById(trans, classIndexId);
+			if (reader == null)
+			{
+				return;
+			}
+			int entries = reader.ReadInt();
+			for (int i = 0; i < entries; i++)
+			{
+				bTree.Add(trans, reader.ReadInt());
+			}
+		}
+
+		public override void Convert(ConversionStage.SystemUpStage stage)
+		{
+			// calling #storedClasses forces reading all classes
+			// That's good enough to load them all and to call the
+			// above convert method.
+			stage.File().StoredClasses();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/CommonConversions.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/CommonConversions.cs
new file mode 100644
index 0000000..f98e98e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/CommonConversions.cs
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Convert;
+using Db4objects.Db4o.Internal.Convert.Conversions;
+
+namespace Db4objects.Db4o.Internal.Convert.Conversions
+{
+	/// <exclude></exclude>
+	public class CommonConversions
+	{
+		public static void Register(Converter converter)
+		{
+			converter.Register(ClassIndexesToBTrees_5_5.Version, new ClassIndexesToBTrees_5_5
+				());
+			converter.Register(FieldIndexesToBTrees_5_7.Version, new FieldIndexesToBTrees_5_7
+				());
+			converter.Register(ClassAspects_7_4.Version, new ClassAspects_7_4());
+			converter.Register(ReindexNetDateTime_7_8.Version, new ReindexNetDateTime_7_8());
+			converter.Register(DropEnumClassIndexes_7_10.Version, new DropEnumClassIndexes_7_10
+				());
+			converter.Register(DropGuidClassIndexes_7_12.Version, new DropGuidClassIndexes_7_12
+				());
+			converter.Register(DropDateTimeOffsetClassIndexes_7_12.Version, new DropDateTimeOffsetClassIndexes_7_12
+				());
+			converter.Register(VersionNumberToCommitTimestamp_8_0.Version, new VersionNumberToCommitTimestamp_8_0
+				());
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/DropDateTimeOffsetClassIndexes_7_12.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/DropDateTimeOffsetClassIndexes_7_12.cs
new file mode 100644
index 0000000..dd122fd
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/DropDateTimeOffsetClassIndexes_7_12.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Convert.Conversions
+{
+	/// <exclude></exclude>
+	public partial class DropDateTimeOffsetClassIndexes_7_12
+	{
+		public const int Version = 11;
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/DropEnumClassIndexes_7_10.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/DropEnumClassIndexes_7_10.cs
new file mode 100644
index 0000000..ccbccd8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/DropEnumClassIndexes_7_10.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Convert.Conversions
+{
+	/// <exclude>*</exclude>
+	public partial class DropEnumClassIndexes_7_10
+	{
+		public const int Version = 9;
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/DropGuidClassIndexes_7_12.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/DropGuidClassIndexes_7_12.cs
new file mode 100644
index 0000000..96210e9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/DropGuidClassIndexes_7_12.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Convert.Conversions
+{
+	/// <exclude></exclude>
+	public partial class DropGuidClassIndexes_7_12
+	{
+		public const int Version = 10;
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/FieldIndexesToBTrees_5_7.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/FieldIndexesToBTrees_5_7.cs
new file mode 100644
index 0000000..a4e6940
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/FieldIndexesToBTrees_5_7.cs
@@ -0,0 +1,40 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Convert;
+
+namespace Db4objects.Db4o.Internal.Convert.Conversions
+{
+	/// <exclude></exclude>
+	public class FieldIndexesToBTrees_5_7 : Conversion
+	{
+		public const int Version = 6;
+
+		public override void Convert(ConversionStage.SystemUpStage stage)
+		{
+			stage.File().ClassCollection().WriteAllClasses();
+			RebuildUUIDIndex(stage.File());
+			FreeOldUUIDMetaIndex(stage.File());
+		}
+
+		private void RebuildUUIDIndex(LocalObjectContainer file)
+		{
+			UUIDFieldMetadata uuid = file.UUIDIndex();
+			ClassMetadataIterator i = file.ClassCollection().Iterator();
+			while (i.MoveNext())
+			{
+				ClassMetadata clazz = i.CurrentClass();
+				if (clazz.GenerateUUIDs())
+				{
+					uuid.RebuildIndexForClass(file, clazz);
+				}
+			}
+		}
+
+		/// <param name="file"></param>
+		private void FreeOldUUIDMetaIndex(LocalObjectContainer file)
+		{
+		}
+		// updating removed here to allow removing MetaIndex class
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/ReindexNetDateTime_7_8.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/ReindexNetDateTime_7_8.cs
new file mode 100644
index 0000000..064930a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/ReindexNetDateTime_7_8.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Convert.Conversions
+{
+	/// <exclude></exclude>
+	public partial class ReindexNetDateTime_7_8
+	{
+		public const int Version = 8;
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/VersionNumberToCommitTimestamp_8_0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/VersionNumberToCommitTimestamp_8_0.cs
new file mode 100644
index 0000000..2fdc5e8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Conversions/VersionNumberToCommitTimestamp_8_0.cs
@@ -0,0 +1,90 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Convert;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Convert.Conversions
+{
+	/// <exclude></exclude>
+	public class VersionNumberToCommitTimestamp_8_0 : Conversion
+	{
+		public const int Version = 12;
+
+		private VersionFieldMetadata versionFieldMetadata;
+
+		public override void Convert(ConversionStage.SystemUpStage stage)
+		{
+			LocalObjectContainer container = stage.File();
+			if (!container.Config().GenerateCommitTimestamps().DefiniteYes())
+			{
+				return;
+			}
+			container.ClassCollection().WriteAllClasses();
+			BuildCommitTimestampIndex(container);
+			container.SystemTransaction().Commit();
+		}
+
+		private void BuildCommitTimestampIndex(LocalObjectContainer container)
+		{
+			versionFieldMetadata = container.Handlers.Indexes()._version;
+			ClassMetadataIterator i = container.ClassCollection().Iterator();
+			while (i.MoveNext())
+			{
+				ClassMetadata clazz = i.CurrentClass();
+				if (clazz.HasVersionField() && !clazz.IsStruct())
+				{
+					RebuildIndexForClass(container, clazz);
+				}
+			}
+		}
+
+		public virtual bool RebuildIndexForClass(LocalObjectContainer container, ClassMetadata
+			 classMetadata)
+		{
+			long[] ids = classMetadata.GetIDs();
+			for (int i = 0; i < ids.Length; i++)
+			{
+				RebuildIndexForObject(container, (int)ids[i]);
+			}
+			return ids.Length > 0;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.FieldIndexException"></exception>
+		protected virtual void RebuildIndexForObject(LocalObjectContainer container, int 
+			objectId)
+		{
+			StatefulBuffer writer = container.ReadStatefulBufferById(container.SystemTransaction
+				(), objectId);
+			if (writer != null)
+			{
+				RebuildIndexForWriter(container, writer, objectId);
+			}
+		}
+
+		protected virtual void RebuildIndexForWriter(LocalObjectContainer container, StatefulBuffer
+			 buffer, int objectId)
+		{
+			ObjectHeader objectHeader = new ObjectHeader(container, buffer);
+			ObjectIdContextImpl context = new ObjectIdContextImpl(container.SystemTransaction
+				(), buffer, objectHeader, objectId);
+			ClassMetadata classMetadata = context.ClassMetadata();
+			if (classMetadata.IsStruct())
+			{
+				// We don't keep version information for structs.
+				return;
+			}
+			if (classMetadata.SeekToField(container.SystemTransaction(), buffer, versionFieldMetadata
+				) != HandlerVersion.Invalid)
+			{
+				long version = ((long)versionFieldMetadata.Read(context));
+				if (version != 0)
+				{
+					LocalTransaction t = (LocalTransaction)container.SystemTransaction();
+					t.CommitTimestampSupport().Put(container.SystemTransaction(), objectId, version);
+				}
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Converter.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Converter.cs
new file mode 100644
index 0000000..e808141
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Convert/Converter.cs
@@ -0,0 +1,87 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Internal.Convert;
+using Db4objects.Db4o.Internal.Convert.Conversions;
+
+namespace Db4objects.Db4o.Internal.Convert
+{
+	/// <exclude></exclude>
+	public class Converter
+	{
+		public const int Version = VersionNumberToCommitTimestamp_8_0.Version;
+
+		public static bool Convert(ConversionStage stage)
+		{
+			if (!NeedsConversion(stage.ConverterVersion()))
+			{
+				return false;
+			}
+			return Instance().RunConversions(stage);
+		}
+
+		private static Db4objects.Db4o.Internal.Convert.Converter _instance;
+
+		private IDictionary _conversions;
+
+		private int _minimumVersion = int.MaxValue;
+
+		private Converter()
+		{
+			_conversions = new Hashtable();
+			// TODO: There probably will be Java and .NET conversions
+			//       Create Platform4.registerConversions() method ann
+			//       call from here when needed.
+			CommonConversions.Register(this);
+		}
+
+		public static Db4objects.Db4o.Internal.Convert.Converter Instance()
+		{
+			if (_instance == null)
+			{
+				_instance = new Db4objects.Db4o.Internal.Convert.Converter();
+			}
+			return _instance;
+		}
+
+		public virtual Conversion ConversionFor(int version)
+		{
+			return ((Conversion)_conversions[version]);
+		}
+
+		private static bool NeedsConversion(int converterVersion)
+		{
+			return converterVersion < Version;
+		}
+
+		public virtual void Register(int introducedVersion, Conversion conversion)
+		{
+			if (_conversions.Contains(introducedVersion))
+			{
+				throw new InvalidOperationException();
+			}
+			if (introducedVersion < _minimumVersion)
+			{
+				_minimumVersion = introducedVersion;
+			}
+			_conversions[introducedVersion] = conversion;
+		}
+
+		public virtual bool RunConversions(ConversionStage stage)
+		{
+			int startingVersion = Math.Max(stage.ConverterVersion() + 1, _minimumVersion);
+			for (int version = startingVersion; version <= Version; version++)
+			{
+				Conversion conversion = ConversionFor(version);
+				if (conversion == null)
+				{
+					throw new InvalidOperationException("Could not find a conversion for version " + 
+						version);
+				}
+				stage.Accept(conversion);
+			}
+			return true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/DefragmentContextImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/DefragmentContextImpl.cs
new file mode 100644
index 0000000..c39f188
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/DefragmentContextImpl.cs
@@ -0,0 +1,480 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Defragment;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Internal.Mapping;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public sealed class DefragmentContextImpl : IReadWriteBuffer, IDefragmentContext
+	{
+		private ByteArrayBuffer _source;
+
+		private ByteArrayBuffer _target;
+
+		private IDefragmentServices _services;
+
+		private readonly ObjectHeader _objectHeader;
+
+		private int _declaredAspectCount;
+
+		private int _currentParentSourceID;
+
+		public DefragmentContextImpl(ByteArrayBuffer source, Db4objects.Db4o.Internal.DefragmentContextImpl
+			 context) : this(source, context._services, context._objectHeader)
+		{
+		}
+
+		public DefragmentContextImpl(ByteArrayBuffer source, IDefragmentServices services
+			) : this(source, services, null)
+		{
+		}
+
+		public DefragmentContextImpl(ByteArrayBuffer source, IDefragmentServices services
+			, ObjectHeader header)
+		{
+			_source = source;
+			_services = services;
+			_target = new ByteArrayBuffer(Length());
+			_source.CopyTo(_target, 0, 0, Length());
+			_objectHeader = header;
+		}
+
+		public DefragmentContextImpl(Db4objects.Db4o.Internal.DefragmentContextImpl parentContext
+			, ObjectHeader header)
+		{
+			_source = parentContext._source;
+			_target = parentContext._target;
+			_services = parentContext._services;
+			_objectHeader = header;
+		}
+
+		public int Offset()
+		{
+			return _source.Offset();
+		}
+
+		public void Seek(int offset)
+		{
+			_source.Seek(offset);
+			_target.Seek(offset);
+		}
+
+		public void IncrementOffset(int numBytes)
+		{
+			_source.IncrementOffset(numBytes);
+			_target.IncrementOffset(numBytes);
+		}
+
+		public void IncrementIntSize()
+		{
+			IncrementOffset(Const4.IntLength);
+		}
+
+		public int CopySlotlessID()
+		{
+			return CopyUnindexedId(false);
+		}
+
+		public int CopyUnindexedID()
+		{
+			return CopyUnindexedId(true);
+		}
+
+		private int CopyUnindexedId(bool doRegister)
+		{
+			int orig = _source.ReadInt();
+			// TODO: There is no test case for the zero case
+			if (orig == 0)
+			{
+				_target.WriteInt(0);
+				return 0;
+			}
+			int mapped = -1;
+			try
+			{
+				mapped = _services.StrictMappedID(orig);
+			}
+			catch (MappingNotFoundException)
+			{
+				mapped = _services.TargetNewId();
+				_services.MapIDs(orig, mapped, false);
+				if (doRegister)
+				{
+					_services.RegisterUnindexed(orig);
+				}
+			}
+			_target.WriteInt(mapped);
+			return mapped;
+		}
+
+		public int CopyID()
+		{
+			// This code is slightly redundant. 
+			// The profiler shows it's a hotspot.
+			// The following would be non-redudant. 
+			// return copy(false, false);
+			int id = _source.ReadInt();
+			return WriteMappedID(id);
+		}
+
+		public int CopyID(bool flipNegative)
+		{
+			int id = _source.ReadInt();
+			return InternalCopyID(flipNegative, id);
+		}
+
+		public int CopyIDReturnOriginalID()
+		{
+			return CopyIDReturnOriginalID(false);
+		}
+
+		public int CopyIDReturnOriginalID(bool flipNegative)
+		{
+			int id = _source.ReadInt();
+			InternalCopyID(flipNegative, id);
+			bool flipped = flipNegative && (id < 0);
+			if (flipped)
+			{
+				return -id;
+			}
+			return id;
+		}
+
+		private int InternalCopyID(bool flipNegative, int id)
+		{
+			bool flipped = flipNegative && (id < 0);
+			if (flipped)
+			{
+				id = -id;
+			}
+			int mapped = _services.MappedID(id);
+			if (flipped)
+			{
+				mapped = -mapped;
+			}
+			_target.WriteInt(mapped);
+			return mapped;
+		}
+
+		public void ReadBegin(byte identifier)
+		{
+			_source.ReadBegin(identifier);
+			_target.ReadBegin(identifier);
+		}
+
+		public byte ReadByte()
+		{
+			byte value = _source.ReadByte();
+			_target.IncrementOffset(1);
+			return value;
+		}
+
+		public void ReadBytes(byte[] bytes)
+		{
+			_source.ReadBytes(bytes);
+			_target.IncrementOffset(bytes.Length);
+		}
+
+		public int ReadInt()
+		{
+			int value = _source.ReadInt();
+			_target.IncrementOffset(Const4.IntLength);
+			return value;
+		}
+
+		public void WriteInt(int value)
+		{
+			_source.IncrementOffset(Const4.IntLength);
+			_target.WriteInt(value);
+		}
+
+		public void Write(LocalObjectContainer file, int address)
+		{
+			file.WriteBytes(_target, address, 0);
+		}
+
+		public void IncrementStringOffset(LatinStringIO sio)
+		{
+			IncrementStringOffset(sio, _source);
+			IncrementStringOffset(sio, _target);
+		}
+
+		private void IncrementStringOffset(LatinStringIO sio, ByteArrayBuffer buffer)
+		{
+			sio.ReadLengthAndString(buffer);
+		}
+
+		public ByteArrayBuffer SourceBuffer()
+		{
+			return _source;
+		}
+
+		public ByteArrayBuffer TargetBuffer()
+		{
+			return _target;
+		}
+
+		public IIDMapping Mapping()
+		{
+			return _services;
+		}
+
+		public Db4objects.Db4o.Internal.Transaction SystemTrans()
+		{
+			return Transaction();
+		}
+
+		public IDefragmentServices Services()
+		{
+			return _services;
+		}
+
+		public static void ProcessCopy(IDefragmentServices context, int sourceID, ISlotCopyHandler
+			 command)
+		{
+			ByteArrayBuffer sourceReader = context.SourceBufferByID(sourceID);
+			ProcessCopy(context, sourceID, command, sourceReader);
+		}
+
+		public static void ProcessCopy(IDefragmentServices services, int sourceID, ISlotCopyHandler
+			 command, ByteArrayBuffer sourceReader)
+		{
+			int targetID = services.StrictMappedID(sourceID);
+			Slot targetSlot = services.AllocateTargetSlot(sourceReader.Length());
+			services.Mapping().MapId(targetID, targetSlot);
+			Db4objects.Db4o.Internal.DefragmentContextImpl context = new Db4objects.Db4o.Internal.DefragmentContextImpl
+				(sourceReader, services);
+			command.ProcessCopy(context);
+			services.TargetWriteBytes(context, targetSlot.Address());
+		}
+
+		public void WriteByte(byte value)
+		{
+			_source.IncrementOffset(1);
+			_target.WriteByte(value);
+		}
+
+		public long ReadLong()
+		{
+			long value = _source.ReadLong();
+			_target.IncrementOffset(Const4.LongLength);
+			return value;
+		}
+
+		public void WriteLong(long value)
+		{
+			_source.IncrementOffset(Const4.LongLength);
+			_target.WriteLong(value);
+		}
+
+		public BitMap4 ReadBitMap(int bitCount)
+		{
+			BitMap4 value = _source.ReadBitMap(bitCount);
+			_target.IncrementOffset(value.MarshalledLength());
+			return value;
+		}
+
+		public void ReadEnd()
+		{
+			_source.ReadEnd();
+			_target.ReadEnd();
+		}
+
+		public int WriteMappedID(int originalID)
+		{
+			int mapped = _services.MappedID(originalID);
+			_target.WriteInt(mapped);
+			return mapped;
+		}
+
+		public int Length()
+		{
+			return _source.Length();
+		}
+
+		public Db4objects.Db4o.Internal.Transaction Transaction()
+		{
+			return Services().SystemTrans();
+		}
+
+		public ObjectContainerBase Container()
+		{
+			return Transaction().Container();
+		}
+
+		public ITypeHandler4 TypeHandlerForId(int id)
+		{
+			return Container().TypeHandlerForClassMetadataID(id);
+		}
+
+		public int HandlerVersion()
+		{
+			return _objectHeader.HandlerVersion();
+		}
+
+		public bool IsLegacyHandlerVersion()
+		{
+			return HandlerVersion() == 0;
+		}
+
+		public int MappedID(int origID)
+		{
+			return Mapping().StrictMappedID(origID);
+		}
+
+		public IObjectContainer ObjectContainer()
+		{
+			return Container();
+		}
+
+		/// <summary>only used by old handlers: OpenTypeHandler0, StringHandler0, ArrayHandler0.
+		/// 	</summary>
+		/// <remarks>
+		/// only used by old handlers: OpenTypeHandler0, StringHandler0, ArrayHandler0.
+		/// Doesn't need to work with modern IdSystems.
+		/// </remarks>
+		public Slot AllocateTargetSlot(int length)
+		{
+			return _services.AllocateTargetSlot(length);
+		}
+
+		/// <summary>only used by old handlers: OpenTypeHandler0, StringHandler0, ArrayHandler0.
+		/// 	</summary>
+		/// <remarks>
+		/// only used by old handlers: OpenTypeHandler0, StringHandler0, ArrayHandler0.
+		/// Doesn't need to work with modern IdSystems.
+		/// </remarks>
+		public Slot AllocateMappedTargetSlot(int sourceAddress, int length)
+		{
+			Slot slot = AllocateTargetSlot(length);
+			_services.MapIDs(sourceAddress, slot.Address(), false);
+			return slot;
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public int CopySlotToNewMapped(int sourceAddress, int length)
+		{
+			Slot slot = AllocateMappedTargetSlot(sourceAddress, length);
+			ByteArrayBuffer sourceBuffer = SourceBufferByAddress(sourceAddress, length);
+			TargetWriteBytes(slot.Address(), sourceBuffer);
+			return slot.Address();
+		}
+
+		public void TargetWriteBytes(int address, ByteArrayBuffer buffer)
+		{
+			_services.TargetWriteBytes(buffer, address);
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public ByteArrayBuffer SourceBufferByAddress(int sourceAddress, int length)
+		{
+			ByteArrayBuffer sourceBuffer = _services.SourceBufferByAddress(sourceAddress, length
+				);
+			return sourceBuffer;
+		}
+
+		/// <exception cref="System.IO.IOException"></exception>
+		public ByteArrayBuffer SourceBufferById(int sourceId)
+		{
+			ByteArrayBuffer sourceBuffer = _services.SourceBufferByID(sourceId);
+			return sourceBuffer;
+		}
+
+		public void WriteToTarget(int address)
+		{
+			_services.TargetWriteBytes(this, address);
+		}
+
+		public void WriteBytes(byte[] bytes)
+		{
+			_target.WriteBytes(bytes);
+			_source.IncrementOffset(bytes.Length);
+		}
+
+		public IReadBuffer Buffer()
+		{
+			return _source;
+		}
+
+		public void Defragment(ITypeHandler4 handler)
+		{
+			ITypeHandler4 typeHandler = HandlerRegistry.CorrectHandlerVersion(this, handler);
+			if (Handlers4.UseDedicatedSlot(this, typeHandler))
+			{
+				if (Handlers4.HasClassIndex(typeHandler))
+				{
+					CopyID();
+				}
+				else
+				{
+					CopyUnindexedID();
+				}
+				return;
+			}
+			typeHandler.Defragment(this);
+		}
+
+		public void BeginSlot()
+		{
+		}
+
+		// do nothing
+		public Db4objects.Db4o.Internal.ClassMetadata ClassMetadata()
+		{
+			return _objectHeader.ClassMetadata();
+		}
+
+		public bool IsNull(int fieldIndex)
+		{
+			return _objectHeader._headerAttributes.IsNull(fieldIndex);
+		}
+
+		public int DeclaredAspectCount()
+		{
+			return _declaredAspectCount;
+		}
+
+		public void DeclaredAspectCount(int count)
+		{
+			_declaredAspectCount = count;
+		}
+
+		public Db4objects.Db4o.Internal.Marshall.SlotFormat SlotFormat()
+		{
+			return Db4objects.Db4o.Internal.Marshall.SlotFormat.ForHandlerVersion(HandlerVersion
+				());
+		}
+
+		public void CurrentParentSourceID(int id)
+		{
+			_currentParentSourceID = id;
+		}
+
+		public int ConsumeCurrentParentSourceID()
+		{
+			int id = _currentParentSourceID;
+			_currentParentSourceID = 0;
+			return id;
+		}
+
+		public void CopyAddress()
+		{
+			int sourceEntryAddress = _source.ReadInt();
+			int sourceId = ConsumeCurrentParentSourceID();
+			int sourceObjectAddress = _services.SourceAddressByID(sourceId);
+			int entryOffset = sourceEntryAddress - sourceObjectAddress;
+			int targetObjectAddress = _services.TargetAddressByID(_services.StrictMappedID(sourceId
+				));
+			_target.WriteInt(targetObjectAddress + entryOffset);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Delete/DeleteContextImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Delete/DeleteContextImpl.cs
new file mode 100644
index 0000000..bb09d88
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Delete/DeleteContextImpl.cs
@@ -0,0 +1,122 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Diagnostic;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Diagnostic;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Delete
+{
+	/// <exclude></exclude>
+	public class DeleteContextImpl : ObjectHeaderContext, IDeleteContext, IObjectIdContext
+	{
+		private readonly IReflectClass _fieldClass;
+
+		private readonly Config4Field _fieldConfig;
+
+		public DeleteContextImpl(Db4objects.Db4o.Internal.StatefulBuffer buffer, ObjectHeader
+			 objectHeader, IReflectClass fieldClass, Config4Field fieldConfig) : base(buffer
+			.Transaction(), buffer, objectHeader)
+		{
+			_fieldClass = fieldClass;
+			_fieldConfig = fieldConfig;
+		}
+
+		public DeleteContextImpl(Db4objects.Db4o.Internal.Delete.DeleteContextImpl parentContext
+			, IReflectClass fieldClass, Config4Field fieldConfig) : this(parentContext.StatefulBuffer
+			(), parentContext._objectHeader, fieldClass, fieldConfig)
+		{
+		}
+
+		public virtual void CascadeDeleteDepth(int depth)
+		{
+			StatefulBuffer().SetCascadeDeletes(depth);
+		}
+
+		private Db4objects.Db4o.Internal.StatefulBuffer StatefulBuffer()
+		{
+			return ((Db4objects.Db4o.Internal.StatefulBuffer)Buffer());
+		}
+
+		public virtual int CascadeDeleteDepth()
+		{
+			return StatefulBuffer().CascadeDeletes();
+		}
+
+		public virtual bool CascadeDelete()
+		{
+			return CascadeDeleteDepth() > 0;
+		}
+
+		public virtual void DefragmentRecommended()
+		{
+			DiagnosticProcessor dp = Container()._handlers.DiagnosticProcessor();
+			if (dp.Enabled())
+			{
+				dp.DefragmentRecommended(DefragmentRecommendation.DefragmentRecommendationReason.
+					DeleteEmbeded);
+			}
+		}
+
+		public virtual Slot ReadSlot()
+		{
+			return new Slot(Buffer().ReadInt(), Buffer().ReadInt());
+		}
+
+		public virtual void Delete(ITypeHandler4 handler)
+		{
+			ITypeHandler4 correctHandlerVersion = HandlerRegistry.CorrectHandlerVersion(this, 
+				handler);
+			int preservedCascadeDepth = CascadeDeleteDepth();
+			CascadeDeleteDepth(AdjustedDepth());
+			if (Handlers4.HandleAsObject(correctHandlerVersion))
+			{
+				DeleteObject();
+			}
+			else
+			{
+				correctHandlerVersion.Delete(this);
+			}
+			CascadeDeleteDepth(preservedCascadeDepth);
+		}
+
+		public virtual void DeleteObject()
+		{
+			int id = Buffer().ReadInt();
+			if (CascadeDelete())
+			{
+				Container().DeleteByID(Transaction(), id, CascadeDeleteDepth());
+			}
+		}
+
+		private int AdjustedDepth()
+		{
+			if (Platform4.IsStruct(_fieldClass))
+			{
+				return 1;
+			}
+			if (_fieldConfig == null)
+			{
+				return CascadeDeleteDepth();
+			}
+			if (_fieldConfig.CascadeOnDelete().DefiniteYes())
+			{
+				return 1;
+			}
+			if (_fieldConfig.CascadeOnDelete().DefiniteNo())
+			{
+				return 0;
+			}
+			return CascadeDeleteDepth();
+		}
+
+		public virtual int ObjectId()
+		{
+			return StatefulBuffer().GetID();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Delete/IDeleteContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Delete/IDeleteContext.cs
new file mode 100644
index 0000000..f406948
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Delete/IDeleteContext.cs
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Delete
+{
+	/// <exclude></exclude>
+	public interface IDeleteContext : IContext, IReadBuffer, IHandlerVersionContext
+	{
+		bool CascadeDelete();
+
+		int CascadeDeleteDepth();
+
+		void Delete(ITypeHandler4 handler);
+
+		void DeleteObject();
+
+		bool IsLegacyHandlerVersion();
+
+		void DefragmentRecommended();
+
+		Slot ReadSlot();
+
+		int ObjectId();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/DeleteInfo.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/DeleteInfo.cs
new file mode 100644
index 0000000..9ea75a3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/DeleteInfo.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class DeleteInfo : TreeInt
+	{
+		internal int _cascade;
+
+		public ObjectReference _reference;
+
+		public DeleteInfo(int id, ObjectReference reference, int cascade) : base(id)
+		{
+			_reference = reference;
+			_cascade = cascade;
+		}
+
+		public override object ShallowClone()
+		{
+			Db4objects.Db4o.Internal.DeleteInfo deleteinfo = new Db4objects.Db4o.Internal.DeleteInfo
+				(0, _reference, _cascade);
+			return ShallowCloneInternal(deleteinfo);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Diagnostic/DiagnosticProcessor.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Diagnostic/DiagnosticProcessor.cs
new file mode 100644
index 0000000..bf454b3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Diagnostic/DiagnosticProcessor.cs
@@ -0,0 +1,153 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Diagnostic;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Diagnostic
+{
+	/// <exclude>FIXME: remove me from the core and make me a facade over Events</exclude>
+	public class DiagnosticProcessor : IDiagnosticConfiguration, IDeepClone
+	{
+		private Collection4 _listeners;
+
+		public DiagnosticProcessor()
+		{
+		}
+
+		private DiagnosticProcessor(Collection4 listeners)
+		{
+			_listeners = listeners;
+		}
+
+		public virtual void AddListener(IDiagnosticListener listener)
+		{
+			if (_listeners == null)
+			{
+				_listeners = new Collection4();
+			}
+			_listeners.Add(listener);
+		}
+
+		public virtual void CheckClassHasFields(ClassMetadata classMetadata)
+		{
+			if (classMetadata.AspectsAreNull() || classMetadata.DeclaredAspectCount() == 0)
+			{
+				string name = classMetadata.GetName();
+				string[] ignoredPackages = new string[] { "java.util." };
+				for (int i = 0; i < ignoredPackages.Length; i++)
+				{
+					if (name.IndexOf(ignoredPackages[i]) == 0)
+					{
+						return;
+					}
+				}
+				if (IsDb4oClass(classMetadata))
+				{
+					return;
+				}
+				OnDiagnostic(new ClassHasNoFields(name));
+			}
+		}
+
+		public virtual void CheckUpdateDepth(int depth)
+		{
+			if (depth > 1)
+			{
+				OnDiagnostic(new UpdateDepthGreaterOne(depth));
+			}
+		}
+
+		public virtual object DeepClone(object context)
+		{
+			return new Db4objects.Db4o.Internal.Diagnostic.DiagnosticProcessor(CloneListeners
+				());
+		}
+
+		public virtual void DeletionFailed()
+		{
+			OnDiagnostic(new Db4objects.Db4o.Diagnostic.DeletionFailed());
+		}
+
+		public virtual void DefragmentRecommended(DefragmentRecommendation.DefragmentRecommendationReason
+			 reason)
+		{
+			OnDiagnostic(new DefragmentRecommendation(reason));
+		}
+
+		private Collection4 CloneListeners()
+		{
+			return _listeners != null ? new Collection4(_listeners) : null;
+		}
+
+		public virtual bool Enabled()
+		{
+			return _listeners != null;
+		}
+
+		private bool IsDb4oClass(ClassMetadata classMetadata)
+		{
+			return classMetadata.IsInternal();
+		}
+
+		public virtual void LoadedFromClassIndex(ClassMetadata classMetadata)
+		{
+			if (IsDb4oClass(classMetadata))
+			{
+				return;
+			}
+			OnDiagnostic(new Db4objects.Db4o.Diagnostic.LoadedFromClassIndex(classMetadata.GetName
+				()));
+		}
+
+		public virtual void DescendIntoTranslator(ClassMetadata parent, string fieldName)
+		{
+			OnDiagnostic(new Db4objects.Db4o.Diagnostic.DescendIntoTranslator(parent.GetName(
+				), fieldName));
+		}
+
+		public virtual void NativeQueryUnoptimized(Predicate predicate, Exception exception
+			)
+		{
+			OnDiagnostic(new NativeQueryNotOptimized(predicate, exception));
+		}
+
+		public virtual void NativeQueryOptimizerNotLoaded(int reason, Exception e)
+		{
+			OnDiagnostic(new Db4objects.Db4o.Diagnostic.NativeQueryOptimizerNotLoaded(reason, 
+				e));
+		}
+
+		public virtual void ObjectFieldDoesNotExist(string className, string fieldName)
+		{
+			OnDiagnostic(new Db4objects.Db4o.Diagnostic.ObjectFieldDoesNotExist(className, fieldName
+				));
+		}
+
+		public virtual void ClassMissed(string className)
+		{
+			OnDiagnostic(new MissingClass(className));
+		}
+
+		public virtual void OnDiagnostic(IDiagnostic d)
+		{
+			if (_listeners == null)
+			{
+				return;
+			}
+			IEnumerator i = _listeners.GetEnumerator();
+			while (i.MoveNext())
+			{
+				((IDiagnosticListener)i.Current).OnDiagnostic(d);
+			}
+		}
+
+		public virtual void RemoveAllListeners()
+		{
+			_listeners = null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/DisabledBlockConverter.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/DisabledBlockConverter.cs
new file mode 100644
index 0000000..66569e9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/DisabledBlockConverter.cs
@@ -0,0 +1,36 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class DisabledBlockConverter : IBlockConverter
+	{
+		public virtual int BlockAlignedBytes(int bytes)
+		{
+			return bytes;
+		}
+
+		public virtual int BlocksToBytes(int blocks)
+		{
+			return blocks;
+		}
+
+		public virtual int BytesToBlocks(long bytes)
+		{
+			return (int)bytes;
+		}
+
+		public virtual Slot ToBlockedLength(Slot slot)
+		{
+			return slot;
+		}
+
+		public virtual Slot ToNonBlockedLength(Slot slot)
+		{
+			return slot;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/BuiltInStringEncoding.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/BuiltInStringEncoding.cs
new file mode 100644
index 0000000..a68bb1f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/BuiltInStringEncoding.cs
@@ -0,0 +1,62 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Config.Encoding;
+using Db4objects.Db4o.Internal.Encoding;
+
+namespace Db4objects.Db4o.Internal.Encoding
+{
+	/// <exclude></exclude>
+	public abstract class BuiltInStringEncoding : IStringEncoding
+	{
+		/// <summary>keep the position in the array.</summary>
+		/// <remarks>
+		/// keep the position in the array.
+		/// Information is used to look up encodings.
+		/// </remarks>
+		private static readonly BuiltInStringEncoding[] AllEncodings = new BuiltInStringEncoding
+			[] { null, new LatinStringEncoding(), new UnicodeStringEncoding(), new UTF8StringEncoding
+			() };
+
+		public static byte EncodingByteForEncoding(IStringEncoding encoding)
+		{
+			for (int i = 1; i < AllEncodings.Length; i++)
+			{
+				if (encoding.GetType() == AllEncodings[i].GetType())
+				{
+					return (byte)i;
+				}
+			}
+			return 0;
+		}
+
+		public static LatinStringIO StringIoForEncoding(byte encodingByte, IStringEncoding
+			 encoding)
+		{
+			if (encodingByte < 0 || encodingByte > AllEncodings.Length)
+			{
+				throw new ArgumentException();
+			}
+			if (encodingByte == 0)
+			{
+				if (encoding is BuiltInStringEncoding)
+				{
+					Sharpen.Runtime.Out.WriteLine("Warning! Database was created with a custom string encoding but no custom string encoding is configured for this session."
+						);
+				}
+				return new DelegatingStringIO(encoding);
+			}
+			BuiltInStringEncoding builtInEncoding = AllEncodings[encodingByte];
+			return builtInEncoding.CreateStringIo(encoding);
+		}
+
+		protected virtual LatinStringIO CreateStringIo(IStringEncoding encoding)
+		{
+			return new DelegatingStringIO(encoding);
+		}
+
+		public abstract string Decode(byte[] arg1, int arg2, int arg3);
+
+		public abstract byte[] Encode(string arg1);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/DelegatingStringIO.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/DelegatingStringIO.cs
new file mode 100644
index 0000000..46ec5dc
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/DelegatingStringIO.cs
@@ -0,0 +1,93 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config.Encoding;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Encoding
+{
+	/// <exclude></exclude>
+	public class DelegatingStringIO : LatinStringIO
+	{
+		private readonly IStringEncoding _encoding;
+
+		public DelegatingStringIO(IStringEncoding encoding)
+		{
+			_encoding = encoding;
+		}
+
+		private string Decode(byte[] bytes, int start, int length)
+		{
+			return _encoding.Decode(bytes, start, length);
+		}
+
+		private byte[] Encode(string str)
+		{
+			return _encoding.Encode(str);
+		}
+
+		public override byte EncodingByte()
+		{
+			if (_encoding is BuiltInStringEncoding)
+			{
+				return BuiltInStringEncoding.EncodingByteForEncoding(_encoding);
+			}
+			return 0;
+		}
+
+		public override int Length(string str)
+		{
+			return Encode(str).Length + Const4.ObjectLength + Const4.IntLength;
+		}
+
+		public override string Read(IReadBuffer buffer, int length)
+		{
+			byte[] bytes = new byte[length];
+			buffer.ReadBytes(bytes);
+			return Decode(bytes, 0, bytes.Length);
+		}
+
+		public override string Read(byte[] bytes)
+		{
+			return Decode(bytes, 0, bytes.Length);
+		}
+
+		public override int ShortLength(string str)
+		{
+			return Encode(str).Length + Const4.IntLength;
+		}
+
+		public override void Write(IWriteBuffer buffer, string str)
+		{
+			buffer.WriteBytes(Encode(str));
+		}
+
+		public override byte[] Write(string str)
+		{
+			return Encode(str);
+		}
+
+		/// <summary>
+		/// Note the different implementation when compared to LatinStringIO and UnicodeStringIO:
+		/// Instead of writing the length of the string, UTF8StringIO writes the length of the
+		/// byte array.
+		/// </summary>
+		/// <remarks>
+		/// Note the different implementation when compared to LatinStringIO and UnicodeStringIO:
+		/// Instead of writing the length of the string, UTF8StringIO writes the length of the
+		/// byte array.
+		/// </remarks>
+		public override void WriteLengthAndString(IWriteBuffer buffer, string str)
+		{
+			if (str == null)
+			{
+				buffer.WriteInt(0);
+				return;
+			}
+			byte[] bytes = Encode(str);
+			buffer.WriteInt(bytes.Length);
+			buffer.WriteBytes(bytes);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/LatinStringEncoding.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/LatinStringEncoding.cs
new file mode 100644
index 0000000..3267f09
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/LatinStringEncoding.cs
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Config.Encoding;
+using Db4objects.Db4o.Internal.Encoding;
+
+namespace Db4objects.Db4o.Internal.Encoding
+{
+	/// <exclude></exclude>
+	public class LatinStringEncoding : BuiltInStringEncoding
+	{
+		public override string Decode(byte[] bytes, int start, int length)
+		{
+			throw new NotImplementedException();
+		}
+
+		// special StringIO, should never be called
+		public override byte[] Encode(string str)
+		{
+			throw new NotImplementedException();
+		}
+
+		// special StringIO, should never be called
+		protected override LatinStringIO CreateStringIo(IStringEncoding encoding)
+		{
+			return new LatinStringIO();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/LatinStringIO.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/LatinStringIO.cs
new file mode 100644
index 0000000..65a5843
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/LatinStringIO.cs
@@ -0,0 +1,107 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Marshall;
+using Sharpen;
+
+namespace Db4objects.Db4o.Internal.Encoding
+{
+	/// <exclude></exclude>
+	public class LatinStringIO
+	{
+		public virtual byte[] Bytes(ByteArrayBuffer buffer)
+		{
+			int len = buffer.ReadInt();
+			len = BytesPerChar() * len;
+			byte[] res = new byte[len];
+			System.Array.Copy(buffer._buffer, buffer._offset, res, 0, len);
+			return res;
+		}
+
+		protected virtual int BytesPerChar()
+		{
+			return 1;
+		}
+
+		public virtual byte EncodingByte()
+		{
+			return BuiltInStringEncoding.EncodingByteForEncoding(new LatinStringEncoding());
+		}
+
+		public virtual int Length(string str)
+		{
+			return str.Length + Const4.ObjectLength + Const4.IntLength;
+		}
+
+		public virtual string Read(IReadBuffer buffer, int length)
+		{
+			char[] chars = new char[length];
+			for (int ii = 0; ii < length; ii++)
+			{
+				chars[ii] = (char)(buffer.ReadByte() & unchecked((int)(0xff)));
+			}
+			return new string(chars, 0, length);
+		}
+
+		public virtual string Read(byte[] bytes)
+		{
+			char[] chars = new char[bytes.Length];
+			for (int i = 0; i < bytes.Length; i++)
+			{
+				chars[i] = (char)(bytes[i] & unchecked((int)(0xff)));
+			}
+			return new string(chars, 0, bytes.Length);
+		}
+
+		public virtual string ReadLengthAndString(IReadBuffer buffer)
+		{
+			int length = buffer.ReadInt();
+			if (length == 0)
+			{
+				return string.Empty;
+			}
+			return Read(buffer, length);
+		}
+
+		public virtual int ShortLength(string str)
+		{
+			return str.Length + Const4.IntLength;
+		}
+
+		public virtual void Write(IWriteBuffer buffer, string str)
+		{
+			int length = str.Length;
+			char[] chars = new char[length];
+			Sharpen.Runtime.GetCharsForString(str, 0, length, chars, 0);
+			for (int i = 0; i < length; i++)
+			{
+				buffer.WriteByte((byte)(chars[i] & unchecked((int)(0xff))));
+			}
+		}
+
+		public virtual byte[] Write(string str)
+		{
+			int length = str.Length;
+			char[] chars = new char[length];
+			Sharpen.Runtime.GetCharsForString(str, 0, length, chars, 0);
+			byte[] bytes = new byte[length];
+			for (int i = 0; i < length; i++)
+			{
+				bytes[i] = (byte)(chars[i] & unchecked((int)(0xff)));
+			}
+			return bytes;
+		}
+
+		public virtual void WriteLengthAndString(IWriteBuffer buffer, string str)
+		{
+			if (str == null)
+			{
+				buffer.WriteInt(0);
+				return;
+			}
+			buffer.WriteInt(str.Length);
+			Write(buffer, str);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/UnicodeStringEncoding.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/UnicodeStringEncoding.cs
new file mode 100644
index 0000000..6269cce
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/UnicodeStringEncoding.cs
@@ -0,0 +1,16 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config.Encoding;
+using Db4objects.Db4o.Internal.Encoding;
+
+namespace Db4objects.Db4o.Internal.Encoding
+{
+	/// <exclude></exclude>
+	public class UnicodeStringEncoding : LatinStringEncoding
+	{
+		protected override LatinStringIO CreateStringIo(IStringEncoding encoding)
+		{
+			return new UnicodeStringIO();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/UnicodeStringIO.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/UnicodeStringIO.cs
new file mode 100644
index 0000000..05f5dba
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Encoding/UnicodeStringIO.cs
@@ -0,0 +1,83 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Encoding
+{
+	/// <exclude></exclude>
+	public sealed class UnicodeStringIO : LatinStringIO
+	{
+		protected override int BytesPerChar()
+		{
+			return 2;
+		}
+
+		public override byte EncodingByte()
+		{
+			return BuiltInStringEncoding.EncodingByteForEncoding(new UnicodeStringEncoding());
+		}
+
+		public override int Length(string str)
+		{
+			return (str.Length * 2) + Const4.ObjectLength + Const4.IntLength;
+		}
+
+		public override string Read(IReadBuffer buffer, int length)
+		{
+			char[] chars = new char[length];
+			for (int ii = 0; ii < length; ii++)
+			{
+				chars[ii] = (char)((buffer.ReadByte() & unchecked((int)(0xff))) | ((buffer.ReadByte
+					() & unchecked((int)(0xff))) << 8));
+			}
+			return new string(chars, 0, length);
+		}
+
+		public override string Read(byte[] bytes)
+		{
+			int length = bytes.Length / 2;
+			char[] chars = new char[length];
+			int j = 0;
+			for (int ii = 0; ii < length; ii++)
+			{
+				chars[ii] = (char)((bytes[j++] & unchecked((int)(0xff))) | ((bytes[j++] & unchecked(
+					(int)(0xff))) << 8));
+			}
+			return new string(chars, 0, length);
+		}
+
+		public override int ShortLength(string str)
+		{
+			return (str.Length * 2) + Const4.IntLength;
+		}
+
+		public override void Write(IWriteBuffer buffer, string str)
+		{
+			int length = str.Length;
+			char[] chars = new char[length];
+			Sharpen.Runtime.GetCharsForString(str, 0, length, chars, 0);
+			for (int i = 0; i < length; i++)
+			{
+				buffer.WriteByte((byte)(chars[i] & unchecked((int)(0xff))));
+				buffer.WriteByte((byte)(chars[i] >> 8));
+			}
+		}
+
+		public override byte[] Write(string str)
+		{
+			int length = str.Length;
+			char[] chars = new char[length];
+			Sharpen.Runtime.GetCharsForString(str, 0, length, chars, 0);
+			byte[] bytes = new byte[length * 2];
+			int j = 0;
+			for (int i = 0; i < length; i++)
+			{
+				bytes[j++] = (byte)(chars[i] & unchecked((int)(0xff)));
+				bytes[j++] = (byte)(chars[i] >> 8);
+			}
+			return bytes;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/EventDispatchers.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/EventDispatchers.cs
new file mode 100644
index 0000000..c594707
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/EventDispatchers.cs
@@ -0,0 +1,182 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public sealed class EventDispatchers
+	{
+		private sealed class _IEventDispatcher_11 : IEventDispatcher
+		{
+			public _IEventDispatcher_11()
+			{
+			}
+
+			public bool Dispatch(Transaction trans, object obj, int eventID)
+			{
+				return true;
+			}
+
+			public bool HasEventRegistered(int eventID)
+			{
+				return false;
+			}
+		}
+
+		public static readonly IEventDispatcher NullDispatcher = new _IEventDispatcher_11
+			();
+
+		private static readonly string[] events = new string[] { "objectCanDelete", "objectOnDelete"
+			, "objectOnActivate", "objectOnDeactivate", "objectOnNew", "objectOnUpdate", "objectCanActivate"
+			, "objectCanDeactivate", "objectCanNew", "objectCanUpdate" };
+
+		internal const int CanDelete = 0;
+
+		internal const int Delete = 1;
+
+		internal const int Activate = 2;
+
+		internal const int Deactivate = 3;
+
+		internal const int New = 4;
+
+		public const int Update = 5;
+
+		internal const int CanActivate = 6;
+
+		internal const int CanDeactivate = 7;
+
+		internal const int CanNew = 8;
+
+		internal const int CanUpdate = 9;
+
+		internal const int DeleteCount = 2;
+
+		internal const int Count = 10;
+
+		private class EventDispatcherImpl : IEventDispatcher
+		{
+			private readonly IReflectMethod[] methods;
+
+			public EventDispatcherImpl(IReflectMethod[] methods_)
+			{
+				methods = methods_;
+			}
+
+			public virtual bool HasEventRegistered(int eventID)
+			{
+				return methods[eventID] != null;
+			}
+
+			public virtual bool Dispatch(Transaction trans, object obj, int eventID)
+			{
+				if (methods[eventID] == null)
+				{
+					return true;
+				}
+				object[] parameters = new object[] { trans.ObjectContainer() };
+				ObjectContainerBase container = trans.Container();
+				int stackDepth = container.StackDepth();
+				int topLevelCallId = container.TopLevelCallId();
+				container.StackDepth(0);
+				try
+				{
+					object res = methods[eventID].Invoke(obj, parameters);
+					if (res is bool)
+					{
+						return ((bool)res);
+					}
+				}
+				finally
+				{
+					container.StackDepth(stackDepth);
+					container.TopLevelCallId(topLevelCallId);
+				}
+				return true;
+			}
+		}
+
+		public static IEventDispatcher ForClass(ObjectContainerBase container, IReflectClass
+			 classReflector)
+		{
+			if (container == null || classReflector == null)
+			{
+				throw new ArgumentNullException();
+			}
+			if (!container.DispatchsEvents())
+			{
+				return NullDispatcher;
+			}
+			int count = EventCountFor(container);
+			if (count == 0)
+			{
+				return NullDispatcher;
+			}
+			IReflectMethod[] handlers = EventHandlerTableFor(container, classReflector);
+			return HasEventHandler(handlers) ? new EventDispatchers.EventDispatcherImpl(handlers
+				) : NullDispatcher;
+		}
+
+		private static IReflectMethod[] EventHandlerTableFor(ObjectContainerBase container
+			, IReflectClass classReflector)
+		{
+			IReflectClass[] parameterClasses = new IReflectClass[] { container._handlers.IclassObjectcontainer
+				 };
+			IReflectMethod[] methods = new IReflectMethod[Count];
+			for (int i = Count - 1; i >= 0; i--)
+			{
+				IReflectMethod method = classReflector.GetMethod(events[i], parameterClasses);
+				if (null == method)
+				{
+					method = classReflector.GetMethod(ToPascalCase(events[i]), parameterClasses);
+				}
+				if (method != null)
+				{
+					methods[i] = method;
+				}
+			}
+			return methods;
+		}
+
+		private static bool HasEventHandler(IReflectMethod[] methods)
+		{
+			return Iterators.Any(Iterators.Iterate(methods), new _IPredicate4_118());
+		}
+
+		private sealed class _IPredicate4_118 : IPredicate4
+		{
+			public _IPredicate4_118()
+			{
+			}
+
+			public bool Match(object candidate)
+			{
+				return candidate != null;
+			}
+		}
+
+		private static int EventCountFor(ObjectContainerBase container)
+		{
+			CallBackMode callbackMode = container.ConfigImpl.CallbackMode();
+			if (callbackMode == CallBackMode.All)
+			{
+				return Count;
+			}
+			if (callbackMode == CallBackMode.DeleteOnly)
+			{
+				return DeleteCount;
+			}
+			return 0;
+		}
+
+		private static string ToPascalCase(string name)
+		{
+			return Sharpen.Runtime.Substring(name, 0, 1).ToUpper() + Sharpen.Runtime.Substring
+				(name, 1);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Events/EventRegistryImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Events/EventRegistryImpl.cs
new file mode 100644
index 0000000..08aee1e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Events/EventRegistryImpl.cs
@@ -0,0 +1,732 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Events;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Callbacks;
+using Db4objects.Db4o.Internal.Events;
+using Db4objects.Db4o.Query;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal.Events
+{
+	/// <exclude></exclude>
+	public class EventRegistryImpl : ICallbacks, IEventRegistry
+	{
+		protected System.EventHandler<Db4objects.Db4o.Events.QueryEventArgs> _queryStarted;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.QueryEventArgs> _queryFinished;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs> 
+			_creating;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs> 
+			_activating;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs> 
+			_updating;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs> 
+			_deleting;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs> 
+			_deactivating;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs> _created;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs> _activated;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs> _updated;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs> _deleted;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs> _deactivated;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.CommitEventArgs> _committing;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.CommitEventArgs> _committed;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs> _instantiated;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.ClassEventArgs> _classRegistered;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.ObjectContainerEventArgs> _closing;
+
+		protected System.EventHandler<Db4objects.Db4o.Events.ObjectContainerEventArgs> _opened;
+
+		// Callbacks implementation
+		public virtual void QueryOnFinished(Transaction transaction, IQuery query)
+		{
+			if (!(_queryFinished != null))
+			{
+				return;
+			}
+			WithExceptionHandling(new _IRunnable_50(this, transaction, query));
+		}
+
+		private sealed class _IRunnable_50 : IRunnable
+		{
+			public _IRunnable_50(EventRegistryImpl _enclosing, Transaction transaction, IQuery
+				 query)
+			{
+				this._enclosing = _enclosing;
+				this.transaction = transaction;
+				this.query = query;
+			}
+
+			public void Run()
+			{
+				if (null != this._enclosing._queryFinished) this._enclosing._queryFinished(null, 
+					new QueryEventArgs(transaction, query));
+			}
+
+			private readonly EventRegistryImpl _enclosing;
+
+			private readonly Transaction transaction;
+
+			private readonly IQuery query;
+		}
+
+		public virtual void QueryOnStarted(Transaction transaction, IQuery query)
+		{
+			if (!(_queryStarted != null))
+			{
+				return;
+			}
+			WithExceptionHandling(new _IRunnable_59(this, transaction, query));
+		}
+
+		private sealed class _IRunnable_59 : IRunnable
+		{
+			public _IRunnable_59(EventRegistryImpl _enclosing, Transaction transaction, IQuery
+				 query)
+			{
+				this._enclosing = _enclosing;
+				this.transaction = transaction;
+				this.query = query;
+			}
+
+			public void Run()
+			{
+				if (null != this._enclosing._queryStarted) this._enclosing._queryStarted(null, new 
+					QueryEventArgs(transaction, query));
+			}
+
+			private readonly EventRegistryImpl _enclosing;
+
+			private readonly Transaction transaction;
+
+			private readonly IQuery query;
+		}
+
+		public virtual bool ObjectCanNew(Transaction transaction, object obj)
+		{
+			return TriggerCancellableObjectEventArgsInCallback(transaction, _creating, null, 
+				obj);
+		}
+
+		public virtual bool ObjectCanActivate(Transaction transaction, object obj)
+		{
+			return TriggerCancellableObjectEventArgsInCallback(transaction, _activating, null
+				, obj);
+		}
+
+		public virtual bool ObjectCanUpdate(Transaction transaction, IObjectInfo objectInfo
+			)
+		{
+			return TriggerCancellableObjectEventArgsInCallback(transaction, _updating, objectInfo
+				, objectInfo.GetObject());
+		}
+
+		public virtual bool ObjectCanDelete(Transaction transaction, IObjectInfo objectInfo
+			)
+		{
+			return TriggerCancellableObjectEventArgsInCallback(transaction, _deleting, objectInfo
+				, objectInfo.GetObject());
+		}
+
+		public virtual bool ObjectCanDeactivate(Transaction transaction, IObjectInfo objectInfo
+			)
+		{
+			return TriggerCancellableObjectEventArgsInCallback(transaction, _deactivating, objectInfo
+				, objectInfo.GetObject());
+		}
+
+		public virtual void ObjectOnActivate(Transaction transaction, IObjectInfo obj)
+		{
+			TriggerObjectInfoEventInCallback(transaction, _activated, obj);
+		}
+
+		public virtual void ObjectOnNew(Transaction transaction, IObjectInfo obj)
+		{
+			TriggerObjectInfoEventInCallback(transaction, _created, obj);
+		}
+
+		public virtual void ObjectOnUpdate(Transaction transaction, IObjectInfo obj)
+		{
+			TriggerObjectInfoEventInCallback(transaction, _updated, obj);
+		}
+
+		public virtual void ObjectOnDelete(Transaction transaction, IObjectInfo obj)
+		{
+			TriggerObjectInfoEventInCallback(transaction, _deleted, obj);
+		}
+
+		public virtual void ClassOnRegistered(ClassMetadata clazz)
+		{
+			if (!(_classRegistered != null))
+			{
+				return;
+			}
+			WithExceptionHandling(new _IRunnable_104(this, clazz));
+		}
+
+		private sealed class _IRunnable_104 : IRunnable
+		{
+			public _IRunnable_104(EventRegistryImpl _enclosing, ClassMetadata clazz)
+			{
+				this._enclosing = _enclosing;
+				this.clazz = clazz;
+			}
+
+			public void Run()
+			{
+				if (null != this._enclosing._classRegistered) this._enclosing._classRegistered(null, 
+					new ClassEventArgs(clazz));
+			}
+
+			private readonly EventRegistryImpl _enclosing;
+
+			private readonly ClassMetadata clazz;
+		}
+
+		public virtual void ObjectOnDeactivate(Transaction transaction, IObjectInfo obj)
+		{
+			TriggerObjectInfoEventInCallback(transaction, _deactivated, obj);
+		}
+
+		public virtual void ObjectOnInstantiate(Transaction transaction, IObjectInfo obj)
+		{
+			TriggerObjectInfoEventInCallback(transaction, _instantiated, obj);
+		}
+
+		public virtual void CommitOnStarted(Transaction transaction, CallbackObjectInfoCollections
+			 objectInfoCollections)
+		{
+			if (!(_committing != null))
+			{
+				return;
+			}
+			WithExceptionHandlingInCallback(new _IRunnable_121(this, transaction, objectInfoCollections
+				));
+		}
+
+		private sealed class _IRunnable_121 : IRunnable
+		{
+			public _IRunnable_121(EventRegistryImpl _enclosing, Transaction transaction, CallbackObjectInfoCollections
+				 objectInfoCollections)
+			{
+				this._enclosing = _enclosing;
+				this.transaction = transaction;
+				this.objectInfoCollections = objectInfoCollections;
+			}
+
+			public void Run()
+			{
+				if (null != this._enclosing._committing) this._enclosing._committing(null, new CommitEventArgs
+					(transaction, objectInfoCollections, false));
+			}
+
+			private readonly EventRegistryImpl _enclosing;
+
+			private readonly Transaction transaction;
+
+			private readonly CallbackObjectInfoCollections objectInfoCollections;
+		}
+
+		public virtual void CommitOnCompleted(Transaction transaction, CallbackObjectInfoCollections
+			 objectInfoCollections, bool isOwnCommit)
+		{
+			if (!(_committed != null))
+			{
+				return;
+			}
+			WithExceptionHandlingInCallback(new _IRunnable_132(this, transaction, objectInfoCollections
+				, isOwnCommit));
+		}
+
+		private sealed class _IRunnable_132 : IRunnable
+		{
+			public _IRunnable_132(EventRegistryImpl _enclosing, Transaction transaction, CallbackObjectInfoCollections
+				 objectInfoCollections, bool isOwnCommit)
+			{
+				this._enclosing = _enclosing;
+				this.transaction = transaction;
+				this.objectInfoCollections = objectInfoCollections;
+				this.isOwnCommit = isOwnCommit;
+			}
+
+			public void Run()
+			{
+				if (null != this._enclosing._committed) this._enclosing._committed(null, new CommitEventArgs
+					(transaction, objectInfoCollections, isOwnCommit));
+			}
+
+			private readonly EventRegistryImpl _enclosing;
+
+			private readonly Transaction transaction;
+
+			private readonly CallbackObjectInfoCollections objectInfoCollections;
+
+			private readonly bool isOwnCommit;
+		}
+
+		public virtual void CloseOnStarted(IObjectContainer container)
+		{
+			if (!(_closing != null))
+			{
+				return;
+			}
+			WithExceptionHandlingInCallback(new _IRunnable_143(this, container));
+		}
+
+		private sealed class _IRunnable_143 : IRunnable
+		{
+			public _IRunnable_143(EventRegistryImpl _enclosing, IObjectContainer container)
+			{
+				this._enclosing = _enclosing;
+				this.container = container;
+			}
+
+			public void Run()
+			{
+				if (null != this._enclosing._closing) this._enclosing._closing(null, new ObjectContainerEventArgs
+					(container));
+			}
+
+			private readonly EventRegistryImpl _enclosing;
+
+			private readonly IObjectContainer container;
+		}
+
+		public virtual void OpenOnFinished(IObjectContainer container)
+		{
+			if (!(_opened != null))
+			{
+				return;
+			}
+			WithExceptionHandlingInCallback(new _IRunnable_154(this, container));
+		}
+
+		private sealed class _IRunnable_154 : IRunnable
+		{
+			public _IRunnable_154(EventRegistryImpl _enclosing, IObjectContainer container)
+			{
+				this._enclosing = _enclosing;
+				this.container = container;
+			}
+
+			public void Run()
+			{
+				if (null != this._enclosing._opened) this._enclosing._opened(null, new ObjectContainerEventArgs
+					(container));
+			}
+
+			private readonly EventRegistryImpl _enclosing;
+
+			private readonly IObjectContainer container;
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.QueryEventArgs> QueryFinished
+		{
+			add
+			{
+				_queryFinished = (System.EventHandler<Db4objects.Db4o.Events.QueryEventArgs>)System.Delegate.Combine
+					(_queryFinished, value);
+			}
+			remove
+			{
+				_queryFinished = (System.EventHandler<Db4objects.Db4o.Events.QueryEventArgs>)System.Delegate.Remove
+					(_queryFinished, value);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.QueryEventArgs> QueryStarted
+		{
+			add
+			{
+				_queryStarted = (System.EventHandler<Db4objects.Db4o.Events.QueryEventArgs>)System.Delegate.Combine
+					(_queryStarted, value);
+			}
+			remove
+			{
+				_queryStarted = (System.EventHandler<Db4objects.Db4o.Events.QueryEventArgs>)System.Delegate.Remove
+					(_queryStarted, value);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs>
+			 Creating
+		{
+			add
+			{
+				_creating = (System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs>
+					)System.Delegate.Combine(_creating, value);
+			}
+			remove
+			{
+				_creating = (System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs>
+					)System.Delegate.Remove(_creating, value);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs>
+			 Activating
+		{
+			add
+			{
+				_activating = (System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs>
+					)System.Delegate.Combine(_activating, value);
+			}
+			remove
+			{
+				_activating = (System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs>
+					)System.Delegate.Remove(_activating, value);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs>
+			 Updating
+		{
+			add
+			{
+				_updating = (System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs>
+					)System.Delegate.Combine(_updating, value);
+			}
+			remove
+			{
+				_updating = (System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs>
+					)System.Delegate.Remove(_updating, value);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs>
+			 Deleting
+		{
+			add
+			{
+				_deleting = (System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs>
+					)System.Delegate.Combine(_deleting, value);
+			}
+			remove
+			{
+				_deleting = (System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs>
+					)System.Delegate.Remove(_deleting, value);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs>
+			 Deactivating
+		{
+			add
+			{
+				_deactivating = (System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs>
+					)System.Delegate.Combine(_deactivating, value);
+			}
+			remove
+			{
+				_deactivating = (System.EventHandler<Db4objects.Db4o.Events.CancellableObjectEventArgs>
+					)System.Delegate.Remove(_deactivating, value);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>
+			 Created
+		{
+			add
+			{
+				_created = (System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>)System.Delegate.Combine
+					(_created, value);
+			}
+			remove
+			{
+				_created = (System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>)System.Delegate.Remove
+					(_created, value);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>
+			 Activated
+		{
+			add
+			{
+				_activated = (System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>)System.Delegate.Combine
+					(_activated, value);
+			}
+			remove
+			{
+				_activated = (System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>)System.Delegate.Remove
+					(_activated, value);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>
+			 Updated
+		{
+			add
+			{
+				_updated = (System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>)System.Delegate.Combine
+					(_updated, value);
+			}
+			remove
+			{
+				_updated = (System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>)System.Delegate.Remove
+					(_updated, value);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>
+			 Deleted
+		{
+			add
+			{
+				_deleted = (System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>)System.Delegate.Combine
+					(_deleted, value);
+			}
+			remove
+			{
+				_deleted = (System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>)System.Delegate.Remove
+					(_deleted, value);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>
+			 Deactivated
+		{
+			add
+			{
+				_deactivated = (System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>)System.Delegate.Combine
+					(_deactivated, value);
+			}
+			remove
+			{
+				_deactivated = (System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>)System.Delegate.Remove
+					(_deactivated, value);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.CommitEventArgs> 
+			Committing
+		{
+			add
+			{
+				_committing = (System.EventHandler<Db4objects.Db4o.Events.CommitEventArgs>)System.Delegate.Combine
+					(_committing, value);
+			}
+			remove
+			{
+				_committing = (System.EventHandler<Db4objects.Db4o.Events.CommitEventArgs>)System.Delegate.Remove
+					(_committing, value);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.CommitEventArgs> 
+			Committed
+		{
+			add
+			{
+				_committed = (System.EventHandler<Db4objects.Db4o.Events.CommitEventArgs>)System.Delegate.Combine
+					(_committed, value);
+				OnCommittedListenerAdded();
+			}
+			remove
+			{
+				_committed = (System.EventHandler<Db4objects.Db4o.Events.CommitEventArgs>)System.Delegate.Remove
+					(_committed, value);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.ClassEventArgs> ClassRegistered
+		{
+			add
+			{
+				_classRegistered = (System.EventHandler<Db4objects.Db4o.Events.ClassEventArgs>)System.Delegate.Combine
+					(_classRegistered, value);
+			}
+			remove
+			{
+				_classRegistered = (System.EventHandler<Db4objects.Db4o.Events.ClassEventArgs>)System.Delegate.Remove
+					(_classRegistered, value);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>
+			 Instantiated
+		{
+			add
+			{
+				_instantiated = (System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>)
+					System.Delegate.Combine(_instantiated, value);
+			}
+			remove
+			{
+				_instantiated = (System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>)
+					System.Delegate.Remove(_instantiated, value);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.ObjectContainerEventArgs>
+			 Closing
+		{
+			add
+			{
+				_closing = (System.EventHandler<Db4objects.Db4o.Events.ObjectContainerEventArgs>)
+					System.Delegate.Combine(_closing, value);
+			}
+			remove
+			{
+				_closing = (System.EventHandler<Db4objects.Db4o.Events.ObjectContainerEventArgs>)
+					System.Delegate.Remove(_closing, value);
+			}
+		}
+
+		protected virtual void OnCommittedListenerAdded()
+		{
+		}
+
+		// do nothing 
+		public virtual bool CaresAboutCommitting()
+		{
+			return (_committing != null);
+		}
+
+		public virtual bool CaresAboutCommitted()
+		{
+			return (_committed != null);
+		}
+
+		public virtual bool CaresAboutDeleting()
+		{
+			return (_deleting != null);
+		}
+
+		public virtual bool CaresAboutDeleted()
+		{
+			return (_deleted != null);
+		}
+
+		internal virtual bool TriggerCancellableObjectEventArgsInCallback(Transaction transaction
+			, System.EventHandler<CancellableObjectEventArgs> e, IObjectInfo objectInfo, object
+			 o)
+		{
+			if (!(e != null))
+			{
+				return true;
+			}
+			CancellableObjectEventArgs args = new CancellableObjectEventArgs(transaction, objectInfo
+				, o);
+			WithExceptionHandlingInCallback(new _IRunnable_258(e, args));
+			return !args.IsCancelled;
+		}
+
+		private sealed class _IRunnable_258 : IRunnable
+		{
+			public _IRunnable_258(System.EventHandler<CancellableObjectEventArgs> e, CancellableObjectEventArgs
+				 args)
+			{
+				this.e = e;
+				this.args = args;
+			}
+
+			public void Run()
+			{
+				if (null != e) e(null, args);
+			}
+
+			private readonly System.EventHandler<CancellableObjectEventArgs> e;
+
+			private readonly CancellableObjectEventArgs args;
+		}
+
+		internal virtual void TriggerObjectInfoEventInCallback(Transaction transaction, System.EventHandler<
+			ObjectInfoEventArgs> e, IObjectInfo o)
+		{
+			if (!(e != null))
+			{
+				return;
+			}
+			WithExceptionHandlingInCallback(new _IRunnable_270(e, transaction, o));
+		}
+
+		private sealed class _IRunnable_270 : IRunnable
+		{
+			public _IRunnable_270(System.EventHandler<ObjectInfoEventArgs> e, Transaction transaction
+				, IObjectInfo o)
+			{
+				this.e = e;
+				this.transaction = transaction;
+				this.o = o;
+			}
+
+			public void Run()
+			{
+				if (null != e) e(null, new ObjectInfoEventArgs(transaction, o));
+			}
+
+			private readonly System.EventHandler<ObjectInfoEventArgs> e;
+
+			private readonly Transaction transaction;
+
+			private readonly IObjectInfo o;
+		}
+
+		private void WithExceptionHandlingInCallback(IRunnable runnable)
+		{
+			try
+			{
+				InCallback.Run(runnable);
+			}
+			catch (Db4oException e)
+			{
+				throw;
+			}
+			catch (Exception x)
+			{
+				throw new EventException(x);
+			}
+		}
+
+		private void WithExceptionHandling(IRunnable runnable)
+		{
+			try
+			{
+				runnable.Run();
+			}
+			catch (Db4oException e)
+			{
+				throw;
+			}
+			catch (Exception x)
+			{
+				throw new EventException(x);
+			}
+		}
+
+		public virtual event System.EventHandler<Db4objects.Db4o.Events.ObjectContainerEventArgs>
+			 Opened
+		{
+			add
+			{
+				_opened = (System.EventHandler<Db4objects.Db4o.Events.ObjectContainerEventArgs>)System.Delegate.Combine
+					(_opened, value);
+			}
+			remove
+			{
+				_opened = (System.EventHandler<Db4objects.Db4o.Events.ObjectContainerEventArgs>)System.Delegate.Remove
+					(_opened, value);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Exceptions4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Exceptions4.cs
new file mode 100644
index 0000000..11aca99
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Exceptions4.cs
@@ -0,0 +1,68 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class Exceptions4
+	{
+		public static void ThrowRuntimeException(int code)
+		{
+			ThrowRuntimeException(code, null, null);
+		}
+
+		public static void ThrowRuntimeException(int code, Exception cause)
+		{
+			ThrowRuntimeException(code, null, cause);
+		}
+
+		public static void ThrowRuntimeException(int code, string msg)
+		{
+			ThrowRuntimeException(code, msg, null);
+		}
+
+		public static void ThrowRuntimeException(int code, string msg, Exception cause)
+		{
+			ThrowRuntimeException(code, msg, cause, true);
+		}
+
+		[System.ObsoleteAttribute]
+		public static void ThrowRuntimeException(int code, string msg, Exception cause, bool
+			 doLog)
+		{
+			if (doLog)
+			{
+				Db4objects.Db4o.Internal.Messages.LogErr(Db4oFactory.Configure(), code, msg, cause
+					);
+			}
+			throw new Db4oException(Db4objects.Db4o.Internal.Messages.Get(code, msg));
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oException"></exception>
+		public static void CatchAllExceptDb4oException(Exception exc)
+		{
+			if (exc is Db4oException)
+			{
+				throw (Db4oException)exc;
+			}
+		}
+
+		public static Exception ShouldNeverBeCalled()
+		{
+			throw new Exception();
+		}
+
+		public static void ShouldNeverHappen()
+		{
+			throw new Exception();
+		}
+
+		public static Exception VirtualException()
+		{
+			throw new Exception();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ExternalObjectContainer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ExternalObjectContainer.cs
new file mode 100644
index 0000000..3cde0ad
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ExternalObjectContainer.cs
@@ -0,0 +1,193 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public abstract class ExternalObjectContainer : ObjectContainerBase
+	{
+		public ExternalObjectContainer(IConfiguration config) : base(config)
+		{
+		}
+
+		public sealed override void Activate(object obj)
+		{
+			Activate(null, obj);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public sealed override void Activate(object obj, int depth)
+		{
+			Activate(null, obj, ActivationDepthProvider().ActivationDepth(depth, ActivationMode
+				.Activate));
+		}
+
+		public sealed override void Deactivate(object obj)
+		{
+			Deactivate(null, obj);
+		}
+
+		/// <exception cref="System.ArgumentNullException"></exception>
+		/// <exception cref="System.ArgumentException"></exception>
+		public sealed override void Bind(object obj, long id)
+		{
+			Bind(null, obj, id);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public sealed override void Commit()
+		{
+			Commit(null);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public sealed override void Deactivate(object obj, int depth)
+		{
+			Deactivate(null, obj, depth);
+		}
+
+		public sealed override void Delete(object a_object)
+		{
+			Delete(null, a_object);
+		}
+
+		public override object Descend(object obj, string[] path)
+		{
+			return Descend(null, obj, path);
+		}
+
+		public override IExtObjectContainer Ext()
+		{
+			return this;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public sealed override IObjectSet QueryByExample(object template)
+		{
+			return QueryByExample(null, template);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.InvalidIDException"></exception>
+		public sealed override object GetByID(long id)
+		{
+			return GetByID(null, id);
+		}
+
+		public sealed override object GetByUUID(Db4oUUID uuid)
+		{
+			return GetByUUID(null, uuid);
+		}
+
+		public sealed override long GetID(object obj)
+		{
+			return GetID(null, obj);
+		}
+
+		public sealed override IObjectInfo GetObjectInfo(object obj)
+		{
+			return GetObjectInfo(null, obj);
+		}
+
+		public override bool IsActive(object obj)
+		{
+			return IsActive(null, obj);
+		}
+
+		public override bool IsCached(long id)
+		{
+			return IsCached(null, id);
+		}
+
+		public override bool IsStored(object obj)
+		{
+			return IsStored(null, obj);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public sealed override object PeekPersisted(object obj, int depth, bool committed
+			)
+		{
+			return PeekPersisted(null, obj, ActivationDepthProvider().ActivationDepth(depth, 
+				ActivationMode.Peek), committed);
+		}
+
+		public sealed override void Purge(object obj)
+		{
+			Purge(null, obj);
+		}
+
+		public override IQuery Query()
+		{
+			return Query((Transaction)null);
+		}
+
+		public sealed override IObjectSet Query(Type clazz)
+		{
+			return QueryByExample(clazz);
+		}
+
+		public sealed override IObjectSet Query(Predicate predicate)
+		{
+			return Query(predicate, (IQueryComparator)null);
+		}
+
+		public sealed override IObjectSet Query(Predicate predicate, IQueryComparator comparator
+			)
+		{
+			return Query(null, predicate, comparator);
+		}
+
+		public sealed override void Refresh(object obj, int depth)
+		{
+			Refresh(null, obj, depth);
+		}
+
+		public sealed override void Rollback()
+		{
+			Rollback(null);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		public sealed override void Store(object obj)
+		{
+			Store(obj, Const4.Unspecified);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		public sealed override void Store(object obj, int depth)
+		{
+			Store(null, obj, depth == Const4.Unspecified ? (IUpdateDepth)UpdateDepthProvider(
+				).Unspecified(NullModifiedObjectQuery.Instance) : (IUpdateDepth)UpdateDepthProvider
+				().ForDepth(depth));
+		}
+
+		public sealed override IStoredClass StoredClass(object clazz)
+		{
+			return StoredClass(null, clazz);
+		}
+
+		public override IStoredClass[] StoredClasses()
+		{
+			return StoredClasses(null);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="System.NotSupportedException"></exception>
+		public abstract override void Backup(IStorage targetStorage, string path);
+
+		public abstract override Db4oDatabase Identity();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/FieldIndexException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/FieldIndexException.cs
new file mode 100644
index 0000000..0c36533
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/FieldIndexException.cs
@@ -0,0 +1,62 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	[System.Serializable]
+	public class FieldIndexException : Exception
+	{
+		private string _className;
+
+		private string _fieldName;
+
+		public FieldIndexException(FieldMetadata field) : this(null, null, field)
+		{
+		}
+
+		public FieldIndexException(string msg, FieldMetadata field) : this(msg, null, field
+			)
+		{
+		}
+
+		public FieldIndexException(Exception cause, FieldMetadata field) : this(null, cause
+			, field)
+		{
+		}
+
+		public FieldIndexException(string msg, Exception cause, FieldMetadata field) : this
+			(msg, cause, field.ContainingClass().GetName(), field.GetName())
+		{
+		}
+
+		public FieldIndexException(string msg, Exception cause, string className, string 
+			fieldName) : base(EnhancedMessage(msg, className, fieldName), cause)
+		{
+			_className = className;
+			_fieldName = fieldName;
+		}
+
+		public virtual string ClassName()
+		{
+			return _className;
+		}
+
+		public virtual string FieldName()
+		{
+			return _fieldName;
+		}
+
+		private static string EnhancedMessage(string msg, string className, string fieldName
+			)
+		{
+			string enhancedMessage = "Field index for " + className + "#" + fieldName;
+			if (msg != null)
+			{
+				enhancedMessage += ": " + msg;
+			}
+			return enhancedMessage;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/FieldMetadata.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/FieldMetadata.cs
new file mode 100644
index 0000000..452ab71
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/FieldMetadata.cs
@@ -0,0 +1,1374 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using System.Text;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Handlers.Array;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Internal.Reflect;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Generic;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class FieldMetadata : ClassAspect, IStoredField
+	{
+		private ClassMetadata _containingClass;
+
+		private string _name;
+
+		protected bool _isArray;
+
+		private bool _isNArray;
+
+		private bool _isPrimitive;
+
+		private IReflectField _reflectField;
+
+		private FieldMetadataState _state = FieldMetadataState.NotLoaded;
+
+		private Config4Field _config;
+
+		private IDb4oTypeImpl _db4oType;
+
+		private int _linkLength;
+
+		private BTree _index;
+
+		protected ClassMetadata _fieldType;
+
+		protected int _fieldTypeID;
+
+		internal static readonly Db4objects.Db4o.Internal.FieldMetadata[] EmptyArray = new 
+			Db4objects.Db4o.Internal.FieldMetadata[0];
+
+		public FieldMetadata(ClassMetadata classMetadata)
+		{
+			_containingClass = classMetadata;
+		}
+
+		protected Type TranslatorStoredClass(IObjectTranslator translator)
+		{
+			try
+			{
+				return translator.StoredClass();
+			}
+			catch (Exception e)
+			{
+				throw new ReflectException(e);
+			}
+		}
+
+		internal FieldMetadata(ClassMetadata containingClass, IReflectField field, ClassMetadata
+			 fieldType) : this(containingClass)
+		{
+			Init(field.GetName());
+			_reflectField = field;
+			_fieldType = fieldType;
+			_fieldTypeID = fieldType.GetID();
+			// TODO: beautify !!!  possibly pull up isPrimitive to ReflectField
+			bool isPrimitive = field is GenericField ? ((GenericField)field).IsPrimitive() : 
+				false;
+			Configure(field.GetFieldType(), isPrimitive);
+			CheckDb4oType();
+			SetAvailable();
+		}
+
+		protected virtual void SetAvailable()
+		{
+			_state = FieldMetadataState.Available;
+		}
+
+		protected FieldMetadata(int fieldTypeID)
+		{
+			_fieldTypeID = fieldTypeID;
+		}
+
+		public FieldMetadata(ClassMetadata containingClass, string name, int fieldTypeID, 
+			bool primitive, bool isArray, bool isNArray) : this(containingClass)
+		{
+			Init(name, fieldTypeID, primitive, isArray, isNArray);
+		}
+
+		protected FieldMetadata(ClassMetadata containingClass, string name) : this(containingClass
+			)
+		{
+			Init(name);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.FieldIndexException"></exception>
+		public virtual void AddFieldIndex(ObjectIdContextImpl context)
+		{
+			if (!HasIndex())
+			{
+				IncrementOffset(context);
+				return;
+			}
+			try
+			{
+				AddIndexEntry(context.Transaction(), context.ObjectId(), ReadIndexEntry(context));
+			}
+			catch (CorruptionException exc)
+			{
+				throw new FieldIndexException(exc, this);
+			}
+		}
+
+		protected void AddIndexEntry(StatefulBuffer a_bytes, object indexEntry)
+		{
+			AddIndexEntry(a_bytes.Transaction(), a_bytes.GetID(), indexEntry);
+		}
+
+		public virtual void AddIndexEntry(Transaction trans, int parentID, object indexEntry
+			)
+		{
+			if (!HasIndex())
+			{
+				return;
+			}
+			BTree index = GetIndex(trans);
+			index.Add(trans, CreateFieldIndexKey(parentID, indexEntry));
+		}
+
+		protected virtual IFieldIndexKey CreateFieldIndexKey(int parentID, object indexEntry
+			)
+		{
+			object convertedIndexEntry = IndexEntryFor(indexEntry);
+			return new FieldIndexKeyImpl(parentID, convertedIndexEntry);
+		}
+
+		protected virtual object IndexEntryFor(object indexEntry)
+		{
+			return _reflectField.IndexEntry(indexEntry);
+		}
+
+		public virtual bool CanUseNullBitmap()
+		{
+			return true;
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public object ReadIndexEntry(IObjectIdContext context)
+		{
+			IIndexableTypeHandler indexableTypeHandler = (IIndexableTypeHandler)HandlerRegistry
+				.CorrectHandlerVersion(context, GetHandler());
+			return indexableTypeHandler.ReadIndexEntry(context);
+		}
+
+		public virtual void RemoveIndexEntry(Transaction trans, int parentID, object indexEntry
+			)
+		{
+			if (!HasIndex())
+			{
+				return;
+			}
+			BTree index = GetIndex(trans);
+			if (index == null)
+			{
+				return;
+			}
+			index.Remove(trans, CreateFieldIndexKey(parentID, indexEntry));
+		}
+
+		//TODO: Split into command query separation.
+		public virtual bool Alive()
+		{
+			if (_state == FieldMetadataState.Available)
+			{
+				return true;
+			}
+			if (_state == FieldMetadataState.NotLoaded)
+			{
+				return Load();
+			}
+			return _state == FieldMetadataState.Available;
+		}
+
+		private bool Load()
+		{
+			if (_fieldType == null)
+			{
+				// this may happen if the local ClassMetadataRepository
+				// has not been updated from the server and presumably 
+				// in some refactoring cases. 
+				// We try to heal the problem by re-reading the class.
+				// This could be dangerous, if the class type of a field
+				// has been modified.
+				// TODO: add class refactoring features
+				_fieldType = DetectFieldType();
+				CheckFieldTypeID();
+			}
+			CheckCorrectTypeForField();
+			if (_fieldType == null || _reflectField == null)
+			{
+				_state = FieldMetadataState.Unavailable;
+				_reflectField = null;
+				return false;
+			}
+			if (Updating())
+			{
+				return false;
+			}
+			SetAvailable();
+			CheckDb4oType();
+			return true;
+		}
+
+		private bool ShouldStoreField()
+		{
+			return !_reflectField.IsTransient() || (_containingClass != null && _containingClass
+				.ShouldStoreTransientFields());
+		}
+
+		public virtual bool Updating()
+		{
+			return _state == FieldMetadataState.Updating;
+		}
+
+		private void CheckFieldTypeID()
+		{
+			int id = _fieldType != null ? _fieldType.GetID() : 0;
+			if (_fieldTypeID == 0)
+			{
+				_fieldTypeID = id;
+				return;
+			}
+			if (id > 0 && id != _fieldTypeID)
+			{
+				// wrong type, refactoring, field should be turned off
+				// TODO: it would be cool to log something here
+				_fieldType = null;
+			}
+		}
+
+		internal virtual bool CanAddToQuery(string fieldName)
+		{
+			if (!Alive())
+			{
+				return false;
+			}
+			return fieldName.Equals(GetName()) && ContainingClass() != null && !ContainingClass
+				().IsInternal();
+		}
+
+		private bool CanHold(IReflectClass type)
+		{
+			if (type == null)
+			{
+				throw new ArgumentNullException();
+			}
+			ITypeHandler4 typeHandler = GetHandler();
+			if (typeHandler is IQueryableTypeHandler)
+			{
+				if (((IQueryableTypeHandler)typeHandler).DescendsIntoMembers())
+				{
+					return true;
+				}
+			}
+			IReflectClass classReflector = FieldType().ClassReflector();
+			if (classReflector.IsCollection())
+			{
+				return true;
+			}
+			return classReflector.IsAssignableFrom(type);
+		}
+
+		public virtual GenericReflector Reflector()
+		{
+			ObjectContainerBase container = Container();
+			if (container == null)
+			{
+				return null;
+			}
+			return container.Reflector();
+		}
+
+		public virtual object Coerce(IReflectClass valueClass, object value)
+		{
+			if (value == null)
+			{
+				return _isPrimitive ? No4.Instance : value;
+			}
+			if (valueClass == null)
+			{
+				throw new ArgumentNullException();
+			}
+			if (GetHandler() is PrimitiveHandler)
+			{
+				return ((PrimitiveHandler)GetHandler()).Coerce(valueClass, value);
+			}
+			if (!CanHold(valueClass))
+			{
+				return No4.Instance;
+			}
+			return value;
+		}
+
+		public bool CanLoadByIndex()
+		{
+			return Handlers4.CanLoadFieldByIndex(GetHandler());
+		}
+
+		public sealed override void CascadeActivation(IActivationContext context)
+		{
+			if (!Alive())
+			{
+				return;
+			}
+			object cascadeTo = CascadingTarget(context);
+			if (cascadeTo == null)
+			{
+				return;
+			}
+			IActivationContext cascadeContext = context.ForObject(cascadeTo);
+			ClassMetadata classMetadata = cascadeContext.ClassMetadata();
+			if (classMetadata == null)
+			{
+				return;
+			}
+			EnsureObjectIsActive(cascadeContext);
+			Handlers4.CascadeActivation(cascadeContext, classMetadata.TypeHandler());
+		}
+
+		private void EnsureObjectIsActive(IActivationContext context)
+		{
+			if (!context.Depth().Mode().IsActivate())
+			{
+				return;
+			}
+			if (Handlers4.IsValueType(GetHandler()))
+			{
+				return;
+			}
+			ObjectContainerBase container = context.Container();
+			ClassMetadata classMetadata = container.ClassMetadataForObject(context.TargetObject
+				());
+			if (classMetadata == null || !classMetadata.HasIdentity())
+			{
+				return;
+			}
+			if (container.IsActive(context.TargetObject()))
+			{
+				return;
+			}
+			container.StillToActivate(context.Descend());
+		}
+
+		protected object CascadingTarget(IActivationContext context)
+		{
+			if (context.Depth().Mode().IsDeactivate())
+			{
+				if (null == _reflectField)
+				{
+					return null;
+				}
+				return FieldAccessor().Get(_reflectField, context.TargetObject());
+			}
+			return GetOrCreate(context.Transaction(), context.TargetObject());
+		}
+
+		private void CheckDb4oType()
+		{
+			if (_reflectField != null)
+			{
+				if (Container()._handlers.IclassDb4otype.IsAssignableFrom(_reflectField.GetFieldType
+					()))
+				{
+					_db4oType = HandlerRegistry.GetDb4oType(_reflectField.GetFieldType());
+				}
+			}
+		}
+
+		internal virtual void CollectConstraints(Transaction trans, QConObject a_parent, 
+			object a_template, IVisitor4 a_visitor)
+		{
+			object obj = GetOn(trans, a_template);
+			if (obj != null)
+			{
+				Collection4 objs = Platform4.FlattenCollection(trans.Container(), obj);
+				IEnumerator j = objs.GetEnumerator();
+				while (j.MoveNext())
+				{
+					obj = j.Current;
+					if (obj != null)
+					{
+						if (_isPrimitive && !_isArray)
+						{
+							object nullValue = _reflectField.GetFieldType().NullValue();
+							if (obj.Equals(nullValue))
+							{
+								return;
+							}
+						}
+						if (Platform4.IgnoreAsConstraint(obj))
+						{
+							return;
+						}
+						if (!a_parent.HasObjectInParentPath(obj))
+						{
+							QConObject constraint = new QConObject(trans, a_parent, QField(trans), obj);
+							constraint.ByExample();
+							a_visitor.Visit(constraint);
+						}
+					}
+				}
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.FieldIndexException"></exception>
+		public sealed override void CollectIDs(CollectIdContext context)
+		{
+			if (!Alive())
+			{
+				IncrementOffset(context.Buffer());
+				return;
+			}
+			ITypeHandler4 handler = HandlerRegistry.CorrectHandlerVersion(context, GetHandler
+				());
+			Handlers4.CollectIdsInternal(context, handler, LinkLength(), true);
+		}
+
+		internal virtual void Configure(IReflectClass clazz, bool isPrimitive)
+		{
+			_isArray = clazz.IsArray();
+			if (_isArray)
+			{
+				IReflectArray reflectArray = Reflector().Array();
+				_isNArray = reflectArray.IsNDimensional(clazz);
+				_isPrimitive = reflectArray.GetComponentType(clazz).IsPrimitive();
+			}
+			else
+			{
+				_isPrimitive = isPrimitive | clazz.IsPrimitive();
+			}
+		}
+
+		protected ITypeHandler4 WrapHandlerToArrays(ITypeHandler4 handler)
+		{
+			if (handler == null)
+			{
+				return null;
+			}
+			if (_isNArray)
+			{
+				return new MultidimensionalArrayHandler(handler, ArraysUsePrimitiveClassReflector
+					());
+			}
+			if (_isArray)
+			{
+				return new ArrayHandler(handler, ArraysUsePrimitiveClassReflector());
+			}
+			return handler;
+		}
+
+		private bool ArraysUsePrimitiveClassReflector()
+		{
+			return _isPrimitive;
+		}
+
+		public override void Deactivate(IActivationContext context)
+		{
+			if (!Alive() || !ShouldStoreField())
+			{
+				return;
+			}
+			bool isEnumClass = _containingClass.IsEnum();
+			if (_isPrimitive && !_isArray)
+			{
+				if (!isEnumClass)
+				{
+					object nullValue = _reflectField.GetFieldType().NullValue();
+					FieldAccessor().Set(_reflectField, context.TargetObject(), nullValue);
+				}
+				return;
+			}
+			if (context.Depth().RequiresActivation())
+			{
+				CascadeActivation(context);
+			}
+			if (!isEnumClass)
+			{
+				FieldAccessor().Set(_reflectField, context.TargetObject(), null);
+			}
+		}
+
+		private IFieldAccessor FieldAccessor()
+		{
+			return _containingClass.FieldAccessor();
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.FieldIndexException"></exception>
+		public override void Delete(DeleteContextImpl context, bool isUpdate)
+		{
+			if (!CheckAlive(context))
+			{
+				return;
+			}
+			try
+			{
+				RemoveIndexEntry(context);
+				if (isUpdate)
+				{
+					IncrementOffset(context);
+					return;
+				}
+				StatefulBuffer buffer = (StatefulBuffer)context.Buffer();
+				DeleteContextImpl childContext = new DeleteContextImpl(context, GetStoredType(), 
+					_config);
+				context.SlotFormat().DoWithSlotIndirection(buffer, GetHandler(), new _IClosure4_445
+					(this, childContext));
+			}
+			catch (CorruptionException exc)
+			{
+				throw new FieldIndexException(exc, this);
+			}
+		}
+
+		private sealed class _IClosure4_445 : IClosure4
+		{
+			public _IClosure4_445(FieldMetadata _enclosing, DeleteContextImpl childContext)
+			{
+				this._enclosing = _enclosing;
+				this.childContext = childContext;
+			}
+
+			public object Run()
+			{
+				childContext.Delete(this._enclosing.GetHandler());
+				return null;
+			}
+
+			private readonly FieldMetadata _enclosing;
+
+			private readonly DeleteContextImpl childContext;
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private void RemoveIndexEntry(DeleteContextImpl context)
+		{
+			if (!HasIndex())
+			{
+				return;
+			}
+			int offset = context.Offset();
+			object obj = ReadIndexEntry(context);
+			RemoveIndexEntry(context.Transaction(), context.ObjectId(), obj);
+			context.Seek(offset);
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (!(obj is Db4objects.Db4o.Internal.FieldMetadata))
+			{
+				return false;
+			}
+			Db4objects.Db4o.Internal.FieldMetadata other = (Db4objects.Db4o.Internal.FieldMetadata
+				)obj;
+			other.Alive();
+			Alive();
+			return other._isPrimitive == _isPrimitive && other._fieldType == _fieldType && other
+				._name.Equals(_name);
+		}
+
+		public override int GetHashCode()
+		{
+			return _name.GetHashCode();
+		}
+
+		public object Get(object onObject)
+		{
+			return Get(null, onObject);
+		}
+
+		public object Get(Transaction trans, object onObject)
+		{
+			if (_containingClass == null)
+			{
+				return null;
+			}
+			ObjectContainerBase container = Container();
+			if (container == null)
+			{
+				return null;
+			}
+			lock (container.Lock())
+			{
+				// FIXME: The following is not really transactional.
+				//        This will work OK for normal C/S and for
+				//        single local mode but the transaction will
+				//        be wrong for MTOC.
+				if (trans == null)
+				{
+					trans = container.Transaction;
+				}
+				container.CheckClosed();
+				ObjectReference @ref = trans.ReferenceForObject(onObject);
+				if (@ref == null)
+				{
+					return null;
+				}
+				int id = @ref.GetID();
+				if (id <= 0)
+				{
+					return null;
+				}
+				UnmarshallingContext context = new UnmarshallingContext(trans, @ref, Const4.AddToIdTree
+					, false);
+				context.ActivationDepth(new LegacyActivationDepth(1));
+				return context.ReadFieldValue(this);
+			}
+		}
+
+		public override string GetName()
+		{
+			return _name;
+		}
+
+		public ClassMetadata FieldType()
+		{
+			// alive needs to be checked by all callers: Done
+			return _fieldType;
+		}
+
+		public virtual ITypeHandler4 GetHandler()
+		{
+			if (_fieldType == null)
+			{
+				return null;
+			}
+			// alive needs to be checked by all callers: Done
+			return WrapHandlerToArrays(_fieldType.TypeHandler());
+		}
+
+		public virtual int FieldTypeID()
+		{
+			// alive needs to be checked by all callers: Done
+			return _fieldTypeID;
+		}
+
+		public virtual object GetOn(Transaction trans, object onObject)
+		{
+			if (Alive())
+			{
+				return FieldAccessor().Get(_reflectField, onObject);
+			}
+			return null;
+		}
+
+		/// <summary>
+		/// dirty hack for com.db4o.types some of them (BlobImpl) need to be set automatically
+		/// TODO: Derive from FieldMetadata for Db4oTypes
+		/// </summary>
+		public virtual object GetOrCreate(Transaction trans, object onObject)
+		{
+			if (!Alive())
+			{
+				return null;
+			}
+			object obj = FieldAccessor().Get(_reflectField, onObject);
+			if (_db4oType != null && obj == null)
+			{
+				obj = _db4oType.CreateDefault(trans);
+				FieldAccessor().Set(_reflectField, onObject, obj);
+			}
+			return obj;
+		}
+
+		public ClassMetadata ContainingClass()
+		{
+			// alive needs to be checked by all callers: Done
+			return _containingClass;
+		}
+
+		public virtual IReflectClass GetStoredType()
+		{
+			if (_reflectField == null)
+			{
+				return null;
+			}
+			return Handlers4.BaseType(_reflectField.GetFieldType());
+		}
+
+		public virtual ObjectContainerBase Container()
+		{
+			if (_containingClass == null)
+			{
+				return null;
+			}
+			return _containingClass.Container();
+		}
+
+		public virtual bool HasConfig()
+		{
+			return _config != null;
+		}
+
+		public virtual bool HasIndex()
+		{
+			return _index != null;
+		}
+
+		public void Init(string name)
+		{
+			_name = name;
+			InitConfiguration(name);
+		}
+
+		internal void InitConfiguration(string name)
+		{
+			Config4Class containingClassConfig = _containingClass.Config();
+			if (containingClassConfig == null)
+			{
+				return;
+			}
+			_config = containingClassConfig.ConfigField(name);
+		}
+
+		public virtual void Init(string name, int fieldTypeID, bool isPrimitive, bool isArray
+			, bool isNArray)
+		{
+			_fieldTypeID = fieldTypeID;
+			_isPrimitive = isPrimitive;
+			_isArray = isArray;
+			_isNArray = isNArray;
+			Init(name);
+			LoadFieldTypeById();
+			Alive();
+		}
+
+		private bool _initialized = false;
+
+		internal void InitConfigOnUp(Transaction trans)
+		{
+			if (_initialized)
+			{
+				return;
+			}
+			_initialized = true;
+			if (_config != null)
+			{
+				_config.InitOnUp(trans, this);
+			}
+		}
+
+		public override void Activate(UnmarshallingContext context)
+		{
+			if (!CheckAlive(context))
+			{
+				return;
+			}
+			if (!ShouldStoreField())
+			{
+				IncrementOffset(context);
+				return;
+			}
+			object toSet = Read(context);
+			InformAboutTransaction(toSet, context.Transaction());
+			Set(context.PersistentObject(), toSet);
+		}
+
+		public virtual void AttemptUpdate(UnmarshallingContext context)
+		{
+			if (!Updating())
+			{
+				IncrementOffset(context);
+				return;
+			}
+			int savedOffset = context.Offset();
+			try
+			{
+				object toSet = context.Read(GetHandler());
+				if (toSet != null)
+				{
+					Set(context.PersistentObject(), toSet);
+				}
+			}
+			catch (Exception)
+			{
+				// FIXME: COR-547 Diagnostics here please.
+				context.Buffer().Seek(savedOffset);
+				IncrementOffset(context);
+			}
+		}
+
+		private bool CheckAlive(IAspectVersionContext context)
+		{
+			if (!CheckEnabled(context))
+			{
+				return false;
+			}
+			bool alive = Alive();
+			if (!alive)
+			{
+				IncrementOffset((IReadBuffer)context);
+			}
+			return alive;
+		}
+
+		private void InformAboutTransaction(object obj, Transaction trans)
+		{
+			if (_db4oType != null && obj != null)
+			{
+				((IDb4oTypeImpl)obj).SetTrans(trans);
+			}
+		}
+
+		public virtual bool IsArray()
+		{
+			return _isArray;
+		}
+
+		public override int LinkLength()
+		{
+			Alive();
+			if (_linkLength == 0)
+			{
+				_linkLength = CalculateLinkLength();
+			}
+			return _linkLength;
+		}
+
+		private int CalculateLinkLength()
+		{
+			return Handlers4.CalculateLinkLength(GetHandler());
+		}
+
+		public virtual void LoadFieldTypeById()
+		{
+			_fieldType = Container().ClassMetadataForID(_fieldTypeID);
+		}
+
+		private ClassMetadata DetectFieldType()
+		{
+			IReflectClass claxx = _containingClass.ClassReflector();
+			if (claxx == null)
+			{
+				return null;
+			}
+			_reflectField = claxx.GetDeclaredField(_name);
+			if (_reflectField == null)
+			{
+				return null;
+			}
+			IReflectClass fieldType = _reflectField.GetFieldType();
+			if (fieldType == null)
+			{
+				return null;
+			}
+			return Handlers4.ErasedFieldType(Container(), fieldType);
+		}
+
+		protected virtual ITypeHandler4 TypeHandlerForClass(ObjectContainerBase container
+			, IReflectClass fieldType)
+		{
+			container.ShowInternalClasses(true);
+			try
+			{
+				return container.TypeHandlerForClass(Handlers4.BaseType(fieldType));
+			}
+			finally
+			{
+				container.ShowInternalClasses(false);
+			}
+		}
+
+		private void CheckCorrectTypeForField()
+		{
+			ClassMetadata currentFieldType = DetectFieldType();
+			if (currentFieldType == null)
+			{
+				_reflectField = null;
+				_state = FieldMetadataState.Unavailable;
+				return;
+			}
+			if (currentFieldType == _fieldType && Handlers4.BaseType(_reflectField.GetFieldType
+				()).IsPrimitive() == _isPrimitive)
+			{
+				return;
+			}
+			// special case when migrating from type handler ids
+			// to class metadata ids which caused
+			// any interface metadata id to be mapped to UNTYPED_ID
+			if (Handlers4.IsUntyped(currentFieldType.TypeHandler()) && Handlers4.IsUntyped(_fieldType
+				.TypeHandler()))
+			{
+				return;
+			}
+			// FIXME: COR-547 Diagnostics here please.
+			_state = FieldMetadataState.Updating;
+		}
+
+		private IUpdateDepth AdjustUpdateDepthForCascade(object obj, IUpdateDepth updateDepth
+			)
+		{
+			return updateDepth.AdjustUpdateDepthForCascade(_containingClass.IsCollection(obj)
+				);
+		}
+
+		private bool CascadeOnUpdate(Config4Class parentClassConfiguration)
+		{
+			return ((parentClassConfiguration != null && (parentClassConfiguration.CascadeOnUpdate
+				().DefiniteYes())) || (_config != null && (_config.CascadeOnUpdate().DefiniteYes
+				())));
+		}
+
+		public override void Marshall(MarshallingContext context, object obj)
+		{
+			// alive needs to be checked by all callers: Done
+			IUpdateDepth updateDepth = context.UpdateDepth();
+			if (obj != null && CascadeOnUpdate(context.ClassConfiguration()))
+			{
+				context.UpdateDepth(AdjustUpdateDepthForCascade(obj, updateDepth));
+			}
+			context.WriteObjectWithCurrentState(GetHandler(), obj);
+			context.UpdateDepth(updateDepth);
+			if (HasIndex())
+			{
+				context.AddIndexEntry(this, obj);
+			}
+		}
+
+		public virtual bool NeedsArrayAndPrimitiveInfo()
+		{
+			return true;
+		}
+
+		public virtual IPreparedComparison PrepareComparison(IContext context, object obj
+			)
+		{
+			if (!Alive())
+			{
+				return null;
+			}
+			return Handlers4.PrepareComparisonFor(GetHandler(), context, obj);
+		}
+
+		public virtual Db4objects.Db4o.Internal.Query.Processor.QField QField(Transaction
+			 a_trans)
+		{
+			int classMetadataID = 0;
+			if (_containingClass != null)
+			{
+				classMetadataID = _containingClass.GetID();
+			}
+			return new Db4objects.Db4o.Internal.Query.Processor.QField(a_trans, _name, this, 
+				classMetadataID, _handle);
+		}
+
+		public virtual object Read(IObjectIdContext context)
+		{
+			if (!CanReadFromSlot((IAspectVersionContext)context))
+			{
+				IncrementOffset(context);
+				return null;
+			}
+			return context.Read(GetHandler());
+		}
+
+		private bool CanReadFromSlot(IAspectVersionContext context)
+		{
+			if (!IsEnabledOn(context))
+			{
+				return false;
+			}
+			if (Alive())
+			{
+				return true;
+			}
+			return _state != FieldMetadataState.NotLoaded;
+		}
+
+		internal virtual void Refresh()
+		{
+			ClassMetadata newFieldType = DetectFieldType();
+			if (newFieldType != null && newFieldType.Equals(_fieldType))
+			{
+				return;
+			}
+			_reflectField = null;
+			_state = FieldMetadataState.Unavailable;
+		}
+
+		// FIXME: needs test case
+		public virtual void Rename(string newName)
+		{
+			ObjectContainerBase container = Container();
+			if (!container.IsClient)
+			{
+				_name = newName;
+				_containingClass.SetStateDirty();
+				_containingClass.Write(container.SystemTransaction());
+			}
+			else
+			{
+				Exceptions4.ThrowRuntimeException(58);
+			}
+		}
+
+		public virtual void Set(object onObject, object obj)
+		{
+			// TODO: remove the following if and check callers
+			if (null == _reflectField)
+			{
+				return;
+			}
+			FieldAccessor().Set(_reflectField, onObject, obj);
+		}
+
+		internal virtual void SetName(string a_name)
+		{
+			_name = a_name;
+		}
+
+		internal virtual bool SupportsIndex()
+		{
+			return Alive() && (GetHandler() is IIndexable4) && (!Handlers4.IsUntyped(GetHandler
+				()));
+		}
+
+		public void TraverseValues(IVisitor4 userVisitor)
+		{
+			if (!Alive())
+			{
+				return;
+			}
+			TraverseValues(Container().Transaction, userVisitor);
+		}
+
+		public void TraverseValues(Transaction transaction, IVisitor4 userVisitor)
+		{
+			if (!Alive())
+			{
+				return;
+			}
+			AssertHasIndex();
+			ObjectContainerBase stream = transaction.Container();
+			if (stream.IsClient)
+			{
+				Exceptions4.ThrowRuntimeException(Db4objects.Db4o.Internal.Messages.ClientServerUnsupported
+					);
+			}
+			lock (stream.Lock())
+			{
+				IContext context = transaction.Context();
+				_index.TraverseKeys(transaction, new _IVisitor4_866(this, userVisitor, context));
+			}
+		}
+
+		private sealed class _IVisitor4_866 : IVisitor4
+		{
+			public _IVisitor4_866(FieldMetadata _enclosing, IVisitor4 userVisitor, IContext context
+				)
+			{
+				this._enclosing = _enclosing;
+				this.userVisitor = userVisitor;
+				this.context = context;
+			}
+
+			public void Visit(object obj)
+			{
+				IFieldIndexKey key = (IFieldIndexKey)obj;
+				userVisitor.Visit(((IIndexableTypeHandler)this._enclosing.GetHandler()).IndexEntryToObject
+					(context, key.Value()));
+			}
+
+			private readonly FieldMetadata _enclosing;
+
+			private readonly IVisitor4 userVisitor;
+
+			private readonly IContext context;
+		}
+
+		private void AssertHasIndex()
+		{
+			if (!HasIndex())
+			{
+				Exceptions4.ThrowRuntimeException(Db4objects.Db4o.Internal.Messages.OnlyForIndexedFields
+					);
+			}
+		}
+
+		public override string ToString()
+		{
+			StringBuilder sb = new StringBuilder();
+			if (_containingClass != null)
+			{
+				sb.Append(_containingClass.GetName());
+				sb.Append(".");
+			}
+			sb.Append(GetName());
+			return sb.ToString();
+		}
+
+		private void InitIndex(Transaction systemTrans)
+		{
+			InitIndex(systemTrans, 0);
+		}
+
+		public virtual void InitIndex(Transaction systemTrans, int id)
+		{
+			if (_index != null)
+			{
+				throw new InvalidOperationException();
+			}
+			if (systemTrans.Container().IsClient)
+			{
+				return;
+			}
+			_index = NewBTree(systemTrans, id);
+		}
+
+		protected BTree NewBTree(Transaction systemTrans, int id)
+		{
+			ObjectContainerBase stream = systemTrans.Container();
+			IIndexable4 indexHandler = IndexHandler(stream);
+			if (indexHandler == null)
+			{
+				return null;
+			}
+			return new BTree(systemTrans, id, new FieldIndexKeyHandler(indexHandler));
+		}
+
+		protected virtual IIndexable4 IndexHandler(ObjectContainerBase stream)
+		{
+			if (_reflectField == null)
+			{
+				return null;
+			}
+			IReflectClass indexType = _reflectField.IndexType();
+			ITypeHandler4 classHandler = TypeHandlerForClass(stream, indexType);
+			if (!(classHandler is IIndexable4))
+			{
+				return null;
+			}
+			return (IIndexable4)classHandler;
+		}
+
+		/// <param name="trans"></param>
+		public virtual BTree GetIndex(Transaction trans)
+		{
+			return _index;
+		}
+
+		public virtual bool IsVirtual()
+		{
+			return false;
+		}
+
+		public virtual bool IsPrimitive()
+		{
+			return _isPrimitive;
+		}
+
+		public virtual IBTreeRange Search(Transaction transaction, object value)
+		{
+			AssertHasIndex();
+			object transActionalValue = Handlers4.WrapWithTransactionContext(transaction, value
+				, GetHandler());
+			BTreeNodeSearchResult lowerBound = SearchLowerBound(transaction, transActionalValue
+				);
+			BTreeNodeSearchResult upperBound = SearchUpperBound(transaction, transActionalValue
+				);
+			return lowerBound.CreateIncludingRange(upperBound);
+		}
+
+		private BTreeNodeSearchResult SearchUpperBound(Transaction transaction, object value
+			)
+		{
+			return SearchBound(transaction, int.MaxValue, value);
+		}
+
+		private BTreeNodeSearchResult SearchLowerBound(Transaction transaction, object value
+			)
+		{
+			return SearchBound(transaction, 0, value);
+		}
+
+		private BTreeNodeSearchResult SearchBound(Transaction transaction, int parentID, 
+			object keyPart)
+		{
+			return GetIndex(transaction).SearchLeaf(transaction, CreateFieldIndexKey(parentID
+				, keyPart), SearchTarget.Lowest);
+		}
+
+		public virtual bool RebuildIndexForClass(LocalObjectContainer stream, ClassMetadata
+			 classMetadata)
+		{
+			// FIXME: BTree traversal over index here.
+			long[] ids = classMetadata.GetIDs();
+			for (int i = 0; i < ids.Length; i++)
+			{
+				RebuildIndexForObject(stream, classMetadata, (int)ids[i]);
+			}
+			return ids.Length > 0;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.FieldIndexException"></exception>
+		protected virtual void RebuildIndexForObject(LocalObjectContainer stream, ClassMetadata
+			 classMetadata, int objectId)
+		{
+			StatefulBuffer writer = stream.ReadStatefulBufferById(stream.SystemTransaction(), 
+				objectId);
+			if (writer != null)
+			{
+				RebuildIndexForWriter(stream, writer, objectId);
+			}
+		}
+
+		protected virtual void RebuildIndexForWriter(LocalObjectContainer stream, StatefulBuffer
+			 writer, int objectId)
+		{
+			ObjectHeader oh = new ObjectHeader(stream, writer);
+			object obj = ReadIndexEntryForRebuild(writer, oh);
+			AddIndexEntry(stream.SystemTransaction(), objectId, obj);
+		}
+
+		private object ReadIndexEntryForRebuild(StatefulBuffer writer, ObjectHeader oh)
+		{
+			ClassMetadata classMetadata = oh.ClassMetadata();
+			if (classMetadata == null)
+			{
+				return DefaultValueForFieldType();
+			}
+			ObjectIdContextImpl context = new ObjectIdContextImpl(writer.Transaction(), writer
+				, oh, writer.GetID());
+			if (!classMetadata.SeekToField(context, this))
+			{
+				return DefaultValueForFieldType();
+			}
+			try
+			{
+				return ReadIndexEntry(context);
+			}
+			catch (CorruptionException exc)
+			{
+				throw new FieldIndexException(exc, this);
+			}
+		}
+
+		private object DefaultValueForFieldType()
+		{
+			ITypeHandler4 handler = _fieldType.TypeHandler();
+			return (handler is PrimitiveHandler) ? ((PrimitiveHandler)handler).PrimitiveNull(
+				) : null;
+		}
+
+		public void DropIndex(LocalTransaction systemTrans)
+		{
+			if (_index == null)
+			{
+				return;
+			}
+			ObjectContainerBase stream = systemTrans.Container();
+			if (stream.ConfigImpl.MessageLevel() > Const4.None)
+			{
+				stream.Message("dropping index " + ToString());
+			}
+			_index.Free(systemTrans);
+			stream.SetDirtyInSystemTransaction(ContainingClass());
+			_index = null;
+		}
+
+		public override void DefragAspect(IDefragmentContext context)
+		{
+			if (!CanDefragment())
+			{
+				throw new InvalidOperationException("Field '" + ToString() + "' cannot be defragmented at this time."
+					);
+			}
+			ITypeHandler4 correctTypeHandlerVersion = HandlerRegistry.CorrectHandlerVersion(context
+				, GetHandler(), _fieldType);
+			context.SlotFormat().DoWithSlotIndirection(context, correctTypeHandlerVersion, new 
+				_IClosure4_1029(context, correctTypeHandlerVersion));
+		}
+
+		private sealed class _IClosure4_1029 : IClosure4
+		{
+			public _IClosure4_1029(IDefragmentContext context, ITypeHandler4 correctTypeHandlerVersion
+				)
+			{
+				this.context = context;
+				this.correctTypeHandlerVersion = correctTypeHandlerVersion;
+			}
+
+			public object Run()
+			{
+				context.Defragment(correctTypeHandlerVersion);
+				return null;
+			}
+
+			private readonly IDefragmentContext context;
+
+			private readonly ITypeHandler4 correctTypeHandlerVersion;
+		}
+
+		private bool CanDefragment()
+		{
+			if (Alive() || Updating())
+			{
+				return true;
+			}
+			if (_fieldType == null || GetHandler() == null)
+			{
+				return false;
+			}
+			return !_fieldType.StateDead();
+		}
+
+		public virtual void CreateIndex()
+		{
+			if (HasIndex())
+			{
+				return;
+			}
+			LocalObjectContainer container = (LocalObjectContainer)Container();
+			if (container.ConfigImpl.MessageLevel() > Const4.None)
+			{
+				container.Message("creating index " + ToString());
+			}
+			InitIndex(container.SystemTransaction());
+			container.SetDirtyInSystemTransaction(ContainingClass());
+			Reindex(container);
+		}
+
+		private void Reindex(LocalObjectContainer container)
+		{
+			ClassMetadata clazz = ContainingClass();
+			if (RebuildIndexForClass(container, clazz))
+			{
+				container.SystemTransaction().Commit();
+			}
+		}
+
+		public override Db4objects.Db4o.Internal.Marshall.AspectType AspectType()
+		{
+			return Db4objects.Db4o.Internal.Marshall.AspectType.Field;
+		}
+
+		// overriden in VirtualFieldMetadata
+		public override bool CanBeDisabled()
+		{
+			return true;
+		}
+
+		public virtual void DropIndex()
+		{
+			DropIndex((LocalTransaction)Container().SystemTransaction());
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/FieldMetadataState.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/FieldMetadataState.cs
new file mode 100644
index 0000000..e126801
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/FieldMetadataState.cs
@@ -0,0 +1,32 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	internal class FieldMetadataState
+	{
+		private readonly string _info;
+
+		private FieldMetadataState(string info)
+		{
+			_info = info;
+		}
+
+		internal static readonly Db4objects.Db4o.Internal.FieldMetadataState NotLoaded = 
+			new Db4objects.Db4o.Internal.FieldMetadataState("not loaded");
+
+		internal static readonly Db4objects.Db4o.Internal.FieldMetadataState Unavailable = 
+			new Db4objects.Db4o.Internal.FieldMetadataState("unavailable");
+
+		internal static readonly Db4objects.Db4o.Internal.FieldMetadataState Available = 
+			new Db4objects.Db4o.Internal.FieldMetadataState("available");
+
+		internal static readonly Db4objects.Db4o.Internal.FieldMetadataState Updating = new 
+			Db4objects.Db4o.Internal.FieldMetadataState("updating");
+
+		public override string ToString()
+		{
+			return _info;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/AndIndexedLeaf.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/AndIndexedLeaf.cs
new file mode 100644
index 0000000..a903fa8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/AndIndexedLeaf.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Fieldindex;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Fieldindex
+{
+	public class AndIndexedLeaf : JoinedLeaf
+	{
+		public AndIndexedLeaf(QCon constraint, IIndexedNodeWithRange leaf1, IIndexedNodeWithRange
+			 leaf2) : base(constraint, leaf1, leaf1.GetRange().Intersect(leaf2.GetRange()))
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/FieldIndexProcessor.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/FieldIndexProcessor.cs
new file mode 100644
index 0000000..3511506
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/FieldIndexProcessor.cs
@@ -0,0 +1,75 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Internal.Fieldindex;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Fieldindex
+{
+	public class FieldIndexProcessor
+	{
+		private readonly QCandidates _candidates;
+
+		public FieldIndexProcessor(QCandidates candidates)
+		{
+			_candidates = candidates;
+		}
+
+		public virtual FieldIndexProcessorResult Run()
+		{
+			IIndexedNode bestIndex = SelectBestIndex();
+			if (null == bestIndex)
+			{
+				return FieldIndexProcessorResult.NoIndexFound;
+			}
+			if (bestIndex.ResultSize() > 0)
+			{
+				IIndexedNode resolved = ResolveFully(bestIndex);
+				if (null == resolved)
+				{
+					return FieldIndexProcessorResult.NoIndexFound;
+				}
+				resolved.MarkAsBestIndex();
+				return new FieldIndexProcessorResult(resolved);
+			}
+			return FieldIndexProcessorResult.FoundIndexButNoMatch;
+		}
+
+		private IIndexedNode ResolveFully(IIndexedNode bestIndex)
+		{
+			if (null == bestIndex)
+			{
+				return null;
+			}
+			if (bestIndex.IsResolved())
+			{
+				return bestIndex;
+			}
+			return ResolveFully(bestIndex.Resolve());
+		}
+
+		public virtual IIndexedNode SelectBestIndex()
+		{
+			IEnumerator i = CollectIndexedNodes();
+			if (!i.MoveNext())
+			{
+				return null;
+			}
+			IIndexedNode best = (IIndexedNode)i.Current;
+			while (i.MoveNext())
+			{
+				IIndexedNode leaf = (IIndexedNode)i.Current;
+				if (leaf.ResultSize() < best.ResultSize())
+				{
+					best = leaf;
+				}
+			}
+			return best;
+		}
+
+		public virtual IEnumerator CollectIndexedNodes()
+		{
+			return new IndexedNodeCollector(_candidates).GetNodes();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/FieldIndexProcessorResult.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/FieldIndexProcessorResult.cs
new file mode 100644
index 0000000..d31fbdd
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/FieldIndexProcessorResult.cs
@@ -0,0 +1,76 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Fieldindex;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Fieldindex
+{
+	public class FieldIndexProcessorResult
+	{
+		public static readonly Db4objects.Db4o.Internal.Fieldindex.FieldIndexProcessorResult
+			 NoIndexFound = new Db4objects.Db4o.Internal.Fieldindex.FieldIndexProcessorResult
+			(null);
+
+		public static readonly Db4objects.Db4o.Internal.Fieldindex.FieldIndexProcessorResult
+			 FoundIndexButNoMatch = new Db4objects.Db4o.Internal.Fieldindex.FieldIndexProcessorResult
+			(null);
+
+		private readonly IIndexedNode _indexedNode;
+
+		public FieldIndexProcessorResult(IIndexedNode indexedNode)
+		{
+			_indexedNode = indexedNode;
+		}
+
+		public virtual Tree ToQCandidate(QCandidates candidates)
+		{
+			return TreeInt.ToQCandidate(ToTreeInt(), candidates);
+		}
+
+		public virtual TreeInt ToTreeInt()
+		{
+			if (FoundMatch())
+			{
+				return _indexedNode.ToTreeInt();
+			}
+			return null;
+		}
+
+		public virtual bool FoundMatch()
+		{
+			return FoundIndex() && !NoMatch();
+		}
+
+		public virtual bool FoundIndex()
+		{
+			return this != NoIndexFound;
+		}
+
+		public virtual bool NoMatch()
+		{
+			return this == FoundIndexButNoMatch;
+		}
+
+		public virtual IEnumerator IterateIDs()
+		{
+			return new _MappingIterator_46(_indexedNode.GetEnumerator());
+		}
+
+		private sealed class _MappingIterator_46 : MappingIterator
+		{
+			public _MappingIterator_46(IEnumerator baseArg1) : base(baseArg1)
+			{
+			}
+
+			protected override object Map(object current)
+			{
+				IFieldIndexKey composite = (IFieldIndexKey)current;
+				return composite.ParentID();
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IIndexedNode.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IIndexedNode.cs
new file mode 100644
index 0000000..38315a7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IIndexedNode.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Fieldindex;
+
+namespace Db4objects.Db4o.Internal.Fieldindex
+{
+	public interface IIndexedNode : IEnumerable
+	{
+		bool IsResolved();
+
+		IIndexedNode Resolve();
+
+		BTree GetIndex();
+
+		int ResultSize();
+
+		//FIXME: do we need this?
+		TreeInt ToTreeInt();
+
+		void MarkAsBestIndex();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IIndexedNodeWithRange.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IIndexedNodeWithRange.cs
new file mode 100644
index 0000000..6dc0b20
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IIndexedNodeWithRange.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Fieldindex;
+
+namespace Db4objects.Db4o.Internal.Fieldindex
+{
+	public interface IIndexedNodeWithRange : IIndexedNode
+	{
+		IBTreeRange GetRange();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IndexedLeaf.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IndexedLeaf.cs
new file mode 100644
index 0000000..aa868ad
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IndexedLeaf.cs
@@ -0,0 +1,68 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Fieldindex;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Fieldindex
+{
+	/// <exclude></exclude>
+	public class IndexedLeaf : IndexedNodeBase, IIndexedNodeWithRange
+	{
+		private readonly IBTreeRange _range;
+
+		public IndexedLeaf(QConObject qcon) : base(qcon)
+		{
+			_range = Search();
+		}
+
+		private IBTreeRange Search()
+		{
+			IBTreeRange range = Search(Constraint().GetObject());
+			QEBitmap bitmap = QEBitmap.ForQE(Constraint().Evaluator());
+			if (bitmap.TakeGreater())
+			{
+				if (bitmap.TakeEqual())
+				{
+					return range.ExtendToLast();
+				}
+				IBTreeRange greater = range.Greater();
+				if (bitmap.TakeSmaller())
+				{
+					return greater.Union(range.Smaller());
+				}
+				return greater;
+			}
+			if (bitmap.TakeSmaller())
+			{
+				if (bitmap.TakeEqual())
+				{
+					return range.ExtendToFirst();
+				}
+				return range.Smaller();
+			}
+			return range;
+		}
+
+		public override int ResultSize()
+		{
+			return _range.Size();
+		}
+
+		public override IEnumerator GetEnumerator()
+		{
+			return _range.Keys();
+		}
+
+		public virtual IBTreeRange GetRange()
+		{
+			return _range;
+		}
+
+		public override void MarkAsBestIndex()
+		{
+			_constraint.SetProcessedByIndex();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IndexedNodeBase.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IndexedNodeBase.cs
new file mode 100644
index 0000000..106c1cf
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IndexedNodeBase.cs
@@ -0,0 +1,92 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Fieldindex;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Fieldindex
+{
+	public abstract class IndexedNodeBase : IIndexedNode
+	{
+		protected readonly QConObject _constraint;
+
+		public IndexedNodeBase(QConObject qcon)
+		{
+			if (null == qcon)
+			{
+				throw new ArgumentNullException();
+			}
+			if (null == qcon.GetField())
+			{
+				throw new ArgumentException();
+			}
+			_constraint = qcon;
+		}
+
+		public virtual TreeInt ToTreeInt()
+		{
+			return AddToTree(null, this);
+		}
+
+		public BTree GetIndex()
+		{
+			return GetYapField().GetIndex(Transaction());
+		}
+
+		private FieldMetadata GetYapField()
+		{
+			return _constraint.GetField().GetFieldMetadata();
+		}
+
+		public virtual QCon Constraint()
+		{
+			return _constraint;
+		}
+
+		public virtual bool IsResolved()
+		{
+			QCon parent = Constraint().Parent();
+			return null == parent || !parent.HasParent();
+		}
+
+		public virtual IBTreeRange Search(object value)
+		{
+			return GetYapField().Search(Transaction(), value);
+		}
+
+		public static TreeInt AddToTree(TreeInt tree, IIndexedNode node)
+		{
+			IEnumerator i = node.GetEnumerator();
+			while (i.MoveNext())
+			{
+				IFieldIndexKey composite = (IFieldIndexKey)i.Current;
+				tree = (TreeInt)((TreeInt)Tree.Add(tree, new TreeInt(composite.ParentID())));
+			}
+			return tree;
+		}
+
+		public virtual IIndexedNode Resolve()
+		{
+			if (IsResolved())
+			{
+				return null;
+			}
+			return IndexedPath.NewParentPath(this, Constraint());
+		}
+
+		private Db4objects.Db4o.Internal.Transaction Transaction()
+		{
+			return Constraint().Transaction();
+		}
+
+		public abstract IEnumerator GetEnumerator();
+
+		public abstract void MarkAsBestIndex();
+
+		public abstract int ResultSize();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IndexedNodeCollector.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IndexedNodeCollector.cs
new file mode 100644
index 0000000..5f16500
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IndexedNodeCollector.cs
@@ -0,0 +1,354 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Fieldindex;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Fieldindex
+{
+	public class IndexedNodeCollector
+	{
+		private readonly Collection4 _nodes;
+
+		private readonly Hashtable4 _nodeCache;
+
+		public IndexedNodeCollector(QCandidates candidates)
+		{
+			_nodes = new Collection4();
+			_nodeCache = new Hashtable4();
+			CollectIndexedNodes(candidates);
+		}
+
+		public virtual IEnumerator GetNodes()
+		{
+			return _nodes.GetEnumerator();
+		}
+
+		private void CollectIndexedNodes(QCandidates candidates)
+		{
+			CollectIndexedNodes(candidates.IterateConstraints());
+			ImplicitlyAndJoinsOnSameField();
+		}
+
+		private void ImplicitlyAndJoinsOnSameField()
+		{
+			object[] nodes = _nodes.ToArray();
+			for (int i = 0; i < nodes.Length; i++)
+			{
+				object node = nodes[i];
+				if (node is OrIndexedLeaf)
+				{
+					OrIndexedLeaf current = (OrIndexedLeaf)node;
+					OrIndexedLeaf other = FindJoinOnSameFieldAtSameLevel(current);
+					if (null != other)
+					{
+						nodes[Arrays4.IndexOfIdentity(nodes, other)] = null;
+						CollectImplicitAnd(current.GetConstraint(), current, other);
+					}
+				}
+			}
+		}
+
+		private OrIndexedLeaf FindJoinOnSameFieldAtSameLevel(OrIndexedLeaf join)
+		{
+			IEnumerator i = _nodes.GetEnumerator();
+			while (i.MoveNext())
+			{
+				if (i.Current == join)
+				{
+					continue;
+				}
+				if (i.Current is OrIndexedLeaf)
+				{
+					OrIndexedLeaf current = (OrIndexedLeaf)i.Current;
+					if (current.GetIndex() == join.GetIndex() && ParentConstraint(current) == ParentConstraint
+						(join))
+					{
+						return current;
+					}
+				}
+			}
+			return null;
+		}
+
+		private object ParentConstraint(OrIndexedLeaf node)
+		{
+			return node.GetConstraint().Parent();
+		}
+
+		private void CollectIndexedNodes(IEnumerator qcons)
+		{
+			while (qcons.MoveNext())
+			{
+				QCon qcon = (QCon)qcons.Current;
+				if (IsCached(qcon))
+				{
+					continue;
+				}
+				if (IsLeaf(qcon))
+				{
+					if (qcon.CanLoadByIndex() && qcon.CanBeIndexLeaf())
+					{
+						QConObject conObject = (QConObject)qcon;
+						if (conObject.HasJoins())
+						{
+							CollectJoinedNode(conObject);
+						}
+						else
+						{
+							CollectStandaloneNode(conObject);
+						}
+					}
+				}
+				else
+				{
+					if (!qcon.HasJoins())
+					{
+						CollectIndexedNodes(qcon.IterateChildren());
+					}
+				}
+			}
+		}
+
+		private bool IsCached(QCon qcon)
+		{
+			return null != _nodeCache.Get(qcon);
+		}
+
+		private void CollectStandaloneNode(QConObject conObject)
+		{
+			IndexedLeaf existing = FindLeafOnSameField(conObject);
+			if (existing != null)
+			{
+				CollectImplicitAnd(conObject, existing, new IndexedLeaf(conObject));
+			}
+			else
+			{
+				_nodes.Add(new IndexedLeaf(conObject));
+			}
+		}
+
+		private void CollectJoinedNode(QConObject constraintWithJoins)
+		{
+			Collection4 joins = CollectTopLevelJoins(constraintWithJoins);
+			if (!CanJoinsBeSearchedByIndex(joins))
+			{
+				return;
+			}
+			if (1 == joins.Size())
+			{
+				_nodes.Add(NodeForConstraint((QCon)joins.SingleElement()));
+				return;
+			}
+			CollectImplicitlyAndingJoins(joins, constraintWithJoins);
+		}
+
+		private bool AllHaveSamePath(Collection4 leaves)
+		{
+			IEnumerator i = leaves.GetEnumerator();
+			i.MoveNext();
+			QCon first = (QCon)i.Current;
+			while (i.MoveNext())
+			{
+				if (!HaveSamePath(first, (QCon)i.Current))
+				{
+					return false;
+				}
+			}
+			return true;
+		}
+
+		private bool HaveSamePath(QCon x, QCon y)
+		{
+			if (x == y)
+			{
+				return true;
+			}
+			if (!x.OnSameFieldAs(y))
+			{
+				return false;
+			}
+			if (!x.HasParent())
+			{
+				return !y.HasParent();
+			}
+			return HaveSamePath(x.Parent(), y.Parent());
+		}
+
+		private Collection4 CollectLeaves(Collection4 joins)
+		{
+			Collection4 leaves = new Collection4();
+			CollectLeaves(leaves, joins);
+			return leaves;
+		}
+
+		private void CollectLeaves(Collection4 leaves, Collection4 joins)
+		{
+			IEnumerator i = joins.GetEnumerator();
+			while (i.MoveNext())
+			{
+				QConJoin join = ((QConJoin)i.Current);
+				CollectLeavesFromJoin(leaves, join);
+			}
+		}
+
+		private void CollectLeavesFromJoin(Collection4 leaves, QConJoin join)
+		{
+			CollectLeavesFromJoinConstraint(leaves, join.Constraint1());
+			CollectLeavesFromJoinConstraint(leaves, join.Constraint2());
+		}
+
+		private void CollectLeavesFromJoinConstraint(Collection4 leaves, QCon constraint)
+		{
+			if (constraint is QConJoin)
+			{
+				CollectLeavesFromJoin(leaves, (QConJoin)constraint);
+			}
+			else
+			{
+				if (!leaves.ContainsByIdentity(constraint))
+				{
+					leaves.Add(constraint);
+				}
+			}
+		}
+
+		private bool CanJoinsBeSearchedByIndex(Collection4 joins)
+		{
+			Collection4 leaves = CollectLeaves(joins);
+			return AllHaveSamePath(leaves) && AllCanBeSearchedByIndex(leaves);
+		}
+
+		private bool AllCanBeSearchedByIndex(Collection4 leaves)
+		{
+			IEnumerator i = leaves.GetEnumerator();
+			while (i.MoveNext())
+			{
+				QCon leaf = ((QCon)i.Current);
+				if (!leaf.CanLoadByIndex())
+				{
+					return false;
+				}
+			}
+			return true;
+		}
+
+		private void CollectImplicitlyAndingJoins(Collection4 joins, QConObject constraintWithJoins
+			)
+		{
+			IEnumerator i = joins.GetEnumerator();
+			i.MoveNext();
+			IIndexedNodeWithRange last = NodeForConstraint((QCon)i.Current);
+			while (i.MoveNext())
+			{
+				IIndexedNodeWithRange node = NodeForConstraint((QCon)i.Current);
+				last = new AndIndexedLeaf(constraintWithJoins, node, last);
+				_nodes.Add(last);
+			}
+		}
+
+		private Collection4 CollectTopLevelJoins(QConObject constraintWithJoins)
+		{
+			Collection4 joins = new Collection4();
+			CollectTopLevelJoins(joins, constraintWithJoins);
+			return joins;
+		}
+
+		private void CollectTopLevelJoins(Collection4 joins, QCon constraintWithJoins)
+		{
+			IEnumerator i = constraintWithJoins.IterateJoins();
+			while (i.MoveNext())
+			{
+				QConJoin join = (QConJoin)i.Current;
+				if (!join.HasJoins())
+				{
+					if (!joins.ContainsByIdentity(join))
+					{
+						joins.Add(join);
+					}
+				}
+				else
+				{
+					CollectTopLevelJoins(joins, join);
+				}
+			}
+		}
+
+		private IIndexedNodeWithRange NewNodeForConstraint(QConJoin join)
+		{
+			IIndexedNodeWithRange c1 = NodeForConstraint(join.Constraint1());
+			IIndexedNodeWithRange c2 = NodeForConstraint(join.Constraint2());
+			if (join.IsOr())
+			{
+				return new OrIndexedLeaf(FindLeafForJoin(join), c1, c2);
+			}
+			return new AndIndexedLeaf(join.Constraint1(), c1, c2);
+		}
+
+		private QCon FindLeafForJoin(QConJoin join)
+		{
+			if (join.Constraint1() is QConObject)
+			{
+				return join.Constraint1();
+			}
+			QCon con = join.Constraint2();
+			if (con is QConObject)
+			{
+				return con;
+			}
+			return FindLeafForJoin((QConJoin)con);
+		}
+
+		private IIndexedNodeWithRange NodeForConstraint(QCon con)
+		{
+			IIndexedNodeWithRange node = (IIndexedNodeWithRange)_nodeCache.Get(con);
+			if (null != node || _nodeCache.ContainsKey(con))
+			{
+				return node;
+			}
+			node = NewNodeForConstraint(con);
+			_nodeCache.Put(con, node);
+			return node;
+		}
+
+		private IIndexedNodeWithRange NewNodeForConstraint(QCon con)
+		{
+			if (con is QConJoin)
+			{
+				return NewNodeForConstraint((QConJoin)con);
+			}
+			return new IndexedLeaf((QConObject)con);
+		}
+
+		private void CollectImplicitAnd(QCon constraint, IIndexedNodeWithRange x, IIndexedNodeWithRange
+			 y)
+		{
+			_nodes.Remove(x);
+			_nodes.Remove(y);
+			_nodes.Add(new AndIndexedLeaf(constraint, x, y));
+		}
+
+		private IndexedLeaf FindLeafOnSameField(QConObject conObject)
+		{
+			IEnumerator i = _nodes.GetEnumerator();
+			while (i.MoveNext())
+			{
+				if (i.Current is IndexedLeaf)
+				{
+					IndexedLeaf leaf = (IndexedLeaf)i.Current;
+					if (conObject.OnSameFieldAs(leaf.Constraint()))
+					{
+						return leaf;
+					}
+				}
+			}
+			return null;
+		}
+
+		private bool IsLeaf(QCon qcon)
+		{
+			return !qcon.HasChildren();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IndexedPath.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IndexedPath.cs
new file mode 100644
index 0000000..cc32b5f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IndexedPath.cs
@@ -0,0 +1,73 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Fieldindex;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Fieldindex
+{
+	public class IndexedPath : IndexedNodeBase
+	{
+		public static IIndexedNode NewParentPath(IIndexedNode next, QCon constraint)
+		{
+			if (!CanFollowParent(constraint))
+			{
+				return null;
+			}
+			return new Db4objects.Db4o.Internal.Fieldindex.IndexedPath((QConObject)constraint
+				.Parent(), next);
+		}
+
+		private static bool CanFollowParent(QCon con)
+		{
+			QCon parent = con.Parent();
+			FieldMetadata parentField = GetYapField(parent);
+			if (null == parentField)
+			{
+				return false;
+			}
+			FieldMetadata conField = GetYapField(con);
+			if (null == conField)
+			{
+				return false;
+			}
+			return parentField.HasIndex() && parentField.FieldType().IsAssignableFrom(conField
+				.ContainingClass());
+		}
+
+		private static FieldMetadata GetYapField(QCon con)
+		{
+			QField field = con.GetField();
+			if (null == field)
+			{
+				return null;
+			}
+			return field.GetFieldMetadata();
+		}
+
+		private IIndexedNode _next;
+
+		public IndexedPath(QConObject parent, IIndexedNode next) : base(parent)
+		{
+			_next = next;
+		}
+
+		public override IEnumerator GetEnumerator()
+		{
+			return new IndexedPathIterator(this, _next.GetEnumerator());
+		}
+
+		public override int ResultSize()
+		{
+			throw new NotSupportedException();
+		}
+
+		public override void MarkAsBestIndex()
+		{
+			_constraint.SetProcessedByIndex();
+			_next.MarkAsBestIndex();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IndexedPathIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IndexedPathIterator.cs
new file mode 100644
index 0000000..2b067b4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/IndexedPathIterator.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Fieldindex;
+
+namespace Db4objects.Db4o.Internal.Fieldindex
+{
+	internal sealed class IndexedPathIterator : CompositeIterator4
+	{
+		private IndexedPath _path;
+
+		public IndexedPathIterator(IndexedPath path, IEnumerator iterator) : base(iterator
+			)
+		{
+			_path = path;
+		}
+
+		protected override IEnumerator NextIterator(object current)
+		{
+			IFieldIndexKey key = (IFieldIndexKey)current;
+			return _path.Search(key.ParentID()).Keys();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/JoinedLeaf.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/JoinedLeaf.cs
new file mode 100644
index 0000000..a9d3424
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/JoinedLeaf.cs
@@ -0,0 +1,78 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Fieldindex;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Fieldindex
+{
+	public abstract class JoinedLeaf : IIndexedNodeWithRange
+	{
+		private readonly QCon _constraint;
+
+		private readonly IIndexedNodeWithRange _leaf1;
+
+		private readonly IBTreeRange _range;
+
+		public JoinedLeaf(QCon constraint, IIndexedNodeWithRange leaf1, IBTreeRange range
+			)
+		{
+			if (null == constraint || null == leaf1 || null == range)
+			{
+				throw new ArgumentNullException();
+			}
+			_constraint = constraint;
+			_leaf1 = leaf1;
+			_range = range;
+		}
+
+		public virtual QCon GetConstraint()
+		{
+			return _constraint;
+		}
+
+		public virtual IBTreeRange GetRange()
+		{
+			return _range;
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			return _range.Keys();
+		}
+
+		public virtual TreeInt ToTreeInt()
+		{
+			return IndexedNodeBase.AddToTree(null, this);
+		}
+
+		public virtual BTree GetIndex()
+		{
+			return _leaf1.GetIndex();
+		}
+
+		public virtual bool IsResolved()
+		{
+			return _leaf1.IsResolved();
+		}
+
+		public virtual IIndexedNode Resolve()
+		{
+			return IndexedPath.NewParentPath(this, _constraint);
+		}
+
+		public virtual int ResultSize()
+		{
+			return _range.Size();
+		}
+
+		public virtual void MarkAsBestIndex()
+		{
+			_leaf1.MarkAsBestIndex();
+			_constraint.SetProcessedByIndex();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/OrIndexedLeaf.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/OrIndexedLeaf.cs
new file mode 100644
index 0000000..9e8a66c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/OrIndexedLeaf.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Fieldindex;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Fieldindex
+{
+	public class OrIndexedLeaf : JoinedLeaf
+	{
+		public OrIndexedLeaf(QCon constraint, IIndexedNodeWithRange leaf1, IIndexedNodeWithRange
+			 leaf2) : base(constraint, leaf1, leaf1.GetRange().Union(leaf2.GetRange()))
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/QEBitmap.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/QEBitmap.cs
new file mode 100644
index 0000000..e9cdca9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fieldindex/QEBitmap.cs
@@ -0,0 +1,38 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Fieldindex
+{
+	internal class QEBitmap
+	{
+		public static Db4objects.Db4o.Internal.Fieldindex.QEBitmap ForQE(QE qe)
+		{
+			bool[] bitmap = new bool[4];
+			qe.IndexBitMap(bitmap);
+			return new Db4objects.Db4o.Internal.Fieldindex.QEBitmap(bitmap);
+		}
+
+		private QEBitmap(bool[] bitmap)
+		{
+			_bitmap = bitmap;
+		}
+
+		private bool[] _bitmap;
+
+		public virtual bool TakeGreater()
+		{
+			return _bitmap[QE.Greater];
+		}
+
+		public virtual bool TakeEqual()
+		{
+			return _bitmap[QE.Equal];
+		}
+
+		public virtual bool TakeSmaller()
+		{
+			return _bitmap[QE.Smaller];
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeader.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeader.cs
new file mode 100644
index 0000000..75a8c72
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeader.cs
@@ -0,0 +1,151 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Fileheader;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal.Fileheader
+{
+	/// <exclude></exclude>
+	public abstract class FileHeader
+	{
+		public const int TransactionPointerLength = Const4.IntLength * 2;
+
+		private static readonly FileHeader[] AvailableFileHeaders = new FileHeader[] { new 
+			FileHeader1(), new FileHeader2(), new FileHeader3() };
+
+		public static NewFileHeaderBase NewCurrentFileHeader()
+		{
+			return new FileHeader3();
+		}
+
+		private static int ReaderLength()
+		{
+			int length = AvailableFileHeaders[0].Length();
+			for (int i = 1; i < AvailableFileHeaders.Length; i++)
+			{
+				length = Math.Max(length, AvailableFileHeaders[i].Length());
+			}
+			return length;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.OldFormatException"></exception>
+		public static FileHeader Read(LocalObjectContainer file)
+		{
+			ByteArrayBuffer reader = PrepareFileHeaderReader(file);
+			FileHeader header = DetectFileHeader(file, reader);
+			if (header == null)
+			{
+				Exceptions4.ThrowRuntimeException(Db4objects.Db4o.Internal.Messages.IncompatibleFormat
+					, file.ToString());
+			}
+			else
+			{
+				header.Read(file, reader);
+			}
+			return header;
+		}
+
+		public virtual FileHeader Convert(LocalObjectContainer file)
+		{
+			FileHeader3 fileHeader = new FileHeader3();
+			fileHeader.InitNew(file);
+			return fileHeader;
+		}
+
+		private static ByteArrayBuffer PrepareFileHeaderReader(LocalObjectContainer file)
+		{
+			ByteArrayBuffer reader = new ByteArrayBuffer(ReaderLength());
+			reader.Read(file, 0, 0);
+			return reader;
+		}
+
+		private static FileHeader DetectFileHeader(LocalObjectContainer file, ByteArrayBuffer
+			 reader)
+		{
+			for (int i = 0; i < AvailableFileHeaders.Length; i++)
+			{
+				reader.Seek(0);
+				FileHeader result = AvailableFileHeaders[i].NewOnSignatureMatch(file, reader);
+				if (result != null)
+				{
+					return result;
+				}
+			}
+			return null;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public abstract void Close();
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public abstract void InitNew(LocalObjectContainer file);
+
+		public abstract void CompleteInterruptedTransaction(LocalObjectContainer container
+			);
+
+		public abstract int Length();
+
+		protected abstract FileHeader NewOnSignatureMatch(LocalObjectContainer file, ByteArrayBuffer
+			 reader);
+
+		protected virtual long TimeToWrite(long time, bool shuttingDown)
+		{
+			return shuttingDown ? 0 : time;
+		}
+
+		protected abstract void Read(LocalObjectContainer file, ByteArrayBuffer reader);
+
+		protected virtual bool SignatureMatches(ByteArrayBuffer reader, byte[] signature, 
+			byte version)
+		{
+			for (int i = 0; i < signature.Length; i++)
+			{
+				if (reader.ReadByte() != signature[i])
+				{
+					return false;
+				}
+			}
+			return reader.ReadByte() == version;
+		}
+
+		// TODO: freespaceID should not be passed here, it should be taken from SystemData
+		public abstract void WriteFixedPart(LocalObjectContainer file, bool startFileLockingThread
+			, bool shuttingDown, StatefulBuffer writer, int blockSize);
+
+		public abstract void WriteTransactionPointer(Transaction systemTransaction, int transactionPointer
+			);
+
+		protected virtual void WriteTransactionPointer(Transaction systemTransaction, int
+			 transactionPointer, int address, int offset)
+		{
+			StatefulBuffer bytes = new StatefulBuffer(systemTransaction, address, TransactionPointerLength
+				);
+			bytes.MoveForward(offset);
+			bytes.WriteInt(transactionPointer);
+			bytes.WriteInt(transactionPointer);
+			// Dangerous write. 
+			// On corruption transaction pointers will not be the same and nothing will happen.
+			bytes.Write();
+		}
+
+		public virtual void WriteVariablePart(LocalObjectContainer file)
+		{
+			WriteVariablePart(file, false);
+		}
+
+		public abstract void WriteVariablePart(LocalObjectContainer file, bool shuttingDown
+			);
+
+		public static bool LockedByOtherSession(LocalObjectContainer container, long lastAccessTime
+			)
+		{
+			return container.NeedsLockFileThread() && (lastAccessTime != 0);
+		}
+
+		public abstract void ReadIdentity(LocalObjectContainer container);
+
+		public abstract IRunnable Commit(bool shuttingDown);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeader1.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeader1.cs
new file mode 100644
index 0000000..646720e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeader1.cs
@@ -0,0 +1,88 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Fileheader;
+
+namespace Db4objects.Db4o.Internal.Fileheader
+{
+	/// <exclude></exclude>
+	public class FileHeader1 : NewFileHeaderBase
+	{
+		private static readonly int TransactionPointerOffset = AccessTimeOffset + Const4.
+			LongLength;
+
+		private static readonly int BlocksizeOffset = TransactionPointerOffset + (Const4.
+			IntLength * 2);
+
+		public static readonly int HeaderLength = TransactionPointerOffset + (Const4.IntLength
+			 * 6);
+
+		// The header format is:
+		// (byte) 'd'
+		// (byte) 'b'
+		// (byte) '4'
+		// (byte) 'o'
+		// (byte) headerVersion
+		// (int) headerLock
+		// (long) openTime
+		// (long) accessTime
+		// (int) Transaction pointer 1
+		// (int) Transaction pointer 2
+		// (int) blockSize
+		// (int) classCollectionID
+		// (int) freespaceID
+		// (int) variablePartID
+		public override int Length()
+		{
+			return HeaderLength;
+		}
+
+		protected override void Read(LocalObjectContainer file, ByteArrayBuffer reader)
+		{
+			NewTimerFileLock(file);
+			OldEncryptionOff(file);
+			CheckThreadFileLock(file, reader);
+			reader.Seek(TransactionPointerOffset);
+			file.SystemData().TransactionPointer1(reader.ReadInt());
+			file.SystemData().TransactionPointer2(reader.ReadInt());
+			reader.Seek(BlocksizeOffset);
+			file.BlockSizeReadFromFile(reader.ReadInt());
+			SystemData systemData = file.SystemData();
+			systemData.ClassCollectionID(reader.ReadInt());
+			reader.ReadInt();
+			// was freespace ID, can no longer be read
+			_variablePart = CreateVariablePart(file);
+			int variablePartId = reader.ReadInt();
+			_variablePart.Read(variablePartId, 0);
+		}
+
+		public override void WriteFixedPart(LocalObjectContainer file, bool startFileLockingThread
+			, bool shuttingDown, StatefulBuffer writer, int blockSize)
+		{
+			throw new InvalidOperationException();
+		}
+
+		public override void WriteTransactionPointer(Transaction systemTransaction, int transactionPointer
+			)
+		{
+			throw new InvalidOperationException();
+		}
+
+		protected override NewFileHeaderBase CreateNew()
+		{
+			return new FileHeader1();
+		}
+
+		protected override byte Version()
+		{
+			return (byte)1;
+		}
+
+		public override FileHeaderVariablePart CreateVariablePart(LocalObjectContainer file
+			)
+		{
+			return new FileHeaderVariablePart1(file);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeader2.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeader2.cs
new file mode 100644
index 0000000..ecf583d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeader2.cs
@@ -0,0 +1,125 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Fileheader;
+using Sharpen;
+
+namespace Db4objects.Db4o.Internal.Fileheader
+{
+	/// <exclude></exclude>
+	public class FileHeader2 : NewFileHeaderBase
+	{
+		private static readonly int BlocksizeOffset = AccessTimeOffset + Const4.LongLength;
+
+		public static readonly int HeaderLength = BlocksizeOffset + (Const4.IntLength * 5
+			) + 1;
+
+		private int _transactionPointerAddress = 0;
+
+		// The header format is:
+		// (byte) 'd'
+		// (byte) 'b'
+		// (byte) '4'
+		// (byte) 'o'
+		// (byte) headerVersion
+		// (int) headerLock
+		// (long) openTime
+		// (long) accessTime
+		// (int) blockSize
+		// (int) classCollectionID
+		// (byte) idSystemType
+		// (int) variable part address
+		// (int) variable part length
+		// (int) transaction pointer address
+		public override int Length()
+		{
+			return HeaderLength;
+		}
+
+		protected override void Read(LocalObjectContainer container, ByteArrayBuffer reader
+			)
+		{
+			NewTimerFileLock(container);
+			OldEncryptionOff(container);
+			CheckThreadFileLock(container, reader);
+			reader.Seek(BlocksizeOffset);
+			container.BlockSizeReadFromFile(reader.ReadInt());
+			SystemData systemData = container.SystemData();
+			systemData.ClassCollectionID(reader.ReadInt());
+			container.SystemData().IdSystemType(reader.ReadByte());
+			_variablePart = CreateVariablePart(container);
+			int variablePartAddress = reader.ReadInt();
+			int variablePartLength = reader.ReadInt();
+			_variablePart.Read(variablePartAddress, variablePartLength);
+			_transactionPointerAddress = reader.ReadInt();
+			if (_transactionPointerAddress != 0)
+			{
+				ByteArrayBuffer buffer = new ByteArrayBuffer(TransactionPointerLength);
+				buffer.Read(container, _transactionPointerAddress, 0);
+				systemData.TransactionPointer1(buffer.ReadInt());
+				systemData.TransactionPointer2(buffer.ReadInt());
+			}
+		}
+
+		public override void WriteFixedPart(LocalObjectContainer file, bool startFileLockingThread
+			, bool shuttingDown, StatefulBuffer writer, int blockSize)
+		{
+			SystemData systemData = file.SystemData();
+			writer.Append(Signature);
+			writer.WriteByte(Version());
+			writer.WriteInt((int)TimeToWrite(_timerFileLock.OpenTime(), shuttingDown));
+			writer.WriteLong(TimeToWrite(_timerFileLock.OpenTime(), shuttingDown));
+			writer.WriteLong(TimeToWrite(Runtime.CurrentTimeMillis(), shuttingDown));
+			writer.WriteInt(blockSize);
+			writer.WriteInt(systemData.ClassCollectionID());
+			writer.WriteByte(systemData.IdSystemType());
+			writer.WriteInt(((FileHeaderVariablePart2)_variablePart).Address());
+			writer.WriteInt(((FileHeaderVariablePart2)_variablePart).Length());
+			writer.WriteInt(_transactionPointerAddress);
+			writer.Write();
+			if (shuttingDown)
+			{
+				WriteVariablePart(file, true);
+			}
+			else
+			{
+				file.SyncFiles();
+			}
+			if (startFileLockingThread)
+			{
+				file.ThreadPool().Start("db4o lock thread", _timerFileLock);
+			}
+		}
+
+		public override void WriteTransactionPointer(Transaction systemTransaction, int transactionPointer
+			)
+		{
+			if (_transactionPointerAddress == 0)
+			{
+				LocalObjectContainer file = ((LocalTransaction)systemTransaction).LocalContainer(
+					);
+				_transactionPointerAddress = file.AllocateSafeSlot(TransactionPointerLength).Address
+					();
+				file.WriteHeader(false, false);
+			}
+			WriteTransactionPointer(systemTransaction, transactionPointer, _transactionPointerAddress
+				, 0);
+		}
+
+		protected override byte Version()
+		{
+			return (byte)2;
+		}
+
+		protected override NewFileHeaderBase CreateNew()
+		{
+			return new FileHeader2();
+		}
+
+		public override FileHeaderVariablePart CreateVariablePart(LocalObjectContainer file
+			)
+		{
+			return new FileHeaderVariablePart2(file);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeader3.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeader3.cs
new file mode 100644
index 0000000..efa2d07
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeader3.cs
@@ -0,0 +1,32 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Fileheader;
+
+namespace Db4objects.Db4o.Internal.Fileheader
+{
+	/// <exclude></exclude>
+	public class FileHeader3 : FileHeader2
+	{
+		public override FileHeaderVariablePart CreateVariablePart(LocalObjectContainer file
+			)
+		{
+			return new FileHeaderVariablePart3(file);
+		}
+
+		protected override byte Version()
+		{
+			return (byte)3;
+		}
+
+		protected override NewFileHeaderBase CreateNew()
+		{
+			return new FileHeader3();
+		}
+
+		public override FileHeader Convert(LocalObjectContainer file)
+		{
+			return this;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeaderVariablePart.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeaderVariablePart.cs
new file mode 100644
index 0000000..5b3a0ff
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeaderVariablePart.cs
@@ -0,0 +1,65 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Slots;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal.Fileheader
+{
+	/// <exclude></exclude>
+	public abstract class FileHeaderVariablePart
+	{
+		protected readonly LocalObjectContainer _container;
+
+		public abstract IRunnable Commit(bool shuttingDown);
+
+		public abstract void Read(int variablePartAddress, int variablePartLength);
+
+		protected FileHeaderVariablePart(LocalObjectContainer container)
+		{
+			_container = container;
+		}
+
+		public byte GetIdentifier()
+		{
+			return Const4.Header;
+		}
+
+		protected Db4objects.Db4o.Internal.SystemData SystemData()
+		{
+			return _container.SystemData();
+		}
+
+		protected Slot AllocateSlot(int length)
+		{
+			Slot reusedSlot = _container.FreespaceManager().AllocateSafeSlot(length);
+			if (reusedSlot != null)
+			{
+				return reusedSlot;
+			}
+			return _container.AppendBytes(length);
+		}
+
+		public virtual void ReadIdentity(LocalTransaction trans)
+		{
+			LocalObjectContainer file = trans.LocalContainer();
+			Db4oDatabase identity = Debug4.staticIdentity ? Db4oDatabase.StaticIdentity : (Db4oDatabase
+				)file.GetByID(trans, SystemData().IdentityId());
+			if (null != identity)
+			{
+				file.Activate(trans, identity, new FixedActivationDepth(2));
+				SystemData().Identity(identity);
+			}
+		}
+
+		// TODO: What now?
+		// Apparently we get this state after defragment
+		// and defragment then sets the identity.
+		// If we blindly generate a new identity here,
+		// ObjectUpdateFileSizeTestCase reports trouble.
+		public abstract int MarshalledLength();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeaderVariablePart1.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeaderVariablePart1.cs
new file mode 100644
index 0000000..bee4c67
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeaderVariablePart1.cs
@@ -0,0 +1,81 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Fileheader;
+using Db4objects.Db4o.Internal.Slots;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal.Fileheader
+{
+	/// <exclude></exclude>
+	public class FileHeaderVariablePart1 : FileHeaderVariablePart
+	{
+		private const int Length = 1 + (Const4.IntLength * 4) + Const4.LongLength + Const4
+			.AddedLength;
+
+		private int _id;
+
+		public FileHeaderVariablePart1(LocalObjectContainer container, int id) : base(container
+			)
+		{
+			// The variable part format is:
+			// (int) converter version
+			// (byte) freespace system used
+			// (int)  freespace address
+			// (int) identity ID
+			// (long) versionGenerator
+			// (int) uuid index ID
+			_id = id;
+		}
+
+		public FileHeaderVariablePart1(LocalObjectContainer container) : this(container, 
+			0)
+		{
+		}
+
+		public virtual int OwnLength()
+		{
+			return Length;
+		}
+
+		public virtual void ReadThis(ByteArrayBuffer buffer)
+		{
+			SystemData().ConverterVersion(buffer.ReadInt());
+			SystemData().FreespaceSystem(buffer.ReadByte());
+			buffer.ReadInt();
+			// was BTreeFreespaceId, converted to slot, can no longer be used
+			SystemData().IdentityId(buffer.ReadInt());
+			SystemData().LastTimeStampID(buffer.ReadLong());
+			SystemData().UuidIndexId(buffer.ReadInt());
+		}
+
+		public virtual void WriteThis(ByteArrayBuffer buffer)
+		{
+			throw new InvalidOperationException();
+		}
+
+		public override IRunnable Commit(bool shuttingDown)
+		{
+			throw new InvalidOperationException();
+		}
+
+		public virtual int Id()
+		{
+			return _id;
+		}
+
+		public override void Read(int variablePartID, int unused)
+		{
+			_id = variablePartID;
+			Slot slot = _container.ReadPointerSlot(_id);
+			ByteArrayBuffer buffer = _container.ReadBufferBySlot(slot);
+			ReadThis(buffer);
+		}
+
+		public override int MarshalledLength()
+		{
+			return OwnLength();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeaderVariablePart2.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeaderVariablePart2.cs
new file mode 100644
index 0000000..2bc26ce
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeaderVariablePart2.cs
@@ -0,0 +1,283 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Fileheader;
+using Db4objects.Db4o.Internal.Slots;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal.Fileheader
+{
+	/// <exclude></exclude>
+	public class FileHeaderVariablePart2 : FileHeaderVariablePart
+	{
+		private const int ChecksumLength = Const4.LongLength;
+
+		private const int SingleLength = ChecksumLength + (Const4.IntLength * 8) + Const4
+			.LongLength + 1 + Const4.AddedLength;
+
+		private int _address;
+
+		private int _length;
+
+		public FileHeaderVariablePart2(LocalObjectContainer container, int address, int length
+			) : base(container)
+		{
+			// The variable part format is:
+			// (long) checksum
+			// (int) address of InMemoryIdSystem slot
+			// (int) length of InMemoryIdSystem slot
+			// (int) address of InMemoryFreespace
+			// (int) length of InMemoryFreespace
+			// (int) BTreeFreespace id
+			// (int) converter version
+			// (int) uuid index ID
+			// (int) identity ID
+			// (long) versionGenerator
+			// (byte) freespace system used
+			_address = address;
+			_length = length;
+		}
+
+		public FileHeaderVariablePart2(LocalObjectContainer container) : this(container, 
+			0, 0)
+		{
+		}
+
+		public override IRunnable Commit(bool shuttingDown)
+		{
+			int length = OwnLength();
+			if (_address == 0 || _length < length)
+			{
+				Slot slot = AllocateSlot(MarshalledLength(length));
+				_address = slot.Address();
+				_length = length;
+			}
+			ByteArrayBuffer buffer = new ByteArrayBuffer(length);
+			Marshall(buffer, shuttingDown);
+			WriteToFile(0, buffer);
+			return new _IRunnable_65(this, length, buffer);
+		}
+
+		private sealed class _IRunnable_65 : IRunnable
+		{
+			public _IRunnable_65(FileHeaderVariablePart2 _enclosing, int length, ByteArrayBuffer
+				 buffer)
+			{
+				this._enclosing = _enclosing;
+				this.length = length;
+				this.buffer = buffer;
+			}
+
+			public void Run()
+			{
+				this._enclosing.WriteToFile(length * 2, buffer);
+			}
+
+			private readonly FileHeaderVariablePart2 _enclosing;
+
+			private readonly int length;
+
+			private readonly ByteArrayBuffer buffer;
+		}
+
+		private int MarshalledLength(int length)
+		{
+			return length * 4;
+		}
+
+		private void WriteToFile(int startAdress, ByteArrayBuffer buffer)
+		{
+			_container.WriteEncrypt(buffer, _address, startAdress);
+			_container.WriteEncrypt(buffer, _address, startAdress + _length);
+		}
+
+		public virtual int OwnLength()
+		{
+			return SingleLength;
+		}
+
+		public virtual int Address()
+		{
+			return _address;
+		}
+
+		public virtual int Length()
+		{
+			return _length;
+		}
+
+		public override void Read(int address, int length)
+		{
+			_address = address;
+			_length = length;
+			ByteArrayBuffer buffer = _container.ReadBufferBySlot(new Slot(address, MarshalledLength
+				(length)));
+			bool versionsAreConsistent = VersionsAreConsistentAndSeek(buffer);
+			// TODO: Diagnostic message if versions aren't consistent.
+			ReadBuffer(buffer, versionsAreConsistent);
+		}
+
+		protected virtual void ReadBuffer(ByteArrayBuffer buffer, bool versionsAreConsistent
+			)
+		{
+			buffer.IncrementOffset(ChecksumLength);
+			SystemData systemData = SystemData();
+			systemData.IdSystemSlot(ReadSlot(buffer, false));
+			systemData.InMemoryFreespaceSlot(ReadSlot(buffer, !versionsAreConsistent));
+			systemData.BTreeFreespaceId(buffer.ReadInt());
+			systemData.ConverterVersion(buffer.ReadInt());
+			systemData.UuidIndexId(buffer.ReadInt());
+			systemData.IdentityId(buffer.ReadInt());
+			systemData.LastTimeStampID(buffer.ReadLong());
+			systemData.FreespaceSystem(buffer.ReadByte());
+		}
+
+		private Slot ReadSlot(ByteArrayBuffer buffer, bool readZero)
+		{
+			Slot slot = new Slot(buffer.ReadInt(), buffer.ReadInt());
+			if (readZero)
+			{
+				return Slot.Zero;
+			}
+			return slot;
+		}
+
+		private void Marshall(ByteArrayBuffer buffer, bool shuttingDown)
+		{
+			int checkSumOffset = buffer.Offset();
+			buffer.IncrementOffset(ChecksumLength);
+			int checkSumBeginOffset = buffer.Offset();
+			WriteBuffer(buffer, shuttingDown);
+			int checkSumEndOffSet = buffer.Offset();
+			byte[] bytes = buffer._buffer;
+			int length = checkSumEndOffSet - checkSumBeginOffset;
+			long checkSum = CRC32.CheckSum(bytes, checkSumBeginOffset, length);
+			buffer.Seek(checkSumOffset);
+			buffer.WriteLong(checkSum);
+			buffer.Seek(checkSumEndOffSet);
+		}
+
+		protected virtual void WriteBuffer(ByteArrayBuffer buffer, bool shuttingDown)
+		{
+			SystemData systemData = SystemData();
+			WriteSlot(buffer, systemData.IdSystemSlot(), false);
+			WriteSlot(buffer, systemData.InMemoryFreespaceSlot(), !shuttingDown);
+			buffer.WriteInt(systemData.BTreeFreespaceId());
+			buffer.WriteInt(systemData.ConverterVersion());
+			buffer.WriteInt(systemData.UuidIndexId());
+			Db4oDatabase identity = systemData.Identity();
+			buffer.WriteInt(identity == null ? 0 : identity.GetID(_container.SystemTransaction
+				()));
+			buffer.WriteLong(systemData.LastTimeStampID());
+			buffer.WriteByte(systemData.FreespaceSystem());
+		}
+
+		private void WriteSlot(ByteArrayBuffer buffer, Slot slot, bool writeZero)
+		{
+			if (writeZero || slot == null)
+			{
+				buffer.WriteInt(0);
+				buffer.WriteInt(0);
+				return;
+			}
+			buffer.WriteInt(slot.Address());
+			buffer.WriteInt(slot.Length());
+		}
+
+		private bool CheckSumOK(ByteArrayBuffer buffer, int offset)
+		{
+			int initialOffSet = buffer.Offset();
+			int length = OwnLength();
+			length -= ChecksumLength;
+			buffer.Seek(offset);
+			long readCheckSum = buffer.ReadLong();
+			int checkSumBeginOffset = buffer.Offset();
+			byte[] bytes = buffer._buffer;
+			long calculatedCheckSum = CRC32.CheckSum(bytes, checkSumBeginOffset, length);
+			buffer.Seek(initialOffSet);
+			return calculatedCheckSum == readCheckSum;
+		}
+
+		private bool VersionsAreConsistentAndSeek(ByteArrayBuffer buffer)
+		{
+			byte[] bytes = buffer._buffer;
+			int length = OwnLength();
+			int[] offsets = Offsets();
+			bool different = false;
+			for (int i = 0; i < length; i++)
+			{
+				byte b = bytes[offsets[0] + i];
+				for (int j = 1; j < 4; j++)
+				{
+					if (b != bytes[offsets[j] + i])
+					{
+						different = true;
+						break;
+					}
+				}
+			}
+			if (!different)
+			{
+				// The following line cements our checksum algorithm in stone.
+				// Things should be safe enough if we remove the throw.
+				// If all four versions of the header are the same,
+				// it's bound to be OK. (unless all bytes are zero or
+				// greyed out by some kind of overwriting algorithm.)
+				int firstOffset = 0;
+				if (!CheckSumOK(buffer, firstOffset))
+				{
+					throw new Db4oFileHeaderCorruptionException();
+				}
+				return true;
+			}
+			bool firstPairDiffers = false;
+			bool secondPairDiffers = false;
+			for (int i = 0; i < length; i++)
+			{
+				if (bytes[offsets[0] + i] != bytes[offsets[1] + i])
+				{
+					firstPairDiffers = true;
+				}
+				if (bytes[offsets[2] + i] != bytes[offsets[3] + i])
+				{
+					secondPairDiffers = true;
+				}
+			}
+			if (!secondPairDiffers)
+			{
+				if (CheckSumOK(buffer, offsets[2]))
+				{
+					buffer.Seek(offsets[2]);
+					return false;
+				}
+			}
+			if (firstPairDiffers)
+			{
+				// Should never ever happen, we are toast.
+				// We could still try to use any random version of
+				// the header but which one?
+				// Maybe the first of the second pair could be an 
+				// option for a recovery tool, or it could try all
+				// versions.
+				throw new Db4oFileHeaderCorruptionException();
+			}
+			if (!CheckSumOK(buffer, 0))
+			{
+				throw new Db4oFileHeaderCorruptionException();
+			}
+			return false;
+		}
+
+		private int[] Offsets()
+		{
+			return new int[] { 0, OwnLength(), OwnLength() * 2, OwnLength() * 3 };
+		}
+
+		public override int MarshalledLength()
+		{
+			return MarshalledLength(OwnLength());
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeaderVariablePart3.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeaderVariablePart3.cs
new file mode 100644
index 0000000..94f7457
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/FileHeaderVariablePart3.cs
@@ -0,0 +1,37 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Fileheader;
+
+namespace Db4objects.Db4o.Internal.Fileheader
+{
+	/// <exclude></exclude>
+	public class FileHeaderVariablePart3 : FileHeaderVariablePart2
+	{
+		public FileHeaderVariablePart3(LocalObjectContainer container) : base(container)
+		{
+		}
+
+		public override int OwnLength()
+		{
+			return base.OwnLength() + Const4.IntLength * 2;
+		}
+
+		protected override void ReadBuffer(ByteArrayBuffer buffer, bool versionsAreConsistent
+			)
+		{
+			base.ReadBuffer(buffer, versionsAreConsistent);
+			SystemData systemData = SystemData();
+			systemData.IdToTimestampIndexId(buffer.ReadInt());
+			systemData.TimestampToIdIndexId(buffer.ReadInt());
+		}
+
+		protected override void WriteBuffer(ByteArrayBuffer buffer, bool shuttingDown)
+		{
+			base.WriteBuffer(buffer, shuttingDown);
+			SystemData systemData = SystemData();
+			buffer.WriteInt(systemData.IdToTimestampIndexId());
+			buffer.WriteInt(systemData.TimestampToIdIndexId());
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/NewFileHeaderBase.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/NewFileHeaderBase.cs
new file mode 100644
index 0000000..1230373
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/NewFileHeaderBase.cs
@@ -0,0 +1,120 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Fileheader;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal.Fileheader
+{
+	/// <exclude></exclude>
+	public abstract class NewFileHeaderBase : FileHeader
+	{
+		protected static readonly byte[] Signature = new byte[] { (byte)'d', (byte)'b', (
+			byte)'4', (byte)'o' };
+
+		protected static readonly int HeaderLockOffset = Signature.Length + 1;
+
+		protected static readonly int OpenTimeOffset = HeaderLockOffset + Const4.IntLength;
+
+		protected static readonly int AccessTimeOffset = OpenTimeOffset + Const4.LongLength;
+
+		protected TimerFileLock _timerFileLock;
+
+		protected FileHeaderVariablePart _variablePart;
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Close()
+		{
+			if (_timerFileLock == null)
+			{
+				return;
+			}
+			_timerFileLock.Close();
+		}
+
+		protected virtual void NewTimerFileLock(LocalObjectContainer file)
+		{
+			_timerFileLock = TimerFileLock.ForFile(file);
+			_timerFileLock.SetAddresses(0, OpenTimeOffset, AccessTimeOffset);
+		}
+
+		protected abstract NewFileHeaderBase CreateNew();
+
+		protected abstract byte Version();
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public sealed override void InitNew(LocalObjectContainer file)
+		{
+			NewTimerFileLock(file);
+			OldEncryptionOff(file);
+			_variablePart = CreateVariablePart(file);
+			WriteVariablePart(file);
+		}
+
+		public abstract FileHeaderVariablePart CreateVariablePart(LocalObjectContainer file
+			);
+
+		protected virtual void OldEncryptionOff(LocalObjectContainer file)
+		{
+			file._handlers.OldEncryptionOff();
+		}
+
+		public sealed override void WriteVariablePart(LocalObjectContainer file, bool shuttingDown
+			)
+		{
+			if (!IsInitalized())
+			{
+				return;
+			}
+			IRunnable commitHook = Commit(shuttingDown);
+			file.SyncFiles();
+			commitHook.Run();
+			file.SyncFiles();
+		}
+
+		private bool IsInitalized()
+		{
+			return _variablePart != null;
+		}
+
+		protected override FileHeader NewOnSignatureMatch(LocalObjectContainer file, ByteArrayBuffer
+			 reader)
+		{
+			if (SignatureMatches(reader, Signature, Version()))
+			{
+				return CreateNew();
+			}
+			return null;
+		}
+
+		public override void CompleteInterruptedTransaction(LocalObjectContainer container
+			)
+		{
+			SystemData systemData = container.SystemData();
+			container.IdSystem().CompleteInterruptedTransaction(systemData.TransactionPointer1
+				(), systemData.TransactionPointer2());
+		}
+
+		protected virtual void CheckThreadFileLock(LocalObjectContainer container, ByteArrayBuffer
+			 reader)
+		{
+			reader.Seek(AccessTimeOffset);
+			long lastAccessTime = reader.ReadLong();
+			if (FileHeader.LockedByOtherSession(container, lastAccessTime))
+			{
+				_timerFileLock.CheckIfOtherSessionAlive(container, 0, AccessTimeOffset, lastAccessTime
+					);
+			}
+		}
+
+		public override void ReadIdentity(LocalObjectContainer container)
+		{
+			_variablePart.ReadIdentity((LocalTransaction)container.SystemTransaction());
+		}
+
+		public override IRunnable Commit(bool shuttingDown)
+		{
+			return _variablePart.Commit(shuttingDown);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/TimerFileLock.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/TimerFileLock.cs
new file mode 100644
index 0000000..19dcc39
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/TimerFileLock.cs
@@ -0,0 +1,44 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Fileheader;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal.Fileheader
+{
+	/// <exclude></exclude>
+	public abstract class TimerFileLock : IRunnable
+	{
+		public static TimerFileLock ForFile(LocalObjectContainer file)
+		{
+			return new TimerFileLockDisabled();
+		}
+
+		public abstract void CheckHeaderLock();
+
+		public abstract void CheckOpenTime();
+
+		public abstract bool LockFile();
+
+		public abstract long OpenTime();
+
+		public abstract void SetAddresses(int baseAddress, int openTimeOffset, int accessTimeOffset
+			);
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public abstract void Start();
+
+		public abstract void WriteHeaderLock();
+
+		public abstract void WriteOpenTime();
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public abstract void Close();
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public abstract void CheckIfOtherSessionAlive(LocalObjectContainer container, int
+			 address, int offset, long lastAccessTime);
+
+		public abstract void Run();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/TimerFileLockDisabled.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/TimerFileLockDisabled.cs
new file mode 100644
index 0000000..8869084
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Fileheader/TimerFileLockDisabled.cs
@@ -0,0 +1,60 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Fileheader;
+
+namespace Db4objects.Db4o.Internal.Fileheader
+{
+	/// <exclude></exclude>
+	public class TimerFileLockDisabled : TimerFileLock
+	{
+		public override void CheckHeaderLock()
+		{
+		}
+
+		public override void CheckOpenTime()
+		{
+		}
+
+		public override void Close()
+		{
+		}
+
+		public override bool LockFile()
+		{
+			return false;
+		}
+
+		public override long OpenTime()
+		{
+			return 0;
+		}
+
+		public override void Run()
+		{
+		}
+
+		public override void SetAddresses(int baseAddress, int openTimeOffset, int accessTimeOffset
+			)
+		{
+		}
+
+		public override void Start()
+		{
+		}
+
+		public override void WriteHeaderLock()
+		{
+		}
+
+		public override void WriteOpenTime()
+		{
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void CheckIfOtherSessionAlive(LocalObjectContainer container, int
+			 address, int offset, long lastAccessTime)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/AbstractFreespaceManager.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/AbstractFreespaceManager.cs
new file mode 100644
index 0000000..ac87ebc
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/AbstractFreespaceManager.cs
@@ -0,0 +1,267 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Freespace
+{
+	public abstract class AbstractFreespaceManager : IFreespaceManager
+	{
+		public const byte FmDebug = 127;
+
+		public const byte FmDefault = 0;
+
+		public const byte FmLegacyRam = 1;
+
+		public const byte FmRam = 2;
+
+		public const byte FmIx = 3;
+
+		public const byte FmBtree = 4;
+
+		private const int IntsInSlot = 12;
+
+		public const int RemainderSizeLimit = 20;
+
+		public static byte CheckType(byte systemType)
+		{
+			if (systemType == FmDefault)
+			{
+				return FmRam;
+			}
+			return systemType;
+		}
+
+		protected IProcedure4 _slotFreedCallback;
+
+		private readonly int _discardLimit;
+
+		public AbstractFreespaceManager(IProcedure4 slotFreedCallback, int discardLimit)
+		{
+			_slotFreedCallback = slotFreedCallback;
+			_discardLimit = discardLimit;
+		}
+
+		public static Db4objects.Db4o.Internal.Freespace.AbstractFreespaceManager CreateNew
+			(LocalObjectContainer file)
+		{
+			return CreateNew(file, file.SystemData().FreespaceSystem());
+		}
+
+		public static Db4objects.Db4o.Internal.Freespace.AbstractFreespaceManager CreateNew
+			(LocalObjectContainer file, byte systemType)
+		{
+			systemType = CheckType(systemType);
+			int unblockedDiscardLimit = file.ConfigImpl.DiscardFreeSpace();
+			int blockedDiscardLimit = unblockedDiscardLimit == int.MaxValue ? unblockedDiscardLimit
+				 : file.BlockConverter().BytesToBlocks(unblockedDiscardLimit);
+			IProcedure4 slotFreedCallback = new _IProcedure4_50(file);
+			switch (systemType)
+			{
+				case FmIx:
+				{
+					return new FreespaceManagerIx(blockedDiscardLimit);
+				}
+
+				case FmBtree:
+				{
+					return new BTreeFreespaceManager(file, slotFreedCallback, blockedDiscardLimit);
+				}
+
+				default:
+				{
+					return new InMemoryFreespaceManager(slotFreedCallback, blockedDiscardLimit);
+					break;
+				}
+			}
+		}
+
+		private sealed class _IProcedure4_50 : IProcedure4
+		{
+			public _IProcedure4_50(LocalObjectContainer file)
+			{
+				this.file = file;
+			}
+
+			public void Apply(object slot)
+			{
+				file.OverwriteDeletedBlockedSlot(((Slot)slot));
+			}
+
+			private readonly LocalObjectContainer file;
+		}
+
+		public static int InitSlot(LocalObjectContainer file)
+		{
+			int address = file.AllocateSlot(SlotLength()).Address();
+			SlotEntryToZeroes(file, address);
+			return address;
+		}
+
+		public virtual void MigrateTo(IFreespaceManager fm)
+		{
+			Traverse(new _IVisitor4_72(fm));
+		}
+
+		private sealed class _IVisitor4_72 : IVisitor4
+		{
+			public _IVisitor4_72(IFreespaceManager fm)
+			{
+				this.fm = fm;
+			}
+
+			public void Visit(object obj)
+			{
+				fm.Free((Slot)obj);
+			}
+
+			private readonly IFreespaceManager fm;
+		}
+
+		internal static void SlotEntryToZeroes(LocalObjectContainer file, int address)
+		{
+			StatefulBuffer writer = new StatefulBuffer(file.SystemTransaction(), address, SlotLength
+				());
+			for (int i = 0; i < IntsInSlot; i++)
+			{
+				writer.WriteInt(0);
+			}
+			writer.WriteEncrypt();
+		}
+
+		internal static int SlotLength()
+		{
+			return Const4.IntLength * IntsInSlot;
+		}
+
+		public virtual int TotalFreespace()
+		{
+			IntByRef mint = new IntByRef();
+			Traverse(new _IVisitor4_97(mint));
+			return mint.value;
+		}
+
+		private sealed class _IVisitor4_97 : IVisitor4
+		{
+			public _IVisitor4_97(IntByRef mint)
+			{
+				this.mint = mint;
+			}
+
+			public void Visit(object obj)
+			{
+				Slot slot = (Slot)obj;
+				mint.value += slot.Length();
+			}
+
+			private readonly IntByRef mint;
+		}
+
+		protected virtual int DiscardLimit()
+		{
+			return _discardLimit;
+		}
+
+		protected bool SplitRemainder(int length)
+		{
+			if (CanDiscard(length))
+			{
+				return false;
+			}
+			return length > RemainderSizeLimit;
+		}
+
+		internal bool CanDiscard(int length)
+		{
+			return length == 0 || length < DiscardLimit();
+		}
+
+		public static void Migrate(IFreespaceManager oldFM, IFreespaceManager newFM)
+		{
+			oldFM.MigrateTo(newFM);
+			oldFM.FreeSelf();
+		}
+
+		public virtual void DebugCheckIntegrity()
+		{
+			IntByRef lastStart = new IntByRef();
+			IntByRef lastEnd = new IntByRef();
+			Traverse(new _IVisitor4_129(lastEnd, lastStart));
+		}
+
+		private sealed class _IVisitor4_129 : IVisitor4
+		{
+			public _IVisitor4_129(IntByRef lastEnd, IntByRef lastStart)
+			{
+				this.lastEnd = lastEnd;
+				this.lastStart = lastStart;
+			}
+
+			public void Visit(object obj)
+			{
+				Slot slot = (Slot)obj;
+				if (slot.Address() <= lastEnd.value)
+				{
+					throw new InvalidOperationException();
+				}
+				lastStart.value = slot.Address();
+				lastEnd.value = slot.Address() + slot.Length();
+			}
+
+			private readonly IntByRef lastEnd;
+
+			private readonly IntByRef lastStart;
+		}
+
+		public static bool MigrationRequired(byte systemType)
+		{
+			return systemType == FmLegacyRam || systemType == FmIx;
+		}
+
+		public virtual void SlotFreed(Slot slot)
+		{
+			if (_slotFreedCallback == null)
+			{
+				return;
+			}
+			_slotFreedCallback.Apply(slot);
+		}
+
+		public abstract Slot AllocateSafeSlot(int arg1);
+
+		public abstract Slot AllocateSlot(int arg1);
+
+		public abstract Slot AllocateTransactionLogSlot(int arg1);
+
+		public abstract void BeginCommit();
+
+		public abstract void Commit();
+
+		public abstract void EndCommit();
+
+		public abstract void Free(Slot arg1);
+
+		public abstract void FreeSafeSlot(Slot arg1);
+
+		public abstract void FreeSelf();
+
+		public abstract bool IsStarted();
+
+		public abstract void Listener(IFreespaceListener arg1);
+
+		public abstract void Read(LocalObjectContainer arg1, Slot arg2);
+
+		public abstract int SlotCount();
+
+		public abstract void Start(int arg1);
+
+		public abstract byte SystemType();
+
+		public abstract void Traverse(IVisitor4 arg1);
+
+		public abstract void Write(LocalObjectContainer arg1);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/AddressKeySlotHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/AddressKeySlotHandler.cs
new file mode 100644
index 0000000..4cc1783
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/AddressKeySlotHandler.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Freespace
+{
+	/// <exclude></exclude>
+	public class AddressKeySlotHandler : SlotHandler
+	{
+		public virtual int CompareTo(object obj)
+		{
+			return _current.CompareByAddress((Slot)obj);
+		}
+
+		public override IPreparedComparison PrepareComparison(IContext context, object slot
+			)
+		{
+			Slot sourceSlot = (Slot)slot;
+			return new _IPreparedComparison_21(sourceSlot);
+		}
+
+		private sealed class _IPreparedComparison_21 : IPreparedComparison
+		{
+			public _IPreparedComparison_21(Slot sourceSlot)
+			{
+				this.sourceSlot = sourceSlot;
+			}
+
+			public int CompareTo(object obj)
+			{
+				Slot targetSlot = (Slot)obj;
+				// FIXME: The comparison method in #compareByAddress is the wrong way around.
+				// Fix there and here after other references are fixed.
+				return -sourceSlot.CompareByAddress(targetSlot);
+			}
+
+			private readonly Slot sourceSlot;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/BTreeFreespaceManager.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/BTreeFreespaceManager.cs
new file mode 100644
index 0000000..0453f31
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/BTreeFreespaceManager.cs
@@ -0,0 +1,339 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Freespace
+{
+	/// <exclude></exclude>
+	public class BTreeFreespaceManager : AbstractFreespaceManager
+	{
+		private readonly LocalObjectContainer _file;
+
+		private InMemoryFreespaceManager _delegate;
+
+		private BTree _slotsByAddress;
+
+		private BTree _slotsByLength;
+
+		private PersistentIntegerArray _idArray;
+
+		private int _delegationRequests;
+
+		private IFreespaceListener _listener = NullFreespaceListener.Instance;
+
+		private ITransactionalIdSystem _idSystem;
+
+		public BTreeFreespaceManager(LocalObjectContainer file, IProcedure4 slotFreedCallback
+			, int discardLimit) : base(slotFreedCallback, discardLimit)
+		{
+			_file = file;
+			_delegate = new InMemoryFreespaceManager(slotFreedCallback, discardLimit);
+			_idSystem = file.SystemData().FreespaceIdSystem();
+		}
+
+		private void AddSlot(Slot slot)
+		{
+			_slotsByLength.Add(Transaction(), slot);
+			_slotsByAddress.Add(Transaction(), slot);
+			_listener.SlotAdded(slot.Length());
+		}
+
+		public override Slot AllocateSafeSlot(int length)
+		{
+			return _delegate.AllocateSafeSlot(length);
+		}
+
+		public override void BeginCommit()
+		{
+			BeginDelegation();
+		}
+
+		private void BeginDelegation()
+		{
+			_delegationRequests++;
+		}
+
+		public override void Commit()
+		{
+			_slotsByAddress.Commit(Transaction());
+			_slotsByLength.Commit(Transaction());
+		}
+
+		private void CreateBTrees(int addressID, int lengthID)
+		{
+			BTreeConfiguration config = new BTreeConfiguration(_idSystem, SlotChangeFactory.FreeSpace
+				, 64, false);
+			_slotsByAddress = new BTree(Transaction(), config, addressID, new AddressKeySlotHandler
+				());
+			_slotsByLength = new BTree(Transaction(), config, lengthID, new LengthKeySlotHandler
+				());
+		}
+
+		public override void EndCommit()
+		{
+			EndDelegation();
+		}
+
+		private void EndDelegation()
+		{
+			_delegationRequests--;
+		}
+
+		public override void Free(Slot slot)
+		{
+			if (!IsStarted())
+			{
+				return;
+			}
+			if (IsDelegating())
+			{
+				_delegate.Free(slot);
+				return;
+			}
+			try
+			{
+				BeginDelegation();
+				if (DTrace.enabled)
+				{
+					DTrace.FreespacemanagerBtreeFree.LogLength(slot.Address(), slot.Length());
+				}
+				Slot[] remove = new Slot[2];
+				Slot newFreeSlot = slot;
+				BTreePointer pointer = SearchBTree(_slotsByAddress, slot, SearchTarget.Lowest);
+				BTreePointer previousPointer = pointer != null ? pointer.Previous() : _slotsByAddress
+					.LastPointer(Transaction());
+				if (previousPointer != null)
+				{
+					Slot previousSlot = (Slot)previousPointer.Key();
+					if (previousSlot.IsDirectlyPreceding(newFreeSlot))
+					{
+						remove[0] = previousSlot;
+						newFreeSlot = previousSlot.Append(newFreeSlot);
+					}
+				}
+				if (pointer != null)
+				{
+					Slot nextSlot = (Slot)pointer.Key();
+					if (newFreeSlot.IsDirectlyPreceding(nextSlot))
+					{
+						remove[1] = nextSlot;
+						newFreeSlot = newFreeSlot.Append(nextSlot);
+					}
+				}
+				for (int i = 0; i < remove.Length; i++)
+				{
+					if (remove[i] != null)
+					{
+						RemoveSlot(remove[i]);
+					}
+				}
+				if (!CanDiscard(newFreeSlot.Length()))
+				{
+					AddSlot(newFreeSlot);
+				}
+				SlotFreed(slot);
+			}
+			finally
+			{
+				EndDelegation();
+			}
+		}
+
+		public override void FreeSelf()
+		{
+			_slotsByAddress.Free(Transaction());
+			_slotsByLength.Free(Transaction());
+		}
+
+		public override void FreeSafeSlot(Slot slot)
+		{
+			_delegate.FreeSafeSlot(slot);
+		}
+
+		public override Slot AllocateSlot(int length)
+		{
+			if (!IsStarted())
+			{
+				return null;
+			}
+			if (IsDelegating())
+			{
+				return _delegate.AllocateSlot(length);
+			}
+			try
+			{
+				BeginDelegation();
+				BTreePointer pointer = SearchBTree(_slotsByLength, new Slot(0, length), SearchTarget
+					.Highest);
+				if (pointer == null)
+				{
+					return null;
+				}
+				Slot slot = (Slot)pointer.Key();
+				RemoveSlot(slot);
+				int remainingLength = slot.Length() - length;
+				if (SplitRemainder(remainingLength))
+				{
+					AddSlot(slot.SubSlot(length));
+					slot = slot.Truncate(length);
+				}
+				if (DTrace.enabled)
+				{
+					DTrace.FreespacemanagerGetSlot.LogLength(slot.Address(), slot.Length());
+				}
+				return slot;
+			}
+			finally
+			{
+				EndDelegation();
+			}
+		}
+
+		private void InitializeExisting(int id)
+		{
+			_idArray = new PersistentIntegerArray(SlotChangeFactory.FreeSpace, _idSystem, id);
+			_idArray.Read(Transaction());
+			int[] ids = _idArray.Array();
+			int addressId = ids[0];
+			int lengthID = ids[1];
+			CreateBTrees(addressId, lengthID);
+			_slotsByAddress.Read(Transaction());
+			_slotsByLength.Read(Transaction());
+			_delegate.Read(_file, _file.SystemData().InMemoryFreespaceSlot());
+		}
+
+		private void InitializeNew()
+		{
+			CreateBTrees(0, 0);
+			_slotsByAddress.Write(Transaction());
+			_slotsByLength.Write(Transaction());
+			int[] ids = new int[] { _slotsByAddress.GetID(), _slotsByLength.GetID() };
+			_idArray = new PersistentIntegerArray(SlotChangeFactory.FreeSpace, _idSystem, ids
+				);
+			_idArray.Write(Transaction());
+			_file.SystemData().BTreeFreespaceId(_idArray.GetID());
+		}
+
+		private bool IsDelegating()
+		{
+			return _delegationRequests > 0;
+		}
+
+		public virtual void Read(LocalObjectContainer container, int freeSpaceID)
+		{
+		}
+
+		// do nothing
+		// reading happens in start( )
+		private void RemoveSlot(Slot slot)
+		{
+			_slotsByLength.Remove(Transaction(), slot);
+			_slotsByAddress.Remove(Transaction(), slot);
+			_listener.SlotRemoved(slot.Length());
+		}
+
+		private BTreePointer SearchBTree(BTree bTree, Slot slot, SearchTarget target)
+		{
+			BTreeNodeSearchResult searchResult = bTree.SearchLeaf(Transaction(), slot, target
+				);
+			return searchResult.FirstValidPointer();
+		}
+
+		public override int SlotCount()
+		{
+			return _slotsByAddress.Size(Transaction()) + _delegate.SlotCount();
+		}
+
+		public override void Start(int id)
+		{
+			try
+			{
+				BeginDelegation();
+				if (id == 0)
+				{
+					InitializeNew();
+				}
+				else
+				{
+					InitializeExisting(id);
+				}
+			}
+			finally
+			{
+				EndDelegation();
+			}
+		}
+
+		public override bool IsStarted()
+		{
+			return _idArray != null;
+		}
+
+		public override byte SystemType()
+		{
+			return FmBtree;
+		}
+
+		public override string ToString()
+		{
+			return _slotsByLength.ToString();
+		}
+
+		public override int TotalFreespace()
+		{
+			return base.TotalFreespace() + _delegate.TotalFreespace();
+		}
+
+		public override void Traverse(IVisitor4 visitor)
+		{
+			_slotsByAddress.TraverseKeys(Transaction(), visitor);
+		}
+
+		public override void MigrateTo(IFreespaceManager fm)
+		{
+			base.MigrateTo(fm);
+			_delegate.MigrateTo(fm);
+		}
+
+		public override void Write(LocalObjectContainer container)
+		{
+			try
+			{
+				BeginDelegation();
+				_delegate.Write(container);
+				container.SystemData().BTreeFreespaceId(_idArray.GetID());
+			}
+			finally
+			{
+				EndDelegation();
+			}
+		}
+
+		public override void Listener(IFreespaceListener listener)
+		{
+			_listener = listener;
+		}
+
+		private LocalTransaction Transaction()
+		{
+			return (LocalTransaction)_file.SystemTransaction();
+		}
+
+		public override Slot AllocateTransactionLogSlot(int length)
+		{
+			return _delegate.AllocateTransactionLogSlot(length);
+		}
+
+		public override void Read(LocalObjectContainer container, Slot slot)
+		{
+		}
+		// do nothing
+		// everything happens in start
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/BlockAwareFreespaceManager.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/BlockAwareFreespaceManager.cs
new file mode 100644
index 0000000..31830c1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/BlockAwareFreespaceManager.cs
@@ -0,0 +1,159 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Freespace
+{
+	/// <exclude></exclude>
+	public class BlockAwareFreespaceManager : IFreespaceManager
+	{
+		private readonly IFreespaceManager _delegate;
+
+		private readonly IBlockConverter _blockConverter;
+
+		public BlockAwareFreespaceManager(IFreespaceManager delegate_, IBlockConverter blockConverter
+			)
+		{
+			_delegate = delegate_;
+			_blockConverter = blockConverter;
+		}
+
+		public virtual Slot AllocateSlot(int length)
+		{
+			Slot slot = _delegate.AllocateSlot(_blockConverter.BytesToBlocks(length));
+			if (slot == null)
+			{
+				return null;
+			}
+			return _blockConverter.ToNonBlockedLength(slot);
+		}
+
+		public virtual Slot AllocateSafeSlot(int length)
+		{
+			Slot slot = _delegate.AllocateSafeSlot(_blockConverter.BytesToBlocks(length));
+			if (slot == null)
+			{
+				return null;
+			}
+			return _blockConverter.ToNonBlockedLength(slot);
+		}
+
+		public virtual void BeginCommit()
+		{
+			_delegate.BeginCommit();
+		}
+
+		public virtual void Commit()
+		{
+			_delegate.Commit();
+		}
+
+		public virtual void EndCommit()
+		{
+			_delegate.EndCommit();
+		}
+
+		public virtual void Free(Slot slot)
+		{
+			_delegate.Free(_blockConverter.ToBlockedLength(slot));
+		}
+
+		public virtual void FreeSelf()
+		{
+			_delegate.FreeSelf();
+		}
+
+		public virtual void FreeSafeSlot(Slot slot)
+		{
+			_delegate.FreeSafeSlot(_blockConverter.ToBlockedLength(slot));
+		}
+
+		public virtual void Listener(IFreespaceListener listener)
+		{
+			_delegate.Listener(listener);
+		}
+
+		public virtual void MigrateTo(IFreespaceManager fm)
+		{
+			throw new InvalidOperationException();
+		}
+
+		public virtual int SlotCount()
+		{
+			return _delegate.SlotCount();
+		}
+
+		public virtual void Start(int id)
+		{
+			throw new InvalidOperationException();
+		}
+
+		public virtual byte SystemType()
+		{
+			return _delegate.SystemType();
+		}
+
+		public virtual int TotalFreespace()
+		{
+			return _blockConverter.BlocksToBytes(_delegate.TotalFreespace());
+		}
+
+		public virtual void Traverse(IVisitor4 visitor)
+		{
+			_delegate.Traverse(new _IVisitor4_89(this, visitor));
+		}
+
+		private sealed class _IVisitor4_89 : IVisitor4
+		{
+			public _IVisitor4_89(BlockAwareFreespaceManager _enclosing, IVisitor4 visitor)
+			{
+				this._enclosing = _enclosing;
+				this.visitor = visitor;
+			}
+
+			public void Visit(object slot)
+			{
+				visitor.Visit(this._enclosing._blockConverter.ToNonBlockedLength(((Slot)slot)));
+			}
+
+			private readonly BlockAwareFreespaceManager _enclosing;
+
+			private readonly IVisitor4 visitor;
+		}
+
+		public virtual void Write(LocalObjectContainer container)
+		{
+			_delegate.Write(container);
+		}
+
+		public virtual void SlotFreed(Slot slot)
+		{
+			_delegate.SlotFreed(slot);
+		}
+
+		public virtual bool IsStarted()
+		{
+			return _delegate.IsStarted();
+		}
+
+		public virtual Slot AllocateTransactionLogSlot(int length)
+		{
+			Slot slot = _delegate.AllocateTransactionLogSlot(_blockConverter.BytesToBlocks(length
+				));
+			if (slot == null)
+			{
+				return null;
+			}
+			return _blockConverter.ToNonBlockedLength(slot);
+		}
+
+		public virtual void Read(LocalObjectContainer container, Slot slot)
+		{
+			throw new InvalidOperationException();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/FreeSlotNode.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/FreeSlotNode.cs
new file mode 100644
index 0000000..80734a0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/FreeSlotNode.cs
@@ -0,0 +1,149 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Freespace
+{
+	/// <exclude></exclude>
+	public sealed class FreeSlotNode : TreeInt
+	{
+		internal static int sizeLimit;
+
+		internal Db4objects.Db4o.Internal.Freespace.FreeSlotNode _peer;
+
+		internal FreeSlotNode(int a_key) : base(a_key)
+		{
+		}
+
+		public override object ShallowClone()
+		{
+			Db4objects.Db4o.Internal.Freespace.FreeSlotNode frslot = new Db4objects.Db4o.Internal.Freespace.FreeSlotNode
+				(_key);
+			frslot._peer = _peer;
+			return base.ShallowCloneInternal(frslot);
+		}
+
+		internal void CreatePeer(int a_key)
+		{
+			_peer = new Db4objects.Db4o.Internal.Freespace.FreeSlotNode(a_key);
+			_peer._peer = this;
+		}
+
+		public override bool Duplicates()
+		{
+			return true;
+		}
+
+		public sealed override int OwnLength()
+		{
+			return Const4.IntLength * 2;
+		}
+
+		internal static Tree RemoveGreaterOrEqual(Db4objects.Db4o.Internal.Freespace.FreeSlotNode
+			 a_in, TreeIntObject a_finder)
+		{
+			if (a_in == null)
+			{
+				return null;
+			}
+			int cmp = a_in._key - a_finder._key;
+			if (cmp == 0)
+			{
+				a_finder._object = a_in;
+				// the highest node in the hierarchy !!!
+				return a_in.Remove();
+			}
+			if (cmp > 0)
+			{
+				a_in._preceding = RemoveGreaterOrEqual((Db4objects.Db4o.Internal.Freespace.FreeSlotNode
+					)((Tree)a_in._preceding), a_finder);
+				if (a_finder._object != null)
+				{
+					a_in._size--;
+					return a_in;
+				}
+				a_finder._object = a_in;
+				return a_in.Remove();
+			}
+			a_in._subsequent = RemoveGreaterOrEqual((Db4objects.Db4o.Internal.Freespace.FreeSlotNode
+				)((Tree)a_in._subsequent), a_finder);
+			if (a_finder._object != null)
+			{
+				a_in._size--;
+			}
+			return a_in;
+		}
+
+		public override object Read(ByteArrayBuffer buffer)
+		{
+			int size = buffer.ReadInt();
+			int address = buffer.ReadInt();
+			if (size > sizeLimit)
+			{
+				Db4objects.Db4o.Internal.Freespace.FreeSlotNode node = new Db4objects.Db4o.Internal.Freespace.FreeSlotNode
+					(size);
+				node.CreatePeer(address);
+				if (Deploy.debug && Debug4.xbytes)
+				{
+					DebugCheckBuffer(buffer, node);
+				}
+				return node;
+			}
+			return null;
+		}
+
+		private void DebugCheckBuffer(ByteArrayBuffer buffer, Db4objects.Db4o.Internal.Freespace.FreeSlotNode
+			 node)
+		{
+			if (!(buffer is StatefulBuffer))
+			{
+				return;
+			}
+			Transaction trans = ((StatefulBuffer)buffer).Transaction();
+			if (!(trans.Container() is IoAdaptedObjectContainer))
+			{
+				return;
+			}
+			StatefulBuffer checker = trans.Container().CreateStatefulBuffer(trans, node._peer
+				._key, node._key);
+			checker.Read();
+			for (int i = 0; i < node._key; i++)
+			{
+				if (checker.ReadByte() != (byte)'X')
+				{
+					Sharpen.Runtime.Out.WriteLine("!!! Free space corruption at:" + node._peer._key);
+					break;
+				}
+			}
+		}
+
+		public sealed override void Write(ByteArrayBuffer a_writer)
+		{
+			// byte order: size, address
+			a_writer.WriteInt(_key);
+			a_writer.WriteInt(_peer._key);
+		}
+
+		// public static final void debug(FreeSlotNode a_node){
+		// if(a_node == null){
+		// return;
+		// }
+		// System.out.println("Address:" + a_node.i_key);
+		// System.out.println("Length:" + a_node.i_peer.i_key);
+		// debug((FreeSlotNode)a_node.i_preceding);
+		// debug((FreeSlotNode)a_node.i_subsequent);
+		// }
+		public override string ToString()
+		{
+			return base.ToString();
+			string str = "FreeSlotNode " + _key;
+			if (_peer != null)
+			{
+				str += " peer: " + _peer._key;
+			}
+			return str;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/FreespaceManagerIx.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/FreespaceManagerIx.cs
new file mode 100644
index 0000000..75fa080
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/FreespaceManagerIx.cs
@@ -0,0 +1,108 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Freespace
+{
+	/// <summary>Old freespacemanager, before version 7.0.</summary>
+	/// <remarks>
+	/// Old freespacemanager, before version 7.0.
+	/// If it is still in use freespace is dropped.
+	/// <see cref="BTreeFreespaceManager">BTreeFreespaceManager</see>
+	/// should be used instead.
+	/// </remarks>
+	public class FreespaceManagerIx : AbstractFreespaceManager
+	{
+		public FreespaceManagerIx(int discardLimit) : base(null, discardLimit)
+		{
+		}
+
+		public override Slot AllocateSafeSlot(int length)
+		{
+			return null;
+		}
+
+		public override void FreeSafeSlot(Slot slot)
+		{
+		}
+
+		// do nothing
+		public override void BeginCommit()
+		{
+		}
+
+		public override void EndCommit()
+		{
+		}
+
+		public override int SlotCount()
+		{
+			throw new InvalidOperationException();
+		}
+
+		public override void Free(Slot slot)
+		{
+		}
+
+		// Should no longer be used: Should not happen.
+		public override void FreeSelf()
+		{
+		}
+
+		// do nothing, freespace is dropped.
+		public override Slot AllocateSlot(int length)
+		{
+			// implementation is no longer present, no freespace returned.
+			return null;
+		}
+
+		public override void MigrateTo(IFreespaceManager fm)
+		{
+		}
+
+		// do nothing, freespace is dropped.
+		public override void Traverse(IVisitor4 visitor)
+		{
+			throw new InvalidOperationException();
+		}
+
+		public override void Start(int id)
+		{
+		}
+
+		public override byte SystemType()
+		{
+			return FmIx;
+		}
+
+		public override void Write(LocalObjectContainer container)
+		{
+		}
+
+		public override void Commit()
+		{
+		}
+
+		public override void Listener(IFreespaceListener listener)
+		{
+		}
+
+		public override bool IsStarted()
+		{
+			return false;
+		}
+
+		public override Slot AllocateTransactionLogSlot(int length)
+		{
+			return null;
+		}
+
+		public override void Read(LocalObjectContainer container, Slot slot)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/IFreespaceListener.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/IFreespaceListener.cs
new file mode 100644
index 0000000..05ef070
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/IFreespaceListener.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Freespace
+{
+	/// <exclude></exclude>
+	public interface IFreespaceListener
+	{
+		void SlotAdded(int size);
+
+		void SlotRemoved(int size);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/IFreespaceManager.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/IFreespaceManager.cs
new file mode 100644
index 0000000..f1fca60
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/IFreespaceManager.cs
@@ -0,0 +1,53 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Freespace
+{
+	/// <exclude></exclude>
+	public interface IFreespaceManager
+	{
+		void BeginCommit();
+
+		void EndCommit();
+
+		int SlotCount();
+
+		void Free(Slot slot);
+
+		void FreeSelf();
+
+		int TotalFreespace();
+
+		Slot AllocateTransactionLogSlot(int length);
+
+		Slot AllocateSlot(int length);
+
+		void MigrateTo(IFreespaceManager fm);
+
+		void Read(LocalObjectContainer container, Slot slot);
+
+		void Start(int id);
+
+		byte SystemType();
+
+		void Traverse(IVisitor4 visitor);
+
+		void Write(LocalObjectContainer container);
+
+		void Commit();
+
+		Slot AllocateSafeSlot(int length);
+
+		void FreeSafeSlot(Slot slot);
+
+		void Listener(IFreespaceListener listener);
+
+		void SlotFreed(Slot slot);
+
+		bool IsStarted();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/InMemoryFreespaceManager.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/InMemoryFreespaceManager.cs
new file mode 100644
index 0000000..54aa80f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/InMemoryFreespaceManager.cs
@@ -0,0 +1,336 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Text;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Freespace
+{
+	public class InMemoryFreespaceManager : AbstractFreespaceManager
+	{
+		private readonly TreeIntObject _finder = new TreeIntObject(0);
+
+		private Tree _freeByAddress;
+
+		private Tree _freeBySize;
+
+		private IFreespaceListener _listener = NullFreespaceListener.Instance;
+
+		public InMemoryFreespaceManager(IProcedure4 slotFreedCallback, int discardLimit) : 
+			base(slotFreedCallback, discardLimit)
+		{
+		}
+
+		private void AddFreeSlotNodes(int address, int length)
+		{
+			FreeSlotNode addressNode = new FreeSlotNode(address);
+			addressNode.CreatePeer(length);
+			_freeByAddress = Tree.Add(_freeByAddress, addressNode);
+			AddToFreeBySize(addressNode._peer);
+		}
+
+		private void AddToFreeBySize(FreeSlotNode node)
+		{
+			_freeBySize = Tree.Add(_freeBySize, node);
+			_listener.SlotAdded(node._key);
+		}
+
+		public override Slot AllocateTransactionLogSlot(int length)
+		{
+			FreeSlotNode sizeNode = (FreeSlotNode)Tree.Last(_freeBySize);
+			if (sizeNode == null || sizeNode._key < length)
+			{
+				return null;
+			}
+			// We can just be appending to the end of the file, using one
+			// really big contigous slot that keeps growing. Let's limit.
+			int limit = length + 100;
+			if (sizeNode._key > limit)
+			{
+				return AllocateSlot(limit);
+			}
+			RemoveFromBothTrees(sizeNode);
+			return new Slot(sizeNode._peer._key, sizeNode._key);
+		}
+
+		public override Slot AllocateSafeSlot(int length)
+		{
+			return AllocateSlot(length);
+		}
+
+		public override void FreeSafeSlot(Slot slot)
+		{
+			Free(slot);
+		}
+
+		public override void BeginCommit()
+		{
+		}
+
+		// do nothing
+		public override void Commit()
+		{
+		}
+
+		// do nothing
+		public override void EndCommit()
+		{
+		}
+
+		// do nothing
+		public override void Free(Slot slot)
+		{
+			int address = slot.Address();
+			if (address <= 0)
+			{
+				throw new ArgumentException();
+			}
+			int length = slot.Length();
+			if (DTrace.enabled)
+			{
+				DTrace.FreespacemanagerRamFree.LogLength(address, length);
+			}
+			_finder._key = address;
+			FreeSlotNode sizeNode;
+			FreeSlotNode addressnode = (FreeSlotNode)Tree.FindSmaller(_freeByAddress, _finder
+				);
+			if ((addressnode != null) && ((addressnode._key + addressnode._peer._key) == address
+				))
+			{
+				sizeNode = addressnode._peer;
+				RemoveFromFreeBySize(sizeNode);
+				sizeNode._key += length;
+				FreeSlotNode secondAddressNode = (FreeSlotNode)Tree.FindGreaterOrEqual(_freeByAddress
+					, _finder);
+				if ((secondAddressNode != null) && (address + length == secondAddressNode._key))
+				{
+					sizeNode._key += secondAddressNode._peer._key;
+					RemoveFromBothTrees(secondAddressNode._peer);
+				}
+				sizeNode.RemoveChildren();
+				AddToFreeBySize(sizeNode);
+			}
+			else
+			{
+				addressnode = (FreeSlotNode)Tree.FindGreaterOrEqual(_freeByAddress, _finder);
+				if ((addressnode != null) && (address + length == addressnode._key))
+				{
+					sizeNode = addressnode._peer;
+					RemoveFromBothTrees(sizeNode);
+					sizeNode._key += length;
+					addressnode._key = address;
+					addressnode.RemoveChildren();
+					sizeNode.RemoveChildren();
+					_freeByAddress = Tree.Add(_freeByAddress, addressnode);
+					AddToFreeBySize(sizeNode);
+				}
+				else
+				{
+					if (CanDiscard(length))
+					{
+						return;
+					}
+					AddFreeSlotNodes(address, length);
+				}
+			}
+			SlotFreed(slot);
+		}
+
+		public override void FreeSelf()
+		{
+		}
+
+		// Do nothing.
+		// The RAM manager frees itself on reading.
+		public override Slot AllocateSlot(int length)
+		{
+			_finder._key = length;
+			_finder._object = null;
+			_freeBySize = FreeSlotNode.RemoveGreaterOrEqual((FreeSlotNode)_freeBySize, _finder
+				);
+			if (_finder._object == null)
+			{
+				return null;
+			}
+			FreeSlotNode node = (FreeSlotNode)_finder._object;
+			_listener.SlotRemoved(node._key);
+			int blocksFound = node._key;
+			int address = node._peer._key;
+			_freeByAddress = _freeByAddress.RemoveNode(node._peer);
+			int remainingBlocks = blocksFound - length;
+			if (SplitRemainder(remainingBlocks))
+			{
+				AddFreeSlotNodes(address + length, remainingBlocks);
+			}
+			else
+			{
+				length = blocksFound;
+			}
+			if (DTrace.enabled)
+			{
+				DTrace.FreespacemanagerGetSlot.LogLength(address, length);
+			}
+			return new Slot(address, length);
+		}
+
+		internal virtual int MarshalledLength()
+		{
+			return TreeInt.MarshalledLength((TreeInt)_freeBySize);
+		}
+
+		private void Read(ByteArrayBuffer reader)
+		{
+			FreeSlotNode.sizeLimit = DiscardLimit();
+			_freeBySize = new TreeReader(reader, new FreeSlotNode(0), true).Read();
+			ByRef addressTree = ByRef.NewInstance();
+			if (_freeBySize != null)
+			{
+				_freeBySize.Traverse(new _IVisitor4_176(addressTree));
+			}
+			_freeByAddress = ((Tree)addressTree.value);
+		}
+
+		private sealed class _IVisitor4_176 : IVisitor4
+		{
+			public _IVisitor4_176(ByRef addressTree)
+			{
+				this.addressTree = addressTree;
+			}
+
+			public void Visit(object a_object)
+			{
+				FreeSlotNode node = ((FreeSlotNode)a_object)._peer;
+				addressTree.value = Tree.Add(((Tree)addressTree.value), node);
+			}
+
+			private readonly ByRef addressTree;
+		}
+
+		public override void Read(LocalObjectContainer container, Slot slot)
+		{
+			if (Slot.IsNull(slot))
+			{
+				return;
+			}
+			ByteArrayBuffer buffer = container.ReadBufferBySlot(slot);
+			if (buffer == null)
+			{
+				return;
+			}
+			Read(buffer);
+			container.Free(slot);
+		}
+
+		private void RemoveFromBothTrees(FreeSlotNode sizeNode)
+		{
+			RemoveFromFreeBySize(sizeNode);
+			_freeByAddress = _freeByAddress.RemoveNode(sizeNode._peer);
+		}
+
+		private void RemoveFromFreeBySize(FreeSlotNode node)
+		{
+			_freeBySize = _freeBySize.RemoveNode(node);
+			_listener.SlotRemoved(node._key);
+		}
+
+		public override int SlotCount()
+		{
+			return Tree.Size(_freeByAddress);
+		}
+
+		public override void Start(int id)
+		{
+		}
+
+		// this is done in read(), nothing to do here
+		public override byte SystemType()
+		{
+			return FmRam;
+		}
+
+		public override string ToString()
+		{
+			StringBuilder sb = new StringBuilder();
+			sb.Append("RAM FreespaceManager\n");
+			sb.Append("Address Index\n");
+			_freeByAddress.Traverse(new InMemoryFreespaceManager.ToStringVisitor(sb));
+			sb.Append("Length Index\n");
+			_freeBySize.Traverse(new InMemoryFreespaceManager.ToStringVisitor(sb));
+			return sb.ToString();
+		}
+
+		public override void Traverse(IVisitor4 visitor)
+		{
+			if (_freeByAddress == null)
+			{
+				return;
+			}
+			_freeByAddress.Traverse(new _IVisitor4_236(visitor));
+		}
+
+		private sealed class _IVisitor4_236 : IVisitor4
+		{
+			public _IVisitor4_236(IVisitor4 visitor)
+			{
+				this.visitor = visitor;
+			}
+
+			public void Visit(object a_object)
+			{
+				FreeSlotNode fsn = (FreeSlotNode)a_object;
+				int address = fsn._key;
+				int length = fsn._peer._key;
+				visitor.Visit(new Slot(address, length));
+			}
+
+			private readonly IVisitor4 visitor;
+		}
+
+		public override void Write(LocalObjectContainer container)
+		{
+			Slot slot = container.AllocateSlot(MarshalledLength());
+			while (slot.Length() < MarshalledLength())
+			{
+				// This can happen if DatabaseGrowthSize is configured.
+				// Allocating a slot may produce an additional entry
+				// in this FreespaceManager.
+				container.Free(slot);
+				slot = container.AllocateSlot(MarshalledLength());
+			}
+			ByteArrayBuffer buffer = new ByteArrayBuffer(slot.Length());
+			TreeInt.Write(buffer, (TreeInt)_freeBySize);
+			container.WriteEncrypt(buffer, slot.Address(), 0);
+			container.SystemData().InMemoryFreespaceSlot(slot);
+		}
+
+		internal sealed class ToStringVisitor : IVisitor4
+		{
+			private readonly StringBuilder _sb;
+
+			internal ToStringVisitor(StringBuilder sb)
+			{
+				_sb = sb;
+			}
+
+			public void Visit(object obj)
+			{
+				_sb.Append(obj);
+				_sb.Append("\n");
+			}
+		}
+
+		public override void Listener(IFreespaceListener listener)
+		{
+			_listener = listener;
+		}
+
+		public override bool IsStarted()
+		{
+			return true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/LengthKeySlotHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/LengthKeySlotHandler.cs
new file mode 100644
index 0000000..5bcaa38
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/LengthKeySlotHandler.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Freespace
+{
+	/// <exclude></exclude>
+	public class LengthKeySlotHandler : SlotHandler
+	{
+		public virtual int CompareTo(object obj)
+		{
+			return _current.CompareByLength((Slot)obj);
+		}
+
+		public override IPreparedComparison PrepareComparison(IContext context, object slot
+			)
+		{
+			Slot sourceSlot = (Slot)slot;
+			return new _IPreparedComparison_21(sourceSlot);
+		}
+
+		private sealed class _IPreparedComparison_21 : IPreparedComparison
+		{
+			public _IPreparedComparison_21(Slot sourceSlot)
+			{
+				this.sourceSlot = sourceSlot;
+			}
+
+			public int CompareTo(object obj)
+			{
+				Slot targetSlot = (Slot)obj;
+				// FIXME: The comparison method in #compareByLength is the wrong way around.
+				// Fix there and here after other references are fixed.
+				return -sourceSlot.CompareByLength(targetSlot);
+			}
+
+			private readonly Slot sourceSlot;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/NullFreespaceListener.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/NullFreespaceListener.cs
new file mode 100644
index 0000000..d3e73da
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/NullFreespaceListener.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Freespace;
+
+namespace Db4objects.Db4o.Internal.Freespace
+{
+	/// <exclude></exclude>
+	public class NullFreespaceListener : IFreespaceListener
+	{
+		public static readonly IFreespaceListener Instance = new Db4objects.Db4o.Internal.Freespace.NullFreespaceListener
+			();
+
+		private NullFreespaceListener()
+		{
+		}
+
+		public virtual void SlotAdded(int size)
+		{
+		}
+
+		// do nothing;
+		public virtual void SlotRemoved(int size)
+		{
+		}
+		// do nothing
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/NullFreespaceManager.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/NullFreespaceManager.cs
new file mode 100644
index 0000000..e9e03fc
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/NullFreespaceManager.cs
@@ -0,0 +1,107 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Freespace
+{
+	/// <exclude></exclude>
+	public class NullFreespaceManager : IFreespaceManager
+	{
+		public static readonly IFreespaceManager Instance = new Db4objects.Db4o.Internal.Freespace.NullFreespaceManager
+			();
+
+		private NullFreespaceManager()
+		{
+		}
+
+		public virtual Slot AllocateSlot(int length)
+		{
+			return null;
+		}
+
+		public virtual Slot AllocateSafeSlot(int length)
+		{
+			return null;
+		}
+
+		public virtual void BeginCommit()
+		{
+		}
+
+		public virtual void Commit()
+		{
+		}
+
+		public virtual void EndCommit()
+		{
+		}
+
+		public virtual void Free(Slot slot)
+		{
+		}
+
+		public virtual void FreeSelf()
+		{
+		}
+
+		public virtual void FreeSafeSlot(Slot slot)
+		{
+		}
+
+		public virtual void Listener(IFreespaceListener listener)
+		{
+		}
+
+		public virtual void MigrateTo(IFreespaceManager fm)
+		{
+		}
+
+		public virtual int SlotCount()
+		{
+			return 0;
+		}
+
+		public virtual void SlotFreed(Slot slot)
+		{
+		}
+
+		public virtual void Start(int id)
+		{
+		}
+
+		public virtual byte SystemType()
+		{
+			return 0;
+		}
+
+		public virtual int TotalFreespace()
+		{
+			return 0;
+		}
+
+		public virtual void Traverse(IVisitor4 visitor)
+		{
+		}
+
+		public virtual void Write(LocalObjectContainer container)
+		{
+		}
+
+		public virtual bool IsStarted()
+		{
+			return false;
+		}
+
+		public virtual Slot AllocateTransactionLogSlot(int length)
+		{
+			return null;
+		}
+
+		public virtual void Read(LocalObjectContainer container, Slot slot)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/SlotHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/SlotHandler.cs
new file mode 100644
index 0000000..0e8c863
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Freespace/SlotHandler.cs
@@ -0,0 +1,41 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Freespace
+{
+	/// <exclude></exclude>
+	public abstract class SlotHandler : IIndexable4
+	{
+		protected Slot _current;
+
+		public virtual void DefragIndexEntry(DefragmentContextImpl context)
+		{
+			throw new NotImplementedException();
+		}
+
+		public virtual int LinkLength()
+		{
+			return Slot.MarshalledLength;
+		}
+
+		public virtual object ReadIndexEntry(IContext context, ByteArrayBuffer reader)
+		{
+			return new Slot(reader.ReadInt(), reader.ReadInt());
+		}
+
+		public virtual void WriteIndexEntry(IContext context, ByteArrayBuffer writer, object
+			 obj)
+		{
+			Slot slot = (Slot)obj;
+			writer.WriteInt(slot.Address());
+			writer.WriteInt(slot.Length());
+		}
+
+		public abstract IPreparedComparison PrepareComparison(IContext arg1, object arg2);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/FrozenObjectInfo.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/FrozenObjectInfo.cs
new file mode 100644
index 0000000..bdea638
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/FrozenObjectInfo.cs
@@ -0,0 +1,92 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	public class FrozenObjectInfo : IObjectInfo
+	{
+		private readonly Db4oDatabase _sourceDatabase;
+
+		private readonly long _uuidLongPart;
+
+		private readonly long _id;
+
+		private readonly long _commitTimestamp;
+
+		private readonly object _object;
+
+		public FrozenObjectInfo(object @object, long id, Db4oDatabase sourceDatabase, long
+			 uuidLongPart, long commitTimestamp)
+		{
+			_sourceDatabase = sourceDatabase;
+			_uuidLongPart = uuidLongPart;
+			_id = id;
+			_commitTimestamp = commitTimestamp;
+			_object = @object;
+		}
+
+		private FrozenObjectInfo(ObjectReference @ref, VirtualAttributes virtualAttributes
+			) : this(@ref == null ? null : @ref.GetObject(), @ref == null ? -1 : @ref.GetID(
+			), virtualAttributes == null ? null : virtualAttributes.i_database, virtualAttributes
+			 == null ? -1 : virtualAttributes.i_uuid, virtualAttributes == null ? 0 : virtualAttributes
+			.i_version)
+		{
+		}
+
+		public FrozenObjectInfo(Transaction trans, ObjectReference @ref, bool committed) : 
+			this(@ref, IsInstantiatedReference(@ref) ? @ref.VirtualAttributes(trans, committed
+			) : null)
+		{
+		}
+
+		private static bool IsInstantiatedReference(ObjectReference @ref)
+		{
+			return @ref != null && @ref.GetObject() != null;
+		}
+
+		public virtual long GetInternalID()
+		{
+			return _id;
+		}
+
+		public virtual object GetObject()
+		{
+			return _object;
+		}
+
+		public virtual Db4oUUID GetUUID()
+		{
+			if (_sourceDatabase == null)
+			{
+				return null;
+			}
+			return new Db4oUUID(_uuidLongPart, _sourceDatabase.GetSignature());
+		}
+
+		public virtual long GetVersion()
+		{
+			return GetCommitTimestamp();
+		}
+
+		public virtual long GetCommitTimestamp()
+		{
+			return _commitTimestamp;
+		}
+
+		public virtual long SourceDatabaseId(Transaction trans)
+		{
+			if (_sourceDatabase == null)
+			{
+				return -1;
+			}
+			return _sourceDatabase.GetID(trans);
+		}
+
+		public virtual long UuidLongPart()
+		{
+			return _uuidLongPart;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/HandlerRegistry.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/HandlerRegistry.cs
new file mode 100644
index 0000000..5e078a7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/HandlerRegistry.cs
@@ -0,0 +1,640 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Handlers.Array;
+using Db4objects.Db4o.Internal.Handlers.Versions;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Replication;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Generic;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude>
+	/// TODO: This class was written to make ObjectContainerBase
+	/// leaner, so TransportObjectContainer has less members.
+	/// All functionality of this class should become part of
+	/// ObjectContainerBase and the functionality in
+	/// ObjectContainerBase should delegate to independent
+	/// modules without circular references.
+	/// </exclude>
+	public sealed class HandlerRegistry
+	{
+		public const byte HandlerVersion = (byte)10;
+
+		private readonly ObjectContainerBase _container;
+
+		private static readonly IDb4oTypeImpl[] _db4oTypes = new IDb4oTypeImpl[] { new BlobImpl
+			() };
+
+		private ITypeHandler4 _openArrayHandler;
+
+		private ITypeHandler4 _openMultiDimensionalArrayHandler;
+
+		private ITypeHandler4 _openTypeHandler;
+
+		public StringHandler _stringHandler;
+
+		private Hashtable4 _mapIdToTypeInfo = NewHashtable();
+
+		private Hashtable4 _mapReflectorToClassMetadata = NewHashtable();
+
+		private int _highestBuiltinTypeID = Handlers4.AnyArrayNId + 1;
+
+		private readonly VirtualFieldMetadata[] _virtualFields = new VirtualFieldMetadata
+			[3];
+
+		private readonly Hashtable4 _mapReflectorToTypeHandler = NewHashtable();
+
+		private SharedIndexedFields _indexes;
+
+		internal IDb4oReplicationReferenceProvider _replicationReferenceProvider;
+
+		private readonly Db4objects.Db4o.Internal.Diagnostic.DiagnosticProcessor _diagnosticProcessor;
+
+		public bool i_encrypt;
+
+		internal byte[] i_encryptor;
+
+		internal int i_lastEncryptorByte;
+
+		internal readonly GenericReflector _reflector;
+
+		private readonly HandlerVersionRegistry _handlerVersions;
+
+		private LatinStringIO _stringIO;
+
+		public IReflectClass IclassCompare;
+
+		internal IReflectClass IclassDb4otype;
+
+		internal IReflectClass IclassDb4otypeimpl;
+
+		public IReflectClass IclassInternal;
+
+		internal IReflectClass IclassUnversioned;
+
+		public IReflectClass IclassObject;
+
+		internal IReflectClass IclassObjectcontainer;
+
+		public IReflectClass IclassStaticclass;
+
+		public IReflectClass IclassString;
+
+		internal IReflectClass IclassTransientclass;
+
+		private PrimitiveTypeMetadata _untypedArrayMetadata;
+
+		private PrimitiveTypeMetadata _untypedMultiDimensionalMetadata;
+
+		internal HandlerRegistry(ObjectContainerBase container, byte stringEncoding, GenericReflector
+			 reflector)
+		{
+			// this is the master container and not valid
+			// for TransportObjectContainer
+			_handlerVersions = new HandlerVersionRegistry(this);
+			_stringIO = BuiltInStringEncoding.StringIoForEncoding(stringEncoding, container.ConfigImpl
+				.StringEncoding());
+			_container = container;
+			container._handlers = this;
+			_reflector = reflector;
+			_diagnosticProcessor = container.ConfigImpl.DiagnosticProcessor();
+			InitClassReflectors(reflector);
+			_indexes = new SharedIndexedFields();
+			_virtualFields[0] = _indexes._version;
+			_virtualFields[1] = _indexes._uUID;
+			_virtualFields[2] = _indexes._commitTimestamp;
+			RegisterBuiltinHandlers();
+			RegisterPlatformTypes();
+			InitArrayHandlers();
+			Platform4.RegisterPlatformHandlers(container);
+		}
+
+		private void InitArrayHandlers()
+		{
+			ITypeHandler4 elementHandler = OpenTypeHandler();
+			_untypedArrayMetadata = new PrimitiveTypeMetadata(Container(), new ArrayHandler(elementHandler
+				, false), Handlers4.AnyArrayId, IclassObject);
+			_openArrayHandler = _untypedArrayMetadata.TypeHandler();
+			MapTypeInfo(Handlers4.AnyArrayId, _untypedArrayMetadata, null);
+			_untypedMultiDimensionalMetadata = new PrimitiveTypeMetadata(Container(), new MultidimensionalArrayHandler
+				(elementHandler, false), Handlers4.AnyArrayNId, IclassObject);
+			_openMultiDimensionalArrayHandler = _untypedMultiDimensionalMetadata.TypeHandler(
+				);
+			MapTypeInfo(Handlers4.AnyArrayNId, _untypedMultiDimensionalMetadata, null);
+		}
+
+		private void RegisterPlatformTypes()
+		{
+			NetTypeHandler[] handlers = Platform4.Types(_container.Reflector());
+			for (int i = 0; i < handlers.Length; i++)
+			{
+				RegisterNetTypeHandler(handlers[i]);
+			}
+		}
+
+		public void RegisterNetTypeHandler(NetTypeHandler handler)
+		{
+			handler.RegisterReflector(_reflector);
+			IGenericConverter converter = (handler is IGenericConverter) ? (IGenericConverter
+				)handler : null;
+			RegisterBuiltinHandler(handler.GetID(), handler, true, handler.GetName(), converter
+				);
+		}
+
+		private void RegisterBuiltinHandlers()
+		{
+			IntHandler intHandler = new IntHandler();
+			RegisterBuiltinHandler(Handlers4.IntId, intHandler);
+			RegisterHandlerVersion(intHandler, 0, new IntHandler0());
+			LongHandler longHandler = new LongHandler();
+			RegisterBuiltinHandler(Handlers4.LongId, longHandler);
+			RegisterHandlerVersion(longHandler, 0, new LongHandler0());
+			FloatHandler floatHandler = new FloatHandler();
+			RegisterBuiltinHandler(Handlers4.FloatId, floatHandler);
+			RegisterHandlerVersion(floatHandler, 0, new FloatHandler0());
+			BooleanHandler booleanHandler = new BooleanHandler();
+			RegisterBuiltinHandler(Handlers4.BooleanId, booleanHandler);
+			// TODO: Are we missing a boolean handler version?
+			DoubleHandler doubleHandler = new DoubleHandler();
+			RegisterBuiltinHandler(Handlers4.DoubleId, doubleHandler);
+			RegisterHandlerVersion(doubleHandler, 0, new DoubleHandler0());
+			ByteHandler byteHandler = new ByteHandler();
+			RegisterBuiltinHandler(Handlers4.ByteId, byteHandler);
+			// TODO: Are we missing a byte handler version?
+			CharHandler charHandler = new CharHandler();
+			RegisterBuiltinHandler(Handlers4.CharId, charHandler);
+			// TODO: Are we missing a char handler version?
+			ShortHandler shortHandler = new ShortHandler();
+			RegisterBuiltinHandler(Handlers4.ShortId, shortHandler);
+			RegisterHandlerVersion(shortHandler, 0, new ShortHandler0());
+			_stringHandler = new StringHandler();
+			RegisterBuiltinHandler(Handlers4.StringId, _stringHandler);
+			RegisterHandlerVersion(_stringHandler, 0, new StringHandler0());
+			DateHandler dateHandler = new DateHandler();
+			RegisterBuiltinHandler(Handlers4.DateId, dateHandler);
+			RegisterHandlerVersion(dateHandler, 0, new DateHandler0());
+			RegisterUntypedHandlers();
+			RegisterCompositeHandlerVersions();
+		}
+
+		private void RegisterUntypedHandlers()
+		{
+			_openTypeHandler = new Db4objects.Db4o.Internal.OpenTypeHandler(Container());
+			PrimitiveTypeMetadata classMetadata = new ObjectTypeMetadata(Container(), _openTypeHandler
+				, Handlers4.UntypedId, IclassObject);
+			Map(Handlers4.UntypedId, classMetadata, IclassObject);
+			RegisterHandlerVersion(_openTypeHandler, 0, new OpenTypeHandler0(Container()));
+			RegisterHandlerVersion(_openTypeHandler, 2, new OpenTypeHandler2(Container()));
+			RegisterHandlerVersion(_openTypeHandler, 7, new OpenTypeHandler7(Container()));
+		}
+
+		private void RegisterCompositeHandlerVersions()
+		{
+			RegisterHandlerVersion(new StandardReferenceTypeHandler(), 0, new StandardReferenceTypeHandler0
+				());
+			ArrayHandler arrayHandler = new ArrayHandler();
+			RegisterHandlerVersion(arrayHandler, 0, new ArrayHandler0());
+			RegisterHandlerVersion(arrayHandler, 1, new ArrayHandler1());
+			RegisterHandlerVersion(arrayHandler, 3, new ArrayHandler3());
+			RegisterHandlerVersion(arrayHandler, 5, new ArrayHandler5());
+			MultidimensionalArrayHandler multidimensionalArrayHandler = new MultidimensionalArrayHandler
+				();
+			RegisterHandlerVersion(multidimensionalArrayHandler, 0, new MultidimensionalArrayHandler0
+				());
+			RegisterHandlerVersion(multidimensionalArrayHandler, 3, new MultidimensionalArrayHandler3
+				());
+		}
+
+		private void RegisterBuiltinHandler(int id, IBuiltinTypeHandler handler)
+		{
+			RegisterBuiltinHandler(id, handler, true, null, null);
+		}
+
+		private void RegisterBuiltinHandler(int id, IBuiltinTypeHandler typeHandler, bool
+			 registerPrimitiveClass, string primitiveName, IGenericConverter converter)
+		{
+			typeHandler.RegisterReflector(_reflector);
+			if (primitiveName == null)
+			{
+				primitiveName = typeHandler.ClassReflector().GetName();
+			}
+			if (registerPrimitiveClass)
+			{
+				_reflector.RegisterPrimitiveClass(id, primitiveName, converter);
+			}
+			IReflectClass classReflector = typeHandler.ClassReflector();
+			PrimitiveTypeMetadata classMetadata = new PrimitiveTypeMetadata(Container(), typeHandler
+				, id, classReflector);
+			Map(id, classMetadata, classReflector);
+			if (typeHandler is PrimitiveHandler)
+			{
+				IReflectClass primitiveClassReflector = ((PrimitiveHandler)typeHandler).PrimitiveClassReflector
+					();
+				if (primitiveClassReflector != null)
+				{
+					MapPrimitive(0, classMetadata, primitiveClassReflector);
+				}
+			}
+		}
+
+		private void Map(int id, PrimitiveTypeMetadata classMetadata, IReflectClass classReflector
+			)
+		{
+			// TODO: remove when _mapIdToClassMetadata is gone 
+			MapTypeInfo(id, classMetadata, classReflector);
+			MapPrimitive(id, classMetadata, classReflector);
+			if (id > _highestBuiltinTypeID)
+			{
+				_highestBuiltinTypeID = id;
+			}
+		}
+
+		private void MapTypeInfo(int id, ClassMetadata classMetadata, IReflectClass classReflector
+			)
+		{
+			_mapIdToTypeInfo.Put(id, new HandlerRegistry.TypeInfo(classMetadata, classReflector
+				));
+		}
+
+		private void MapPrimitive(int id, ClassMetadata classMetadata, IReflectClass classReflector
+			)
+		{
+			MapClassToTypeHandler(classReflector, classMetadata.TypeHandler());
+			if (classReflector != null)
+			{
+				_mapReflectorToClassMetadata.Put(classReflector, classMetadata);
+			}
+		}
+
+		private void MapClassToTypeHandler(IReflectClass classReflector, ITypeHandler4 typeHandler
+			)
+		{
+			_mapReflectorToTypeHandler.Put(classReflector, typeHandler);
+		}
+
+		public void RegisterHandlerVersion(ITypeHandler4 handler, int version, ITypeHandler4
+			 replacement)
+		{
+			if (replacement is IBuiltinTypeHandler)
+			{
+				((IBuiltinTypeHandler)replacement).RegisterReflector(_reflector);
+			}
+			_handlerVersions.Put(handler, version, replacement);
+		}
+
+		public ITypeHandler4 CorrectHandlerVersion(ITypeHandler4 handler, int version)
+		{
+			return _handlerVersions.CorrectHandlerVersion(handler, version);
+		}
+
+		public static ITypeHandler4 CorrectHandlerVersion(IHandlerVersionContext context, 
+			ITypeHandler4 typeHandler, ClassMetadata classMetadata)
+		{
+			ITypeHandler4 correctHandlerVersion = CorrectHandlerVersion(context, typeHandler);
+			if (typeHandler != correctHandlerVersion)
+			{
+				CorrectClassMetadataOn(correctHandlerVersion, classMetadata);
+				if (correctHandlerVersion is ArrayHandler)
+				{
+					ArrayHandler arrayHandler = (ArrayHandler)correctHandlerVersion;
+					CorrectClassMetadataOn(arrayHandler.DelegateTypeHandler(), classMetadata);
+				}
+			}
+			return correctHandlerVersion;
+		}
+
+		private static void CorrectClassMetadataOn(ITypeHandler4 typeHandler, ClassMetadata
+			 classMetadata)
+		{
+			if (typeHandler is StandardReferenceTypeHandler)
+			{
+				StandardReferenceTypeHandler handler = (StandardReferenceTypeHandler)typeHandler;
+				handler.ClassMetadata(classMetadata);
+			}
+		}
+
+		internal Db4objects.Db4o.Internal.ArrayType ArrayType(object obj)
+		{
+			IReflectClass claxx = Reflector().ForObject(obj);
+			if (!claxx.IsArray())
+			{
+				return Db4objects.Db4o.Internal.ArrayType.None;
+			}
+			if (IsNDimensional(claxx))
+			{
+				return Db4objects.Db4o.Internal.ArrayType.MultidimensionalArray;
+			}
+			return Db4objects.Db4o.Internal.ArrayType.PlainArray;
+		}
+
+		public void Decrypt(ByteArrayBuffer reader)
+		{
+			if (i_encrypt)
+			{
+				int encryptorOffSet = i_lastEncryptorByte;
+				byte[] bytes = reader._buffer;
+				for (int i = reader.Length() - 1; i >= 0; i--)
+				{
+					bytes[i] += i_encryptor[encryptorOffSet];
+					if (encryptorOffSet == 0)
+					{
+						encryptorOffSet = i_lastEncryptorByte;
+					}
+					else
+					{
+						encryptorOffSet--;
+					}
+				}
+			}
+		}
+
+		public void Encrypt(ByteArrayBuffer reader)
+		{
+			if (i_encrypt)
+			{
+				byte[] bytes = reader._buffer;
+				int encryptorOffSet = i_lastEncryptorByte;
+				for (int i = reader.Length() - 1; i >= 0; i--)
+				{
+					bytes[i] -= i_encryptor[encryptorOffSet];
+					if (encryptorOffSet == 0)
+					{
+						encryptorOffSet = i_lastEncryptorByte;
+					}
+					else
+					{
+						encryptorOffSet--;
+					}
+				}
+			}
+		}
+
+		public void OldEncryptionOff()
+		{
+			i_encrypt = false;
+			i_encryptor = null;
+			i_lastEncryptorByte = 0;
+			Container().ConfigImpl.OldEncryptionOff();
+		}
+
+		public IReflectClass ClassForID(int id)
+		{
+			HandlerRegistry.TypeInfo typeInfo = TypeInfoForID(id);
+			if (typeInfo == null)
+			{
+				return null;
+			}
+			return typeInfo.classReflector;
+		}
+
+		private HandlerRegistry.TypeInfo TypeInfoForID(int id)
+		{
+			return (HandlerRegistry.TypeInfo)_mapIdToTypeInfo.Get(id);
+		}
+
+		private void InitClassReflectors(GenericReflector reflector)
+		{
+			IclassCompare = reflector.ForClass(Const4.ClassCompare);
+			IclassDb4otype = reflector.ForClass(Const4.ClassDb4otype);
+			IclassDb4otypeimpl = reflector.ForClass(Const4.ClassDb4otypeimpl);
+			IclassInternal = reflector.ForClass(Const4.ClassInternal);
+			IclassUnversioned = reflector.ForClass(Const4.ClassUnversioned);
+			IclassObject = reflector.ForClass(Const4.ClassObject);
+			IclassObjectcontainer = reflector.ForClass(Const4.ClassObjectcontainer);
+			IclassStaticclass = reflector.ForClass(Const4.ClassStaticclass);
+			IclassString = reflector.ForClass(typeof(string));
+			IclassTransientclass = reflector.ForClass(Const4.ClassTransientclass);
+			Platform4.RegisterCollections(reflector);
+		}
+
+		internal void InitEncryption(Config4Impl a_config)
+		{
+			if (a_config.Encrypt() && a_config.Password() != null && a_config.Password().Length
+				 > 0)
+			{
+				i_encrypt = true;
+				i_encryptor = new byte[a_config.Password().Length];
+				for (int i = 0; i < i_encryptor.Length; i++)
+				{
+					i_encryptor[i] = (byte)(a_config.Password()[i] & unchecked((int)(0xff)));
+				}
+				i_lastEncryptorByte = a_config.Password().Length - 1;
+				return;
+			}
+			OldEncryptionOff();
+		}
+
+		internal static IDb4oTypeImpl GetDb4oType(IReflectClass clazz)
+		{
+			for (int i = 0; i < _db4oTypes.Length; i++)
+			{
+				if (clazz.IsInstance(_db4oTypes[i]))
+				{
+					return _db4oTypes[i];
+				}
+			}
+			return null;
+		}
+
+		public ClassMetadata ClassMetadataForId(int id)
+		{
+			HandlerRegistry.TypeInfo typeInfo = TypeInfoForID(id);
+			if (typeInfo == null)
+			{
+				return null;
+			}
+			return typeInfo.classMetadata;
+		}
+
+		internal ClassMetadata ClassMetadataForClass(IReflectClass clazz)
+		{
+			if (clazz == null)
+			{
+				return null;
+			}
+			if (clazz.IsArray())
+			{
+				return IsNDimensional(clazz) ? _untypedMultiDimensionalMetadata : _untypedArrayMetadata;
+			}
+			return (ClassMetadata)_mapReflectorToClassMetadata.Get(clazz);
+		}
+
+		public ITypeHandler4 OpenTypeHandler()
+		{
+			return _openTypeHandler;
+		}
+
+		public ITypeHandler4 OpenArrayHandler(IReflectClass clazz)
+		{
+			if (clazz.IsArray())
+			{
+				if (IsNDimensional(clazz))
+				{
+					return _openMultiDimensionalArrayHandler;
+				}
+				return _openArrayHandler;
+			}
+			return null;
+		}
+
+		private bool IsNDimensional(IReflectClass clazz)
+		{
+			return Reflector().Array().IsNDimensional(clazz);
+		}
+
+		public ITypeHandler4 TypeHandlerForClass(IReflectClass clazz)
+		{
+			if (clazz == null)
+			{
+				return null;
+			}
+			if (clazz.IsArray())
+			{
+				if (IsNDimensional(clazz))
+				{
+					return _openMultiDimensionalArrayHandler;
+				}
+				return _openArrayHandler;
+			}
+			ITypeHandler4 cachedTypeHandler = (ITypeHandler4)_mapReflectorToTypeHandler.Get(clazz
+				);
+			if (cachedTypeHandler != null)
+			{
+				return cachedTypeHandler;
+			}
+			ITypeHandler4 configuredTypeHandler = ConfiguredTypeHandler(clazz);
+			if (Handlers4.IsValueType(configuredTypeHandler))
+			{
+				return configuredTypeHandler;
+			}
+			return null;
+		}
+
+		public bool IsSystemHandler(int id)
+		{
+			return id > 0 && id <= _highestBuiltinTypeID;
+		}
+
+		public int LowestValidId()
+		{
+			return _highestBuiltinTypeID + 1;
+		}
+
+		public VirtualFieldMetadata VirtualFieldByName(string name)
+		{
+			for (int i = 0; i < _virtualFields.Length; i++)
+			{
+				if (name.Equals(_virtualFields[i].GetName()))
+				{
+					return _virtualFields[i];
+				}
+			}
+			return null;
+		}
+
+		public SharedIndexedFields Indexes()
+		{
+			return _indexes;
+		}
+
+		public LatinStringIO StringIO()
+		{
+			return _stringIO;
+		}
+
+		public void StringIO(LatinStringIO io)
+		{
+			_stringIO = io;
+		}
+
+		private GenericReflector Reflector()
+		{
+			return Container().Reflector();
+		}
+
+		private ObjectContainerBase Container()
+		{
+			return _container;
+		}
+
+		private static Hashtable4 NewHashtable()
+		{
+			return new Hashtable4(32);
+		}
+
+		public ITypeHandler4 ConfiguredTypeHandler(IReflectClass claxx)
+		{
+			object cachedHandler = _mapReflectorToTypeHandler.Get(claxx);
+			if (null != cachedHandler)
+			{
+				return (ITypeHandler4)cachedHandler;
+			}
+			ITypeHandler4 typeHandler = Container().ConfigImpl.TypeHandlerForClass(claxx, HandlerVersion
+				);
+			if (typeHandler is IBuiltinTypeHandler)
+			{
+				((IBuiltinTypeHandler)typeHandler).RegisterReflector(Reflector());
+			}
+			if (Handlers4.IsValueType(typeHandler))
+			{
+				MapClassToTypeHandler(claxx, typeHandler);
+			}
+			return typeHandler;
+		}
+
+		public static ITypeHandler4 CorrectHandlerVersion(IHandlerVersionContext context, 
+			ITypeHandler4 handler)
+		{
+			int version = context.HandlerVersion();
+			if (version >= HandlerVersion)
+			{
+				return handler;
+			}
+			return context.Transaction().Container().Handlers.CorrectHandlerVersion(handler, 
+				version);
+		}
+
+		public bool IsTransient(IReflectClass claxx)
+		{
+			return IclassTransientclass.IsAssignableFrom(claxx) || Platform4.IsTransient(claxx
+				);
+		}
+
+		public void TreatAsOpenType(Type clazz)
+		{
+			MapClassToTypeHandler(ReflectClassFor(clazz), OpenTypeHandler());
+		}
+
+		private IReflectClass ReflectClassFor(Type clazz)
+		{
+			return Container().Reflector().ForClass(clazz);
+		}
+
+		public Db4objects.Db4o.Internal.Diagnostic.DiagnosticProcessor DiagnosticProcessor
+			()
+		{
+			return _diagnosticProcessor;
+		}
+
+		private class TypeInfo
+		{
+			public ClassMetadata classMetadata;
+
+			public IReflectClass classReflector;
+
+			public TypeInfo(ClassMetadata classMetadata_, IReflectClass classReflector_)
+			{
+				// TODO: remove when no longer needed in HandlerRegistry
+				classMetadata = classMetadata_;
+				classReflector = classReflector_;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/HandlerVersionRegistry.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/HandlerVersionRegistry.cs
new file mode 100644
index 0000000..095171d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/HandlerVersionRegistry.cs
@@ -0,0 +1,92 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class HandlerVersionRegistry
+	{
+		private readonly HandlerRegistry _registry;
+
+		private readonly Hashtable4 _versions = new Hashtable4();
+
+		public HandlerVersionRegistry(HandlerRegistry registry)
+		{
+			_registry = registry;
+		}
+
+		public virtual void Put(ITypeHandler4 handler, int version, ITypeHandler4 replacement
+			)
+		{
+			_versions.Put(new HandlerVersionRegistry.HandlerVersionKey(this, handler, version
+				), replacement);
+		}
+
+		public virtual ITypeHandler4 CorrectHandlerVersion(ITypeHandler4 originalHandler, 
+			int version)
+		{
+			if (version >= HandlerRegistry.HandlerVersion)
+			{
+				return originalHandler;
+			}
+			if (originalHandler == null)
+			{
+				return null;
+			}
+			// HandlerVersionKey with null key will throw NPE.
+			ITypeHandler4 replacement = (ITypeHandler4)_versions.Get(new HandlerVersionRegistry.HandlerVersionKey
+				(this, GenericTemplate(originalHandler), version));
+			if (replacement == null)
+			{
+				return CorrectHandlerVersion(originalHandler, version + 1);
+			}
+			if (replacement is IVersionedTypeHandler)
+			{
+				return (ITypeHandler4)((IVersionedTypeHandler)replacement).DeepClone(new TypeHandlerCloneContext
+					(_registry, originalHandler, version));
+			}
+			return replacement;
+		}
+
+		private ITypeHandler4 GenericTemplate(ITypeHandler4 handler)
+		{
+			if (handler is IVersionedTypeHandler)
+			{
+				return ((IVersionedTypeHandler)handler).UnversionedTemplate();
+			}
+			return handler;
+		}
+
+		private class HandlerVersionKey
+		{
+			private readonly ITypeHandler4 _handler;
+
+			private readonly int _version;
+
+			public HandlerVersionKey(HandlerVersionRegistry _enclosing, ITypeHandler4 handler
+				, int version)
+			{
+				this._enclosing = _enclosing;
+				this._handler = handler;
+				this._version = version;
+			}
+
+			public override int GetHashCode()
+			{
+				return this._handler.GetHashCode() + this._version * 4271;
+			}
+
+			public override bool Equals(object obj)
+			{
+				HandlerVersionRegistry.HandlerVersionKey other = (HandlerVersionRegistry.HandlerVersionKey
+					)obj;
+				return this._handler.Equals(other._handler) && this._version == other._version;
+			}
+
+			private readonly HandlerVersionRegistry _enclosing;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayHandler.cs
new file mode 100644
index 0000000..c8770a7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayHandler.cs
@@ -0,0 +1,689 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Handlers.Array;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal.Handlers.Array
+{
+	/// <summary>This is the latest version, the one that should be used.</summary>
+	/// <remarks>This is the latest version, the one that should be used.</remarks>
+	/// <exclude></exclude>
+	public class ArrayHandler : ICascadingTypeHandler, IComparable4, IValueTypeHandler
+		, IVariableLengthTypeHandler, IVersionedTypeHandler, IQueryableTypeHandler
+	{
+		private ITypeHandler4 _handler;
+
+		private bool _usePrimitiveClassReflector;
+
+		protected readonly ArrayVersionHelper _versionHelper;
+
+		public ArrayHandler()
+		{
+			_versionHelper = CreateVersionHelper();
+		}
+
+		public ArrayHandler(ITypeHandler4 handler, bool usePrimitiveClassReflector) : this
+			()
+		{
+			_handler = handler;
+			_usePrimitiveClassReflector = usePrimitiveClassReflector;
+		}
+
+		protected virtual ArrayVersionHelper CreateVersionHelper()
+		{
+			return new ArrayVersionHelper();
+		}
+
+		protected virtual IReflectArray ArrayReflector(ObjectContainerBase container)
+		{
+			return container.Reflector().Array();
+		}
+
+		public virtual IEnumerator AllElements(ObjectContainerBase container, object a_object
+			)
+		{
+			return AllElements(ArrayReflector(container), a_object);
+		}
+
+		public static IEnumerator AllElements(IReflectArray reflectArray, object array)
+		{
+			return new ReflectArrayIterator(reflectArray, array);
+		}
+
+		public void CascadeActivation(IActivationContext context)
+		{
+			if (!Handlers4.IsCascading(_handler))
+			{
+				return;
+			}
+			ObjectContainerBase container = context.Container();
+			IEnumerator all = AllElements(container, context.TargetObject());
+			while (all.MoveNext())
+			{
+				context.CascadeActivationToChild(all.Current);
+			}
+		}
+
+		internal virtual ObjectContainerBase Container(Transaction trans)
+		{
+			return trans.Container();
+		}
+
+		public virtual void CollectIDs(QueryingReadContext context)
+		{
+			ITypeHandler4 handler = HandlerRegistry.CorrectHandlerVersion(context, _handler);
+			ForEachElement(context, new _IRunnable_71(context, handler));
+		}
+
+		private sealed class _IRunnable_71 : IRunnable
+		{
+			public _IRunnable_71(QueryingReadContext context, ITypeHandler4 handler)
+			{
+				this.context = context;
+				this.handler = handler;
+			}
+
+			public void Run()
+			{
+				context.ReadId(handler);
+			}
+
+			private readonly QueryingReadContext context;
+
+			private readonly ITypeHandler4 handler;
+		}
+
+		protected virtual ArrayInfo ForEachElement(AbstractBufferContext context, IRunnable
+			 elementRunnable)
+		{
+			ArrayInfo info = NewArrayInfo();
+			WithContent(context, new _IRunnable_80(this, context, info, elementRunnable));
+			return info;
+		}
+
+		private sealed class _IRunnable_80 : IRunnable
+		{
+			public _IRunnable_80(ArrayHandler _enclosing, AbstractBufferContext context, ArrayInfo
+				 info, IRunnable elementRunnable)
+			{
+				this._enclosing = _enclosing;
+				this.context = context;
+				this.info = info;
+				this.elementRunnable = elementRunnable;
+			}
+
+			public void Run()
+			{
+				if (context.Buffer() == null)
+				{
+					return;
+				}
+				if (this._enclosing.IsUntypedByteArray(context))
+				{
+					return;
+				}
+				this._enclosing.ReadInfo(context.Transaction(), context, info);
+				int elementCount = info.ElementCount();
+				elementCount -= this._enclosing.ReducedCountForNullBitMap(info, context);
+				for (int i = 0; i < elementCount; i++)
+				{
+					elementRunnable.Run();
+				}
+			}
+
+			private readonly ArrayHandler _enclosing;
+
+			private readonly AbstractBufferContext context;
+
+			private readonly ArrayInfo info;
+
+			private readonly IRunnable elementRunnable;
+		}
+
+		protected virtual void WithContent(AbstractBufferContext context, IRunnable runnable
+			)
+		{
+			runnable.Run();
+		}
+
+		private int ReducedCountForNullBitMap(ArrayInfo info, IReadBuffer context)
+		{
+			if (!HasNullBitmap(info))
+			{
+				return 0;
+			}
+			return ReducedCountForNullBitMap(info.ElementCount(), ReadNullBitmap(context, info
+				.ElementCount()));
+		}
+
+		private int ReducedCountForNullBitMap(int count, BitMap4 bitMap)
+		{
+			int nullCount = 0;
+			for (int i = 0; i < count; i++)
+			{
+				if (bitMap.IsTrue(i))
+				{
+					nullCount++;
+				}
+			}
+			return nullCount;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Delete(IDeleteContext context)
+		{
+			if (!CascadeDelete(context))
+			{
+				return;
+			}
+			ForEachElement((AbstractBufferContext)context, new _IRunnable_127(this, context));
+		}
+
+		private sealed class _IRunnable_127 : IRunnable
+		{
+			public _IRunnable_127(ArrayHandler _enclosing, IDeleteContext context)
+			{
+				this._enclosing = _enclosing;
+				this.context = context;
+			}
+
+			public void Run()
+			{
+				this._enclosing._handler.Delete(context);
+			}
+
+			private readonly ArrayHandler _enclosing;
+
+			private readonly IDeleteContext context;
+		}
+
+		private bool CascadeDelete(IDeleteContext context)
+		{
+			// FIXME: ValueType could reference objects, shouldn't they be deleted too?
+			return context.CascadeDelete() && Handlers4.IsCascading(_handler);
+		}
+
+		// FIXME: This code has not been called in any test case when the 
+		//        new ArrayMarshaller was written.
+		//        Apparently it only frees slots.
+		//        For now the code simply returns without freeing.
+		/// <param name="classPrimitive"></param>
+		public void DeletePrimitiveEmbedded(StatefulBuffer buffer, PrimitiveTypeMetadata 
+			classPrimitive)
+		{
+			buffer.ReadInt();
+			//int address = a_bytes.readInt();
+			buffer.ReadInt();
+		}
+
+		//int length = a_bytes.readInt();
+		public override bool Equals(object obj)
+		{
+			if (!(obj is Db4objects.Db4o.Internal.Handlers.Array.ArrayHandler))
+			{
+				return false;
+			}
+			Db4objects.Db4o.Internal.Handlers.Array.ArrayHandler other = (Db4objects.Db4o.Internal.Handlers.Array.ArrayHandler
+				)obj;
+			if (other.Identifier() != Identifier())
+			{
+				return false;
+			}
+			if (_handler == null)
+			{
+				return other._handler == null;
+			}
+			return _handler.Equals(other._handler) && _usePrimitiveClassReflector == other._usePrimitiveClassReflector;
+		}
+
+		public override int GetHashCode()
+		{
+			if (_handler == null)
+			{
+				return HashcodeForNull;
+			}
+			int hc = _handler.GetHashCode() >> 7;
+			return _usePrimitiveClassReflector ? hc : -hc;
+		}
+
+		protected virtual bool HandleAsByteArray(object obj)
+		{
+			return obj.GetType() == typeof(byte[]);
+			return obj is byte[];
+		}
+
+		public virtual byte Identifier()
+		{
+			return Const4.Yaparray;
+		}
+
+		public virtual IReflectClass PrimitiveClassReflector(IReflector reflector)
+		{
+			return Handlers4.PrimitiveClassReflector(_handler, reflector);
+		}
+
+		protected virtual object ReadCreate(Transaction trans, IReadBuffer buffer, ArrayInfo
+			 info)
+		{
+			ReadInfo(trans, buffer, info);
+			IReflectClass clazz = NewInstanceReflectClass(trans.Reflector(), info);
+			if (clazz == null)
+			{
+				return null;
+			}
+			return NewInstance(ArrayReflector(Container(trans)), info, clazz);
+		}
+
+		protected object NewInstance(IReflectArray arrayReflector, ArrayInfo info, IReflectClass
+			 clazz)
+		{
+			return arrayReflector.NewInstance(clazz, info);
+		}
+
+		protected IReflectClass NewInstanceReflectClass(IReflector reflector, ArrayInfo info
+			)
+		{
+			if (_usePrimitiveClassReflector)
+			{
+				return PrimitiveClassReflector(reflector);
+			}
+			return info.ReflectClass();
+		}
+
+		public virtual ITypeHandler4 ReadCandidateHandler(QueryingReadContext context)
+		{
+			return this;
+		}
+
+		protected virtual void ReadInfo(Transaction trans, IReadBuffer buffer, ArrayInfo 
+			info)
+		{
+			int classID = buffer.ReadInt();
+			if (IsPreVersion0Format(classID))
+			{
+				throw new UnsupportedOldFormatException();
+			}
+			else
+			{
+				_versionHelper.ReadTypeInfo(trans, buffer, info, classID);
+				ReflectClassFromElementsEntry(Container(trans), info, classID);
+				ReadDimensions(info, buffer);
+			}
+			if (Debug4.ExceedsMaximumArrayEntries(info.ElementCount(), _usePrimitiveClassReflector
+				))
+			{
+				info.ElementCount(0);
+			}
+		}
+
+		protected virtual void ReadDimensions(ArrayInfo info, IReadBuffer buffer)
+		{
+			info.ElementCount(buffer.ReadInt());
+		}
+
+		protected virtual bool IsPreVersion0Format(int elementCount)
+		{
+			return _versionHelper.IsPreVersion0Format(elementCount);
+		}
+
+		private void ReflectClassFromElementsEntry(ObjectContainerBase container, ArrayInfo
+			 info, int classID)
+		{
+			info.ReflectClass(_versionHelper.ReflectClassFromElementsEntry(container, info, classID
+				));
+		}
+
+		protected IReflectClass ClassReflector(IReflector reflector, Db4objects.Db4o.Internal.ClassMetadata
+			 classMetadata, bool isPrimitive)
+		{
+			return _versionHelper.ClassReflector(reflector, classMetadata, isPrimitive);
+		}
+
+		public static IEnumerator Iterator(IReflectClass claxx, object obj)
+		{
+			IReflectArray reflectArray = claxx.Reflector().Array();
+			if (reflectArray.IsNDimensional(claxx))
+			{
+				return MultidimensionalArrayHandler.AllElementsMultidimensional(reflectArray, obj
+					);
+			}
+			return Db4objects.Db4o.Internal.Handlers.Array.ArrayHandler.AllElements(reflectArray
+				, obj);
+		}
+
+		protected virtual bool UseJavaHandling()
+		{
+			return _versionHelper.UseJavaHandling();
+		}
+
+		protected virtual int ClassIDFromInfo(ObjectContainerBase container, ArrayInfo info
+			)
+		{
+			return _versionHelper.ClassIDFromInfo(container, info);
+		}
+
+		private int MarshalledClassID(ObjectContainerBase container, ArrayInfo info)
+		{
+			return ClassIdToMarshalledClassId(ClassIDFromInfo(container, info), info.Primitive
+				());
+		}
+
+		public int ClassIdToMarshalledClassId(int classID, bool primitive)
+		{
+			return _versionHelper.ClassIdToMarshalledClassId(classID, primitive);
+		}
+
+		protected bool IsPrimitive(IReflector reflector, IReflectClass claxx, Db4objects.Db4o.Internal.ClassMetadata
+			 classMetadata)
+		{
+			return _versionHelper.IsPrimitive(reflector, claxx, classMetadata);
+		}
+
+		private IReflectClass ComponentType(ObjectContainerBase container, object obj)
+		{
+			return ArrayReflector(container).GetComponentType(container.Reflector().ForObject
+				(obj));
+		}
+
+		public virtual void Defragment(IDefragmentContext context)
+		{
+			if (context.ClassMetadata().HasIdentity())
+			{
+				DefragmentSlot(context);
+			}
+			else
+			{
+				context.IncrementOffset(LinkLength());
+			}
+		}
+
+		public void DefragmentSlot(IDefragmentContext context)
+		{
+			if (IsUntypedByteArray(context))
+			{
+				return;
+			}
+			int classIdOffset = context.TargetBuffer().Offset();
+			ArrayInfo info = NewArrayInfo();
+			ReadInfo(context.Transaction(), context, info);
+			DefragmentWriteMappedClassId(context, info, classIdOffset);
+			int elementCount = info.ElementCount();
+			if (HasNullBitmap(info))
+			{
+				BitMap4 bitMap = ReadNullBitmap(context, elementCount);
+				elementCount -= ReducedCountForNullBitMap(elementCount, bitMap);
+			}
+			ITypeHandler4 correctTypeHandlerVersion = CorrectHandlerVersion(context, _handler
+				, info);
+			for (int i = 0; i < elementCount; i++)
+			{
+				context.Defragment(correctTypeHandlerVersion);
+			}
+		}
+
+		private ITypeHandler4 CorrectHandlerVersion(IDefragmentContext context, ITypeHandler4
+			 handler, ArrayInfo info)
+		{
+			Db4objects.Db4o.Internal.ClassMetadata classMetadata = ClassMetadata(context, info
+				);
+			return HandlerRegistry.CorrectHandlerVersion(context, handler, classMetadata);
+		}
+
+		private Db4objects.Db4o.Internal.ClassMetadata ClassMetadata(IDefragmentContext context
+			, ArrayInfo info)
+		{
+			int classMetadataId = ClassIDFromInfo(Container(context), info);
+			return Container(context).ClassMetadataForID(classMetadataId);
+		}
+
+		private void DefragmentWriteMappedClassId(IDefragmentContext context, ArrayInfo info
+			, int classIdOffset)
+		{
+			ByteArrayBuffer targetBuffer = context.TargetBuffer();
+			int currentOffset = targetBuffer.Offset();
+			targetBuffer.Seek(classIdOffset);
+			int classID = ClassIDFromInfo(Container(context), info);
+			int mappedID = context.MappedID(classID);
+			int marshalledMappedId = ClassIdToMarshalledClassId(mappedID, info.Primitive());
+			targetBuffer.WriteInt(marshalledMappedId);
+			targetBuffer.Seek(currentOffset);
+		}
+
+		private bool IsUntypedByteArray(IBufferContext context)
+		{
+			return Handlers4.IsUntyped(_handler) && HandleAsByteArray(context);
+		}
+
+		protected virtual bool HandleAsByteArray(IBufferContext context)
+		{
+			int offset = context.Offset();
+			ArrayInfo info = NewArrayInfo();
+			ReadInfo(context.Transaction(), context, info);
+			bool isByteArray = context.Transaction().Reflector().ForClass(typeof(byte)).Equals
+				(info.ReflectClass());
+			context.Seek(offset);
+			return isByteArray;
+		}
+
+		public virtual object Read(IReadContext context)
+		{
+			ArrayInfo info = NewArrayInfo();
+			object array = ReadCreate(context.Transaction(), context, info);
+			ReadElements(context, info, array);
+			return array;
+		}
+
+		protected virtual void ReadElements(IReadContext context, ArrayInfo info, object 
+			array)
+		{
+			ReadInto(context, info, array);
+		}
+
+		protected virtual ArrayInfo NewArrayInfo()
+		{
+			return new ArrayInfo();
+		}
+
+		protected void ReadInto(IReadContext context, ArrayInfo info, object array)
+		{
+			if (array == null)
+			{
+				return;
+			}
+			if (HandleAsByteArray(array))
+			{
+				context.ReadBytes((byte[])array);
+				// byte[] performance optimisation
+				return;
+			}
+			if (HasNullBitmap(info))
+			{
+				BitMap4 nullBitMap = ReadNullBitmap(context, info.ElementCount());
+				for (int i = 0; i < info.ElementCount(); i++)
+				{
+					object obj = nullBitMap.IsTrue(i) ? null : context.ReadObject(_handler);
+					ArrayReflector(Container(context)).Set(array, i, obj);
+				}
+			}
+			else
+			{
+				for (int i = 0; i < info.ElementCount(); i++)
+				{
+					ArrayReflector(Container(context)).Set(array, i, context.ReadObject(_handler));
+				}
+			}
+		}
+
+		protected virtual BitMap4 ReadNullBitmap(IReadBuffer context, int length)
+		{
+			return context.ReadBitMap(length);
+		}
+
+		protected bool HasNullBitmap(ArrayInfo info)
+		{
+			return _versionHelper.HasNullBitmap(info);
+		}
+
+		public virtual void Write(IWriteContext context, object obj)
+		{
+			ArrayInfo info = NewArrayInfo();
+			Analyze(Container(context), obj, info);
+			WriteInfo(context, info);
+			WriteElements(context, obj, info);
+		}
+
+		protected virtual void WriteElements(IWriteContext context, object obj, ArrayInfo
+			 info)
+		{
+			if (HandleAsByteArray(obj))
+			{
+				context.WriteBytes((byte[])obj);
+			}
+			else
+			{
+				// byte[] performance optimisation
+				if (HasNullBitmap(info))
+				{
+					BitMap4 nullItems = NullItemsMap(ArrayReflector(Container(context)), obj);
+					WriteNullBitmap(context, nullItems);
+					for (int i = 0; i < info.ElementCount(); i++)
+					{
+						if (!nullItems.IsTrue(i))
+						{
+							context.WriteObject(_handler, ArrayReflector(Container(context)).Get(obj, i));
+						}
+					}
+				}
+				else
+				{
+					for (int i = 0; i < info.ElementCount(); i++)
+					{
+						context.WriteObject(_handler, ArrayReflector(Container(context)).Get(obj, i));
+					}
+				}
+			}
+		}
+
+		protected virtual void WriteInfo(IWriteContext context, ArrayInfo info)
+		{
+			WriteHeader(context, info);
+			WriteDimensions(context, info);
+		}
+
+		private void WriteHeader(IWriteContext context, ArrayInfo info)
+		{
+			context.WriteInt(MarshalledClassID(Container(context), info));
+			_versionHelper.WriteTypeInfo(context, info);
+		}
+
+		protected virtual void WriteDimensions(IWriteContext context, ArrayInfo info)
+		{
+			context.WriteInt(info.ElementCount());
+		}
+
+		protected void Analyze(ObjectContainerBase container, object obj, ArrayInfo info)
+		{
+			// TODO: Move as much analysis as possible to ReflectArray#analyze() 
+			ArrayReflector(container).Analyze(obj, info);
+			IReflectClass claxx = ComponentType(container, obj);
+			Db4objects.Db4o.Internal.ClassMetadata classMetadata = container.ProduceClassMetadata
+				(claxx);
+			bool primitive = IsPrimitive(container.Reflector(), claxx, classMetadata);
+			if (primitive)
+			{
+				claxx = classMetadata.ClassReflector();
+			}
+			info.Primitive(primitive);
+			info.ReflectClass(claxx);
+			AnalyzeDimensions(container, obj, info);
+		}
+
+		protected virtual void AnalyzeDimensions(ObjectContainerBase container, object obj
+			, ArrayInfo info)
+		{
+			info.ElementCount(ArrayReflector(container).GetLength(obj));
+		}
+
+		private void WriteNullBitmap(IWriteBuffer context, BitMap4 bitMap)
+		{
+			context.WriteBytes(bitMap.Bytes());
+		}
+
+		protected virtual BitMap4 NullItemsMap(IReflectArray reflector, object array)
+		{
+			int arrayLength = reflector.GetLength(array);
+			BitMap4 nullBitMap = new BitMap4(arrayLength);
+			for (int i = 0; i < arrayLength; i++)
+			{
+				if (reflector.Get(array, i) == null)
+				{
+					nullBitMap.Set(i, true);
+				}
+			}
+			return nullBitMap;
+		}
+
+		internal virtual ObjectContainerBase Container(IContext context)
+		{
+			return context.Transaction().Container();
+		}
+
+		public virtual IPreparedComparison PrepareComparison(IContext context, object obj
+			)
+		{
+			return new PreparedArrayContainsComparison(context, this, _handler, obj);
+		}
+
+		public virtual int LinkLength()
+		{
+			return Const4.IndirectionLength;
+		}
+
+		public virtual ITypeHandler4 UnversionedTemplate()
+		{
+			return new Db4objects.Db4o.Internal.Handlers.Array.ArrayHandler();
+		}
+
+		public virtual object DeepClone(object context)
+		{
+			TypeHandlerCloneContext typeHandlerCloneContext = (TypeHandlerCloneContext)context;
+			Db4objects.Db4o.Internal.Handlers.Array.ArrayHandler original = (Db4objects.Db4o.Internal.Handlers.Array.ArrayHandler
+				)typeHandlerCloneContext.original;
+			Db4objects.Db4o.Internal.Handlers.Array.ArrayHandler cloned = (Db4objects.Db4o.Internal.Handlers.Array.ArrayHandler
+				)Reflection4.NewInstance(this);
+			cloned._usePrimitiveClassReflector = original._usePrimitiveClassReflector;
+			cloned._handler = typeHandlerCloneContext.CorrectHandlerVersion(original.DelegateTypeHandler
+				());
+			return cloned;
+		}
+
+		public virtual ITypeHandler4 DelegateTypeHandler()
+		{
+			return _handler;
+		}
+
+		private const int HashcodeForNull = 9141078;
+
+		public override string ToString()
+		{
+			return "ArrayHandler(isPrimitive=" + _usePrimitiveClassReflector + ", handler=" +
+				 _handler + ")";
+		}
+
+		public virtual bool DescendsIntoMembers()
+		{
+			return true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayHandler0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayHandler0.cs
new file mode 100644
index 0000000..e375b21
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayHandler0.cs
@@ -0,0 +1,100 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.IO;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers.Array;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Marshall;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal.Handlers.Array
+{
+	/// <exclude></exclude>
+	public class ArrayHandler0 : ArrayHandler1
+	{
+		protected override ArrayVersionHelper CreateVersionHelper()
+		{
+			return new ArrayVersionHelper0();
+		}
+
+		protected override void WithContent(AbstractBufferContext context, IRunnable runnable
+			)
+		{
+			int address = context.ReadInt();
+			int length = context.ReadInt();
+			if (address == 0)
+			{
+				return;
+			}
+			IReadBuffer temp = context.Buffer();
+			ByteArrayBuffer indirectedBuffer = Container(context).DecryptedBufferByAddress(address
+				, length);
+			context.Buffer(indirectedBuffer);
+			runnable.Run();
+			context.Buffer(temp);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Delete(IDeleteContext context)
+		{
+			context.ReadSlot();
+			context.DefragmentRecommended();
+		}
+
+		public override object Read(IReadContext readContext)
+		{
+			IInternalReadContext context = (IInternalReadContext)readContext;
+			ByteArrayBuffer buffer = (ByteArrayBuffer)context.ReadIndirectedBuffer();
+			if (buffer == null)
+			{
+				return null;
+			}
+			// With the following line we ask the context to work with 
+			// a different buffer. Should this logic ever be needed by
+			// a user handler, it should be implemented by using a Queue
+			// in the UnmarshallingContext.
+			// The buffer has to be set back from the outside!  See below
+			IReadBuffer contextBuffer = context.Buffer(buffer);
+			object array = base.Read(context);
+			// The context buffer has to be set back.
+			context.Buffer(contextBuffer);
+			return array;
+		}
+
+		public static void Defragment(IDefragmentContext context, ArrayHandler handler)
+		{
+			int sourceAddress = context.SourceBuffer().ReadInt();
+			int length = context.SourceBuffer().ReadInt();
+			if (sourceAddress == 0 && length == 0)
+			{
+				context.TargetBuffer().WriteInt(0);
+				context.TargetBuffer().WriteInt(0);
+				return;
+			}
+			Slot slot = context.AllocateMappedTargetSlot(sourceAddress, length);
+			ByteArrayBuffer sourceBuffer = null;
+			try
+			{
+				sourceBuffer = context.SourceBufferByAddress(sourceAddress, length);
+			}
+			catch (IOException exc)
+			{
+				throw new Db4oIOException(exc);
+			}
+			DefragmentContextImpl payloadContext = new DefragmentContextImpl(sourceBuffer, (DefragmentContextImpl
+				)context);
+			handler.DefragmentSlot(payloadContext);
+			payloadContext.WriteToTarget(slot.Address());
+			context.TargetBuffer().WriteInt(slot.Address());
+			context.TargetBuffer().WriteInt(length);
+		}
+
+		public override void Defragment(IDefragmentContext context)
+		{
+			Defragment(context, this);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayHandler1.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayHandler1.cs
new file mode 100644
index 0000000..482f693
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayHandler1.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Handlers.Array;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers.Array
+{
+	/// <exclude></exclude>
+	public class ArrayHandler1 : ArrayHandler3
+	{
+		protected override bool HandleAsByteArray(IBufferContext context)
+		{
+			return false;
+		}
+
+		protected override bool HandleAsByteArray(object obj)
+		{
+			return false;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayHandler3.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayHandler3.cs
new file mode 100644
index 0000000..304e78a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayHandler3.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Handlers.Array;
+
+namespace Db4objects.Db4o.Internal.Handlers.Array
+{
+	/// <exclude></exclude>
+	public class ArrayHandler3 : ArrayHandler5
+	{
+		protected override ArrayVersionHelper CreateVersionHelper()
+		{
+			return new ArrayVersionHelper3();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayHandler5.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayHandler5.cs
new file mode 100644
index 0000000..10b94ef
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayHandler5.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Handlers.Array;
+
+namespace Db4objects.Db4o.Internal.Handlers.Array
+{
+	/// <exclude></exclude>
+	public class ArrayHandler5 : ArrayHandler
+	{
+		protected override ArrayVersionHelper CreateVersionHelper()
+		{
+			return new ArrayVersionHelper5();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayVersionHelper.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayVersionHelper.cs
new file mode 100644
index 0000000..5354b0f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayVersionHelper.cs
@@ -0,0 +1,91 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Handlers.Array
+{
+	/// <exclude></exclude>
+	public class ArrayVersionHelper
+	{
+		public virtual int ClassIDFromInfo(ObjectContainerBase container, ArrayInfo info)
+		{
+			ClassMetadata classMetadata = container.ProduceClassMetadata(info.ReflectClass());
+			if (classMetadata == null)
+			{
+				return 0;
+			}
+			return classMetadata.GetID();
+		}
+
+		public virtual int ClassIdToMarshalledClassId(int classID, bool primitive)
+		{
+			return classID;
+		}
+
+		public virtual IReflectClass ClassReflector(IReflector reflector, ClassMetadata classMetadata
+			, bool isPrimitive)
+		{
+			return isPrimitive ? Handlers4.PrimitiveClassReflector(classMetadata, reflector) : 
+				classMetadata.ClassReflector();
+		}
+
+		public virtual bool UseJavaHandling()
+		{
+			return true;
+		}
+
+		public virtual bool HasNullBitmap(ArrayInfo info)
+		{
+			if (info.Nullable())
+			{
+				return true;
+			}
+			return !info.Primitive();
+		}
+
+		public virtual bool IsPreVersion0Format(int elementCount)
+		{
+			return false;
+		}
+
+		public virtual bool IsPrimitive(IReflector reflector, IReflectClass claxx, ClassMetadata
+			 classMetadata)
+		{
+			return claxx.IsPrimitive();
+		}
+
+		public virtual IReflectClass ReflectClassFromElementsEntry(ObjectContainerBase container
+			, ArrayInfo info, int classID)
+		{
+			if (classID == 0)
+			{
+				return null;
+			}
+			ClassMetadata classMetadata = container.ClassMetadataForID(classID);
+			if (classMetadata == null)
+			{
+				return null;
+			}
+			return ClassReflector(container.Reflector(), classMetadata, info.Primitive());
+		}
+
+		public virtual void WriteTypeInfo(IWriteContext context, ArrayInfo info)
+		{
+			BitMap4 typeInfoBitmap = new BitMap4(2);
+			typeInfoBitmap.Set(0, info.Primitive());
+			typeInfoBitmap.Set(1, info.Nullable());
+			context.WriteByte(typeInfoBitmap.GetByte(0));
+		}
+
+		public virtual void ReadTypeInfo(Transaction trans, IReadBuffer buffer, ArrayInfo
+			 info, int classID)
+		{
+			BitMap4 typeInfoBitmap = new BitMap4(buffer.ReadByte());
+			info.Primitive(typeInfoBitmap.IsTrue(0));
+			info.Nullable(typeInfoBitmap.IsTrue(1));
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayVersionHelper0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayVersionHelper0.cs
new file mode 100644
index 0000000..5e53ff3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayVersionHelper0.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Handlers.Array;
+
+namespace Db4objects.Db4o.Internal.Handlers.Array
+{
+	/// <exclude></exclude>
+	public class ArrayVersionHelper0 : ArrayVersionHelper3
+	{
+		public override bool IsPreVersion0Format(int elementCount)
+		{
+			return elementCount >= 0;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayVersionHelper3.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayVersionHelper3.cs
new file mode 100644
index 0000000..db3f35a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayVersionHelper3.cs
@@ -0,0 +1,104 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers.Array;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Handlers.Array
+{
+	/// <exclude></exclude>
+	public class ArrayVersionHelper3 : ArrayVersionHelper5
+	{
+		public override int ClassIDFromInfo(ObjectContainerBase container, ArrayInfo info
+			)
+		{
+			ClassMetadata classMetadata = container.ProduceClassMetadata(info.ReflectClass());
+			if (classMetadata == null)
+			{
+				// TODO: This one is a terrible low-frequency blunder !!!
+				// If YapClass-ID == 99999 then we will get IGNORE back.
+				// Discovered on adding the primitives
+				return Const4.IgnoreId;
+			}
+			return classMetadata.GetID();
+		}
+
+		public override int ClassIdToMarshalledClassId(int classID, bool primitive)
+		{
+			if (primitive)
+			{
+				classID -= Const4.Primitive;
+			}
+			return -classID;
+		}
+
+		public override IReflectClass ClassReflector(IReflector reflector, ClassMetadata 
+			classMetadata, bool isPrimitive)
+		{
+			IReflectClass primitiveClaxx = Handlers4.PrimitiveClassReflector(classMetadata, reflector
+				);
+			if (primitiveClaxx != null)
+			{
+				return primitiveClaxx;
+			}
+			return base.ClassReflector(reflector, classMetadata, isPrimitive);
+		}
+
+		public override bool HasNullBitmap(ArrayInfo info)
+		{
+			return false;
+		}
+
+		public override bool IsPrimitive(IReflector reflector, IReflectClass claxx, ClassMetadata
+			 classMetadata)
+		{
+			return Handlers4.PrimitiveClassReflector(classMetadata, reflector) != null;
+			return claxx.IsPrimitive();
+		}
+
+		public override IReflectClass ReflectClassFromElementsEntry(ObjectContainerBase container
+			, ArrayInfo info, int classID)
+		{
+			if (classID == Const4.IgnoreId)
+			{
+				// TODO: Here is a low-frequency mistake, extremely unlikely.
+				// If classID == 99999 by accident then we will get ignore.
+				return null;
+			}
+			info.Primitive(false);
+			if (UseJavaHandling())
+			{
+				if (classID < Const4.Primitive)
+				{
+					info.Primitive(true);
+					classID -= Const4.Primitive;
+				}
+			}
+			classID = -classID;
+			ClassMetadata classMetadata = container.ClassMetadataForID(classID);
+			if (classMetadata != null)
+			{
+				return ClassReflector(container.Reflector(), classMetadata, info.Primitive());
+			}
+			return null;
+		}
+
+		public sealed override bool UseJavaHandling()
+		{
+			return !Deploy.csharp;
+		}
+
+		public override void WriteTypeInfo(IWriteContext context, ArrayInfo info)
+		{
+		}
+
+		// do nothing, the byte for additional type information was added after format 3
+		public override void ReadTypeInfo(Transaction trans, IReadBuffer buffer, ArrayInfo
+			 info, int classID)
+		{
+		}
+		// do nothing, the byte for additional type information was added after format 3
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayVersionHelper5.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayVersionHelper5.cs
new file mode 100644
index 0000000..e599407
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ArrayVersionHelper5.cs
@@ -0,0 +1,16 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Handlers.Array;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Handlers.Array
+{
+	/// <exclude></exclude>
+	public class ArrayVersionHelper5 : ArrayVersionHelper
+	{
+		public override bool HasNullBitmap(ArrayInfo info)
+		{
+			return !info.Primitive();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/MultidimensionalArrayHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/MultidimensionalArrayHandler.cs
new file mode 100644
index 0000000..087b01d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/MultidimensionalArrayHandler.cs
@@ -0,0 +1,145 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers.Array;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Handlers.Array
+{
+	/// <summary>n-dimensional array</summary>
+	/// <exclude></exclude>
+	public class MultidimensionalArrayHandler : ArrayHandler
+	{
+		public MultidimensionalArrayHandler(ITypeHandler4 a_handler, bool a_isPrimitive) : 
+			base(a_handler, a_isPrimitive)
+		{
+		}
+
+		public MultidimensionalArrayHandler()
+		{
+		}
+
+		// required for reflection cloning
+		public sealed override IEnumerator AllElements(ObjectContainerBase container, object
+			 array)
+		{
+			return AllElementsMultidimensional(ArrayReflector(container), array);
+		}
+
+		public static IEnumerator AllElementsMultidimensional(IReflectArray reflectArray, 
+			object array)
+		{
+			return new MultidimensionalArrayIterator(reflectArray, (object[])array);
+		}
+
+		protected static int ElementCount(int[] a_dim)
+		{
+			int elements = a_dim[0];
+			for (int i = 1; i < a_dim.Length; i++)
+			{
+				elements = elements * a_dim[i];
+			}
+			return elements;
+		}
+
+		public sealed override byte Identifier()
+		{
+			return Const4.Yaparrayn;
+		}
+
+		protected override ArrayInfo NewArrayInfo()
+		{
+			return new MultidimensionalArrayInfo();
+		}
+
+		protected override void ReadDimensions(ArrayInfo info, IReadBuffer buffer)
+		{
+			ReadDimensions(info, buffer, buffer.ReadInt());
+		}
+
+		private void ReadDimensions(ArrayInfo info, IReadBuffer buffer, int dimensionCount
+			)
+		{
+			int[] dim = new int[dimensionCount];
+			for (int i = 0; i < dim.Length; i++)
+			{
+				dim[i] = buffer.ReadInt();
+			}
+			((MultidimensionalArrayInfo)info).Dimensions(dim);
+			info.ElementCount(ElementCount(dim));
+		}
+
+		protected override void ReadElements(IReadContext context, ArrayInfo info, object
+			 array)
+		{
+			if (array == null)
+			{
+				return;
+			}
+			object[] objects = new object[info.ElementCount()];
+			ReadInto(context, info, objects);
+			ArrayReflector(Container(context)).Shape(objects, 0, array, ((MultidimensionalArrayInfo
+				)info).Dimensions(), 0);
+		}
+
+		protected override void WriteDimensions(IWriteContext context, ArrayInfo info)
+		{
+			int[] dim = ((MultidimensionalArrayInfo)info).Dimensions();
+			context.WriteInt(dim.Length);
+			for (int i = 0; i < dim.Length; i++)
+			{
+				context.WriteInt(dim[i]);
+			}
+		}
+
+		protected override void WriteElements(IWriteContext context, object obj, ArrayInfo
+			 info)
+		{
+			IEnumerator objects = AllElements(Container(context), obj);
+			if (HasNullBitmap(info))
+			{
+				BitMap4 nullBitMap = new BitMap4(info.ElementCount());
+				IReservedBuffer nullBitMapBuffer = context.Reserve(nullBitMap.MarshalledLength());
+				int currentElement = 0;
+				while (objects.MoveNext())
+				{
+					object current = objects.Current;
+					if (current == null)
+					{
+						nullBitMap.SetTrue(currentElement);
+					}
+					else
+					{
+						context.WriteObject(DelegateTypeHandler(), current);
+					}
+					currentElement++;
+				}
+				nullBitMapBuffer.WriteBytes(nullBitMap.Bytes());
+			}
+			else
+			{
+				while (objects.MoveNext())
+				{
+					context.WriteObject(DelegateTypeHandler(), objects.Current);
+				}
+			}
+		}
+
+		protected override void AnalyzeDimensions(ObjectContainerBase container, object obj
+			, ArrayInfo info)
+		{
+			int[] dim = ArrayReflector(container).Dimensions(obj);
+			((MultidimensionalArrayInfo)info).Dimensions(dim);
+			info.ElementCount(ElementCount(dim));
+		}
+
+		public override ITypeHandler4 UnversionedTemplate()
+		{
+			return new Db4objects.Db4o.Internal.Handlers.Array.MultidimensionalArrayHandler();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/MultidimensionalArrayHandler0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/MultidimensionalArrayHandler0.cs
new file mode 100644
index 0000000..cfcb4ba
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/MultidimensionalArrayHandler0.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers.Array;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers.Array
+{
+	/// <exclude></exclude>
+	public class MultidimensionalArrayHandler0 : MultidimensionalArrayHandler3
+	{
+		protected override ArrayVersionHelper CreateVersionHelper()
+		{
+			return new ArrayVersionHelper0();
+		}
+
+		public override object Read(IReadContext readContext)
+		{
+			IInternalReadContext context = (IInternalReadContext)readContext;
+			ByteArrayBuffer buffer = (ByteArrayBuffer)context.ReadIndirectedBuffer();
+			if (buffer == null)
+			{
+				return null;
+			}
+			// With the following line we ask the context to work with 
+			// a different buffer. Should this logic ever be needed by
+			// a user handler, it should be implemented by using a Queue
+			// in the UnmarshallingContext.
+			// The buffer has to be set back from the outside!  See below
+			IReadBuffer contextBuffer = context.Buffer(buffer);
+			object array = base.Read(context);
+			// The context buffer has to be set back.
+			context.Buffer(contextBuffer);
+			return array;
+		}
+
+		public override void Defragment(IDefragmentContext context)
+		{
+			ArrayHandler0.Defragment(context, this);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/MultidimensionalArrayHandler3.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/MultidimensionalArrayHandler3.cs
new file mode 100644
index 0000000..fa2c00f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/MultidimensionalArrayHandler3.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Handlers.Array;
+
+namespace Db4objects.Db4o.Internal.Handlers.Array
+{
+	/// <exclude></exclude>
+	public class MultidimensionalArrayHandler3 : MultidimensionalArrayHandler
+	{
+		protected override ArrayVersionHelper CreateVersionHelper()
+		{
+			return new ArrayVersionHelper3();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/MultidimensionalArrayIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/MultidimensionalArrayIterator.cs
new file mode 100644
index 0000000..ac80fc4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/MultidimensionalArrayIterator.cs
@@ -0,0 +1,79 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Internal.Handlers.Array;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Handlers.Array
+{
+	/// <exclude></exclude>
+	public class MultidimensionalArrayIterator : IEnumerator
+	{
+		private readonly IReflectArray _reflectArray;
+
+		private readonly object[] _array;
+
+		private int _currentElement;
+
+		private IEnumerator _delegate;
+
+		public MultidimensionalArrayIterator(IReflectArray reflectArray, object[] array)
+		{
+			_reflectArray = reflectArray;
+			_array = array;
+			Reset();
+		}
+
+		public virtual object Current
+		{
+			get
+			{
+				if (_delegate == null)
+				{
+					return _array[_currentElement];
+				}
+				return _delegate.Current;
+			}
+		}
+
+		public virtual bool MoveNext()
+		{
+			if (_delegate != null)
+			{
+				if (_delegate.MoveNext())
+				{
+					return true;
+				}
+				_delegate = null;
+			}
+			_currentElement++;
+			if (_currentElement >= _array.Length)
+			{
+				return false;
+			}
+			object obj = _array[_currentElement];
+			Type clazz = obj.GetType();
+			if (clazz.IsArray)
+			{
+				if (clazz.GetElementType().IsArray)
+				{
+					_delegate = new Db4objects.Db4o.Internal.Handlers.Array.MultidimensionalArrayIterator
+						(_reflectArray, (object[])obj);
+				}
+				else
+				{
+					_delegate = new ReflectArrayIterator(_reflectArray, obj);
+				}
+				return MoveNext();
+			}
+			return true;
+		}
+
+		public virtual void Reset()
+		{
+			_currentElement = -1;
+			_delegate = null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ReflectArrayIterator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ReflectArrayIterator.cs
new file mode 100644
index 0000000..4ec622a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Array/ReflectArrayIterator.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Handlers.Array
+{
+	/// <exclude></exclude>
+	internal sealed class ReflectArrayIterator : IndexedIterator
+	{
+		private readonly object _array;
+
+		private readonly IReflectArray _reflectArray;
+
+		public ReflectArrayIterator(IReflectArray reflectArray, object array) : base(reflectArray
+			.GetLength(array))
+		{
+			_reflectArray = reflectArray;
+			_array = array;
+		}
+
+		protected override object Get(int index)
+		{
+			return _reflectArray.Get(_array, index);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/BooleanHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/BooleanHandler.cs
new file mode 100644
index 0000000..b69f159
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/BooleanHandler.cs
@@ -0,0 +1,121 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public sealed class BooleanHandler : PrimitiveHandler
+	{
+		internal const int Length = 1 + Const4.AddedLength;
+
+		private const byte True = (byte)'T';
+
+		private const byte False = (byte)'F';
+
+		private const byte Null = (byte)'N';
+
+		private static readonly bool Defaultvalue = false;
+
+		public override object DefaultValue()
+		{
+			return Defaultvalue;
+		}
+
+		public override int LinkLength()
+		{
+			return Length;
+		}
+
+		public override Type PrimitiveJavaClass()
+		{
+			return typeof(bool);
+		}
+
+		internal override object Read1(ByteArrayBuffer a_bytes)
+		{
+			byte ret = a_bytes.ReadByte();
+			if (ret == True)
+			{
+				return true;
+			}
+			if (ret == False)
+			{
+				return false;
+			}
+			return null;
+		}
+
+		public override void Write(object obj, ByteArrayBuffer buffer)
+		{
+			buffer.WriteByte(GetEncodedByteValue(obj));
+		}
+
+		private byte GetEncodedByteValue(object obj)
+		{
+			if (obj == null)
+			{
+				return Null;
+			}
+			if (((bool)obj))
+			{
+				return True;
+			}
+			return False;
+		}
+
+		public override object Read(IReadContext context)
+		{
+			byte ret = context.ReadByte();
+			if (ret == True)
+			{
+				return true;
+			}
+			if (ret == False)
+			{
+				return false;
+			}
+			return null;
+		}
+
+		public override void Write(IWriteContext context, object obj)
+		{
+			context.WriteByte(GetEncodedByteValue(obj));
+		}
+
+		public override object NullRepresentationInUntypedArrays()
+		{
+			return null;
+		}
+
+		public override IPreparedComparison InternalPrepareComparison(object source)
+		{
+			bool sourceBoolean = ((bool)source);
+			return new _IPreparedComparison_111(sourceBoolean);
+		}
+
+		private sealed class _IPreparedComparison_111 : IPreparedComparison
+		{
+			public _IPreparedComparison_111(bool sourceBoolean)
+			{
+				this.sourceBoolean = sourceBoolean;
+			}
+
+			public int CompareTo(object target)
+			{
+				if (target == null)
+				{
+					return 1;
+				}
+				bool targetBoolean = ((bool)target);
+				return sourceBoolean == targetBoolean ? 0 : (sourceBoolean ? 1 : -1);
+			}
+
+			private readonly bool sourceBoolean;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/ByteHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/ByteHandler.cs
new file mode 100644
index 0000000..778eb11
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/ByteHandler.cs
@@ -0,0 +1,86 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	public sealed class ByteHandler : PrimitiveHandler
+	{
+		internal const int Length = 1 + Const4.AddedLength;
+
+		private static readonly byte Defaultvalue = (byte)0;
+
+		public override object Coerce(IReflectClass claxx, object obj)
+		{
+			return Coercion4.ToByte(obj);
+		}
+
+		public override object DefaultValue()
+		{
+			return Defaultvalue;
+		}
+
+		public override int LinkLength()
+		{
+			return Length;
+		}
+
+		public override Type PrimitiveJavaClass()
+		{
+			return typeof(byte);
+		}
+
+		internal override object Read1(ByteArrayBuffer a_bytes)
+		{
+			byte ret = a_bytes.ReadByte();
+			return ret;
+		}
+
+		public override void Write(object a_object, ByteArrayBuffer a_bytes)
+		{
+			a_bytes.WriteByte(((byte)a_object));
+		}
+
+		public override object Read(IReadContext context)
+		{
+			byte byteValue = context.ReadByte();
+			return byteValue;
+		}
+
+		public override void Write(IWriteContext context, object obj)
+		{
+			context.WriteByte(((byte)obj));
+		}
+
+		public override IPreparedComparison InternalPrepareComparison(object source)
+		{
+			byte sourceByte = ((byte)source);
+			return new _IPreparedComparison_82(sourceByte);
+		}
+
+		private sealed class _IPreparedComparison_82 : IPreparedComparison
+		{
+			public _IPreparedComparison_82(byte sourceByte)
+			{
+				this.sourceByte = sourceByte;
+			}
+
+			public int CompareTo(object target)
+			{
+				if (target == null)
+				{
+					return 1;
+				}
+				byte targetByte = ((byte)target);
+				return sourceByte == targetByte ? 0 : (sourceByte < targetByte ? -1 : 1);
+			}
+
+			private readonly byte sourceByte;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/CharHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/CharHandler.cs
new file mode 100644
index 0000000..622e9ce
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/CharHandler.cs
@@ -0,0 +1,90 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	public sealed class CharHandler : PrimitiveHandler
+	{
+		internal const int Length = Const4.CharBytes + Const4.AddedLength;
+
+		private static readonly char Defaultvalue = (char)0;
+
+		public override object DefaultValue()
+		{
+			return Defaultvalue;
+		}
+
+		public override int LinkLength()
+		{
+			return Length;
+		}
+
+		public override Type PrimitiveJavaClass()
+		{
+			return typeof(char);
+		}
+
+		internal override object Read1(ByteArrayBuffer a_bytes)
+		{
+			byte b1 = a_bytes.ReadByte();
+			byte b2 = a_bytes.ReadByte();
+			char ret = (char)((b1 & unchecked((int)(0xff))) | ((b2 & unchecked((int)(0xff))) 
+				<< 8));
+			return ret;
+		}
+
+		public override void Write(object a_object, ByteArrayBuffer a_bytes)
+		{
+			char char_ = ((char)a_object);
+			a_bytes.WriteByte((byte)(char_ & unchecked((int)(0xff))));
+			a_bytes.WriteByte((byte)(char_ >> 8));
+		}
+
+		public override object Read(IReadContext context)
+		{
+			byte b1 = context.ReadByte();
+			byte b2 = context.ReadByte();
+			char charValue = (char)((b1 & unchecked((int)(0xff))) | ((b2 & unchecked((int)(0xff
+				))) << 8));
+			return charValue;
+		}
+
+		public override void Write(IWriteContext context, object obj)
+		{
+			char charValue = ((char)obj);
+			context.WriteBytes(new byte[] { (byte)(charValue & unchecked((int)(0xff))), (byte
+				)(charValue >> 8) });
+		}
+
+		public override IPreparedComparison InternalPrepareComparison(object source)
+		{
+			char sourceChar = ((char)source);
+			return new _IPreparedComparison_90(sourceChar);
+		}
+
+		private sealed class _IPreparedComparison_90 : IPreparedComparison
+		{
+			public _IPreparedComparison_90(char sourceChar)
+			{
+				this.sourceChar = sourceChar;
+			}
+
+			public int CompareTo(object target)
+			{
+				if (target == null)
+				{
+					return 1;
+				}
+				char targetChar = ((char)target);
+				return sourceChar == targetChar ? 0 : (sourceChar < targetChar ? -1 : 1);
+			}
+
+			private readonly char sourceChar;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/DateHandler0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/DateHandler0.cs
new file mode 100644
index 0000000..9ed8890
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/DateHandler0.cs
@@ -0,0 +1,22 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public class DateHandler0 : DateHandler
+	{
+		public override object Read(IReadContext context)
+		{
+			long value = context.ReadLong();
+			if (value == long.MaxValue)
+			{
+				return PrimitiveNull();
+			}
+			return new DateTime(value);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/DateHandlerBase.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/DateHandlerBase.cs
new file mode 100644
index 0000000..00bf615
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/DateHandlerBase.cs
@@ -0,0 +1,104 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <summary>Shared (java/.net) logic for Date handling.</summary>
+	/// <remarks>Shared (java/.net) logic for Date handling.</remarks>
+	public abstract class DateHandlerBase : LongHandler
+	{
+		public override object Coerce(IReflectClass claxx, object obj)
+		{
+			return ClassReflector().IsAssignableFrom(claxx) ? obj : No4.Instance;
+		}
+
+		public abstract object CopyValue(object from, object to);
+
+		public abstract override object DefaultValue();
+
+		public abstract override object NullRepresentationInUntypedArrays();
+
+		public override Type PrimitiveJavaClass()
+		{
+			return null;
+		}
+
+		protected override Type JavaClass()
+		{
+			return DefaultValue().GetType();
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		public override object Read(MarshallerFamily mf, StatefulBuffer writer, bool redirect
+			)
+		{
+			return mf._primitive.ReadDate(writer);
+		}
+
+		internal override object Read1(ByteArrayBuffer a_bytes)
+		{
+			return PrimitiveMarshaller().ReadDate(a_bytes);
+		}
+
+		public override void Write(object a_object, ByteArrayBuffer a_bytes)
+		{
+			// TODO: This is a temporary fix to prevent exceptions with
+			// Marshaller.LEGACY.  
+			if (a_object == null)
+			{
+				a_object = new DateTime(0);
+			}
+			a_bytes.WriteLong(((DateTime)a_object).Ticks);
+		}
+
+		public static string Now()
+		{
+			return Platform4.Format(Platform4.Now(), true);
+		}
+
+		public override object Read(IReadContext context)
+		{
+			long milliseconds = ((long)base.Read(context));
+			return new DateTime(milliseconds);
+		}
+
+		public override void Write(IWriteContext context, object obj)
+		{
+			long milliseconds = ((DateTime)obj).Ticks;
+			base.Write(context, milliseconds);
+		}
+
+		public override IPreparedComparison InternalPrepareComparison(object source)
+		{
+			long sourceDate = ((DateTime)source).Ticks;
+			return new _IPreparedComparison_69(sourceDate);
+		}
+
+		private sealed class _IPreparedComparison_69 : IPreparedComparison
+		{
+			public _IPreparedComparison_69(long sourceDate)
+			{
+				this.sourceDate = sourceDate;
+			}
+
+			public int CompareTo(object target)
+			{
+				if (target == null)
+				{
+					return 1;
+				}
+				long targetDate = ((DateTime)target).Ticks;
+				return sourceDate == targetDate ? 0 : (sourceDate < targetDate ? -1 : 1);
+			}
+
+			private readonly long sourceDate;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/DoubleHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/DoubleHandler.cs
new file mode 100644
index 0000000..0b8586e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/DoubleHandler.cs
@@ -0,0 +1,87 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public class DoubleHandler : LongHandler
+	{
+		private static readonly double Defaultvalue = System.Convert.ToDouble(0);
+
+		public override object Coerce(IReflectClass claxx, object obj)
+		{
+			return Coercion4.ToDouble(obj);
+		}
+
+		public override object DefaultValue()
+		{
+			return Defaultvalue;
+		}
+
+		public override Type PrimitiveJavaClass()
+		{
+			return typeof(double);
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		public override object Read(MarshallerFamily mf, StatefulBuffer buffer, bool redirect
+			)
+		{
+			return mf._primitive.ReadDouble(buffer);
+		}
+
+		internal override object Read1(ByteArrayBuffer buffer)
+		{
+			return PrimitiveMarshaller().ReadDouble(buffer);
+		}
+
+		public override void Write(object a_object, ByteArrayBuffer a_bytes)
+		{
+			a_bytes.WriteLong(Platform4.DoubleToLong(((double)a_object)));
+		}
+
+		public override object Read(IReadContext context)
+		{
+			long l = (long)base.Read(context);
+			return Platform4.LongToDouble(l);
+		}
+
+		public override void Write(IWriteContext context, object obj)
+		{
+			context.WriteLong(Platform4.DoubleToLong(((double)obj)));
+		}
+
+		public override IPreparedComparison InternalPrepareComparison(object source)
+		{
+			double sourceDouble = ((double)source);
+			return new _IPreparedComparison_55(sourceDouble);
+		}
+
+		private sealed class _IPreparedComparison_55 : IPreparedComparison
+		{
+			public _IPreparedComparison_55(double sourceDouble)
+			{
+				this.sourceDouble = sourceDouble;
+			}
+
+			public int CompareTo(object target)
+			{
+				if (target == null)
+				{
+					return 1;
+				}
+				double targetDouble = ((double)target);
+				return sourceDouble == targetDouble ? 0 : (sourceDouble < targetDouble ? -1 : 1);
+			}
+
+			private readonly double sourceDouble;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/DoubleHandler0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/DoubleHandler0.cs
new file mode 100644
index 0000000..5fc8738
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/DoubleHandler0.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	public class DoubleHandler0 : DoubleHandler
+	{
+		public override object Read(IReadContext context)
+		{
+			double value = (double)base.Read(context);
+			if (double.IsNaN(value))
+			{
+				return null;
+			}
+			return value;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/FloatHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/FloatHandler.cs
new file mode 100644
index 0000000..04108d4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/FloatHandler.cs
@@ -0,0 +1,85 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	public class FloatHandler : IntHandler
+	{
+		private static readonly float Defaultvalue = System.Convert.ToSingle(0);
+
+		public override object Coerce(IReflectClass claxx, object obj)
+		{
+			return Coercion4.ToFloat(obj);
+		}
+
+		public override object DefaultValue()
+		{
+			return Defaultvalue;
+		}
+
+		public override Type PrimitiveJavaClass()
+		{
+			return typeof(float);
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		public override object Read(MarshallerFamily mf, StatefulBuffer writer, bool redirect
+			)
+		{
+			return mf._primitive.ReadFloat(writer);
+		}
+
+		internal override object Read1(ByteArrayBuffer a_bytes)
+		{
+			return PrimitiveMarshaller().ReadFloat(a_bytes);
+		}
+
+		public override void Write(object a_object, ByteArrayBuffer a_bytes)
+		{
+			WriteInt(Sharpen.Runtime.FloatToIntBits(((float)a_object)), a_bytes);
+		}
+
+		public override object Read(IReadContext context)
+		{
+			return Sharpen.Runtime.IntBitsToFloat(context.ReadInt());
+		}
+
+		public override void Write(IWriteContext context, object obj)
+		{
+			context.WriteInt(Sharpen.Runtime.FloatToIntBits(((float)obj)));
+		}
+
+		public override IPreparedComparison InternalPrepareComparison(object source)
+		{
+			float sourceFloat = ((float)source);
+			return new _IPreparedComparison_54(sourceFloat);
+		}
+
+		private sealed class _IPreparedComparison_54 : IPreparedComparison
+		{
+			public _IPreparedComparison_54(float sourceFloat)
+			{
+				this.sourceFloat = sourceFloat;
+			}
+
+			public int CompareTo(object target)
+			{
+				if (target == null)
+				{
+					return 1;
+				}
+				float targetFloat = ((float)target);
+				return sourceFloat == targetFloat ? 0 : (sourceFloat < targetFloat ? -1 : 1);
+			}
+
+			private readonly float sourceFloat;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/FloatHandler0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/FloatHandler0.cs
new file mode 100644
index 0000000..3a00af8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/FloatHandler0.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	public class FloatHandler0 : FloatHandler
+	{
+		public override object Read(IReadContext context)
+		{
+			float value = (float)base.Read(context);
+			if (float.IsNaN(value))
+			{
+				return null;
+			}
+			return value;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/HandlerVersion.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/HandlerVersion.cs
new file mode 100644
index 0000000..609c8ac
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/HandlerVersion.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public class HandlerVersion
+	{
+		public readonly int _number;
+
+		public static readonly Db4objects.Db4o.Internal.Handlers.HandlerVersion Invalid = 
+			new Db4objects.Db4o.Internal.Handlers.HandlerVersion(-1);
+
+		public HandlerVersion(int number)
+		{
+			_number = number;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj)
+			{
+				return true;
+			}
+			return ((Db4objects.Db4o.Internal.Handlers.HandlerVersion)obj)._number == _number;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/IFieldAwareTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/IFieldAwareTypeHandler.cs
new file mode 100644
index 0000000..524e3a4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/IFieldAwareTypeHandler.cs
@@ -0,0 +1,28 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public interface IFieldAwareTypeHandler : IReferenceTypeHandler, IVersionedTypeHandler
+		, ICascadingTypeHandler, IVirtualAttributeHandler
+	{
+		void AddFieldIndices(ObjectIdContextImpl context);
+
+		void CollectIDs(CollectIdContext context, IPredicate4 predicate);
+
+		void DeleteMembers(DeleteContextImpl deleteContext, bool isUpdate);
+
+		void ReadVirtualAttributes(ObjectReferenceContext context);
+
+		void ClassMetadata(Db4objects.Db4o.Internal.ClassMetadata classMetadata);
+
+		bool SeekToField(ObjectHeaderContext context, ClassAspect aspect);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/IVariableLengthTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/IVariableLengthTypeHandler.cs
new file mode 100644
index 0000000..eb35fce
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/IVariableLengthTypeHandler.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <summary>
+	/// marker interface for TypeHandlers where the slot
+	/// length can change, depending on the object stored
+	/// </summary>
+	/// <exclude></exclude>
+	public interface IVariableLengthTypeHandler : ITypeHandler4
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/IVirtualAttributeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/IVirtualAttributeHandler.cs
new file mode 100644
index 0000000..ef9e566
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/IVirtualAttributeHandler.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public interface IVirtualAttributeHandler
+	{
+		void ReadVirtualAttributes(ObjectReferenceContext context);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/IntHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/IntHandler.cs
new file mode 100644
index 0000000..42099c8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/IntHandler.cs
@@ -0,0 +1,122 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public class IntHandler : PrimitiveHandler
+	{
+		private static readonly int Defaultvalue = 0;
+
+		public override object Coerce(IReflectClass claxx, object obj)
+		{
+			return Coercion4.ToInt(obj);
+		}
+
+		public override object DefaultValue()
+		{
+			return Defaultvalue;
+		}
+
+		public override Type PrimitiveJavaClass()
+		{
+			return typeof(int);
+		}
+
+		public override int LinkLength()
+		{
+			return Const4.IntLength;
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		public override object Read(MarshallerFamily mf, StatefulBuffer writer, bool redirect
+			)
+		{
+			return mf._primitive.ReadInteger(writer);
+		}
+
+		internal override object Read1(ByteArrayBuffer a_bytes)
+		{
+			return a_bytes.ReadInt();
+		}
+
+		public override void Write(object obj, ByteArrayBuffer writer)
+		{
+			Write(((int)obj), writer);
+		}
+
+		public virtual void Write(int intValue, ByteArrayBuffer writer)
+		{
+			WriteInt(intValue, writer);
+		}
+
+		public static void WriteInt(int a_int, ByteArrayBuffer a_bytes)
+		{
+			a_bytes.WriteInt(a_int);
+		}
+
+		public override void DefragIndexEntry(DefragmentContextImpl context)
+		{
+			context.IncrementIntSize();
+		}
+
+		public override object Read(IReadContext context)
+		{
+			return context.ReadInt();
+		}
+
+		public override void Write(IWriteContext context, object obj)
+		{
+			context.WriteInt(((int)obj));
+		}
+
+		public override IPreparedComparison InternalPrepareComparison(object source)
+		{
+			return NewPrepareCompare(((int)source));
+		}
+
+		public virtual IPreparedComparison NewPrepareCompare(int i)
+		{
+			return new IntHandler.PreparedIntComparison(this, i);
+		}
+
+		public static int Compare(int first, int second)
+		{
+			if (first == second)
+			{
+				return 0;
+			}
+			return first > second ? 1 : -1;
+		}
+
+		public sealed class PreparedIntComparison : IPreparedComparison
+		{
+			private readonly int _sourceInt;
+
+			public PreparedIntComparison(IntHandler _enclosing, int sourceInt)
+			{
+				this._enclosing = _enclosing;
+				this._sourceInt = sourceInt;
+			}
+
+			public int CompareTo(object target)
+			{
+				if (target == null)
+				{
+					return 1;
+				}
+				int targetInt = ((int)target);
+				return IntHandler.Compare(this._sourceInt, targetInt);
+			}
+
+			private readonly IntHandler _enclosing;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/IntHandler0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/IntHandler0.cs
new file mode 100644
index 0000000..c96386a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/IntHandler0.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public class IntHandler0 : IntHandler
+	{
+		public override object Read(IReadContext context)
+		{
+			int i = context.ReadInt();
+			if (i == int.MaxValue)
+			{
+				return null;
+			}
+			return i;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/LongHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/LongHandler.cs
new file mode 100644
index 0000000..f32c12c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/LongHandler.cs
@@ -0,0 +1,136 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public class LongHandler : PrimitiveHandler
+	{
+		private static readonly long Defaultvalue = System.Convert.ToInt64(0);
+
+		public override object Coerce(IReflectClass claxx, object obj)
+		{
+			return Coercion4.ToLong(obj);
+		}
+
+		public override object DefaultValue()
+		{
+			return Defaultvalue;
+		}
+
+		public override Type PrimitiveJavaClass()
+		{
+			return typeof(long);
+		}
+
+		public override int LinkLength()
+		{
+			return Const4.LongLength;
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		public override object Read(MarshallerFamily mf, StatefulBuffer buffer, bool redirect
+			)
+		{
+			return mf._primitive.ReadLong(buffer);
+		}
+
+		internal override object Read1(ByteArrayBuffer a_bytes)
+		{
+			return a_bytes.ReadLong();
+		}
+
+		public override void Write(object obj, ByteArrayBuffer buffer)
+		{
+			WriteLong(buffer, ((long)obj));
+		}
+
+		public static void WriteLong(IWriteBuffer buffer, long val)
+		{
+			if (Deploy.debug && Deploy.debugLong)
+			{
+				string l_s = "                                " + val;
+				new LatinStringIO().Write(buffer, Sharpen.Runtime.Substring(l_s, l_s.Length - Const4
+					.LongBytes));
+			}
+			else
+			{
+				for (int i = 0; i < Const4.LongBytes; i++)
+				{
+					buffer.WriteByte((byte)(val >> ((Const4.LongBytes - 1 - i) * 8)));
+				}
+			}
+		}
+
+		public static long ReadLong(IReadBuffer buffer)
+		{
+			long ret = 0;
+			if (Deploy.debug && Deploy.debugLong)
+			{
+				ret = long.Parse(new LatinStringIO().Read(buffer, Const4.LongBytes).Trim());
+			}
+			else
+			{
+				for (int i = 0; i < Const4.LongBytes; i++)
+				{
+					ret = (ret << 8) + (buffer.ReadByte() & unchecked((int)(0xff)));
+				}
+			}
+			return ret;
+		}
+
+		public override object Read(IReadContext context)
+		{
+			return context.ReadLong();
+		}
+
+		public override void Write(IWriteContext context, object obj)
+		{
+			context.WriteLong(((long)obj));
+		}
+
+		public static int Compare(long first, long second)
+		{
+			if (first == second)
+			{
+				return 0;
+			}
+			return first > second ? 1 : -1;
+		}
+
+		public override IPreparedComparison InternalPrepareComparison(object source)
+		{
+			long sourceLong = ((long)source);
+			return new _IPreparedComparison_102(sourceLong);
+		}
+
+		private sealed class _IPreparedComparison_102 : IPreparedComparison
+		{
+			public _IPreparedComparison_102(long sourceLong)
+			{
+				this.sourceLong = sourceLong;
+			}
+
+			public int CompareTo(object target)
+			{
+				if (target == null)
+				{
+					return 1;
+				}
+				long targetLong = ((long)target);
+				return LongHandler.Compare(sourceLong, targetLong);
+			}
+
+			private readonly long sourceLong;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/LongHandler0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/LongHandler0.cs
new file mode 100644
index 0000000..d4cc82b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/LongHandler0.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	public class LongHandler0 : LongHandler
+	{
+		public override object Read(IReadContext context)
+		{
+			long value = (long)base.Read(context);
+			if (value == long.MaxValue)
+			{
+				return null;
+			}
+			return value;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/NetType.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/NetType.cs
new file mode 100644
index 0000000..dbdcabf
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/NetType.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	internal interface INetType
+	{
+		object DefaultValue();
+
+		int TypeID();
+
+		void Write(object obj, byte[] bytes, int offset);
+
+		object Read(byte[] bytes, int offset);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/NetTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/NetTypeHandler.cs
new file mode 100644
index 0000000..9a849a6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/NetTypeHandler.cs
@@ -0,0 +1,105 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public abstract class NetTypeHandler : PrimitiveHandler, INetType
+	{
+		private int i_linkLength;
+
+		public virtual string DotNetClassName()
+		{
+			string className = this.GetType().FullName;
+			int pos = className.IndexOf(".Net");
+			if (pos >= 0)
+			{
+				return "System." + Sharpen.Runtime.Substring(className, pos + 4) + ", mscorlib";
+			}
+			return DefaultValue().GetType().FullName;
+		}
+
+		public override void RegisterReflector(IReflector reflector)
+		{
+			base.RegisterReflector(reflector);
+			byte[] bytes = new byte[65];
+			for (int i = 0; i < bytes.Length; i++)
+			{
+				bytes[i] = 55;
+			}
+			// TODO: Why 55? This is a '7'. Remove.
+			Write(PrimitiveNull(), bytes, 0);
+			for (int i = 0; i < bytes.Length; i++)
+			{
+				if (bytes[i] == 55)
+				{
+					i_linkLength = i;
+					break;
+				}
+			}
+		}
+
+		public virtual int GetID()
+		{
+			return TypeID();
+		}
+
+		// This method is needed for NetSimpleTypeHandler only during
+		// initalisation and overloaded there. No abstract declaration 
+		// here, so we don't have to implement the methods on .NET.
+		public virtual string GetName()
+		{
+			return DotNetClassName();
+		}
+
+		public override int LinkLength()
+		{
+			return i_linkLength;
+		}
+
+		public override Type PrimitiveJavaClass()
+		{
+			return DefaultValue().GetType();
+		}
+
+		protected override Type JavaClass()
+		{
+			return base.JavaClass();
+		}
+
+		public abstract object Read(byte[] bytes, int offset);
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		internal override object Read1(ByteArrayBuffer a_bytes)
+		{
+			int offset = a_bytes._offset;
+			object ret = Read(a_bytes._buffer, a_bytes._offset);
+			a_bytes._offset = offset + LinkLength();
+			return ret;
+		}
+
+		public abstract int TypeID();
+
+		public abstract void Write(object obj, byte[] bytes, int offset);
+
+		public override void Write(object a_object, ByteArrayBuffer a_bytes)
+		{
+			int offset = a_bytes._offset;
+			if (a_object != null)
+			{
+				Write(a_object, a_bytes._buffer, a_bytes._offset);
+			}
+			a_bytes._offset = offset + LinkLength();
+		}
+
+		public override IPreparedComparison InternalPrepareComparison(object obj)
+		{
+			throw new NotImplementedException();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/NullFieldAwareTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/NullFieldAwareTypeHandler.cs
new file mode 100644
index 0000000..4b4094a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/NullFieldAwareTypeHandler.cs
@@ -0,0 +1,91 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public class NullFieldAwareTypeHandler : IFieldAwareTypeHandler
+	{
+		public static readonly IFieldAwareTypeHandler Instance = new NullFieldAwareTypeHandler
+			();
+
+		public virtual void AddFieldIndices(ObjectIdContextImpl context)
+		{
+		}
+
+		public virtual void ClassMetadata(Db4objects.Db4o.Internal.ClassMetadata classMetadata
+			)
+		{
+		}
+
+		public virtual void CollectIDs(CollectIdContext context, IPredicate4 predicate)
+		{
+		}
+
+		public virtual void DeleteMembers(DeleteContextImpl deleteContext, bool isUpdate)
+		{
+		}
+
+		public virtual void ReadVirtualAttributes(ObjectReferenceContext context)
+		{
+		}
+
+		public virtual bool SeekToField(ObjectHeaderContext context, ClassAspect aspect)
+		{
+			return false;
+		}
+
+		public virtual void Defragment(IDefragmentContext context)
+		{
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Delete(IDeleteContext context)
+		{
+		}
+
+		public virtual void Activate(IReferenceActivationContext context)
+		{
+		}
+
+		public virtual void Write(IWriteContext context, object obj)
+		{
+		}
+
+		public virtual IPreparedComparison PrepareComparison(IContext context, object obj
+			)
+		{
+			return null;
+		}
+
+		public virtual ITypeHandler4 UnversionedTemplate()
+		{
+			return null;
+		}
+
+		public virtual object DeepClone(object context)
+		{
+			return null;
+		}
+
+		public virtual void CascadeActivation(IActivationContext context)
+		{
+		}
+
+		public virtual void CollectIDs(QueryingReadContext context)
+		{
+		}
+
+		public virtual ITypeHandler4 ReadCandidateHandler(QueryingReadContext context)
+		{
+			return null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/PlainObjectHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/PlainObjectHandler.cs
new file mode 100644
index 0000000..805b8f0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/PlainObjectHandler.cs
@@ -0,0 +1,31 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <summary>Tyehandler for naked plain objects (java.lang.Object).</summary>
+	/// <remarks>Tyehandler for naked plain objects (java.lang.Object).</remarks>
+	public class PlainObjectHandler : IReferenceTypeHandler
+	{
+		public virtual void Defragment(IDefragmentContext context)
+		{
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Delete(IDeleteContext context)
+		{
+		}
+
+		public virtual void Activate(IReferenceActivationContext context)
+		{
+		}
+
+		public virtual void Write(IWriteContext context, object obj)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/PrimitiveHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/PrimitiveHandler.cs
new file mode 100644
index 0000000..faee081
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/PrimitiveHandler.cs
@@ -0,0 +1,196 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public abstract class PrimitiveHandler : IValueTypeHandler, IIndexableTypeHandler
+		, IBuiltinTypeHandler, IQueryableTypeHandler
+	{
+		protected IReflectClass _classReflector;
+
+		private IReflectClass _primitiveClassReflector;
+
+		private object _primitiveNull;
+
+		public virtual object Coerce(IReflectClass claxx, object obj)
+		{
+			return IsAssignableFrom(claxx) ? obj : No4.Instance;
+		}
+
+		private bool IsAssignableFrom(IReflectClass claxx)
+		{
+			return ClassReflector().IsAssignableFrom(claxx) || PrimitiveClassReflector().IsAssignableFrom
+				(claxx);
+		}
+
+		public abstract object DefaultValue();
+
+		public virtual void Delete(IDeleteContext context)
+		{
+			context.Seek(context.Offset() + LinkLength());
+		}
+
+		public object IndexEntryToObject(IContext context, object indexEntry)
+		{
+			return indexEntry;
+		}
+
+		public abstract Type PrimitiveJavaClass();
+
+		protected virtual Type JavaClass()
+		{
+			return Platform4.NullableTypeFor(PrimitiveJavaClass());
+		}
+
+		public virtual bool DescendsIntoMembers()
+		{
+			return false;
+		}
+
+		public virtual object PrimitiveNull()
+		{
+			if (_primitiveNull == null)
+			{
+				IReflectClass claxx = (_primitiveClassReflector == null ? _classReflector : _primitiveClassReflector
+					);
+				_primitiveNull = claxx.NullValue();
+			}
+			return _primitiveNull;
+		}
+
+		/// <param name="mf"></param>
+		/// <param name="buffer"></param>
+		/// <param name="redirect"></param>
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		public virtual object Read(MarshallerFamily mf, StatefulBuffer buffer, bool redirect
+			)
+		{
+			return Read1(buffer);
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		internal abstract object Read1(ByteArrayBuffer reader);
+
+		public virtual object ReadIndexEntry(IContext context, ByteArrayBuffer buffer)
+		{
+			try
+			{
+				return Read1(buffer);
+			}
+			catch (CorruptionException)
+			{
+			}
+			return null;
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		public object ReadIndexEntryFromObjectSlot(MarshallerFamily mf, StatefulBuffer statefulBuffer
+			)
+		{
+			return Read(mf, statefulBuffer, true);
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual object ReadIndexEntry(IObjectIdContext context)
+		{
+			return Read(context);
+		}
+
+		public virtual IReflectClass ClassReflector()
+		{
+			return _classReflector;
+		}
+
+		public virtual IReflectClass PrimitiveClassReflector()
+		{
+			return _primitiveClassReflector;
+		}
+
+		public virtual void RegisterReflector(IReflector reflector)
+		{
+			_classReflector = reflector.ForClass(JavaClass());
+			Type clazz = PrimitiveJavaClass();
+			if (clazz != null)
+			{
+				_primitiveClassReflector = reflector.ForClass(clazz);
+			}
+		}
+
+		public abstract void Write(object a_object, ByteArrayBuffer a_bytes);
+
+		public virtual void WriteIndexEntry(IContext context, ByteArrayBuffer a_writer, object
+			 a_object)
+		{
+			if (a_object == null)
+			{
+				a_object = PrimitiveNull();
+			}
+			Write(a_object, a_writer);
+		}
+
+		// redundant, only added to make Sun JDK 1.2's java happy :(
+		public abstract int LinkLength();
+
+		public void Defragment(IDefragmentContext context)
+		{
+			context.IncrementOffset(LinkLength());
+		}
+
+		public virtual void DefragIndexEntry(DefragmentContextImpl context)
+		{
+			try
+			{
+				Read1(context.SourceBuffer());
+				Read1(context.TargetBuffer());
+			}
+			catch (CorruptionException)
+			{
+				Exceptions4.VirtualException();
+			}
+		}
+
+		protected virtual Db4objects.Db4o.Internal.Marshall.PrimitiveMarshaller PrimitiveMarshaller
+			()
+		{
+			return MarshallerFamily.Current()._primitive;
+		}
+
+		public virtual void Write(IWriteContext context, object obj)
+		{
+			throw new NotImplementedException();
+		}
+
+		public virtual object Read(IReadContext context)
+		{
+			throw new NotImplementedException();
+		}
+
+		public virtual object NullRepresentationInUntypedArrays()
+		{
+			return PrimitiveNull();
+		}
+
+		public virtual IPreparedComparison PrepareComparison(IContext context, object obj
+			)
+		{
+			if (obj == null)
+			{
+				return Null.Instance;
+			}
+			return InternalPrepareComparison(obj);
+		}
+
+		public abstract IPreparedComparison InternalPrepareComparison(object obj);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/ShortHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/ShortHandler.cs
new file mode 100644
index 0000000..b04feaf
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/ShortHandler.cs
@@ -0,0 +1,104 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	public class ShortHandler : PrimitiveHandler
+	{
+		internal const int Length = Const4.ShortBytes + Const4.AddedLength;
+
+		private static readonly short Defaultvalue = (short)0;
+
+		public override object Coerce(IReflectClass claxx, object obj)
+		{
+			return Coercion4.ToShort(obj);
+		}
+
+		public override object DefaultValue()
+		{
+			return Defaultvalue;
+		}
+
+		public override int LinkLength()
+		{
+			return Length;
+		}
+
+		public override Type PrimitiveJavaClass()
+		{
+			return typeof(short);
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		public override object Read(MarshallerFamily mf, StatefulBuffer buffer, bool redirect
+			)
+		{
+			return mf._primitive.ReadShort(buffer);
+		}
+
+		internal override object Read1(ByteArrayBuffer buffer)
+		{
+			return PrimitiveMarshaller().ReadShort(buffer);
+		}
+
+		public override void Write(object a_object, ByteArrayBuffer a_bytes)
+		{
+			WriteShort(((short)a_object), a_bytes);
+		}
+
+		internal static void WriteShort(int a_short, ByteArrayBuffer a_bytes)
+		{
+			for (int i = 0; i < Const4.ShortBytes; i++)
+			{
+				a_bytes._buffer[a_bytes._offset++] = (byte)(a_short >> ((Const4.ShortBytes - 1 - 
+					i) * 8));
+			}
+		}
+
+		public override object Read(IReadContext context)
+		{
+			int value = ((context.ReadByte() & unchecked((int)(0xff))) << 8) + (context.ReadByte
+				() & unchecked((int)(0xff)));
+			return (short)value;
+		}
+
+		public override void Write(IWriteContext context, object obj)
+		{
+			int shortValue = ((short)obj);
+			context.WriteBytes(new byte[] { (byte)(shortValue >> 8), (byte)shortValue });
+		}
+
+		public override IPreparedComparison InternalPrepareComparison(object source)
+		{
+			short sourceShort = ((short)source);
+			return new _IPreparedComparison_86(sourceShort);
+		}
+
+		private sealed class _IPreparedComparison_86 : IPreparedComparison
+		{
+			public _IPreparedComparison_86(short sourceShort)
+			{
+				this.sourceShort = sourceShort;
+			}
+
+			public int CompareTo(object target)
+			{
+				if (target == null)
+				{
+					return 1;
+				}
+				short targetShort = ((short)target);
+				return sourceShort == targetShort ? 0 : (sourceShort < targetShort ? -1 : 1);
+			}
+
+			private readonly short sourceShort;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/ShortHandler0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/ShortHandler0.cs
new file mode 100644
index 0000000..f35b1e4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/ShortHandler0.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	public class ShortHandler0 : ShortHandler
+	{
+		public override object Read(IReadContext context)
+		{
+			short value = (short)base.Read(context);
+			if (value == short.MaxValue)
+			{
+				return null;
+			}
+			return value;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StandardReferenceTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StandardReferenceTypeHandler.cs
new file mode 100644
index 0000000..9fed1eb
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StandardReferenceTypeHandler.cs
@@ -0,0 +1,816 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Metadata;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public class StandardReferenceTypeHandler : IFieldAwareTypeHandler, IIndexableTypeHandler
+		, IReadsObjectIds
+	{
+		private const int HashcodeForNull = 72483944;
+
+		private Db4objects.Db4o.Internal.ClassMetadata _classMetadata;
+
+		public StandardReferenceTypeHandler(Db4objects.Db4o.Internal.ClassMetadata classMetadata
+			)
+		{
+			ClassMetadata(classMetadata);
+		}
+
+		public StandardReferenceTypeHandler()
+		{
+		}
+
+		public virtual void Defragment(IDefragmentContext context)
+		{
+			TraverseAllAspects(context, new _MarshallingInfoTraverseAspectCommand_35(context, 
+				EnsureFieldList(context)));
+		}
+
+		private sealed class _MarshallingInfoTraverseAspectCommand_35 : MarshallingInfoTraverseAspectCommand
+		{
+			public _MarshallingInfoTraverseAspectCommand_35(IDefragmentContext context, IMarshallingInfo
+				 baseArg1) : base(baseArg1)
+			{
+				this.context = context;
+			}
+
+			protected override int InternalDeclaredAspectCount(Db4objects.Db4o.Internal.ClassMetadata
+				 classMetadata)
+			{
+				return context.ReadInt();
+			}
+
+			protected override void ProcessAspect(ClassAspect aspect, int currentSlot, bool isNull
+				)
+			{
+				if (!isNull)
+				{
+					aspect.DefragAspect(context);
+				}
+			}
+
+			public override bool Accept(ClassAspect aspect)
+			{
+				return aspect.IsEnabledOn(context);
+			}
+
+			private readonly IDefragmentContext context;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Delete(IDeleteContext context)
+		{
+			context.DeleteObject();
+		}
+
+		public void ActivateAspects(UnmarshallingContext context)
+		{
+			BooleanByRef schemaUpdateDetected = new BooleanByRef();
+			ContextState savedState = context.SaveState();
+			ITraverseAspectCommand command = new _MarshallingInfoTraverseAspectCommand_63(context
+				, schemaUpdateDetected, EnsureFieldList(context));
+			// TODO: cant the aspect handle it itself?
+			// Probably no because old aspect versions might not be able
+			// to handle null...
+			TraverseAllAspects(context, command);
+			if (schemaUpdateDetected.value)
+			{
+				context.RestoreState(savedState);
+				command = new _MarshallingInfoTraverseAspectCommand_94(context, EnsureFieldList(context
+					));
+				TraverseAllAspects(context, command);
+			}
+		}
+
+		private sealed class _MarshallingInfoTraverseAspectCommand_63 : MarshallingInfoTraverseAspectCommand
+		{
+			public _MarshallingInfoTraverseAspectCommand_63(UnmarshallingContext context, BooleanByRef
+				 schemaUpdateDetected, IMarshallingInfo baseArg1) : base(baseArg1)
+			{
+				this.context = context;
+				this.schemaUpdateDetected = schemaUpdateDetected;
+			}
+
+			public override bool Accept(ClassAspect aspect)
+			{
+				return aspect.IsEnabledOn(context);
+			}
+
+			protected override void ProcessAspect(ClassAspect aspect, int currentSlot, bool isNull
+				)
+			{
+				if (aspect is FieldMetadata)
+				{
+					FieldMetadata field = (FieldMetadata)aspect;
+					if (field.Updating())
+					{
+						schemaUpdateDetected.value = true;
+					}
+					if (isNull)
+					{
+						if (field.GetStoredType() == null || !field.GetStoredType().IsPrimitive())
+						{
+							field.Set(context.PersistentObject(), null);
+						}
+						return;
+					}
+				}
+				aspect.Activate(context);
+			}
+
+			private readonly UnmarshallingContext context;
+
+			private readonly BooleanByRef schemaUpdateDetected;
+		}
+
+		private sealed class _MarshallingInfoTraverseAspectCommand_94 : MarshallingInfoTraverseAspectCommand
+		{
+			public _MarshallingInfoTraverseAspectCommand_94(UnmarshallingContext context, IMarshallingInfo
+				 baseArg1) : base(baseArg1)
+			{
+				this.context = context;
+			}
+
+			protected override void ProcessAspect(ClassAspect aspect, int currentSlot, bool isNull
+				)
+			{
+				FieldMetadata field = (FieldMetadata)aspect;
+				if (!isNull)
+				{
+					field.AttemptUpdate(context);
+				}
+			}
+
+			public override bool Accept(ClassAspect aspect)
+			{
+				return aspect is FieldMetadata;
+			}
+
+			private readonly UnmarshallingContext context;
+		}
+
+		public virtual void Activate(IReferenceActivationContext context)
+		{
+			ActivateAspects((UnmarshallingContext)context);
+		}
+
+		public virtual void Write(IWriteContext context, object obj)
+		{
+			MarshallAspects(obj, (MarshallingContext)context);
+		}
+
+		public virtual void MarshallAspects(object obj, MarshallingContext context)
+		{
+			Transaction trans = context.Transaction();
+			ITraverseAspectCommand command = new _MarshallingInfoTraverseAspectCommand_122(context
+				, obj, trans, EnsureFieldList(context));
+			TraverseAllAspects(context, command);
+		}
+
+		private sealed class _MarshallingInfoTraverseAspectCommand_122 : MarshallingInfoTraverseAspectCommand
+		{
+			public _MarshallingInfoTraverseAspectCommand_122(MarshallingContext context, object
+				 obj, Transaction trans, IMarshallingInfo baseArg1) : base(baseArg1)
+			{
+				this.context = context;
+				this.obj = obj;
+				this.trans = trans;
+			}
+
+			protected override int InternalDeclaredAspectCount(Db4objects.Db4o.Internal.ClassMetadata
+				 classMetadata)
+			{
+				int aspectCount = classMetadata._aspects.Length;
+				context.WriteDeclaredAspectCount(aspectCount);
+				return aspectCount;
+			}
+
+			public override bool Accept(ClassAspect aspect)
+			{
+				return aspect.IsEnabledOn(context);
+			}
+
+			protected override void ProcessAspect(ClassAspect aspect, int currentSlot, bool isNull
+				)
+			{
+				object marshalledObject = obj;
+				if (aspect is FieldMetadata)
+				{
+					FieldMetadata field = (FieldMetadata)aspect;
+					marshalledObject = field.GetOrCreate(trans, obj);
+					if (marshalledObject == null)
+					{
+						context.IsNull(currentSlot, true);
+						field.AddIndexEntry(trans, context.ObjectID(), null);
+						return;
+					}
+				}
+				aspect.Marshall(context, marshalledObject);
+			}
+
+			public override void ProcessAspectOnMissingClass(ClassAspect aspect, int currentSlot
+				)
+			{
+				((MarshallingContext)context).IsNull(currentSlot, true);
+			}
+
+			private readonly MarshallingContext context;
+
+			private readonly object obj;
+
+			private readonly Transaction trans;
+		}
+
+		public virtual IPreparedComparison PrepareComparison(IContext context, object source
+			)
+		{
+			if (source == null)
+			{
+				return Null.Instance;
+			}
+			if (source is int)
+			{
+				int id = ((int)source);
+				return new StandardReferenceTypeHandler.PreparedComparisonImpl(id, null);
+			}
+			if (source is TransactionContext)
+			{
+				TransactionContext tc = (TransactionContext)source;
+				object obj = tc._object;
+				int id = IdFor(obj, tc._transaction);
+				return new StandardReferenceTypeHandler.PreparedComparisonImpl(id, ReflectClassFor
+					(obj));
+			}
+			return PlatformComparisonFor(source);
+		}
+
+		private IPreparedComparison PlatformComparisonFor(object source)
+		{
+			if (source == null)
+			{
+				return new _IPreparedComparison_179();
+			}
+			//TODO: Move the comparable wrapping to a .Net specific StandardStructHandler
+			if (source is IComparable)
+			{
+				return new _IPreparedComparison_187(source);
+			}
+			throw new IllegalComparisonException();
+		}
+
+		private sealed class _IPreparedComparison_179 : IPreparedComparison
+		{
+			public _IPreparedComparison_179()
+			{
+			}
+
+			public int CompareTo(object obj)
+			{
+				return obj == null ? 0 : -1;
+			}
+		}
+
+		private sealed class _IPreparedComparison_187 : IPreparedComparison
+		{
+			public _IPreparedComparison_187(object source)
+			{
+				this.source = source;
+			}
+
+			public int CompareTo(object obj)
+			{
+				if (obj == null)
+				{
+					return 1;
+				}
+				IComparable self = (IComparable)source;
+				return self.CompareTo(obj);
+			}
+
+			private readonly object source;
+		}
+
+		private IReflectClass ReflectClassFor(object obj)
+		{
+			return ClassMetadata().Reflector().ForObject(obj);
+		}
+
+		private int IdFor(object @object, Transaction inTransaction)
+		{
+			return Stream().GetID(inTransaction, @object);
+		}
+
+		private ObjectContainerBase Stream()
+		{
+			return ClassMetadata().Container();
+		}
+
+		public sealed class PreparedComparisonImpl : IPreparedComparison
+		{
+			private readonly int _id;
+
+			private readonly IReflectClass _claxx;
+
+			public PreparedComparisonImpl(int id, IReflectClass claxx)
+			{
+				_id = id;
+				_claxx = claxx;
+			}
+
+			public int CompareTo(object obj)
+			{
+				if (obj is TransactionContext)
+				{
+					obj = ((TransactionContext)obj)._object;
+				}
+				if (obj == null)
+				{
+					return _id == 0 ? 0 : 1;
+				}
+				if (obj is int)
+				{
+					int targetInt = ((int)obj);
+					return _id == targetInt ? 0 : (_id < targetInt ? -1 : 1);
+				}
+				if (_claxx != null)
+				{
+					if (_claxx.IsAssignableFrom(_claxx.Reflector().ForObject(obj)))
+					{
+						return 0;
+					}
+				}
+				throw new IllegalComparisonException();
+			}
+		}
+
+		public void TraverseAllAspects(IMarshallingInfo context, ITraverseAspectCommand command
+			)
+		{
+			ClassMetadata classMetadata = ClassMetadata();
+			AssertClassMetadata(context.ClassMetadata());
+			classMetadata.TraverseAllAspects(command);
+		}
+
+		protected virtual IMarshallingInfo EnsureFieldList(IMarshallingInfo context)
+		{
+			return context;
+		}
+
+		private void AssertClassMetadata(ClassMetadata contextMetadata)
+		{
+		}
+
+		//		if (contextMetadata != classMetadata()) {
+		//        	throw new IllegalStateException("expecting '" + classMetadata() + "', got '" + contextMetadata + "'");
+		//        }
+		public virtual ClassMetadata ClassMetadata()
+		{
+			return _classMetadata;
+		}
+
+		public virtual void ClassMetadata(ClassMetadata classMetadata)
+		{
+			_classMetadata = classMetadata;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (!(obj is StandardReferenceTypeHandler))
+			{
+				return false;
+			}
+			StandardReferenceTypeHandler other = (StandardReferenceTypeHandler)obj;
+			if (ClassMetadata() == null)
+			{
+				return other.ClassMetadata() == null;
+			}
+			return ClassMetadata().Equals(other.ClassMetadata());
+		}
+
+		public override int GetHashCode()
+		{
+			if (ClassMetadata() != null)
+			{
+				return ClassMetadata().GetHashCode();
+			}
+			return HashcodeForNull;
+		}
+
+		public virtual ITypeHandler4 UnversionedTemplate()
+		{
+			return new StandardReferenceTypeHandler(null);
+		}
+
+		public virtual object DeepClone(object context)
+		{
+			TypeHandlerCloneContext typeHandlerCloneContext = (TypeHandlerCloneContext)context;
+			StandardReferenceTypeHandler cloned = (StandardReferenceTypeHandler)Reflection4.NewInstance
+				(this);
+			if (typeHandlerCloneContext.original is StandardReferenceTypeHandler)
+			{
+				StandardReferenceTypeHandler original = (StandardReferenceTypeHandler)typeHandlerCloneContext
+					.original;
+				cloned.ClassMetadata(original.ClassMetadata());
+			}
+			else
+			{
+				// New logic: ClassMetadata takes the responsibility in 
+				//           #correctHandlerVersion() to set the 
+				//           ClassMetadata directly on cloned handler.
+				//            if(_classMetadata == null){
+				//                throw new IllegalStateException();
+				//            }
+				cloned.ClassMetadata(_classMetadata);
+			}
+			return cloned;
+		}
+
+		public virtual void CollectIDs(CollectIdContext context, IPredicate4 predicate)
+		{
+			ITraverseAspectCommand command = new _MarshallingInfoTraverseAspectCommand_311(predicate
+				, context, EnsureFieldList(context));
+			TraverseAllAspects(context, command);
+		}
+
+		private sealed class _MarshallingInfoTraverseAspectCommand_311 : MarshallingInfoTraverseAspectCommand
+		{
+			public _MarshallingInfoTraverseAspectCommand_311(IPredicate4 predicate, CollectIdContext
+				 context, IMarshallingInfo baseArg1) : base(baseArg1)
+			{
+				this.predicate = predicate;
+				this.context = context;
+			}
+
+			protected override void ProcessAspect(ClassAspect aspect, int currentSlot, bool isNull
+				)
+			{
+				if (isNull)
+				{
+					return;
+				}
+				if (predicate.Match(aspect))
+				{
+					aspect.CollectIDs(context);
+				}
+				else
+				{
+					aspect.IncrementOffset(context);
+				}
+			}
+
+			private readonly IPredicate4 predicate;
+
+			private readonly CollectIdContext context;
+		}
+
+		public virtual void CascadeActivation(IActivationContext context)
+		{
+			AssertClassMetadata(context.ClassMetadata());
+			context.CascadeActivationToTarget();
+		}
+
+		public virtual ITypeHandler4 ReadCandidateHandler(QueryingReadContext context)
+		{
+			if (ClassMetadata().IsArray())
+			{
+				return this;
+			}
+			return null;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void CollectIDs(QueryingReadContext context)
+		{
+			if (CollectIDsByTypehandlerAspect(context))
+			{
+				return;
+			}
+			CollectIDsByInstantiatingCollection(context);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private bool CollectIDsByTypehandlerAspect(QueryingReadContext context)
+		{
+			BooleanByRef aspectFound = new BooleanByRef(false);
+			CollectIdContext subContext = CollectIdContext.ForID(context.Transaction(), context
+				.Collector(), context.CollectionID());
+			ITraverseAspectCommand command = new _MarshallingInfoTraverseAspectCommand_349(this
+				, aspectFound, subContext, EnsureFieldList(subContext));
+			TraverseAllAspects(subContext, command);
+			return aspectFound.value;
+		}
+
+		private sealed class _MarshallingInfoTraverseAspectCommand_349 : MarshallingInfoTraverseAspectCommand
+		{
+			public _MarshallingInfoTraverseAspectCommand_349(StandardReferenceTypeHandler _enclosing
+				, BooleanByRef aspectFound, CollectIdContext subContext, IMarshallingInfo baseArg1
+				) : base(baseArg1)
+			{
+				this._enclosing = _enclosing;
+				this.aspectFound = aspectFound;
+				this.subContext = subContext;
+			}
+
+			protected override void ProcessAspect(ClassAspect aspect, int currentSlot, bool isNull
+				)
+			{
+				if (isNull)
+				{
+					return;
+				}
+				if (this._enclosing.IsCollectIdTypehandlerAspect(aspect))
+				{
+					aspectFound.value = true;
+					aspect.CollectIDs(subContext);
+				}
+				else
+				{
+					aspect.IncrementOffset(subContext);
+				}
+			}
+
+			private readonly StandardReferenceTypeHandler _enclosing;
+
+			private readonly BooleanByRef aspectFound;
+
+			private readonly CollectIdContext subContext;
+		}
+
+		private bool IsCollectIdTypehandlerAspect(ClassAspect aspect)
+		{
+			if (!(aspect is TypeHandlerAspect))
+			{
+				return false;
+			}
+			ITypeHandler4 typehandler = ((TypeHandlerAspect)aspect)._typeHandler;
+			return Handlers4.IsCascading(typehandler);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private void CollectIDsByInstantiatingCollection(QueryingReadContext context)
+		{
+			int id = context.CollectionID();
+			if (id == 0)
+			{
+				return;
+			}
+			Transaction transaction = context.Transaction();
+			ObjectContainerBase container = context.Container();
+			object obj = container.GetByID(transaction, id);
+			if (obj == null)
+			{
+				return;
+			}
+			// FIXME: [TA] review activation depth
+			int depth = DepthUtil.AdjustDepthToBorders(2);
+			container.Activate(transaction, obj, container.ActivationDepthProvider().ActivationDepth
+				(depth, ActivationMode.Activate));
+			Platform4.ForEachCollectionElement(obj, new _IVisitor4_390(context));
+		}
+
+		private sealed class _IVisitor4_390 : IVisitor4
+		{
+			public _IVisitor4_390(QueryingReadContext context)
+			{
+				this.context = context;
+			}
+
+			public void Visit(object elem)
+			{
+				context.Add(elem);
+			}
+
+			private readonly QueryingReadContext context;
+		}
+
+		public virtual void ReadVirtualAttributes(ObjectReferenceContext context)
+		{
+			ITraverseAspectCommand command = new _MarshallingInfoTraverseAspectCommand_398(context
+				, EnsureFieldList(context));
+			TraverseAllAspects(context, command);
+		}
+
+		private sealed class _MarshallingInfoTraverseAspectCommand_398 : MarshallingInfoTraverseAspectCommand
+		{
+			public _MarshallingInfoTraverseAspectCommand_398(ObjectReferenceContext context, 
+				IMarshallingInfo baseArg1) : base(baseArg1)
+			{
+				this.context = context;
+			}
+
+			protected override void ProcessAspect(ClassAspect aspect, int currentSlot, bool isNull
+				)
+			{
+				if (!isNull)
+				{
+					if (aspect is VirtualFieldMetadata)
+					{
+						((VirtualFieldMetadata)aspect).ReadVirtualAttribute(context);
+					}
+					else
+					{
+						aspect.IncrementOffset(context);
+					}
+				}
+			}
+
+			private readonly ObjectReferenceContext context;
+		}
+
+		public virtual void AddFieldIndices(ObjectIdContextImpl context)
+		{
+			ITraverseAspectCommand command = new _MarshallingInfoTraverseAspectCommand_414(context
+				, EnsureFieldList(context));
+			TraverseAllAspects(context, command);
+		}
+
+		private sealed class _MarshallingInfoTraverseAspectCommand_414 : MarshallingInfoTraverseAspectCommand
+		{
+			public _MarshallingInfoTraverseAspectCommand_414(ObjectIdContextImpl context, IMarshallingInfo
+				 baseArg1) : base(baseArg1)
+			{
+				this.context = context;
+			}
+
+			protected override void ProcessAspect(ClassAspect aspect, int currentSlot, bool isNull
+				)
+			{
+				if (aspect is FieldMetadata)
+				{
+					FieldMetadata field = (FieldMetadata)aspect;
+					if (isNull)
+					{
+						field.AddIndexEntry(context.Transaction(), context.ObjectId(), null);
+					}
+					else
+					{
+						field.AddFieldIndex(context);
+					}
+				}
+				else
+				{
+					aspect.IncrementOffset(context.Buffer());
+				}
+			}
+
+			public override bool Accept(ClassAspect aspect)
+			{
+				return aspect.IsEnabledOn(context);
+			}
+
+			private readonly ObjectIdContextImpl context;
+		}
+
+		public virtual void DeleteMembers(DeleteContextImpl context, bool isUpdate)
+		{
+			ITraverseAspectCommand command = new _MarshallingInfoTraverseAspectCommand_438(context
+				, isUpdate, EnsureFieldList(context));
+			TraverseAllAspects(context, command);
+		}
+
+		private sealed class _MarshallingInfoTraverseAspectCommand_438 : MarshallingInfoTraverseAspectCommand
+		{
+			public _MarshallingInfoTraverseAspectCommand_438(DeleteContextImpl context, bool 
+				isUpdate, IMarshallingInfo baseArg1) : base(baseArg1)
+			{
+				this.context = context;
+				this.isUpdate = isUpdate;
+			}
+
+			protected override void ProcessAspect(ClassAspect aspect, int currentSlot, bool isNull
+				)
+			{
+				if (isNull)
+				{
+					if (aspect is FieldMetadata)
+					{
+						FieldMetadata field = (FieldMetadata)aspect;
+						field.RemoveIndexEntry(context.Transaction(), context.ObjectId(), null);
+					}
+					return;
+				}
+				aspect.Delete(context, isUpdate);
+			}
+
+			private readonly DeleteContextImpl context;
+
+			private readonly bool isUpdate;
+		}
+
+		public virtual bool SeekToField(ObjectHeaderContext context, ClassAspect aspect)
+		{
+			BooleanByRef found = new BooleanByRef(false);
+			ITraverseAspectCommand command = new _MarshallingInfoTraverseAspectCommand_456(aspect
+				, found, EnsureFieldList(context));
+			TraverseAllAspects(context, command);
+			return found.value;
+		}
+
+		private sealed class _MarshallingInfoTraverseAspectCommand_456 : MarshallingInfoTraverseAspectCommand
+		{
+			public _MarshallingInfoTraverseAspectCommand_456(ClassAspect aspect, BooleanByRef
+				 found, IMarshallingInfo baseArg1) : base(baseArg1)
+			{
+				this.aspect = aspect;
+				this.found = found;
+			}
+
+			public override bool Accept(ClassAspect aspect)
+			{
+				return aspect.IsEnabledOn(this._marshallingInfo);
+			}
+
+			protected override void ProcessAspect(ClassAspect curField, int currentSlot, bool
+				 isNull)
+			{
+				if (curField == aspect)
+				{
+					found.value = !isNull;
+					this.Cancel();
+					return;
+				}
+				if (!isNull)
+				{
+					curField.IncrementOffset(this._marshallingInfo.Buffer());
+				}
+			}
+
+			private readonly ClassAspect aspect;
+
+			private readonly BooleanByRef found;
+		}
+
+		public object IndexEntryToObject(IContext context, object indexEntry)
+		{
+			if (indexEntry == null)
+			{
+				return null;
+			}
+			int id = ((int)indexEntry);
+			return ((ObjectContainerBase)context.ObjectContainer()).GetByID2(context.Transaction
+				(), id);
+		}
+
+		public void DefragIndexEntry(DefragmentContextImpl context)
+		{
+			context.CopyID();
+		}
+
+		public object ReadIndexEntry(IContext context, ByteArrayBuffer a_reader)
+		{
+			return a_reader.ReadInt();
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		public object ReadIndexEntryFromObjectSlot(MarshallerFamily mf, StatefulBuffer statefulBuffer
+			)
+		{
+			return ReadIndexEntry(statefulBuffer.Transaction().Context(), statefulBuffer);
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual object ReadIndexEntry(IObjectIdContext context)
+		{
+			return context.ReadInt();
+		}
+
+		public virtual int LinkLength()
+		{
+			return Const4.IdLength;
+		}
+
+		public virtual void WriteIndexEntry(IContext context, ByteArrayBuffer a_writer, object
+			 a_object)
+		{
+			if (a_object == null)
+			{
+				a_writer.WriteInt(0);
+				return;
+			}
+			a_writer.WriteInt(((int)a_object));
+		}
+
+		public virtual ITypeHandler4 DelegateTypeHandler(IContext context)
+		{
+			return ClassMetadata().DelegateTypeHandler(context);
+		}
+
+		public virtual ObjectID ReadObjectID(IInternalReadContext context)
+		{
+			return ObjectID.Read(context);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StandardReferenceTypeHandler0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StandardReferenceTypeHandler0.cs
new file mode 100644
index 0000000..bfbef31
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StandardReferenceTypeHandler0.cs
@@ -0,0 +1,58 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public class StandardReferenceTypeHandler0 : StandardReferenceTypeHandler
+	{
+		protected override IMarshallingInfo EnsureFieldList(IMarshallingInfo context)
+		{
+			return new _IMarshallingInfo_16(context);
+		}
+
+		private sealed class _IMarshallingInfo_16 : IMarshallingInfo
+		{
+			public _IMarshallingInfo_16(IMarshallingInfo context)
+			{
+				this.context = context;
+			}
+
+			public void DeclaredAspectCount(int count)
+			{
+				context.DeclaredAspectCount(count);
+			}
+
+			public int DeclaredAspectCount()
+			{
+				return context.DeclaredAspectCount();
+			}
+
+			public bool IsNull(int fieldIndex)
+			{
+				return false;
+			}
+
+			public ClassMetadata ClassMetadata()
+			{
+				return context.ClassMetadata();
+			}
+
+			public IReadBuffer Buffer()
+			{
+				return context.Buffer();
+			}
+
+			public void BeginSlot()
+			{
+				context.BeginSlot();
+			}
+
+			private readonly IMarshallingInfo context;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StringBasedValueTypeHandlerBase.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StringBasedValueTypeHandlerBase.cs
new file mode 100644
index 0000000..5670502
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StringBasedValueTypeHandlerBase.cs
@@ -0,0 +1,88 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	public abstract class StringBasedValueTypeHandlerBase : IValueTypeHandler, IBuiltinTypeHandler
+		, IVariableLengthTypeHandler, IQueryableTypeHandler, IComparable4
+	{
+		public readonly Type _clazz;
+
+		private IReflectClass _classReflector;
+
+		public StringBasedValueTypeHandlerBase(Type clazz)
+		{
+			_clazz = clazz;
+		}
+
+		public virtual void Defragment(IDefragmentContext context)
+		{
+			StringHandler(context).Defragment(context);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Delete(IDeleteContext context)
+		{
+			StringHandler(context).Delete(context);
+		}
+
+		public virtual object Read(IReadContext context)
+		{
+			object read = StringHandler(context).Read(context);
+			if (null == read)
+			{
+				return null;
+			}
+			return ConvertString((string)read);
+		}
+
+		public virtual void Write(IWriteContext context, object obj)
+		{
+			StringHandler(context).Write(context, ConvertObject((object)obj));
+		}
+
+		private Db4objects.Db4o.Internal.Handlers.StringHandler StringHandler(IContext context
+			)
+		{
+			return Handlers(context)._stringHandler;
+		}
+
+		private HandlerRegistry Handlers(IContext context)
+		{
+			return ((IInternalObjectContainer)context.ObjectContainer()).Handlers;
+		}
+
+		public virtual IPreparedComparison PrepareComparison(IContext context, object obj
+			)
+		{
+			return StringHandler(context).PrepareComparison(context, obj);
+		}
+
+		public virtual IReflectClass ClassReflector()
+		{
+			return _classReflector;
+		}
+
+		public virtual void RegisterReflector(IReflector reflector)
+		{
+			_classReflector = reflector.ForClass(_clazz);
+		}
+
+		public virtual bool DescendsIntoMembers()
+		{
+			return false;
+		}
+
+		protected abstract string ConvertObject(object obj);
+
+		protected abstract object ConvertString(string str);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StringBufferHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StringBufferHandler.cs
new file mode 100644
index 0000000..862589b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StringBufferHandler.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Text;
+using Db4objects.Db4o.Internal.Handlers;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	public sealed class StringBufferHandler : StringBasedValueTypeHandlerBase
+	{
+		public StringBufferHandler() : base(typeof(StringBuilder))
+		{
+		}
+
+		protected override string ConvertObject(object obj)
+		{
+			return ((StringBuilder)obj).ToString();
+		}
+
+		protected override object ConvertString(string str)
+		{
+			return new StringBuilder(str);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StringHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StringHandler.cs
new file mode 100644
index 0000000..f539d1e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StringHandler.cs
@@ -0,0 +1,299 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public class StringHandler : IValueTypeHandler, IIndexableTypeHandler, IBuiltinTypeHandler
+		, IVariableLengthTypeHandler, IQueryableTypeHandler
+	{
+		private IReflectClass _classReflector;
+
+		public virtual IReflectClass ClassReflector()
+		{
+			return _classReflector;
+		}
+
+		public virtual void Delete(IDeleteContext context)
+		{
+		}
+
+		// do nothing, we are in a slot indirection anyway, the 
+		// buffer position does not need to be changed.
+		internal virtual byte GetIdentifier()
+		{
+			return Const4.Yapstring;
+		}
+
+		public virtual bool DescendsIntoMembers()
+		{
+			return false;
+		}
+
+		public object IndexEntryToObject(IContext context, object indexEntry)
+		{
+			if (indexEntry is Slot)
+			{
+				Slot slot = (Slot)indexEntry;
+				indexEntry = context.Transaction().Container().DecryptedBufferByAddress(slot.Address
+					(), slot.Length());
+			}
+			return ReadStringNoDebug(context, (IReadBuffer)indexEntry);
+		}
+
+		/// <summary>This readIndexEntry method reads from the parent slot.</summary>
+		/// <remarks>This readIndexEntry method reads from the parent slot.</remarks>
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual object ReadIndexEntryFromObjectSlot(MarshallerFamily mf, StatefulBuffer
+			 buffer)
+		{
+			int payLoadOffSet = buffer.ReadInt();
+			int length = buffer.ReadInt();
+			if (payLoadOffSet == 0)
+			{
+				return null;
+			}
+			return buffer.ReadPayloadWriter(payLoadOffSet, length);
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual object ReadIndexEntry(IObjectIdContext context)
+		{
+			int payLoadOffSet = context.ReadInt();
+			int length = context.ReadInt();
+			if (payLoadOffSet == 0)
+			{
+				return null;
+			}
+			return ((StatefulBuffer)context.Buffer()).ReadPayloadWriter(payLoadOffSet, length
+				);
+		}
+
+		/// <summary>This readIndexEntry method reads from the actual index in the file.</summary>
+		/// <remarks>This readIndexEntry method reads from the actual index in the file.</remarks>
+		public virtual object ReadIndexEntry(IContext context, ByteArrayBuffer reader)
+		{
+			Slot s = new Slot(reader.ReadInt(), reader.ReadInt());
+			if (IsInvalidSlot(s))
+			{
+				return null;
+			}
+			return s;
+		}
+
+		private bool IsInvalidSlot(Slot slot)
+		{
+			return slot.IsNull();
+		}
+
+		public virtual void WriteIndexEntry(IContext context, ByteArrayBuffer writer, object
+			 entry)
+		{
+			if (entry == null)
+			{
+				writer.WriteInt(0);
+				writer.WriteInt(0);
+				return;
+			}
+			if (entry is StatefulBuffer)
+			{
+				StatefulBuffer entryAsWriter = (StatefulBuffer)entry;
+				writer.WriteInt(entryAsWriter.GetAddress());
+				writer.WriteInt(entryAsWriter.Length());
+				return;
+			}
+			if (entry is Slot)
+			{
+				Slot s = (Slot)entry;
+				writer.WriteInt(s.Address());
+				writer.WriteInt(s.Length());
+				return;
+			}
+			throw new ArgumentException();
+		}
+
+		public void WriteShort(Transaction trans, string str, ByteArrayBuffer buffer)
+		{
+			StringIo(trans.Container()).WriteLengthAndString(buffer, str);
+		}
+
+		internal virtual ByteArrayBuffer Val(object obj, IContext context)
+		{
+			if (obj is ByteArrayBuffer)
+			{
+				return (ByteArrayBuffer)obj;
+			}
+			ObjectContainerBase oc = context.Transaction().Container();
+			if (obj is string)
+			{
+				return WriteToBuffer((IInternalObjectContainer)oc, (string)obj);
+			}
+			if (obj is Slot)
+			{
+				Slot s = (Slot)obj;
+				return oc.DecryptedBufferByAddress(s.Address(), s.Length());
+			}
+			return null;
+		}
+
+		/// <summary>
+		/// returns: -x for left is greater and +x for right is greater
+		/// FIXME: The returned value is the wrong way around.
+		/// </summary>
+		/// <remarks>
+		/// returns: -x for left is greater and +x for right is greater
+		/// FIXME: The returned value is the wrong way around.
+		/// TODO: You will need collators here for different languages.
+		/// </remarks>
+		internal int Compare(ByteArrayBuffer a_compare, ByteArrayBuffer a_with)
+		{
+			if (a_compare == null)
+			{
+				if (a_with == null)
+				{
+					return 0;
+				}
+				return -1;
+			}
+			if (a_with == null)
+			{
+				return 1;
+			}
+			return Compare(a_compare._buffer, a_with._buffer);
+		}
+
+		public static int Compare(byte[] compare, byte[] with)
+		{
+			int min = compare.Length < with.Length ? compare.Length : with.Length;
+			int start = Const4.IntLength;
+			for (int i = start; i < min; i++)
+			{
+				if (compare[i] != with[i])
+				{
+					return compare[i] - with[i];
+				}
+			}
+			return compare.Length - with.Length;
+		}
+
+		public virtual void DefragIndexEntry(DefragmentContextImpl context)
+		{
+			context.CopyAddress();
+			// length
+			context.IncrementIntSize();
+		}
+
+		public virtual void Write(IWriteContext context, object obj)
+		{
+			InternalWrite((IInternalObjectContainer)context.ObjectContainer(), context, (string
+				)obj);
+		}
+
+		protected static void InternalWrite(IInternalObjectContainer objectContainer, IWriteBuffer
+			 buffer, string str)
+		{
+			StringIo(objectContainer).WriteLengthAndString(buffer, str);
+		}
+
+		public static ByteArrayBuffer WriteToBuffer(IInternalObjectContainer container, string
+			 str)
+		{
+			ByteArrayBuffer buffer = new ByteArrayBuffer(StringIo(container).Length(str));
+			InternalWrite(container, buffer, str);
+			return buffer;
+		}
+
+		protected static LatinStringIO StringIo(IContext context)
+		{
+			return StringIo((IInternalObjectContainer)context.ObjectContainer());
+		}
+
+		protected static LatinStringIO StringIo(IInternalObjectContainer objectContainer)
+		{
+			return objectContainer.Container.StringIO();
+		}
+
+		public static string ReadString(IContext context, IReadBuffer buffer)
+		{
+			string str = ReadStringNoDebug(context, buffer);
+			return str;
+		}
+
+		public static string ReadStringNoDebug(IContext context, IReadBuffer buffer)
+		{
+			return Intern(context, StringIo(context).ReadLengthAndString(buffer));
+		}
+
+		protected static string Intern(IContext context, string str)
+		{
+			if (context.ObjectContainer().Ext().Configure().InternStrings())
+			{
+				return string.Intern(str);
+			}
+			return str;
+		}
+
+		public virtual object Read(IReadContext context)
+		{
+			return ReadString(context, context);
+		}
+
+		public virtual void Defragment(IDefragmentContext context)
+		{
+			context.IncrementOffset(LinkLength());
+		}
+
+		public virtual IPreparedComparison PrepareComparison(IContext context, object obj
+			)
+		{
+			ByteArrayBuffer sourceBuffer = Val(obj, context);
+			return new _IPreparedComparison_229(this, context, sourceBuffer);
+		}
+
+		private sealed class _IPreparedComparison_229 : IPreparedComparison
+		{
+			public _IPreparedComparison_229(StringHandler _enclosing, IContext context, ByteArrayBuffer
+				 sourceBuffer)
+			{
+				this._enclosing = _enclosing;
+				this.context = context;
+				this.sourceBuffer = sourceBuffer;
+			}
+
+			public int CompareTo(object target)
+			{
+				ByteArrayBuffer targetBuffer = this._enclosing.Val(target, context);
+				return this._enclosing.Compare(sourceBuffer, targetBuffer);
+			}
+
+			private readonly StringHandler _enclosing;
+
+			private readonly IContext context;
+
+			private readonly ByteArrayBuffer sourceBuffer;
+		}
+
+		public virtual int LinkLength()
+		{
+			return Const4.IndirectionLength;
+		}
+
+		public virtual void RegisterReflector(IReflector reflector)
+		{
+			_classReflector = reflector.ForClass(typeof(string));
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StringHandler0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StringHandler0.cs
new file mode 100644
index 0000000..36ea14a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/StringHandler0.cs
@@ -0,0 +1,72 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.IO;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public class StringHandler0 : StringHandler
+	{
+		public override object Read(IReadContext context)
+		{
+			ByteArrayBuffer buffer = (ByteArrayBuffer)((IInternalReadContext)context).ReadIndirectedBuffer
+				();
+			if (buffer == null)
+			{
+				return null;
+			}
+			return ReadString(context, buffer);
+		}
+
+		public override void Delete(IDeleteContext context)
+		{
+			context.DefragmentRecommended();
+		}
+
+		public override void Defragment(IDefragmentContext context)
+		{
+			int sourceAddress = context.SourceBuffer().ReadInt();
+			int length = context.SourceBuffer().ReadInt();
+			if (sourceAddress == 0 && length == 0)
+			{
+				context.TargetBuffer().WriteInt(0);
+				context.TargetBuffer().WriteInt(0);
+				return;
+			}
+			int targetAddress = 0;
+			try
+			{
+				targetAddress = context.CopySlotToNewMapped(sourceAddress, length);
+			}
+			catch (IOException exc)
+			{
+				throw new Db4oIOException(exc);
+			}
+			context.TargetBuffer().WriteInt(targetAddress);
+			context.TargetBuffer().WriteInt(length);
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override object ReadIndexEntryFromObjectSlot(MarshallerFamily mf, StatefulBuffer
+			 buffer)
+		{
+			return buffer.Container().ReadWriterByAddress(buffer.Transaction(), buffer.ReadInt
+				(), buffer.ReadInt());
+		}
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override object ReadIndexEntry(IObjectIdContext context)
+		{
+			return context.Transaction().Container().ReadWriterByAddress(context.Transaction(
+				), context.ReadInt(), context.ReadInt());
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/TypeHandlerPredicatePair.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/TypeHandlerPredicatePair.cs
new file mode 100644
index 0000000..41e5b31
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/TypeHandlerPredicatePair.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	/// <exclude></exclude>
+	public class TypeHandlerPredicatePair
+	{
+		public readonly ITypeHandlerPredicate _predicate;
+
+		public readonly ITypeHandler4 _typeHandler;
+
+		public TypeHandlerPredicatePair(ITypeHandlerPredicate predicate, ITypeHandler4 typeHandler
+			)
+		{
+			_predicate = predicate;
+			_typeHandler = typeHandler;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Versions/OpenTypeHandler0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Versions/OpenTypeHandler0.cs
new file mode 100644
index 0000000..8b25096
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Versions/OpenTypeHandler0.cs
@@ -0,0 +1,116 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.IO;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers.Versions;
+using Db4objects.Db4o.Internal.Mapping;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Handlers.Versions
+{
+	/// <exclude></exclude>
+	public class OpenTypeHandler0 : OpenTypeHandler2
+	{
+		public OpenTypeHandler0(ObjectContainerBase container) : base(container)
+		{
+		}
+
+		public override object Read(IReadContext context)
+		{
+			return context.ReadObject();
+		}
+
+		public override ITypeHandler4 ReadCandidateHandler(QueryingReadContext context)
+		{
+			int id = 0;
+			int offset = context.Offset();
+			try
+			{
+				id = context.ReadInt();
+			}
+			catch (Exception)
+			{
+			}
+			context.Seek(offset);
+			if (id != 0)
+			{
+				StatefulBuffer reader = context.Container().ReadStatefulBufferById(context.Transaction
+					(), id);
+				if (reader != null)
+				{
+					ObjectHeader oh = new ObjectHeader(context.Container(), reader);
+					try
+					{
+						if (oh.ClassMetadata() != null)
+						{
+							context.Buffer(reader);
+							return oh.ClassMetadata().SeekCandidateHandler(context);
+						}
+					}
+					catch (Exception e)
+					{
+					}
+				}
+			}
+			// TODO: Check Exception Types
+			// Errors typically occur, if classes don't match
+			return null;
+		}
+
+		public override ObjectID ReadObjectID(IInternalReadContext context)
+		{
+			int id = context.ReadInt();
+			return id == 0 ? ObjectID.IsNull : new ObjectID(id);
+		}
+
+		public override void Defragment(IDefragmentContext context)
+		{
+			int sourceId = context.SourceBuffer().ReadInt();
+			if (sourceId == 0)
+			{
+				context.TargetBuffer().WriteInt(0);
+				return;
+			}
+			int targetId = 0;
+			try
+			{
+				targetId = context.MappedID(sourceId);
+			}
+			catch (MappingNotFoundException)
+			{
+				targetId = CopyDependentSlot(context, sourceId);
+			}
+			context.TargetBuffer().WriteInt(targetId);
+		}
+
+		private int CopyDependentSlot(IDefragmentContext context, int sourceId)
+		{
+			try
+			{
+				ByteArrayBuffer sourceBuffer = context.SourceBufferById(sourceId);
+				Slot targetPayloadSlot = context.AllocateTargetSlot(sourceBuffer.Length());
+				int targetId = context.Services().TargetNewId();
+				context.Services().MapIDs(sourceId, targetId, false);
+				context.Services().Mapping().MapId(targetId, targetPayloadSlot);
+				DefragmentContextImpl payloadContext = new DefragmentContextImpl(sourceBuffer, (DefragmentContextImpl
+					)context);
+				int clazzId = payloadContext.CopyIDReturnOriginalID();
+				ITypeHandler4 payloadHandler = payloadContext.TypeHandlerForId(clazzId);
+				ITypeHandler4 versionedPayloadHandler = HandlerRegistry.CorrectHandlerVersion(payloadContext
+					, payloadHandler);
+				versionedPayloadHandler.Defragment(payloadContext);
+				payloadContext.WriteToTarget(targetPayloadSlot.Address());
+				return targetId;
+			}
+			catch (IOException ioexc)
+			{
+				throw new Db4oIOException(ioexc);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Versions/OpenTypeHandler2.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Versions/OpenTypeHandler2.cs
new file mode 100644
index 0000000..cc5234e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Versions/OpenTypeHandler2.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers.Versions;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Handlers.Versions
+{
+	/// <exclude></exclude>
+	public class OpenTypeHandler2 : OpenTypeHandler7
+	{
+		public OpenTypeHandler2(ObjectContainerBase container) : base(container)
+		{
+		}
+
+		protected override void SeekSecondaryOffset(IReadBuffer buffer, ITypeHandler4 typeHandler
+			)
+		{
+			if (Handlers4.HandlesPrimitiveArray(typeHandler))
+			{
+				buffer.Seek(buffer.ReadInt());
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Versions/OpenTypeHandler7.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Versions/OpenTypeHandler7.cs
new file mode 100644
index 0000000..b4fe95f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers/Versions/OpenTypeHandler7.cs
@@ -0,0 +1,136 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Handlers.Versions
+{
+	public class OpenTypeHandler7 : OpenTypeHandler
+	{
+		public OpenTypeHandler7(ObjectContainerBase container) : base(container)
+		{
+		}
+
+		public override object Read(IReadContext readContext)
+		{
+			IInternalReadContext context = (IInternalReadContext)readContext;
+			int payloadOffset = context.ReadInt();
+			if (payloadOffset == 0)
+			{
+				context.NotifyNullReferenceSkipped();
+				return null;
+			}
+			int savedOffSet = context.Offset();
+			try
+			{
+				ITypeHandler4 typeHandler = ReadTypeHandler(context, payloadOffset);
+				if (typeHandler == null)
+				{
+					return null;
+				}
+				if (IsPlainObject(typeHandler))
+				{
+					return ReadPlainObject(readContext);
+				}
+				SeekSecondaryOffset(context, typeHandler);
+				return context.ReadAtCurrentSeekPosition(typeHandler);
+			}
+			finally
+			{
+				context.Seek(savedOffSet);
+			}
+		}
+
+		public override void Defragment(IDefragmentContext context)
+		{
+			int payLoadOffSet = context.ReadInt();
+			if (payLoadOffSet == 0)
+			{
+				return;
+			}
+			int savedOffSet = context.Offset();
+			context.Seek(payLoadOffSet);
+			int classMetadataId = context.CopyIDReturnOriginalID();
+			ITypeHandler4 typeHandler = CorrectTypeHandlerVersionFor(context, classMetadataId
+				);
+			if (typeHandler != null)
+			{
+				if (IsPlainObject(typeHandler))
+				{
+					context.CopySlotlessID();
+				}
+				else
+				{
+					SeekSecondaryOffset(context, typeHandler);
+					context.Defragment(typeHandler);
+				}
+			}
+			context.Seek(savedOffSet);
+		}
+
+		private object ReadPlainObject(IReadContext context)
+		{
+			int id = context.ReadInt();
+			Transaction transaction = context.Transaction();
+			object obj = transaction.ObjectForIdFromCache(id);
+			if (obj != null)
+			{
+				return obj;
+			}
+			obj = new object();
+			AddReference(context, obj, id);
+			return obj;
+		}
+
+		private void AddReference(IContext context, object obj, int id)
+		{
+			Transaction transaction = context.Transaction();
+			ObjectReference @ref = new _ObjectReference_74(id);
+			@ref.ClassMetadata(transaction.Container().ClassMetadataForID(Handlers4.UntypedId
+				));
+			@ref.SetObjectWeak(transaction.Container(), obj);
+			transaction.AddNewReference(@ref);
+		}
+
+		private sealed class _ObjectReference_74 : ObjectReference
+		{
+			public _ObjectReference_74(int baseArg1) : base(baseArg1)
+			{
+				this._firstUpdate = true;
+			}
+
+			internal bool _firstUpdate;
+
+			public override void WriteUpdate(Transaction transaction, IUpdateDepth updatedepth
+				)
+			{
+				if (!this._firstUpdate)
+				{
+					base.WriteUpdate(transaction, updatedepth);
+					return;
+				}
+				this._firstUpdate = false;
+				ObjectContainerBase container = transaction.Container();
+				this.SetStateClean();
+				MarshallingContext context = new MarshallingContext(transaction, this, updatedepth
+					, false);
+				Handlers4.Write(this.ClassMetadata().TypeHandler(), context, this.GetObject());
+				int length = this.Container().BlockConverter().BlockAlignedBytes(context.MarshalledLength
+					());
+				Slot slot = context.AllocateNewSlot(length);
+				Pointer4 pointer = new Pointer4(this.GetID(), slot);
+				ByteArrayBuffer buffer = context.ToWriteBuffer(pointer);
+				container.WriteUpdate(transaction, pointer, this.ClassMetadata(), ArrayType.None, 
+					buffer);
+				if (this.IsActive())
+				{
+					this.SetStateClean();
+				}
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers4.cs
new file mode 100644
index 0000000..dff1eda
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Handlers4.cs
@@ -0,0 +1,402 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Handlers.Array;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class Handlers4
+	{
+		public const int IntId = 1;
+
+		public const int LongId = 2;
+
+		public const int FloatId = 3;
+
+		public const int BooleanId = 4;
+
+		public const int DoubleId = 5;
+
+		public const int ByteId = 6;
+
+		public const int CharId = 7;
+
+		public const int ShortId = 8;
+
+		public const int StringId = 9;
+
+		public const int DateId = 10;
+
+		public const int UntypedId = 11;
+
+		public const int AnyArrayId = 12;
+
+		public const int AnyArrayNId = 13;
+
+		public static bool IsQueryLeaf(ITypeHandler4 handler)
+		{
+			ITypeHandler4 baseTypeHandler = BaseTypeHandler(handler);
+			if (!(baseTypeHandler is IQueryableTypeHandler))
+			{
+				return false;
+			}
+			if (baseTypeHandler is ArrayHandler)
+			{
+				return false;
+			}
+			return baseTypeHandler is IValueTypeHandler;
+		}
+
+		public static bool HandlesArray(ITypeHandler4 handler)
+		{
+			return handler is ArrayHandler;
+		}
+
+		public static bool HandlesMultidimensionalArray(ITypeHandler4 handler)
+		{
+			return handler is MultidimensionalArrayHandler;
+		}
+
+		public static bool HandlesClass(ITypeHandler4 handler)
+		{
+			return BaseTypeHandler(handler) is ICascadingTypeHandler;
+		}
+
+		public static IReflectClass PrimitiveClassReflector(ITypeHandler4 handler, IReflector
+			 reflector)
+		{
+			ITypeHandler4 baseTypeHandler = BaseTypeHandler(handler);
+			if (baseTypeHandler is PrimitiveHandler)
+			{
+				return ((PrimitiveHandler)baseTypeHandler).PrimitiveClassReflector();
+			}
+			return null;
+		}
+
+		public static ITypeHandler4 BaseTypeHandler(ITypeHandler4 handler)
+		{
+			if (handler is ArrayHandler)
+			{
+				return ((ArrayHandler)handler).DelegateTypeHandler();
+			}
+			if (handler is PrimitiveTypeMetadata)
+			{
+				return ((PrimitiveTypeMetadata)handler).TypeHandler();
+			}
+			return handler;
+		}
+
+		public static IReflectClass BaseType(IReflectClass clazz)
+		{
+			if (clazz == null)
+			{
+				return null;
+			}
+			if (clazz.IsArray())
+			{
+				return BaseType(clazz.GetComponentType());
+			}
+			return clazz;
+		}
+
+		public static bool IsClassAware(ITypeHandler4 typeHandler)
+		{
+			return typeHandler is IBuiltinTypeHandler || typeHandler is StandardReferenceTypeHandler;
+		}
+
+		public static int CalculateLinkLength(ITypeHandler4 handler)
+		{
+			if (handler == null)
+			{
+				throw new ArgumentNullException();
+			}
+			if (handler is ILinkLengthAware)
+			{
+				return ((ILinkLengthAware)handler).LinkLength();
+			}
+			if (handler is IReferenceTypeHandler)
+			{
+				return Const4.IdLength;
+			}
+			if (handler is IVariableLengthTypeHandler)
+			{
+				return Const4.IndirectionLength;
+			}
+			// TODO: For custom handlers there will have to be a way 
+			//       to calculate the length in the slot.
+			//        Options:
+			//        (1) Remember when the first object is marshalled.
+			//        (2) Add a #defaultValue() method to TypeHandler4,
+			//            marshall the default value and check.
+			//        (3) Add a way to test the custom handler when it
+			//            is installed and remember the length there. 
+			throw new NotImplementedException("Unexpected typehandler: " + handler);
+		}
+
+		public static bool HoldsValueType(ITypeHandler4 handler)
+		{
+			return IsValueType(BaseTypeHandler(handler));
+		}
+
+		public static bool IsValueType(ITypeHandler4 handler)
+		{
+			return !(handler is IReferenceTypeHandler);
+		}
+
+		public static bool IsCascading(ITypeHandler4 handler)
+		{
+			return handler is ICascadingTypeHandler;
+		}
+
+		public static bool IsUntyped(ITypeHandler4 handler)
+		{
+			return handler is OpenTypeHandler;
+		}
+
+		public static bool IsVariableLength(ITypeHandler4 handler)
+		{
+			return handler is IVariableLengthTypeHandler;
+		}
+
+		public static IFieldAwareTypeHandler FieldAwareTypeHandler(ITypeHandler4 typeHandler
+			)
+		{
+			if (typeHandler is IFieldAwareTypeHandler)
+			{
+				return (IFieldAwareTypeHandler)typeHandler;
+			}
+			return NullFieldAwareTypeHandler.Instance;
+		}
+
+		public static void CollectIDs(QueryingReadContext context, ITypeHandler4 typeHandler
+			)
+		{
+			if (typeHandler is ICascadingTypeHandler)
+			{
+				((ICascadingTypeHandler)typeHandler).CollectIDs(context);
+			}
+		}
+
+		public static bool UseDedicatedSlot(IContext context, ITypeHandler4 handler)
+		{
+			if (IsValueType(handler))
+			{
+				return false;
+			}
+			if (IsUntyped(handler))
+			{
+				return false;
+			}
+			return true;
+		}
+
+		public static ITypeHandler4 ArrayElementHandler(ITypeHandler4 handler, QueryingReadContext
+			 queryingReadContext)
+		{
+			if (!(handler is ICascadingTypeHandler))
+			{
+				return null;
+			}
+			ICascadingTypeHandler cascadingHandler = (ICascadingTypeHandler)HandlerRegistry.CorrectHandlerVersion
+				(queryingReadContext, handler);
+			return HandlerRegistry.CorrectHandlerVersion(queryingReadContext, cascadingHandler
+				.ReadCandidateHandler(queryingReadContext));
+		}
+
+		public static object NullRepresentationInUntypedArrays(ITypeHandler4 handler)
+		{
+			if (handler is PrimitiveHandler)
+			{
+				return ((PrimitiveHandler)handler).NullRepresentationInUntypedArrays();
+			}
+			return null;
+		}
+
+		public static bool HandleAsObject(ITypeHandler4 typeHandler)
+		{
+			if (IsValueType(typeHandler))
+			{
+				return false;
+			}
+			if (IsUntyped(typeHandler))
+			{
+				return false;
+			}
+			return true;
+		}
+
+		public static void CascadeActivation(IActivationContext context, ITypeHandler4 handler
+			)
+		{
+			if (!(handler is ICascadingTypeHandler))
+			{
+				return;
+			}
+			((ICascadingTypeHandler)handler).CascadeActivation(context);
+		}
+
+		public static bool HandlesPrimitiveArray(ITypeHandler4 typeHandler)
+		{
+			return typeHandler is ArrayHandler;
+		}
+
+		//	    	&& isPrimitive(((ArrayHandler)typeHandler).delegateTypeHandler());
+		public static bool HasClassIndex(ITypeHandler4 typeHandler)
+		{
+			if (typeHandler is StandardReferenceTypeHandler)
+			{
+				return ((StandardReferenceTypeHandler)typeHandler).ClassMetadata().HasClassIndex(
+					);
+			}
+			return false;
+		}
+
+		public static bool CanLoadFieldByIndex(ITypeHandler4 handler)
+		{
+			if (handler is IQueryableTypeHandler)
+			{
+				return !((IQueryableTypeHandler)handler).DescendsIntoMembers();
+			}
+			return true;
+		}
+
+		public static object WrapWithTransactionContext(Transaction transaction, object value
+			, ITypeHandler4 handler)
+		{
+			if (IsValueType(handler))
+			{
+				return value;
+			}
+			return transaction.Wrap(value);
+		}
+
+		public static void CollectIdsInternal(CollectIdContext context, ITypeHandler4 handler
+			, int linkLength, bool doWithSlotIndirection)
+		{
+			if (!(IsCascading(handler)))
+			{
+				IReadBuffer buffer = context.Buffer();
+				buffer.Seek(buffer.Offset() + linkLength);
+				return;
+			}
+			if (handler is StandardReferenceTypeHandler)
+			{
+				context.AddId();
+				return;
+			}
+			LocalObjectContainer container = (LocalObjectContainer)context.Container();
+			SlotFormat slotFormat = context.SlotFormat();
+			if (HandleAsObject(handler))
+			{
+				// TODO: Code is similar to QCandidate.readArrayCandidates. Try to refactor to one place.
+				int collectionID = context.ReadInt();
+				ByteArrayBuffer collectionBuffer = container.ReadBufferById(context.Transaction()
+					, collectionID);
+				ObjectHeader objectHeader = new ObjectHeader(container, collectionBuffer);
+				QueryingReadContext subContext = new QueryingReadContext(context.Transaction(), context
+					.HandlerVersion(), collectionBuffer, collectionID, context.Collector());
+				objectHeader.ClassMetadata().CollectIDs(subContext);
+				return;
+			}
+			QueryingReadContext queryingReadContext = new QueryingReadContext(context.Transaction
+				(), context.HandlerVersion(), context.Buffer(), 0, context.Collector());
+			IClosure4 collectIDsFromQueryingContext = new _IClosure4_263(handler, queryingReadContext
+				);
+			if (doWithSlotIndirection)
+			{
+				slotFormat.DoWithSlotIndirection(queryingReadContext, handler, collectIDsFromQueryingContext
+					);
+			}
+			else
+			{
+				collectIDsFromQueryingContext.Run();
+			}
+		}
+
+		private sealed class _IClosure4_263 : IClosure4
+		{
+			public _IClosure4_263(ITypeHandler4 handler, QueryingReadContext queryingReadContext
+				)
+			{
+				this.handler = handler;
+				this.queryingReadContext = queryingReadContext;
+			}
+
+			public object Run()
+			{
+				((ICascadingTypeHandler)handler).CollectIDs(queryingReadContext);
+				return null;
+			}
+
+			private readonly ITypeHandler4 handler;
+
+			private readonly QueryingReadContext queryingReadContext;
+		}
+
+		public static bool IsIndirectedIndexed(ITypeHandler4 handler)
+		{
+			return IsValueType(handler) && (handler is IVariableLengthTypeHandler) && (handler
+				 is IIndexableTypeHandler);
+		}
+
+		public static IPreparedComparison PrepareComparisonFor(ITypeHandler4 handler, IContext
+			 context, object obj)
+		{
+			if (!(handler is IComparable4))
+			{
+				return null;
+			}
+			return ((IComparable4)handler).PrepareComparison(context, obj);
+		}
+
+		public static IReflectClass PrimitiveClassReflector(ClassMetadata classMetadata, 
+			IReflector reflector)
+		{
+			if (classMetadata is PrimitiveTypeMetadata)
+			{
+				return PrimitiveClassReflector(((PrimitiveTypeMetadata)classMetadata).TypeHandler
+					(), reflector);
+			}
+			return null;
+		}
+
+		public static void Activate(UnmarshallingContext context, ITypeHandler4 handler)
+		{
+			if (handler is IReferenceTypeHandler)
+			{
+				((IReferenceTypeHandler)handler).Activate(context);
+			}
+		}
+
+		public static void Write(ITypeHandler4 handler, IWriteContext context, object obj
+			)
+		{
+			handler.Write(context, obj);
+		}
+
+		public static object ReadValueType(IReadContext context, ITypeHandler4 handler)
+		{
+			return ((IValueTypeHandler)handler).Read(context);
+		}
+
+		public static bool IsStandaloneTypeHandler(ITypeHandler4 customTypeHandler)
+		{
+			return IsValueType(customTypeHandler) || customTypeHandler is OpenTypeHandler;
+		}
+
+		public static ClassMetadata ErasedFieldType(ObjectContainerBase container, IReflectClass
+			 fieldType)
+		{
+			return fieldType.IsInterface() ? container.ClassMetadataForID(UntypedId) : container
+				.ProduceClassMetadata(BaseType(fieldType));
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/HardObjectReference.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/HardObjectReference.cs
new file mode 100644
index 0000000..8fe9a7c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/HardObjectReference.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class HardObjectReference
+	{
+		public static readonly Db4objects.Db4o.Internal.HardObjectReference Invalid = new 
+			Db4objects.Db4o.Internal.HardObjectReference(null, null);
+
+		public readonly ObjectReference _reference;
+
+		public readonly object _object;
+
+		public HardObjectReference(ObjectReference @ref, object obj)
+		{
+			_reference = @ref;
+			_object = obj;
+		}
+
+		public static Db4objects.Db4o.Internal.HardObjectReference PeekPersisted(Transaction
+			 trans, int id, int depth)
+		{
+			object obj = trans.Container().PeekPersisted(trans, id, ActivationDepthProvider(trans
+				).ActivationDepth(depth, ActivationMode.Peek), true);
+			if (obj == null)
+			{
+				return null;
+			}
+			ObjectReference @ref = trans.ReferenceForId(id);
+			return new Db4objects.Db4o.Internal.HardObjectReference(@ref, obj);
+		}
+
+		private static IActivationDepthProvider ActivationDepthProvider(Transaction trans
+			)
+		{
+			return trans.Container().ActivationDepthProvider();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IBlockConverter.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IBlockConverter.cs
new file mode 100644
index 0000000..0360d37
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IBlockConverter.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public interface IBlockConverter
+	{
+		int BytesToBlocks(long bytes);
+
+		int BlockAlignedBytes(int bytes);
+
+		int BlocksToBytes(int blocks);
+
+		Slot ToBlockedLength(Slot slot);
+
+		Slot ToNonBlockedLength(Slot slot);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IBuiltinTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IBuiltinTypeHandler.cs
new file mode 100644
index 0000000..b6eeb23
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IBuiltinTypeHandler.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public interface IBuiltinTypeHandler : ITypeHandler4
+	{
+		void RegisterReflector(IReflector reflector);
+
+		IReflectClass ClassReflector();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ICallbackInfoCollector.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ICallbackInfoCollector.cs
new file mode 100644
index 0000000..8f8d4e4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ICallbackInfoCollector.cs
@@ -0,0 +1,13 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal
+{
+	public interface ICallbackInfoCollector
+	{
+		void Added(int id);
+
+		void Updated(int id);
+
+		void Deleted(int id);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ICommittedCallbackDispatcher.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ICommittedCallbackDispatcher.cs
new file mode 100644
index 0000000..c5117f2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ICommittedCallbackDispatcher.cs
@@ -0,0 +1,14 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public interface ICommittedCallbackDispatcher
+	{
+		bool WillDispatchCommitted();
+
+		void DispatchCommitted(CallbackObjectInfoCollections committedInfo);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IComparable4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IComparable4.cs
new file mode 100644
index 0000000..510e81a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IComparable4.cs
@@ -0,0 +1,28 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <summary>Interface for comparison support in queries.</summary>
+	/// <remarks>Interface for comparison support in queries.</remarks>
+	public interface IComparable4
+	{
+		/// <summary>
+		/// creates a prepared comparison to compare multiple objects
+		/// against one single object.
+		/// </summary>
+		/// <remarks>
+		/// creates a prepared comparison to compare multiple objects
+		/// against one single object.
+		/// </remarks>
+		/// <param name="context">the context of the comparison</param>
+		/// <param name="obj">
+		/// the object that is to be compared
+		/// against multiple other objects
+		/// </param>
+		/// <returns>the prepared comparison</returns>
+		IPreparedComparison PrepareComparison(IContext context, object obj);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IDGenerator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IDGenerator.cs
new file mode 100644
index 0000000..43086a1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IDGenerator.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal
+{
+	public class IDGenerator
+	{
+		private int id = 0;
+
+		public virtual int Next()
+		{
+			id++;
+			if (id > 0)
+			{
+				return id;
+			}
+			id = 1;
+			return 1;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IDHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IDHandler.cs
new file mode 100644
index 0000000..b584dcb
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IDHandler.cs
@@ -0,0 +1,17 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class IDHandler : IntHandler
+	{
+		public override void DefragIndexEntry(DefragmentContextImpl context)
+		{
+			int sourceId = context.CopyIDReturnOriginalID(true);
+			context.CurrentParentSourceID(sourceId);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IDb4oTypeImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IDb4oTypeImpl.cs
new file mode 100644
index 0000000..2845cd6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IDb4oTypeImpl.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <summary>marker interface for special db4o datatypes</summary>
+	/// <exclude></exclude>
+	public interface IDb4oTypeImpl : ITransactionAware
+	{
+		object CreateDefault(Transaction trans);
+
+		bool HasClassIndex();
+
+		void SetObjectReference(ObjectReference @ref);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IDefragmentContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IDefragmentContext.cs
new file mode 100644
index 0000000..c4f799c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IDefragmentContext.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Defragment;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	public interface IDefragmentContext : IBufferContext, IMarshallingInfo, IHandlerVersionContext
+	{
+		ITypeHandler4 TypeHandlerForId(int id);
+
+		int CopyID();
+
+		int CopyIDReturnOriginalID();
+
+		int CopySlotlessID();
+
+		int CopyUnindexedID();
+
+		void Defragment(ITypeHandler4 handler);
+
+		int HandlerVersion();
+
+		void IncrementOffset(int length);
+
+		bool IsLegacyHandlerVersion();
+
+		int MappedID(int origID);
+
+		ByteArrayBuffer SourceBuffer();
+
+		ByteArrayBuffer TargetBuffer();
+
+		Slot AllocateTargetSlot(int length);
+
+		Slot AllocateMappedTargetSlot(int sourceAddress, int length);
+
+		/// <exception cref="System.IO.IOException"></exception>
+		int CopySlotToNewMapped(int sourceAddress, int length);
+
+		/// <exception cref="System.IO.IOException"></exception>
+		ByteArrayBuffer SourceBufferByAddress(int sourceAddress, int length);
+
+		/// <exception cref="System.IO.IOException"></exception>
+		ByteArrayBuffer SourceBufferById(int sourceId);
+
+		void TargetWriteBytes(int address, ByteArrayBuffer buffer);
+
+		IDefragmentServices Services();
+
+		ObjectContainerBase Container();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IEventDispatcher.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IEventDispatcher.cs
new file mode 100644
index 0000000..669dc9c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IEventDispatcher.cs
@@ -0,0 +1,13 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	public interface IEventDispatcher
+	{
+		bool Dispatch(Transaction trans, object obj, int eventID);
+
+		bool HasEventRegistered(int eventID);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IIndexable4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IIndexable4.cs
new file mode 100644
index 0000000..448879a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IIndexable4.cs
@@ -0,0 +1,17 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public interface IIndexable4 : IComparable4, ILinkLengthAware
+	{
+		object ReadIndexEntry(IContext context, ByteArrayBuffer reader);
+
+		void WriteIndexEntry(IContext context, ByteArrayBuffer writer, object obj);
+
+		void DefragIndexEntry(DefragmentContextImpl context);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IIndexableTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IIndexableTypeHandler.cs
new file mode 100644
index 0000000..177b090
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IIndexableTypeHandler.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public interface IIndexableTypeHandler : IIndexable4, ITypeHandler4
+	{
+		object IndexEntryToObject(IContext context, object indexEntry);
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		object ReadIndexEntryFromObjectSlot(MarshallerFamily mf, StatefulBuffer writer);
+
+		/// <exception cref="Db4objects.Db4o.CorruptionException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		object ReadIndexEntry(IObjectIdContext context);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IInternalObjectContainer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IInternalObjectContainer.cs
new file mode 100644
index 0000000..c90687f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IInternalObjectContainer.cs
@@ -0,0 +1,66 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Callbacks;
+using Db4objects.Db4o.Internal.Events;
+using Db4objects.Db4o.Internal.Query;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public partial interface IInternalObjectContainer : IExtObjectContainer
+	{
+		void Callbacks(ICallbacks cb);
+
+		ICallbacks Callbacks();
+
+		ObjectContainerBase Container
+		{
+			get;
+		}
+
+		Db4objects.Db4o.Internal.Transaction Transaction
+		{
+			get;
+		}
+
+		NativeQueryHandler GetNativeQueryHandler();
+
+		ClassMetadata ClassMetadataForReflectClass(IReflectClass reflectClass);
+
+		ClassMetadata ClassMetadataForName(string name);
+
+		ClassMetadata ClassMetadataForID(int id);
+
+		HandlerRegistry Handlers
+		{
+			get;
+		}
+
+		Config4Impl ConfigImpl
+		{
+			get;
+		}
+
+		object SyncExec(IClosure4 block);
+
+		int InstanceCount(ClassMetadata clazz, Db4objects.Db4o.Internal.Transaction trans
+			);
+
+		bool IsClient
+		{
+			get;
+		}
+
+		void StoreAll(Db4objects.Db4o.Internal.Transaction trans, IEnumerator objects);
+
+		IUpdateDepthProvider UpdateDepthProvider();
+
+		EventRegistryImpl NewEventRegistry();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ILinkLengthAware.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ILinkLengthAware.cs
new file mode 100644
index 0000000..2b88052
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ILinkLengthAware.cs
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal
+{
+	public interface ILinkLengthAware
+	{
+		int LinkLength();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IModificationAware.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IModificationAware.cs
new file mode 100644
index 0000000..f4ace76
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IModificationAware.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public interface IModificationAware
+	{
+		bool IsModified(object obj);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IO/BlockSizeImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IO/BlockSizeImpl.cs
new file mode 100644
index 0000000..7a963a8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IO/BlockSizeImpl.cs
@@ -0,0 +1,31 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.IO;
+
+namespace Db4objects.Db4o.Internal.IO
+{
+	public class BlockSizeImpl : IBlockSize
+	{
+		private readonly ListenerRegistry _listenerRegistry = ListenerRegistry.NewInstance
+			();
+
+		private int _value;
+
+		public virtual void Register(IListener4 listener)
+		{
+			_listenerRegistry.Register(listener);
+		}
+
+		public virtual void Set(int newValue)
+		{
+			_value = newValue;
+			_listenerRegistry.NotifyListeners(_value);
+		}
+
+		public virtual int Value()
+		{
+			return _value;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IObjectContainerSpec.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IObjectContainerSpec.cs
new file mode 100644
index 0000000..c33aa89
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IObjectContainerSpec.cs
@@ -0,0 +1,16 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <summary>Workaround to provide the Java 5 version with a hook to add ExtObjectContainer.
+	/// 	</summary>
+	/// <remarks>
+	/// Workaround to provide the Java 5 version with a hook to add ExtObjectContainer.
+	/// (Generic method declarations won't match ungenerified YapStreamBase implementations
+	/// otherwise and implementing it directly kills .NET conversion.)
+	/// </remarks>
+	/// <exclude></exclude>
+	public interface IObjectContainerSpec
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IPersistent.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IPersistent.cs
new file mode 100644
index 0000000..dba3a73
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IPersistent.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public interface IPersistent
+	{
+		byte GetIdentifier();
+
+		int OwnLength();
+
+		void ReadThis(Transaction trans, ByteArrayBuffer reader);
+
+		void WriteThis(Transaction trans, ByteArrayBuffer writer);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IQueryResultIteratorFactory.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IQueryResultIteratorFactory.cs
new file mode 100644
index 0000000..53b13a1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IQueryResultIteratorFactory.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Internal.Query.Result;
+
+namespace Db4objects.Db4o.Internal
+{
+	public interface IQueryResultIteratorFactory
+	{
+		IEnumerator NewInstance(AbstractQueryResult result);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IReadWriteBuffer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IReadWriteBuffer.cs
new file mode 100644
index 0000000..b4e17d5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IReadWriteBuffer.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public interface IReadWriteBuffer : IReadBuffer, IWriteBuffer
+	{
+		void IncrementOffset(int numBytes);
+
+		void IncrementIntSize();
+
+		int Length();
+
+		void ReadBegin(byte identifier);
+
+		void ReadEnd();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IReadWriteable.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IReadWriteable.cs
new file mode 100644
index 0000000..0aa671e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IReadWriteable.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public interface IReadWriteable : IReadable
+	{
+		void Write(ByteArrayBuffer buffer);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IReadable.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IReadable.cs
new file mode 100644
index 0000000..ed344a8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IReadable.cs
@@ -0,0 +1,14 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public interface IReadable
+	{
+		object Read(ByteArrayBuffer buffer);
+
+		int MarshalledLength();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IReadsObjectIds.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IReadsObjectIds.cs
new file mode 100644
index 0000000..f128471
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IReadsObjectIds.cs
@@ -0,0 +1,13 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public interface IReadsObjectIds
+	{
+		ObjectID ReadObjectID(IInternalReadContext context);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ISlotCopyHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ISlotCopyHandler.cs
new file mode 100644
index 0000000..01a0bc0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ISlotCopyHandler.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public interface ISlotCopyHandler
+	{
+		void ProcessCopy(DefragmentContextImpl context);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ITransactionParticipant.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ITransactionParticipant.cs
new file mode 100644
index 0000000..60569e3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ITransactionParticipant.cs
@@ -0,0 +1,16 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public interface ITransactionParticipant
+	{
+		void Commit(Transaction transaction);
+
+		void Rollback(Transaction transaction);
+
+		void Dispose(Transaction transaction);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IVersionedTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IVersionedTypeHandler.cs
new file mode 100644
index 0000000..dadb01f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IVersionedTypeHandler.cs
@@ -0,0 +1,13 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public interface IVersionedTypeHandler : ITypeHandler4, IDeepClone
+	{
+		ITypeHandler4 UnversionedTemplate();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Identifiable.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Identifiable.cs
new file mode 100644
index 0000000..b3e2aea
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Identifiable.cs
@@ -0,0 +1,107 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public abstract class Identifiable
+	{
+		protected int _id;
+
+		protected int _state = 2;
+
+		// DIRTY and ACTIVE
+		public bool BeginProcessing()
+		{
+			if (BitIsTrue(Const4.Processing))
+			{
+				return false;
+			}
+			BitTrue(Const4.Processing);
+			return true;
+		}
+
+		internal void BitFalse(int bitPos)
+		{
+			_state &= ~(1 << bitPos);
+		}
+
+		internal bool BitIsFalse(int bitPos)
+		{
+			return (_state | (1 << bitPos)) != _state;
+		}
+
+		internal bool BitIsTrue(int bitPos)
+		{
+			return (_state | (1 << bitPos)) == _state;
+		}
+
+		internal void BitTrue(int bitPos)
+		{
+			_state |= (1 << bitPos);
+		}
+
+		public virtual void EndProcessing()
+		{
+			BitFalse(Const4.Processing);
+		}
+
+		public virtual int GetID()
+		{
+			return _id;
+		}
+
+		public bool IsActive()
+		{
+			return BitIsTrue(Const4.Active);
+		}
+
+		public virtual bool IsDirty()
+		{
+			return BitIsTrue(Const4.Active) && (!BitIsTrue(Const4.Clean));
+		}
+
+		public bool IsNew()
+		{
+			return GetID() == 0;
+		}
+
+		public virtual void SetID(int id)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.PersistentbaseSetId.Log(id);
+			}
+			_id = id;
+		}
+
+		public void SetStateClean()
+		{
+			BitTrue(Const4.Active);
+			BitTrue(Const4.Clean);
+		}
+
+		public void SetStateDeactivated()
+		{
+			BitFalse(Const4.Active);
+		}
+
+		public virtual void SetStateDirty()
+		{
+			BitTrue(Const4.Active);
+			BitFalse(Const4.Clean);
+		}
+
+		public override int GetHashCode()
+		{
+			if (IsNew())
+			{
+				throw new InvalidOperationException();
+			}
+			return GetID();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/BTreeIdSystem.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/BTreeIdSystem.cs
new file mode 100644
index 0000000..5992b58
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/BTreeIdSystem.cs
@@ -0,0 +1,313 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Ids
+{
+	/// <exclude></exclude>
+	public class BTreeIdSystem : IStackableIdSystem
+	{
+		private const int BtreeIdIndex = 0;
+
+		private const int IdGeneratorIndex = 1;
+
+		private const int ChildIdIndex = 2;
+
+		private readonly LocalObjectContainer _container;
+
+		private readonly IStackableIdSystem _parentIdSystem;
+
+		private readonly ITransactionalIdSystem _transactionalIdSystem;
+
+		private readonly SequentialIdGenerator _idGenerator;
+
+		private BTree _bTree;
+
+		private PersistentIntegerArray _persistentState;
+
+		public BTreeIdSystem(LocalObjectContainer container, IStackableIdSystem parentIdSystem
+			, int maxValidId)
+		{
+			_container = container;
+			_parentIdSystem = parentIdSystem;
+			_transactionalIdSystem = container.NewTransactionalIdSystem(null, new _IClosure4_40
+				(parentIdSystem));
+			int persistentArrayId = parentIdSystem.ChildId();
+			if (persistentArrayId == 0)
+			{
+				InitializeNew();
+			}
+			else
+			{
+				InitializeExisting(persistentArrayId);
+			}
+			_idGenerator = new SequentialIdGenerator(new _IFunction4_52(this), IdGeneratorValue
+				(), _container.Handlers.LowestValidId(), maxValidId);
+		}
+
+		private sealed class _IClosure4_40 : IClosure4
+		{
+			public _IClosure4_40(IStackableIdSystem parentIdSystem)
+			{
+				this.parentIdSystem = parentIdSystem;
+			}
+
+			public object Run()
+			{
+				return parentIdSystem;
+			}
+
+			private readonly IStackableIdSystem parentIdSystem;
+		}
+
+		private sealed class _IFunction4_52 : IFunction4
+		{
+			public _IFunction4_52(BTreeIdSystem _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Apply(object start)
+			{
+				return this._enclosing.FindFreeId((((int)start)));
+			}
+
+			private readonly BTreeIdSystem _enclosing;
+		}
+
+		public BTreeIdSystem(LocalObjectContainer container, IStackableIdSystem idSystem)
+			 : this(container, idSystem, int.MaxValue)
+		{
+		}
+
+		private void InitializeExisting(int persistentArrayId)
+		{
+			_persistentState = new PersistentIntegerArray(SlotChangeFactory.IdSystem, _transactionalIdSystem
+				, persistentArrayId);
+			_persistentState.Read(Transaction());
+			_bTree = new BTree(Transaction(), BTreeConfiguration(), BTreeId(), new BTreeIdSystem.IdSlotMappingHandler
+				());
+		}
+
+		private Db4objects.Db4o.Internal.Btree.BTreeConfiguration BTreeConfiguration()
+		{
+			return new Db4objects.Db4o.Internal.Btree.BTreeConfiguration(_transactionalIdSystem
+				, SlotChangeFactory.IdSystem, 64, false);
+		}
+
+		private int IdGeneratorValue()
+		{
+			return _persistentState.Array()[IdGeneratorIndex];
+		}
+
+		private void IdGeneratorValue(int value)
+		{
+			_persistentState.Array()[IdGeneratorIndex] = value;
+		}
+
+		private int BTreeId()
+		{
+			return _persistentState.Array()[BtreeIdIndex];
+		}
+
+		private void InitializeNew()
+		{
+			_bTree = new BTree(Transaction(), BTreeConfiguration(), new BTreeIdSystem.IdSlotMappingHandler
+				());
+			int idGeneratorValue = _container.Handlers.LowestValidId() - 1;
+			_persistentState = new PersistentIntegerArray(SlotChangeFactory.IdSystem, _transactionalIdSystem
+				, new int[] { _bTree.GetID(), idGeneratorValue, 0 });
+			_persistentState.Write(Transaction());
+			_parentIdSystem.ChildId(_persistentState.GetID());
+		}
+
+		private int FindFreeId(int start)
+		{
+			throw new NotImplementedException();
+		}
+
+		public virtual void Close()
+		{
+		}
+
+		public virtual Slot CommittedSlot(int id)
+		{
+			IdSlotMapping mapping = (IdSlotMapping)_bTree.Search(Transaction(), new IdSlotMapping
+				(id, 0, 0));
+			if (mapping == null)
+			{
+				throw new InvalidIDException(id);
+			}
+			return mapping.Slot();
+		}
+
+		public virtual void CompleteInterruptedTransaction(int transactionId1, int transactionId2
+			)
+		{
+		}
+
+		// do nothing
+		public virtual int NewId()
+		{
+			int id = _idGenerator.NewId();
+			_bTree.Add(Transaction(), new IdSlotMapping(id, 0, 0));
+			return id;
+		}
+
+		private Db4objects.Db4o.Internal.Transaction Transaction()
+		{
+			return _container.SystemTransaction();
+		}
+
+		public virtual void Commit(IVisitable slotChanges, FreespaceCommitter freespaceCommitter
+			)
+		{
+			_container.FreespaceManager().BeginCommit();
+			slotChanges.Accept(new _IVisitor4_129(this));
+			// TODO: Maybe we want a BTree that doesn't allow duplicates.
+			// Then we could do the following in one step without removing first.
+			_bTree.Commit(Transaction());
+			IdGeneratorValue(_idGenerator.PersistentGeneratorValue());
+			if (_idGenerator.IsDirty())
+			{
+				_idGenerator.SetClean();
+				_persistentState.SetStateDirty();
+			}
+			if (_persistentState.IsDirty())
+			{
+				_persistentState.Write(Transaction());
+			}
+			_container.FreespaceManager().EndCommit();
+			_transactionalIdSystem.Commit(freespaceCommitter);
+			_transactionalIdSystem.Clear();
+		}
+
+		private sealed class _IVisitor4_129 : IVisitor4
+		{
+			public _IVisitor4_129(BTreeIdSystem _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Visit(object slotChange)
+			{
+				if (!((SlotChange)slotChange).SlotModified())
+				{
+					return;
+				}
+				this._enclosing._bTree.Remove(this._enclosing.Transaction(), new IdSlotMapping(((
+					TreeInt)slotChange)._key, 0, 0));
+				if (((SlotChange)slotChange).RemoveId())
+				{
+					return;
+				}
+				this._enclosing._bTree.Add(this._enclosing.Transaction(), new IdSlotMapping(((TreeInt
+					)slotChange)._key, ((SlotChange)slotChange).NewSlot()));
+				if (DTrace.enabled)
+				{
+					DTrace.SlotMapped.LogLength(((TreeInt)slotChange)._key, ((SlotChange)slotChange).
+						NewSlot());
+				}
+			}
+
+			private readonly BTreeIdSystem _enclosing;
+		}
+
+		public virtual void ReturnUnusedIds(IVisitable visitable)
+		{
+			visitable.Accept(new _IVisitor4_167(this));
+		}
+
+		private sealed class _IVisitor4_167 : IVisitor4
+		{
+			public _IVisitor4_167(BTreeIdSystem _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Visit(object id)
+			{
+				this._enclosing._bTree.Remove(this._enclosing.Transaction(), new IdSlotMapping(((
+					(int)id)), 0, 0));
+			}
+
+			private readonly BTreeIdSystem _enclosing;
+		}
+
+		public class IdSlotMappingHandler : IIndexable4
+		{
+			public virtual void DefragIndexEntry(DefragmentContextImpl context)
+			{
+				throw new NotImplementedException();
+			}
+
+			public virtual object ReadIndexEntry(IContext context, ByteArrayBuffer buffer)
+			{
+				return IdSlotMapping.Read(buffer);
+			}
+
+			public virtual void WriteIndexEntry(IContext context, ByteArrayBuffer buffer, object
+				 mapping)
+			{
+				((IdSlotMapping)mapping).Write(buffer);
+			}
+
+			public virtual IPreparedComparison PrepareComparison(IContext context, object sourceMapping
+				)
+			{
+				return new _IPreparedComparison_190(sourceMapping);
+			}
+
+			private sealed class _IPreparedComparison_190 : IPreparedComparison
+			{
+				public _IPreparedComparison_190(object sourceMapping)
+				{
+					this.sourceMapping = sourceMapping;
+				}
+
+				public int CompareTo(object targetMapping)
+				{
+					return ((IdSlotMapping)sourceMapping)._id == ((IdSlotMapping)targetMapping)._id ? 
+						0 : (((IdSlotMapping)sourceMapping)._id < ((IdSlotMapping)targetMapping)._id ? -
+						1 : 1);
+				}
+
+				private readonly object sourceMapping;
+			}
+
+			public int LinkLength()
+			{
+				return Const4.IntLength * 3;
+			}
+		}
+
+		public virtual ITransactionalIdSystem FreespaceIdSystem()
+		{
+			return _transactionalIdSystem;
+		}
+
+		public virtual int ChildId()
+		{
+			return _persistentState.Array()[ChildIdIndex];
+		}
+
+		public virtual void ChildId(int id)
+		{
+			_persistentState.Array()[ChildIdIndex] = id;
+			_persistentState.SetStateDirty();
+		}
+
+		public virtual void TraverseIds(IVisitor4 visitor)
+		{
+			_bTree.TraverseKeys(_container.SystemTransaction(), visitor);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/FreespaceCommitter.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/FreespaceCommitter.cs
new file mode 100644
index 0000000..912deed
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/FreespaceCommitter.cs
@@ -0,0 +1,79 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Ids
+{
+	/// <exclude></exclude>
+	public class FreespaceCommitter
+	{
+		public static readonly Db4objects.Db4o.Internal.Ids.FreespaceCommitter DoNothing = 
+			new FreespaceCommitter.NullFreespaceCommitter();
+
+		private readonly IList _freeToUserFreespaceSystem = new ArrayList();
+
+		private readonly IList _freeToSystemFreespaceSystem = new ArrayList();
+
+		private readonly IFreespaceManager _freespaceManager;
+
+		private ITransactionalIdSystem _transactionalIdSystem;
+
+		public FreespaceCommitter(IFreespaceManager freespaceManager)
+		{
+			_freespaceManager = freespaceManager == null ? NullFreespaceManager.Instance : freespaceManager;
+		}
+
+		public virtual void Commit()
+		{
+			Apply(_freeToUserFreespaceSystem);
+			_freespaceManager.BeginCommit();
+			_freespaceManager.Commit();
+			_transactionalIdSystem.AccumulateFreeSlots(this, true);
+			Apply(_freeToSystemFreespaceSystem);
+			_freespaceManager.EndCommit();
+		}
+
+		private void Apply(IList toFree)
+		{
+			for (IEnumerator slotIter = toFree.GetEnumerator(); slotIter.MoveNext(); )
+			{
+				Slot slot = ((Slot)slotIter.Current);
+				_freespaceManager.Free(slot);
+			}
+			toFree.Clear();
+		}
+
+		public virtual void TransactionalIdSystem(ITransactionalIdSystem transactionalIdSystem
+			)
+		{
+			_transactionalIdSystem = transactionalIdSystem;
+		}
+
+		private class NullFreespaceCommitter : FreespaceCommitter
+		{
+			public NullFreespaceCommitter() : base(NullFreespaceManager.Instance)
+			{
+			}
+
+			public override void Commit()
+			{
+			}
+			// do nothing
+		}
+
+		public virtual void DelayedFree(Slot slot, bool freeToSystemFreeSpaceSystem)
+		{
+			if (freeToSystemFreeSpaceSystem)
+			{
+				_freeToSystemFreespaceSystem.Add(slot);
+			}
+			else
+			{
+				_freeToUserFreespaceSystem.Add(slot);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/IIdSystem.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/IIdSystem.cs
new file mode 100644
index 0000000..9fbc1e4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/IIdSystem.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Ids
+{
+	/// <exclude></exclude>
+	public interface IIdSystem
+	{
+		int NewId();
+
+		Slot CommittedSlot(int id);
+
+		void ReturnUnusedIds(IVisitable visitable);
+
+		void Close();
+
+		void CompleteInterruptedTransaction(int transactionId1, int transactionId2);
+
+		void Commit(IVisitable slotChanges, FreespaceCommitter freespaceCommitter);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/IStackableIdSystem.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/IStackableIdSystem.cs
new file mode 100644
index 0000000..9340e9f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/IStackableIdSystem.cs
@@ -0,0 +1,14 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Ids;
+
+namespace Db4objects.Db4o.Internal.Ids
+{
+	/// <exclude></exclude>
+	public interface IStackableIdSystem : IIdSystem
+	{
+		int ChildId();
+
+		void ChildId(int id);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/ITransactionalIdSystem.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/ITransactionalIdSystem.cs
new file mode 100644
index 0000000..29bfdd7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/ITransactionalIdSystem.cs
@@ -0,0 +1,45 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Ids
+{
+	/// <exclude></exclude>
+	public interface ITransactionalIdSystem
+	{
+		void CollectCallBackInfo(ICallbackInfoCollector collector);
+
+		bool IsDirty();
+
+		void Commit(FreespaceCommitter freespaceCommitter);
+
+		Slot CommittedSlot(int id);
+
+		Slot CurrentSlot(int id);
+
+		void AccumulateFreeSlots(FreespaceCommitter freespaceCommitter, bool forFreespace
+			);
+
+		void Rollback();
+
+		void Clear();
+
+		bool IsDeleted(int id);
+
+		void NotifySlotUpdated(int id, Slot slot, SlotChangeFactory slotChangeFactory);
+
+		void NotifySlotCreated(int id, Slot slot, SlotChangeFactory slotChangeFactory);
+
+		void NotifySlotDeleted(int id, SlotChangeFactory slotChangeFactory);
+
+		int NewId(SlotChangeFactory slotChangeFactory);
+
+		int PrefetchID();
+
+		void PrefetchedIDConsumed(int id);
+
+		void Close();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/IdSlotChanges.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/IdSlotChanges.cs
new file mode 100644
index 0000000..730e6d7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/IdSlotChanges.cs
@@ -0,0 +1,177 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Ids
+{
+	public class IdSlotChanges
+	{
+		private readonly LockedTree _slotChanges = new LockedTree();
+
+		private readonly TransactionalIdSystemImpl _idSystem;
+
+		private readonly IClosure4 _freespaceManager;
+
+		private TreeInt _prefetchedIDs;
+
+		public IdSlotChanges(TransactionalIdSystemImpl idSystem, IClosure4 freespaceManager
+			)
+		{
+			_idSystem = idSystem;
+			_freespaceManager = freespaceManager;
+		}
+
+		public void AccumulateFreeSlots(FreespaceCommitter freespaceCommitter, bool forFreespace
+			, bool traverseMutable)
+		{
+			IVisitor4 visitor = new _IVisitor4_27(this, freespaceCommitter, forFreespace);
+			if (traverseMutable)
+			{
+				_slotChanges.TraverseMutable(visitor);
+			}
+			else
+			{
+				_slotChanges.TraverseLocked(visitor);
+			}
+		}
+
+		private sealed class _IVisitor4_27 : IVisitor4
+		{
+			public _IVisitor4_27(IdSlotChanges _enclosing, FreespaceCommitter freespaceCommitter
+				, bool forFreespace)
+			{
+				this._enclosing = _enclosing;
+				this.freespaceCommitter = freespaceCommitter;
+				this.forFreespace = forFreespace;
+			}
+
+			public void Visit(object obj)
+			{
+				((SlotChange)obj).AccumulateFreeSlot(this._enclosing._idSystem, freespaceCommitter
+					, forFreespace);
+			}
+
+			private readonly IdSlotChanges _enclosing;
+
+			private readonly FreespaceCommitter freespaceCommitter;
+
+			private readonly bool forFreespace;
+		}
+
+		public virtual void Clear()
+		{
+			_slotChanges.Clear();
+		}
+
+		public virtual void Rollback()
+		{
+			_slotChanges.TraverseLocked(new _IVisitor4_44(this));
+		}
+
+		private sealed class _IVisitor4_44 : IVisitor4
+		{
+			public _IVisitor4_44(IdSlotChanges _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Visit(object slotChange)
+			{
+				((SlotChange)slotChange).Rollback(this._enclosing.FreespaceManager());
+			}
+
+			private readonly IdSlotChanges _enclosing;
+		}
+
+		public virtual bool IsDeleted(int id)
+		{
+			SlotChange slot = FindSlotChange(id);
+			if (slot == null)
+			{
+				return false;
+			}
+			return slot.IsDeleted();
+		}
+
+		public virtual SlotChange ProduceSlotChange(int id, SlotChangeFactory slotChangeFactory
+			)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.ProduceSlotChange.Log(id);
+			}
+			SlotChange slot = slotChangeFactory.NewInstance(id);
+			_slotChanges.Add(slot);
+			return (SlotChange)slot.AddedOrExisting();
+		}
+
+		public SlotChange FindSlotChange(int id)
+		{
+			return (SlotChange)_slotChanges.Find(id);
+		}
+
+		public virtual void TraverseSlotChanges(IVisitor4 visitor)
+		{
+			_slotChanges.TraverseLocked(visitor);
+		}
+
+		public virtual bool IsDirty()
+		{
+			return !_slotChanges.IsEmpty();
+		}
+
+		public virtual void ReadSlotChanges(ByteArrayBuffer buffer)
+		{
+			_slotChanges.Read(buffer, new SlotChange(0));
+		}
+
+		public virtual void AddPrefetchedID(int id)
+		{
+			_prefetchedIDs = ((TreeInt)Tree.Add(_prefetchedIDs, new TreeInt(id)));
+		}
+
+		public virtual void PrefetchedIDConsumed(int id)
+		{
+			_prefetchedIDs = ((TreeInt)_prefetchedIDs.RemoveLike(new TreeInt(id)));
+		}
+
+		internal void FreePrefetchedIDs(IIdSystem idSystem)
+		{
+			if (_prefetchedIDs == null)
+			{
+				return;
+			}
+			idSystem.ReturnUnusedIds(_prefetchedIDs);
+			_prefetchedIDs = null;
+		}
+
+		public virtual void NotifySlotCreated(int id, Slot slot, SlotChangeFactory slotChangeFactory
+			)
+		{
+			ProduceSlotChange(id, slotChangeFactory).NotifySlotCreated(slot);
+		}
+
+		internal virtual void NotifySlotUpdated(int id, Slot slot, SlotChangeFactory slotChangeFactory
+			)
+		{
+			ProduceSlotChange(id, slotChangeFactory).NotifySlotUpdated(FreespaceManager(), slot
+				);
+		}
+
+		public virtual void NotifySlotDeleted(int id, SlotChangeFactory slotChangeFactory
+			)
+		{
+			ProduceSlotChange(id, slotChangeFactory).NotifyDeleted(FreespaceManager());
+		}
+
+		private IFreespaceManager FreespaceManager()
+		{
+			return ((IFreespaceManager)_freespaceManager.Run());
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/IdSlotMapping.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/IdSlotMapping.cs
new file mode 100644
index 0000000..daa1b78
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/IdSlotMapping.cs
@@ -0,0 +1,53 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Ids
+{
+	/// <exclude></exclude>
+	public class IdSlotMapping
+	{
+		public int _id;
+
+		public int _address;
+
+		public int _length;
+
+		public IdSlotMapping(int id, int address, int length)
+		{
+			// persistent and indexed in DatabaseIdMapping, don't change the name
+			_id = id;
+			_address = address;
+			_length = length;
+		}
+
+		public IdSlotMapping(int id, Db4objects.Db4o.Internal.Slots.Slot slot) : this(id, 
+			slot.Address(), slot.Length())
+		{
+		}
+
+		public virtual Db4objects.Db4o.Internal.Slots.Slot Slot()
+		{
+			return new Db4objects.Db4o.Internal.Slots.Slot(_address, _length);
+		}
+
+		public virtual void Write(ByteArrayBuffer buffer)
+		{
+			buffer.WriteInt(_id);
+			buffer.WriteInt(_address);
+			buffer.WriteInt(_length);
+		}
+
+		public static Db4objects.Db4o.Internal.Ids.IdSlotMapping Read(ByteArrayBuffer buffer
+			)
+		{
+			return new Db4objects.Db4o.Internal.Ids.IdSlotMapping(buffer.ReadInt(), buffer.ReadInt
+				(), buffer.ReadInt());
+		}
+
+		public override string ToString()
+		{
+			return string.Empty + _id + ":" + _address + "," + _length;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/IdSlotTree.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/IdSlotTree.cs
new file mode 100644
index 0000000..aed5c88
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/IdSlotTree.cs
@@ -0,0 +1,52 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Ids
+{
+	/// <exclude></exclude>
+	public class IdSlotTree : TreeInt
+	{
+		private readonly Db4objects.Db4o.Internal.Slots.Slot _slot;
+
+		public IdSlotTree(int id, Db4objects.Db4o.Internal.Slots.Slot slot) : base(id)
+		{
+			_slot = slot;
+		}
+
+		public virtual Db4objects.Db4o.Internal.Slots.Slot Slot()
+		{
+			return _slot;
+		}
+
+		public override Tree OnAttemptToAddDuplicate(Tree oldNode)
+		{
+			_preceding = ((Tree)oldNode._preceding);
+			_subsequent = ((Tree)oldNode._subsequent);
+			_size = oldNode._size;
+			return this;
+		}
+
+		public override int OwnLength()
+		{
+			return Const4.IntLength * 3;
+		}
+
+		// _key, _slot._address, _slot._length 
+		public override object Read(ByteArrayBuffer buffer)
+		{
+			int id = buffer.ReadInt();
+			Db4objects.Db4o.Internal.Slots.Slot slot = new Db4objects.Db4o.Internal.Slots.Slot
+				(buffer.ReadInt(), buffer.ReadInt());
+			return new Db4objects.Db4o.Internal.Ids.IdSlotTree(id, slot);
+		}
+
+		public override void Write(ByteArrayBuffer buffer)
+		{
+			buffer.WriteInt(_key);
+			buffer.WriteInt(_slot.Address());
+			buffer.WriteInt(_slot.Length());
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/InMemoryIdSystem.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/InMemoryIdSystem.cs
new file mode 100644
index 0000000..2a49d07
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/InMemoryIdSystem.cs
@@ -0,0 +1,336 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal.Ids
+{
+	/// <exclude></exclude>
+	public class InMemoryIdSystem : IStackableIdSystem
+	{
+		private readonly LocalObjectContainer _container;
+
+		private IdSlotTree _ids;
+
+		private Slot _slot;
+
+		private readonly SequentialIdGenerator _idGenerator;
+
+		private int _childId;
+
+		/// <summary>for testing purposes only.</summary>
+		/// <remarks>for testing purposes only.</remarks>
+		public InMemoryIdSystem(LocalObjectContainer container, int maxValidId)
+		{
+			_container = container;
+			_idGenerator = new SequentialIdGenerator(new _IFunction4_32(this, maxValidId), _container
+				.Handlers.LowestValidId(), maxValidId);
+		}
+
+		private sealed class _IFunction4_32 : IFunction4
+		{
+			public _IFunction4_32(InMemoryIdSystem _enclosing, int maxValidId)
+			{
+				this._enclosing = _enclosing;
+				this.maxValidId = maxValidId;
+			}
+
+			public object Apply(object start)
+			{
+				return this._enclosing.FindFreeId((((int)start)), maxValidId);
+			}
+
+			private readonly InMemoryIdSystem _enclosing;
+
+			private readonly int maxValidId;
+		}
+
+		public InMemoryIdSystem(LocalObjectContainer container) : this(container, int.MaxValue
+			)
+		{
+			ReadThis();
+		}
+
+		private void ReadThis()
+		{
+			SystemData systemData = _container.SystemData();
+			_slot = systemData.IdSystemSlot();
+			if (!Slot.IsNull(_slot))
+			{
+				ByteArrayBuffer buffer = _container.ReadBufferBySlot(_slot);
+				_childId = buffer.ReadInt();
+				_idGenerator.Read(buffer);
+				_ids = (IdSlotTree)new TreeReader(buffer, new IdSlotTree(0, null)).Read();
+			}
+		}
+
+		public virtual void Close()
+		{
+		}
+
+		// do nothing
+		public virtual void Commit(IVisitable slotChanges, FreespaceCommitter freespaceCommitter
+			)
+		{
+			Slot oldSlot = _slot;
+			Slot reservedSlot = AllocateSlot(false, EstimatedSlotLength(EstimateMappingCount(
+				slotChanges)));
+			// No more operations against the FreespaceManager.
+			// Time to free old slots.
+			freespaceCommitter.Commit();
+			slotChanges.Accept(new _IVisitor4_69(this));
+			WriteThis(reservedSlot);
+			FreeSlot(oldSlot);
+		}
+
+		private sealed class _IVisitor4_69 : IVisitor4
+		{
+			public _IVisitor4_69(InMemoryIdSystem _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Visit(object slotChange)
+			{
+				if (!((SlotChange)slotChange).SlotModified())
+				{
+					return;
+				}
+				if (((SlotChange)slotChange).RemoveId())
+				{
+					this._enclosing._ids = (IdSlotTree)Tree.RemoveLike(this._enclosing._ids, new TreeInt
+						(((TreeInt)slotChange)._key));
+					return;
+				}
+				if (DTrace.enabled)
+				{
+					DTrace.SlotCommitted.LogLength(((TreeInt)slotChange)._key, ((SlotChange)slotChange
+						).NewSlot());
+				}
+				this._enclosing._ids = ((IdSlotTree)Tree.Add(this._enclosing._ids, new IdSlotTree
+					(((TreeInt)slotChange)._key, ((SlotChange)slotChange).NewSlot())));
+			}
+
+			private readonly InMemoryIdSystem _enclosing;
+		}
+
+		private Slot AllocateSlot(bool appendToFile, int slotLength)
+		{
+			if (!appendToFile)
+			{
+				Slot slot = _container.FreespaceManager().AllocateSafeSlot(slotLength);
+				if (slot != null)
+				{
+					return slot;
+				}
+			}
+			return _container.AppendBytes(slotLength);
+		}
+
+		private int EstimateMappingCount(IVisitable slotChanges)
+		{
+			IntByRef count = new IntByRef();
+			count.value = _ids == null ? 0 : _ids.Size();
+			slotChanges.Accept(new _IVisitor4_103(count));
+			return count.value;
+		}
+
+		private sealed class _IVisitor4_103 : IVisitor4
+		{
+			public _IVisitor4_103(IntByRef count)
+			{
+				this.count = count;
+			}
+
+			public void Visit(object slotChange)
+			{
+				if (!((SlotChange)slotChange).SlotModified() || ((SlotChange)slotChange).RemoveId
+					())
+				{
+					return;
+				}
+				count.value++;
+			}
+
+			private readonly IntByRef count;
+		}
+
+		private void WriteThis(Slot reservedSlot)
+		{
+			// We need a little dance here to keep filling free slots
+			// with X bytes. The FreespaceManager would do it immediately
+			// upon the free call, but then our CrashSimulatingTestCase
+			// fails because we have the Xses in the file before flushing.
+			Slot xByteSlot = null;
+			int slotLength = SlotLength();
+			if (reservedSlot.Length() >= slotLength)
+			{
+				_slot = reservedSlot;
+				reservedSlot = null;
+			}
+			else
+			{
+				_slot = AllocateSlot(true, slotLength);
+			}
+			ByteArrayBuffer buffer = new ByteArrayBuffer(_slot.Length());
+			buffer.WriteInt(_childId);
+			_idGenerator.Write(buffer);
+			TreeInt.Write(buffer, _ids);
+			_container.WriteBytes(buffer, _slot.Address(), 0);
+			_container.SystemData().IdSystemSlot(_slot);
+			IRunnable commitHook = _container.CommitHook();
+			_container.SyncFiles(commitHook);
+			FreeSlot(reservedSlot);
+		}
+
+		private void FreeSlot(Slot slot)
+		{
+			if (Slot.IsNull(slot))
+			{
+				return;
+			}
+			IFreespaceManager freespaceManager = _container.FreespaceManager();
+			if (freespaceManager == null)
+			{
+				return;
+			}
+			freespaceManager.FreeSafeSlot(slot);
+		}
+
+		private int SlotLength()
+		{
+			return TreeInt.MarshalledLength(_ids) + _idGenerator.MarshalledLength() + Const4.
+				IdLength;
+		}
+
+		private int EstimatedSlotLength(int estimatedCount)
+		{
+			IdSlotTree template = _ids;
+			if (template == null)
+			{
+				template = new IdSlotTree(0, new Slot(0, 0));
+			}
+			return template.MarshalledLength(estimatedCount) + _idGenerator.MarshalledLength(
+				) + Const4.IdLength;
+		}
+
+		public virtual Slot CommittedSlot(int id)
+		{
+			IdSlotTree idSlotMapping = (IdSlotTree)Tree.Find(_ids, new TreeInt(id));
+			if (idSlotMapping == null)
+			{
+				throw new InvalidIDException(id);
+			}
+			return idSlotMapping.Slot();
+		}
+
+		public virtual void CompleteInterruptedTransaction(int address, int length)
+		{
+		}
+
+		// do nothing
+		public virtual int NewId()
+		{
+			int id = _idGenerator.NewId();
+			_ids = ((IdSlotTree)Tree.Add(_ids, new IdSlotTree(id, Slot.Zero)));
+			return id;
+		}
+
+		private int FindFreeId(int start, int end)
+		{
+			if (_ids == null)
+			{
+				return start;
+			}
+			IntByRef lastId = new IntByRef();
+			IntByRef freeId = new IntByRef();
+			Tree.Traverse(_ids, new TreeInt(start), new _ICancellableVisitor4_204(lastId, start
+				, freeId));
+			if (freeId.value > 0)
+			{
+				return freeId.value;
+			}
+			if (lastId.value < end)
+			{
+				return Math.Max(start, lastId.value + 1);
+			}
+			return 0;
+		}
+
+		private sealed class _ICancellableVisitor4_204 : ICancellableVisitor4
+		{
+			public _ICancellableVisitor4_204(IntByRef lastId, int start, IntByRef freeId)
+			{
+				this.lastId = lastId;
+				this.start = start;
+				this.freeId = freeId;
+			}
+
+			public bool Visit(object node)
+			{
+				int id = ((TreeInt)node)._key;
+				if (lastId.value == 0)
+				{
+					if (id > start)
+					{
+						freeId.value = start;
+						return false;
+					}
+					lastId.value = id;
+					return true;
+				}
+				if (id > lastId.value + 1)
+				{
+					freeId.value = lastId.value + 1;
+					return false;
+				}
+				lastId.value = id;
+				return true;
+			}
+
+			private readonly IntByRef lastId;
+
+			private readonly int start;
+
+			private readonly IntByRef freeId;
+		}
+
+		public virtual void ReturnUnusedIds(IVisitable visitable)
+		{
+			visitable.Accept(new _IVisitor4_233(this));
+		}
+
+		private sealed class _IVisitor4_233 : IVisitor4
+		{
+			public _IVisitor4_233(InMemoryIdSystem _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Visit(object obj)
+			{
+				this._enclosing._ids = (IdSlotTree)Tree.RemoveLike(this._enclosing._ids, new TreeInt
+					((((int)obj))));
+			}
+
+			private readonly InMemoryIdSystem _enclosing;
+		}
+
+		public virtual int ChildId()
+		{
+			return _childId;
+		}
+
+		public virtual void ChildId(int id)
+		{
+			_childId = id;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/PointerBasedIdSystem.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/PointerBasedIdSystem.cs
new file mode 100644
index 0000000..8cd1dc6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/PointerBasedIdSystem.cs
@@ -0,0 +1,112 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Internal.Transactionlog;
+
+namespace Db4objects.Db4o.Internal.Ids
+{
+	/// <exclude></exclude>
+	public sealed class PointerBasedIdSystem : IIdSystem
+	{
+		internal readonly TransactionLogHandler _transactionLogHandler;
+
+		private readonly LocalObjectContainer _container;
+
+		public PointerBasedIdSystem(LocalObjectContainer container)
+		{
+			_container = container;
+			_transactionLogHandler = NewTransactionLogHandler(container);
+		}
+
+		public int NewId()
+		{
+			return _container.AllocatePointerSlot();
+		}
+
+		public Slot CommittedSlot(int id)
+		{
+			return _container.ReadPointerSlot(id);
+		}
+
+		public void Commit(IVisitable slotChanges, FreespaceCommitter freespaceCommitter)
+		{
+			Slot reservedSlot = _transactionLogHandler.AllocateSlot(false, CountSlotChanges(slotChanges
+				));
+			freespaceCommitter.Commit();
+			_transactionLogHandler.ApplySlotChanges(slotChanges, CountSlotChanges(slotChanges
+				), reservedSlot);
+		}
+
+		private int CountSlotChanges(IVisitable slotChanges)
+		{
+			IntByRef slotChangeCount = new IntByRef();
+			slotChanges.Accept(new _IVisitor4_40(slotChangeCount));
+			return slotChangeCount.value;
+		}
+
+		private sealed class _IVisitor4_40 : IVisitor4
+		{
+			public _IVisitor4_40(IntByRef slotChangeCount)
+			{
+				this.slotChangeCount = slotChangeCount;
+			}
+
+			public void Visit(object slotChange)
+			{
+				if (((SlotChange)slotChange).SlotModified())
+				{
+					slotChangeCount.value++;
+				}
+			}
+
+			private readonly IntByRef slotChangeCount;
+		}
+
+		public void ReturnUnusedIds(IVisitable visitable)
+		{
+			visitable.Accept(new _IVisitor4_51(this));
+		}
+
+		private sealed class _IVisitor4_51 : IVisitor4
+		{
+			public _IVisitor4_51(PointerBasedIdSystem _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Visit(object id)
+			{
+				this._enclosing._container.Free((((int)id)), Const4.PointerLength);
+			}
+
+			private readonly PointerBasedIdSystem _enclosing;
+		}
+
+		private TransactionLogHandler NewTransactionLogHandler(LocalObjectContainer container
+			)
+		{
+			bool fileBased = container.Config().FileBasedTransactionLog() && container is IoAdaptedObjectContainer;
+			if (!fileBased)
+			{
+				return new EmbeddedTransactionLogHandler(container);
+			}
+			string fileName = ((IoAdaptedObjectContainer)container).FileName();
+			return new FileBasedTransactionLogHandler(container, fileName);
+		}
+
+		public void Close()
+		{
+			_transactionLogHandler.Close();
+		}
+
+		public void CompleteInterruptedTransaction(int transactionId1, int transactionId2
+			)
+		{
+			_transactionLogHandler.CompleteInterruptedTransaction(transactionId1, transactionId2
+				);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/SequentialIdGenerator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/SequentialIdGenerator.cs
new file mode 100644
index 0000000..f6e2f5f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/SequentialIdGenerator.cs
@@ -0,0 +1,115 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Ids
+{
+	/// <exclude></exclude>
+	public class SequentialIdGenerator
+	{
+		private readonly int _minValidId;
+
+		private readonly int _maxValidId;
+
+		private int _idGenerator;
+
+		private bool _overflow;
+
+		private int _lastIdGenerator;
+
+		private readonly IFunction4 _findFreeId;
+
+		public SequentialIdGenerator(IFunction4 findFreeId, int initialValue, int minValidId
+			, int maxValidId)
+		{
+			_findFreeId = findFreeId;
+			_minValidId = minValidId;
+			_maxValidId = maxValidId;
+			InitializeGenerator(initialValue);
+		}
+
+		public SequentialIdGenerator(IFunction4 findFreeId, int minValidId, int maxValidId
+			) : this(findFreeId, minValidId - 1, minValidId, maxValidId)
+		{
+		}
+
+		public virtual void Read(ByteArrayBuffer buffer)
+		{
+			InitializeGenerator(buffer.ReadInt());
+		}
+
+		private void InitializeGenerator(int val)
+		{
+			if (val < 0)
+			{
+				_overflow = true;
+				_idGenerator = -val;
+			}
+			else
+			{
+				_idGenerator = val;
+			}
+			_lastIdGenerator = _idGenerator;
+		}
+
+		public virtual void Write(ByteArrayBuffer buffer)
+		{
+			buffer.WriteInt(PersistentGeneratorValue());
+		}
+
+		public virtual int PersistentGeneratorValue()
+		{
+			return _overflow ? -_idGenerator : _idGenerator;
+		}
+
+		public virtual int NewId()
+		{
+			AdjustIdGenerator(_idGenerator);
+			if (!_overflow)
+			{
+				return _idGenerator;
+			}
+			int id = (((int)_findFreeId.Apply(_idGenerator)));
+			if (id > 0)
+			{
+				AdjustIdGenerator(id - 1);
+				return id;
+			}
+			id = (((int)_findFreeId.Apply(_minValidId)));
+			if (id > 0)
+			{
+				AdjustIdGenerator(id - 1);
+				return id;
+			}
+			throw new Db4oFatalException("Out of IDs");
+		}
+
+		private void AdjustIdGenerator(int id)
+		{
+			if (id == _maxValidId)
+			{
+				_idGenerator = _minValidId;
+				_overflow = true;
+				return;
+			}
+			_idGenerator = id + 1;
+		}
+
+		public virtual int MarshalledLength()
+		{
+			return Const4.IntLength;
+		}
+
+		public virtual bool IsDirty()
+		{
+			return _idGenerator != _lastIdGenerator;
+		}
+
+		public virtual void SetClean()
+		{
+			_lastIdGenerator = _idGenerator;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/StandardIdSystemFactory.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/StandardIdSystemFactory.cs
new file mode 100644
index 0000000..4c674de
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/StandardIdSystemFactory.cs
@@ -0,0 +1,85 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Ids;
+
+namespace Db4objects.Db4o.Internal.Ids
+{
+	/// <exclude></exclude>
+	public class StandardIdSystemFactory
+	{
+		public const byte Legacy = 0;
+
+		public const byte PointerBased = 1;
+
+		public const byte StackedBtree = 2;
+
+		public const byte Default = StackedBtree;
+
+		public const byte InMemory = 3;
+
+		public const byte Custom = 4;
+
+		public const byte SingleBtree = 5;
+
+		public static IIdSystem NewInstance(LocalObjectContainer localContainer)
+		{
+			SystemData systemData = localContainer.SystemData();
+			byte idSystemType = systemData.IdSystemType();
+			switch (idSystemType)
+			{
+				case Legacy:
+				{
+					return new PointerBasedIdSystem(localContainer);
+				}
+
+				case PointerBased:
+				{
+					return new PointerBasedIdSystem(localContainer);
+				}
+
+				case StackedBtree:
+				{
+					InMemoryIdSystem inMemoryIdSystem = new InMemoryIdSystem(localContainer);
+					BTreeIdSystem bTreeIdSystem = new BTreeIdSystem(localContainer, inMemoryIdSystem);
+					systemData.FreespaceIdSystem(bTreeIdSystem.FreespaceIdSystem());
+					return new BTreeIdSystem(localContainer, bTreeIdSystem);
+				}
+
+				case SingleBtree:
+				{
+					InMemoryIdSystem smallInMemoryIdSystem = new InMemoryIdSystem(localContainer);
+					BTreeIdSystem smallBTreeIdSystem = new BTreeIdSystem(localContainer, smallInMemoryIdSystem
+						);
+					systemData.FreespaceIdSystem(smallBTreeIdSystem.FreespaceIdSystem());
+					return smallBTreeIdSystem;
+				}
+
+				case InMemory:
+				{
+					return new InMemoryIdSystem(localContainer);
+				}
+
+				case Custom:
+				{
+					IIdSystemFactory customIdSystemFactory = localContainer.ConfigImpl.CustomIdSystemFactory
+						();
+					if (customIdSystemFactory == null)
+					{
+						throw new Db4oFatalException("Custom IdSystem configured but no factory was found. See IdSystemConfiguration#useCustomSystem()"
+							);
+					}
+					return customIdSystemFactory.NewInstance(localContainer);
+				}
+
+				default:
+				{
+					return new PointerBasedIdSystem(localContainer);
+					break;
+				}
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/TransactionalIdSystemImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/TransactionalIdSystemImpl.cs
new file mode 100644
index 0000000..5552d26
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/TransactionalIdSystemImpl.cs
@@ -0,0 +1,239 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Ids
+{
+	/// <exclude></exclude>
+	public class TransactionalIdSystemImpl : ITransactionalIdSystem
+	{
+		private IdSlotChanges _slotChanges;
+
+		private Db4objects.Db4o.Internal.Ids.TransactionalIdSystemImpl _parentIdSystem;
+
+		private readonly IClosure4 _globalIdSystem;
+
+		public TransactionalIdSystemImpl(IClosure4 freespaceManager, IClosure4 globalIdSystem
+			, Db4objects.Db4o.Internal.Ids.TransactionalIdSystemImpl parentIdSystem)
+		{
+			_globalIdSystem = globalIdSystem;
+			_slotChanges = new IdSlotChanges(this, freespaceManager);
+			_parentIdSystem = parentIdSystem;
+		}
+
+		public virtual void CollectCallBackInfo(ICallbackInfoCollector collector)
+		{
+			if (!_slotChanges.IsDirty())
+			{
+				return;
+			}
+			_slotChanges.TraverseSlotChanges(new _IVisitor4_31(collector));
+		}
+
+		private sealed class _IVisitor4_31 : IVisitor4
+		{
+			public _IVisitor4_31(ICallbackInfoCollector collector)
+			{
+				this.collector = collector;
+			}
+
+			public void Visit(object slotChange)
+			{
+				int id = ((TreeInt)slotChange)._key;
+				if (((SlotChange)slotChange).IsDeleted())
+				{
+					if (!((SlotChange)slotChange).IsNew())
+					{
+						collector.Deleted(id);
+					}
+				}
+				else
+				{
+					if (((SlotChange)slotChange).IsNew())
+					{
+						collector.Added(id);
+					}
+					else
+					{
+						collector.Updated(id);
+					}
+				}
+			}
+
+			private readonly ICallbackInfoCollector collector;
+		}
+
+		public virtual bool IsDirty()
+		{
+			return _slotChanges.IsDirty();
+		}
+
+		public virtual void Commit(FreespaceCommitter freespaceCommitter)
+		{
+			IVisitable slotChangeVisitable = new _IVisitable_52(this);
+			freespaceCommitter.TransactionalIdSystem(this);
+			AccumulateFreeSlots(freespaceCommitter, false);
+			GlobalIdSystem().Commit(slotChangeVisitable, freespaceCommitter);
+		}
+
+		private sealed class _IVisitable_52 : IVisitable
+		{
+			public _IVisitable_52(TransactionalIdSystemImpl _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Accept(IVisitor4 visitor)
+			{
+				this._enclosing.TraverseSlotChanges(visitor);
+			}
+
+			private readonly TransactionalIdSystemImpl _enclosing;
+		}
+
+		public virtual void AccumulateFreeSlots(FreespaceCommitter accumulator, bool forFreespace
+			)
+		{
+			_slotChanges.AccumulateFreeSlots(accumulator, forFreespace, IsSystemIdSystem());
+			if (_parentIdSystem != null)
+			{
+				_parentIdSystem.AccumulateFreeSlots(accumulator, forFreespace);
+			}
+		}
+
+		private bool IsSystemIdSystem()
+		{
+			return _parentIdSystem == null;
+		}
+
+		public virtual void CompleteInterruptedTransaction(int transactionId1, int transactionId2
+			)
+		{
+			GlobalIdSystem().CompleteInterruptedTransaction(transactionId1, transactionId2);
+		}
+
+		public virtual Slot CommittedSlot(int id)
+		{
+			if (id == 0)
+			{
+				return null;
+			}
+			return GlobalIdSystem().CommittedSlot(id);
+		}
+
+		public virtual Slot CurrentSlot(int id)
+		{
+			Slot slot = ModifiedSlot(id);
+			if (slot != null)
+			{
+				return slot;
+			}
+			return CommittedSlot(id);
+		}
+
+		public virtual Slot ModifiedSlot(int id)
+		{
+			if (id == 0)
+			{
+				return null;
+			}
+			SlotChange change = _slotChanges.FindSlotChange(id);
+			if (change != null)
+			{
+				if (change.SlotModified())
+				{
+					return change.NewSlot();
+				}
+			}
+			return ModifiedSlotInParentIdSystem(id);
+		}
+
+		public Slot ModifiedSlotInParentIdSystem(int id)
+		{
+			if (_parentIdSystem == null)
+			{
+				return null;
+			}
+			return _parentIdSystem.ModifiedSlot(id);
+		}
+
+		public virtual void Rollback()
+		{
+			_slotChanges.Rollback();
+		}
+
+		public virtual void Clear()
+		{
+			_slotChanges.Clear();
+		}
+
+		public virtual bool IsDeleted(int id)
+		{
+			return _slotChanges.IsDeleted(id);
+		}
+
+		public virtual void NotifySlotUpdated(int id, Slot slot, SlotChangeFactory slotChangeFactory
+			)
+		{
+			_slotChanges.NotifySlotUpdated(id, slot, slotChangeFactory);
+		}
+
+		private void TraverseSlotChanges(IVisitor4 visitor)
+		{
+			if (_parentIdSystem != null)
+			{
+				_parentIdSystem.TraverseSlotChanges(visitor);
+			}
+			_slotChanges.TraverseSlotChanges(visitor);
+		}
+
+		public virtual int NewId(SlotChangeFactory slotChangeFactory)
+		{
+			int id = AcquireId();
+			_slotChanges.ProduceSlotChange(id, slotChangeFactory).NotifySlotCreated(null);
+			return id;
+		}
+
+		private int AcquireId()
+		{
+			return GlobalIdSystem().NewId();
+		}
+
+		public virtual int PrefetchID()
+		{
+			int id = AcquireId();
+			_slotChanges.AddPrefetchedID(id);
+			return id;
+		}
+
+		public virtual void PrefetchedIDConsumed(int id)
+		{
+			_slotChanges.PrefetchedIDConsumed(id);
+		}
+
+		public virtual void NotifySlotCreated(int id, Slot slot, SlotChangeFactory slotChangeFactory
+			)
+		{
+			_slotChanges.NotifySlotCreated(id, slot, slotChangeFactory);
+		}
+
+		public virtual void NotifySlotDeleted(int id, SlotChangeFactory slotChangeFactory
+			)
+		{
+			_slotChanges.NotifySlotDeleted(id, slotChangeFactory);
+		}
+
+		private IIdSystem GlobalIdSystem()
+		{
+			return ((IIdSystem)_globalIdSystem.Run());
+		}
+
+		public virtual void Close()
+		{
+			_slotChanges.FreePrefetchedIDs(GlobalIdSystem());
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/TransportIdSystem.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/TransportIdSystem.cs
new file mode 100644
index 0000000..ee6866b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Ids/TransportIdSystem.cs
@@ -0,0 +1,103 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Ids
+{
+	/// <exclude></exclude>
+	public sealed class TransportIdSystem : ITransactionalIdSystem
+	{
+		private readonly LocalObjectContainer _container;
+
+		public TransportIdSystem(LocalObjectContainer localObjectContainer)
+		{
+			_container = localObjectContainer;
+		}
+
+		public int NewId(SlotChangeFactory slotChangeFactory)
+		{
+			return _container.AllocatePointerSlot();
+		}
+
+		public void NotifySlotCreated(int id, Slot slot, SlotChangeFactory slotChangeFactory
+			)
+		{
+			WritePointer(id, slot);
+		}
+
+		private void WritePointer(int id, Slot slot)
+		{
+			_container.WritePointer(id, slot);
+		}
+
+		public void NotifySlotUpdated(int id, Slot slot, SlotChangeFactory slotChangeFactory
+			)
+		{
+			WritePointer(id, slot);
+		}
+
+		public void NotifySlotDeleted(int id, SlotChangeFactory slotChangeFactory)
+		{
+			WritePointer(id, Slot.Zero);
+		}
+
+		public void Commit(FreespaceCommitter accumulator)
+		{
+		}
+
+		// don't do anything
+		public Slot CurrentSlot(int id)
+		{
+			return CommittedSlot(id);
+		}
+
+		public void CollectCallBackInfo(ICallbackInfoCollector collector)
+		{
+		}
+
+		// do nothing
+		public void Clear()
+		{
+		}
+
+		// TODO Auto-generated method stub
+		public Slot CommittedSlot(int id)
+		{
+			return _container.ReadPointerSlot(id);
+		}
+
+		public bool IsDeleted(int id)
+		{
+			return false;
+		}
+
+		public bool IsDirty()
+		{
+			return false;
+		}
+
+		public int PrefetchID()
+		{
+			return 0;
+		}
+
+		public void PrefetchedIDConsumed(int id)
+		{
+		}
+
+		public void Rollback()
+		{
+		}
+
+		public void Close()
+		{
+		}
+
+		public void AccumulateFreeSlots(FreespaceCommitter freespaceCommitter, bool forFreespace
+			)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IllegalComparisonException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IllegalComparisonException.cs
new file mode 100644
index 0000000..05f734a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IllegalComparisonException.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	[System.Serializable]
+	public class IllegalComparisonException : Db4oRecoverableException
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/InCallback.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/InCallback.cs
new file mode 100644
index 0000000..0a44c5b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/InCallback.cs
@@ -0,0 +1,35 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class InCallback
+	{
+		private sealed class _DynamicVariable_12 : DynamicVariable
+		{
+			public _DynamicVariable_12()
+			{
+			}
+
+			protected override object DefaultValue()
+			{
+				return false;
+			}
+		}
+
+		private static readonly DynamicVariable _inCallback = new _DynamicVariable_12();
+
+		public static bool Value()
+		{
+			return (((bool)_inCallback.Value));
+		}
+
+		public static void Run(IRunnable runnable)
+		{
+			_inCallback.With(true, runnable);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IntMatcher.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IntMatcher.cs
new file mode 100644
index 0000000..c9c8b9d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IntMatcher.cs
@@ -0,0 +1,54 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public abstract class IntMatcher
+	{
+		public abstract bool Match(int i);
+
+		private sealed class _IntMatcher_13 : IntMatcher
+		{
+			public _IntMatcher_13()
+			{
+			}
+
+			public override bool Match(int i)
+			{
+				return i == 0;
+			}
+		}
+
+		public static readonly IntMatcher Zero = new _IntMatcher_13();
+
+		private sealed class _IntMatcher_19 : IntMatcher
+		{
+			public _IntMatcher_19()
+			{
+			}
+
+			public override bool Match(int i)
+			{
+				return i > 0;
+			}
+		}
+
+		public static readonly IntMatcher Positive = new _IntMatcher_19();
+
+		private sealed class _IntMatcher_25 : IntMatcher
+		{
+			public _IntMatcher_25()
+			{
+			}
+
+			public override bool Match(int i)
+			{
+				return i < 0;
+			}
+		}
+
+		public static readonly IntMatcher Negative = new _IntMatcher_25();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/InterfaceTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/InterfaceTypeHandler.cs
new file mode 100644
index 0000000..85ecd71
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/InterfaceTypeHandler.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	public sealed class InterfaceTypeHandler : OpenTypeHandler
+	{
+		public InterfaceTypeHandler(ObjectContainerBase container) : base(container)
+		{
+		}
+
+		public override bool Equals(object obj)
+		{
+			return obj is Db4objects.Db4o.Internal.InterfaceTypeHandler;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IoAdaptedObjectContainer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IoAdaptedObjectContainer.cs
new file mode 100644
index 0000000..cdda686
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/IoAdaptedObjectContainer.cs
@@ -0,0 +1,441 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.IO;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Slots;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class IoAdaptedObjectContainer : LocalObjectContainer, IEmbeddedObjectContainer
+	{
+		private readonly string _fileName;
+
+		private BlockAwareBin _file;
+
+		private volatile BlockAwareBin _backupFile;
+
+		private object _fileLock;
+
+		private readonly IFreespaceFiller _freespaceFiller;
+
+		/// <exception cref="Db4objects.Db4o.Ext.OldFormatException"></exception>
+		internal IoAdaptedObjectContainer(IConfiguration config, string fileName) : base(
+			config)
+		{
+			_fileLock = new object();
+			_fileName = fileName;
+			_freespaceFiller = CreateFreespaceFiller();
+			Open();
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.OldFormatException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		protected sealed override void OpenImpl()
+		{
+			Config4Impl configImpl = ConfigImpl;
+			IStorage storage = configImpl.Storage;
+			bool isNew = !storage.Exists(FileName());
+			if (isNew)
+			{
+				LogMsg(14, FileName());
+				CheckReadOnly();
+				_handlers.OldEncryptionOff();
+			}
+			bool readOnly = configImpl.IsReadOnly();
+			bool lockFile = Debug4.lockFile && configImpl.LockFile() && (!readOnly);
+			if (NeedsLockFileThread())
+			{
+				IBin fileBin = storage.Open(new BinConfiguration(FileName(), false, 0, false, configImpl
+					.BlockSize()));
+				IBin synchronizedBin = new SynchronizedBin(fileBin);
+				_file = new BlockAwareBin(synchronizedBin);
+			}
+			else
+			{
+				IBin bin = storage.Open(new BinConfiguration(FileName(), lockFile, 0, readOnly, configImpl
+					.BlockSize()));
+				if (configImpl.AsynchronousSync())
+				{
+					bin = new ThreadedSyncBin(bin);
+				}
+				_file = new BlockAwareBin(bin);
+			}
+			if (isNew)
+			{
+				ConfigureNewFile();
+				if (configImpl.ReservedStorageSpace() > 0)
+				{
+					Reserve(configImpl.ReservedStorageSpace());
+				}
+				CommitTransaction();
+				WriteHeader(true, false);
+			}
+			else
+			{
+				ReadThis();
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Backup(IStorage targetStorage, string path)
+		{
+			WithEnvironment(new _IRunnable_76(this, targetStorage, path));
+		}
+
+		private sealed class _IRunnable_76 : IRunnable
+		{
+			public _IRunnable_76(IoAdaptedObjectContainer _enclosing, IStorage targetStorage, 
+				string path)
+			{
+				this._enclosing = _enclosing;
+				this.targetStorage = targetStorage;
+				this.path = path;
+			}
+
+			public void Run()
+			{
+				lock (this._enclosing._lock)
+				{
+					this._enclosing.CheckClosed();
+					if (this._enclosing._backupFile != null)
+					{
+						throw new BackupInProgressException();
+					}
+					this._enclosing._backupFile = new BlockAwareBin(targetStorage.Open(new BinConfiguration
+						(path, true, this._enclosing._file.Length(), false, this._enclosing._blockConverter
+						.BlocksToBytes(1))));
+				}
+				long pos = 0;
+				byte[] buffer = new byte[8192];
+				while (true)
+				{
+					lock (this._enclosing._lock)
+					{
+						int read = this._enclosing._file.Read(pos, buffer);
+						if (read <= 0)
+						{
+							break;
+						}
+						this._enclosing._backupFile.Write(pos, buffer, read);
+						pos += read;
+					}
+					// Let the database engine continue to do 
+					// some work if it likes to.
+					Runtime4.Sleep(1);
+				}
+				lock (this._enclosing._lock)
+				{
+					try
+					{
+						Db4objects.Db4o.Internal.IoAdaptedObjectContainer.SyncAndClose(this._enclosing._backupFile
+							);
+					}
+					finally
+					{
+						this._enclosing._backupFile = null;
+					}
+				}
+			}
+
+			private readonly IoAdaptedObjectContainer _enclosing;
+
+			private readonly IStorage targetStorage;
+
+			private readonly string path;
+		}
+
+		public override void BlockSize(int size)
+		{
+			CreateBlockConverter(size);
+			_file.BlockSize(size);
+		}
+
+		public override byte BlockSize()
+		{
+			return (byte)_file.BlockSize();
+		}
+
+		protected override void ShutdownDataStorage()
+		{
+			lock (_fileLock)
+			{
+				try
+				{
+					CloseFileHeader();
+				}
+				finally
+				{
+					CloseDatabaseFile();
+				}
+			}
+		}
+
+		private void CloseDatabaseFile()
+		{
+			try
+			{
+				SyncAndClose(_file);
+			}
+			finally
+			{
+				_file = null;
+			}
+		}
+
+		private static void SyncAndClose(IBin bin)
+		{
+			if (bin != null)
+			{
+				try
+				{
+					bin.Sync();
+				}
+				finally
+				{
+					bin.Close();
+				}
+			}
+		}
+
+		private void CloseFileHeader()
+		{
+			try
+			{
+				if (_fileHeader != null)
+				{
+					_fileHeader.Close();
+				}
+			}
+			finally
+			{
+				_fileHeader = null;
+			}
+		}
+
+		public override void CloseTransaction(Transaction transaction, bool isSystemTransaction
+			, bool rollbackOnClose)
+		{
+			transaction.Close(rollbackOnClose);
+		}
+
+		public override void Commit1(Transaction trans)
+		{
+			EnsureLastSlotWritten();
+			base.Commit1(trans);
+		}
+
+		private void CheckXBytes(int newAddress, int newAddressOffset, int length)
+		{
+			if (Debug4.xbytes && Deploy.overwrite)
+			{
+				try
+				{
+					byte[] checkXBytes = new byte[length];
+					_file.BlockRead(newAddress, newAddressOffset, checkXBytes);
+					for (int i = 0; i < checkXBytes.Length; i++)
+					{
+						if (checkXBytes[i] != Const4.Xbyte)
+						{
+							string msg = "XByte corruption adress:" + newAddress + " length:" + length + " starting:"
+								 + i;
+							throw new Db4oException(msg);
+						}
+					}
+				}
+				catch (Exception e)
+				{
+					Sharpen.Runtime.PrintStackTrace(e);
+				}
+			}
+		}
+
+		public override long FileLength()
+		{
+			return _file.Length();
+		}
+
+		public override string FileName()
+		{
+			return _fileName;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void ReadBytes(byte[] bytes, int address, int length)
+		{
+			ReadBytes(bytes, address, 0, length);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void ReadBytes(byte[] bytes, int address, int addressOffset, int 
+			length)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.ReadBytes.LogLength(address + addressOffset, length);
+			}
+			int bytesRead = _file.BlockRead(address, addressOffset, bytes, length);
+			CheckReadCount(bytesRead, length);
+		}
+
+		private void CheckReadCount(int bytesRead, int expected)
+		{
+			if (bytesRead != expected)
+			{
+				throw new IncompatibleFileFormatException();
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		public override void Reserve(int byteCount)
+		{
+			CheckReadOnly();
+			lock (_lock)
+			{
+				Slot slot = AllocateSlot(byteCount);
+				ZeroReservedSlot(slot);
+				Free(slot);
+			}
+		}
+
+		private void ZeroReservedSlot(Slot slot)
+		{
+			ZeroFile(_file, slot);
+			ZeroFile(_backupFile, slot);
+		}
+
+		private void ZeroFile(BlockAwareBin io, Slot slot)
+		{
+			if (io == null)
+			{
+				return;
+			}
+			byte[] zeroBytes = new byte[1024];
+			int left = slot.Length();
+			int offset = 0;
+			while (left > zeroBytes.Length)
+			{
+				io.BlockWrite(slot.Address(), offset, zeroBytes, zeroBytes.Length);
+				offset += zeroBytes.Length;
+				left -= zeroBytes.Length;
+			}
+			if (left > 0)
+			{
+				io.BlockWrite(slot.Address(), offset, zeroBytes, left);
+			}
+		}
+
+		public override void SyncFiles()
+		{
+			_file.Sync();
+		}
+
+		public override void SyncFiles(IRunnable runnable)
+		{
+			_file.Sync(runnable);
+		}
+
+		public override void WriteBytes(ByteArrayBuffer buffer, int blockedAddress, int addressOffset
+			)
+		{
+			if (Deploy.debug && !Deploy.flush)
+			{
+				return;
+			}
+			if (Debug4.xbytes && Deploy.overwrite)
+			{
+				if (buffer.CheckXBytes())
+				{
+					CheckXBytes(blockedAddress, addressOffset, buffer.Length());
+				}
+				else
+				{
+					buffer.CheckXBytes(true);
+				}
+			}
+			if (DTrace.enabled)
+			{
+				DTrace.WriteBytes.LogLength(blockedAddress + addressOffset, buffer.Length());
+			}
+			_file.BlockWrite(blockedAddress, addressOffset, buffer._buffer, buffer.Length());
+			if (_backupFile != null)
+			{
+				_backupFile.BlockWrite(blockedAddress, addressOffset, buffer._buffer, buffer.Length
+					());
+			}
+		}
+
+		public override void OverwriteDeletedBytes(int address, int length)
+		{
+			if (_freespaceFiller == null)
+			{
+				return;
+			}
+			if (address > 0 && length > 0)
+			{
+				if (DTrace.enabled)
+				{
+					DTrace.WriteXbytes.LogLength(address, length);
+				}
+				BlockAwareBinWindow window = new BlockAwareBinWindow(_file, address, length);
+				try
+				{
+					CreateFreespaceFiller().Fill(window);
+				}
+				catch (IOException e)
+				{
+					Sharpen.Runtime.PrintStackTrace(e);
+				}
+				finally
+				{
+					window.Disable();
+				}
+			}
+		}
+
+		public virtual BlockAwareBin TimerFile()
+		{
+			return _file;
+		}
+
+		private IFreespaceFiller CreateFreespaceFiller()
+		{
+			return Config().FreespaceFiller();
+		}
+
+		private class XByteFreespaceFiller : IFreespaceFiller
+		{
+			/// <exception cref="System.IO.IOException"></exception>
+			public virtual void Fill(BlockAwareBinWindow io)
+			{
+				io.Write(0, XBytes(io.Length()));
+			}
+
+			private byte[] XBytes(int len)
+			{
+				byte[] bytes = new byte[len];
+				for (int i = 0; i < len; i++)
+				{
+					bytes[i] = Const4.Xbyte;
+				}
+				return bytes;
+			}
+		}
+
+		protected override void FatalStorageShutdown()
+		{
+			if (_file != null)
+			{
+				_file.Close();
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/LazyObjectReference.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/LazyObjectReference.cs
new file mode 100644
index 0000000..a43fc1e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/LazyObjectReference.cs
@@ -0,0 +1,68 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class LazyObjectReference : IObjectInfo
+	{
+		private readonly Transaction _transaction;
+
+		private readonly int _id;
+
+		public LazyObjectReference(Transaction transaction, int id)
+		{
+			_transaction = transaction;
+			_id = id;
+		}
+
+		public virtual long GetInternalID()
+		{
+			return _id;
+		}
+
+		public virtual object GetObject()
+		{
+			lock (ContainerLock())
+			{
+				return Reference().GetObject();
+			}
+		}
+
+		public virtual Db4oUUID GetUUID()
+		{
+			lock (ContainerLock())
+			{
+				return Reference().GetUUID();
+			}
+		}
+
+		public virtual long GetVersion()
+		{
+			return GetCommitTimestamp();
+		}
+
+		public virtual long GetCommitTimestamp()
+		{
+			lock (ContainerLock())
+			{
+				return Reference().GetCommitTimestamp();
+			}
+		}
+
+		public virtual ObjectReference Reference()
+		{
+			HardObjectReference hardRef = _transaction.Container().GetHardObjectReferenceById
+				(_transaction, _id);
+			return hardRef._reference;
+		}
+
+		private object ContainerLock()
+		{
+			_transaction.Container().CheckClosed();
+			return _transaction.Container().Lock();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/LocalObjectContainer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/LocalObjectContainer.cs
new file mode 100644
index 0000000..726e4f9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/LocalObjectContainer.cs
@@ -0,0 +1,1146 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Convert;
+using Db4objects.Db4o.Internal.Events;
+using Db4objects.Db4o.Internal.Fileheader;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Qlin;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Internal.Query.Result;
+using Db4objects.Db4o.Internal.References;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Qlin;
+using Sharpen;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public abstract class LocalObjectContainer : ExternalObjectContainer, IInternalObjectContainer
+		, IEmbeddedObjectContainer
+	{
+		protected FileHeader _fileHeader;
+
+		private readonly Collection4 _dirtyClassMetadata = new Collection4();
+
+		private IFreespaceManager _freespaceManager;
+
+		private bool i_isServer = false;
+
+		private Lock4 _semaphoresLock = new Lock4();
+
+		private Hashtable4 _semaphores;
+
+		private int _blockEndAddress;
+
+		private Db4objects.Db4o.Internal.SystemData _systemData;
+
+		private IIdSystem _idSystem;
+
+		private readonly byte[] _pointerBuffer = new byte[Const4.PointerLength];
+
+		protected readonly ByteArrayBuffer _pointerIo = new ByteArrayBuffer(Const4.PointerLength
+			);
+
+		internal LocalObjectContainer(IConfiguration config) : base(config)
+		{
+		}
+
+		public override Transaction NewTransaction(Transaction parentTransaction, IReferenceSystem
+			 referenceSystem, bool isSystemTransaction)
+		{
+			ITransactionalIdSystem systemIdSystem = null;
+			if (!isSystemTransaction)
+			{
+				systemIdSystem = SystemTransaction().IdSystem();
+			}
+			IClosure4 idSystem = new _IClosure4_58(this);
+			ITransactionalIdSystem transactionalIdSystem = NewTransactionalIdSystem(systemIdSystem
+				, idSystem);
+			return new LocalTransaction(this, parentTransaction, transactionalIdSystem, referenceSystem
+				);
+		}
+
+		private sealed class _IClosure4_58 : IClosure4
+		{
+			public _IClosure4_58(LocalObjectContainer _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Run()
+			{
+				return this._enclosing.IdSystem();
+			}
+
+			private readonly LocalObjectContainer _enclosing;
+		}
+
+		public virtual ITransactionalIdSystem NewTransactionalIdSystem(ITransactionalIdSystem
+			 systemIdSystem, IClosure4 idSystem)
+		{
+			return new TransactionalIdSystemImpl(new _IClosure4_69(this), idSystem, (TransactionalIdSystemImpl
+				)systemIdSystem);
+		}
+
+		private sealed class _IClosure4_69 : IClosure4
+		{
+			public _IClosure4_69(LocalObjectContainer _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Run()
+			{
+				return this._enclosing.FreespaceManager();
+			}
+
+			private readonly LocalObjectContainer _enclosing;
+		}
+
+		public virtual IFreespaceManager FreespaceManager()
+		{
+			return _freespaceManager;
+		}
+
+		public virtual void BlockSizeReadFromFile(int size)
+		{
+			BlockSize(size);
+			SetRegularEndAddress(FileLength());
+		}
+
+		public virtual void SetRegularEndAddress(long address)
+		{
+			_blockEndAddress = _blockConverter.BytesToBlocks(address);
+		}
+
+		protected sealed override void Close2()
+		{
+			try
+			{
+				if (!_config.IsReadOnly())
+				{
+					CommitTransaction();
+					Shutdown();
+				}
+			}
+			finally
+			{
+				ShutdownObjectContainer();
+			}
+		}
+
+		public override void Commit1(Transaction trans)
+		{
+			trans.Commit();
+		}
+
+		internal virtual void ConfigureNewFile()
+		{
+			BlockSize(ConfigImpl.BlockSize());
+			_fileHeader = FileHeader.NewCurrentFileHeader();
+			SetRegularEndAddress(_fileHeader.Length());
+			NewSystemData(ConfigImpl.FreespaceSystem(), ConfigImpl.IdSystemType());
+			SystemData().ConverterVersion(Converter.Version);
+			CreateStringIO(_systemData.StringEncoding());
+			CreateIdSystem();
+			InitializeClassMetadataRepository();
+			InitalizeWeakReferenceSupport();
+			GenerateNewIdentity();
+			AbstractFreespaceManager blockedFreespaceManager = AbstractFreespaceManager.CreateNew
+				(this);
+			InstallFreespaceManager(blockedFreespaceManager);
+			InitNewClassCollection();
+			InitializeEssentialClasses();
+			_fileHeader.InitNew(this);
+			blockedFreespaceManager.Start(0);
+		}
+
+		private void NewSystemData(byte freespaceSystemType, byte idSystemType)
+		{
+			_systemData = new Db4objects.Db4o.Internal.SystemData();
+			_systemData.StringEncoding(ConfigImpl.Encoding());
+			_systemData.FreespaceSystem(freespaceSystemType);
+			_systemData.IdSystemType(idSystemType);
+		}
+
+		public override int ConverterVersion()
+		{
+			return _systemData.ConverterVersion();
+		}
+
+		public override long CurrentVersion()
+		{
+			return _timeStampIdGenerator.Last();
+		}
+
+		internal virtual void InitNewClassCollection()
+		{
+			// overridden in YapObjectCarrier to do nothing
+			ClassCollection().InitTables(1);
+		}
+
+		public BTree CreateBTreeClassIndex(int id)
+		{
+			return new BTree(_transaction, id, new IDHandler());
+		}
+
+		public AbstractQueryResult NewQueryResult(Transaction trans)
+		{
+			return NewQueryResult(trans, Config().EvaluationMode());
+		}
+
+		public sealed override AbstractQueryResult NewQueryResult(Transaction trans, QueryEvaluationMode
+			 mode)
+		{
+			if (trans == null)
+			{
+				throw new ArgumentNullException();
+			}
+			if (mode == QueryEvaluationMode.Immediate)
+			{
+				return new IdListQueryResult(trans);
+			}
+			return new HybridQueryResult(trans, mode);
+		}
+
+		public sealed override bool Delete4(Transaction transaction, ObjectReference @ref
+			, object obj, int cascade, bool userCall)
+		{
+			int id = @ref.GetID();
+			StatefulBuffer reader = ReadStatefulBufferById(transaction, id);
+			if (reader != null)
+			{
+				if (obj != null)
+				{
+					if ((!ShowInternalClasses()) && Const4.ClassInternal.IsAssignableFrom(obj.GetType
+						()))
+					{
+						return false;
+					}
+				}
+				reader.SetCascadeDeletes(cascade);
+				transaction.IdSystem().NotifySlotDeleted(id, SlotChangeFactory.UserObjects);
+				ClassMetadata classMetadata = @ref.ClassMetadata();
+				classMetadata.Delete(reader, obj);
+				return true;
+			}
+			return false;
+		}
+
+		public abstract long FileLength();
+
+		public abstract string FileName();
+
+		public virtual void Free(Slot slot)
+		{
+			if (slot.IsNull())
+			{
+				return;
+			}
+			// TODO: This should really be an IllegalArgumentException but old database files 
+			//       with index-based FreespaceManagers appear to deliver zeroed slots.
+			// throw new IllegalArgumentException();
+			if (_freespaceManager == null)
+			{
+				// Can happen on early free before freespacemanager
+				// is up, during conversion.
+				return;
+			}
+			if (DTrace.enabled)
+			{
+				DTrace.FileFree.LogLength(slot.Address(), slot.Length());
+			}
+			_freespaceManager.Free(slot);
+		}
+
+		public virtual void Free(int address, int a_length)
+		{
+			Free(new Slot(address, a_length));
+		}
+
+		public virtual void GenerateNewIdentity()
+		{
+			lock (_lock)
+			{
+				SetIdentity(Db4oDatabase.Generate());
+			}
+		}
+
+		public override AbstractQueryResult QueryAllObjects(Transaction trans)
+		{
+			return GetAll(trans, Config().EvaluationMode());
+		}
+
+		public virtual AbstractQueryResult GetAll(Transaction trans, QueryEvaluationMode 
+			mode)
+		{
+			AbstractQueryResult queryResult = NewQueryResult(trans, mode);
+			queryResult.LoadFromClassIndexes(ClassCollection().Iterator());
+			return queryResult;
+		}
+
+		public virtual int AllocatePointerSlot()
+		{
+			int id = AllocateSlot(Const4.PointerLength).Address();
+			if (!IsValidPointer(id))
+			{
+				return AllocatePointerSlot();
+			}
+			// write a zero pointer first
+			// to prevent delete interaction trouble
+			WritePointer(id, Slot.Zero);
+			if (DTrace.enabled)
+			{
+				DTrace.GetPointerSlot.Log(id);
+			}
+			return id;
+		}
+
+		protected virtual bool IsValidPointer(int id)
+		{
+			// We have to make sure that object IDs do not collide
+			// with built-in type IDs.
+			return !_handlers.IsSystemHandler(id);
+		}
+
+		public virtual Slot AllocateSlot(int length)
+		{
+			if (length <= 0)
+			{
+				throw new ArgumentException();
+			}
+			if (_freespaceManager != null && _freespaceManager.IsStarted())
+			{
+				Slot slot = _freespaceManager.AllocateSlot(length);
+				if (slot != null)
+				{
+					if (DTrace.enabled)
+					{
+						DTrace.GetSlot.LogLength(slot.Address(), slot.Length());
+					}
+					return slot;
+				}
+				while (GrowDatabaseByConfiguredSize())
+				{
+					slot = _freespaceManager.AllocateSlot(length);
+					if (slot != null)
+					{
+						if (DTrace.enabled)
+						{
+							DTrace.GetSlot.LogLength(slot.Address(), slot.Length());
+						}
+						return slot;
+					}
+				}
+			}
+			Slot appendedSlot = AppendBytes(length);
+			if (DTrace.enabled)
+			{
+				DTrace.GetSlot.LogLength(appendedSlot.Address(), appendedSlot.Length());
+			}
+			return appendedSlot;
+		}
+
+		private bool GrowDatabaseByConfiguredSize()
+		{
+			int reservedStorageSpace = ConfigImpl.DatabaseGrowthSize();
+			if (reservedStorageSpace <= 0)
+			{
+				return false;
+			}
+			int reservedBlocks = _blockConverter.BytesToBlocks(reservedStorageSpace);
+			int reservedBytes = _blockConverter.BlocksToBytes(reservedBlocks);
+			Slot slot = new Slot(_blockEndAddress, reservedBlocks);
+			if (Debug4.xbytes && Deploy.overwrite)
+			{
+				OverwriteDeletedBlockedSlot(slot);
+			}
+			else
+			{
+				WriteBytes(new ByteArrayBuffer(reservedBytes), _blockEndAddress, 0);
+			}
+			_freespaceManager.Free(_blockConverter.ToNonBlockedLength(slot));
+			_blockEndAddress += reservedBlocks;
+			return true;
+		}
+
+		public Slot AppendBytes(long bytes)
+		{
+			int blockCount = _blockConverter.BytesToBlocks(bytes);
+			int blockedStartAddress = _blockEndAddress;
+			int blockedEndAddress = _blockEndAddress + blockCount;
+			CheckBlockedAddress(blockedEndAddress);
+			_blockEndAddress = blockedEndAddress;
+			Slot slot = new Slot(blockedStartAddress, blockCount);
+			if (Debug4.xbytes && Deploy.overwrite)
+			{
+				OverwriteDeletedBlockedSlot(slot);
+			}
+			return _blockConverter.ToNonBlockedLength(slot);
+		}
+
+		private void CheckBlockedAddress(int blockedAddress)
+		{
+			if (blockedAddress < 0)
+			{
+				SwitchToReadOnlyMode();
+				throw new DatabaseMaximumSizeReachedException();
+			}
+		}
+
+		private void SwitchToReadOnlyMode()
+		{
+			_config.ReadOnly(true);
+		}
+
+		// When a file gets opened, it uses the file size to determine where 
+		// new slots can be appended. If this method would not be called, the
+		// freespace system could already contain a slot that points beyond
+		// the end of the file and this space could be allocated and used twice,
+		// for instance if a slot was allocated and freed without ever being
+		// written to file.
+		internal virtual void EnsureLastSlotWritten()
+		{
+			if (_blockEndAddress > _blockConverter.BytesToBlocks(FileLength()))
+			{
+				StatefulBuffer writer = CreateStatefulBuffer(SystemTransaction(), _blockEndAddress
+					 - 1, BlockSize());
+				writer.Write();
+			}
+		}
+
+		public override Db4oDatabase Identity()
+		{
+			return _systemData.Identity();
+		}
+
+		public virtual void SetIdentity(Db4oDatabase identity)
+		{
+			lock (Lock())
+			{
+				_systemData.Identity(identity);
+				// The dirty TimeStampIdGenerator triggers writing of
+				// the variable part of the systemdata. We need to
+				// make it dirty here, so the new identity is persisted:
+				_timeStampIdGenerator.Generate();
+				_fileHeader.WriteVariablePart(this);
+			}
+		}
+
+		internal override bool IsServer()
+		{
+			return i_isServer;
+		}
+
+		public sealed override int IdForNewUserObject(Transaction trans)
+		{
+			return trans.IdSystem().NewId(SlotChangeFactory.UserObjects);
+		}
+
+		public override void RaiseCommitTimestamp(long minimumVersion)
+		{
+			lock (Lock())
+			{
+				_timeStampIdGenerator.SetMinimumNext(minimumVersion);
+			}
+		}
+
+		public override StatefulBuffer ReadStatefulBufferById(Transaction a_ta, int a_id)
+		{
+			return ReadStatefulBufferById(a_ta, a_id, false);
+		}
+
+		public override ByteArrayBuffer[] ReadSlotBuffers(Transaction transaction, int[] 
+			ids)
+		{
+			ByteArrayBuffer[] buffers = new ByteArrayBuffer[ids.Length];
+			for (int i = 0; i < ids.Length; ++i)
+			{
+				if (ids[i] == 0)
+				{
+					buffers[i] = null;
+				}
+				else
+				{
+					buffers[i] = ReadBufferById(transaction, ids[i]);
+				}
+			}
+			return buffers;
+		}
+
+		public override ByteArrayBuffer ReadBufferById(Transaction trans, int id)
+		{
+			return ReadBufferById(trans, id, false);
+		}
+
+		public sealed override ByteArrayBuffer ReadBufferById(Transaction trans, int id, 
+			bool lastCommitted)
+		{
+			if (id <= 0)
+			{
+				throw new ArgumentException();
+			}
+			Slot slot = lastCommitted ? trans.IdSystem().CommittedSlot(id) : trans.IdSystem()
+				.CurrentSlot(id);
+			if (DTrace.enabled)
+			{
+				DTrace.SlotRead.LogLength(id, slot);
+			}
+			return ReadBufferBySlot(slot);
+		}
+
+		public override StatefulBuffer ReadStatefulBufferById(Transaction trans, int id, 
+			bool lastCommitted)
+		{
+			if (id <= 0)
+			{
+				throw new ArgumentException();
+			}
+			Slot slot = lastCommitted ? trans.IdSystem().CommittedSlot(id) : trans.IdSystem()
+				.CurrentSlot(id);
+			if (DTrace.enabled)
+			{
+				DTrace.SlotRead.LogLength(id, slot);
+			}
+			return ReadStatefulBufferBySlot(trans, id, slot);
+		}
+
+		public virtual ByteArrayBuffer ReadBufferBySlot(Slot slot)
+		{
+			if (Slot.IsNull(slot))
+			{
+				return null;
+			}
+			if (DTrace.enabled)
+			{
+				DTrace.ReadSlot.LogLength(slot.Address(), slot.Length());
+			}
+			ByteArrayBuffer buffer = new ByteArrayBuffer(slot.Length());
+			buffer.ReadEncrypt(this, slot.Address());
+			return buffer;
+		}
+
+		public virtual StatefulBuffer ReadStatefulBufferBySlot(Transaction trans, int id, 
+			Slot slot)
+		{
+			if (Slot.IsNull(slot))
+			{
+				return null;
+			}
+			if (DTrace.enabled)
+			{
+				DTrace.ReadSlot.LogLength(slot.Address(), slot.Length());
+			}
+			StatefulBuffer buffer = CreateStatefulBuffer(trans, slot.Address(), slot.Length()
+				);
+			buffer.SetID(id);
+			buffer.ReadEncrypt(this, slot.Address());
+			return buffer;
+		}
+
+		protected override bool DoFinalize()
+		{
+			return _fileHeader != null;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.OldFormatException"></exception>
+		internal virtual void ReadThis()
+		{
+			NewSystemData(AbstractFreespaceManager.FmLegacyRam, StandardIdSystemFactory.Legacy
+				);
+			BlockSizeReadFromFile(1);
+			_fileHeader = FileHeader.Read(this);
+			if (Config().GenerateCommitTimestamps().IsUnspecified())
+			{
+				Config().GenerateCommitTimestamps(_systemData.IdToTimestampIndexId() != 0);
+			}
+			CreateStringIO(_systemData.StringEncoding());
+			CreateIdSystem();
+			InitializeClassMetadataRepository();
+			InitalizeWeakReferenceSupport();
+			SetNextTimeStampId(SystemData().LastTimeStampID());
+			ClassCollection().SetID(_systemData.ClassCollectionID());
+			ClassCollection().Read(SystemTransaction());
+			Converter.Convert(new ConversionStage.ClassCollectionAvailableStage(this));
+			_fileHeader.ReadIdentity(this);
+			if (_config.IsReadOnly())
+			{
+				return;
+			}
+			if (!ConfigImpl.CommitRecoveryDisabled())
+			{
+				_fileHeader.CompleteInterruptedTransaction(this);
+			}
+			IFreespaceManager blockedFreespaceManager = AbstractFreespaceManager.CreateNew(this
+				, _systemData.FreespaceSystem());
+			InstallFreespaceManager(blockedFreespaceManager);
+			blockedFreespaceManager.Read(this, _systemData.InMemoryFreespaceSlot());
+			blockedFreespaceManager.Start(_systemData.BTreeFreespaceId());
+			_fileHeader = _fileHeader.Convert(this);
+			if (FreespaceMigrationRequired(blockedFreespaceManager))
+			{
+				MigrateFreespace(blockedFreespaceManager);
+			}
+			WriteHeader(true, false);
+			if (Converter.Convert(new ConversionStage.SystemUpStage(this)))
+			{
+				_systemData.ConverterVersion(Converter.Version);
+				_fileHeader.WriteVariablePart(this);
+				Transaction.Commit();
+			}
+		}
+
+		private void InstallFreespaceManager(IFreespaceManager blockedFreespaceManager)
+		{
+			_freespaceManager = BlockSize() == 1 ? blockedFreespaceManager : new BlockAwareFreespaceManager
+				(blockedFreespaceManager, _blockConverter);
+		}
+
+		protected virtual void CreateIdSystem()
+		{
+			_idSystem = StandardIdSystemFactory.NewInstance(this);
+		}
+
+		private bool FreespaceMigrationRequired(IFreespaceManager freespaceManager)
+		{
+			if (freespaceManager == null)
+			{
+				return false;
+			}
+			byte readSystem = _systemData.FreespaceSystem();
+			byte configuredSystem = ConfigImpl.FreespaceSystem();
+			if (freespaceManager.SystemType() == configuredSystem)
+			{
+				return false;
+			}
+			if (configuredSystem != 0)
+			{
+				return true;
+			}
+			return AbstractFreespaceManager.MigrationRequired(readSystem);
+		}
+
+		private void MigrateFreespace(IFreespaceManager oldFreespaceManager)
+		{
+			IFreespaceManager newFreespaceManager = AbstractFreespaceManager.CreateNew(this, 
+				ConfigImpl.FreespaceSystem());
+			newFreespaceManager.Start(0);
+			SystemData().FreespaceSystem(ConfigImpl.FreespaceSystem());
+			InstallFreespaceManager(newFreespaceManager);
+			AbstractFreespaceManager.Migrate(oldFreespaceManager, newFreespaceManager);
+			_fileHeader.WriteVariablePart(this);
+		}
+
+		public sealed override void ReleaseSemaphore(string name)
+		{
+			ReleaseSemaphore(null, name);
+		}
+
+		public sealed override void ReleaseSemaphore(Transaction trans, string name)
+		{
+			lock (_lock)
+			{
+				if (_semaphores == null)
+				{
+					return;
+				}
+			}
+			_semaphoresLock.Run(new _IClosure4_574(this, trans, name));
+		}
+
+		private sealed class _IClosure4_574 : IClosure4
+		{
+			public _IClosure4_574(LocalObjectContainer _enclosing, Transaction trans, string 
+				name)
+			{
+				this._enclosing = _enclosing;
+				this.trans = trans;
+				this.name = name;
+			}
+
+			public object Run()
+			{
+				Transaction transaction = this._enclosing.CheckTransaction(trans);
+				if (this._enclosing._semaphores != null && transaction == this._enclosing._semaphores
+					.Get(name))
+				{
+					this._enclosing._semaphores.Remove(name);
+				}
+				this._enclosing._semaphoresLock.Awake();
+				return null;
+			}
+
+			private readonly LocalObjectContainer _enclosing;
+
+			private readonly Transaction trans;
+
+			private readonly string name;
+		}
+
+		public override void ReleaseSemaphores(Transaction trans)
+		{
+			if (_semaphores != null)
+			{
+				Hashtable4 semaphores = _semaphores;
+				_semaphoresLock.Run(new _IClosure4_588(this, semaphores, trans));
+			}
+		}
+
+		private sealed class _IClosure4_588 : IClosure4
+		{
+			public _IClosure4_588(LocalObjectContainer _enclosing, Hashtable4 semaphores, Transaction
+				 trans)
+			{
+				this._enclosing = _enclosing;
+				this.semaphores = semaphores;
+				this.trans = trans;
+			}
+
+			public object Run()
+			{
+				semaphores.ForEachKeyForIdentity(new _IVisitor4_589(semaphores), trans);
+				this._enclosing._semaphoresLock.Awake();
+				return null;
+			}
+
+			private sealed class _IVisitor4_589 : IVisitor4
+			{
+				public _IVisitor4_589(Hashtable4 semaphores)
+				{
+					this.semaphores = semaphores;
+				}
+
+				public void Visit(object a_object)
+				{
+					semaphores.Remove(a_object);
+				}
+
+				private readonly Hashtable4 semaphores;
+			}
+
+			private readonly LocalObjectContainer _enclosing;
+
+			private readonly Hashtable4 semaphores;
+
+			private readonly Transaction trans;
+		}
+
+		public sealed override void Rollback1(Transaction trans)
+		{
+			trans.Rollback();
+		}
+
+		public sealed override void SetDirtyInSystemTransaction(PersistentBase a_object)
+		{
+			a_object.SetStateDirty();
+			a_object.CacheDirty(_dirtyClassMetadata);
+		}
+
+		public sealed override bool SetSemaphore(string name, int timeout)
+		{
+			return SetSemaphore(null, name, timeout);
+		}
+
+		public sealed override bool SetSemaphore(Transaction trans, string name, int timeout
+			)
+		{
+			if (name == null)
+			{
+				throw new ArgumentNullException();
+			}
+			lock (_lock)
+			{
+				if (_semaphores == null)
+				{
+					_semaphores = new Hashtable4(10);
+				}
+			}
+			BooleanByRef acquired = new BooleanByRef();
+			_semaphoresLock.Run(new _IClosure4_625(this, trans, name, acquired, timeout));
+			return acquired.value;
+		}
+
+		private sealed class _IClosure4_625 : IClosure4
+		{
+			public _IClosure4_625(LocalObjectContainer _enclosing, Transaction trans, string 
+				name, BooleanByRef acquired, int timeout)
+			{
+				this._enclosing = _enclosing;
+				this.trans = trans;
+				this.name = name;
+				this.acquired = acquired;
+				this.timeout = timeout;
+			}
+
+			public object Run()
+			{
+				try
+				{
+					Transaction transaction = this._enclosing.CheckTransaction(trans);
+					object candidateTransaction = this._enclosing._semaphores.Get(name);
+					if (trans == candidateTransaction)
+					{
+						acquired.value = true;
+						return null;
+					}
+					if (candidateTransaction == null)
+					{
+						this._enclosing._semaphores.Put(name, transaction);
+						acquired.value = true;
+						return null;
+					}
+					long endtime = Runtime.CurrentTimeMillis() + timeout;
+					long waitTime = timeout;
+					while (waitTime > 0)
+					{
+						this._enclosing._semaphoresLock.Awake();
+						this._enclosing._semaphoresLock.Snooze(waitTime);
+						if (this._enclosing.ClassCollection() == null)
+						{
+							acquired.value = false;
+							return null;
+						}
+						candidateTransaction = this._enclosing._semaphores.Get(name);
+						if (candidateTransaction == null)
+						{
+							this._enclosing._semaphores.Put(name, transaction);
+							acquired.value = true;
+							return null;
+						}
+						waitTime = endtime - Runtime.CurrentTimeMillis();
+					}
+					acquired.value = false;
+					return null;
+				}
+				finally
+				{
+					this._enclosing._semaphoresLock.Awake();
+				}
+			}
+
+			private readonly LocalObjectContainer _enclosing;
+
+			private readonly Transaction trans;
+
+			private readonly string name;
+
+			private readonly BooleanByRef acquired;
+
+			private readonly int timeout;
+		}
+
+		public virtual void SetServer(bool flag)
+		{
+			i_isServer = flag;
+		}
+
+		public abstract void SyncFiles();
+
+		public abstract void SyncFiles(IRunnable runnable);
+
+		protected override string DefaultToString()
+		{
+			return FileName();
+		}
+
+		public override void Shutdown()
+		{
+			WriteHeader(false, true);
+		}
+
+		public void CommitTransaction()
+		{
+			_transaction.Commit();
+		}
+
+		public abstract void WriteBytes(ByteArrayBuffer buffer, int blockedAddress, int addressOffset
+			);
+
+		public sealed override void WriteDirtyClassMetadata()
+		{
+			WriteCachedDirty();
+		}
+
+		private void WriteCachedDirty()
+		{
+			IEnumerator i = _dirtyClassMetadata.GetEnumerator();
+			while (i.MoveNext())
+			{
+				PersistentBase dirty = (PersistentBase)i.Current;
+				dirty.Write(SystemTransaction());
+				dirty.NotCachedDirty();
+			}
+			_dirtyClassMetadata.Clear();
+		}
+
+		public void WriteEncrypt(ByteArrayBuffer buffer, int address, int addressOffset)
+		{
+			_handlers.Encrypt(buffer);
+			WriteBytes(buffer, address, addressOffset);
+			_handlers.Decrypt(buffer);
+		}
+
+		public virtual void WriteHeader(bool startFileLockingThread, bool shuttingDown)
+		{
+			if (shuttingDown)
+			{
+				_freespaceManager.Write(this);
+				_freespaceManager = null;
+			}
+			StatefulBuffer writer = CreateStatefulBuffer(SystemTransaction(), 0, _fileHeader.
+				Length());
+			_fileHeader.WriteFixedPart(this, startFileLockingThread, shuttingDown, writer, BlockSize
+				());
+			if (shuttingDown)
+			{
+				EnsureLastSlotWritten();
+			}
+			SyncFiles();
+		}
+
+		public sealed override void WriteNew(Transaction trans, Pointer4 pointer, ClassMetadata
+			 classMetadata, ByteArrayBuffer buffer)
+		{
+			WriteEncrypt(buffer, pointer.Address(), 0);
+			if (classMetadata == null)
+			{
+				return;
+			}
+			classMetadata.AddToIndex(trans, pointer.Id());
+		}
+
+		// This is a reroute of writeBytes to write the free blocks
+		// unchecked.
+		public abstract void OverwriteDeletedBytes(int address, int length);
+
+		public virtual void OverwriteDeletedBlockedSlot(Slot slot)
+		{
+			OverwriteDeletedBytes(slot.Address(), _blockConverter.BlocksToBytes(slot.Length()
+				));
+		}
+
+		public void WriteTransactionPointer(int pointer)
+		{
+			_fileHeader.WriteTransactionPointer(SystemTransaction(), pointer);
+		}
+
+		public Slot AllocateSlotForUserObjectUpdate(Transaction trans, int id, int length
+			)
+		{
+			Slot slot = AllocateSlot(length);
+			trans.IdSystem().NotifySlotUpdated(id, slot, SlotChangeFactory.UserObjects);
+			return slot;
+		}
+
+		public Slot AllocateSlotForNewUserObject(Transaction trans, int id, int length)
+		{
+			Slot slot = AllocateSlot(length);
+			trans.IdSystem().NotifySlotCreated(id, slot, SlotChangeFactory.UserObjects);
+			return slot;
+		}
+
+		public sealed override void WriteUpdate(Transaction trans, Pointer4 pointer, ClassMetadata
+			 classMetadata, ArrayType arrayType, ByteArrayBuffer buffer)
+		{
+			int address = pointer.Address();
+			if (address == 0)
+			{
+				address = AllocateSlotForUserObjectUpdate(trans, pointer.Id(), pointer.Length()).
+					Address();
+			}
+			WriteEncrypt(buffer, address, 0);
+		}
+
+		public virtual void SetNextTimeStampId(long val)
+		{
+			_timeStampIdGenerator.SetMinimumNext(val);
+		}
+
+		public override ISystemInfo SystemInfo()
+		{
+			return new SystemInfoFileImpl(this);
+		}
+
+		public virtual FileHeader GetFileHeader()
+		{
+			return _fileHeader;
+		}
+
+		public virtual void InstallDebugFreespaceManager(IFreespaceManager manager)
+		{
+			_freespaceManager = manager;
+		}
+
+		public virtual Db4objects.Db4o.Internal.SystemData SystemData()
+		{
+			return _systemData;
+		}
+
+		public override long[] GetIDsForClass(Transaction trans, ClassMetadata clazz)
+		{
+			IntArrayList ids = new IntArrayList();
+			clazz.Index().TraverseAll(trans, new _IVisitor4_792(ids));
+			return ids.AsLong();
+		}
+
+		private sealed class _IVisitor4_792 : IVisitor4
+		{
+			public _IVisitor4_792(IntArrayList ids)
+			{
+				this.ids = ids;
+			}
+
+			public void Visit(object obj)
+			{
+				ids.Add(((int)obj));
+			}
+
+			private readonly IntArrayList ids;
+		}
+
+		public override IQueryResult ClassOnlyQuery(QQueryBase query, ClassMetadata clazz
+			)
+		{
+			if (!clazz.HasClassIndex())
+			{
+				return new IdListQueryResult(query.Transaction());
+			}
+			AbstractQueryResult queryResult = NewQueryResult(query.Transaction());
+			queryResult.LoadFromClassIndex(clazz);
+			return queryResult;
+		}
+
+		public override IQueryResult ExecuteQuery(QQuery query)
+		{
+			AbstractQueryResult queryResult = NewQueryResult(query.Transaction());
+			queryResult.LoadFromQuery(query);
+			return queryResult;
+		}
+
+		public virtual LocalTransaction LocalSystemTransaction()
+		{
+			return (LocalTransaction)SystemTransaction();
+		}
+
+		public override int InstanceCount(ClassMetadata clazz, Transaction trans)
+		{
+			lock (Lock())
+			{
+				return clazz.IndexEntryCount(trans);
+			}
+		}
+
+		public override IObjectContainer OpenSession()
+		{
+			lock (Lock())
+			{
+				return new ObjectContainerSession(this);
+			}
+		}
+
+		public override bool IsDeleted(Transaction trans, int id)
+		{
+			return trans.IdSystem().IsDeleted(id);
+		}
+
+		public virtual void WritePointer(int id, Slot slot)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.WritePointer.Log(id);
+				DTrace.WritePointer.LogLength(slot);
+			}
+			_pointerIo.Seek(0);
+			_pointerIo.WriteInt(slot.Address());
+			_pointerIo.WriteInt(slot.Length());
+			WriteBytes(_pointerIo, id, 0);
+		}
+
+		public virtual Slot DebugReadPointerSlot(int id)
+		{
+			return null;
+		}
+
+		public Slot ReadPointerSlot(int id)
+		{
+			if (!IsValidId(id))
+			{
+				throw new InvalidIDException(id);
+			}
+			ReadBytes(_pointerBuffer, id, Const4.PointerLength);
+			int address = (_pointerBuffer[3] & 255) | (_pointerBuffer[2] & 255) << 8 | (_pointerBuffer
+				[1] & 255) << 16 | _pointerBuffer[0] << 24;
+			int length = (_pointerBuffer[7] & 255) | (_pointerBuffer[6] & 255) << 8 | (_pointerBuffer
+				[5] & 255) << 16 | _pointerBuffer[4] << 24;
+			if (!IsValidSlot(address, length))
+			{
+				throw new InvalidSlotException(address, length, id);
+			}
+			return new Slot(address, length);
+		}
+
+		private bool IsValidId(int id)
+		{
+			return FileLength() >= id;
+		}
+
+		private bool IsValidSlot(int address, int length)
+		{
+			// just in case overflow 
+			long fileLength = FileLength();
+			bool validAddress = fileLength >= address;
+			bool validLength = fileLength >= length;
+			bool validSlot = fileLength >= (address + length);
+			return validAddress && validLength && validSlot;
+		}
+
+		protected override void CloseIdSystem()
+		{
+			if (_idSystem != null)
+			{
+				_idSystem.Close();
+			}
+		}
+
+		public virtual IIdSystem IdSystem()
+		{
+			return _idSystem;
+		}
+
+		public virtual IRunnable CommitHook()
+		{
+			_systemData.LastTimeStampID(_timeStampIdGenerator.Last());
+			return _fileHeader.Commit(false);
+		}
+
+		public Slot AllocateSafeSlot(int length)
+		{
+			Slot reusedSlot = FreespaceManager().AllocateSafeSlot(length);
+			if (reusedSlot != null)
+			{
+				return reusedSlot;
+			}
+			return AppendBytes(length);
+		}
+
+		public override EventRegistryImpl NewEventRegistry()
+		{
+			return new EventRegistryImpl();
+		}
+
+		public virtual IQLin From(Type clazz)
+		{
+			return new QLinRoot(Query(), clazz);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/LocalPersistentBase.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/LocalPersistentBase.cs
new file mode 100644
index 0000000..9aa7055
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/LocalPersistentBase.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public abstract class LocalPersistentBase : PersistentBase
+	{
+		private readonly ITransactionalIdSystem _idSystem;
+
+		public LocalPersistentBase(ITransactionalIdSystem idSystem)
+		{
+			_idSystem = idSystem;
+		}
+
+		public LocalPersistentBase() : this(null)
+		{
+		}
+
+		public override ITransactionalIdSystem IdSystem(Transaction trans)
+		{
+			if (_idSystem != null)
+			{
+				return _idSystem;
+			}
+			return base.IdSystem(trans);
+		}
+
+		protected override ByteArrayBuffer ReadBufferById(Transaction trans)
+		{
+			Slot slot = IdSystem(trans).CurrentSlot(GetID());
+			if (DTrace.enabled)
+			{
+				DTrace.SlotRead.LogLength(GetID(), slot);
+			}
+			return ((LocalObjectContainer)trans.Container()).ReadBufferBySlot(slot);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/LocalTransaction.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/LocalTransaction.cs
new file mode 100644
index 0000000..52ec059
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/LocalTransaction.cs
@@ -0,0 +1,541 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Callbacks;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.References;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class LocalTransaction : Transaction
+	{
+		private readonly IdentitySet4 _participants = new IdentitySet4();
+
+		internal Tree _writtenUpdateAdjustedIndexes;
+
+		protected readonly LocalObjectContainer _file;
+
+		private readonly ICommittedCallbackDispatcher _committedCallbackDispatcher;
+
+		private readonly ITransactionalIdSystem _idSystem;
+
+		private Db4objects.Db4o.Internal.CommitTimestampSupport _commitTimestampSupport = 
+			null;
+
+		private long _timestamp;
+
+		public LocalTransaction(ObjectContainerBase container, Transaction parentTransaction
+			, ITransactionalIdSystem idSystem, IReferenceSystem referenceSystem) : base(container
+			, parentTransaction, referenceSystem)
+		{
+			_file = (LocalObjectContainer)container;
+			_committedCallbackDispatcher = new _ICommittedCallbackDispatcher_35(this);
+			_idSystem = idSystem;
+		}
+
+		private sealed class _ICommittedCallbackDispatcher_35 : ICommittedCallbackDispatcher
+		{
+			public _ICommittedCallbackDispatcher_35(LocalTransaction _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public bool WillDispatchCommitted()
+			{
+				return this._enclosing.Callbacks().CaresAboutCommitted();
+			}
+
+			public void DispatchCommitted(CallbackObjectInfoCollections committedInfo)
+			{
+				this._enclosing.Callbacks().CommitOnCompleted(this._enclosing, committedInfo, false
+					);
+			}
+
+			private readonly LocalTransaction _enclosing;
+		}
+
+		public virtual Config4Impl Config()
+		{
+			return Container().Config();
+		}
+
+		public virtual LocalObjectContainer LocalContainer()
+		{
+			return _file;
+		}
+
+		public override void Commit()
+		{
+			if (IsSystemTransaction())
+			{
+				CommitTimestampSupport().EnsureInitialized();
+			}
+			Commit(_committedCallbackDispatcher);
+		}
+
+		public virtual void Commit(ICommittedCallbackDispatcher dispatcher)
+		{
+			lock (Container().Lock())
+			{
+				DispatchCommittingCallback();
+				if (!DoCommittedCallbacks(dispatcher))
+				{
+					CommitListeners();
+					CommitImpl();
+					CommitClearAll();
+				}
+				else
+				{
+					CommitListeners();
+					Collection4 deleted = CollectCommittedCallbackDeletedInfo();
+					CommitImpl();
+					CallbackObjectInfoCollections committedInfo = CollectCommittedCallbackInfo(deleted
+						);
+					CommitClearAll();
+					dispatcher.DispatchCommitted(CallbackObjectInfoCollections.Emtpy == committedInfo
+						 ? committedInfo : new CallbackObjectInfoCollections(committedInfo.added, committedInfo
+						.updated, new ObjectInfoCollectionImpl(deleted)));
+				}
+			}
+		}
+
+		private void DispatchCommittingCallback()
+		{
+			if (DoCommittingCallbacks())
+			{
+				Callbacks().CommitOnStarted(this, CollectCommittingCallbackInfo());
+			}
+		}
+
+		private bool DoCommittedCallbacks(ICommittedCallbackDispatcher dispatcher)
+		{
+			if (IsSystemTransaction())
+			{
+				return false;
+			}
+			return dispatcher.WillDispatchCommitted();
+		}
+
+		private bool DoCommittingCallbacks()
+		{
+			if (IsSystemTransaction())
+			{
+				return false;
+			}
+			return Callbacks().CaresAboutCommitting();
+		}
+
+		public virtual void Enlist(ITransactionParticipant participant)
+		{
+			if (null == participant)
+			{
+				throw new ArgumentNullException();
+			}
+			CheckSynchronization();
+			if (!_participants.Contains(participant))
+			{
+				_participants.Add(participant);
+			}
+		}
+
+		private void CommitImpl()
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.TransCommit.LogInfo("server == " + Container().IsServer() + ", systemtrans == "
+					 + IsSystemTransaction());
+			}
+			CommitClassMetadata();
+			CommitParticipants();
+			Container().WriteDirtyClassMetadata();
+			IdSystem().Commit(new FreespaceCommitter(LocalContainer().FreespaceManager()));
+		}
+
+		private void CommitListeners()
+		{
+			CommitParentListeners();
+			CommitTransactionListeners();
+		}
+
+		private void CommitParentListeners()
+		{
+			if (_systemTransaction != null)
+			{
+				ParentLocalTransaction().CommitListeners();
+			}
+		}
+
+		private void CommitParticipants()
+		{
+			if (ParentLocalTransaction() != null)
+			{
+				ParentLocalTransaction().CommitParticipants();
+			}
+			IEnumerator iterator = _participants.GetEnumerator();
+			while (iterator.MoveNext())
+			{
+				((ITransactionParticipant)iterator.Current).Commit(this);
+			}
+		}
+
+		private void CommitClassMetadata()
+		{
+			Container().ProcessPendingClassUpdates();
+			Container().WriteDirtyClassMetadata();
+			Container().ClassCollection().Write(Container().SystemTransaction());
+		}
+
+		private Db4objects.Db4o.Internal.LocalTransaction ParentLocalTransaction()
+		{
+			return (Db4objects.Db4o.Internal.LocalTransaction)_systemTransaction;
+		}
+
+		private void CommitClearAll()
+		{
+			if (_systemTransaction != null)
+			{
+				ParentLocalTransaction().CommitClearAll();
+			}
+			ClearAll();
+		}
+
+		protected override void Clear()
+		{
+			IdSystem().Clear();
+			DisposeParticipants();
+			_participants.Clear();
+		}
+
+		private void DisposeParticipants()
+		{
+			IEnumerator iterator = _participants.ValuesIterator();
+			while (iterator.MoveNext())
+			{
+				((ITransactionParticipant)iterator.Current).Dispose(this);
+			}
+		}
+
+		public override void Rollback()
+		{
+			lock (Container().Lock())
+			{
+				RollbackParticipants();
+				IdSystem().Rollback();
+				RollBackTransactionListeners();
+				ClearAll();
+			}
+		}
+
+		private void RollbackParticipants()
+		{
+			IEnumerator iterator = _participants.ValuesIterator();
+			while (iterator.MoveNext())
+			{
+				((ITransactionParticipant)iterator.Current).Rollback(this);
+			}
+		}
+
+		public virtual void FlushFile()
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.TransFlush.Log();
+			}
+			_file.SyncFiles();
+		}
+
+		public override void ProcessDeletes()
+		{
+			if (_delete == null)
+			{
+				_writtenUpdateAdjustedIndexes = null;
+				return;
+			}
+			while (_delete != null)
+			{
+				Tree delete = _delete;
+				_delete = null;
+				delete.Traverse(new _IVisitor4_225(this));
+			}
+			// if the object has been deleted
+			// We need to hold a hard reference here, otherwise we can get 
+			// intermediate garbage collection kicking in.
+			// This means the object was gc'd.
+			// Let's try to read it again, but this may fail in
+			// CS mode if another transaction has deleted it. 
+			_writtenUpdateAdjustedIndexes = null;
+		}
+
+		private sealed class _IVisitor4_225 : IVisitor4
+		{
+			public _IVisitor4_225(LocalTransaction _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Visit(object a_object)
+			{
+				DeleteInfo info = (DeleteInfo)a_object;
+				if (this._enclosing.LocalContainer().IsDeleted(this._enclosing, info._key))
+				{
+					return;
+				}
+				object obj = null;
+				if (info._reference != null)
+				{
+					obj = info._reference.GetObject();
+				}
+				if (obj == null || info._reference.GetID() < 0)
+				{
+					HardObjectReference hardRef = this._enclosing.Container().GetHardObjectReferenceById
+						(this._enclosing, info._key);
+					if (hardRef == HardObjectReference.Invalid)
+					{
+						return;
+					}
+					info._reference = hardRef._reference;
+					info._reference.FlagForDelete(this._enclosing.Container().TopLevelCallId());
+					obj = info._reference.GetObject();
+				}
+				this._enclosing.Container().Delete3(this._enclosing, info._reference, obj, info._cascade
+					, false);
+			}
+
+			private readonly LocalTransaction _enclosing;
+		}
+
+		public override void WriteUpdateAdjustIndexes(int id, ClassMetadata clazz, ArrayType
+			 typeInfo)
+		{
+			new WriteUpdateProcessor(this, id, clazz, typeInfo).Run();
+		}
+
+		private ICallbacks Callbacks()
+		{
+			return Container().Callbacks();
+		}
+
+		private Collection4 CollectCommittedCallbackDeletedInfo()
+		{
+			Collection4 deleted = new Collection4();
+			CollectCallBackInfo(new _ICallbackInfoCollector_275(this, deleted));
+			return deleted;
+		}
+
+		private sealed class _ICallbackInfoCollector_275 : ICallbackInfoCollector
+		{
+			public _ICallbackInfoCollector_275(LocalTransaction _enclosing, Collection4 deleted
+				)
+			{
+				this._enclosing = _enclosing;
+				this.deleted = deleted;
+			}
+
+			public void Deleted(int id)
+			{
+				IObjectInfo @ref = this._enclosing.FrozenReferenceFor(id);
+				if (@ref != null)
+				{
+					deleted.Add(@ref);
+				}
+			}
+
+			public void Updated(int id)
+			{
+			}
+
+			public void Added(int id)
+			{
+			}
+
+			private readonly LocalTransaction _enclosing;
+
+			private readonly Collection4 deleted;
+		}
+
+		private CallbackObjectInfoCollections CollectCommittedCallbackInfo(Collection4 deleted
+			)
+		{
+			if (!IdSystem().IsDirty())
+			{
+				return CallbackObjectInfoCollections.Emtpy;
+			}
+			Collection4 added = new Collection4();
+			Collection4 updated = new Collection4();
+			CollectCallBackInfo(new _ICallbackInfoCollector_298(this, added, updated));
+			return NewCallbackObjectInfoCollections(added, updated, deleted);
+		}
+
+		private sealed class _ICallbackInfoCollector_298 : ICallbackInfoCollector
+		{
+			public _ICallbackInfoCollector_298(LocalTransaction _enclosing, Collection4 added
+				, Collection4 updated)
+			{
+				this._enclosing = _enclosing;
+				this.added = added;
+				this.updated = updated;
+			}
+
+			public void Added(int id)
+			{
+				added.Add(this._enclosing.LazyReferenceFor(id));
+			}
+
+			public void Updated(int id)
+			{
+				updated.Add(this._enclosing.LazyReferenceFor(id));
+			}
+
+			public void Deleted(int id)
+			{
+			}
+
+			private readonly LocalTransaction _enclosing;
+
+			private readonly Collection4 added;
+
+			private readonly Collection4 updated;
+		}
+
+		private CallbackObjectInfoCollections CollectCommittingCallbackInfo()
+		{
+			if (!IdSystem().IsDirty())
+			{
+				return CallbackObjectInfoCollections.Emtpy;
+			}
+			Collection4 added = new Collection4();
+			Collection4 deleted = new Collection4();
+			Collection4 updated = new Collection4();
+			CollectCallBackInfo(new _ICallbackInfoCollector_321(this, added, updated, deleted
+				));
+			return NewCallbackObjectInfoCollections(added, updated, deleted);
+		}
+
+		private sealed class _ICallbackInfoCollector_321 : ICallbackInfoCollector
+		{
+			public _ICallbackInfoCollector_321(LocalTransaction _enclosing, Collection4 added
+				, Collection4 updated, Collection4 deleted)
+			{
+				this._enclosing = _enclosing;
+				this.added = added;
+				this.updated = updated;
+				this.deleted = deleted;
+			}
+
+			public void Added(int id)
+			{
+				added.Add(this._enclosing.LazyReferenceFor(id));
+			}
+
+			public void Updated(int id)
+			{
+				updated.Add(this._enclosing.LazyReferenceFor(id));
+			}
+
+			public void Deleted(int id)
+			{
+				IObjectInfo @ref = this._enclosing.FrozenReferenceFor(id);
+				if (@ref != null)
+				{
+					deleted.Add(@ref);
+				}
+			}
+
+			private readonly LocalTransaction _enclosing;
+
+			private readonly Collection4 added;
+
+			private readonly Collection4 updated;
+
+			private readonly Collection4 deleted;
+		}
+
+		private CallbackObjectInfoCollections NewCallbackObjectInfoCollections(Collection4
+			 added, Collection4 updated, Collection4 deleted)
+		{
+			return new CallbackObjectInfoCollections(new ObjectInfoCollectionImpl(added), new 
+				ObjectInfoCollectionImpl(updated), new ObjectInfoCollectionImpl(deleted));
+		}
+
+		private void CollectCallBackInfo(ICallbackInfoCollector collector)
+		{
+			IdSystem().CollectCallBackInfo(collector);
+		}
+
+		public override ITransactionalIdSystem IdSystem()
+		{
+			return _idSystem;
+		}
+
+		public virtual IObjectInfo FrozenReferenceFor(int id)
+		{
+			ObjectReference @ref = ReferenceForId(id);
+			if (@ref != null)
+			{
+				return new FrozenObjectInfo(this, @ref, true);
+			}
+			@ref = Container().PeekReference(SystemTransaction(), id, new FixedActivationDepth
+				(0), true);
+			if (@ref == null || @ref.GetObject() == null)
+			{
+				return null;
+			}
+			return new FrozenObjectInfo(SystemTransaction(), @ref, true);
+		}
+
+		public virtual LazyObjectReference LazyReferenceFor(int id)
+		{
+			return new LazyObjectReference(this, id);
+		}
+
+		public override long VersionForId(int id)
+		{
+			return CommitTimestampSupport().VersionForId(id);
+		}
+
+		public virtual Db4objects.Db4o.Internal.CommitTimestampSupport CommitTimestampSupport
+			()
+		{
+			if (!IsSystemTransaction())
+			{
+				throw new InvalidOperationException();
+			}
+			if (_commitTimestampSupport == null)
+			{
+				_commitTimestampSupport = new Db4objects.Db4o.Internal.CommitTimestampSupport(LocalContainer
+					());
+			}
+			return _commitTimestampSupport;
+		}
+
+		public override long GenerateTransactionTimestamp(long forcedTimeStamp)
+		{
+			if (forcedTimeStamp > 0)
+			{
+				_timestamp = forcedTimeStamp;
+			}
+			else
+			{
+				_timestamp = LocalContainer().GenerateTimeStampId();
+			}
+			return _timestamp;
+		}
+
+		public override void UseDefaultTransactionTimestamp()
+		{
+			_timestamp = 0;
+		}
+
+		public virtual long Timestamp()
+		{
+			return _timestamp;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/LockedTree.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/LockedTree.cs
new file mode 100644
index 0000000..cac6a33
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/LockedTree.cs
@@ -0,0 +1,87 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class LockedTree
+	{
+		private Tree _tree;
+
+		private int _version;
+
+		public virtual void Add(Tree tree)
+		{
+			Changed();
+			_tree = _tree == null ? tree : _tree.Add(tree);
+		}
+
+		private void Changed()
+		{
+			_version++;
+		}
+
+		public virtual void Clear()
+		{
+			Changed();
+			_tree = null;
+		}
+
+		public virtual Tree Find(int key)
+		{
+			return TreeInt.Find(_tree, key);
+		}
+
+		public virtual void Read(ByteArrayBuffer buffer, IReadable template)
+		{
+			Clear();
+			_tree = new TreeReader(buffer, template).Read();
+			Changed();
+		}
+
+		public virtual void TraverseLocked(IVisitor4 visitor)
+		{
+			int currentVersion = _version;
+			Tree.Traverse(_tree, visitor);
+			if (_version != currentVersion)
+			{
+				throw new InvalidOperationException();
+			}
+		}
+
+		public virtual void TraverseMutable(IVisitor4 visitor)
+		{
+			Collection4 currentContent = new Collection4();
+			TraverseLocked(new _IVisitor4_51(currentContent));
+			IEnumerator i = currentContent.GetEnumerator();
+			while (i.MoveNext())
+			{
+				visitor.Visit(i.Current);
+			}
+		}
+
+		private sealed class _IVisitor4_51 : IVisitor4
+		{
+			public _IVisitor4_51(Collection4 currentContent)
+			{
+				this.currentContent = currentContent;
+			}
+
+			public void Visit(object obj)
+			{
+				currentContent.Add(obj);
+			}
+
+			private readonly Collection4 currentContent;
+		}
+
+		public virtual bool IsEmpty()
+		{
+			return _tree == null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Mapping/IIDMapping.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Mapping/IIDMapping.cs
new file mode 100644
index 0000000..4938211
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Mapping/IIDMapping.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Mapping
+{
+	/// <summary>A mapping from db4o file source IDs/addresses to target IDs/addresses, used for defragmenting.
+	/// 	</summary>
+	/// <remarks>A mapping from db4o file source IDs/addresses to target IDs/addresses, used for defragmenting.
+	/// 	</remarks>
+	/// <exclude></exclude>
+	public interface IIDMapping
+	{
+		/// <returns>a mapping for the given id. if it does refer to a system handler or the empty reference (0), returns the given id.
+		/// 	</returns>
+		/// <exception cref="MappingNotFoundException">if the given id does not refer to a system handler or the empty reference (0) and if no mapping is found
+		/// 	</exception>
+		/// <exception cref="Db4objects.Db4o.Internal.Mapping.MappingNotFoundException"></exception>
+		int StrictMappedID(int oldID);
+
+		void MapIDs(int oldID, int newID, bool isClassID);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Mapping/IdSource.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Mapping/IdSource.cs
new file mode 100644
index 0000000..c047f0e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Mapping/IdSource.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Internal.Mapping
+{
+	public class IdSource
+	{
+		private readonly IQueue4 _queue;
+
+		public IdSource(IQueue4 queue)
+		{
+			_queue = queue;
+		}
+
+		public virtual bool HasMoreIds()
+		{
+			return _queue.HasNext();
+		}
+
+		public virtual int NextId()
+		{
+			return ((int)_queue.Next());
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Mapping/MappedIDPair.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Mapping/MappedIDPair.cs
new file mode 100644
index 0000000..49a9fea
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Mapping/MappedIDPair.cs
@@ -0,0 +1,33 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Mapping
+{
+	/// <exclude></exclude>
+	public class MappedIDPair
+	{
+		private int _orig;
+
+		private int _mapped;
+
+		public MappedIDPair(int orig, int mapped)
+		{
+			_orig = orig;
+			_mapped = mapped;
+		}
+
+		public virtual int Orig()
+		{
+			return _orig;
+		}
+
+		public virtual int Mapped()
+		{
+			return _mapped;
+		}
+
+		public override string ToString()
+		{
+			return _orig + "->" + _mapped;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Mapping/MappedIDPairHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Mapping/MappedIDPairHandler.cs
new file mode 100644
index 0000000..c0609b6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Mapping/MappedIDPairHandler.cs
@@ -0,0 +1,80 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Mapping;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Mapping
+{
+	/// <exclude></exclude>
+	public class MappedIDPairHandler : IIndexable4
+	{
+		private readonly IntHandler _origHandler;
+
+		private readonly IntHandler _mappedHandler;
+
+		public MappedIDPairHandler()
+		{
+			_origHandler = new IntHandler();
+			_mappedHandler = new IntHandler();
+		}
+
+		public virtual void DefragIndexEntry(DefragmentContextImpl context)
+		{
+			throw new NotImplementedException();
+		}
+
+		public virtual int LinkLength()
+		{
+			return _origHandler.LinkLength() + _mappedHandler.LinkLength();
+		}
+
+		public virtual object ReadIndexEntry(IContext context, ByteArrayBuffer reader)
+		{
+			int origID = ReadID(context, reader);
+			int mappedID = ReadID(context, reader);
+			return new MappedIDPair(origID, mappedID);
+		}
+
+		public virtual void WriteIndexEntry(IContext context, ByteArrayBuffer reader, object
+			 obj)
+		{
+			MappedIDPair mappedIDs = (MappedIDPair)obj;
+			_origHandler.WriteIndexEntry(context, reader, mappedIDs.Orig());
+			_mappedHandler.WriteIndexEntry(context, reader, mappedIDs.Mapped());
+		}
+
+		private int ReadID(IContext context, ByteArrayBuffer a_reader)
+		{
+			return ((int)_origHandler.ReadIndexEntry(context, a_reader));
+		}
+
+		public virtual IPreparedComparison PrepareComparison(IContext context, object source
+			)
+		{
+			MappedIDPair sourceIDPair = (MappedIDPair)source;
+			int sourceID = sourceIDPair.Orig();
+			return new _IPreparedComparison_50(sourceID);
+		}
+
+		private sealed class _IPreparedComparison_50 : IPreparedComparison
+		{
+			public _IPreparedComparison_50(int sourceID)
+			{
+				this.sourceID = sourceID;
+			}
+
+			public int CompareTo(object target)
+			{
+				MappedIDPair targetIDPair = (MappedIDPair)target;
+				int targetID = targetIDPair.Orig();
+				return sourceID == targetID ? 0 : (sourceID < targetID ? -1 : 1);
+			}
+
+			private readonly int sourceID;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Mapping/MappingNotFoundException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Mapping/MappingNotFoundException.cs
new file mode 100644
index 0000000..9ab0c5f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Mapping/MappingNotFoundException.cs
@@ -0,0 +1,30 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Internal.Mapping
+{
+	/// <exclude></exclude>
+	[System.Serializable]
+	public class MappingNotFoundException : Exception
+	{
+		private const long serialVersionUID = -1771324770287654802L;
+
+		private int _id;
+
+		public MappingNotFoundException(int id)
+		{
+			this._id = id;
+		}
+
+		public virtual int Id()
+		{
+			return _id;
+		}
+
+		public override string ToString()
+		{
+			return base.ToString() + " : " + _id;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/AbstractFieldMarshaller.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/AbstractFieldMarshaller.cs
new file mode 100644
index 0000000..c3f2acc
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/AbstractFieldMarshaller.cs
@@ -0,0 +1,32 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public abstract class AbstractFieldMarshaller : IFieldMarshaller
+	{
+		protected abstract RawFieldSpec ReadSpec(AspectType aspectType, ObjectContainerBase
+			 stream, ByteArrayBuffer reader);
+
+		public virtual RawFieldSpec ReadSpec(ObjectContainerBase stream, ByteArrayBuffer 
+			reader)
+		{
+			return ReadSpec(AspectType.Field, stream, reader);
+		}
+
+		public abstract void Defrag(ClassMetadata arg1, ClassAspect arg2, LatinStringIO arg3
+			, DefragmentContextImpl arg4);
+
+		public abstract int MarshalledLength(ObjectContainerBase arg1, ClassAspect arg2);
+
+		public abstract FieldMetadata Read(ObjectContainerBase arg1, ClassMetadata arg2, 
+			ByteArrayBuffer arg3);
+
+		public abstract void Write(Transaction arg1, ClassMetadata arg2, ClassAspect arg3
+			, ByteArrayBuffer arg4);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/AbstractReadContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/AbstractReadContext.cs
new file mode 100644
index 0000000..bd97a9f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/AbstractReadContext.cs
@@ -0,0 +1,158 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public abstract class AbstractReadContext : AbstractBufferContext, IInternalReadContext
+	{
+		protected IActivationDepth _activationDepth = UnknownActivationDepth.Instance;
+
+		private bool _lastReferenceReadWasReallyNull = false;
+
+		protected AbstractReadContext(Transaction transaction, IReadBuffer buffer) : base
+			(transaction, buffer)
+		{
+		}
+
+		protected AbstractReadContext(Transaction transaction) : this(transaction, null)
+		{
+		}
+
+		public object Read(ITypeHandler4 handlerType)
+		{
+			return ReadObject(handlerType);
+		}
+
+		public object ReadObject(ITypeHandler4 handlerType)
+		{
+			if (null == handlerType)
+			{
+				throw new ArgumentNullException();
+			}
+			ITypeHandler4 handler = HandlerRegistry.CorrectHandlerVersion(this, handlerType);
+			return SlotFormat().DoWithSlotIndirection(this, handler, new _IClosure4_38(this, 
+				handler));
+		}
+
+		private sealed class _IClosure4_38 : IClosure4
+		{
+			public _IClosure4_38(AbstractReadContext _enclosing, ITypeHandler4 handler)
+			{
+				this._enclosing = _enclosing;
+				this.handler = handler;
+			}
+
+			public object Run()
+			{
+				return this._enclosing.ReadAtCurrentSeekPosition(handler);
+			}
+
+			private readonly AbstractReadContext _enclosing;
+
+			private readonly ITypeHandler4 handler;
+		}
+
+		public virtual object ReadAtCurrentSeekPosition(ITypeHandler4 handler)
+		{
+			if (Handlers4.UseDedicatedSlot(this, handler))
+			{
+				return ReadObject();
+			}
+			return Handlers4.ReadValueType(this, handler);
+		}
+
+		public object ReadObject()
+		{
+			int objectId = ReadInt();
+			if (objectId == 0)
+			{
+				_lastReferenceReadWasReallyNull = true;
+				return null;
+			}
+			_lastReferenceReadWasReallyNull = false;
+			if (objectId == Const4.InvalidObjectId)
+			{
+				return null;
+			}
+			ClassMetadata classMetadata = ClassMetadataForObjectId(objectId);
+			if (null == classMetadata)
+			{
+				// TODO: throw here
+				return null;
+			}
+			IActivationDepth depth = ActivationDepth().Descend(classMetadata);
+			if (PeekPersisted())
+			{
+				return Container().PeekPersisted(Transaction(), objectId, depth, false);
+			}
+			object obj = Container().GetByID2(Transaction(), objectId);
+			if (null == obj)
+			{
+				return null;
+			}
+			// this is OK for boxed value types. They will not be added
+			// to the list, since they will not be found in the ID tree.
+			Container().StillToActivate(Container().ActivationContextFor(Transaction(), obj, 
+				depth));
+			return obj;
+		}
+
+		private ClassMetadata ClassMetadataForObjectId(int objectId)
+		{
+			// TODO: This method is *very* costly as is, since it reads
+			//       the whole slot once and doesn't reuse it. Optimize.
+			HardObjectReference hardRef = Container().GetHardObjectReferenceById(Transaction(
+				), objectId);
+			if (null == hardRef || hardRef._reference == null)
+			{
+				// com.db4o.db4ounit.common.querying.CascadeDeleteDeleted
+				return null;
+			}
+			return hardRef._reference.ClassMetadata();
+		}
+
+		protected virtual bool PeekPersisted()
+		{
+			return false;
+		}
+
+		public virtual IActivationDepth ActivationDepth()
+		{
+			return _activationDepth;
+		}
+
+		public virtual void ActivationDepth(IActivationDepth depth)
+		{
+			_activationDepth = depth;
+		}
+
+		public virtual IReadWriteBuffer ReadIndirectedBuffer()
+		{
+			int address = ReadInt();
+			int length = ReadInt();
+			if (address == 0)
+			{
+				return null;
+			}
+			return Container().DecryptedBufferByAddress(address, length);
+		}
+
+		public virtual bool LastReferenceReadWasReallyNull()
+		{
+			return _lastReferenceReadWasReallyNull;
+		}
+
+		public virtual void NotifyNullReferenceSkipped()
+		{
+			_lastReferenceReadWasReallyNull = true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/AspectType.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/AspectType.cs
new file mode 100644
index 0000000..ad9736b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/AspectType.cs
@@ -0,0 +1,67 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class AspectType
+	{
+		public readonly byte _id;
+
+		public static readonly Db4objects.Db4o.Internal.Marshall.AspectType Field = new Db4objects.Db4o.Internal.Marshall.AspectType
+			((byte)1);
+
+		public static readonly Db4objects.Db4o.Internal.Marshall.AspectType Translator = 
+			new Db4objects.Db4o.Internal.Marshall.AspectType((byte)2);
+
+		public static readonly Db4objects.Db4o.Internal.Marshall.AspectType Typehandler = 
+			new Db4objects.Db4o.Internal.Marshall.AspectType((byte)3);
+
+		private AspectType(byte id)
+		{
+			_id = id;
+		}
+
+		public static Db4objects.Db4o.Internal.Marshall.AspectType ForByte(byte b)
+		{
+			switch (b)
+			{
+				case 1:
+				{
+					return Field;
+				}
+
+				case 2:
+				{
+					return Translator;
+				}
+
+				case 3:
+				{
+					return Typehandler;
+				}
+
+				default:
+				{
+					throw new ArgumentException();
+				}
+			}
+		}
+
+		public virtual bool IsFieldMetadata()
+		{
+			return IsField() || IsTranslator();
+		}
+
+		public virtual bool IsTranslator()
+		{
+			return this == Db4objects.Db4o.Internal.Marshall.AspectType.Translator;
+		}
+
+		public virtual bool IsField()
+		{
+			return this == Db4objects.Db4o.Internal.Marshall.AspectType.Field;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/AspectVersionContextImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/AspectVersionContextImpl.cs
new file mode 100644
index 0000000..87afed6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/AspectVersionContextImpl.cs
@@ -0,0 +1,36 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class AspectVersionContextImpl : IAspectVersionContext
+	{
+		private readonly int _declaredAspectCount;
+
+		private AspectVersionContextImpl(int count)
+		{
+			_declaredAspectCount = count;
+		}
+
+		public virtual int DeclaredAspectCount()
+		{
+			return _declaredAspectCount;
+		}
+
+		public virtual void DeclaredAspectCount(int count)
+		{
+			throw new InvalidOperationException();
+		}
+
+		public static readonly Db4objects.Db4o.Internal.Marshall.AspectVersionContextImpl
+			 AlwaysEnabled = new Db4objects.Db4o.Internal.Marshall.AspectVersionContextImpl(
+			int.MaxValue);
+
+		public static readonly Db4objects.Db4o.Internal.Marshall.AspectVersionContextImpl
+			 CheckAlwaysEnabled = new Db4objects.Db4o.Internal.Marshall.AspectVersionContextImpl
+			(int.MaxValue - 1);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ClassMarshaller.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ClassMarshaller.cs
new file mode 100644
index 0000000..9b624e5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ClassMarshaller.cs
@@ -0,0 +1,215 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public abstract class ClassMarshaller
+	{
+		public MarshallerFamily _family;
+
+		public virtual RawClassSpec ReadSpec(Transaction trans, ByteArrayBuffer reader)
+		{
+			byte[] nameBytes = ReadName(trans, reader);
+			string className = trans.Container().StringIO().Read(nameBytes);
+			ReadMetaClassID(reader);
+			// skip
+			int ancestorID = reader.ReadInt();
+			reader.IncrementOffset(Const4.IntLength);
+			// index ID
+			int numFields = reader.ReadInt();
+			return new RawClassSpec(className, ancestorID, numFields);
+		}
+
+		public virtual void Write(Transaction trans, ClassMetadata clazz, ByteArrayBuffer
+			 writer)
+		{
+			writer.WriteShortString(trans, clazz.NameToWrite());
+			int intFormerlyKnownAsMetaClassID = 0;
+			writer.WriteInt(intFormerlyKnownAsMetaClassID);
+			writer.WriteIDOf(trans, clazz._ancestor);
+			WriteIndex(trans, clazz, writer);
+			writer.WriteInt(clazz.DeclaredAspectCount());
+			clazz.TraverseDeclaredAspects(new _IProcedure4_39(this, trans, clazz, writer));
+		}
+
+		private sealed class _IProcedure4_39 : IProcedure4
+		{
+			public _IProcedure4_39(ClassMarshaller _enclosing, Transaction trans, ClassMetadata
+				 clazz, ByteArrayBuffer writer)
+			{
+				this._enclosing = _enclosing;
+				this.trans = trans;
+				this.clazz = clazz;
+				this.writer = writer;
+			}
+
+			public void Apply(object arg)
+			{
+				this._enclosing._family._field.Write(trans, clazz, (ClassAspect)arg, writer);
+			}
+
+			private readonly ClassMarshaller _enclosing;
+
+			private readonly Transaction trans;
+
+			private readonly ClassMetadata clazz;
+
+			private readonly ByteArrayBuffer writer;
+		}
+
+		protected virtual void WriteIndex(Transaction trans, ClassMetadata clazz, ByteArrayBuffer
+			 writer)
+		{
+			int indexID = clazz.Index().Write(trans);
+			writer.WriteInt(IndexIDForWriting(indexID));
+		}
+
+		protected abstract int IndexIDForWriting(int indexID);
+
+		public byte[] ReadName(Transaction trans, ByteArrayBuffer reader)
+		{
+			return ReadName(trans.Container().StringIO(), reader);
+		}
+
+		public int ReadMetaClassID(ByteArrayBuffer reader)
+		{
+			return reader.ReadInt();
+		}
+
+		private byte[] ReadName(LatinStringIO sio, ByteArrayBuffer reader)
+		{
+			byte[] nameBytes = sio.Bytes(reader);
+			reader.IncrementOffset(nameBytes.Length);
+			nameBytes = Platform4.UpdateClassName(nameBytes);
+			return nameBytes;
+		}
+
+		public void Read(ObjectContainerBase stream, ClassMetadata clazz, ByteArrayBuffer
+			 reader)
+		{
+			clazz.SetAncestor(stream.ClassMetadataForID(reader.ReadInt()));
+			//        if(clazz.callConstructor()){
+			//            // The logic further down checks the ancestor YapClass, whether
+			//            // or not it is allowed, not to call constructors. The ancestor
+			//            // YapClass may possibly have not been loaded yet.
+			//            clazz.createConstructor(true);
+			//        }
+			clazz.CheckType();
+			ReadIndex(stream, clazz, reader);
+			clazz._aspects = ReadAspects(stream, reader, clazz);
+		}
+
+		protected abstract void ReadIndex(ObjectContainerBase stream, ClassMetadata clazz
+			, ByteArrayBuffer reader);
+
+		private ClassAspect[] ReadAspects(ObjectContainerBase stream, ByteArrayBuffer reader
+			, ClassMetadata clazz)
+		{
+			ClassAspect[] aspects = new ClassAspect[reader.ReadInt()];
+			for (int i = 0; i < aspects.Length; i++)
+			{
+				aspects[i] = _family._field.Read(stream, clazz, reader);
+				aspects[i].SetHandle(i);
+			}
+			return aspects;
+		}
+
+		public virtual int MarshalledLength(ObjectContainerBase stream, ClassMetadata clazz
+			)
+		{
+			IntByRef len = new IntByRef(stream.StringIO().ShortLength(clazz.NameToWrite()) + 
+				Const4.ObjectLength + (Const4.IntLength * 2) + (Const4.IdLength));
+			len.value += clazz.Index().OwnLength();
+			clazz.TraverseDeclaredAspects(new _IProcedure4_108(this, len, stream));
+			return len.value;
+		}
+
+		private sealed class _IProcedure4_108 : IProcedure4
+		{
+			public _IProcedure4_108(ClassMarshaller _enclosing, IntByRef len, ObjectContainerBase
+				 stream)
+			{
+				this._enclosing = _enclosing;
+				this.len = len;
+				this.stream = stream;
+			}
+
+			public void Apply(object arg)
+			{
+				len.value += this._enclosing._family._field.MarshalledLength(stream, (ClassAspect
+					)arg);
+			}
+
+			private readonly ClassMarshaller _enclosing;
+
+			private readonly IntByRef len;
+
+			private readonly ObjectContainerBase stream;
+		}
+
+		public virtual void Defrag(ClassMetadata classMetadata, LatinStringIO sio, DefragmentContextImpl
+			 context, int classIndexID)
+		{
+			ReadName(sio, context.SourceBuffer());
+			ReadName(sio, context.TargetBuffer());
+			int metaClassID = 0;
+			context.WriteInt(metaClassID);
+			// ancestor ID
+			context.CopyID();
+			context.WriteInt((classMetadata.HasClassIndex() ? IndexIDForWriting(classIndexID)
+				 : 0));
+			int aspectCount = context.ReadInt();
+			if (aspectCount > classMetadata.DeclaredAspectCount())
+			{
+				throw new InvalidOperationException();
+			}
+			IntByRef processedAspectCount = new IntByRef(0);
+			classMetadata.TraverseDeclaredAspects(new _IProcedure4_136(this, processedAspectCount
+				, aspectCount, classMetadata, sio, context));
+		}
+
+		private sealed class _IProcedure4_136 : IProcedure4
+		{
+			public _IProcedure4_136(ClassMarshaller _enclosing, IntByRef processedAspectCount
+				, int aspectCount, ClassMetadata classMetadata, LatinStringIO sio, DefragmentContextImpl
+				 context)
+			{
+				this._enclosing = _enclosing;
+				this.processedAspectCount = processedAspectCount;
+				this.aspectCount = aspectCount;
+				this.classMetadata = classMetadata;
+				this.sio = sio;
+				this.context = context;
+			}
+
+			public void Apply(object arg)
+			{
+				if (processedAspectCount.value >= aspectCount)
+				{
+					return;
+				}
+				ClassAspect aspect = (ClassAspect)arg;
+				this._enclosing._family._field.Defrag(classMetadata, aspect, sio, context);
+				processedAspectCount.value++;
+			}
+
+			private readonly ClassMarshaller _enclosing;
+
+			private readonly IntByRef processedAspectCount;
+
+			private readonly int aspectCount;
+
+			private readonly ClassMetadata classMetadata;
+
+			private readonly LatinStringIO sio;
+
+			private readonly DefragmentContextImpl context;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ClassMarshaller0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ClassMarshaller0.cs
new file mode 100644
index 0000000..60f356f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ClassMarshaller0.cs
@@ -0,0 +1,55 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Classindex;
+using Db4objects.Db4o.Internal.Convert.Conversions;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class ClassMarshaller0 : ClassMarshaller
+	{
+		protected override void ReadIndex(ObjectContainerBase stream, ClassMetadata clazz
+			, ByteArrayBuffer reader)
+		{
+			int indexID = reader.ReadInt();
+			if (!stream.MaintainsIndices() || !(stream is LocalObjectContainer))
+			{
+				return;
+			}
+			if (Btree(clazz) != null)
+			{
+				return;
+			}
+			clazz.Index().Read(stream, ValidIndexId(indexID));
+			if (IsOldClassIndex(indexID))
+			{
+				new ClassIndexesToBTrees_5_5().Convert((LocalObjectContainer)stream, indexID, Btree
+					(clazz));
+				stream.SetDirtyInSystemTransaction(clazz);
+			}
+		}
+
+		private BTree Btree(ClassMetadata clazz)
+		{
+			return BTreeClassIndexStrategy.Btree(clazz);
+		}
+
+		private int ValidIndexId(int indexID)
+		{
+			return IsOldClassIndex(indexID) ? 0 : -indexID;
+		}
+
+		private bool IsOldClassIndex(int indexID)
+		{
+			return indexID > 0;
+		}
+
+		protected override int IndexIDForWriting(int indexID)
+		{
+			return indexID;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ClassMarshaller1.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ClassMarshaller1.cs
new file mode 100644
index 0000000..7fd9041
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ClassMarshaller1.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class ClassMarshaller1 : ClassMarshaller
+	{
+		protected override void ReadIndex(ObjectContainerBase stream, ClassMetadata clazz
+			, ByteArrayBuffer reader)
+		{
+			int indexID = reader.ReadInt();
+			clazz.Index().Read(stream, -indexID);
+		}
+
+		protected override int IndexIDForWriting(int indexID)
+		{
+			return -indexID;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ClassMarshaller2.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ClassMarshaller2.cs
new file mode 100644
index 0000000..311968e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ClassMarshaller2.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class ClassMarshaller2 : ClassMarshaller
+	{
+		protected override void ReadIndex(ObjectContainerBase stream, ClassMetadata clazz
+			, ByteArrayBuffer reader)
+		{
+			int indexID = reader.ReadInt();
+			if (indexID == 0)
+			{
+				return;
+			}
+			clazz.Index().Read(stream, indexID);
+		}
+
+		protected override int IndexIDForWriting(int indexID)
+		{
+			return indexID;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/CollectIdContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/CollectIdContext.cs
new file mode 100644
index 0000000..6504b16
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/CollectIdContext.cs
@@ -0,0 +1,84 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class CollectIdContext : ObjectHeaderContext
+	{
+		private readonly IdObjectCollector _collector;
+
+		public CollectIdContext(Transaction transaction, IdObjectCollector collector, ObjectHeader
+			 oh, IReadBuffer buffer) : base(transaction, buffer, oh)
+		{
+			_collector = collector;
+		}
+
+		public CollectIdContext(Transaction transaction, ObjectHeader oh, IReadBuffer buffer
+			) : this(transaction, new IdObjectCollector(), oh, buffer)
+		{
+		}
+
+		public static Db4objects.Db4o.Internal.Marshall.CollectIdContext ForID(Transaction
+			 transaction, int id)
+		{
+			return ForID(transaction, new IdObjectCollector(), id);
+		}
+
+		public static Db4objects.Db4o.Internal.Marshall.CollectIdContext ForID(Transaction
+			 transaction, IdObjectCollector collector, int id)
+		{
+			StatefulBuffer reader = transaction.Container().ReadStatefulBufferById(transaction
+				, id);
+			if (reader == null)
+			{
+				return null;
+			}
+			ObjectHeader oh = new ObjectHeader(transaction.Container(), reader);
+			return new Db4objects.Db4o.Internal.Marshall.CollectIdContext(transaction, collector
+				, oh, reader);
+		}
+
+		public virtual void AddId()
+		{
+			int id = ReadInt();
+			if (id <= 0)
+			{
+				return;
+			}
+			AddId(id);
+		}
+
+		private void AddId(int id)
+		{
+			_collector.AddId(id);
+		}
+
+		public override Db4objects.Db4o.Internal.ClassMetadata ClassMetadata()
+		{
+			return _objectHeader.ClassMetadata();
+		}
+
+		public virtual TreeInt Ids()
+		{
+			return _collector.Ids();
+		}
+
+		public virtual void ReadID(IReadsObjectIds objectIDHandler)
+		{
+			ObjectID objectID = objectIDHandler.ReadObjectID(this);
+			if (objectID.IsValid())
+			{
+				AddId(objectID._id);
+			}
+		}
+
+		public virtual IdObjectCollector Collector()
+		{
+			return _collector;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ContextState.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ContextState.cs
new file mode 100644
index 0000000..e54f35c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ContextState.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class ContextState
+	{
+		public readonly int _offset;
+
+		public ContextState(int offset)
+		{
+			_offset = offset;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/FieldMarshaller0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/FieldMarshaller0.cs
new file mode 100644
index 0000000..5bb541c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/FieldMarshaller0.cs
@@ -0,0 +1,136 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class FieldMarshaller0 : AbstractFieldMarshaller
+	{
+		public override int MarshalledLength(ObjectContainerBase stream, ClassAspect aspect
+			)
+		{
+			int len = stream.StringIO().ShortLength(aspect.GetName());
+			if (aspect is FieldMetadata)
+			{
+				FieldMetadata field = (FieldMetadata)aspect;
+				if (field.NeedsArrayAndPrimitiveInfo())
+				{
+					len += 1;
+				}
+				if (!(field is VirtualFieldMetadata))
+				{
+					len += Const4.IdLength;
+				}
+			}
+			return len;
+		}
+
+		protected override RawFieldSpec ReadSpec(AspectType aspectType, ObjectContainerBase
+			 stream, ByteArrayBuffer reader)
+		{
+			string name = StringHandler.ReadStringNoDebug(stream.Transaction.Context(), reader
+				);
+			if (!aspectType.IsFieldMetadata())
+			{
+				return new RawFieldSpec(aspectType, name);
+			}
+			if (name.IndexOf(Const4.VirtualFieldPrefix) == 0)
+			{
+				if (stream._handlers.VirtualFieldByName(name) != null)
+				{
+					return new RawFieldSpec(aspectType, name);
+				}
+			}
+			int fieldTypeID = reader.ReadInt();
+			byte attribs = reader.ReadByte();
+			return new RawFieldSpec(aspectType, name, fieldTypeID, attribs);
+		}
+
+		public sealed override FieldMetadata Read(ObjectContainerBase stream, ClassMetadata
+			 containingClass, ByteArrayBuffer reader)
+		{
+			RawFieldSpec spec = ReadSpec(stream, reader);
+			return FromSpec(spec, stream, containingClass);
+		}
+
+		protected virtual FieldMetadata FromSpec(RawFieldSpec spec, ObjectContainerBase stream
+			, ClassMetadata containingClass)
+		{
+			if (spec == null)
+			{
+				return null;
+			}
+			string name = spec.Name();
+			if (spec.IsVirtualField())
+			{
+				return stream._handlers.VirtualFieldByName(name);
+			}
+			if (spec.IsTranslator())
+			{
+				return new TranslatedAspect(containingClass, name);
+			}
+			if (spec.IsField())
+			{
+				return new FieldMetadata(containingClass, name, spec.FieldTypeID(), spec.IsPrimitive
+					(), spec.IsArray(), spec.IsNArray());
+			}
+			return new UnknownTypeHandlerAspect(containingClass, name);
+		}
+
+		public override void Write(Transaction trans, ClassMetadata clazz, ClassAspect aspect
+			, ByteArrayBuffer writer)
+		{
+			writer.WriteShortString(trans, aspect.GetName());
+			if (!(aspect is FieldMetadata))
+			{
+				return;
+			}
+			FieldMetadata field = (FieldMetadata)aspect;
+			field.Alive();
+			if (field.IsVirtual())
+			{
+				return;
+			}
+			ITypeHandler4 handler = field.GetHandler();
+			if (handler is StandardReferenceTypeHandler)
+			{
+				// TODO: ensure there is a test case, to make this happen 
+				if (((StandardReferenceTypeHandler)handler).ClassMetadata().GetID() == 0)
+				{
+					trans.Container().NeedsUpdate(clazz);
+				}
+			}
+			writer.WriteInt(field.FieldTypeID());
+			BitMap4 bitmap = new BitMap4(3);
+			bitmap.Set(0, field.IsPrimitive());
+			bitmap.Set(1, Handlers4.HandlesArray(handler));
+			bitmap.Set(2, Handlers4.HandlesMultidimensionalArray(handler));
+			// keep the order
+			writer.WriteByte(bitmap.GetByte(0));
+		}
+
+		public override void Defrag(ClassMetadata classMetadata, ClassAspect aspect, LatinStringIO
+			 sio, DefragmentContextImpl context)
+		{
+			context.IncrementStringOffset(sio);
+			if (!(aspect is FieldMetadata))
+			{
+				return;
+			}
+			if (((FieldMetadata)aspect).IsVirtual())
+			{
+				return;
+			}
+			// handler ID
+			context.CopyID();
+			// skip primitive/array/narray attributes
+			context.IncrementOffset(1);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/FieldMarshaller1.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/FieldMarshaller1.cs
new file mode 100644
index 0000000..a07525e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/FieldMarshaller1.cs
@@ -0,0 +1,110 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class FieldMarshaller1 : FieldMarshaller0
+	{
+		private bool HasBTreeIndex(FieldMetadata field)
+		{
+			return !field.IsVirtual();
+		}
+
+		public override void Write(Transaction trans, ClassMetadata clazz, ClassAspect aspect
+			, ByteArrayBuffer writer)
+		{
+			base.Write(trans, clazz, aspect, writer);
+			if (!(aspect is FieldMetadata))
+			{
+				return;
+			}
+			FieldMetadata field = (FieldMetadata)aspect;
+			if (!HasBTreeIndex(field))
+			{
+				return;
+			}
+			writer.WriteIDOf(trans, field.GetIndex(trans));
+		}
+
+		protected override RawFieldSpec ReadSpec(AspectType aspectType, ObjectContainerBase
+			 stream, ByteArrayBuffer reader)
+		{
+			RawFieldSpec spec = base.ReadSpec(aspectType, stream, reader);
+			if (spec == null)
+			{
+				return null;
+			}
+			if (spec.IsVirtual())
+			{
+				return spec;
+			}
+			int indexID = reader.ReadInt();
+			spec.IndexID(indexID);
+			return spec;
+		}
+
+		protected override FieldMetadata FromSpec(RawFieldSpec spec, ObjectContainerBase 
+			stream, ClassMetadata containingClass)
+		{
+			FieldMetadata actualField = base.FromSpec(spec, stream, containingClass);
+			if (spec == null)
+			{
+				return null;
+			}
+			if (spec.IndexID() != 0)
+			{
+				actualField.InitIndex(stream.SystemTransaction(), spec.IndexID());
+			}
+			return actualField;
+		}
+
+		public override int MarshalledLength(ObjectContainerBase stream, ClassAspect aspect
+			)
+		{
+			int len = base.MarshalledLength(stream, aspect);
+			if (!(aspect is FieldMetadata))
+			{
+				return len;
+			}
+			FieldMetadata field = (FieldMetadata)aspect;
+			if (!HasBTreeIndex(field))
+			{
+				return len;
+			}
+			return len + Const4.IdLength;
+		}
+
+		public override void Defrag(ClassMetadata classMetadata, ClassAspect aspect, LatinStringIO
+			 sio, DefragmentContextImpl context)
+		{
+			base.Defrag(classMetadata, aspect, sio, context);
+			if (!(aspect is FieldMetadata))
+			{
+				return;
+			}
+			FieldMetadata field = (FieldMetadata)aspect;
+			if (field.IsVirtual())
+			{
+				return;
+			}
+			if (field.HasIndex())
+			{
+				BTree index = field.GetIndex(context.SystemTrans());
+				int targetIndexID = context.CopyID();
+				if (targetIndexID != 0)
+				{
+					index.DefragBTree(context.Services());
+				}
+			}
+			else
+			{
+				context.WriteInt(0);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/FieldMarshaller2.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/FieldMarshaller2.cs
new file mode 100644
index 0000000..312e548
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/FieldMarshaller2.cs
@@ -0,0 +1,40 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class FieldMarshaller2 : FieldMarshaller1
+	{
+		private const int AspectTypeTagLength = 1;
+
+		public override int MarshalledLength(ObjectContainerBase stream, ClassAspect aspect
+			)
+		{
+			return base.MarshalledLength(stream, aspect) + AspectTypeTagLength;
+		}
+
+		protected override RawFieldSpec ReadSpec(AspectType aspectType, ObjectContainerBase
+			 stream, ByteArrayBuffer reader)
+		{
+			return base.ReadSpec(AspectType.ForByte(reader.ReadByte()), stream, reader);
+		}
+
+		public override void Write(Transaction trans, ClassMetadata clazz, ClassAspect aspect
+			, ByteArrayBuffer writer)
+		{
+			writer.WriteByte(aspect.AspectType()._id);
+			base.Write(trans, clazz, aspect, writer);
+		}
+
+		public override void Defrag(ClassMetadata classMetadata, ClassAspect aspect, LatinStringIO
+			 sio, DefragmentContextImpl context)
+		{
+			context.ReadByte();
+			base.Defrag(classMetadata, aspect, sio, context);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IAspectVersionContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IAspectVersionContext.cs
new file mode 100644
index 0000000..38c70b6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IAspectVersionContext.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public interface IAspectVersionContext
+	{
+		int DeclaredAspectCount();
+
+		void DeclaredAspectCount(int count);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IFieldMarshaller.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IFieldMarshaller.cs
new file mode 100644
index 0000000..4b34637
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IFieldMarshaller.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public interface IFieldMarshaller
+	{
+		void Write(Transaction trans, ClassMetadata clazz, ClassAspect aspect, ByteArrayBuffer
+			 writer);
+
+		RawFieldSpec ReadSpec(ObjectContainerBase stream, ByteArrayBuffer reader);
+
+		FieldMetadata Read(ObjectContainerBase stream, ClassMetadata clazz, ByteArrayBuffer
+			 reader);
+
+		int MarshalledLength(ObjectContainerBase stream, ClassAspect aspect);
+
+		void Defrag(ClassMetadata classMetadata, ClassAspect aspect, LatinStringIO sio, DefragmentContextImpl
+			 context);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IHandlerVersionContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IHandlerVersionContext.cs
new file mode 100644
index 0000000..004a111
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IHandlerVersionContext.cs
@@ -0,0 +1,14 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public interface IHandlerVersionContext : IContext
+	{
+		int HandlerVersion();
+
+		Db4objects.Db4o.Internal.Marshall.SlotFormat SlotFormat();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IInternalReadContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IInternalReadContext.cs
new file mode 100644
index 0000000..a042b00
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IInternalReadContext.cs
@@ -0,0 +1,33 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public interface IInternalReadContext : IReadContext, IHandlerVersionContext
+	{
+		IReadBuffer Buffer(IReadBuffer buffer);
+
+		IReadBuffer Buffer();
+
+		ObjectContainerBase Container();
+
+		int Offset();
+
+		object Read(ITypeHandler4 handler);
+
+		object ReadAtCurrentSeekPosition(ITypeHandler4 handler);
+
+		IReadWriteBuffer ReadIndirectedBuffer();
+
+		void Seek(int offset);
+
+		int HandlerVersion();
+
+		void NotifyNullReferenceSkipped();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IMarshallingInfo.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IMarshallingInfo.cs
new file mode 100644
index 0000000..57a8402
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IMarshallingInfo.cs
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public interface IMarshallingInfo : IAspectVersionContext
+	{
+		Db4objects.Db4o.Internal.ClassMetadata ClassMetadata();
+
+		IReadBuffer Buffer();
+
+		void BeginSlot();
+
+		bool IsNull(int fieldIndex);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IObjectIdContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IObjectIdContext.cs
new file mode 100644
index 0000000..d306717
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IObjectIdContext.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public interface IObjectIdContext : IHandlerVersionContext, IInternalReadContext
+	{
+		int ObjectId();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IdObjectCollector.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IdObjectCollector.cs
new file mode 100644
index 0000000..b63775d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/IdObjectCollector.cs
@@ -0,0 +1,36 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class IdObjectCollector
+	{
+		private TreeInt _ids;
+
+		private List4 _objects;
+
+		public virtual void AddId(int id)
+		{
+			_ids = (TreeInt)((TreeInt)Tree.Add(_ids, new TreeInt(id)));
+		}
+
+		public virtual TreeInt Ids()
+		{
+			return _ids;
+		}
+
+		public virtual void Add(object obj)
+		{
+			_objects = new List4(_objects, obj);
+		}
+
+		public virtual IEnumerator Objects()
+		{
+			return new Iterator4Impl(_objects);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/MarshallerFamily.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/MarshallerFamily.cs
new file mode 100644
index 0000000..7c50da5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/MarshallerFamily.cs
@@ -0,0 +1,129 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Convert.Conversions;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <summary>
+	/// Represents a db4o file format version, assembles all the marshallers
+	/// needed to read/write this specific version.
+	/// </summary>
+	/// <remarks>
+	/// Represents a db4o file format version, assembles all the marshallers
+	/// needed to read/write this specific version.
+	/// A marshaller knows how to read/write certain types of values from/to its
+	/// representation on disk for a given db4o file format version.
+	/// Responsibilities are somewhat overlapping with TypeHandler's.
+	/// </remarks>
+	/// <exclude></exclude>
+	public class MarshallerFamily
+	{
+		public class FamilyVersion
+		{
+			public const int PreMarshaller = 0;
+
+			public const int Marshaller = 1;
+
+			public const int BtreeFieldIndexes = 2;
+
+			public const int ClassAspects = 3;
+		}
+
+		private static int CurrentVersion = MarshallerFamily.FamilyVersion.ClassAspects;
+
+		public readonly ClassMarshaller _class;
+
+		public readonly IFieldMarshaller _field;
+
+		public readonly PrimitiveMarshaller _primitive;
+
+		private readonly int _converterVersion;
+
+		private readonly int _handlerVersion;
+
+		private static readonly MarshallerFamily[] allVersions;
+
+		static MarshallerFamily()
+		{
+			allVersions = new MarshallerFamily[HandlerRegistry.HandlerVersion + 1];
+			allVersions[0] = new MarshallerFamily(0, 0, new ClassMarshaller0(), new FieldMarshaller0
+				(), new PrimitiveMarshaller0());
+			// LEGACY => before 5.4
+			allVersions[1] = new MarshallerFamily(ClassIndexesToBTrees_5_5.Version, 1, new ClassMarshaller1
+				(), new FieldMarshaller0(), new PrimitiveMarshaller1());
+			allVersions[2] = new MarshallerFamily(FieldIndexesToBTrees_5_7.Version, 2, new ClassMarshaller2
+				(), new FieldMarshaller1(), new PrimitiveMarshaller1());
+			for (int i = 3; i < allVersions.Length; i++)
+			{
+				allVersions[i] = LatestFamily(i);
+			}
+		}
+
+		public MarshallerFamily(int converterVersion, int handlerVersion, ClassMarshaller
+			 classMarshaller, IFieldMarshaller fieldMarshaller, PrimitiveMarshaller primitiveMarshaller
+			)
+		{
+			_converterVersion = converterVersion;
+			_handlerVersion = handlerVersion;
+			_class = classMarshaller;
+			_class._family = this;
+			_field = fieldMarshaller;
+			_primitive = primitiveMarshaller;
+			_primitive._family = this;
+		}
+
+		public static MarshallerFamily LatestFamily(int version)
+		{
+			return new MarshallerFamily(ClassAspects_7_4.Version, version, new ClassMarshaller2
+				(), new FieldMarshaller2(), new PrimitiveMarshaller1());
+		}
+
+		public static MarshallerFamily Version(int n)
+		{
+			CheckIfVersionIsTooNew(n);
+			return allVersions[n];
+		}
+
+		private static void CheckIfVersionIsTooNew(int n)
+		{
+			if (n > allVersions.Length)
+			{
+				throw new IncompatibleFileFormatException("Databasefile was created with a newer db4o version. Marshaller version: "
+					 + n);
+			}
+		}
+
+		public static MarshallerFamily Current()
+		{
+			if (CurrentVersion < MarshallerFamily.FamilyVersion.BtreeFieldIndexes)
+			{
+				throw new InvalidOperationException("Using old marshaller versions to write database files is not supported, source code has been removed."
+					);
+			}
+			return Version(CurrentVersion);
+		}
+
+		public static MarshallerFamily ForConverterVersion(int n)
+		{
+			MarshallerFamily result = allVersions[0];
+			for (int i = 1; i < allVersions.Length; i++)
+			{
+				if (allVersions[i]._converterVersion > n)
+				{
+					return result;
+				}
+				result = allVersions[i];
+			}
+			return result;
+		}
+
+		public virtual int HandlerVersion()
+		{
+			return _handlerVersion;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/MarshallingContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/MarshallingContext.cs
new file mode 100644
index 0000000..9613775
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/MarshallingContext.cs
@@ -0,0 +1,396 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class MarshallingContext : IMarshallingInfo, IWriteContext
+	{
+		private const int HeaderLength = Const4.LeadingLength + Const4.IdLength + 1 + Const4
+			.IntLength;
+
+		private readonly Db4objects.Db4o.Internal.Transaction _transaction;
+
+		private readonly ObjectReference _reference;
+
+		private IUpdateDepth _updateDepth;
+
+		private readonly bool _isNew;
+
+		private readonly BitMap4 _nullBitMap;
+
+		private readonly MarshallingBuffer _writeBuffer;
+
+		private MarshallingBuffer _currentBuffer;
+
+		private ByteArrayBuffer _debugPrepend;
+
+		private object _currentMarshalledObject;
+
+		private object _currentIndexEntry;
+
+		private int _declaredAspectCount;
+
+		public MarshallingContext(Db4objects.Db4o.Internal.Transaction trans, ObjectReference
+			 @ref, IUpdateDepth updateDepth, bool isNew)
+		{
+			// YapClass ID
+			// Marshaller Version
+			// number of fields
+			_transaction = trans;
+			_reference = @ref;
+			_nullBitMap = new BitMap4(AspectCount());
+			_updateDepth = ClassMetadata().AdjustUpdateDepth(trans, updateDepth);
+			_isNew = isNew;
+			_writeBuffer = new MarshallingBuffer();
+			_currentBuffer = _writeBuffer;
+		}
+
+		private int AspectCount()
+		{
+			return ClassMetadata().AspectCount();
+		}
+
+		public virtual Db4objects.Db4o.Internal.ClassMetadata ClassMetadata()
+		{
+			return _reference.ClassMetadata();
+		}
+
+		public virtual bool IsNew()
+		{
+			return _isNew;
+		}
+
+		public virtual bool IsNull(int fieldIndex)
+		{
+			// TODO Auto-generated method stub
+			return false;
+		}
+
+		public virtual void IsNull(int fieldIndex, bool flag)
+		{
+			_nullBitMap.Set(fieldIndex, flag);
+		}
+
+		public virtual Db4objects.Db4o.Internal.Transaction Transaction()
+		{
+			return _transaction;
+		}
+
+		public virtual Slot AllocateNewSlot(int length)
+		{
+			if (_transaction is LocalTransaction)
+			{
+				return LocalContainer().AllocateSlotForNewUserObject(_transaction, ObjectID(), length
+					);
+			}
+			return new Slot(Slot.New, length);
+		}
+
+		private Slot AllocateUpdateSlot(int length)
+		{
+			if (_transaction is LocalTransaction)
+			{
+				return LocalContainer().AllocateSlotForUserObjectUpdate(Transaction(), ObjectID()
+					, length);
+			}
+			return new Slot(Slot.Update, length);
+		}
+
+		private LocalObjectContainer LocalContainer()
+		{
+			return ((LocalTransaction)Transaction()).LocalContainer();
+		}
+
+		public virtual Pointer4 AllocateSlot()
+		{
+			int length = Container().BlockConverter().BlockAlignedBytes(MarshalledLength());
+			Slot slot = IsNew() ? AllocateNewSlot(length) : AllocateUpdateSlot(length);
+			return new Pointer4(ObjectID(), slot);
+		}
+
+		public virtual ByteArrayBuffer ToWriteBuffer(Pointer4 pointer)
+		{
+			ByteArrayBuffer buffer = new ByteArrayBuffer(pointer.Length());
+			_writeBuffer.MergeChildren(this, pointer.Address(), WriteBufferOffset());
+			WriteObjectClassID(buffer, ClassMetadata().GetID());
+			buffer.WriteByte(HandlerRegistry.HandlerVersion);
+			buffer.WriteInt(AspectCount());
+			buffer.WriteBitMap(_nullBitMap);
+			_writeBuffer.TransferContentTo(buffer);
+			return buffer;
+		}
+
+		private int WriteBufferOffset()
+		{
+			return HeaderLength + _nullBitMap.MarshalledLength();
+		}
+
+		public virtual int MarshalledLength()
+		{
+			int length = WriteBufferOffset();
+			_writeBuffer.CheckBlockAlignment(this, null, new IntByRef(length));
+			return length + _writeBuffer.MarshalledLength() + Const4.BracketsBytes;
+		}
+
+		public virtual int RequiredLength(MarshallingBuffer buffer, bool align)
+		{
+			if (!align)
+			{
+				return buffer.Length();
+			}
+			return Container().BlockConverter().BlockAlignedBytes(buffer.Length());
+		}
+
+		private void WriteObjectClassID(ByteArrayBuffer reader, int id)
+		{
+			reader.WriteInt(-id);
+		}
+
+		public virtual object GetObject()
+		{
+			return _reference.GetObject();
+		}
+
+		public virtual Config4Class ClassConfiguration()
+		{
+			return ClassMetadata().Config();
+		}
+
+		public virtual IUpdateDepth UpdateDepth()
+		{
+			return _updateDepth;
+		}
+
+		public virtual void UpdateDepth(IUpdateDepth depth)
+		{
+			_updateDepth = depth;
+		}
+
+		public virtual int ObjectID()
+		{
+			return _reference.GetID();
+		}
+
+		public virtual object CurrentIndexEntry()
+		{
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		public virtual ObjectContainerBase Container()
+		{
+			return Transaction().Container();
+		}
+
+		public virtual IObjectContainer ObjectContainer()
+		{
+			return Transaction().ObjectContainer();
+		}
+
+		public virtual void WriteByte(byte b)
+		{
+			PreWrite();
+			_currentBuffer.WriteByte(b);
+			PostWrite();
+		}
+
+		public virtual void WriteBytes(byte[] bytes)
+		{
+			PreWrite();
+			_currentBuffer.WriteBytes(bytes);
+			PostWrite();
+		}
+
+		public virtual void WriteInt(int i)
+		{
+			PreWrite();
+			_currentBuffer.WriteInt(i);
+			PostWrite();
+		}
+
+		public virtual void WriteLong(long l)
+		{
+			PreWrite();
+			_currentBuffer.WriteLong(l);
+			PostWrite();
+		}
+
+		private void PreWrite()
+		{
+		}
+
+		private void PostWrite()
+		{
+		}
+
+		public virtual void CreateChildBuffer(bool storeLengthInLink)
+		{
+			MarshallingBuffer childBuffer = _currentBuffer.AddChild(false, storeLengthInLink);
+			_currentBuffer.ReserveChildLinkSpace(storeLengthInLink);
+			_currentBuffer = childBuffer;
+		}
+
+		public virtual void BeginSlot()
+		{
+			_currentBuffer = _writeBuffer;
+		}
+
+		public virtual void WriteDeclaredAspectCount(int count)
+		{
+			_writeBuffer.WriteInt(count);
+		}
+
+		public virtual void DebugPrependNextWrite(ByteArrayBuffer prepend)
+		{
+		}
+
+		public virtual void DebugWriteEnd(byte b)
+		{
+			_currentBuffer.WriteByte(b);
+		}
+
+		public virtual void WriteObject(object obj)
+		{
+			int id = Container().StoreInternal(Transaction(), obj, _updateDepth, true);
+			WriteInt(id);
+			_currentMarshalledObject = obj;
+			_currentIndexEntry = id;
+		}
+
+		public virtual void WriteObject(ITypeHandler4 handler, object obj)
+		{
+			MarshallingContextState state = CurrentState();
+			WriteObjectWithCurrentState(handler, obj);
+			RestoreState(state);
+		}
+
+		public virtual void WriteObjectWithCurrentState(ITypeHandler4 handler, object obj
+			)
+		{
+			if (Handlers4.UseDedicatedSlot(this, handler))
+			{
+				WriteObject(obj);
+			}
+			else
+			{
+				if (obj == null)
+				{
+					WriteNullReference(handler);
+				}
+				else
+				{
+					CreateIndirectionWithinSlot(handler);
+					handler.Write(this, obj);
+				}
+			}
+		}
+
+		private void WriteNullReference(ITypeHandler4 handler)
+		{
+			if (IsIndirectedWithinSlot(handler))
+			{
+				WriteNullLink();
+				return;
+			}
+			Handlers4.Write(handler, this, Handlers4.NullRepresentationInUntypedArrays(handler
+				));
+		}
+
+		private void WriteNullLink()
+		{
+			WriteInt(0);
+			WriteInt(0);
+		}
+
+		public virtual void AddIndexEntry(FieldMetadata fieldMetadata, object obj)
+		{
+			if (!_currentBuffer.HasParent())
+			{
+				object indexEntry = (obj == _currentMarshalledObject) ? _currentIndexEntry : obj;
+				if (_isNew || !UpdateDepth().CanSkip(_reference))
+				{
+					fieldMetadata.AddIndexEntry(Transaction(), ObjectID(), indexEntry);
+				}
+				return;
+			}
+			_currentBuffer.RequestIndexEntry(fieldMetadata);
+		}
+
+		public virtual void PurgeFieldIndexEntriesOnUpdate(Db4objects.Db4o.Internal.Transaction
+			 transaction, ArrayType arrayType)
+		{
+			if (!UpdateDepth().CanSkip(_reference))
+			{
+				transaction.WriteUpdateAdjustIndexes(_reference.GetID(), _reference.ClassMetadata
+					(), arrayType);
+			}
+		}
+
+		public virtual ObjectReference Reference()
+		{
+			return _reference;
+		}
+
+		public virtual void CreateIndirectionWithinSlot(ITypeHandler4 handler)
+		{
+			if (IsIndirectedWithinSlot(handler))
+			{
+				CreateIndirectionWithinSlot();
+			}
+		}
+
+		public virtual void CreateIndirectionWithinSlot()
+		{
+			CreateChildBuffer(true);
+		}
+
+		private bool IsIndirectedWithinSlot(ITypeHandler4 handler)
+		{
+			return SlotFormat.Current().IsIndirectedWithinSlot(handler);
+		}
+
+		// FIXME: This method was just temporarily added to fulfill contract of MarshallingInfo
+		//        It will go, the buffer is never needed in new marshalling. 
+		public virtual IReadBuffer Buffer()
+		{
+			return null;
+		}
+
+		public virtual MarshallingContextState CurrentState()
+		{
+			return new MarshallingContextState(_currentBuffer);
+		}
+
+		public virtual void RestoreState(MarshallingContextState state)
+		{
+			_currentBuffer = state._buffer;
+		}
+
+		public virtual IReservedBuffer Reserve(int length)
+		{
+			PreWrite();
+			IReservedBuffer reservedBuffer = _currentBuffer.Reserve(length);
+			PostWrite();
+			return reservedBuffer;
+		}
+
+		public virtual int DeclaredAspectCount()
+		{
+			return _declaredAspectCount;
+		}
+
+		public virtual void DeclaredAspectCount(int count)
+		{
+			_declaredAspectCount = count;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/MarshallingContextState.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/MarshallingContextState.cs
new file mode 100644
index 0000000..fee7d90
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/MarshallingContextState.cs
@@ -0,0 +1,17 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class MarshallingContextState
+	{
+		internal readonly MarshallingBuffer _buffer;
+
+		public MarshallingContextState(MarshallingBuffer buffer)
+		{
+			_buffer = buffer;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ObjectHeader.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ObjectHeader.cs
new file mode 100644
index 0000000..b617f6c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ObjectHeader.cs
@@ -0,0 +1,104 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public sealed class ObjectHeader
+	{
+		private readonly Db4objects.Db4o.Internal.ClassMetadata _classMetadata;
+
+		public readonly MarshallerFamily _marshallerFamily;
+
+		public readonly ObjectHeaderAttributes _headerAttributes;
+
+		private int _handlerVersion;
+
+		public ObjectHeader(ObjectContainerBase container, IReadWriteBuffer reader) : this
+			(container, null, reader)
+		{
+		}
+
+		public ObjectHeader(Db4objects.Db4o.Internal.ClassMetadata classMetadata, IReadWriteBuffer
+			 reader) : this(null, classMetadata, reader)
+		{
+		}
+
+		private ObjectHeader(ObjectContainerBase container, Db4objects.Db4o.Internal.ClassMetadata
+			 classMetadata, IReadWriteBuffer reader)
+		{
+			int classID = reader.ReadInt();
+			_marshallerFamily = ReadMarshallerFamily(reader, classID);
+			classID = NormalizeID(classID);
+			_classMetadata = (classMetadata != null ? classMetadata : container.ClassMetadataForID
+				(classID));
+			// This check has been added to cope with defragment in debug mode: SlotDefragment#setIdentity()
+			// will trigger calling this constructor with a source db class metadata and a target db stream,
+			// thus _classMetadata==null. There may be a better solution, since this call is just meant to
+			// skip the object header.
+			_headerAttributes = SlotFormat().ReadHeaderAttributes((ByteArrayBuffer)reader);
+		}
+
+		public static Db4objects.Db4o.Internal.Marshall.ObjectHeader Defrag(DefragmentContextImpl
+			 context)
+		{
+			ByteArrayBuffer source = context.SourceBuffer();
+			ByteArrayBuffer target = context.TargetBuffer();
+			Db4objects.Db4o.Internal.Marshall.ObjectHeader header = new Db4objects.Db4o.Internal.Marshall.ObjectHeader
+				(context.Services().SystemTrans().Container(), null, source);
+			int newID = context.Mapping().StrictMappedID(header.ClassMetadata().GetID());
+			Db4objects.Db4o.Internal.Marshall.SlotFormat slotFormat = header.SlotFormat();
+			slotFormat.WriteObjectClassID(target, newID);
+			slotFormat.SkipMarshallerInfo(target);
+			slotFormat.ReadHeaderAttributes(target);
+			return header;
+		}
+
+		private Db4objects.Db4o.Internal.Marshall.SlotFormat SlotFormat()
+		{
+			return Db4objects.Db4o.Internal.Marshall.SlotFormat.ForHandlerVersion(HandlerVersion
+				());
+		}
+
+		private MarshallerFamily ReadMarshallerFamily(IReadWriteBuffer reader, int classID
+			)
+		{
+			bool marshallerAware = MarshallerAware(classID);
+			_handlerVersion = 0;
+			if (marshallerAware)
+			{
+				_handlerVersion = reader.ReadByte();
+			}
+			MarshallerFamily marshallerFamily = MarshallerFamily.Version(_handlerVersion);
+			return marshallerFamily;
+		}
+
+		private bool MarshallerAware(int id)
+		{
+			return id < 0;
+		}
+
+		private int NormalizeID(int id)
+		{
+			return (id < 0 ? -id : id);
+		}
+
+		public Db4objects.Db4o.Internal.ClassMetadata ClassMetadata()
+		{
+			return _classMetadata;
+		}
+
+		public int HandlerVersion()
+		{
+			return _handlerVersion;
+		}
+
+		public static Db4objects.Db4o.Internal.Marshall.ObjectHeader ScrollBufferToContent
+			(LocalObjectContainer container, ByteArrayBuffer buffer)
+		{
+			return new Db4objects.Db4o.Internal.Marshall.ObjectHeader(container, buffer);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ObjectHeaderAttributes.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ObjectHeaderAttributes.cs
new file mode 100644
index 0000000..ee195a3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ObjectHeaderAttributes.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class ObjectHeaderAttributes
+	{
+		private readonly int _fieldCount;
+
+		private readonly BitMap4 _nullBitMap;
+
+		public ObjectHeaderAttributes(ByteArrayBuffer reader)
+		{
+			_fieldCount = reader.ReadInt();
+			_nullBitMap = reader.ReadBitMap(_fieldCount);
+		}
+
+		public virtual bool IsNull(int fieldIndex)
+		{
+			return _nullBitMap.IsTrue(fieldIndex);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ObjectHeaderContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ObjectHeaderContext.cs
new file mode 100644
index 0000000..69277b9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ObjectHeaderContext.cs
@@ -0,0 +1,67 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class ObjectHeaderContext : AbstractReadContext, IMarshallingInfo, IHandlerVersionContext
+	{
+		protected ObjectHeader _objectHeader;
+
+		private int _declaredAspectCount;
+
+		public ObjectHeaderContext(Transaction transaction, IReadBuffer buffer, ObjectHeader
+			 objectHeader) : base(transaction, buffer)
+		{
+			_objectHeader = objectHeader;
+		}
+
+		public ObjectHeaderAttributes HeaderAttributes()
+		{
+			return _objectHeader._headerAttributes;
+		}
+
+		public bool IsNull(int fieldIndex)
+		{
+			return HeaderAttributes().IsNull(fieldIndex);
+		}
+
+		public override int HandlerVersion()
+		{
+			return _objectHeader.HandlerVersion();
+		}
+
+		public virtual void BeginSlot()
+		{
+		}
+
+		// do nothing
+		public virtual ContextState SaveState()
+		{
+			return new ContextState(Offset());
+		}
+
+		public virtual void RestoreState(ContextState state)
+		{
+			Seek(state._offset);
+		}
+
+		public virtual Db4objects.Db4o.Internal.ClassMetadata ClassMetadata()
+		{
+			return _objectHeader.ClassMetadata();
+		}
+
+		public virtual int DeclaredAspectCount()
+		{
+			return _declaredAspectCount;
+		}
+
+		public virtual void DeclaredAspectCount(int count)
+		{
+			_declaredAspectCount = count;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ObjectIdContextImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ObjectIdContextImpl.cs
new file mode 100644
index 0000000..eec764f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ObjectIdContextImpl.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class ObjectIdContextImpl : ObjectHeaderContext, IObjectIdContext
+	{
+		private readonly int _id;
+
+		public ObjectIdContextImpl(Transaction transaction, IReadBuffer buffer, ObjectHeader
+			 objectHeader, int id) : base(transaction, buffer, objectHeader)
+		{
+			_id = id;
+		}
+
+		public virtual int ObjectId()
+		{
+			return _id;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ObjectReferenceContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ObjectReferenceContext.cs
new file mode 100644
index 0000000..0b5ce0d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/ObjectReferenceContext.cs
@@ -0,0 +1,46 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	public class ObjectReferenceContext : ObjectHeaderContext, IObjectIdContext
+	{
+		protected readonly Db4objects.Db4o.Internal.ObjectReference _reference;
+
+		public ObjectReferenceContext(Transaction transaction, IReadBuffer buffer, ObjectHeader
+			 objectHeader, Db4objects.Db4o.Internal.ObjectReference reference) : base(transaction
+			, buffer, objectHeader)
+		{
+			_reference = reference;
+		}
+
+		public virtual int ObjectId()
+		{
+			return _reference.GetID();
+		}
+
+		public override Db4objects.Db4o.Internal.ClassMetadata ClassMetadata()
+		{
+			Db4objects.Db4o.Internal.ClassMetadata classMetadata = _reference.ClassMetadata();
+			if (classMetadata == null)
+			{
+				throw new InvalidOperationException();
+			}
+			return classMetadata;
+		}
+
+		public virtual Db4objects.Db4o.Internal.ObjectReference ObjectReference()
+		{
+			return _reference;
+		}
+
+		protected virtual Db4objects.Db4o.Internal.ByteArrayBuffer ByteArrayBuffer()
+		{
+			return (Db4objects.Db4o.Internal.ByteArrayBuffer)Buffer();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/PrimitiveMarshaller.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/PrimitiveMarshaller.cs
new file mode 100644
index 0000000..0a34d9b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/PrimitiveMarshaller.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	public abstract class PrimitiveMarshaller
+	{
+		public MarshallerFamily _family;
+
+		public abstract bool UseNormalClassRead();
+
+		public abstract DateTime ReadDate(ByteArrayBuffer bytes);
+
+		public abstract object ReadShort(ByteArrayBuffer buffer);
+
+		public abstract object ReadInteger(ByteArrayBuffer buffer);
+
+		public abstract object ReadFloat(ByteArrayBuffer buffer);
+
+		public abstract object ReadDouble(ByteArrayBuffer buffer);
+
+		public abstract object ReadLong(ByteArrayBuffer buffer);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/PrimitiveMarshaller0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/PrimitiveMarshaller0.cs
new file mode 100644
index 0000000..d0f3b06
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/PrimitiveMarshaller0.cs
@@ -0,0 +1,96 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	public class PrimitiveMarshaller0 : PrimitiveMarshaller
+	{
+		public override bool UseNormalClassRead()
+		{
+			return true;
+		}
+
+		public override DateTime ReadDate(ByteArrayBuffer bytes)
+		{
+			long value = bytes.ReadLong();
+			if (value == long.MaxValue)
+			{
+				return MarshallingConstants0.NullDate;
+			}
+			return new DateTime(value);
+		}
+
+		public override object ReadInteger(ByteArrayBuffer bytes)
+		{
+			int value = bytes.ReadInt();
+			if (value == int.MaxValue)
+			{
+				return null;
+			}
+			return value;
+		}
+
+		public override object ReadFloat(ByteArrayBuffer bytes)
+		{
+			float value = UnmarshallFloat(bytes);
+			if (float.IsNaN(value))
+			{
+				return null;
+			}
+			return value;
+		}
+
+		public override object ReadDouble(ByteArrayBuffer buffer)
+		{
+			double value = UnmarshalDouble(buffer);
+			if (double.IsNaN(value))
+			{
+				return null;
+			}
+			return value;
+		}
+
+		public override object ReadLong(ByteArrayBuffer buffer)
+		{
+			long value = buffer.ReadLong();
+			if (value == long.MaxValue)
+			{
+				return null;
+			}
+			return value;
+		}
+
+		public override object ReadShort(ByteArrayBuffer buffer)
+		{
+			short value = UnmarshallShort(buffer);
+			if (value == short.MaxValue)
+			{
+				return null;
+			}
+			return value;
+		}
+
+		public static double UnmarshalDouble(ByteArrayBuffer buffer)
+		{
+			return Platform4.LongToDouble(buffer.ReadLong());
+		}
+
+		public static float UnmarshallFloat(ByteArrayBuffer buffer)
+		{
+			return Sharpen.Runtime.IntBitsToFloat(buffer.ReadInt());
+		}
+
+		public static short UnmarshallShort(ByteArrayBuffer buffer)
+		{
+			int ret = 0;
+			for (int i = 0; i < Const4.ShortBytes; i++)
+			{
+				ret = (ret << 8) + (buffer._buffer[buffer._offset++] & unchecked((int)(0xff)));
+			}
+			return (short)ret;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/PrimitiveMarshaller1.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/PrimitiveMarshaller1.cs
new file mode 100644
index 0000000..9c1c869
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/PrimitiveMarshaller1.cs
@@ -0,0 +1,46 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	public class PrimitiveMarshaller1 : PrimitiveMarshaller
+	{
+		public override bool UseNormalClassRead()
+		{
+			return false;
+		}
+
+		public override DateTime ReadDate(ByteArrayBuffer bytes)
+		{
+			return new DateTime(bytes.ReadLong());
+		}
+
+		public override object ReadInteger(ByteArrayBuffer bytes)
+		{
+			return bytes.ReadInt();
+		}
+
+		public override object ReadFloat(ByteArrayBuffer bytes)
+		{
+			return PrimitiveMarshaller0.UnmarshallFloat(bytes);
+		}
+
+		public override object ReadDouble(ByteArrayBuffer buffer)
+		{
+			return PrimitiveMarshaller0.UnmarshalDouble(buffer);
+		}
+
+		public override object ReadLong(ByteArrayBuffer buffer)
+		{
+			return buffer.ReadLong();
+		}
+
+		public override object ReadShort(ByteArrayBuffer buffer)
+		{
+			return PrimitiveMarshaller0.UnmarshallShort(buffer);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/QueryingReadContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/QueryingReadContext.cs
new file mode 100644
index 0000000..0d87391
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/QueryingReadContext.cs
@@ -0,0 +1,183 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class QueryingReadContext : AbstractReadContext, IHandlerVersionContext, IAspectVersionContext
+		, IObjectIdContext
+	{
+		private readonly QCandidates _candidates;
+
+		private readonly int _collectionID;
+
+		private readonly int _handlerVersion;
+
+		private IdObjectCollector _collector;
+
+		private int _declaredAspectCount;
+
+		private int _id;
+
+		private QueryingReadContext(Transaction transaction, QCandidates candidates, int 
+			handlerVersion, IReadBuffer buffer, int collectionID, IdObjectCollector collector
+			) : base(transaction, buffer)
+		{
+			_candidates = candidates;
+			_activationDepth = new LegacyActivationDepth(0);
+			_collectionID = collectionID;
+			_handlerVersion = handlerVersion;
+			_collector = collector;
+		}
+
+		public QueryingReadContext(Transaction transaction, QCandidates candidates, int handlerVersion
+			, IReadBuffer buffer, int collectionID) : this(transaction, candidates, handlerVersion
+			, buffer, collectionID, new IdObjectCollector())
+		{
+		}
+
+		public QueryingReadContext(Transaction transaction, int handlerVersion, IReadBuffer
+			 buffer, int id) : this(transaction, null, handlerVersion, buffer, 0)
+		{
+			_id = id;
+		}
+
+		public QueryingReadContext(Transaction transaction, int handlerVersion, IReadBuffer
+			 buffer, int collectionID, IdObjectCollector collector) : this(transaction, null
+			, handlerVersion, buffer, collectionID, collector)
+		{
+		}
+
+		public virtual int CollectionID()
+		{
+			return _collectionID;
+		}
+
+		public virtual QCandidates Candidates()
+		{
+			return _candidates;
+		}
+
+		public override int HandlerVersion()
+		{
+			return _handlerVersion;
+		}
+
+		private void AddId(int id)
+		{
+			_collector.AddId(id);
+		}
+
+		public virtual TreeInt Ids()
+		{
+			return _collector.Ids();
+		}
+
+		public virtual void Add(object obj)
+		{
+			int id = GetID(obj);
+			if (id > 0)
+			{
+				AddId(id);
+				return;
+			}
+			AddObjectWithoutId(obj);
+		}
+
+		private int GetID(object obj)
+		{
+			return Container().GetID(Transaction(), obj);
+		}
+
+		public virtual void ReadId(ITypeHandler4 handler)
+		{
+			ObjectID objectID = ObjectID.NotPossible;
+			try
+			{
+				int offset = Offset();
+				if (handler is IReadsObjectIds)
+				{
+					objectID = ((IReadsObjectIds)handler).ReadObjectID(this);
+				}
+				if (objectID.IsValid())
+				{
+					AddId(objectID._id);
+					return;
+				}
+				if (objectID == ObjectID.NotPossible)
+				{
+					Seek(offset);
+					// FIXME: there's no point in activating the object
+					// just find its id
+					// type handlers know how to do it
+					object obj = Read(handler);
+					if (obj != null)
+					{
+						int id = (int)GetID(obj);
+						if (id > 0)
+						{
+							AddId(id);
+						}
+						else
+						{
+							AddObjectWithoutId(obj);
+						}
+					}
+				}
+			}
+			catch (Exception)
+			{
+			}
+		}
+
+		// FIXME: Catchall
+		private void AddObjectWithoutId(object obj)
+		{
+			_collector.Add(obj);
+		}
+
+		public virtual void SkipId(ITypeHandler4 handler)
+		{
+			if (handler is IReadsObjectIds)
+			{
+				((IReadsObjectIds)handler).ReadObjectID(this);
+				return;
+			}
+			// TODO: Optimize for just doing a seek here.
+			Read(handler);
+		}
+
+		public virtual IEnumerator ObjectsWithoutId()
+		{
+			return _collector.Objects();
+		}
+
+		public virtual int DeclaredAspectCount()
+		{
+			return _declaredAspectCount;
+		}
+
+		public virtual void DeclaredAspectCount(int count)
+		{
+			_declaredAspectCount = count;
+		}
+
+		public virtual IdObjectCollector Collector()
+		{
+			return _collector;
+		}
+
+		public virtual int ObjectId()
+		{
+			return _id;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/RawClassSpec.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/RawClassSpec.cs
new file mode 100644
index 0000000..9688f36
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/RawClassSpec.cs
@@ -0,0 +1,36 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class RawClassSpec
+	{
+		private readonly string _name;
+
+		private readonly int _superClassID;
+
+		private readonly int _numFields;
+
+		public RawClassSpec(string name, int superClassID, int numFields)
+		{
+			_name = name;
+			_superClassID = superClassID;
+			_numFields = numFields;
+		}
+
+		public virtual string Name()
+		{
+			return _name;
+		}
+
+		public virtual int SuperClassID()
+		{
+			return _superClassID;
+		}
+
+		public virtual int NumFields()
+		{
+			return _numFields;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/RawFieldSpec.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/RawFieldSpec.cs
new file mode 100644
index 0000000..08c6b84
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/RawFieldSpec.cs
@@ -0,0 +1,117 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	public class RawFieldSpec
+	{
+		private readonly AspectType _type;
+
+		private readonly string _name;
+
+		private readonly int _fieldTypeID;
+
+		private readonly bool _isPrimitive;
+
+		private readonly bool _isArray;
+
+		private readonly bool _isNArray;
+
+		private readonly bool _isVirtual;
+
+		private int _indexID;
+
+		public RawFieldSpec(AspectType aspectType, string name, int fieldTypeID, byte attribs
+			)
+		{
+			_type = aspectType;
+			_name = name;
+			_fieldTypeID = fieldTypeID;
+			BitMap4 bitmap = new BitMap4(attribs);
+			_isPrimitive = bitmap.IsTrue(0);
+			_isArray = bitmap.IsTrue(1);
+			_isNArray = bitmap.IsTrue(2);
+			_isVirtual = false;
+			_indexID = 0;
+		}
+
+		public RawFieldSpec(AspectType aspectType, string name)
+		{
+			_type = aspectType;
+			_name = name;
+			_fieldTypeID = 0;
+			_isPrimitive = false;
+			_isArray = false;
+			_isNArray = false;
+			_isVirtual = true;
+			_indexID = 0;
+		}
+
+		public virtual string Name()
+		{
+			return _name;
+		}
+
+		public virtual int FieldTypeID()
+		{
+			return _fieldTypeID;
+		}
+
+		public virtual bool IsPrimitive()
+		{
+			return _isPrimitive;
+		}
+
+		public virtual bool IsArray()
+		{
+			return _isArray;
+		}
+
+		public virtual bool IsNArray()
+		{
+			return _isNArray;
+		}
+
+		public virtual bool IsVirtual()
+		{
+			return _isVirtual;
+		}
+
+		public virtual bool IsVirtualField()
+		{
+			return IsVirtual() && IsField();
+		}
+
+		public virtual bool IsField()
+		{
+			return _type.IsField();
+		}
+
+		public virtual int IndexID()
+		{
+			return _indexID;
+		}
+
+		internal virtual void IndexID(int indexID)
+		{
+			_indexID = indexID;
+		}
+
+		public override string ToString()
+		{
+			return "RawFieldSpec(" + Name() + ")";
+		}
+
+		public virtual bool IsFieldMetadata()
+		{
+			return _type.IsFieldMetadata();
+		}
+
+		public virtual bool IsTranslator()
+		{
+			return _type.IsTranslator();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/SlotFormat.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/SlotFormat.cs
new file mode 100644
index 0000000..3b6617d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/SlotFormat.cs
@@ -0,0 +1,118 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public abstract class SlotFormat
+	{
+		private static readonly Hashtable4 _versions = new Hashtable4();
+
+		private static readonly Db4objects.Db4o.Internal.Marshall.SlotFormat CurrentSlotFormat
+			 = new SlotFormatCurrent();
+
+		static SlotFormat()
+		{
+			new SlotFormat0();
+			new SlotFormat2();
+		}
+
+		protected SlotFormat()
+		{
+			_versions.Put(HandlerVersion(), this);
+		}
+
+		public static Db4objects.Db4o.Internal.Marshall.SlotFormat ForHandlerVersion(int 
+			handlerVersion)
+		{
+			if (handlerVersion == HandlerRegistry.HandlerVersion)
+			{
+				return CurrentSlotFormat;
+			}
+			if (handlerVersion < 0 || handlerVersion > CurrentSlotFormat.HandlerVersion())
+			{
+				throw new ArgumentException();
+			}
+			Db4objects.Db4o.Internal.Marshall.SlotFormat slotFormat = (Db4objects.Db4o.Internal.Marshall.SlotFormat
+				)_versions.Get(handlerVersion);
+			if (slotFormat != null)
+			{
+				return slotFormat;
+			}
+			return ForHandlerVersion(handlerVersion + 1);
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (!(obj is Db4objects.Db4o.Internal.Marshall.SlotFormat))
+			{
+				return false;
+			}
+			return HandlerVersion() == ((Db4objects.Db4o.Internal.Marshall.SlotFormat)obj).HandlerVersion
+				();
+		}
+
+		public override int GetHashCode()
+		{
+			return HandlerVersion();
+		}
+
+		protected abstract int HandlerVersion();
+
+		public abstract bool IsIndirectedWithinSlot(ITypeHandler4 handler);
+
+		public static Db4objects.Db4o.Internal.Marshall.SlotFormat Current()
+		{
+			return CurrentSlotFormat;
+		}
+
+		public virtual object DoWithSlotIndirection(IReadBuffer buffer, ITypeHandler4 typeHandler
+			, IClosure4 closure)
+		{
+			if (!IsIndirectedWithinSlot(typeHandler))
+			{
+				return closure.Run();
+			}
+			return DoWithSlotIndirection(buffer, closure);
+		}
+
+		public virtual object DoWithSlotIndirection(IReadBuffer buffer, IClosure4 closure
+			)
+		{
+			int payLoadOffset = buffer.ReadInt();
+			buffer.ReadInt();
+			// length, not used
+			int savedOffset = buffer.Offset();
+			object res = null;
+			if (payLoadOffset != 0)
+			{
+				buffer.Seek(payLoadOffset);
+				res = closure.Run();
+			}
+			buffer.Seek(savedOffset);
+			return res;
+		}
+
+		public virtual void WriteObjectClassID(ByteArrayBuffer buffer, int id)
+		{
+			buffer.WriteInt(-id);
+		}
+
+		public virtual void SkipMarshallerInfo(ByteArrayBuffer reader)
+		{
+			reader.IncrementOffset(1);
+		}
+
+		public virtual ObjectHeaderAttributes ReadHeaderAttributes(ByteArrayBuffer reader
+			)
+		{
+			return new ObjectHeaderAttributes(reader);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/SlotFormat0.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/SlotFormat0.cs
new file mode 100644
index 0000000..babbe54
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/SlotFormat0.cs
@@ -0,0 +1,37 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class SlotFormat0 : SlotFormat
+	{
+		protected override int HandlerVersion()
+		{
+			return 0;
+		}
+
+		public override bool IsIndirectedWithinSlot(ITypeHandler4 handler)
+		{
+			return false;
+		}
+
+		public override void WriteObjectClassID(ByteArrayBuffer buffer, int id)
+		{
+			buffer.WriteInt(id);
+		}
+
+		public override void SkipMarshallerInfo(ByteArrayBuffer reader)
+		{
+		}
+
+		public override ObjectHeaderAttributes ReadHeaderAttributes(ByteArrayBuffer reader
+			)
+		{
+			return null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/SlotFormat2.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/SlotFormat2.cs
new file mode 100644
index 0000000..231b9b1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/SlotFormat2.cs
@@ -0,0 +1,22 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class SlotFormat2 : SlotFormat
+	{
+		protected override int HandlerVersion()
+		{
+			return 2;
+		}
+
+		public override bool IsIndirectedWithinSlot(ITypeHandler4 handler)
+		{
+			return Handlers4.IsVariableLength(handler);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/SlotFormatCurrent.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/SlotFormatCurrent.cs
new file mode 100644
index 0000000..683888c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/SlotFormatCurrent.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <exclude></exclude>
+	public class SlotFormatCurrent : SlotFormat
+	{
+		protected override int HandlerVersion()
+		{
+			return HandlerRegistry.HandlerVersion;
+		}
+
+		public override bool IsIndirectedWithinSlot(ITypeHandler4 handler)
+		{
+			if (Handlers4.IsUntyped(handler))
+			{
+				return false;
+			}
+			return Handlers4.IsVariableLength(handler) && Handlers4.IsValueType(handler);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/UnknownTypeHandlerAspect.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/UnknownTypeHandlerAspect.cs
new file mode 100644
index 0000000..1b8f6bd
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/UnknownTypeHandlerAspect.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	public class UnknownTypeHandlerAspect : FieldMetadata
+	{
+		public UnknownTypeHandlerAspect(ClassMetadata containingClass, string name) : base
+			(containingClass, name)
+		{
+		}
+
+		public override void DefragAspect(IDefragmentContext context)
+		{
+			throw new InvalidOperationException("Type handler for '" + ContainingClass() + "' could not be found. Defragment cannot proceed. "
+				 + " Please ensure all required types are available and try again.");
+		}
+
+		public override bool Alive()
+		{
+			return false;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/UnmarshallingContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/UnmarshallingContext.cs
new file mode 100644
index 0000000..3f0801d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Marshall/UnmarshallingContext.cs
@@ -0,0 +1,201 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	/// <summary>Wraps the low-level details of reading a Buffer, which in turn is a glorified byte array.
+	/// 	</summary>
+	/// <remarks>Wraps the low-level details of reading a Buffer, which in turn is a glorified byte array.
+	/// 	</remarks>
+	/// <exclude></exclude>
+	public class UnmarshallingContext : ObjectReferenceContext, IHandlerVersionContext
+		, IReferenceActivationContext
+	{
+		private object _object;
+
+		private int _addToIDTree;
+
+		private bool _checkIDTree;
+
+		public UnmarshallingContext(Transaction transaction, ByteArrayBuffer buffer, ObjectReference
+			 @ref, int addToIDTree, bool checkIDTree) : base(transaction, buffer, null, @ref
+			)
+		{
+			_addToIDTree = addToIDTree;
+			_checkIDTree = checkIDTree;
+		}
+
+		public UnmarshallingContext(Transaction transaction, ObjectReference @ref, int addToIDTree
+			, bool checkIDTree) : this(transaction, null, @ref, addToIDTree, checkIDTree)
+		{
+		}
+
+		public virtual object Read()
+		{
+			if (!BeginProcessing())
+			{
+				return _object;
+			}
+			ReadBuffer(ObjectId());
+			if (Buffer() == null)
+			{
+				EndProcessing();
+				return _object;
+			}
+			ClassMetadata classMetadata = ReadObjectHeader();
+			if (classMetadata == null)
+			{
+				InvalidSlot();
+				EndProcessing();
+				return _object;
+			}
+			_reference.ClassMetadata(classMetadata);
+			AdjustActivationDepth();
+			if (_checkIDTree)
+			{
+				object objectInCacheFromClassCreation = Transaction().ObjectForIdFromCache(ObjectId
+					());
+				if (objectInCacheFromClassCreation != null)
+				{
+					_object = objectInCacheFromClassCreation;
+					EndProcessing();
+					return _object;
+				}
+			}
+			if (PeekPersisted())
+			{
+				_object = ClassMetadata().InstantiateTransient(this);
+			}
+			else
+			{
+				_object = ClassMetadata().Instantiate(this);
+			}
+			EndProcessing();
+			return _object;
+		}
+
+		private void InvalidSlot()
+		{
+			if (Container().Config().RecoveryMode())
+			{
+				return;
+			}
+			throw new InvalidSlotException("id: " + ObjectId());
+		}
+
+		private void AdjustActivationDepth()
+		{
+			if (UnknownActivationDepth.Instance == _activationDepth)
+			{
+				_activationDepth = Container().DefaultActivationDepth(ClassMetadata());
+			}
+		}
+
+		private IActivationDepthProvider ActivationDepthProvider()
+		{
+			return Container().ActivationDepthProvider();
+		}
+
+		public virtual object ReadFullyActivatedObjectForKeys(ITypeHandler4 handler)
+		{
+			object obj = ReadObject(handler);
+			if (obj == null)
+			{
+				return obj;
+			}
+			IActivationDepth activationDepth = ActivationDepthProvider().ActivationDepth(int.MaxValue
+				, ActivationMode.Activate);
+			Container().Activate(Transaction(), obj, activationDepth);
+			return obj;
+		}
+
+		public virtual object ReadFieldValue(FieldMetadata field)
+		{
+			ReadBuffer(ObjectId());
+			if (Buffer() == null)
+			{
+				return null;
+			}
+			ClassMetadata classMetadata = ReadObjectHeader();
+			if (classMetadata == null)
+			{
+				return null;
+			}
+			return ReadFieldValue(classMetadata, field);
+		}
+
+		private object ReadFieldValue(ClassMetadata classMetadata, FieldMetadata field)
+		{
+			if (!classMetadata.SeekToField(this, field))
+			{
+				return null;
+			}
+			return field.Read(this);
+		}
+
+		private ClassMetadata ReadObjectHeader()
+		{
+			_objectHeader = new ObjectHeader(Container(), ByteArrayBuffer());
+			ClassMetadata classMetadata = _objectHeader.ClassMetadata();
+			if (classMetadata == null)
+			{
+				return null;
+			}
+			return classMetadata;
+		}
+
+		private void ReadBuffer(int id)
+		{
+			if (Buffer() == null && id > 0)
+			{
+				Buffer(Container().ReadBufferById(Transaction(), id));
+			}
+		}
+
+		private bool BeginProcessing()
+		{
+			return _reference.BeginProcessing();
+		}
+
+		private void EndProcessing()
+		{
+			_reference.EndProcessing();
+		}
+
+		public virtual void SetStateClean()
+		{
+			_reference.SetStateClean();
+		}
+
+		public virtual object PersistentObject()
+		{
+			return _object;
+		}
+
+		public virtual void SetObjectWeak(object obj)
+		{
+			_reference.SetObjectWeak(Container(), obj);
+		}
+
+		protected override bool PeekPersisted()
+		{
+			return _addToIDTree == Const4.Transient;
+		}
+
+		public virtual Config4Class ClassConfig()
+		{
+			return ClassMetadata().Config();
+		}
+
+		public virtual void PersistentObject(object obj)
+		{
+			_object = obj;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/MarshallingBuffer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/MarshallingBuffer.cs
new file mode 100644
index 0000000..fd574ca
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/MarshallingBuffer.cs
@@ -0,0 +1,380 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Sharpen;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class MarshallingBuffer : IWriteBuffer
+	{
+		private const int SizeNeeded = Const4.LongLength;
+
+		private const int NoParent = -int.MaxValue;
+
+		private ByteArrayBuffer _delegate;
+
+		private int _lastOffSet;
+
+		private int _addressInParent = NoParent;
+
+		private List4 _children;
+
+		private FieldMetadata _indexedField;
+
+		public virtual int Length()
+		{
+			return Offset();
+		}
+
+		public virtual int Offset()
+		{
+			if (_delegate == null)
+			{
+				return 0;
+			}
+			return _delegate.Offset();
+		}
+
+		public virtual void WriteByte(byte b)
+		{
+			PrepareWrite();
+			_delegate.WriteByte(b);
+		}
+
+		public virtual void WriteBytes(byte[] bytes)
+		{
+			PrepareWrite(bytes.Length);
+			_delegate.WriteBytes(bytes);
+		}
+
+		public virtual void WriteInt(int i)
+		{
+			PrepareWrite();
+			_delegate.WriteInt(i);
+		}
+
+		public virtual void WriteLong(long l)
+		{
+			PrepareWrite();
+			_delegate.WriteLong(l);
+		}
+
+		private void PrepareWrite()
+		{
+			PrepareWrite(SizeNeeded);
+		}
+
+		public virtual void PrepareWrite(int sizeNeeded)
+		{
+			if (_delegate == null)
+			{
+				_delegate = new ByteArrayBuffer(sizeNeeded);
+			}
+			_lastOffSet = _delegate.Offset();
+			if (RemainingSize() < sizeNeeded)
+			{
+				Resize(sizeNeeded);
+			}
+		}
+
+		private int RemainingSize()
+		{
+			return _delegate.Length() - _delegate.Offset();
+		}
+
+		private void Resize(int sizeNeeded)
+		{
+			int newSize = _delegate.Length() * 2;
+			if (newSize - _lastOffSet < sizeNeeded)
+			{
+				newSize += sizeNeeded;
+			}
+			ByteArrayBuffer temp = new ByteArrayBuffer(newSize);
+			temp.Seek(_lastOffSet);
+			_delegate.CopyTo(temp, 0, 0, _delegate.Length());
+			_delegate = temp;
+		}
+
+		public virtual void TransferLastWriteTo(MarshallingBuffer other, bool storeLengthInLink
+			)
+		{
+			other.AddressInParent(_lastOffSet, storeLengthInLink);
+			int length = _delegate.Offset() - _lastOffSet;
+			other.PrepareWrite(length);
+			int otherOffset = other._delegate.Offset();
+			System.Array.Copy(_delegate._buffer, _lastOffSet, other._delegate._buffer, otherOffset
+				, length);
+			_delegate.Seek(_lastOffSet);
+			other._delegate.Seek(otherOffset + length);
+			other._lastOffSet = otherOffset;
+		}
+
+		private void AddressInParent(int offset, bool storeLengthInLink)
+		{
+			_addressInParent = storeLengthInLink ? offset : -offset;
+		}
+
+		public virtual void TransferContentTo(ByteArrayBuffer buffer)
+		{
+			TransferContentTo(buffer, Length());
+		}
+
+		public virtual void TransferContentTo(ByteArrayBuffer buffer, int length)
+		{
+			if (_delegate == null)
+			{
+				return;
+			}
+			System.Array.Copy(_delegate._buffer, 0, buffer._buffer, buffer._offset, length);
+			buffer._offset += length;
+		}
+
+		public virtual ByteArrayBuffer TestDelegate()
+		{
+			return _delegate;
+		}
+
+		public virtual MarshallingBuffer AddChild()
+		{
+			return AddChild(true, false);
+		}
+
+		public virtual MarshallingBuffer AddChild(bool reserveLinkSpace, bool storeLengthInLink
+			)
+		{
+			MarshallingBuffer child = new MarshallingBuffer();
+			child.AddressInParent(Offset(), storeLengthInLink);
+			_children = new List4(_children, child);
+			if (reserveLinkSpace)
+			{
+				ReserveChildLinkSpace(storeLengthInLink);
+			}
+			return child;
+		}
+
+		public virtual void ReserveChildLinkSpace(bool storeLengthInLink)
+		{
+			int length = storeLengthInLink ? Const4.IntLength * 2 : Const4.IntLength;
+			PrepareWrite(length);
+			_delegate.IncrementOffset(length);
+		}
+
+		public virtual void MergeChildren(MarshallingContext context, int masterAddress, 
+			int linkOffset)
+		{
+			MergeChildren(context, masterAddress, this, this, linkOffset);
+		}
+
+		private static void MergeChildren(MarshallingContext context, int masterAddress, 
+			MarshallingBuffer writeBuffer, MarshallingBuffer parentBuffer, int linkOffset)
+		{
+			if (parentBuffer._children == null)
+			{
+				return;
+			}
+			IEnumerator i = new Iterator4Impl(parentBuffer._children);
+			while (i.MoveNext())
+			{
+				Merge(context, masterAddress, writeBuffer, parentBuffer, (MarshallingBuffer)i.Current
+					, linkOffset);
+			}
+		}
+
+		private static void Merge(MarshallingContext context, int masterAddress, MarshallingBuffer
+			 writeBuffer, MarshallingBuffer parentBuffer, MarshallingBuffer childBuffer, int
+			 linkOffset)
+		{
+			int childPosition = writeBuffer.Offset();
+			writeBuffer.Reserve(childBuffer.BlockedLength());
+			MergeChildren(context, masterAddress, writeBuffer, childBuffer, linkOffset);
+			int savedWriteBufferOffset = writeBuffer.Offset();
+			writeBuffer.Seek(childPosition);
+			childBuffer.TransferContentTo(writeBuffer._delegate);
+			writeBuffer.Seek(savedWriteBufferOffset);
+			parentBuffer.WriteLink(childBuffer, childPosition + linkOffset, childBuffer.UnblockedLength
+				());
+			childBuffer.WriteIndex(context, masterAddress, childPosition + linkOffset);
+		}
+
+		public virtual void Seek(int offset)
+		{
+			_delegate.Seek(offset);
+		}
+
+		public virtual IReservedBuffer Reserve(int length)
+		{
+			PrepareWrite(length);
+			IReservedBuffer reservedBuffer = new _IReservedBuffer_178(this);
+			_delegate.Seek(_delegate.Offset() + length);
+			return reservedBuffer;
+		}
+
+		private sealed class _IReservedBuffer_178 : IReservedBuffer
+		{
+			public _IReservedBuffer_178(MarshallingBuffer _enclosing)
+			{
+				this._enclosing = _enclosing;
+				this.reservedOffset = this._enclosing._delegate.Offset();
+			}
+
+			private readonly int reservedOffset;
+
+			public void WriteBytes(byte[] bytes)
+			{
+				int currentOffset = this._enclosing._delegate.Offset();
+				this._enclosing._delegate.Seek(this.reservedOffset);
+				this._enclosing._delegate.WriteBytes(bytes);
+				this._enclosing._delegate.Seek(currentOffset);
+			}
+
+			private readonly MarshallingBuffer _enclosing;
+		}
+
+		private void WriteLink(MarshallingBuffer child, int position, int length)
+		{
+			int offset = Offset();
+			_delegate.Seek(child.AddressInParent());
+			_delegate.WriteInt(position);
+			if (child.StoreLengthInLink())
+			{
+				_delegate.WriteInt(length);
+			}
+			_delegate.Seek(offset);
+		}
+
+		private void WriteIndex(MarshallingContext context, int masterAddress, int position
+			)
+		{
+			if (_indexedField != null)
+			{
+				// for now this is a String index only, it takes the entire slot.
+				StatefulBuffer buffer = new StatefulBuffer(context.Transaction(), UnblockedLength
+					());
+				int blockedPosition = context.Container().BlockConverter().BytesToBlocks(position
+					);
+				int indexID = masterAddress + blockedPosition;
+				buffer.SetID(indexID);
+				buffer.Address(indexID);
+				TransferContentTo(buffer, UnblockedLength());
+				_indexedField.AddIndexEntry(context.Transaction(), context.ObjectID(), buffer);
+			}
+		}
+
+		private int AddressInParent()
+		{
+			if (!HasParent())
+			{
+				throw new InvalidOperationException();
+			}
+			if (_addressInParent < 0)
+			{
+				return -_addressInParent;
+			}
+			return _addressInParent;
+		}
+
+		public virtual void DebugDecrementLastOffset(int count)
+		{
+			_lastOffSet -= count;
+		}
+
+		public virtual bool HasParent()
+		{
+			return _addressInParent != NoParent;
+		}
+
+		private bool StoreLengthInLink()
+		{
+			return _addressInParent > 0;
+		}
+
+		public virtual void RequestIndexEntry(FieldMetadata fieldMetadata)
+		{
+			_indexedField = fieldMetadata;
+		}
+
+		public virtual MarshallingBuffer CheckBlockAlignment(MarshallingContext context, 
+			MarshallingBuffer precedingBuffer, IntByRef precedingLength)
+		{
+			_lastOffSet = Offset();
+			if (DoBlockAlign())
+			{
+				precedingBuffer.BlockAlign(context, precedingLength.value);
+			}
+			if (precedingBuffer != null)
+			{
+				precedingLength.value += precedingBuffer.Length();
+			}
+			precedingBuffer = this;
+			if (_children != null)
+			{
+				IEnumerator i = new Iterator4Impl(_children);
+				while (i.MoveNext())
+				{
+					precedingBuffer = ((MarshallingBuffer)i.Current).CheckBlockAlignment(context, precedingBuffer
+						, precedingLength);
+				}
+			}
+			return precedingBuffer;
+		}
+
+		private void BlockAlign(MarshallingContext context, int precedingLength)
+		{
+			int totalLength = context.Container().BlockConverter().BlockAlignedBytes(precedingLength
+				 + Length());
+			int newLength = totalLength - precedingLength;
+			BlockAlign(newLength);
+		}
+
+		public virtual int MarshalledLength()
+		{
+			int length = Length();
+			if (_children != null)
+			{
+				IEnumerator i = new Iterator4Impl(_children);
+				while (i.MoveNext())
+				{
+					length += ((MarshallingBuffer)i.Current).MarshalledLength();
+				}
+			}
+			return length;
+		}
+
+		private void BlockAlign(int length)
+		{
+			if (_delegate == null)
+			{
+				return;
+			}
+			if (length > _delegate.Length())
+			{
+				int sizeNeeded = length - _delegate.Offset();
+				PrepareWrite(sizeNeeded);
+			}
+			_delegate.Seek(length);
+		}
+
+		private bool DoBlockAlign()
+		{
+			return HasParent();
+		}
+
+		// For now we block align every linked entry. Indexes could be created late.
+		private int BlockedLength()
+		{
+			return Length();
+		}
+
+		private int UnblockedLength()
+		{
+			// This is only valid after checkBlockAlignMent has been called. 
+			return _lastOffSet;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/MessageOutput.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/MessageOutput.cs
new file mode 100644
index 0000000..f3e708f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/MessageOutput.cs
@@ -0,0 +1,45 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.IO;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	internal sealed class MessageOutput
+	{
+		internal readonly TextWriter stream;
+
+		internal MessageOutput(ObjectContainerBase a_stream, string msg)
+		{
+			stream = a_stream.ConfigImpl.OutStream();
+			Print(msg, true);
+		}
+
+		internal MessageOutput(string a_StringParam, int a_intParam, TextWriter a_stream, 
+			bool header)
+		{
+			stream = a_stream;
+			Print(Db4objects.Db4o.Internal.Messages.Get(a_intParam, a_StringParam), header);
+		}
+
+		internal MessageOutput(string a_StringParam, int a_intParam, TextWriter a_stream)
+			 : this(a_StringParam, a_intParam, a_stream, true)
+		{
+		}
+
+		private void Print(string msg, bool header)
+		{
+			if (stream != null)
+			{
+				if (header)
+				{
+					stream.WriteLine("[" + Db4oFactory.Version() + "   " + DateHandlerBase.Now() + "] "
+						);
+				}
+				stream.WriteLine(" " + msg);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Messages.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Messages.cs
new file mode 100644
index 0000000..00fcbe2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Messages.cs
@@ -0,0 +1,152 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.IO;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public sealed class Messages
+	{
+		public const int IncompatibleFormat = 17;
+
+		public const int ClosedOrOpenFailed = 20;
+
+		public const int FailedToShutdown = 28;
+
+		public const int FatalMsgId = 44;
+
+		public const int NotImplemented = 49;
+
+		public const int OldDatabaseFormat = 65;
+
+		public const int OnlyForIndexedFields = 66;
+
+		public const int ClientServerUnsupported = 67;
+
+		public const int CouldNotOpenPort = 30;
+
+		public const int ServerListeningOnPort = 31;
+
+		private static string[] i_messages;
+
+		public static string Get(int a_code)
+		{
+			return Get(a_code, null);
+		}
+
+		public static string Get(int a_code, string param)
+		{
+			if (a_code < 0)
+			{
+				return param;
+			}
+			Load();
+			if (i_messages == null || a_code > i_messages.Length - 1)
+			{
+				return "msg[" + a_code + "]";
+			}
+			string msg = i_messages[a_code];
+			if (param != null)
+			{
+				int pos = msg.IndexOf("%", 0);
+				if (pos > -1)
+				{
+					msg = Sharpen.Runtime.Substring(msg, 0, pos) + "'" + param + "'" + Sharpen.Runtime.Substring
+						(msg, pos + 1);
+				}
+			}
+			return msg;
+		}
+
+		private static void Load()
+		{
+			if (i_messages == null)
+			{
+				i_messages = new string[] { string.Empty, "blocksize should be between 1 and 127"
+					, "% close request", "% closed", "Exception opening %", "% opened O.K.", "Class %: Instantiation failed. \n Check custom ObjectConstructor code."
+					, "Class %: Instantiation failed.\n Add a constructor for use with db4o, ideally with zero arguments."
+					, "renaming %", "rename not possible. % already exists", "rename failed", "File close failed."
+					, "File % not available for readwrite access.", "File read access failed.", "File not found: % Creating new file"
+					, "Creation of file failed: %", "File write failed.", "File format incompatible: %"
+					, "Uncaught Exception. Engine closed.", "writing log for %", "% is closed. close() was called or open() failed."
+					, "Filename not specified.", "The database file is locked by another process.", 
+					"Class not available: %. Check CLASSPATH settings.", "finalized while performing a task.\n DO NOT USE CTRL + C OR System.exit() TO STOP THE ENGINE."
+					, "Please mail the following to exception at db4o.com:\n <db4o " + Db4oVersion.Name
+					 + " stacktrace>", "</db4o " + Db4oVersion.Name + " stacktrace>", "Creation of lock file failed: %"
+					, "Previous session was not shut down correctly", "This method call is only possible on stored objects"
+					, "Could not open port: %", "Server listening on port: %", "Client % connected."
+					, "Client % timed out and closed.", "Connection closed by client %.", "Connection closed by server. %."
+					, "% connected to server.", "The directory % can neither be found nor created.", 
+					"This blob was never stored.", "Blob file % not available.", "Failure finding blob filename."
+					, "File does not exist %.", "Failed to connect to server.", "No blob data stored."
+					, "Uncaught Exception. db4o engine closed.", "Add constructor that won't throw exceptions, configure constructor calls, configure exceptionsOnNotStorable(false) or provide a translator to class % and make sure the class is deployed to the server with the same package/namespace + assembly name."
+					, "This method can only be called before opening the database file.", "AccessibleObject#setAccessible() is not available. Private fields can not be stored."
+					, "ObjectTranslator could not be installed: %.", "Not implemented", "% closed by ShutdownHook."
+					, string.Empty, "Add at least one ObjectContainer to the Cluster", "Unsupported Operation"
+					, "Database password does not match user-provided password.", "Thread interrupted."
+					, "Password can not be null.", "Classes does not match.", "rename() needs to be executed on the server."
+					, "Primitive types like % can not be stored directly. Store and retrieve them in wrapper objects."
+					, "Backups can not be run from clients and memory files.", "Backup in progress."
+					, "Only use persisted first class objects as keys for IdentityHashMap.", "This functionality is only available from version 5.0 onwards."
+					, "By convention a Predicate needs the following method: public boolean match(ExtentClass extent){}"
+					, "Old database file format detected. To allow automatic updates call Db4o.configure().allowVersionUpdates(true)."
+					, "This functionality is only available for indexed fields.", "This functionality is not supported for db4o clients in Client/Server mode."
+					, "Invalid address: %", "Maximum file size reached" };
+			}
+		}
+
+		// unused
+		// 5
+		// 10
+		// 15
+		// 20
+		// 25
+		// 30
+		// 35
+		// 40
+		// 45
+		// 50
+		// removed, can be reused
+		// 55
+		// 60
+		// 65
+		// 66
+		// 67
+		// 69
+		public static void LogErr(IConfiguration config, int code, string msg, Exception 
+			t)
+		{
+			TextWriter ps = ((Config4Impl)SafeConfig(config)).ErrStream();
+			new MessageOutput(msg, code, ps);
+			if (t != null)
+			{
+				new MessageOutput(null, 25, ps);
+				Sharpen.Runtime.PrintStackTrace(t, ps);
+				new MessageOutput(null, 26, ps, false);
+			}
+		}
+
+		[System.ObsoleteAttribute(@"uses deprecated api")]
+		private static IConfiguration SafeConfig(IConfiguration config)
+		{
+			if (config != null)
+			{
+				return config;
+			}
+			return Db4oFactory.Configure();
+		}
+
+		public static void LogMsg(IConfiguration config, int code, string msg)
+		{
+			Config4Impl c4i = (Config4Impl)config;
+			if (c4i.MessageLevel() > Const4.None)
+			{
+				new MessageOutput(msg, code, c4i.OutStream());
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/HierarchyAnalyzer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/HierarchyAnalyzer.cs
new file mode 100644
index 0000000..d772f74
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/HierarchyAnalyzer.cs
@@ -0,0 +1,144 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Metadata;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Metadata
+{
+	/// <exclude></exclude>
+	public class HierarchyAnalyzer
+	{
+		public class Diff
+		{
+			private readonly Db4objects.Db4o.Internal.ClassMetadata _classMetadata;
+
+			public Diff(Db4objects.Db4o.Internal.ClassMetadata classMetadata)
+			{
+				if (classMetadata == null)
+				{
+					throw new ArgumentNullException();
+				}
+				_classMetadata = classMetadata;
+			}
+
+			public override bool Equals(object obj)
+			{
+				if (GetType() != obj.GetType())
+				{
+					return false;
+				}
+				HierarchyAnalyzer.Diff other = (HierarchyAnalyzer.Diff)obj;
+				return _classMetadata == other._classMetadata;
+			}
+
+			public override string ToString()
+			{
+				return ReflectPlatform.SimpleName(GetType()) + "(" + _classMetadata.GetName() + ")";
+			}
+
+			public virtual Db4objects.Db4o.Internal.ClassMetadata ClassMetadata()
+			{
+				return _classMetadata;
+			}
+
+			public virtual bool IsRemoved()
+			{
+				return false;
+			}
+		}
+
+		public class Same : HierarchyAnalyzer.Diff
+		{
+			public Same(ClassMetadata classMetadata) : base(classMetadata)
+			{
+			}
+		}
+
+		public class Removed : HierarchyAnalyzer.Diff
+		{
+			public Removed(ClassMetadata classMetadata) : base(classMetadata)
+			{
+			}
+
+			public override bool IsRemoved()
+			{
+				return true;
+			}
+		}
+
+		private ClassMetadata _storedClass;
+
+		private IReflectClass _runtimeClass;
+
+		private readonly IReflectClass _objectClass;
+
+		public HierarchyAnalyzer(ClassMetadata storedClass, IReflectClass runtimeClass)
+		{
+			if (storedClass == null || runtimeClass == null)
+			{
+				throw new ArgumentNullException();
+			}
+			_storedClass = storedClass;
+			_runtimeClass = runtimeClass;
+			_objectClass = runtimeClass.Reflector().ForClass(typeof(object));
+		}
+
+		public virtual IList Analyze()
+		{
+			IList ancestors = new ArrayList();
+			ClassMetadata storedAncestor = _storedClass.GetAncestor();
+			IReflectClass runtimeAncestor = _runtimeClass.GetSuperclass();
+			while (storedAncestor != null)
+			{
+				if (runtimeAncestor == storedAncestor.ClassReflector())
+				{
+					ancestors.Add(new HierarchyAnalyzer.Same(storedAncestor));
+				}
+				else
+				{
+					do
+					{
+						ancestors.Add(new HierarchyAnalyzer.Removed(storedAncestor));
+						storedAncestor = storedAncestor.GetAncestor();
+						if (null == storedAncestor)
+						{
+							if (IsObject(runtimeAncestor))
+							{
+								return ancestors;
+							}
+							ThrowUnsupportedAdd(runtimeAncestor);
+						}
+						if (runtimeAncestor == storedAncestor.ClassReflector())
+						{
+							ancestors.Add(new HierarchyAnalyzer.Same(storedAncestor));
+							break;
+						}
+					}
+					while (storedAncestor != null);
+				}
+				storedAncestor = storedAncestor.GetAncestor();
+				runtimeAncestor = runtimeAncestor.GetSuperclass();
+			}
+			if (runtimeAncestor != null && (!IsObject(runtimeAncestor)))
+			{
+				ThrowUnsupportedAdd(runtimeAncestor);
+			}
+			return ancestors;
+		}
+
+		private void ThrowUnsupportedAdd(IReflectClass runtimeAncestor)
+		{
+			throw new InvalidOperationException("Unsupported class hierarchy change. Class " 
+				+ runtimeAncestor.GetName() + " was added to hierarchy of " + _runtimeClass.GetName
+				());
+		}
+
+		private bool IsObject(IReflectClass clazz)
+		{
+			return _objectClass == clazz;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/IAspectTraversalStrategy.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/IAspectTraversalStrategy.cs
new file mode 100644
index 0000000..241ff8a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/IAspectTraversalStrategy.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Metadata;
+
+namespace Db4objects.Db4o.Internal.Metadata
+{
+	/// <exclude></exclude>
+	public interface IAspectTraversalStrategy
+	{
+		void TraverseAllAspects(ITraverseAspectCommand command);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/ITraverseAspectCommand.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/ITraverseAspectCommand.cs
new file mode 100644
index 0000000..29eb7b6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/ITraverseAspectCommand.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Metadata
+{
+	/// <exclude></exclude>
+	public interface ITraverseAspectCommand
+	{
+		int DeclaredAspectCount(ClassMetadata classMetadata);
+
+		bool Cancelled();
+
+		void ProcessAspectOnMissingClass(ClassAspect aspect, int currentSlot);
+
+		void ProcessAspect(ClassAspect aspect, int currentSlot);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/MarshallingInfoTraverseAspectCommand.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/MarshallingInfoTraverseAspectCommand.cs
new file mode 100644
index 0000000..eb544f0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/MarshallingInfoTraverseAspectCommand.cs
@@ -0,0 +1,70 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Metadata;
+
+namespace Db4objects.Db4o.Internal.Metadata
+{
+	/// <exclude></exclude>
+	public abstract class MarshallingInfoTraverseAspectCommand : ITraverseAspectCommand
+	{
+		private bool _cancelled = false;
+
+		protected readonly IMarshallingInfo _marshallingInfo;
+
+		public MarshallingInfoTraverseAspectCommand(IMarshallingInfo marshallingInfo)
+		{
+			_marshallingInfo = marshallingInfo;
+		}
+
+		public int DeclaredAspectCount(ClassMetadata classMetadata)
+		{
+			int aspectCount = InternalDeclaredAspectCount(classMetadata);
+			_marshallingInfo.DeclaredAspectCount(aspectCount);
+			return aspectCount;
+		}
+
+		protected virtual int InternalDeclaredAspectCount(ClassMetadata classMetadata)
+		{
+			return classMetadata.ReadAspectCount(_marshallingInfo.Buffer());
+		}
+
+		public virtual bool Cancelled()
+		{
+			return _cancelled;
+		}
+
+		protected virtual void Cancel()
+		{
+			_cancelled = true;
+		}
+
+		public virtual bool Accept(ClassAspect aspect)
+		{
+			return true;
+		}
+
+		public virtual void ProcessAspectOnMissingClass(ClassAspect aspect, int currentSlot
+			)
+		{
+			if (_marshallingInfo.IsNull(currentSlot))
+			{
+				return;
+			}
+			aspect.IncrementOffset(_marshallingInfo.Buffer());
+		}
+
+		public virtual void ProcessAspect(ClassAspect aspect, int currentSlot)
+		{
+			if (Accept(aspect))
+			{
+				ProcessAspect(aspect, currentSlot, _marshallingInfo.IsNull(currentSlot));
+			}
+			_marshallingInfo.BeginSlot();
+		}
+
+		protected abstract void ProcessAspect(ClassAspect aspect, int currentSlot, bool isNull
+			);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/ModifiedAspectTraversalStrategy.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/ModifiedAspectTraversalStrategy.cs
new file mode 100644
index 0000000..f6767e0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/ModifiedAspectTraversalStrategy.cs
@@ -0,0 +1,101 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Metadata;
+
+namespace Db4objects.Db4o.Internal.Metadata
+{
+	/// <exclude></exclude>
+	public class ModifiedAspectTraversalStrategy : IAspectTraversalStrategy
+	{
+		private readonly IList _classDiffs;
+
+		public ModifiedAspectTraversalStrategy(ClassMetadata classMetadata, IList ancestors
+			)
+		{
+			_classDiffs = new ArrayList();
+			_classDiffs.Add(new HierarchyAnalyzer.Same(classMetadata));
+			Sharpen.Collections.AddAll(_classDiffs, ancestors);
+		}
+
+		public virtual void TraverseAllAspects(ITraverseAspectCommand command)
+		{
+			int currentSlot = 0;
+			for (IEnumerator diffIter = _classDiffs.GetEnumerator(); diffIter.MoveNext(); )
+			{
+				HierarchyAnalyzer.Diff diff = ((HierarchyAnalyzer.Diff)diffIter.Current);
+				ClassMetadata classMetadata = diff.ClassMetadata();
+				if (diff.IsRemoved())
+				{
+					currentSlot = SkipAspectsOf(classMetadata, command, currentSlot);
+					continue;
+				}
+				currentSlot = TraverseAspectsOf(classMetadata, command, currentSlot);
+				if (command.Cancelled())
+				{
+					return;
+				}
+			}
+		}
+
+		internal interface ITraverseAspectCommandProcessor
+		{
+			void Process(ITraverseAspectCommand command, ClassAspect currentAspect, int currentSlot
+				);
+		}
+
+		private int TraverseAspectsOf(ClassMetadata classMetadata, ITraverseAspectCommand
+			 command, int currentSlot)
+		{
+			return ProcessAspectsOf(classMetadata, command, currentSlot, new _ITraverseAspectCommandProcessor_49
+				());
+		}
+
+		private sealed class _ITraverseAspectCommandProcessor_49 : ModifiedAspectTraversalStrategy.ITraverseAspectCommandProcessor
+		{
+			public _ITraverseAspectCommandProcessor_49()
+			{
+			}
+
+			public void Process(ITraverseAspectCommand command, ClassAspect currentAspect, int
+				 currentSlot)
+			{
+				command.ProcessAspect(currentAspect, currentSlot);
+			}
+		}
+
+		private int ProcessAspectsOf(ClassMetadata classMetadata, ITraverseAspectCommand 
+			command, int currentSlot, ModifiedAspectTraversalStrategy.ITraverseAspectCommandProcessor
+			 processor)
+		{
+			int aspectCount = command.DeclaredAspectCount(classMetadata);
+			for (int i = 0; i < aspectCount && !command.Cancelled(); i++)
+			{
+				processor.Process(command, classMetadata._aspects[i], currentSlot);
+				currentSlot++;
+			}
+			return currentSlot;
+		}
+
+		private int SkipAspectsOf(ClassMetadata classMetadata, ITraverseAspectCommand command
+			, int currentSlot)
+		{
+			return ProcessAspectsOf(classMetadata, command, currentSlot, new _ITraverseAspectCommandProcessor_70
+				());
+		}
+
+		private sealed class _ITraverseAspectCommandProcessor_70 : ModifiedAspectTraversalStrategy.ITraverseAspectCommandProcessor
+		{
+			public _ITraverseAspectCommandProcessor_70()
+			{
+			}
+
+			public void Process(ITraverseAspectCommand command, ClassAspect currentAspect, int
+				 currentSlot)
+			{
+				command.ProcessAspectOnMissingClass(currentAspect, currentSlot);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/StandardAspectTraversalStrategy.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/StandardAspectTraversalStrategy.cs
new file mode 100644
index 0000000..e42b1c6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/StandardAspectTraversalStrategy.cs
@@ -0,0 +1,38 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Metadata;
+
+namespace Db4objects.Db4o.Internal.Metadata
+{
+	/// <exclude></exclude>
+	public class StandardAspectTraversalStrategy : IAspectTraversalStrategy
+	{
+		private readonly ClassMetadata _classMetadata;
+
+		public StandardAspectTraversalStrategy(ClassMetadata classMetadata)
+		{
+			_classMetadata = classMetadata;
+		}
+
+		public virtual void TraverseAllAspects(ITraverseAspectCommand command)
+		{
+			ClassMetadata classMetadata = _classMetadata;
+			int currentSlot = 0;
+			while (classMetadata != null)
+			{
+				int aspectCount = command.DeclaredAspectCount(classMetadata);
+				for (int i = 0; i < aspectCount && !command.Cancelled(); i++)
+				{
+					command.ProcessAspect(classMetadata._aspects[i], currentSlot);
+					currentSlot++;
+				}
+				if (command.Cancelled())
+				{
+					return;
+				}
+				classMetadata = classMetadata._ancestor;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/TraverseFieldCommand.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/TraverseFieldCommand.cs
new file mode 100644
index 0000000..8435f9a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Metadata/TraverseFieldCommand.cs
@@ -0,0 +1,37 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Metadata;
+
+namespace Db4objects.Db4o.Internal.Metadata
+{
+	/// <exclude></exclude>
+	public abstract class TraverseFieldCommand : ITraverseAspectCommand
+	{
+		public virtual bool Cancelled()
+		{
+			return false;
+		}
+
+		public virtual int DeclaredAspectCount(ClassMetadata classMetadata)
+		{
+			return classMetadata.DeclaredAspectCount();
+		}
+
+		public virtual void ProcessAspect(ClassAspect aspect, int currentSlot)
+		{
+			if (aspect is FieldMetadata)
+			{
+				Process((FieldMetadata)aspect);
+			}
+		}
+
+		public virtual void ProcessAspectOnMissingClass(ClassAspect aspect, int currentSlot
+			)
+		{
+		}
+
+		// do nothing
+		protected abstract void Process(FieldMetadata field);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Null.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Null.cs
new file mode 100644
index 0000000..09994e1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Null.cs
@@ -0,0 +1,75 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class Null : IIndexable4, IPreparedComparison
+	{
+		public static readonly Db4objects.Db4o.Internal.Null Instance = new Db4objects.Db4o.Internal.Null
+			();
+
+		private Null()
+		{
+		}
+
+		public virtual int CompareTo(object a_obj)
+		{
+			if (a_obj == null)
+			{
+				return 0;
+			}
+			return -1;
+		}
+
+		public virtual int LinkLength()
+		{
+			return 0;
+		}
+
+		public virtual object ReadIndexEntry(IContext context, ByteArrayBuffer a_reader)
+		{
+			return null;
+		}
+
+		public virtual void WriteIndexEntry(IContext context, ByteArrayBuffer a_writer, object
+			 a_object)
+		{
+		}
+
+		// do nothing
+		public virtual void DefragIndexEntry(DefragmentContextImpl context)
+		{
+		}
+
+		// do nothing
+		public virtual IPreparedComparison PrepareComparison(IContext context, object obj_
+			)
+		{
+			return new _IPreparedComparison_43();
+		}
+
+		private sealed class _IPreparedComparison_43 : IPreparedComparison
+		{
+			public _IPreparedComparison_43()
+			{
+			}
+
+			public int CompareTo(object obj)
+			{
+				if (obj == null)
+				{
+					return 0;
+				}
+				if (obj is Db4objects.Db4o.Internal.Null)
+				{
+					return 0;
+				}
+				return -1;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/NullFieldMetadata.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/NullFieldMetadata.cs
new file mode 100644
index 0000000..b6f2a28
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/NullFieldMetadata.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class NullFieldMetadata : FieldMetadata
+	{
+		public NullFieldMetadata() : base(null)
+		{
+		}
+
+		/// <param name="obj"></param>
+		public virtual IPreparedComparison PrepareComparison(object obj)
+		{
+			return Null.Instance;
+		}
+
+		public sealed override object Read(IObjectIdContext context)
+		{
+			return null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/NullTransactionListener.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/NullTransactionListener.cs
new file mode 100644
index 0000000..7e3ce87
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/NullTransactionListener.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.Internal
+{
+	public class NullTransactionListener : ITransactionListener
+	{
+		public static readonly ITransactionListener Instance = new Db4objects.Db4o.Internal.NullTransactionListener
+			();
+
+		private NullTransactionListener()
+		{
+		}
+
+		public virtual void PostRollback()
+		{
+		}
+
+		public virtual void PreCommit()
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectAnalyzer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectAnalyzer.cs
new file mode 100644
index 0000000..a630b73
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectAnalyzer.cs
@@ -0,0 +1,102 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	internal class ObjectAnalyzer
+	{
+		private readonly ObjectContainerBase _container;
+
+		private readonly object _obj;
+
+		private Db4objects.Db4o.Internal.ClassMetadata _classMetadata;
+
+		private Db4objects.Db4o.Internal.ObjectReference _ref;
+
+		private bool _notStorable;
+
+		internal ObjectAnalyzer(ObjectContainerBase container, object obj)
+		{
+			_container = container;
+			_obj = obj;
+		}
+
+		internal virtual void Analyze(Transaction trans)
+		{
+			_ref = trans.ReferenceForObject(_obj);
+			if (_ref != null)
+			{
+				_classMetadata = _ref.ClassMetadata();
+				return;
+			}
+			IReflectClass claxx = _container.Reflector().ForObject(_obj);
+			if (claxx == null)
+			{
+				NotStorable(_obj, claxx);
+				return;
+			}
+			if (!DetectClassMetadata(trans, claxx))
+			{
+				return;
+			}
+			if (IsValueType(_classMetadata))
+			{
+				NotStorable(_obj, _classMetadata.ClassReflector());
+			}
+		}
+
+		private bool DetectClassMetadata(Transaction trans, IReflectClass claxx)
+		{
+			_classMetadata = _container.GetActiveClassMetadata(claxx);
+			if (_classMetadata != null)
+			{
+				if (!_classMetadata.IsStorable())
+				{
+					NotStorable(_obj, claxx);
+					return false;
+				}
+				return true;
+			}
+			_classMetadata = _container.ProduceClassMetadata(claxx);
+			if (_classMetadata == null || !_classMetadata.IsStorable())
+			{
+				NotStorable(_obj, claxx);
+				return false;
+			}
+			// The following may return a reference if the object is held
+			// in a static variable somewhere ( often: Enums) that gets
+			// stored or associated on initialization of the ClassMetadata.
+			_ref = trans.ReferenceForObject(_obj);
+			return true;
+		}
+
+		private void NotStorable(object obj, IReflectClass claxx)
+		{
+			_container.NotStorable(claxx, obj);
+			_notStorable = true;
+		}
+
+		internal virtual bool NotStorable()
+		{
+			return _notStorable;
+		}
+
+		private bool IsValueType(Db4objects.Db4o.Internal.ClassMetadata classMetadata)
+		{
+			return classMetadata.IsValueType();
+		}
+
+		internal virtual Db4objects.Db4o.Internal.ObjectReference ObjectReference()
+		{
+			return _ref;
+		}
+
+		public virtual Db4objects.Db4o.Internal.ClassMetadata ClassMetadata()
+		{
+			return _classMetadata;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectContainerBase.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectContainerBase.cs
new file mode 100644
index 0000000..b1b21eb
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectContainerBase.cs
@@ -0,0 +1,2885 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Callbacks;
+using Db4objects.Db4o.Internal.Encoding;
+using Db4objects.Db4o.Internal.Events;
+using Db4objects.Db4o.Internal.Handlers.Array;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Metadata;
+using Db4objects.Db4o.Internal.Query;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Internal.Query.Result;
+using Db4objects.Db4o.Internal.References;
+using Db4objects.Db4o.Internal.Replication;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Internal.Threading;
+using Db4objects.Db4o.Internal.Weakref;
+using Db4objects.Db4o.Query;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Core;
+using Db4objects.Db4o.Reflect.Generic;
+using Db4objects.Db4o.Typehandlers;
+using Db4objects.Db4o.Types;
+using Sharpen;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public abstract partial class ObjectContainerBase : System.IDisposable, ITransientClass
+		, IInternal4, IObjectContainerSpec, IInternalObjectContainer
+	{
+		protected ClassMetadataRepository _classCollection;
+
+		protected Config4Impl _config;
+
+		private int _stackDepth;
+
+		private readonly int _maxStackDepth;
+
+		private readonly Db4objects.Db4o.Internal.References.ReferenceSystemRegistry _referenceSystemRegistry
+			 = new Db4objects.Db4o.Internal.References.ReferenceSystemRegistry();
+
+		private Tree _justPeeked;
+
+		protected object _lock;
+
+		private List4 _pendingClassUpdates;
+
+		internal int _showInternalClasses = 0;
+
+		private List4 _stillToActivate;
+
+		private List4 _stillToDeactivate;
+
+		private List4 _stillToSet;
+
+		private bool _handlingStackLimitPendings = false;
+
+		private Db4objects.Db4o.Internal.Transaction _systemTransaction;
+
+		protected Db4objects.Db4o.Internal.Transaction _transaction;
+
+		public HandlerRegistry _handlers;
+
+		internal int _replicationCallState;
+
+		internal IWeakReferenceSupport _references;
+
+		private NativeQueryHandler _nativeQueryHandler;
+
+		private ICallbacks _callbacks = new NullCallbacks();
+
+		protected readonly TimeStampIdGenerator _timeStampIdGenerator = new TimeStampIdGenerator
+			();
+
+		private int _topLevelCallId = 1;
+
+		private IntIdGenerator _topLevelCallIdGenerator = new IntIdGenerator();
+
+		private readonly IEnvironment _environment;
+
+		private IReferenceSystemFactory _referenceSystemFactory;
+
+		private string _name;
+
+		protected IBlockConverter _blockConverter = new DisabledBlockConverter();
+
+		protected ObjectContainerBase(IConfiguration config)
+		{
+			// Collection of all classes
+			// if (_classCollection == null) the engine is down.
+			// the Configuration context for this ObjectContainer
+			// Counts the number of toplevel calls into YapStream
+			// currently used to resolve self-linking concurrency problems
+			// in cylic links, stores only ClassMetadata objects
+			// a value greater than 0 indicates class implementing the
+			// "Internal" interface are visible in queries and can
+			// be used.
+			// used for ClassMetadata and ClassMetadataRepository
+			// may be parent or equal to i_trans
+			// used for Objects
+			// all the per-YapStream references that we don't
+			// want created in YapobjectCarrier
+			// One of three constants in ReplicationHandler: NONE, OLD, NEW
+			// Detailed replication variables are stored in i_handlers.
+			// Call state has to be maintained here, so YapObjectCarrier (who shares i_handlers) does
+			// not accidentally think it operates in a replication call. 
+			// weak reference management
+			_lock = new object();
+			_config = (Config4Impl)config;
+			_environment = CreateEnvironment(_config);
+			_maxStackDepth = _config.MaxStackDepth();
+		}
+
+		private IEnvironment CreateEnvironment(Config4Impl config)
+		{
+			ArrayList bindings = new ArrayList();
+			Sharpen.Collections.AddAll(bindings, config.EnvironmentContributions());
+			bindings.Add(this);
+			// my(ObjectContainer.class)
+			bindings.Add(config);
+			// my(Configuration.class)
+			return Environments.NewConventionBasedEnvironment(Sharpen.Collections.ToArray(bindings
+				));
+		}
+
+		protected virtual IEnvironment Environment()
+		{
+			return _environment;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.OldFormatException"></exception>
+		protected void Open()
+		{
+			WithEnvironment(new _IRunnable_129(this));
+		}
+
+		private sealed class _IRunnable_129 : IRunnable
+		{
+			public _IRunnable_129(ObjectContainerBase _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Run()
+			{
+				bool ok = false;
+				lock (this._enclosing._lock)
+				{
+					try
+					{
+						this._enclosing._name = this._enclosing.ConfigImpl.NameProvider().Name(this._enclosing
+							);
+						this._enclosing.InitializeReferenceSystemFactory(this._enclosing._config);
+						this._enclosing.InitializeTransactions();
+						this._enclosing.Initialize1(this._enclosing._config);
+						this._enclosing.OpenImpl();
+						this._enclosing.InitializePostOpen();
+						this._enclosing.Callbacks().OpenOnFinished(this._enclosing);
+						ok = true;
+					}
+					finally
+					{
+						if (!ok)
+						{
+							// TODO: This will swallow the causing exception if
+							//       an exception occurs during shutdown.
+							this._enclosing.ShutdownObjectContainer();
+						}
+					}
+				}
+			}
+
+			private readonly ObjectContainerBase _enclosing;
+		}
+
+		private void InitializeReferenceSystemFactory(Config4Impl config)
+		{
+			_referenceSystemFactory = config.ReferenceSystemFactory();
+		}
+
+		public virtual void WithEnvironment(IRunnable runnable)
+		{
+			Environments.RunWith(_environment, runnable);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		protected abstract void OpenImpl();
+
+		public virtual IActivationDepth DefaultActivationDepth(ClassMetadata classMetadata
+			)
+		{
+			return ActivationDepthProvider().ActivationDepthFor(classMetadata, ActivationMode
+				.Activate);
+		}
+
+		public virtual IActivationDepthProvider ActivationDepthProvider()
+		{
+			return ConfigImpl.ActivationDepthProvider();
+		}
+
+		public void Activate(Db4objects.Db4o.Internal.Transaction trans, object obj)
+		{
+			lock (_lock)
+			{
+				Activate(trans, obj, DefaultActivationDepthForObject(obj));
+			}
+		}
+
+		public void Deactivate(Db4objects.Db4o.Internal.Transaction trans, object obj)
+		{
+			Deactivate(trans, obj, 1);
+		}
+
+		private IActivationDepth DefaultActivationDepthForObject(object obj)
+		{
+			ClassMetadata classMetadata = ClassMetadataForObject(obj);
+			return DefaultActivationDepth(classMetadata);
+		}
+
+		public void Activate(Db4objects.Db4o.Internal.Transaction trans, object obj, IActivationDepth
+			 depth)
+		{
+			lock (_lock)
+			{
+				AsTopLevelCall(new _IFunction4_189(this, obj, depth), trans);
+			}
+		}
+
+		private sealed class _IFunction4_189 : IFunction4
+		{
+			public _IFunction4_189(ObjectContainerBase _enclosing, object obj, IActivationDepth
+				 depth)
+			{
+				this._enclosing = _enclosing;
+				this.obj = obj;
+				this.depth = depth;
+			}
+
+			public object Apply(object trans)
+			{
+				this._enclosing.StillToActivate(this._enclosing.ActivationContextFor(((Db4objects.Db4o.Internal.Transaction
+					)trans), obj, depth));
+				this._enclosing.ActivatePending(((Db4objects.Db4o.Internal.Transaction)trans));
+				return null;
+			}
+
+			private readonly ObjectContainerBase _enclosing;
+
+			private readonly object obj;
+
+			private readonly IActivationDepth depth;
+		}
+
+		internal sealed class PendingActivation
+		{
+			public readonly ObjectReference @ref;
+
+			public readonly IActivationDepth depth;
+
+			public PendingActivation(ObjectReference ref_, IActivationDepth depth_)
+			{
+				this. at ref = ref_;
+				this.depth = depth_;
+			}
+		}
+
+		internal void ActivatePending(Transaction ta)
+		{
+			while (_stillToActivate != null)
+			{
+				// TODO: Optimize!  A lightweight int array would be faster.
+				IEnumerator i = new Iterator4Impl(_stillToActivate);
+				_stillToActivate = null;
+				while (i.MoveNext())
+				{
+					ObjectContainerBase.PendingActivation item = (ObjectContainerBase.PendingActivation
+						)i.Current;
+					ObjectReference @ref = item. at ref;
+					object obj = @ref.GetObject();
+					if (obj == null)
+					{
+						ta.RemoveReference(@ref);
+					}
+					else
+					{
+						@ref.ActivateInternal(ActivationContextFor(ta, obj, item.depth));
+					}
+				}
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Backup(string path)
+		{
+			Backup(ConfigImpl.Storage, path);
+		}
+
+		public virtual ActivationContext4 ActivationContextFor(Transaction ta, object obj
+			, IActivationDepth depth)
+		{
+			return new ActivationContext4(ta, obj, depth);
+		}
+
+		/// <exception cref="System.ArgumentNullException"></exception>
+		/// <exception cref="System.ArgumentException"></exception>
+		public void Bind(Transaction trans, object obj, long id)
+		{
+			lock (_lock)
+			{
+				if (obj == null)
+				{
+					throw new ArgumentNullException();
+				}
+				if (DTrace.enabled)
+				{
+					DTrace.Bind.Log(id, " ihc " + Runtime.IdentityHashCode(obj));
+				}
+				trans = CheckTransaction(trans);
+				int intID = (int)id;
+				object oldObject = GetByID(trans, id);
+				if (oldObject == null)
+				{
+					throw new ArgumentException("id");
+				}
+				ObjectReference @ref = trans.ReferenceForId(intID);
+				if (@ref == null)
+				{
+					throw new ArgumentException("obj");
+				}
+				if (ReflectorForObject(obj) == @ref.ClassMetadata().ClassReflector())
+				{
+					ObjectReference newRef = Bind2(trans, @ref, obj);
+					newRef.VirtualAttributes(trans, false);
+				}
+				else
+				{
+					throw new Db4oException(Db4objects.Db4o.Internal.Messages.Get(57));
+				}
+			}
+		}
+
+		public ObjectReference Bind2(Transaction trans, ObjectReference oldRef, object obj
+			)
+		{
+			int id = oldRef.GetID();
+			trans.RemoveReference(oldRef);
+			ObjectReference newRef = new ObjectReference(ClassMetadataForObject(obj), id);
+			newRef.SetObjectWeak(this, obj);
+			newRef.SetStateDirty();
+			trans.ReferenceSystem().AddExistingReference(newRef);
+			return newRef;
+		}
+
+		public virtual ClassMetadata ClassMetadataForObject(object obj)
+		{
+			return ProduceClassMetadata(ReflectorForObject(obj));
+		}
+
+		public abstract byte BlockSize();
+
+		private bool BreakDeleteForEnum(ObjectReference reference, bool userCall)
+		{
+			return false;
+			if (userCall)
+			{
+				return false;
+			}
+			if (reference == null)
+			{
+				return false;
+			}
+			return Platform4.IsEnum(Reflector(), reference.ClassMetadata().ClassReflector());
+		}
+
+		internal virtual bool CanUpdate()
+		{
+			return true;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public void CheckClosed()
+		{
+			if (_classCollection == null)
+			{
+				throw new DatabaseClosedException();
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		protected void CheckReadOnly()
+		{
+			if (_config.IsReadOnly())
+			{
+				throw new DatabaseReadOnlyException();
+			}
+		}
+
+		internal void ProcessPendingClassUpdates()
+		{
+			if (_pendingClassUpdates == null)
+			{
+				return;
+			}
+			IEnumerator i = new Iterator4Impl(_pendingClassUpdates);
+			while (i.MoveNext())
+			{
+				ClassMetadata classMetadata = (ClassMetadata)i.Current;
+				classMetadata.SetStateDirty();
+				classMetadata.Write(_systemTransaction);
+			}
+			_pendingClassUpdates = null;
+		}
+
+		public Transaction CheckTransaction()
+		{
+			return CheckTransaction(null);
+		}
+
+		public Transaction CheckTransaction(Transaction ta)
+		{
+			CheckClosed();
+			if (ta != null)
+			{
+				return ta;
+			}
+			return Transaction;
+		}
+
+		public bool Close()
+		{
+			lock (_lock)
+			{
+				Callbacks().CloseOnStarted(this);
+				if (DTrace.enabled)
+				{
+					DTrace.CloseCalled.Log(this.ToString());
+				}
+				Close1();
+				return true;
+			}
+		}
+
+		protected virtual void HandleExceptionOnClose(Exception exc)
+		{
+			FatalException(exc);
+		}
+
+		private void Close1()
+		{
+			if (IsClosed())
+			{
+				return;
+			}
+			ProcessPendingClassUpdates();
+			if (StateMessages())
+			{
+				LogMsg(2, ToString());
+			}
+			Close2();
+		}
+
+		protected abstract void Close2();
+
+		public void ShutdownObjectContainer()
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.Close.Log();
+			}
+			LogMsg(3, ToString());
+			lock (_lock)
+			{
+				CloseUserTransaction();
+				CloseSystemTransaction();
+				CloseIdSystem();
+				StopSession();
+				ShutdownDataStorage();
+			}
+		}
+
+		protected abstract void CloseIdSystem();
+
+		protected void CloseUserTransaction()
+		{
+			CloseTransaction(_transaction, false, false);
+		}
+
+		protected void CloseSystemTransaction()
+		{
+			CloseTransaction(_systemTransaction, true, false);
+		}
+
+		public abstract void CloseTransaction(Transaction transaction, bool isSystemTransaction
+			, bool rollbackOnClose);
+
+		protected abstract void ShutdownDataStorage();
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public void Commit(Transaction trans)
+		{
+			lock (_lock)
+			{
+				if (DTrace.enabled)
+				{
+					DTrace.Commit.Log();
+				}
+				CheckReadOnly();
+				AsTopLevelCall(new _IFunction4_399(this), trans);
+			}
+		}
+
+		private sealed class _IFunction4_399 : IFunction4
+		{
+			public _IFunction4_399(ObjectContainerBase _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Apply(object trans)
+			{
+				this._enclosing.Commit1(((Transaction)trans));
+				((Transaction)trans).CommitReferenceSystem();
+				return null;
+			}
+
+			private readonly ObjectContainerBase _enclosing;
+		}
+
+		private object AsTopLevelStore(IFunction4 block, Transaction trans)
+		{
+			trans = CheckTransaction(trans);
+			object result = AsTopLevelCall(block, trans);
+			if (_stackDepth == 0)
+			{
+				trans.ProcessDeletes();
+			}
+			return result;
+		}
+
+		// should never happen - just to make compiler happy
+		public virtual void FatalShutdown(Exception origExc)
+		{
+			try
+			{
+				StopSession();
+				FatalStorageShutdown();
+			}
+			catch (Exception exc)
+			{
+				throw new CompositeDb4oException(new Exception[] { origExc, exc });
+			}
+			Platform4.ThrowUncheckedException(origExc);
+		}
+
+		protected abstract void FatalStorageShutdown();
+
+		public abstract void Commit1(Transaction trans);
+
+		public virtual IConfiguration Configure()
+		{
+			return ConfigImpl;
+		}
+
+		public virtual Config4Impl Config()
+		{
+			return ConfigImpl;
+		}
+
+		public abstract int ConverterVersion();
+
+		public abstract AbstractQueryResult NewQueryResult(Transaction trans, QueryEvaluationMode
+			 mode);
+
+		protected void CreateStringIO(byte encoding)
+		{
+			StringIO(BuiltInStringEncoding.StringIoForEncoding(encoding, ConfigImpl.StringEncoding
+				()));
+		}
+
+		protected void InitializeTransactions()
+		{
+			_systemTransaction = NewSystemTransaction();
+			_transaction = NewUserTransaction();
+		}
+
+		public abstract Transaction NewTransaction(Transaction parentTransaction, IReferenceSystem
+			 referenceSystem, bool isSystemTransaction);
+
+		public virtual Transaction NewUserTransaction()
+		{
+			return NewTransaction(SystemTransaction(), CreateReferenceSystem(), false);
+		}
+
+		public virtual Transaction NewSystemTransaction()
+		{
+			return NewTransaction(null, CreateReferenceSystem(), true);
+		}
+
+		public abstract long CurrentVersion();
+
+		public virtual bool CreateClassMetadata(ClassMetadata classMeta, IReflectClass clazz
+			, ClassMetadata superClassMeta)
+		{
+			return classMeta.Init(superClassMeta);
+		}
+
+		/// <summary>allows special handling for all Db4oType objects.</summary>
+		/// <remarks>
+		/// allows special handling for all Db4oType objects.
+		/// Redirected here from #set() so only instanceof check is necessary
+		/// in the #set() method.
+		/// </remarks>
+		/// <returns>object if handled here and #set() should not continue processing</returns>
+		public virtual IDb4oType Db4oTypeStored(Transaction trans, object obj)
+		{
+			if (!(obj is Db4oDatabase))
+			{
+				return null;
+			}
+			Db4oDatabase database = (Db4oDatabase)obj;
+			if (trans.ReferenceForObject(obj) != null)
+			{
+				return database;
+			}
+			ShowInternalClasses(true);
+			try
+			{
+				return database.Query(trans);
+			}
+			finally
+			{
+				ShowInternalClasses(false);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public void Deactivate(Transaction trans, object obj, int depth)
+		{
+			lock (_lock)
+			{
+				AsTopLevelCall(new _IFunction4_516(this, obj, depth), trans);
+			}
+		}
+
+		private sealed class _IFunction4_516 : IFunction4
+		{
+			public _IFunction4_516(ObjectContainerBase _enclosing, object obj, int depth)
+			{
+				this._enclosing = _enclosing;
+				this.obj = obj;
+				this.depth = depth;
+			}
+
+			public object Apply(object trans)
+			{
+				this._enclosing.DeactivateInternal(((Transaction)trans), obj, this._enclosing.ActivationDepthProvider
+					().ActivationDepth(depth, ActivationMode.Deactivate));
+				return null;
+			}
+
+			private readonly ObjectContainerBase _enclosing;
+
+			private readonly object obj;
+
+			private readonly int depth;
+		}
+
+		private void DeactivateInternal(Transaction trans, object obj, IActivationDepth depth
+			)
+		{
+			StillToDeactivate(trans, obj, depth, true);
+			DeactivatePending(trans);
+		}
+
+		private void DeactivatePending(Transaction trans)
+		{
+			while (_stillToDeactivate != null)
+			{
+				IEnumerator i = new Iterator4Impl(_stillToDeactivate);
+				_stillToDeactivate = null;
+				while (i.MoveNext())
+				{
+					ObjectContainerBase.PendingActivation item = (ObjectContainerBase.PendingActivation
+						)i.Current;
+					item. at ref.Deactivate(trans, item.depth);
+				}
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public void Delete(Transaction trans, object obj)
+		{
+			if (null == obj)
+			{
+				throw new ArgumentNullException();
+			}
+			lock (Lock())
+			{
+				trans = CheckTransaction(trans);
+				CheckReadOnly();
+				Delete1(trans, obj, true);
+				UnregisterFromTransparentPersistence(trans, obj);
+				trans.ProcessDeletes();
+			}
+		}
+
+		public void Delete1(Transaction trans, object obj, bool userCall)
+		{
+			if (obj == null)
+			{
+				return;
+			}
+			ObjectReference @ref = trans.ReferenceForObject(obj);
+			if (@ref == null)
+			{
+				return;
+			}
+			if (userCall)
+			{
+				GenerateCallIDOnTopLevel();
+			}
+			AsTopLevelCall(new _IFunction4_565(this, @ref, obj, userCall), trans);
+		}
+
+		private sealed class _IFunction4_565 : IFunction4
+		{
+			public _IFunction4_565(ObjectContainerBase _enclosing, ObjectReference @ref, object
+				 obj, bool userCall)
+			{
+				this._enclosing = _enclosing;
+				this. at ref = @ref;
+				this.obj = obj;
+				this.userCall = userCall;
+			}
+
+			public object Apply(object trans)
+			{
+				this._enclosing.Delete2(((Transaction)trans), @ref, obj, 0, userCall);
+				return null;
+			}
+
+			private readonly ObjectContainerBase _enclosing;
+
+			private readonly ObjectReference @ref;
+
+			private readonly object obj;
+
+			private readonly bool userCall;
+		}
+
+		public void Delete2(Transaction trans, ObjectReference @ref, object obj, int cascade
+			, bool userCall)
+		{
+			// This check is performed twice, here and in delete3, intentionally.
+			if (BreakDeleteForEnum(@ref, userCall))
+			{
+				return;
+			}
+			if (obj is Entry)
+			{
+				if (!FlagForDelete(@ref))
+				{
+					return;
+				}
+				Delete3(trans, @ref, obj, cascade, userCall);
+				return;
+			}
+			trans.Delete(@ref, @ref.GetID(), cascade);
+		}
+
+		internal void Delete3(Transaction trans, ObjectReference @ref, object obj, int cascade
+			, bool userCall)
+		{
+			// The passed reference can be null, when calling from Transaction.
+			if (@ref == null || !@ref.BeginProcessing())
+			{
+				return;
+			}
+			// This check is performed twice, here and in delete2, intentionally.
+			if (BreakDeleteForEnum(@ref, userCall))
+			{
+				@ref.EndProcessing();
+				return;
+			}
+			if (!@ref.IsFlaggedForDelete())
+			{
+				@ref.EndProcessing();
+				return;
+			}
+			ClassMetadata yc = @ref.ClassMetadata();
+			// We have to end processing temporarily here, otherwise the can delete callback
+			// can't do anything at all with this object.
+			@ref.EndProcessing();
+			ActivateForDeletionCallback(trans, yc, @ref, obj);
+			if (!ObjectCanDelete(trans, yc, @ref))
+			{
+				return;
+			}
+			@ref.BeginProcessing();
+			if (DTrace.enabled)
+			{
+				DTrace.Delete.Log(@ref.GetID());
+			}
+			if (Delete4(trans, @ref, obj, cascade, userCall))
+			{
+				ObjectOnDelete(trans, yc, @ref);
+				if (ConfigImpl.MessageLevel() > Const4.State)
+				{
+					Message(string.Empty + @ref.GetID() + " delete " + @ref.ClassMetadata().GetName()
+						);
+				}
+			}
+			@ref.EndProcessing();
+		}
+
+		private void UnregisterFromTransparentPersistence(Transaction trans, object obj)
+		{
+			if (!(ActivationDepthProvider() is ITransparentActivationDepthProvider))
+			{
+				return;
+			}
+			ITransparentActivationDepthProvider provider = (ITransparentActivationDepthProvider
+				)ActivationDepthProvider();
+			provider.RemoveModified(obj, trans);
+		}
+
+		private void ActivateForDeletionCallback(Transaction trans, ClassMetadata classMetadata
+			, ObjectReference @ref, object obj)
+		{
+			if (!@ref.IsActive() && (CaresAboutDeleting(classMetadata) || CaresAboutDeleted(classMetadata
+				)))
+			{
+				// Activate Objects for Callbacks, because in C/S mode Objects are not activated on the Server
+				// FIXME: [TA] review activation depth
+				IActivationDepth depth = classMetadata.AdjustCollectionDepthToBorders(new FixedActivationDepth
+					(1));
+				Activate(trans, obj, depth);
+			}
+		}
+
+		private bool CaresAboutDeleting(ClassMetadata yc)
+		{
+			return this._callbacks.CaresAboutDeleting() || yc.HasEventRegistered(SystemTransaction
+				(), EventDispatchers.CanDelete);
+		}
+
+		private bool CaresAboutDeleted(ClassMetadata yc)
+		{
+			return this._callbacks.CaresAboutDeleted() || yc.HasEventRegistered(SystemTransaction
+				(), EventDispatchers.Delete);
+		}
+
+		private bool ObjectCanDelete(Transaction transaction, ClassMetadata yc, IObjectInfo
+			 objectInfo)
+		{
+			return Callbacks().ObjectCanDelete(transaction, objectInfo) && yc.DispatchEvent(transaction
+				, objectInfo.GetObject(), EventDispatchers.CanDelete);
+		}
+
+		private void ObjectOnDelete(Transaction transaction, ClassMetadata yc, IObjectInfo
+			 reference)
+		{
+			Callbacks().ObjectOnDelete(transaction, reference);
+			yc.DispatchEvent(transaction, reference.GetObject(), EventDispatchers.Delete);
+		}
+
+		public abstract bool Delete4(Transaction ta, ObjectReference @ref, object obj, int
+			 a_cascade, bool userCall);
+
+		internal virtual object Descend(Transaction trans, object obj, string[] path)
+		{
+			lock (_lock)
+			{
+				trans = CheckTransaction(trans);
+				ObjectReference @ref = trans.ReferenceForObject(obj);
+				if (@ref == null)
+				{
+					return null;
+				}
+				string fieldName = path[0];
+				if (fieldName == null)
+				{
+					return null;
+				}
+				ClassMetadata classMetadata = @ref.ClassMetadata();
+				ByRef foundField = new ByRef();
+				classMetadata.TraverseAllAspects(new _TraverseFieldCommand_693(fieldName, foundField
+					));
+				FieldMetadata field = (FieldMetadata)foundField.value;
+				if (field == null)
+				{
+					return null;
+				}
+				object child = @ref.IsActive() ? field.Get(trans, obj) : DescendMarshallingContext
+					(trans, @ref).ReadFieldValue(field);
+				if (path.Length == 1)
+				{
+					return child;
+				}
+				if (child == null)
+				{
+					return null;
+				}
+				string[] subPath = new string[path.Length - 1];
+				System.Array.Copy(path, 1, subPath, 0, path.Length - 1);
+				return Descend(trans, child, subPath);
+			}
+		}
+
+		private sealed class _TraverseFieldCommand_693 : TraverseFieldCommand
+		{
+			public _TraverseFieldCommand_693(string fieldName, ByRef foundField)
+			{
+				this.fieldName = fieldName;
+				this.foundField = foundField;
+			}
+
+			protected override void Process(FieldMetadata field)
+			{
+				if (field.CanAddToQuery(fieldName))
+				{
+					foundField.value = field;
+				}
+			}
+
+			private readonly string fieldName;
+
+			private readonly ByRef foundField;
+		}
+
+		private UnmarshallingContext DescendMarshallingContext(Transaction trans, ObjectReference
+			 @ref)
+		{
+			UnmarshallingContext context = new UnmarshallingContext(trans, @ref, Const4.AddToIdTree
+				, false);
+			context.ActivationDepth(ActivationDepthProvider().ActivationDepth(1, ActivationMode
+				.Activate));
+			return context;
+		}
+
+		public virtual bool DetectSchemaChanges()
+		{
+			// overriden in YapClient
+			return ConfigImpl.DetectSchemaChanges();
+		}
+
+		public virtual bool DispatchsEvents()
+		{
+			return true;
+		}
+
+		protected virtual bool DoFinalize()
+		{
+			return true;
+		}
+
+		internal void ShutdownHook()
+		{
+			if (IsClosed())
+			{
+				return;
+			}
+			if (AllOperationsCompleted())
+			{
+				Db4objects.Db4o.Internal.Messages.LogErr(ConfigImpl, 50, ToString(), null);
+				Close();
+			}
+			else
+			{
+				ShutdownObjectContainer();
+				if (OperationIsProcessing())
+				{
+					Db4objects.Db4o.Internal.Messages.LogErr(ConfigImpl, 24, null, null);
+				}
+			}
+		}
+
+		private bool OperationIsProcessing()
+		{
+			return _stackDepth > 0;
+		}
+
+		private bool AllOperationsCompleted()
+		{
+			return _stackDepth == 0;
+		}
+
+		internal virtual void FatalException(int msgID)
+		{
+			FatalException(null, msgID);
+		}
+
+		internal void FatalException(Exception t)
+		{
+			FatalException(t, Db4objects.Db4o.Internal.Messages.FatalMsgId);
+		}
+
+		internal void FatalException(Exception t, int msgID)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.FatalException.Log(t.ToString());
+			}
+			Db4objects.Db4o.Internal.Messages.LogErr(ConfigImpl, (msgID == Db4objects.Db4o.Internal.Messages
+				.FatalMsgId ? 18 : msgID), null, t);
+			if (!IsClosed())
+			{
+				ShutdownObjectContainer();
+			}
+			throw new Db4oException(Db4objects.Db4o.Internal.Messages.Get(msgID));
+		}
+
+		private bool ConfiguredForAutomaticShutDown()
+		{
+			return (ConfigImpl == null || ConfigImpl.AutomaticShutDown());
+		}
+
+		internal virtual void Gc()
+		{
+			_references.Purge();
+		}
+
+		public IObjectSet QueryByExample(Transaction trans, object template)
+		{
+			lock (_lock)
+			{
+				trans = CheckTransaction(trans);
+				IQueryResult res = ((IQueryResult)AsTopLevelCall(new _IFunction4_810(this, template
+					), trans));
+				return new ObjectSetFacade(res);
+			}
+		}
+
+		private sealed class _IFunction4_810 : IFunction4
+		{
+			public _IFunction4_810(ObjectContainerBase _enclosing, object template)
+			{
+				this._enclosing = _enclosing;
+				this.template = template;
+			}
+
+			public object Apply(object trans)
+			{
+				return this._enclosing.QueryByExampleInternal(((Transaction)trans), template);
+			}
+
+			private readonly ObjectContainerBase _enclosing;
+
+			private readonly object template;
+		}
+
+		private IQueryResult QueryByExampleInternal(Transaction trans, object template)
+		{
+			if (template == null || template.GetType() == Const4.ClassObject || template == Const4
+				.ClassObject)
+			{
+				return QueryAllObjects(trans);
+			}
+			IQuery q = Query(trans);
+			q.Constrain(template).ByExample();
+			return ExecuteQuery((QQuery)q);
+		}
+
+		public abstract AbstractQueryResult QueryAllObjects(Transaction ta);
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public object TryGetByID(Transaction ta, long id)
+		{
+			try
+			{
+				return GetByID(ta, id);
+			}
+			catch (InvalidSlotException)
+			{
+			}
+			catch (InvalidIDException)
+			{
+			}
+			// can happen return null
+			// can happen return null
+			return null;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.InvalidIDException"></exception>
+		public object GetByID(Transaction ta, long id)
+		{
+			lock (_lock)
+			{
+				if (id <= 0 || id >= int.MaxValue)
+				{
+					throw new ArgumentException();
+				}
+				CheckClosed();
+				ta = CheckTransaction(ta);
+				BeginTopLevelCall();
+				try
+				{
+					return GetByID2(ta, (int)id);
+				}
+				catch (Db4oRecoverableException exc)
+				{
+					throw;
+				}
+				catch (OutOfMemoryException e)
+				{
+					throw new Db4oRecoverableException(e);
+				}
+				catch (Exception e)
+				{
+					throw new Db4oRecoverableException(e);
+				}
+				finally
+				{
+					// Never shut down for getById()
+					// There may be OutOfMemoryErrors or similar
+					// The user may want to catch and continue working.
+					EndTopLevelCall();
+				}
+			}
+		}
+
+		public virtual object GetByID2(Transaction ta, int id)
+		{
+			object obj = ta.ObjectForIdFromCache(id);
+			if (obj != null)
+			{
+				// Take care about handling the returned candidate reference.
+				// If you loose the reference, weak reference management might
+				// also.
+				return obj;
+			}
+			return new ObjectReference(id).Read(ta, new LegacyActivationDepth(0), Const4.AddToIdTree
+				, true);
+		}
+
+		public object GetActivatedObjectFromCache(Transaction ta, int id)
+		{
+			object obj = ta.ObjectForIdFromCache(id);
+			if (obj == null)
+			{
+				return null;
+			}
+			Activate(ta, obj);
+			return obj;
+		}
+
+		public object ReadActivatedObjectNotInCache(Transaction trans, int id)
+		{
+			object obj = AsTopLevelCall(new _IFunction4_892(id), trans);
+			ActivatePending(trans);
+			return obj;
+		}
+
+		private sealed class _IFunction4_892 : IFunction4
+		{
+			public _IFunction4_892(int id)
+			{
+				this.id = id;
+			}
+
+			public object Apply(object trans)
+			{
+				return new ObjectReference(id).Read(((Transaction)trans), UnknownActivationDepth.
+					Instance, Const4.AddToIdTree, true);
+			}
+
+			private readonly int id;
+		}
+
+		public object GetByUUID(Transaction trans, Db4oUUID uuid)
+		{
+			lock (_lock)
+			{
+				if (uuid == null)
+				{
+					return null;
+				}
+				HardObjectReference hardRef = GetHardReferenceBySignature(CheckTransaction(trans)
+					, uuid.GetLongPart(), uuid.GetSignaturePart());
+				return hardRef._object;
+			}
+		}
+
+		public virtual HardObjectReference GetHardReferenceBySignature(Transaction trans, 
+			long uuid, byte[] signature)
+		{
+			return UUIDIndex().GetHardObjectReferenceBySignature(trans, uuid, signature);
+		}
+
+		public int GetID(Transaction trans, object obj)
+		{
+			lock (_lock)
+			{
+				trans = CheckTransaction(trans);
+				CheckClosed();
+				if (obj == null)
+				{
+					return 0;
+				}
+				ObjectReference yo = trans.ReferenceForObject(obj);
+				if (yo != null)
+				{
+					return yo.GetID();
+				}
+				return 0;
+			}
+		}
+
+		public IObjectInfo GetObjectInfo(Transaction trans, object obj)
+		{
+			lock (_lock)
+			{
+				trans = CheckTransaction(trans);
+				return trans.ReferenceForObject(obj);
+			}
+		}
+
+		public HardObjectReference GetHardObjectReferenceById(Transaction trans, int id)
+		{
+			if (id <= 0)
+			{
+				return HardObjectReference.Invalid;
+			}
+			ObjectReference @ref = trans.ReferenceForId(id);
+			if (@ref != null)
+			{
+				// Take care about handling the returned candidate reference.
+				// If you loose the reference, weak reference management might also.
+				object candidate = @ref.GetObject();
+				if (candidate != null)
+				{
+					return new HardObjectReference(@ref, candidate);
+				}
+				trans.RemoveReference(@ref);
+			}
+			@ref = new ObjectReference(id);
+			object readObject = @ref.Read(trans, new LegacyActivationDepth(0), Const4.AddToIdTree
+				, true);
+			if (readObject == null)
+			{
+				return HardObjectReference.Invalid;
+			}
+			// check class creation side effect and simply retry recursively
+			// if it hits:
+			if (readObject != @ref.GetObject())
+			{
+				return GetHardObjectReferenceById(trans, id);
+			}
+			return new HardObjectReference(@ref, readObject);
+		}
+
+		public StatefulBuffer CreateStatefulBuffer(Transaction trans, int address, int length
+			)
+		{
+			if (Debug4.ExceedsMaximumBlockSize(length))
+			{
+				return null;
+			}
+			return new StatefulBuffer(trans, address, length);
+		}
+
+		public Transaction SystemTransaction()
+		{
+			return _systemTransaction;
+		}
+
+		public Transaction Transaction
+		{
+			get
+			{
+				return _transaction;
+			}
+		}
+
+		public ClassMetadata ClassMetadataForReflectClass(IReflectClass claxx)
+		{
+			if (null == claxx)
+			{
+				throw new ArgumentNullException();
+			}
+			if (HideClassForExternalUse(claxx))
+			{
+				return null;
+			}
+			ClassMetadata classMetadata = _handlers.ClassMetadataForClass(claxx);
+			if (classMetadata != null)
+			{
+				return classMetadata;
+			}
+			return _classCollection.ClassMetadataForReflectClass(claxx);
+		}
+
+		// TODO: Some ReflectClass implementations could hold a 
+		// reference to ClassMetadata to improve lookup performance here.
+		public virtual ClassMetadata ProduceClassMetadata(IReflectClass claxx)
+		{
+			if (null == claxx)
+			{
+				throw new ArgumentNullException();
+			}
+			if (HideClassForExternalUse(claxx))
+			{
+				return null;
+			}
+			ClassMetadata classMetadata = _handlers.ClassMetadataForClass(claxx);
+			if (classMetadata != null)
+			{
+				return classMetadata;
+			}
+			return _classCollection.ProduceClassMetadata(claxx);
+		}
+
+		/// <summary>
+		/// Differentiating getActiveClassMetadata from getYapClass is a tuning
+		/// optimization: If we initialize a YapClass, #set3() has to check for
+		/// the possibility that class initialization associates the currently
+		/// stored object with a previously stored static object, causing the
+		/// object to be known afterwards.
+		/// </summary>
+		/// <remarks>
+		/// Differentiating getActiveClassMetadata from getYapClass is a tuning
+		/// optimization: If we initialize a YapClass, #set3() has to check for
+		/// the possibility that class initialization associates the currently
+		/// stored object with a previously stored static object, causing the
+		/// object to be known afterwards.
+		/// In this call we only return active YapClasses, initialization
+		/// is not done on purpose
+		/// </remarks>
+		internal ClassMetadata GetActiveClassMetadata(IReflectClass claxx)
+		{
+			if (HideClassForExternalUse(claxx))
+			{
+				return null;
+			}
+			return _classCollection.GetActiveClassMetadata(claxx);
+		}
+
+		private bool HideClassForExternalUse(IReflectClass claxx)
+		{
+			if ((!ShowInternalClasses()) && _handlers.IclassInternal.IsAssignableFrom(claxx))
+			{
+				return true;
+			}
+			return false;
+		}
+
+		public virtual int ClassMetadataIdForName(string name)
+		{
+			return _classCollection.ClassMetadataIdForName(name);
+		}
+
+		public virtual ClassMetadata ClassMetadataForName(string name)
+		{
+			return ClassMetadataForID(ClassMetadataIdForName(name));
+		}
+
+		public virtual ClassMetadata ClassMetadataForID(int id)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.ClassmetadataById.Log(id);
+			}
+			if (id == 0)
+			{
+				return null;
+			}
+			ClassMetadata classMetadata = _handlers.ClassMetadataForId(id);
+			if (classMetadata != null)
+			{
+				return classMetadata;
+			}
+			return _classCollection.ClassMetadataForId(id);
+		}
+
+		public virtual HandlerRegistry Handlers
+		{
+			get
+			{
+				return _handlers;
+			}
+		}
+
+		public virtual bool NeedsLockFileThread()
+		{
+			if (!Platform4.NeedsLockFileThread())
+			{
+				return false;
+			}
+			if (ConfigImpl.IsReadOnly())
+			{
+				return false;
+			}
+			return ConfigImpl.LockFile();
+		}
+
+		protected virtual bool HasShutDownHook()
+		{
+			return ConfigImpl.AutomaticShutDown();
+		}
+
+		protected virtual void Initialize1(IConfiguration config)
+		{
+			_config = InitializeConfig(config);
+			_handlers = new HandlerRegistry(this, ConfigImpl.Encoding(), ConfigImpl.Reflector
+				());
+			if (_references != null)
+			{
+				Gc();
+				_references.Stop();
+			}
+			_references = WeakReferenceSupportFactory.ForObjectContainer(this);
+			if (HasShutDownHook())
+			{
+				Platform4.AddShutDownHook(this);
+			}
+			_handlers.InitEncryption(ConfigImpl);
+			_stillToSet = null;
+		}
+
+		private Config4Impl InitializeConfig(IConfiguration config)
+		{
+			Config4Impl impl = ((Config4Impl)config);
+			impl.Container(this);
+			impl.Reflector().SetTransaction(SystemTransaction());
+			impl.Reflector().Configuration(new ReflectorConfigurationImpl(impl));
+			impl.Taint();
+			return impl;
+		}
+
+		public virtual IReferenceSystem CreateReferenceSystem()
+		{
+			IReferenceSystem referenceSystem = _referenceSystemFactory.NewReferenceSystem(this
+				);
+			_referenceSystemRegistry.AddReferenceSystem(referenceSystem);
+			return referenceSystem;
+		}
+
+		protected virtual void InitalizeWeakReferenceSupport()
+		{
+			_references.Start();
+		}
+
+		protected virtual void InitializeClassMetadataRepository()
+		{
+			_classCollection = new ClassMetadataRepository(_systemTransaction);
+		}
+
+		private void InitializePostOpen()
+		{
+			_showInternalClasses = 100000;
+			InitializePostOpenExcludingTransportObjectContainer();
+			_showInternalClasses = 0;
+		}
+
+		protected virtual void InitializePostOpenExcludingTransportObjectContainer()
+		{
+			InitializeEssentialClasses();
+			Rename(ConfigImpl);
+			_classCollection.InitOnUp(_systemTransaction);
+			if (ConfigImpl.DetectSchemaChanges())
+			{
+				if (!ConfigImpl.IsReadOnly())
+				{
+					_systemTransaction.Commit();
+				}
+			}
+			ConfigImpl.ApplyConfigurationItems(this);
+		}
+
+		internal virtual void InitializeEssentialClasses()
+		{
+			for (int i = 0; i < Const4.EssentialClasses.Length; i++)
+			{
+				ProduceClassMetadata(Reflector().ForClass(Const4.EssentialClasses[i]));
+			}
+		}
+
+		internal bool IsActive(Transaction trans, object obj)
+		{
+			lock (_lock)
+			{
+				trans = CheckTransaction(trans);
+				if (obj != null)
+				{
+					ObjectReference @ref = trans.ReferenceForObject(obj);
+					if (@ref != null)
+					{
+						return @ref.IsActive();
+					}
+				}
+				return false;
+			}
+		}
+
+		public virtual bool IsCached(Transaction trans, long id)
+		{
+			lock (_lock)
+			{
+				trans = CheckTransaction(trans);
+				return trans.ObjectForIdFromCache((int)id) != null;
+			}
+		}
+
+		/// <summary>
+		/// overridden in ClientObjectContainer
+		/// The method allows checking whether will make it easier to refactor than
+		/// an "instanceof YapClient" check.
+		/// </summary>
+		/// <remarks>
+		/// overridden in ClientObjectContainer
+		/// The method allows checking whether will make it easier to refactor than
+		/// an "instanceof YapClient" check.
+		/// </remarks>
+		public virtual bool IsClient
+		{
+			get
+			{
+				return false;
+			}
+		}
+
+		public bool IsClosed()
+		{
+			lock (_lock)
+			{
+				// this is set to null in close2 and is therefore our check for down.
+				return _classCollection == null;
+			}
+		}
+
+		internal virtual bool IsServer()
+		{
+			return false;
+		}
+
+		public bool IsStored(Transaction trans, object obj)
+		{
+			lock (_lock)
+			{
+				trans = CheckTransaction(trans);
+				if (obj == null)
+				{
+					return false;
+				}
+				ObjectReference @ref = trans.ReferenceForObject(obj);
+				if (@ref == null)
+				{
+					return false;
+				}
+				return !IsDeleted(trans, @ref.GetID());
+			}
+		}
+
+		public virtual IReflectClass[] KnownClasses()
+		{
+			lock (_lock)
+			{
+				CheckClosed();
+				return Reflector().KnownClasses();
+			}
+		}
+
+		public virtual ITypeHandler4 TypeHandlerForClass(IReflectClass claxx)
+		{
+			if (HideClassForExternalUse(claxx))
+			{
+				return null;
+			}
+			ITypeHandler4 typeHandler = _handlers.TypeHandlerForClass(claxx);
+			if (typeHandler != null)
+			{
+				return typeHandler;
+			}
+			return _classCollection.ProduceClassMetadata(claxx).TypeHandler();
+		}
+
+		public virtual ITypeHandler4 TypeHandlerForClassMetadataID(int id)
+		{
+			if (id < 1)
+			{
+				return null;
+			}
+			ClassMetadata classMetadata = ClassMetadataForID(id);
+			if (classMetadata == null)
+			{
+				return null;
+			}
+			return classMetadata.TypeHandler();
+		}
+
+		public virtual object Lock()
+		{
+			return _lock;
+		}
+
+		public void LogMsg(int code, string msg)
+		{
+			Db4objects.Db4o.Internal.Messages.LogMsg(ConfigImpl, code, msg);
+		}
+
+		public virtual bool MaintainsIndices()
+		{
+			return true;
+		}
+
+		internal virtual void Message(string msg)
+		{
+			new MessageOutput(this, msg);
+		}
+
+		public void NeedsUpdate(ClassMetadata classMetadata)
+		{
+			_pendingClassUpdates = new List4(_pendingClassUpdates, classMetadata);
+		}
+
+		public virtual long GenerateTimeStampId()
+		{
+			return _timeStampIdGenerator.Generate();
+		}
+
+		public abstract int IdForNewUserObject(Transaction trans);
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public virtual object PeekPersisted(Transaction trans, object obj, IActivationDepth
+			 depth, bool committed)
+		{
+			// TODO: peekPersisted is not stack overflow safe, if depth is too high. 
+			lock (_lock)
+			{
+				CheckClosed();
+				return AsTopLevelCall(new _IFunction4_1271(this, obj, committed, depth), trans);
+			}
+		}
+
+		private sealed class _IFunction4_1271 : IFunction4
+		{
+			public _IFunction4_1271(ObjectContainerBase _enclosing, object obj, bool committed
+				, IActivationDepth depth)
+			{
+				this._enclosing = _enclosing;
+				this.obj = obj;
+				this.committed = committed;
+				this.depth = depth;
+			}
+
+			public object Apply(object trans)
+			{
+				trans = this._enclosing.CheckTransaction(((Transaction)trans));
+				ObjectReference @ref = ((Transaction)trans).ReferenceForObject(obj);
+				trans = committed ? this._enclosing._systemTransaction : ((Transaction)trans);
+				object cloned = null;
+				if (@ref != null)
+				{
+					cloned = this._enclosing.PeekPersisted(((Transaction)trans), @ref.GetID(), depth, 
+						true);
+				}
+				return cloned;
+			}
+
+			private readonly ObjectContainerBase _enclosing;
+
+			private readonly object obj;
+
+			private readonly bool committed;
+
+			private readonly IActivationDepth depth;
+		}
+
+		public object PeekPersisted(Transaction trans, int id, IActivationDepth depth, bool
+			 resetJustPeeked)
+		{
+			if (resetJustPeeked)
+			{
+				_justPeeked = null;
+			}
+			else
+			{
+				TreeInt ti = new TreeInt(id);
+				TreeIntObject tio = (TreeIntObject)Tree.Find(_justPeeked, ti);
+				if (tio != null)
+				{
+					return tio._object;
+				}
+			}
+			ObjectReference @ref = PeekReference(trans, id, depth, resetJustPeeked);
+			return @ref.GetObject();
+		}
+
+		public virtual ObjectReference PeekReference(Transaction trans, int id, IActivationDepth
+			 depth, bool resetJustPeeked)
+		{
+			ObjectReference @ref = new ObjectReference(id);
+			@ref.PeekPersisted(trans, depth);
+			if (resetJustPeeked)
+			{
+				_justPeeked = null;
+			}
+			return @ref;
+		}
+
+		internal virtual void Peeked(int id, object obj)
+		{
+			_justPeeked = Tree.Add(_justPeeked, new TreeIntObject(id, obj));
+		}
+
+		public virtual void Purge()
+		{
+			lock (_lock)
+			{
+				CheckClosed();
+				Runtime.Gc();
+				Runtime.RunFinalization();
+				Runtime.Gc();
+				Gc();
+				_classCollection.Purge();
+			}
+		}
+
+		public void Purge(Transaction trans, object obj)
+		{
+			lock (_lock)
+			{
+				trans = CheckTransaction(trans);
+				trans.RemoveObjectFromReferenceSystem(obj);
+			}
+		}
+
+		internal void RemoveFromAllReferenceSystems(object obj)
+		{
+			if (obj == null)
+			{
+				return;
+			}
+			if (obj is ObjectReference)
+			{
+				_referenceSystemRegistry.RemoveReference((ObjectReference)obj);
+				return;
+			}
+			_referenceSystemRegistry.RemoveObject(obj);
+		}
+
+		public NativeQueryHandler GetNativeQueryHandler()
+		{
+			lock (_lock)
+			{
+				if (null == _nativeQueryHandler)
+				{
+					_nativeQueryHandler = new NativeQueryHandler(this);
+				}
+				return _nativeQueryHandler;
+			}
+		}
+
+		public IObjectSet Query(Transaction trans, Predicate predicate)
+		{
+			return Query(trans, predicate, (IQueryComparator)null);
+		}
+
+		public IObjectSet Query(Transaction trans, Predicate predicate, IQueryComparator 
+			comparator)
+		{
+			lock (_lock)
+			{
+				return GetNativeQueryHandler().Execute(Query(trans), predicate, comparator);
+			}
+		}
+
+		public IObjectSet Query(Transaction trans, Type clazz)
+		{
+			return QueryByExample(trans, clazz);
+		}
+
+		public IQuery Query(Transaction ta)
+		{
+			return new QQuery(CheckTransaction(ta), null, null);
+		}
+
+		public abstract void RaiseCommitTimestamp(long minimumTimestamp);
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public abstract void ReadBytes(byte[] a_bytes, int a_address, int a_length);
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public abstract void ReadBytes(byte[] bytes, int address, int addressOffset, int 
+			length);
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public ByteArrayBuffer DecryptedBufferByAddress(int address, int length)
+		{
+			ByteArrayBuffer reader = RawBufferByAddress(address, length);
+			_handlers.Decrypt(reader);
+			return reader;
+		}
+
+		public virtual ByteArrayBuffer RawBufferByAddress(int address, int length)
+		{
+			CheckAddress(address);
+			ByteArrayBuffer reader = new ByteArrayBuffer(length);
+			ReadBytes(reader._buffer, address, length);
+			return reader;
+		}
+
+		/// <exception cref="System.ArgumentException"></exception>
+		private void CheckAddress(int address)
+		{
+			if (address <= 0)
+			{
+				throw new ArgumentException("Invalid address offset: " + address);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public StatefulBuffer ReadWriterByAddress(Transaction a_trans, int address, int length
+			)
+		{
+			CheckAddress(address);
+			StatefulBuffer reader = CreateStatefulBuffer(a_trans, address, length);
+			reader.ReadEncrypt(this, address);
+			return reader;
+		}
+
+		public abstract StatefulBuffer ReadStatefulBufferById(Transaction trans, int id);
+
+		public abstract StatefulBuffer ReadStatefulBufferById(Transaction trans, int id, 
+			bool lastCommitted);
+
+		public abstract ByteArrayBuffer ReadBufferById(Transaction trans, int id);
+
+		public abstract ByteArrayBuffer ReadBufferById(Transaction trans, int id, bool lastCommitted
+			);
+
+		public abstract ByteArrayBuffer[] ReadSlotBuffers(Transaction trans, int[] ids);
+
+		private void Reboot()
+		{
+			Commit(null);
+			Close();
+			Open();
+		}
+
+		public virtual GenericReflector Reflector()
+		{
+			return _handlers._reflector;
+		}
+
+		public void Refresh(Transaction trans, object obj, int depth)
+		{
+			lock (_lock)
+			{
+				RefreshInternal(trans, obj, depth);
+			}
+		}
+
+		protected virtual void RefreshInternal(Transaction trans, object obj, int depth)
+		{
+			Activate(trans, obj, RefreshActivationDepth(depth));
+		}
+
+		private IActivationDepth RefreshActivationDepth(int depth)
+		{
+			return ActivationDepthProvider().ActivationDepth(depth, ActivationMode.Refresh);
+		}
+
+		public abstract void ReleaseSemaphore(string name);
+
+		public virtual void FlagAsHandled(ObjectReference @ref)
+		{
+			@ref.FlagAsHandled(_topLevelCallId);
+		}
+
+		internal virtual bool FlagForDelete(ObjectReference @ref)
+		{
+			if (@ref == null)
+			{
+				return false;
+			}
+			if (HandledInCurrentTopLevelCall(@ref))
+			{
+				return false;
+			}
+			@ref.FlagForDelete(_topLevelCallId);
+			return true;
+		}
+
+		public abstract void ReleaseSemaphores(Transaction ta);
+
+		internal virtual void Rename(Config4Impl config)
+		{
+			bool renamedOne = false;
+			if (config.Rename() != null)
+			{
+				renamedOne = ApplyRenames(config);
+			}
+			_classCollection.CheckChanges();
+			if (renamedOne)
+			{
+				Reboot();
+			}
+		}
+
+		protected virtual bool ApplyRenames(Config4Impl config)
+		{
+			bool renamed = false;
+			IEnumerator i = config.Rename().GetEnumerator();
+			while (i.MoveNext())
+			{
+				Rename ren = (Rename)i.Current;
+				if (AlreadyApplied(ren))
+				{
+					continue;
+				}
+				if (ApplyRename(ren))
+				{
+					renamed = true;
+				}
+			}
+			return renamed;
+		}
+
+		private bool ApplyRename(Rename ren)
+		{
+			if (ren.IsField())
+			{
+				return ApplyFieldRename(ren);
+			}
+			return ApplyClassRename(ren);
+		}
+
+		private bool ApplyClassRename(Rename ren)
+		{
+			ClassMetadata classToRename = _classCollection.GetClassMetadata(ren.rFrom);
+			if (classToRename == null)
+			{
+				return false;
+			}
+			ClassMetadata existing = _classCollection.GetClassMetadata(ren.rTo);
+			if (existing != null)
+			{
+				LogMsg(9, "class " + ren.rTo);
+				return false;
+			}
+			classToRename.SetName(ren.rTo);
+			CommitRenameFor(ren, classToRename);
+			return true;
+		}
+
+		private bool ApplyFieldRename(Rename ren)
+		{
+			ClassMetadata parentClass = _classCollection.GetClassMetadata(ren.rClass);
+			if (parentClass == null)
+			{
+				return false;
+			}
+			if (!parentClass.RenameField(ren.rFrom, ren.rTo))
+			{
+				return false;
+			}
+			CommitRenameFor(ren, parentClass);
+			return true;
+		}
+
+		private void CommitRenameFor(Rename rename, ClassMetadata classMetadata)
+		{
+			SetDirtyInSystemTransaction(classMetadata);
+			LogMsg(8, rename.rFrom + " to " + rename.rTo);
+			DeleteInverseRenames(rename);
+			// store the rename, so we only do it once
+			Store(SystemTransaction(), rename);
+		}
+
+		private void DeleteInverseRenames(Rename rename)
+		{
+			// delete all that rename from the new name
+			// to allow future backswitching
+			IObjectSet inverseRenames = QueryInverseRenames(rename);
+			while (inverseRenames.HasNext())
+			{
+				Delete(SystemTransaction(), inverseRenames.Next());
+			}
+		}
+
+		private IObjectSet QueryInverseRenames(Rename ren)
+		{
+			return QueryByExample(SystemTransaction(), Renames.ForInverseQBE(ren));
+		}
+
+		private bool AlreadyApplied(Rename ren)
+		{
+			return QueryByExample(SystemTransaction(), ren).Count != 0;
+		}
+
+		public bool HandledInCurrentTopLevelCall(ObjectReference @ref)
+		{
+			return @ref.IsFlaggedAsHandled(_topLevelCallId);
+		}
+
+		public abstract void Reserve(int byteCount);
+
+		public void Rollback(Transaction trans)
+		{
+			lock (_lock)
+			{
+				trans = CheckTransaction(trans);
+				CheckReadOnly();
+				Rollback1(trans);
+				trans.RollbackReferenceSystem();
+			}
+		}
+
+		public abstract void Rollback1(Transaction trans);
+
+		/// <param name="obj"></param>
+		public virtual void Send(object obj)
+		{
+			// TODO: implement
+			throw new NotSupportedException();
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		public void Store(Transaction trans, object obj)
+		{
+			Store(trans, obj, UpdateDepthProvider().Unspecified(NullModifiedObjectQuery.Instance
+				));
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		public int Store(Transaction trans, object obj, IUpdateDepth depth)
+		{
+			lock (_lock)
+			{
+				try
+				{
+					ShowInternalClasses(true);
+					return StoreInternal(trans, obj, depth, true);
+				}
+				finally
+				{
+					ShowInternalClasses(false);
+				}
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		public int StoreInternal(Transaction trans, object obj, bool checkJustSet)
+		{
+			return StoreInternal(trans, obj, UpdateDepthProvider().Unspecified(NullModifiedObjectQuery
+				.Instance), checkJustSet);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		public virtual int StoreInternal(Transaction trans, object obj, IUpdateDepth depth
+			, bool checkJustSet)
+		{
+			CheckReadOnly();
+			return (((int)AsTopLevelStore(new _IFunction4_1599(this, obj, depth, checkJustSet
+				), trans)));
+		}
+
+		private sealed class _IFunction4_1599 : IFunction4
+		{
+			public _IFunction4_1599(ObjectContainerBase _enclosing, object obj, IUpdateDepth 
+				depth, bool checkJustSet)
+			{
+				this._enclosing = _enclosing;
+				this.obj = obj;
+				this.depth = depth;
+				this.checkJustSet = checkJustSet;
+			}
+
+			public object Apply(object trans)
+			{
+				return this._enclosing.StoreAfterReplication(((Transaction)trans), obj, depth, checkJustSet
+					);
+			}
+
+			private readonly ObjectContainerBase _enclosing;
+
+			private readonly object obj;
+
+			private readonly IUpdateDepth depth;
+
+			private readonly bool checkJustSet;
+		}
+
+		public int StoreAfterReplication(Transaction trans, object obj, IUpdateDepth depth
+			, bool checkJust)
+		{
+			if (obj is IDb4oType)
+			{
+				IDb4oType db4oType = Db4oTypeStored(trans, obj);
+				if (db4oType != null)
+				{
+					return GetID(trans, db4oType);
+				}
+			}
+			return Store2(trans, obj, depth, checkJust);
+		}
+
+		public void StoreByNewReplication(IDb4oReplicationReferenceProvider referenceProvider
+			, object obj)
+		{
+			lock (_lock)
+			{
+				_replicationCallState = Const4.New;
+				_handlers._replicationReferenceProvider = referenceProvider;
+				try
+				{
+					Store2(CheckTransaction(), obj, UpdateDepthProvider().ForDepth(1), false);
+				}
+				finally
+				{
+					_replicationCallState = Const4.None;
+					_handlers._replicationReferenceProvider = null;
+				}
+			}
+		}
+
+		public virtual void CheckStillToSet()
+		{
+			List4 postponedStillToSet = null;
+			while (_stillToSet != null)
+			{
+				IEnumerator i = new Iterator4Impl(_stillToSet);
+				_stillToSet = null;
+				while (i.MoveNext())
+				{
+					ObjectContainerBase.PendingSet item = (ObjectContainerBase.PendingSet)i.Current;
+					ObjectReference @ref = item. at ref;
+					Transaction trans = item.transaction;
+					if (!@ref.ContinueSet(trans, item.depth))
+					{
+						postponedStillToSet = new List4(postponedStillToSet, item);
+					}
+				}
+			}
+			_stillToSet = postponedStillToSet;
+		}
+
+		internal virtual void NotStorable(IReflectClass claxx, object obj)
+		{
+			if (!ConfigImpl.ExceptionsOnNotStorable())
+			{
+				return;
+			}
+			if (claxx == null)
+			{
+				throw new ObjectNotStorableException(obj.ToString());
+			}
+			if (_handlers.IsTransient(claxx))
+			{
+				return;
+			}
+			throw new ObjectNotStorableException(claxx);
+		}
+
+		public int Store2(Transaction trans, object obj, IUpdateDepth updateDepth, bool checkJustSet
+			)
+		{
+			if (obj == null || (obj is ITransientClass))
+			{
+				return 0;
+			}
+			ObjectAnalyzer analyzer = new ObjectAnalyzer(this, obj);
+			analyzer.Analyze(trans);
+			if (analyzer.NotStorable())
+			{
+				return 0;
+			}
+			ObjectReference @ref = analyzer.ObjectReference();
+			if (@ref == null)
+			{
+				ClassMetadata classMetadata = analyzer.ClassMetadata();
+				if (!ObjectCanNew(trans, classMetadata, obj))
+				{
+					return 0;
+				}
+				@ref = new ObjectReference();
+				@ref.Store(trans, classMetadata, obj);
+				trans.AddNewReference(@ref);
+				if (obj is IDb4oTypeImpl)
+				{
+					((IDb4oTypeImpl)obj).SetTrans(trans);
+				}
+				if (ConfigImpl.MessageLevel() > Const4.State)
+				{
+					Message(string.Empty + @ref.GetID() + " new " + @ref.ClassMetadata().GetName());
+				}
+				FlagAsHandled(@ref);
+				StillToSet(trans, @ref, updateDepth);
+			}
+			else
+			{
+				if (@ref.IsFlaggedAsHandled(_topLevelCallId))
+				{
+					AssertNotInCallback();
+				}
+				if (CanUpdate())
+				{
+					if (checkJustSet)
+					{
+						if ((!@ref.IsNew()) && HandledInCurrentTopLevelCall(@ref))
+						{
+							return @ref.GetID();
+						}
+					}
+					if (updateDepth.SufficientDepth())
+					{
+						FlagAsHandled(@ref);
+						@ref.WriteUpdate(trans, updateDepth);
+					}
+				}
+			}
+			ProcessPendingClassUpdates();
+			return @ref.GetID();
+		}
+
+		private void AssertNotInCallback()
+		{
+			if (InCallback.Value())
+			{
+				throw new Db4oIllegalStateException("Objects must not be updated in callback");
+			}
+		}
+
+		private bool ObjectCanNew(Transaction transaction, ClassMetadata yc, object obj)
+		{
+			return Callbacks().ObjectCanNew(transaction, obj) && yc.DispatchEvent(transaction
+				, obj, EventDispatchers.CanNew);
+		}
+
+		public abstract void SetDirtyInSystemTransaction(PersistentBase a_object);
+
+		public abstract bool SetSemaphore(string name, int timeout);
+
+		public abstract bool SetSemaphore(Transaction trans, string name, int timeout);
+
+		public abstract void ReleaseSemaphore(Transaction trans, string name);
+
+		internal virtual void StringIO(LatinStringIO io)
+		{
+			_handlers.StringIO(io);
+		}
+
+		internal bool ShowInternalClasses()
+		{
+			return IsServer() || _showInternalClasses > 0;
+		}
+
+		/// <summary>
+		/// Objects implementing the "Internal4" marker interface are
+		/// not visible to queries, unless this flag is set to true.
+		/// </summary>
+		/// <remarks>
+		/// Objects implementing the "Internal4" marker interface are
+		/// not visible to queries, unless this flag is set to true.
+		/// The caller should reset the flag after the call.
+		/// </remarks>
+		public virtual void ShowInternalClasses(bool show)
+		{
+			lock (this)
+			{
+				if (show)
+				{
+					_showInternalClasses++;
+				}
+				else
+				{
+					_showInternalClasses--;
+				}
+				if (_showInternalClasses < 0)
+				{
+					_showInternalClasses = 0;
+				}
+			}
+		}
+
+		private bool StackIsSmall()
+		{
+			return _stackDepth < _maxStackDepth;
+		}
+
+		internal virtual bool StateMessages()
+		{
+			return true;
+		}
+
+		// overridden to do nothing in YapObjectCarrier
+		internal List4 StillTo1(Transaction trans, List4 still, object obj, IActivationDepth
+			 depth)
+		{
+			if (obj == null || !depth.RequiresActivation())
+			{
+				return still;
+			}
+			ObjectReference @ref = trans.ReferenceForObject(obj);
+			if (@ref != null)
+			{
+				if (HandledInCurrentTopLevelCall(@ref))
+				{
+					return still;
+				}
+				FlagAsHandled(@ref);
+				return new List4(still, new ObjectContainerBase.PendingActivation(@ref, depth));
+			}
+			IReflectClass clazz = ReflectorForObject(obj);
+			if (clazz.IsArray())
+			{
+				if (!clazz.GetComponentType().IsPrimitive())
+				{
+					IEnumerator arr = ArrayHandler.Iterator(clazz, obj);
+					while (arr.MoveNext())
+					{
+						object current = arr.Current;
+						if (current == null)
+						{
+							continue;
+						}
+						ClassMetadata classMetadata = ClassMetadataForObject(current);
+						still = StillTo1(trans, still, current, depth.Descend(classMetadata));
+					}
+				}
+				return still;
+			}
+			else
+			{
+				if (obj is Entry)
+				{
+					still = StillTo1(trans, still, ((Entry)obj).key, depth);
+					still = StillTo1(trans, still, ((Entry)obj).value, depth);
+				}
+				else
+				{
+					if (depth.Mode().IsDeactivate())
+					{
+						// Special handling to deactivate .net structs
+						ClassMetadata metadata = ClassMetadataForObject(obj);
+						if (metadata != null && metadata.IsStruct())
+						{
+							metadata.ForceDeactivation(trans, depth, obj);
+						}
+					}
+				}
+			}
+			return still;
+		}
+
+		public void StillToActivate(IActivationContext context)
+		{
+			// TODO: We don't want the simple classes to search the hc_tree
+			// Kick them out here.
+			//		if (a_object != null) {
+			//			Class clazz = a_object.getClass();
+			//			if(! clazz.isPrimitive()){
+			if (ProcessedByImmediateActivation(context))
+			{
+				return;
+			}
+			_stillToActivate = StillTo1(context.Transaction(), _stillToActivate, context.TargetObject
+				(), context.Depth());
+		}
+
+		private bool ProcessedByImmediateActivation(IActivationContext context)
+		{
+			if (!StackIsSmall())
+			{
+				return false;
+			}
+			if (!context.Depth().RequiresActivation())
+			{
+				return true;
+			}
+			ObjectReference @ref = context.Transaction().ReferenceForObject(context.TargetObject
+				());
+			if (@ref == null)
+			{
+				return false;
+			}
+			if (HandledInCurrentTopLevelCall(@ref))
+			{
+				return true;
+			}
+			FlagAsHandled(@ref);
+			IncStackDepth();
+			try
+			{
+				@ref.ActivateInternal(context);
+			}
+			finally
+			{
+				DecStackDepth();
+			}
+			return true;
+		}
+
+		private int DecStackDepth()
+		{
+			int i = _stackDepth--;
+			if (StackIsSmall() && !_handlingStackLimitPendings)
+			{
+				_handlingStackLimitPendings = true;
+				try
+				{
+					HandleStackLimitPendings();
+				}
+				finally
+				{
+					_handlingStackLimitPendings = false;
+				}
+			}
+			return i;
+		}
+
+		private void HandleStackLimitPendings()
+		{
+			CheckStillToSet();
+		}
+
+		//		activatePending();
+		//		deactivatePending();
+		private int IncStackDepth()
+		{
+			return _stackDepth++;
+		}
+
+		public void StillToDeactivate(Transaction trans, object a_object, IActivationDepth
+			 a_depth, bool a_forceUnknownDeactivate)
+		{
+			_stillToDeactivate = StillTo1(trans, _stillToDeactivate, a_object, a_depth);
+		}
+
+		internal class PendingSet
+		{
+			public readonly Transaction transaction;
+
+			public readonly ObjectReference @ref;
+
+			public readonly IUpdateDepth depth;
+
+			public PendingSet(Transaction transaction_, ObjectReference ref_, IUpdateDepth depth_
+				)
+			{
+				this.transaction = transaction_;
+				this. at ref = ref_;
+				this.depth = depth_;
+			}
+		}
+
+		internal virtual void StillToSet(Transaction transaction, ObjectReference @ref, IUpdateDepth
+			 updateDepth)
+		{
+			if (StackIsSmall())
+			{
+				if (@ref.ContinueSet(transaction, updateDepth))
+				{
+					return;
+				}
+			}
+			_stillToSet = new List4(_stillToSet, new ObjectContainerBase.PendingSet(transaction
+				, @ref, updateDepth));
+		}
+
+		protected void StopSession()
+		{
+			if (HasShutDownHook())
+			{
+				Platform4.RemoveShutDownHook(this);
+			}
+			_classCollection = null;
+			if (_references != null)
+			{
+				_references.Stop();
+			}
+			_systemTransaction = null;
+			_transaction = null;
+		}
+
+		public IStoredClass StoredClass(Transaction trans, object clazz)
+		{
+			lock (_lock)
+			{
+				trans = CheckTransaction(trans);
+				IReflectClass claxx = ReflectorUtils.ReflectClassFor(Reflector(), clazz);
+				if (claxx == null)
+				{
+					return null;
+				}
+				ClassMetadata classMetadata = ClassMetadataForReflectClass(claxx);
+				if (classMetadata == null)
+				{
+					return null;
+				}
+				return new StoredClassImpl(trans, classMetadata);
+			}
+		}
+
+		public virtual IStoredClass[] StoredClasses(Transaction trans)
+		{
+			lock (_lock)
+			{
+				trans = CheckTransaction(trans);
+				IStoredClass[] classMetadata = _classCollection.StoredClasses();
+				IStoredClass[] storedClasses = new IStoredClass[classMetadata.Length];
+				for (int i = 0; i < classMetadata.Length; i++)
+				{
+					storedClasses[i] = new StoredClassImpl(trans, (ClassMetadata)classMetadata[i]);
+				}
+				return storedClasses;
+			}
+		}
+
+		public virtual LatinStringIO StringIO()
+		{
+			return _handlers.StringIO();
+		}
+
+		public abstract ISystemInfo SystemInfo();
+
+		private void BeginTopLevelCall()
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.BeginTopLevelCall.Log();
+			}
+			GenerateCallIDOnTopLevel();
+			IncStackDepth();
+		}
+
+		private void EndTopLevelCall()
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.EndTopLevelCall.Log();
+			}
+			DecStackDepth();
+			GenerateCallIDOnTopLevel();
+		}
+
+		private void GenerateCallIDOnTopLevel()
+		{
+			if (_stackDepth == 0)
+			{
+				_topLevelCallId = _topLevelCallIdGenerator.Next();
+			}
+		}
+
+		public virtual int StackDepth()
+		{
+			return _stackDepth;
+		}
+
+		public virtual void StackDepth(int depth)
+		{
+			_stackDepth = depth;
+		}
+
+		public virtual int TopLevelCallId()
+		{
+			return _topLevelCallId;
+		}
+
+		public virtual void TopLevelCallId(int id)
+		{
+			_topLevelCallId = id;
+		}
+
+		public virtual long Version()
+		{
+			lock (_lock)
+			{
+				return CurrentVersion();
+			}
+		}
+
+		public abstract void Shutdown();
+
+		public abstract void WriteDirtyClassMetadata();
+
+		public abstract void WriteNew(Transaction trans, Pointer4 pointer, ClassMetadata 
+			classMetadata, ByteArrayBuffer buffer);
+
+		public abstract void WriteUpdate(Transaction trans, Pointer4 pointer, ClassMetadata
+			 classMetadata, ArrayType arrayType, ByteArrayBuffer buffer);
+
+		public virtual ICallbacks Callbacks()
+		{
+			return _callbacks;
+		}
+
+		public virtual void Callbacks(ICallbacks cb)
+		{
+			if (cb == null)
+			{
+				throw new ArgumentException();
+			}
+			_callbacks = cb;
+		}
+
+		public virtual Config4Impl ConfigImpl
+		{
+			get
+			{
+				return _config;
+			}
+		}
+
+		public virtual UUIDFieldMetadata UUIDIndex()
+		{
+			return _handlers.Indexes()._uUID;
+		}
+
+		public virtual VersionFieldMetadata VersionIndex()
+		{
+			return _handlers.Indexes()._version;
+		}
+
+		public virtual CommitTimestampFieldMetadata CommitTimestampIndex()
+		{
+			return _handlers.Indexes()._commitTimestamp;
+		}
+
+		public virtual ClassMetadataRepository ClassCollection()
+		{
+			return _classCollection;
+		}
+
+		public abstract long[] GetIDsForClass(Transaction trans, ClassMetadata clazz);
+
+		public abstract IQueryResult ClassOnlyQuery(QQueryBase queryBase, ClassMetadata clazz
+			);
+
+		public abstract IQueryResult ExecuteQuery(QQuery query);
+
+		public virtual void ReplicationCallState(int state)
+		{
+			_replicationCallState = state;
+		}
+
+		public virtual ReferenceSystemRegistry ReferenceSystemRegistry()
+		{
+			return _referenceSystemRegistry;
+		}
+
+		public virtual ObjectContainerBase Container
+		{
+			get
+			{
+				return this;
+			}
+		}
+
+		public virtual void DeleteByID(Transaction transaction, int id, int cascadeDeleteDepth
+			)
+		{
+			if (id <= 0)
+			{
+				throw new ArgumentException("ID: " + id);
+			}
+			//			return;
+			if (cascadeDeleteDepth <= 0)
+			{
+				return;
+			}
+			object obj = GetByID2(transaction, id);
+			if (obj == null)
+			{
+				return;
+			}
+			cascadeDeleteDepth--;
+			IReflectClass claxx = ReflectorForObject(obj);
+			if (claxx.IsCollection())
+			{
+				cascadeDeleteDepth += 1;
+			}
+			ObjectReference @ref = transaction.ReferenceForId(id);
+			if (@ref == null)
+			{
+				return;
+			}
+			Delete2(transaction, @ref, obj, cascadeDeleteDepth, false);
+		}
+
+		internal virtual IReflectClass ReflectorForObject(object obj)
+		{
+			return Reflector().ForObject(obj);
+		}
+
+		public virtual object SyncExec(IClosure4 block)
+		{
+			lock (_lock)
+			{
+				CheckClosed();
+				return block.Run();
+			}
+		}
+
+		public virtual void StoreAll(Transaction transaction, IEnumerator objects)
+		{
+			while (objects.MoveNext())
+			{
+				Store(transaction, objects.Current);
+			}
+		}
+
+		public virtual void StoreAll(Transaction transaction, IEnumerator objects, IUpdateDepth
+			 depth)
+		{
+			while (objects.MoveNext())
+			{
+				Store(transaction, objects.Current, depth);
+			}
+		}
+
+		public virtual void WithTransaction(Transaction transaction, IRunnable runnable)
+		{
+			lock (_lock)
+			{
+				Transaction old = _transaction;
+				_transaction = transaction;
+				try
+				{
+					runnable.Run();
+				}
+				finally
+				{
+					_transaction = old;
+				}
+			}
+		}
+
+		public virtual IThreadPool4 ThreadPool()
+		{
+			return ((IThreadPool4)Environment().Provide(typeof(IThreadPool4)));
+		}
+
+		public virtual object NewWeakReference(ObjectReference referent, object obj)
+		{
+			return _references.NewWeakReference(referent, obj);
+		}
+
+		public sealed override string ToString()
+		{
+			if (_name != null)
+			{
+				return _name;
+			}
+			return DefaultToString();
+		}
+
+		protected abstract string DefaultToString();
+
+		public abstract bool IsDeleted(Transaction trans, int id);
+
+		public abstract void BlockSize(int size);
+
+		public virtual IBlockConverter BlockConverter()
+		{
+			return _blockConverter;
+		}
+
+		protected virtual void CreateBlockConverter(int blockSize)
+		{
+			if (blockSize == 1)
+			{
+				_blockConverter = new DisabledBlockConverter();
+			}
+			else
+			{
+				_blockConverter = new BlockSizeBlockConverter(blockSize);
+			}
+		}
+
+		public virtual IUpdateDepthProvider UpdateDepthProvider()
+		{
+			return ConfigImpl.UpdateDepthProvider();
+		}
+
+		public virtual void ReplaceClassMetadataRepository(ClassMetadataRepository repository
+			)
+		{
+			_classCollection = repository;
+		}
+
+		public long GenerateTransactionTimestamp(long forcedTimestamp)
+		{
+			lock (Lock())
+			{
+				return CheckTransaction().GenerateTransactionTimestamp(forcedTimestamp);
+			}
+		}
+
+		public void UseDefaultTransactionTimestamp()
+		{
+			lock (Lock())
+			{
+				CheckTransaction().UseDefaultTransactionTimestamp();
+			}
+		}
+
+		public abstract void Activate(object arg1, int arg2);
+
+		public abstract void Commit();
+
+		public abstract void Deactivate(object arg1, int arg2);
+
+		public abstract void Delete(object arg1);
+
+		public abstract IExtObjectContainer Ext();
+
+		public abstract IQuery Query();
+
+		public abstract IObjectSet Query(Type arg1);
+
+		public abstract IObjectSet Query(Predicate arg1);
+
+		public abstract IObjectSet Query(Predicate arg1, IQueryComparator arg2);
+
+		public abstract IObjectSet QueryByExample(object arg1);
+
+		public abstract void Rollback();
+
+		public abstract void Store(object arg1);
+
+		public abstract void Activate(object arg1);
+
+		public abstract void Backup(IStorage arg1, string arg2);
+
+		public abstract void Bind(object arg1, long arg2);
+
+		public abstract void Deactivate(object arg1);
+
+		public abstract object Descend(object arg1, string[] arg2);
+
+		public abstract object GetByID(long arg1);
+
+		public abstract object GetByUUID(Db4oUUID arg1);
+
+		public abstract long GetID(object arg1);
+
+		public abstract IObjectInfo GetObjectInfo(object arg1);
+
+		public abstract Db4oDatabase Identity();
+
+		public abstract bool IsActive(object arg1);
+
+		public abstract bool IsCached(long arg1);
+
+		public abstract bool IsStored(object arg1);
+
+		public abstract IObjectContainer OpenSession();
+
+		public abstract object PeekPersisted(object arg1, int arg2, bool arg3);
+
+		public abstract void Purge(object arg1);
+
+		public abstract void Refresh(object arg1, int arg2);
+
+		public abstract void Store(object arg1, int arg2);
+
+		public abstract IStoredClass StoredClass(object arg1);
+
+		public abstract IStoredClass[] StoredClasses();
+
+		public abstract int InstanceCount(ClassMetadata arg1, Transaction arg2);
+
+		public abstract EventRegistryImpl NewEventRegistry();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectContainerFactory.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectContainerFactory.cs
new file mode 100644
index 0000000..4361abe
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectContainerFactory.cs
@@ -0,0 +1,30 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Config;
+
+namespace Db4objects.Db4o.Internal
+{
+	public class ObjectContainerFactory
+	{
+		/// <exception cref="Db4objects.Db4o.Ext.OldFormatException"></exception>
+		public static IEmbeddedObjectContainer OpenObjectContainer(IEmbeddedConfiguration
+			 config, string databaseFileName)
+		{
+			IConfiguration legacyConfig = Db4oLegacyConfigurationBridge.AsLegacy(config);
+			Config4Impl.AssertIsNotTainted(legacyConfig);
+			EmitDebugInfo();
+			IEmbeddedObjectContainer oc = new IoAdaptedObjectContainer(legacyConfig, databaseFileName
+				);
+			((EmbeddedConfigurationImpl)config).ApplyConfigurationItems(oc);
+			Db4objects.Db4o.Internal.Messages.LogMsg(legacyConfig, 5, databaseFileName);
+			return oc;
+		}
+
+		private static void EmitDebugInfo()
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectContainerSession.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectContainerSession.cs
new file mode 100644
index 0000000..e36b8ce
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectContainerSession.cs
@@ -0,0 +1,605 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Callbacks;
+using Db4objects.Db4o.Internal.Events;
+using Db4objects.Db4o.Internal.Qlin;
+using Db4objects.Db4o.Internal.Query;
+using Db4objects.Db4o.Qlin;
+using Db4objects.Db4o.Query;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Generic;
+using Db4objects.Db4o.Types;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public partial class ObjectContainerSession : IInternalObjectContainer, ITransientClass
+		, IObjectContainerSpec
+	{
+		protected readonly ObjectContainerBase _server;
+
+		protected readonly Db4objects.Db4o.Internal.Transaction _transaction;
+
+		private bool _closed = false;
+
+		public ObjectContainerSession(ObjectContainerBase server, Db4objects.Db4o.Internal.Transaction
+			 trans)
+		{
+			_server = server;
+			_transaction = trans;
+		}
+
+		public ObjectContainerSession(ObjectContainerBase server) : this(server, server.NewUserTransaction
+			())
+		{
+			_transaction.SetOutSideRepresentation(this);
+		}
+
+		/// <param name="path"></param>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="System.NotSupportedException"></exception>
+		public virtual void Backup(string path)
+		{
+			throw new NotSupportedException();
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="System.NotSupportedException"></exception>
+		public virtual void Backup(IStorage storage, string path)
+		{
+			throw new NotSupportedException();
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.InvalidIDException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public virtual void Bind(object obj, long id)
+		{
+			_server.Bind(_transaction, obj, id);
+		}
+
+		public virtual Config4Impl ConfigImpl
+		{
+			get
+			{
+				// internal interface method doesn't need to lock
+				return _server.ConfigImpl;
+			}
+		}
+
+		public virtual IConfiguration Configure()
+		{
+			// FIXME: Consider throwing NotSupportedException here.
+			// throw new NotSupportedException();
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.Configure();
+			}
+		}
+
+		public virtual object Descend(object obj, string[] path)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.Descend(_transaction, obj, path);
+			}
+		}
+
+		private void CheckClosed()
+		{
+			if (IsClosed())
+			{
+				throw new DatabaseClosedException();
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.InvalidIDException"></exception>
+		public virtual object GetByID(long id)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.GetByID(_transaction, id);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual object GetByUUID(Db4oUUID uuid)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.GetByUUID(_transaction, uuid);
+			}
+		}
+
+		public virtual long GetID(object obj)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.GetID(_transaction, obj);
+			}
+		}
+
+		public virtual IObjectInfo GetObjectInfo(object obj)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.GetObjectInfo(_transaction, obj);
+			}
+		}
+
+		// TODO: Db4oDatabase is shared between embedded clients.
+		// This should work, since there is an automatic bind
+		// replacement. Replication test cases will tell.
+		public virtual Db4oDatabase Identity()
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.Identity();
+			}
+		}
+
+		public virtual bool IsActive(object obj)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.IsActive(_transaction, obj);
+			}
+		}
+
+		public virtual bool IsCached(long id)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.IsCached(_transaction, id);
+			}
+		}
+
+		public virtual bool IsClosed()
+		{
+			lock (Lock())
+			{
+				return _closed == true;
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public virtual bool IsStored(object obj)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.IsStored(_transaction, obj);
+			}
+		}
+
+		public virtual IReflectClass[] KnownClasses()
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.KnownClasses();
+			}
+		}
+
+		public virtual object Lock()
+		{
+			return _server.Lock();
+		}
+
+		public virtual object PeekPersisted(object @object, int depth, bool committed)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.PeekPersisted(_transaction, @object, ActivationDepthProvider().ActivationDepth
+					(depth, ActivationMode.Peek), committed);
+			}
+		}
+
+		public virtual void Purge()
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				_server.Purge();
+			}
+		}
+
+		public virtual void Purge(object obj)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				_server.Purge(_transaction, obj);
+			}
+		}
+
+		public virtual GenericReflector Reflector()
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.Reflector();
+			}
+		}
+
+		public virtual void Refresh(object obj, int depth)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				_server.Refresh(_transaction, obj, depth);
+			}
+		}
+
+		public virtual void ReleaseSemaphore(string name)
+		{
+			CheckClosed();
+			_server.ReleaseSemaphore(_transaction, name);
+		}
+
+		public virtual void Store(object obj, int depth)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				_server.Store(_transaction, obj, (depth == Const4.Unspecified ? (IUpdateDepth)UpdateDepthProvider
+					().Unspecified(NullModifiedObjectQuery.Instance) : (IUpdateDepth)UpdateDepthProvider
+					().ForDepth(depth)));
+			}
+		}
+
+		public virtual bool SetSemaphore(string name, int waitForAvailability)
+		{
+			CheckClosed();
+			return _server.SetSemaphore(_transaction, name, waitForAvailability);
+		}
+
+		public virtual IStoredClass StoredClass(object clazz)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.StoredClass(_transaction, clazz);
+			}
+		}
+
+		public virtual IStoredClass[] StoredClasses()
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.StoredClasses(_transaction);
+			}
+		}
+
+		public virtual ISystemInfo SystemInfo()
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.SystemInfo();
+			}
+		}
+
+		public virtual long Version()
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.Version();
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public virtual void Activate(object obj)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				_server.Activate(_transaction, obj);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public virtual void Activate(object obj, int depth)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				_server.Activate(_transaction, obj, ActivationDepthProvider().ActivationDepth(depth
+					, ActivationMode.Activate));
+			}
+		}
+
+		private IActivationDepthProvider ActivationDepthProvider()
+		{
+			return _server.ActivationDepthProvider();
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual bool Close()
+		{
+			lock (Lock())
+			{
+				if (IsClosed())
+				{
+					return false;
+				}
+				if (!_server.IsClosed())
+				{
+					if (!_server.ConfigImpl.IsReadOnly())
+					{
+						Commit();
+					}
+				}
+				_server.Callbacks().CloseOnStarted(this);
+				_server.CloseTransaction(_transaction, false, false);
+				_closed = true;
+				return true;
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		/// <exception cref="Db4objects.Db4o.Constraints.UniqueFieldValueConstraintViolationException
+		/// 	"></exception>
+		public virtual void Commit()
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				_server.Commit(_transaction);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public virtual void Deactivate(object obj, int depth)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				_server.Deactivate(_transaction, obj, depth);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public virtual void Deactivate(object obj)
+		{
+			Deactivate(obj, 1);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		public virtual void Delete(object obj)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				_server.Delete(_transaction, obj);
+			}
+		}
+
+		public virtual IExtObjectContainer Ext()
+		{
+			return (IExtObjectContainer)this;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public virtual IObjectSet QueryByExample(object template)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.QueryByExample(_transaction, template);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public virtual IQuery Query()
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.Query(_transaction);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public virtual IObjectSet Query(Type clazz)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.Query(_transaction, clazz);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public virtual IObjectSet Query(Predicate predicate)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.Query(_transaction, predicate);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		public virtual IObjectSet Query(Predicate predicate, IQueryComparator comparator)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.Query(_transaction, predicate, comparator);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		public virtual void Rollback()
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				_server.Rollback(_transaction);
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		public virtual void Store(object obj)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				_server.Store(_transaction, obj);
+			}
+		}
+
+		public virtual ObjectContainerBase Container
+		{
+			get
+			{
+				return _server;
+			}
+		}
+
+		public virtual Db4objects.Db4o.Internal.Transaction Transaction
+		{
+			get
+			{
+				return _transaction;
+			}
+		}
+
+		public virtual void Callbacks(ICallbacks cb)
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				_server.Callbacks(cb);
+			}
+		}
+
+		public virtual ICallbacks Callbacks()
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.Callbacks();
+			}
+		}
+
+		public NativeQueryHandler GetNativeQueryHandler()
+		{
+			lock (Lock())
+			{
+				CheckClosed();
+				return _server.GetNativeQueryHandler();
+			}
+		}
+
+		public virtual ClassMetadata ClassMetadataForReflectClass(IReflectClass reflectClass
+			)
+		{
+			return _server.ClassMetadataForReflectClass(reflectClass);
+		}
+
+		public virtual ClassMetadata ClassMetadataForName(string name)
+		{
+			return _server.ClassMetadataForName(name);
+		}
+
+		public virtual ClassMetadata ClassMetadataForID(int id)
+		{
+			return _server.ClassMetadataForID(id);
+		}
+
+		public virtual HandlerRegistry Handlers
+		{
+			get
+			{
+				return _server.Handlers;
+			}
+		}
+
+		public virtual object SyncExec(IClosure4 block)
+		{
+			return _server.SyncExec(block);
+		}
+
+		public virtual int InstanceCount(ClassMetadata clazz, Db4objects.Db4o.Internal.Transaction
+			 trans)
+		{
+			return _server.InstanceCount(clazz, trans);
+		}
+
+		public virtual bool IsClient
+		{
+			get
+			{
+				return true;
+			}
+		}
+
+		public virtual void StoreAll(Db4objects.Db4o.Internal.Transaction transaction, IEnumerator
+			 objects)
+		{
+			_server.StoreAll(transaction, objects);
+		}
+
+		public virtual IUpdateDepthProvider UpdateDepthProvider()
+		{
+			return ConfigImpl.UpdateDepthProvider();
+		}
+
+		public virtual IObjectContainer OpenSession()
+		{
+			lock (Lock())
+			{
+				return new Db4objects.Db4o.Internal.ObjectContainerSession(_server);
+			}
+		}
+
+		public virtual EventRegistryImpl NewEventRegistry()
+		{
+			return new EventRegistryImpl();
+		}
+
+		public virtual IQLin From(Type clazz)
+		{
+			return new QLinRoot(Query(), clazz);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectID.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectID.cs
new file mode 100644
index 0000000..8e1bfba
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectID.cs
@@ -0,0 +1,80 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Marshall;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class ObjectID
+	{
+		public readonly int _id;
+
+		private sealed class _ObjectID_15 : Db4objects.Db4o.Internal.ObjectID
+		{
+			public _ObjectID_15(int baseArg1) : base(baseArg1)
+			{
+			}
+
+			public override string ToString()
+			{
+				return "ObjectID.IS_NULL";
+			}
+		}
+
+		public static readonly Db4objects.Db4o.Internal.ObjectID IsNull = new _ObjectID_15
+			(-1);
+
+		private sealed class _ObjectID_21 : Db4objects.Db4o.Internal.ObjectID
+		{
+			public _ObjectID_21(int baseArg1) : base(baseArg1)
+			{
+			}
+
+			public override string ToString()
+			{
+				return "ObjectID.NOT_POSSIBLE";
+			}
+		}
+
+		public static readonly Db4objects.Db4o.Internal.ObjectID NotPossible = new _ObjectID_21
+			(-2);
+
+		private sealed class _ObjectID_27 : Db4objects.Db4o.Internal.ObjectID
+		{
+			public _ObjectID_27(int baseArg1) : base(baseArg1)
+			{
+			}
+
+			public override string ToString()
+			{
+				return "ObjectID.IGNORE";
+			}
+		}
+
+		public static readonly Db4objects.Db4o.Internal.ObjectID Ignore = new _ObjectID_27
+			(-3);
+
+		public ObjectID(int id)
+		{
+			_id = id;
+		}
+
+		public virtual bool IsValid()
+		{
+			return _id > 0;
+		}
+
+		public static Db4objects.Db4o.Internal.ObjectID Read(IInternalReadContext context
+			)
+		{
+			int id = context.ReadInt();
+			return id == 0 ? Db4objects.Db4o.Internal.ObjectID.IsNull : new Db4objects.Db4o.Internal.ObjectID
+				(id);
+		}
+
+		public override string ToString()
+		{
+			return "ObjectID(" + _id + ")";
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectInfoCollectionImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectInfoCollectionImpl.cs
new file mode 100644
index 0000000..7eb1827
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectInfoCollectionImpl.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public sealed class ObjectInfoCollectionImpl : IObjectInfoCollection
+	{
+		public static readonly IObjectInfoCollection Empty = new Db4objects.Db4o.Internal.ObjectInfoCollectionImpl
+			(Iterators.EmptyIterable);
+
+		public IEnumerable _collection;
+
+		public ObjectInfoCollectionImpl(IEnumerable collection)
+		{
+			_collection = collection;
+		}
+
+		public IEnumerator GetEnumerator()
+		{
+			return _collection.GetEnumerator();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectReference.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectReference.cs
new file mode 100644
index 0000000..f8065e2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectReference.cs
@@ -0,0 +1,1103 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Activation;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+using Sharpen;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <summary>A weak reference to an known object.</summary>
+	/// <remarks>
+	/// A weak reference to an known object.
+	/// "Known" ~ has been stored and/or retrieved within a transaction.
+	/// References the corresponding ClassMetaData along with further metadata:
+	/// internal id, UUID/version information, ...
+	/// </remarks>
+	/// <exclude></exclude>
+	public class ObjectReference : Identifiable, IObjectInfo, IActivator
+	{
+		private Db4objects.Db4o.Internal.ClassMetadata _class;
+
+		private object _object;
+
+		private Db4objects.Db4o.Internal.VirtualAttributes _virtualAttributes;
+
+		private Db4objects.Db4o.Internal.ObjectReference _idPreceding;
+
+		private Db4objects.Db4o.Internal.ObjectReference _idSubsequent;
+
+		private int _idSize;
+
+		private Db4objects.Db4o.Internal.ObjectReference _hcPreceding;
+
+		private Db4objects.Db4o.Internal.ObjectReference _hcSubsequent;
+
+		private int _hcSize;
+
+		public int _hcHashcode;
+
+		private int _lastTopLevelCallId;
+
+		public ObjectReference()
+		{
+		}
+
+		public ObjectReference(int id)
+		{
+			// redundant hashCode
+			_id = id;
+			if (DTrace.enabled)
+			{
+				DTrace.ObjectReferenceCreated.Log(id);
+			}
+		}
+
+		public ObjectReference(Db4objects.Db4o.Internal.ClassMetadata classMetadata, int 
+			id) : this(id)
+		{
+			_class = classMetadata;
+		}
+
+		public virtual void Activate(ActivationPurpose purpose)
+		{
+			ActivateOn(Container().Transaction, purpose);
+		}
+
+		public virtual void ActivateOn(Db4objects.Db4o.Internal.Transaction transaction, 
+			ActivationPurpose purpose)
+		{
+			if (Activating())
+			{
+				return;
+			}
+			try
+			{
+				Activating(true);
+				ObjectContainerBase container = transaction.Container();
+				if (!(container.ActivationDepthProvider() is ITransparentActivationDepthProvider))
+				{
+					return;
+				}
+				ITransparentActivationDepthProvider provider = (ITransparentActivationDepthProvider
+					)container.ActivationDepthProvider();
+				if (ActivationPurpose.Write == purpose)
+				{
+					lock (container.Lock())
+					{
+						provider.AddModified(GetObject(), transaction);
+					}
+				}
+				if (IsActive())
+				{
+					return;
+				}
+				lock (container.Lock())
+				{
+					Activate(transaction, GetObject(), new DescendingActivationDepth(provider, ActivationMode
+						.Activate));
+				}
+			}
+			finally
+			{
+				Activating(false);
+			}
+		}
+
+		private bool Activating()
+		{
+			return BitIsTrue(Const4.Activating);
+		}
+
+		private void Activating(bool isActivating)
+		{
+			if (isActivating)
+			{
+				BitTrue(Const4.Activating);
+			}
+			else
+			{
+				BitFalse(Const4.Activating);
+			}
+		}
+
+		public virtual void Activate(Db4objects.Db4o.Internal.Transaction ta, object obj, 
+			IActivationDepth depth)
+		{
+			ObjectContainerBase container = ta.Container();
+			ActivateInternal(container.ActivationContextFor(ta, obj, depth));
+			container.ActivatePending(ta);
+		}
+
+		internal virtual void ActivateInternal(IActivationContext context)
+		{
+			if (null == context)
+			{
+				throw new ArgumentNullException();
+			}
+			if (!context.Depth().RequiresActivation())
+			{
+				return;
+			}
+			ObjectContainerBase container = context.Container();
+			if (context.Depth().Mode().IsRefresh())
+			{
+				LogActivation(container, "refresh");
+			}
+			else
+			{
+				if (IsActive())
+				{
+					_class.CascadeActivation(context);
+					return;
+				}
+				LogActivation(container, "activate");
+			}
+			ReadForActivation(context);
+		}
+
+		private void ReadForActivation(IActivationContext context)
+		{
+			Read(context.Transaction(), null, context.TargetObject(), context.Depth(), Const4
+				.AddMembersToIdTreeOnly, false);
+		}
+
+		private void LogActivation(ObjectContainerBase container, string @event)
+		{
+			LogEvent(container, @event, Const4.Activation);
+		}
+
+		private void LogEvent(ObjectContainerBase container, string @event, int level)
+		{
+			if (container.ConfigImpl.MessageLevel() > level)
+			{
+				container.Message(string.Empty + GetID() + " " + @event + " " + _class.GetName());
+			}
+		}
+
+		/// <summary>return false if class not completely initialized, otherwise true</summary>
+		internal virtual bool ContinueSet(Db4objects.Db4o.Internal.Transaction trans, IUpdateDepth
+			 updateDepth)
+		{
+			if (!BitIsTrue(Const4.Continue))
+			{
+				return true;
+			}
+			if (!_class.StateOK())
+			{
+				return false;
+			}
+			if (!_class.AspectsAreInitialized())
+			{
+				return false;
+			}
+			if (DTrace.enabled)
+			{
+				DTrace.Continueset.Log(GetID());
+			}
+			BitFalse(Const4.Continue);
+			MarshallingContext context = new MarshallingContext(trans, this, updateDepth, true
+				);
+			Handlers4.Write(ClassMetadata().TypeHandler(), context, GetObject());
+			Pointer4 pointer = context.AllocateSlot();
+			ByteArrayBuffer buffer = context.ToWriteBuffer(pointer);
+			ObjectContainerBase container = trans.Container();
+			container.WriteNew(trans, pointer, _class, buffer);
+			object obj = _object;
+			ObjectOnNew(trans, obj);
+			if (_class.HasIdentity())
+			{
+				_object = container.NewWeakReference(this, obj);
+			}
+			SetStateClean();
+			EndProcessing();
+			return true;
+		}
+
+		private void ObjectOnNew(Db4objects.Db4o.Internal.Transaction transaction, object
+			 obj)
+		{
+			ObjectContainerBase container = transaction.Container();
+			container.Callbacks().ObjectOnNew(transaction, this);
+			_class.DispatchEvent(transaction, obj, EventDispatchers.New);
+		}
+
+		public virtual void Deactivate(Db4objects.Db4o.Internal.Transaction trans, IActivationDepth
+			 depth)
+		{
+			if (!depth.RequiresActivation())
+			{
+				return;
+			}
+			object obj = GetObject();
+			if (obj == null)
+			{
+				return;
+			}
+			ObjectContainerBase container = trans.Container();
+			LogActivation(container, "deactivate");
+			SetStateDeactivated();
+			_class.Deactivate(trans, this, depth);
+		}
+
+		public virtual byte GetIdentifier()
+		{
+			return Const4.Yapobject;
+		}
+
+		public virtual long GetInternalID()
+		{
+			return GetID();
+		}
+
+		public virtual object GetObject()
+		{
+			if (Platform4.HasWeakReferences())
+			{
+				return Platform4.GetYapRefObject(_object);
+			}
+			return _object;
+		}
+
+		public virtual object GetObjectReference()
+		{
+			return _object;
+		}
+
+		public virtual ObjectContainerBase Container()
+		{
+			if (_class == null)
+			{
+				throw new InvalidOperationException();
+			}
+			return _class.Container();
+		}
+
+		public virtual Db4objects.Db4o.Internal.Transaction Transaction()
+		{
+			return Container().Transaction;
+		}
+
+		public virtual Db4oUUID GetUUID()
+		{
+			Db4objects.Db4o.Internal.VirtualAttributes va = VirtualAttributes(Transaction());
+			if (va != null && va.i_database != null)
+			{
+				return new Db4oUUID(va.i_uuid, va.i_database.i_signature);
+			}
+			return null;
+		}
+
+		public virtual long GetVersion()
+		{
+			return GetCommitTimestamp();
+		}
+
+		public virtual long GetCommitTimestamp()
+		{
+			lock (Container().Lock())
+			{
+				return Container().SystemTransaction().VersionForId(GetID());
+			}
+		}
+
+		public Db4objects.Db4o.Internal.ClassMetadata ClassMetadata()
+		{
+			return _class;
+		}
+
+		public virtual void ClassMetadata(Db4objects.Db4o.Internal.ClassMetadata classMetadata
+			)
+		{
+			if (_class == classMetadata)
+			{
+				return;
+			}
+			if (_class != null)
+			{
+				throw new InvalidOperationException("Object types aren't supposed to change!");
+			}
+			_class = classMetadata;
+		}
+
+		public virtual int OwnLength()
+		{
+			throw Exceptions4.ShouldNeverBeCalled();
+		}
+
+		public virtual Db4objects.Db4o.Internal.VirtualAttributes ProduceVirtualAttributes
+			()
+		{
+			if (_virtualAttributes == null)
+			{
+				_virtualAttributes = new Db4objects.Db4o.Internal.VirtualAttributes();
+			}
+			return _virtualAttributes;
+		}
+
+		internal void PeekPersisted(Db4objects.Db4o.Internal.Transaction trans, IActivationDepth
+			 depth)
+		{
+			SetObject(Read(trans, depth, Const4.Transient, false));
+		}
+
+		internal object Read(Db4objects.Db4o.Internal.Transaction trans, IActivationDepth
+			 instantiationDepth, int addToIDTree, bool checkIDTree)
+		{
+			return Read(trans, null, null, instantiationDepth, addToIDTree, checkIDTree);
+		}
+
+		public object Read(Db4objects.Db4o.Internal.Transaction trans, ByteArrayBuffer buffer
+			, object obj, IActivationDepth instantiationDepth, int addToIDTree, bool checkIDTree
+			)
+		{
+			UnmarshallingContext context = new UnmarshallingContext(trans, buffer, this, addToIDTree
+				, checkIDTree);
+			context.PersistentObject(obj);
+			context.ActivationDepth(instantiationDepth);
+			return context.Read();
+		}
+
+		public virtual object ReadPrefetch(Db4objects.Db4o.Internal.Transaction trans, ByteArrayBuffer
+			 buffer, int addToIDTree)
+		{
+			UnmarshallingContext context = new UnmarshallingContext(trans, buffer, this, addToIDTree
+				, false);
+			context.ActivationDepth(new FixedActivationDepth(1, ActivationMode.Prefetch));
+			return context.Read();
+		}
+
+		public void ReadThis(Db4objects.Db4o.Internal.Transaction trans, ByteArrayBuffer 
+			buffer)
+		{
+		}
+
+		public virtual void SetObjectWeak(ObjectContainerBase container, object obj)
+		{
+			if (_object != null)
+			{
+				Platform4.KillYapRef(_object);
+			}
+			_object = container.NewWeakReference(this, obj);
+		}
+
+		public virtual void SetObject(object obj)
+		{
+			_object = obj;
+		}
+
+		internal void Store(Db4objects.Db4o.Internal.Transaction trans, Db4objects.Db4o.Internal.ClassMetadata
+			 classMetadata, object obj)
+		{
+			_object = obj;
+			_class = classMetadata;
+			int id = trans.Container().IdForNewUserObject(trans);
+			SetID(id);
+			// will be ended in continueset()
+			BeginProcessing();
+			BitTrue(Const4.Continue);
+		}
+
+		public virtual void FlagForDelete(int callId)
+		{
+			_lastTopLevelCallId = -callId;
+		}
+
+		public virtual bool IsFlaggedForDelete()
+		{
+			return _lastTopLevelCallId < 0;
+		}
+
+		public virtual void FlagAsHandled(int callId)
+		{
+			_lastTopLevelCallId = callId;
+		}
+
+		public bool IsFlaggedAsHandled(int callID)
+		{
+			return _lastTopLevelCallId == callID;
+		}
+
+		public bool IsValid()
+		{
+			return IsValidId(GetID()) && GetObject() != null;
+		}
+
+		public static bool IsValidId(int id)
+		{
+			return id > 0;
+		}
+
+		public virtual Db4objects.Db4o.Internal.VirtualAttributes VirtualAttributes()
+		{
+			return _virtualAttributes;
+		}
+
+		public virtual Db4objects.Db4o.Internal.VirtualAttributes VirtualAttributes(Db4objects.Db4o.Internal.Transaction
+			 trans, bool lastCommitted)
+		{
+			if (trans == null)
+			{
+				return _virtualAttributes;
+			}
+			lock (trans.Container().Lock())
+			{
+				if (_virtualAttributes == null)
+				{
+					if (_class.HasVirtualAttributes())
+					{
+						_virtualAttributes = new Db4objects.Db4o.Internal.VirtualAttributes();
+						_class.ReadVirtualAttributes(trans, this, lastCommitted);
+					}
+				}
+				else
+				{
+					if (!_virtualAttributes.SuppliesUUID())
+					{
+						if (_class.HasVirtualAttributes())
+						{
+							_class.ReadVirtualAttributes(trans, this, lastCommitted);
+						}
+					}
+				}
+				return _virtualAttributes;
+			}
+		}
+
+		public virtual Db4objects.Db4o.Internal.VirtualAttributes VirtualAttributes(Db4objects.Db4o.Internal.Transaction
+			 trans)
+		{
+			return VirtualAttributes(trans, false);
+		}
+
+		public virtual void SetVirtualAttributes(Db4objects.Db4o.Internal.VirtualAttributes
+			 at)
+		{
+			_virtualAttributes = at;
+		}
+
+		public virtual void WriteThis(Db4objects.Db4o.Internal.Transaction trans, ByteArrayBuffer
+			 buffer)
+		{
+		}
+
+		public virtual void WriteUpdate(Db4objects.Db4o.Internal.Transaction transaction, 
+			IUpdateDepth updatedepth)
+		{
+			ContinueSet(transaction, updatedepth);
+			// make sure, a concurrent new, possibly triggered by objectOnNew
+			// is written to the file
+			// preventing recursive
+			if (!BeginProcessing())
+			{
+				return;
+			}
+			object obj = GetObject();
+			if (!ObjectCanUpdate(transaction, obj) || !IsActive() || obj == null || !ClassMetadata
+				().IsModified(obj))
+			{
+				EndProcessing();
+				return;
+			}
+			MarshallingContext context = new MarshallingContext(transaction, this, updatedepth
+				, false);
+			if (context.UpdateDepth().Negative())
+			{
+				EndProcessing();
+				return;
+			}
+			ObjectContainerBase container = transaction.Container();
+			LogEvent(container, "update", Const4.State);
+			SetStateClean();
+			context.PurgeFieldIndexEntriesOnUpdate(transaction, container._handlers.ArrayType
+				(obj));
+			Handlers4.Write(_class.TypeHandler(), context, obj);
+			if (context.UpdateDepth().CanSkip(this))
+			{
+				EndProcessing();
+				return;
+			}
+			Pointer4 pointer = context.AllocateSlot();
+			ByteArrayBuffer buffer = context.ToWriteBuffer(pointer);
+			container.WriteUpdate(transaction, pointer, _class, container._handlers.ArrayType
+				(obj), buffer);
+			if (IsActive())
+			{
+				SetStateClean();
+			}
+			EndProcessing();
+			container.Callbacks().ObjectOnUpdate(transaction, this);
+			ClassMetadata().DispatchEvent(transaction, obj, EventDispatchers.Update);
+		}
+
+		protected virtual bool ObjectCanUpdate(Db4objects.Db4o.Internal.Transaction transaction
+			, object obj)
+		{
+			ObjectContainerBase container = transaction.Container();
+			return container.Callbacks().ObjectCanUpdate(transaction, this) && _class.DispatchEvent
+				(transaction, obj, EventDispatchers.CanUpdate);
+		}
+
+		public virtual void Ref_init()
+		{
+			Hc_init();
+			Id_init();
+		}
+
+		/// <summary>HCTREE</summary>
+		public virtual Db4objects.Db4o.Internal.ObjectReference Hc_add(Db4objects.Db4o.Internal.ObjectReference
+			 newRef)
+		{
+			if (newRef.GetObject() == null)
+			{
+				return this;
+			}
+			newRef.Hc_init();
+			return Hc_add1(newRef);
+		}
+
+		private void Hc_init()
+		{
+			_hcPreceding = null;
+			_hcSubsequent = null;
+			_hcSize = 1;
+			_hcHashcode = Hc_getCode(GetObject());
+		}
+
+		private Db4objects.Db4o.Internal.ObjectReference Hc_add1(Db4objects.Db4o.Internal.ObjectReference
+			 newRef)
+		{
+			int cmp = Hc_compare(newRef);
+			if (cmp < 0)
+			{
+				if (_hcPreceding == null)
+				{
+					_hcPreceding = newRef;
+					_hcSize++;
+				}
+				else
+				{
+					_hcPreceding = _hcPreceding.Hc_add1(newRef);
+					if (_hcSubsequent == null)
+					{
+						return Hc_rotateRight();
+					}
+					return Hc_balance();
+				}
+			}
+			else
+			{
+				if (_hcSubsequent == null)
+				{
+					_hcSubsequent = newRef;
+					_hcSize++;
+				}
+				else
+				{
+					_hcSubsequent = _hcSubsequent.Hc_add1(newRef);
+					if (_hcPreceding == null)
+					{
+						return Hc_rotateLeft();
+					}
+					return Hc_balance();
+				}
+			}
+			return this;
+		}
+
+		private Db4objects.Db4o.Internal.ObjectReference Hc_balance()
+		{
+			int cmp = _hcSubsequent._hcSize - _hcPreceding._hcSize;
+			if (cmp < -2)
+			{
+				return Hc_rotateRight();
+			}
+			else
+			{
+				if (cmp > 2)
+				{
+					return Hc_rotateLeft();
+				}
+				else
+				{
+					_hcSize = _hcPreceding._hcSize + _hcSubsequent._hcSize + 1;
+					return this;
+				}
+			}
+		}
+
+		private void Hc_calculateSize()
+		{
+			if (_hcPreceding == null)
+			{
+				if (_hcSubsequent == null)
+				{
+					_hcSize = 1;
+				}
+				else
+				{
+					_hcSize = _hcSubsequent._hcSize + 1;
+				}
+			}
+			else
+			{
+				if (_hcSubsequent == null)
+				{
+					_hcSize = _hcPreceding._hcSize + 1;
+				}
+				else
+				{
+					_hcSize = _hcPreceding._hcSize + _hcSubsequent._hcSize + 1;
+				}
+			}
+		}
+
+		private int Hc_compare(Db4objects.Db4o.Internal.ObjectReference toRef)
+		{
+			int cmp = toRef._hcHashcode - _hcHashcode;
+			if (cmp == 0)
+			{
+				cmp = toRef._id - _id;
+			}
+			return cmp;
+		}
+
+		public virtual Db4objects.Db4o.Internal.ObjectReference Hc_find(object obj)
+		{
+			return Hc_find(Hc_getCode(obj), obj);
+		}
+
+		private Db4objects.Db4o.Internal.ObjectReference Hc_find(int id, object obj)
+		{
+			int cmp = id - _hcHashcode;
+			if (cmp < 0)
+			{
+				if (_hcPreceding != null)
+				{
+					return _hcPreceding.Hc_find(id, obj);
+				}
+			}
+			else
+			{
+				if (cmp > 0)
+				{
+					if (_hcSubsequent != null)
+					{
+						return _hcSubsequent.Hc_find(id, obj);
+					}
+				}
+				else
+				{
+					if (obj == GetObject())
+					{
+						return this;
+					}
+					if (_hcPreceding != null)
+					{
+						Db4objects.Db4o.Internal.ObjectReference inPreceding = _hcPreceding.Hc_find(id, obj
+							);
+						if (inPreceding != null)
+						{
+							return inPreceding;
+						}
+					}
+					if (_hcSubsequent != null)
+					{
+						return _hcSubsequent.Hc_find(id, obj);
+					}
+				}
+			}
+			return null;
+		}
+
+		public static int Hc_getCode(object obj)
+		{
+			int hcode = Runtime.IdentityHashCode(obj);
+			if (hcode < 0)
+			{
+				hcode = ~hcode;
+			}
+			return hcode;
+		}
+
+		private Db4objects.Db4o.Internal.ObjectReference Hc_rotateLeft()
+		{
+			Db4objects.Db4o.Internal.ObjectReference tree = _hcSubsequent;
+			_hcSubsequent = tree._hcPreceding;
+			Hc_calculateSize();
+			tree._hcPreceding = this;
+			if (tree._hcSubsequent == null)
+			{
+				tree._hcSize = 1 + _hcSize;
+			}
+			else
+			{
+				tree._hcSize = 1 + _hcSize + tree._hcSubsequent._hcSize;
+			}
+			return tree;
+		}
+
+		private Db4objects.Db4o.Internal.ObjectReference Hc_rotateRight()
+		{
+			Db4objects.Db4o.Internal.ObjectReference tree = _hcPreceding;
+			_hcPreceding = tree._hcSubsequent;
+			Hc_calculateSize();
+			tree._hcSubsequent = this;
+			if (tree._hcPreceding == null)
+			{
+				tree._hcSize = 1 + _hcSize;
+			}
+			else
+			{
+				tree._hcSize = 1 + _hcSize + tree._hcPreceding._hcSize;
+			}
+			return tree;
+		}
+
+		private Db4objects.Db4o.Internal.ObjectReference Hc_rotateSmallestUp()
+		{
+			if (_hcPreceding != null)
+			{
+				_hcPreceding = _hcPreceding.Hc_rotateSmallestUp();
+				return Hc_rotateRight();
+			}
+			return this;
+		}
+
+		public virtual Db4objects.Db4o.Internal.ObjectReference Hc_remove(Db4objects.Db4o.Internal.ObjectReference
+			 findRef)
+		{
+			if (this == findRef)
+			{
+				return Hc_remove();
+			}
+			int cmp = Hc_compare(findRef);
+			if (cmp <= 0)
+			{
+				if (_hcPreceding != null)
+				{
+					_hcPreceding = _hcPreceding.Hc_remove(findRef);
+				}
+			}
+			if (cmp >= 0)
+			{
+				if (_hcSubsequent != null)
+				{
+					_hcSubsequent = _hcSubsequent.Hc_remove(findRef);
+				}
+			}
+			Hc_calculateSize();
+			return this;
+		}
+
+		public virtual void Hc_traverse(IVisitor4 visitor)
+		{
+			if (_hcPreceding != null)
+			{
+				_hcPreceding.Hc_traverse(visitor);
+			}
+			if (_hcSubsequent != null)
+			{
+				_hcSubsequent.Hc_traverse(visitor);
+			}
+			// Traversing the leaves first allows to add ObjectReference 
+			// nodes to different ReferenceSystem trees during commit
+			visitor.Visit(this);
+		}
+
+		private Db4objects.Db4o.Internal.ObjectReference Hc_remove()
+		{
+			if (_hcSubsequent != null && _hcPreceding != null)
+			{
+				_hcSubsequent = _hcSubsequent.Hc_rotateSmallestUp();
+				_hcSubsequent._hcPreceding = _hcPreceding;
+				_hcSubsequent.Hc_calculateSize();
+				return _hcSubsequent;
+			}
+			if (_hcSubsequent != null)
+			{
+				return _hcSubsequent;
+			}
+			return _hcPreceding;
+		}
+
+		/// <summary>IDTREE</summary>
+		public virtual Db4objects.Db4o.Internal.ObjectReference Id_add(Db4objects.Db4o.Internal.ObjectReference
+			 newRef)
+		{
+			newRef.Id_init();
+			return Id_add1(newRef);
+		}
+
+		private void Id_init()
+		{
+			_idPreceding = null;
+			_idSubsequent = null;
+			_idSize = 1;
+		}
+
+		private Db4objects.Db4o.Internal.ObjectReference Id_add1(Db4objects.Db4o.Internal.ObjectReference
+			 newRef)
+		{
+			int cmp = newRef._id - _id;
+			if (cmp < 0)
+			{
+				if (_idPreceding == null)
+				{
+					_idPreceding = newRef;
+					_idSize++;
+				}
+				else
+				{
+					_idPreceding = _idPreceding.Id_add1(newRef);
+					if (_idSubsequent == null)
+					{
+						return Id_rotateRight();
+					}
+					return Id_balance();
+				}
+			}
+			else
+			{
+				if (cmp > 0)
+				{
+					if (_idSubsequent == null)
+					{
+						_idSubsequent = newRef;
+						_idSize++;
+					}
+					else
+					{
+						_idSubsequent = _idSubsequent.Id_add1(newRef);
+						if (_idPreceding == null)
+						{
+							return Id_rotateLeft();
+						}
+						return Id_balance();
+					}
+				}
+			}
+			return this;
+		}
+
+		private Db4objects.Db4o.Internal.ObjectReference Id_balance()
+		{
+			int cmp = _idSubsequent._idSize - _idPreceding._idSize;
+			if (cmp < -2)
+			{
+				return Id_rotateRight();
+			}
+			else
+			{
+				if (cmp > 2)
+				{
+					return Id_rotateLeft();
+				}
+				else
+				{
+					_idSize = _idPreceding._idSize + _idSubsequent._idSize + 1;
+					return this;
+				}
+			}
+		}
+
+		private void Id_calculateSize()
+		{
+			if (_idPreceding == null)
+			{
+				if (_idSubsequent == null)
+				{
+					_idSize = 1;
+				}
+				else
+				{
+					_idSize = _idSubsequent._idSize + 1;
+				}
+			}
+			else
+			{
+				if (_idSubsequent == null)
+				{
+					_idSize = _idPreceding._idSize + 1;
+				}
+				else
+				{
+					_idSize = _idPreceding._idSize + _idSubsequent._idSize + 1;
+				}
+			}
+		}
+
+		public virtual Db4objects.Db4o.Internal.ObjectReference Id_find(int id)
+		{
+			int cmp = id - _id;
+			if (cmp > 0)
+			{
+				if (_idSubsequent != null)
+				{
+					return _idSubsequent.Id_find(id);
+				}
+			}
+			else
+			{
+				if (cmp < 0)
+				{
+					if (_idPreceding != null)
+					{
+						return _idPreceding.Id_find(id);
+					}
+				}
+				else
+				{
+					return this;
+				}
+			}
+			return null;
+		}
+
+		private Db4objects.Db4o.Internal.ObjectReference Id_rotateLeft()
+		{
+			Db4objects.Db4o.Internal.ObjectReference tree = _idSubsequent;
+			_idSubsequent = tree._idPreceding;
+			Id_calculateSize();
+			tree._idPreceding = this;
+			if (tree._idSubsequent == null)
+			{
+				tree._idSize = _idSize + 1;
+			}
+			else
+			{
+				tree._idSize = _idSize + 1 + tree._idSubsequent._idSize;
+			}
+			return tree;
+		}
+
+		private Db4objects.Db4o.Internal.ObjectReference Id_rotateRight()
+		{
+			Db4objects.Db4o.Internal.ObjectReference tree = _idPreceding;
+			_idPreceding = tree._idSubsequent;
+			Id_calculateSize();
+			tree._idSubsequent = this;
+			if (tree._idPreceding == null)
+			{
+				tree._idSize = _idSize + 1;
+			}
+			else
+			{
+				tree._idSize = _idSize + 1 + tree._idPreceding._idSize;
+			}
+			return tree;
+		}
+
+		private Db4objects.Db4o.Internal.ObjectReference Id_rotateSmallestUp()
+		{
+			if (_idPreceding != null)
+			{
+				_idPreceding = _idPreceding.Id_rotateSmallestUp();
+				return Id_rotateRight();
+			}
+			return this;
+		}
+
+		public virtual Db4objects.Db4o.Internal.ObjectReference Id_remove(Db4objects.Db4o.Internal.ObjectReference
+			 @ref)
+		{
+			int cmp = @ref._id - _id;
+			if (cmp < 0)
+			{
+				if (_idPreceding != null)
+				{
+					_idPreceding = _idPreceding.Id_remove(@ref);
+				}
+			}
+			else
+			{
+				if (cmp > 0)
+				{
+					if (_idSubsequent != null)
+					{
+						_idSubsequent = _idSubsequent.Id_remove(@ref);
+					}
+				}
+				else
+				{
+					if (this == @ref)
+					{
+						return Id_remove();
+					}
+					return this;
+				}
+			}
+			Id_calculateSize();
+			return this;
+		}
+
+		private Db4objects.Db4o.Internal.ObjectReference Id_remove()
+		{
+			if (_idSubsequent != null && _idPreceding != null)
+			{
+				_idSubsequent = _idSubsequent.Id_rotateSmallestUp();
+				_idSubsequent._idPreceding = _idPreceding;
+				_idSubsequent.Id_calculateSize();
+				return _idSubsequent;
+			}
+			if (_idSubsequent != null)
+			{
+				return _idSubsequent;
+			}
+			return _idPreceding;
+		}
+
+		public override string ToString()
+		{
+			try
+			{
+				int id = GetID();
+				string str = "ObjectReference\nID=" + id;
+				object obj = GetObject();
+				if (obj == null && _class != null)
+				{
+					ObjectContainerBase container = _class.Container();
+					if (container != null && id > 0)
+					{
+						obj = container.PeekPersisted(container.Transaction, id, container.DefaultActivationDepth
+							(ClassMetadata()), true).ToString();
+					}
+				}
+				if (obj == null)
+				{
+					str += "\nfor [null]";
+				}
+				else
+				{
+					string objToString = string.Empty;
+					try
+					{
+						objToString = obj.ToString();
+					}
+					catch (Exception)
+					{
+					}
+					if (ClassMetadata() != null)
+					{
+						IReflectClass claxx = ClassMetadata().Reflector().ForObject(obj);
+						str += "\n" + claxx.GetName();
+					}
+					str += "\n" + objToString;
+				}
+				return str;
+			}
+			catch (Exception)
+			{
+			}
+			return "ObjectReference " + GetID();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectTypeMetadata.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectTypeMetadata.cs
new file mode 100644
index 0000000..c1b645b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ObjectTypeMetadata.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	public class ObjectTypeMetadata : PrimitiveTypeMetadata
+	{
+		public ObjectTypeMetadata(ObjectContainerBase container, ITypeHandler4 handler, int
+			 id, IReflectClass classReflector) : base(container, handler, id, classReflector
+			)
+		{
+		}
+
+		public override object Instantiate(UnmarshallingContext context)
+		{
+			object @object = new object();
+			OnInstantiate(context, @object);
+			return @object;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/OpenTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/OpenTypeHandler.cs
new file mode 100644
index 0000000..a455f75
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/OpenTypeHandler.cs
@@ -0,0 +1,393 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Handlers.Versions;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	public class OpenTypeHandler : IReferenceTypeHandler, IValueTypeHandler, IBuiltinTypeHandler
+		, ICascadingTypeHandler, ILinkLengthAware
+	{
+		private const int Hashcode = 1003303143;
+
+		private ObjectContainerBase _container;
+
+		public OpenTypeHandler(ObjectContainerBase container)
+		{
+			_container = container;
+		}
+
+		internal virtual ObjectContainerBase Container()
+		{
+			return _container;
+		}
+
+		public virtual IReflectClass ClassReflector()
+		{
+			return Container().Handlers.IclassObject;
+		}
+
+		public virtual void CascadeActivation(IActivationContext context)
+		{
+			object targetObject = context.TargetObject();
+			if (IsPlainObject(targetObject))
+			{
+				return;
+			}
+			ITypeHandler4 typeHandler = TypeHandlerForObject(targetObject);
+			Handlers4.CascadeActivation(context, typeHandler);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Delete(IDeleteContext context)
+		{
+			int payLoadOffset = context.ReadInt();
+			if (context.IsLegacyHandlerVersion())
+			{
+				context.DefragmentRecommended();
+				return;
+			}
+			if (payLoadOffset <= 0)
+			{
+				return;
+			}
+			int linkOffset = context.Offset();
+			context.Seek(payLoadOffset);
+			int classMetadataID = context.ReadInt();
+			ITypeHandler4 typeHandler = Container().ClassMetadataForID(classMetadataID).TypeHandler
+				();
+			if (typeHandler != null)
+			{
+				context.Delete(typeHandler);
+			}
+			context.Seek(linkOffset);
+		}
+
+		public virtual int GetID()
+		{
+			return Handlers4.UntypedId;
+		}
+
+		public virtual bool HasField(ObjectContainerBase a_stream, string a_path)
+		{
+			return a_stream.ClassCollection().FieldExists(a_path);
+		}
+
+		public virtual ITypeHandler4 ReadCandidateHandler(QueryingReadContext context)
+		{
+			int payLoadOffSet = context.ReadInt();
+			if (payLoadOffSet == 0)
+			{
+				return null;
+			}
+			context.Seek(payLoadOffSet);
+			int classMetadataID = context.ReadInt();
+			ClassMetadata classMetadata = context.Container().ClassMetadataForID(classMetadataID
+				);
+			if (classMetadata == null)
+			{
+				return null;
+			}
+			return classMetadata.ReadCandidateHandler(context);
+		}
+
+		public virtual ObjectID ReadObjectID(IInternalReadContext context)
+		{
+			int payloadOffset = context.ReadInt();
+			if (payloadOffset == 0)
+			{
+				return ObjectID.IsNull;
+			}
+			int savedOffset = context.Offset();
+			ITypeHandler4 typeHandler = ReadTypeHandler(context, payloadOffset);
+			if (typeHandler == null)
+			{
+				context.Seek(savedOffset);
+				return ObjectID.IsNull;
+			}
+			SeekSecondaryOffset(context, typeHandler);
+			if (typeHandler is IReadsObjectIds)
+			{
+				ObjectID readObjectID = ((IReadsObjectIds)typeHandler).ReadObjectID(context);
+				context.Seek(savedOffset);
+				return readObjectID;
+			}
+			context.Seek(savedOffset);
+			return ObjectID.NotPossible;
+		}
+
+		public virtual void Defragment(IDefragmentContext context)
+		{
+			int payLoadOffSet = context.ReadInt();
+			if (payLoadOffSet == 0)
+			{
+				return;
+			}
+			int savedOffSet = context.Offset();
+			context.Seek(payLoadOffSet);
+			try
+			{
+				int classMetadataId = context.CopyIDReturnOriginalID();
+				ITypeHandler4 typeHandler = CorrectTypeHandlerVersionFor(context, classMetadataId
+					);
+				if (typeHandler == null)
+				{
+					return;
+				}
+				SeekSecondaryOffset(context, typeHandler);
+				if (IsPlainObject(typeHandler))
+				{
+					context.Defragment(new PlainObjectHandler());
+				}
+				else
+				{
+					context.Defragment(typeHandler);
+				}
+			}
+			finally
+			{
+				context.Seek(savedOffSet);
+			}
+		}
+
+		protected virtual ITypeHandler4 CorrectTypeHandlerVersionFor(IDefragmentContext context
+			, int classMetadataId)
+		{
+			ITypeHandler4 typeHandler = context.TypeHandlerForId(classMetadataId);
+			if (null == typeHandler)
+			{
+				return null;
+			}
+			ClassMetadata classMetadata = Container(context).ClassMetadataForID(classMetadataId
+				);
+			return HandlerRegistry.CorrectHandlerVersion(context, typeHandler, classMetadata);
+		}
+
+		protected virtual ObjectContainerBase Container(IDefragmentContext context)
+		{
+			return context.Transaction().Container();
+		}
+
+		protected virtual ITypeHandler4 ReadTypeHandler(IInternalReadContext context, int
+			 payloadOffset)
+		{
+			context.Seek(payloadOffset);
+			ITypeHandler4 typeHandler = Container().TypeHandlerForClassMetadataID(context.ReadInt
+				());
+			return HandlerRegistry.CorrectHandlerVersion(context, typeHandler);
+		}
+
+		/// <param name="buffer"></param>
+		/// <param name="typeHandler"></param>
+		protected virtual void SeekSecondaryOffset(IReadBuffer buffer, ITypeHandler4 typeHandler
+			)
+		{
+		}
+
+		// do nothing, no longer needed in current implementation.
+		public virtual object Read(IReadContext readContext)
+		{
+			IInternalReadContext context = (IInternalReadContext)readContext;
+			int payloadOffset = context.ReadInt();
+			if (payloadOffset == 0)
+			{
+				context.NotifyNullReferenceSkipped();
+				return null;
+			}
+			int savedOffSet = context.Offset();
+			try
+			{
+				ITypeHandler4 typeHandler = ReadTypeHandler(context, payloadOffset);
+				if (typeHandler == null)
+				{
+					return null;
+				}
+				SeekSecondaryOffset(context, typeHandler);
+				if (IsPlainObject(typeHandler))
+				{
+					return context.ReadAtCurrentSeekPosition(new PlainObjectHandler());
+				}
+				return context.ReadAtCurrentSeekPosition(typeHandler);
+			}
+			finally
+			{
+				context.Seek(savedOffSet);
+			}
+		}
+
+		public virtual void Activate(IReferenceActivationContext context)
+		{
+		}
+
+		//    	throw new IllegalStateException();
+		public virtual void CollectIDs(QueryingReadContext readContext)
+		{
+			IInternalReadContext context = (IInternalReadContext)readContext;
+			int payloadOffset = context.ReadInt();
+			if (payloadOffset == 0)
+			{
+				return;
+			}
+			int savedOffSet = context.Offset();
+			try
+			{
+				ITypeHandler4 typeHandler = ReadTypeHandler(context, payloadOffset);
+				if (typeHandler == null)
+				{
+					return;
+				}
+				SeekSecondaryOffset(context, typeHandler);
+				if (IsPlainObject(typeHandler))
+				{
+					readContext.Collector().AddId(readContext.ReadInt());
+					return;
+				}
+				CollectIdContext collectIdContext = new _CollectIdContext_201(readContext, readContext
+					.Transaction(), readContext.Collector(), null, readContext.Buffer());
+				Handlers4.CollectIdsInternal(collectIdContext, context.Container().Handlers.CorrectHandlerVersion
+					(typeHandler, context.HandlerVersion()), 0, false);
+			}
+			finally
+			{
+				context.Seek(savedOffSet);
+			}
+		}
+
+		private sealed class _CollectIdContext_201 : CollectIdContext
+		{
+			public _CollectIdContext_201(QueryingReadContext readContext, Transaction baseArg1
+				, IdObjectCollector baseArg2, ObjectHeader baseArg3, IReadBuffer baseArg4) : base
+				(baseArg1, baseArg2, baseArg3, baseArg4)
+			{
+				this.readContext = readContext;
+			}
+
+			public override int HandlerVersion()
+			{
+				return readContext.HandlerVersion();
+			}
+
+			public override SlotFormat SlotFormat()
+			{
+				return new _SlotFormatCurrent_207();
+			}
+
+			private sealed class _SlotFormatCurrent_207 : SlotFormatCurrent
+			{
+				public _SlotFormatCurrent_207()
+				{
+				}
+
+				public override bool IsIndirectedWithinSlot(ITypeHandler4 handler)
+				{
+					return false;
+				}
+			}
+
+			private readonly QueryingReadContext readContext;
+		}
+
+		public virtual ITypeHandler4 ReadTypeHandlerRestoreOffset(IInternalReadContext context
+			)
+		{
+			int savedOffset = context.Offset();
+			int payloadOffset = context.ReadInt();
+			ITypeHandler4 typeHandler = payloadOffset == 0 ? null : ReadTypeHandler(context, 
+				payloadOffset);
+			context.Seek(savedOffset);
+			return typeHandler;
+		}
+
+		public virtual void Write(IWriteContext context, object obj)
+		{
+			if (obj == null)
+			{
+				context.WriteInt(0);
+				return;
+			}
+			MarshallingContext marshallingContext = (MarshallingContext)context;
+			ClassMetadata classMetadata = ClassMetadataFor(obj);
+			if (classMetadata == null)
+			{
+				context.WriteInt(0);
+				return;
+			}
+			MarshallingContextState state = marshallingContext.CurrentState();
+			marshallingContext.CreateChildBuffer(false);
+			context.WriteInt(classMetadata.GetID());
+			WriteObject(context, classMetadata.TypeHandler(), obj);
+			marshallingContext.RestoreState(state);
+		}
+
+		private ClassMetadata ClassMetadataFor(object obj)
+		{
+			return Container().ClassMetadataForObject(obj);
+		}
+
+		private void WriteObject(IWriteContext context, ITypeHandler4 typeHandler, object
+			 obj)
+		{
+			if (IsPlainObject(obj))
+			{
+				context.WriteObject(new PlainObjectHandler(), obj);
+				return;
+			}
+			if (Handlers4.UseDedicatedSlot(context, typeHandler))
+			{
+				context.WriteObject(obj);
+			}
+			else
+			{
+				typeHandler.Write(context, obj);
+			}
+		}
+
+		private bool IsPlainObject(object obj)
+		{
+			if (obj == null)
+			{
+				return false;
+			}
+			return obj.GetType() == Const4.ClassObject;
+		}
+
+		public static bool IsPlainObject(ITypeHandler4 typeHandler)
+		{
+			return typeHandler.GetType() == typeof(Db4objects.Db4o.Internal.OpenTypeHandler) 
+				|| typeHandler.GetType() == typeof(OpenTypeHandler0) || typeHandler.GetType() ==
+				 typeof(OpenTypeHandler2) || typeHandler.GetType() == typeof(OpenTypeHandler7);
+		}
+
+		public virtual ITypeHandler4 TypeHandlerForObject(object obj)
+		{
+			return ClassMetadataFor(obj).TypeHandler();
+		}
+
+		public override bool Equals(object obj)
+		{
+			return obj is Db4objects.Db4o.Internal.OpenTypeHandler && !(obj is InterfaceTypeHandler
+				);
+		}
+
+		public override int GetHashCode()
+		{
+			return Hashcode;
+		}
+
+		public virtual void RegisterReflector(IReflector reflector)
+		{
+		}
+
+		// nothing to do
+		public virtual int LinkLength()
+		{
+			return Const4.IdLength;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/PendingClassInits.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/PendingClassInits.cs
new file mode 100644
index 0000000..d9d8a88
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/PendingClassInits.cs
@@ -0,0 +1,104 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	internal class PendingClassInits
+	{
+		private readonly Transaction _systemTransaction;
+
+		private Collection4 _pending = new Collection4();
+
+		private IQueue4 _members = new NonblockingQueue();
+
+		private IQueue4 _statics = new NonblockingQueue();
+
+		private IQueue4 _writes = new NonblockingQueue();
+
+		private IQueue4 _inits = new NonblockingQueue();
+
+		private bool _running = false;
+
+		internal PendingClassInits(Transaction systemTransaction)
+		{
+			_systemTransaction = systemTransaction;
+		}
+
+		internal virtual void Process(ClassMetadata newClassMetadata)
+		{
+			if (_pending.Contains(newClassMetadata))
+			{
+				return;
+			}
+			ClassMetadata ancestor = newClassMetadata.GetAncestor();
+			if (ancestor != null)
+			{
+				Process(ancestor);
+			}
+			_pending.Add(newClassMetadata);
+			_members.Add(newClassMetadata);
+			if (_running)
+			{
+				return;
+			}
+			_running = true;
+			try
+			{
+				CheckInits();
+				_pending = new Collection4();
+			}
+			finally
+			{
+				_running = false;
+			}
+		}
+
+		private void InitializeAspects()
+		{
+			while (_members.HasNext())
+			{
+				ClassMetadata classMetadata = ((ClassMetadata)_members.Next());
+				classMetadata.InitializeAspects();
+				_statics.Add(classMetadata);
+			}
+		}
+
+		private void CheckStatics()
+		{
+			InitializeAspects();
+			while (_statics.HasNext())
+			{
+				ClassMetadata classMetadata = ((ClassMetadata)_statics.Next());
+				classMetadata.StoreStaticFieldValues(_systemTransaction, true);
+				_writes.Add(classMetadata);
+				InitializeAspects();
+			}
+		}
+
+		private void CheckWrites()
+		{
+			CheckStatics();
+			while (_writes.HasNext())
+			{
+				ClassMetadata classMetadata = ((ClassMetadata)_writes.Next());
+				classMetadata.SetStateDirty();
+				classMetadata.Write(_systemTransaction);
+				_inits.Add(classMetadata);
+				CheckStatics();
+			}
+		}
+
+		private void CheckInits()
+		{
+			CheckWrites();
+			while (_inits.HasNext())
+			{
+				ClassMetadata classMetadata = ((ClassMetadata)_inits.Next());
+				classMetadata.InitConfigOnUp(_systemTransaction);
+				CheckWrites();
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/PersistentBase.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/PersistentBase.cs
new file mode 100644
index 0000000..ec42038
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/PersistentBase.cs
@@ -0,0 +1,181 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public abstract class PersistentBase : Identifiable, IPersistent, ILinkLengthAware
+	{
+		internal virtual void CacheDirty(Collection4 col)
+		{
+			if (!BitIsTrue(Const4.CachedDirty))
+			{
+				BitTrue(Const4.CachedDirty);
+				col.Add(this);
+			}
+		}
+
+		public virtual void Free(LocalTransaction trans)
+		{
+			IdSystem(trans.SystemTransaction()).NotifySlotDeleted(GetID(), SlotChangeFactory(
+				));
+		}
+
+		public int LinkLength()
+		{
+			return Const4.IdLength;
+		}
+
+		internal void NotCachedDirty()
+		{
+			BitFalse(Const4.CachedDirty);
+		}
+
+		public virtual void Read(Transaction trans)
+		{
+			if (!BeginProcessing())
+			{
+				return;
+			}
+			try
+			{
+				Read(trans, ProduceReadBuffer(trans));
+			}
+			finally
+			{
+				EndProcessing();
+			}
+		}
+
+		protected virtual void Read(Transaction trans, ByteArrayBuffer reader)
+		{
+			ReadThis(trans, reader);
+			SetStateOnRead(reader);
+		}
+
+		protected ByteArrayBuffer ProduceReadBuffer(Transaction trans)
+		{
+			return ReadBufferById(trans);
+		}
+
+		protected virtual ByteArrayBuffer ReadBufferById(Transaction trans)
+		{
+			return trans.Container().ReadBufferById(trans, GetID());
+		}
+
+		internal virtual void SetStateOnRead(ByteArrayBuffer reader)
+		{
+			if (BitIsTrue(Const4.CachedDirty))
+			{
+				SetStateDirty();
+			}
+			else
+			{
+				SetStateClean();
+			}
+		}
+
+		public virtual void Write(Transaction trans)
+		{
+			if (!WriteObjectBegin())
+			{
+				return;
+			}
+			try
+			{
+				LocalObjectContainer container = (LocalObjectContainer)trans.Container();
+				if (DTrace.enabled)
+				{
+					DTrace.PersistentOwnLength.Log(GetID());
+				}
+				int length = OwnLength();
+				length = container.BlockConverter().BlockAlignedBytes(length);
+				Slot slot = container.AllocateSlot(length);
+				if (IsNew())
+				{
+					SetID(IdSystem(trans).NewId(SlotChangeFactory()));
+					IdSystem(trans).NotifySlotCreated(_id, slot, SlotChangeFactory());
+				}
+				else
+				{
+					IdSystem(trans).NotifySlotUpdated(_id, slot, SlotChangeFactory());
+				}
+				if (DTrace.enabled)
+				{
+					DTrace.PersistentBaseNewSlot.LogLength(GetID(), slot);
+				}
+				ByteArrayBuffer writer = ProduceWriteBuffer(trans, length);
+				WriteToFile(trans, writer, slot);
+			}
+			finally
+			{
+				EndProcessing();
+			}
+		}
+
+		public virtual ITransactionalIdSystem IdSystem(Transaction trans)
+		{
+			return trans.IdSystem();
+		}
+
+		protected virtual ByteArrayBuffer ProduceWriteBuffer(Transaction trans, int length
+			)
+		{
+			return NewWriteBuffer(length);
+		}
+
+		protected virtual ByteArrayBuffer NewWriteBuffer(int length)
+		{
+			return new ByteArrayBuffer(length);
+		}
+
+		private void WriteToFile(Transaction trans, ByteArrayBuffer writer, Slot slot)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.PersistentbaseWrite.Log(GetID());
+			}
+			LocalObjectContainer container = (LocalObjectContainer)trans.Container();
+			WriteThis(trans, writer);
+			container.WriteEncrypt(writer, slot.Address(), 0);
+			if (IsActive())
+			{
+				SetStateClean();
+			}
+		}
+
+		public virtual bool WriteObjectBegin()
+		{
+			if (IsDirty())
+			{
+				return BeginProcessing();
+			}
+			return false;
+		}
+
+		public virtual void WriteOwnID(Transaction trans, ByteArrayBuffer writer)
+		{
+			Write(trans);
+			writer.WriteInt(GetID());
+		}
+
+		public virtual Db4objects.Db4o.Internal.Slots.SlotChangeFactory SlotChangeFactory
+			()
+		{
+			return Db4objects.Db4o.Internal.Slots.SlotChangeFactory.SystemObjects;
+		}
+
+		public abstract byte GetIdentifier();
+
+		public abstract int OwnLength();
+
+		public abstract void ReadThis(Transaction arg1, ByteArrayBuffer arg2);
+
+		public abstract void WriteThis(Transaction arg1, ByteArrayBuffer arg2);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/PersistentIntegerArray.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/PersistentIntegerArray.cs
new file mode 100644
index 0000000..957c646
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/PersistentIntegerArray.cs
@@ -0,0 +1,76 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Ids;
+using Sharpen;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class PersistentIntegerArray : LocalPersistentBase
+	{
+		private readonly Db4objects.Db4o.Internal.Slots.SlotChangeFactory _slotChangeFactory;
+
+		private int[] _ints;
+
+		public PersistentIntegerArray(Db4objects.Db4o.Internal.Slots.SlotChangeFactory slotChangeFactory
+			, ITransactionalIdSystem idSystem, int[] arr) : base(idSystem)
+		{
+			_slotChangeFactory = slotChangeFactory;
+			_ints = new int[arr.Length];
+			System.Array.Copy(arr, 0, _ints, 0, arr.Length);
+		}
+
+		public PersistentIntegerArray(Db4objects.Db4o.Internal.Slots.SlotChangeFactory slotChangeFactory
+			, ITransactionalIdSystem idSystem, int id) : base(idSystem)
+		{
+			_slotChangeFactory = slotChangeFactory;
+			SetID(id);
+		}
+
+		public override byte GetIdentifier()
+		{
+			return Const4.IntegerArray;
+		}
+
+		public override int OwnLength()
+		{
+			return (Const4.IntLength * (Size() + 1)) + Const4.AddedLength;
+		}
+
+		public override void ReadThis(Transaction trans, ByteArrayBuffer reader)
+		{
+			int length = reader.ReadInt();
+			_ints = new int[length];
+			for (int i = 0; i < length; i++)
+			{
+				_ints[i] = reader.ReadInt();
+			}
+		}
+
+		public override void WriteThis(Transaction trans, ByteArrayBuffer writer)
+		{
+			writer.WriteInt(Size());
+			for (int i = 0; i < _ints.Length; i++)
+			{
+				writer.WriteInt(_ints[i]);
+			}
+		}
+
+		private int Size()
+		{
+			return _ints.Length;
+		}
+
+		public virtual int[] Array()
+		{
+			return _ints;
+		}
+
+		public override Db4objects.Db4o.Internal.Slots.SlotChangeFactory SlotChangeFactory
+			()
+		{
+			return _slotChangeFactory;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/PreparedArrayContainsComparison.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/PreparedArrayContainsComparison.cs
new file mode 100644
index 0000000..65eb3b1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/PreparedArrayContainsComparison.cs
@@ -0,0 +1,70 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers.Array;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class PreparedArrayContainsComparison : IPreparedComparison
+	{
+		private readonly ArrayHandler _arrayHandler;
+
+		private readonly IPreparedComparison _preparedComparison;
+
+		private ObjectContainerBase _container;
+
+		public PreparedArrayContainsComparison(IContext context, ArrayHandler arrayHandler
+			, ITypeHandler4 typeHandler, object obj)
+		{
+			_arrayHandler = arrayHandler;
+			_preparedComparison = Handlers4.PrepareComparisonFor(typeHandler, context, obj);
+			_container = context.Transaction().Container();
+		}
+
+		public virtual int CompareTo(object obj)
+		{
+			// We never expect this call
+			// TODO: The callers of this class should be refactored to pass a matcher and
+			//       to expect a PreparedArrayComparison.
+			throw new InvalidOperationException();
+		}
+
+		public virtual bool IsEqual(object array)
+		{
+			return IsMatch(array, IntMatcher.Zero);
+		}
+
+		public virtual bool IsGreaterThan(object array)
+		{
+			return IsMatch(array, IntMatcher.Positive);
+		}
+
+		public virtual bool IsSmallerThan(object array)
+		{
+			return IsMatch(array, IntMatcher.Negative);
+		}
+
+		private bool IsMatch(object array, IntMatcher matcher)
+		{
+			if (array == null)
+			{
+				return false;
+			}
+			IEnumerator i = _arrayHandler.AllElements(_container, array);
+			while (i.MoveNext())
+			{
+				if (matcher.Match(_preparedComparison.CompareTo(i.Current)))
+				{
+					return true;
+				}
+			}
+			return false;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/PrimitiveTypeMetadata.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/PrimitiveTypeMetadata.cs
new file mode 100644
index 0000000..27314c5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/PrimitiveTypeMetadata.cs
@@ -0,0 +1,236 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers.Array;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Metadata;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class PrimitiveTypeMetadata : ClassMetadata
+	{
+		private const int HashcodeForNull = 283636383;
+
+		public PrimitiveTypeMetadata(ObjectContainerBase container, ITypeHandler4 handler
+			, int id, IReflectClass classReflector) : base(container, classReflector)
+		{
+			_aspects = FieldMetadata.EmptyArray;
+			_typeHandler = handler;
+			_id = id;
+		}
+
+		public PrimitiveTypeMetadata(ObjectContainerBase container) : base(container)
+		{
+			_typeHandler = null;
+		}
+
+		public override void CascadeActivation(IActivationContext context)
+		{
+		}
+
+		// Override
+		// do nothing
+		internal sealed override void AddToIndex(Transaction trans, int id)
+		{
+		}
+
+		// Override
+		// Primitive Indices will be created later.
+		internal override bool AllowsQueries()
+		{
+			return false;
+		}
+
+		internal override void CacheDirty(Collection4 col)
+		{
+		}
+
+		// do nothing
+		public override bool DescendOnCascadingActivation()
+		{
+			return false;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public override void Delete(IDeleteContext context)
+		{
+			if (context.IsLegacyHandlerVersion())
+			{
+				context.ReadInt();
+				context.DefragmentRecommended();
+			}
+		}
+
+		internal override void DeleteMembers(DeleteContextImpl context, ArrayType arrayType
+			, bool isUpdate)
+		{
+			if (arrayType == ArrayType.PlainArray)
+			{
+				new ArrayHandler(TypeHandler(), true).DeletePrimitiveEmbedded((StatefulBuffer)context
+					.Buffer(), this);
+			}
+			else
+			{
+				if (arrayType == ArrayType.MultidimensionalArray)
+				{
+					new MultidimensionalArrayHandler(TypeHandler(), true).DeletePrimitiveEmbedded((StatefulBuffer
+						)context.Buffer(), this);
+				}
+			}
+		}
+
+		public override bool HasClassIndex()
+		{
+			return false;
+		}
+
+		public override object Instantiate(UnmarshallingContext context)
+		{
+			object obj = context.PersistentObject();
+			if (obj == null)
+			{
+				obj = context.Read(TypeHandler());
+				context.SetObjectWeak(obj);
+			}
+			context.SetStateClean();
+			return obj;
+		}
+
+		public override object InstantiateTransient(UnmarshallingContext context)
+		{
+			return Handlers4.ReadValueType(context, CorrectHandlerVersion(context));
+		}
+
+		internal override void InstantiateFields(UnmarshallingContext context)
+		{
+			throw new NotImplementedException();
+		}
+
+		public override bool IsArray()
+		{
+			return _id == Handlers4.AnyArrayId || _id == Handlers4.AnyArrayNId;
+		}
+
+		public override bool HasIdentity()
+		{
+			return false;
+		}
+
+		public override bool IsStronglyTyped()
+		{
+			return false;
+		}
+
+		public override IPreparedComparison PrepareComparison(IContext context, object source
+			)
+		{
+			return Handlers4.PrepareComparisonFor(TypeHandler(), context, source);
+		}
+
+		public override ITypeHandler4 ReadCandidateHandler(QueryingReadContext context)
+		{
+			if (IsArray())
+			{
+				return TypeHandler();
+			}
+			return null;
+		}
+
+		//	@Override
+		//    public ObjectID readObjectID(InternalReadContext context){
+		//        if(_handler instanceof ClassMetadata){
+		//            return ((ClassMetadata)_handler).readObjectID(context);
+		//        }
+		//        if(Handlers4.handlesArray(_handler)){
+		//            // TODO: Here we should theoretically read through the array and collect candidates.
+		//            // The respective construct is wild: "Contains query through an array in an array."
+		//            // Ignore for now.
+		//            return ObjectID.IGNORE;
+		//        }
+		//        return ObjectID.NOT_POSSIBLE;
+		//    }
+		internal override void RemoveFromIndex(Transaction ta, int id)
+		{
+		}
+
+		// do nothing
+		public sealed override bool WriteObjectBegin()
+		{
+			return false;
+		}
+
+		public override string ToString()
+		{
+			return GetType().FullName + "(" + TypeHandler() + ")";
+		}
+
+		public override void Defragment(IDefragmentContext context)
+		{
+			CorrectHandlerVersion(context).Defragment(context);
+		}
+
+		public override object WrapWithTransactionContext(Transaction transaction, object
+			 value)
+		{
+			return value;
+		}
+
+		public override ITypeHandler4 DelegateTypeHandler(IContext context)
+		{
+			return TypeHandler();
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (!(obj is Db4objects.Db4o.Internal.PrimitiveTypeMetadata))
+			{
+				return false;
+			}
+			Db4objects.Db4o.Internal.PrimitiveTypeMetadata other = (Db4objects.Db4o.Internal.PrimitiveTypeMetadata
+				)obj;
+			if (TypeHandler() == null)
+			{
+				return other.TypeHandler() == null;
+			}
+			return TypeHandler().Equals(other.TypeHandler());
+		}
+
+		public override int GetHashCode()
+		{
+			if (TypeHandler() == null)
+			{
+				return HashcodeForNull;
+			}
+			return TypeHandler().GetHashCode();
+		}
+
+		public virtual object DeepClone(object context)
+		{
+			throw new InvalidOperationException();
+		}
+
+		protected override IAspectTraversalStrategy DetectAspectTraversalStrategy()
+		{
+			return new _IAspectTraversalStrategy_178();
+		}
+
+		private sealed class _IAspectTraversalStrategy_178 : IAspectTraversalStrategy
+		{
+			public _IAspectTraversalStrategy_178()
+			{
+			}
+
+			public void TraverseAllAspects(ITraverseAspectCommand command)
+			{
+			}
+		}
+		// do nothing
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinConstraint.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinConstraint.cs
new file mode 100644
index 0000000..13354ab
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinConstraint.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Qlin;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Qlin
+{
+	/// <exclude></exclude>
+	public class QLinConstraint : QLinSubNode
+	{
+		private readonly IConstraint _constraint;
+
+		public QLinConstraint(QLinRoot root, IConstraint constraint) : base(root)
+		{
+			_constraint = constraint;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinField.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinField.cs
new file mode 100644
index 0000000..88cc2c0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinField.cs
@@ -0,0 +1,47 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Qlin;
+using Db4objects.Db4o.Qlin;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Qlin
+{
+	/// <exclude></exclude>
+	public class QLinField : QLinSubNode
+	{
+		private readonly IQuery _node;
+
+		public QLinField(QLinRoot root, object expression) : base(root)
+		{
+			_node = root.Descend(expression);
+		}
+
+		public override IQLin Equal(object obj)
+		{
+			IConstraint constraint = _node.Constrain(obj);
+			constraint.Equal();
+			return new QLinConstraint(((QLinRoot)_root), constraint);
+		}
+
+		public override IQLin StartsWith(string @string)
+		{
+			IConstraint constraint = _node.Constrain(@string);
+			constraint.StartsWith(true);
+			return new QLinConstraint(((QLinRoot)_root), constraint);
+		}
+
+		public override IQLin Smaller(object obj)
+		{
+			IConstraint constraint = _node.Constrain(obj);
+			constraint.Smaller();
+			return new QLinConstraint(((QLinRoot)_root), constraint);
+		}
+
+		public override IQLin Greater(object obj)
+		{
+			IConstraint constraint = _node.Constrain(obj);
+			constraint.Greater();
+			return new QLinConstraint(((QLinRoot)_root), constraint);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinNode.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinNode.cs
new file mode 100644
index 0000000..94c0b0c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinNode.cs
@@ -0,0 +1,73 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Qlin;
+
+namespace Db4objects.Db4o.Internal.Qlin
+{
+	/// <exclude></exclude>
+	public abstract class QLinNode : IQLin
+	{
+		public virtual IQLin Equal(object obj)
+		{
+			throw new QLinException("#equal() is not supported on this node");
+		}
+
+		public virtual IQLin StartsWith(string @string)
+		{
+			throw new QLinException("#startsWith() is not supported on this node");
+		}
+
+		public virtual IQLin Smaller(object obj)
+		{
+			throw new QLinException("#smaller() is not supported on this node");
+		}
+
+		public virtual IQLin Greater(object obj)
+		{
+			throw new QLinException("#greater() is not supported on this node");
+		}
+
+		public virtual object SingleOrDefault(object defaultValue)
+		{
+			IObjectSet collection = Select();
+			// TODO: Change to #isEmpty here after decafs, so the size doesn#t need to be calculated
+			if (collection.Count == 0)
+			{
+				return defaultValue;
+			}
+			if (collection.Count > 1)
+			{
+				// Consider: Use a more specific exception if a query does not return
+				//           the expected result
+				throw new QLinException("Expected one or none. Found: " + collection.Count);
+			}
+			// The following would be the right way to work against
+			// a collection but for now it won't decaf.
+			// return collection.iterator().next();
+			// This is the ugly old db4o interface, where a Collection is
+			// an iterator directly. For now it's convenient but we don't
+			// really want to use this in the future.
+			// Update #single() in the same way.
+			return collection.Next();
+		}
+
+		public virtual object Single()
+		{
+			IObjectSet collection = Select();
+			if (collection.Count != 1)
+			{
+				throw new QLinException("Expected exactly one. Found: " + collection.Count);
+			}
+			return collection.Next();
+		}
+
+		public abstract IQLin Limit(int arg1);
+
+		public abstract IQLin OrderBy(object arg1, QLinOrderByDirection arg2);
+
+		public abstract IObjectSet Select();
+
+		public abstract IQLin Where(object arg1);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinOrderBy.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinOrderBy.cs
new file mode 100644
index 0000000..ee27231
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinOrderBy.cs
@@ -0,0 +1,28 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Qlin;
+using Db4objects.Db4o.Qlin;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Qlin
+{
+	/// <exclude></exclude>
+	public class QLinOrderBy : QLinSubNode
+	{
+		private readonly IQuery _node;
+
+		public QLinOrderBy(QLinRoot root, object expression, QLinOrderByDirection direction
+			) : base(root)
+		{
+			_node = root.Descend(expression);
+			if (direction == QLinSupport.Ascending())
+			{
+				_node.OrderAscending();
+			}
+			else
+			{
+				_node.OrderDescending();
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinRoot.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinRoot.cs
new file mode 100644
index 0000000..636b023
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinRoot.cs
@@ -0,0 +1,77 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Qlin;
+using Db4objects.Db4o.Internal.Query;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Internal.Query.Result;
+using Db4objects.Db4o.Qlin;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Qlin
+{
+	/// <exclude></exclude>
+	public class QLinRoot : QLinSodaNode
+	{
+		private readonly QQuery _query;
+
+		private int _limit = -1;
+
+		public QLinRoot(IQuery query, Type clazz)
+		{
+			_query = (QQuery)query;
+			query.Constrain(clazz);
+			QLinSupport.Context(clazz);
+		}
+
+		public virtual IQuery Query()
+		{
+			return _query;
+		}
+
+		public override IObjectSet Select()
+		{
+			if (_limit == -1)
+			{
+				return _query.Execute();
+			}
+			IQueryResult queryResult = _query.GetQueryResult();
+			IdListQueryResult limitedResult = new IdListQueryResult(_query.Transaction(), _limit
+				);
+			int counter = 0;
+			IIntIterator4 i = queryResult.IterateIDs();
+			while (i.MoveNext())
+			{
+				if (counter++ >= _limit)
+				{
+					break;
+				}
+				limitedResult.Add(i.CurrentInt());
+			}
+			return new ObjectSetFacade(limitedResult);
+		}
+
+		public override IQLin Limit(int size)
+		{
+			if (size < 1)
+			{
+				throw new QLinException("Limit must be greater that 0");
+			}
+			_limit = size;
+			return this;
+		}
+
+		protected override Db4objects.Db4o.Internal.Qlin.QLinRoot Root()
+		{
+			return this;
+		}
+
+		internal virtual IQuery Descend(object expression)
+		{
+			// TODO: Implement deep descend
+			return Query().Descend(QLinSupport.Field(expression).GetName());
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinSodaNode.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinSodaNode.cs
new file mode 100644
index 0000000..64acd88
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinSodaNode.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Qlin;
+using Db4objects.Db4o.Qlin;
+
+namespace Db4objects.Db4o.Internal.Qlin
+{
+	/// <exclude></exclude>
+	public abstract class QLinSodaNode : QLinNode
+	{
+		protected abstract QLinRoot Root();
+
+		public override IQLin Where(object expression)
+		{
+			return new QLinField(Root(), expression);
+		}
+
+		public override IQLin OrderBy(object expression, QLinOrderByDirection direction)
+		{
+			return new QLinOrderBy(Root(), expression, direction);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinSubNode.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinSubNode.cs
new file mode 100644
index 0000000..f49927f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Qlin/QLinSubNode.cs
@@ -0,0 +1,41 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Internal.Qlin;
+using Db4objects.Db4o.Qlin;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Qlin
+{
+	/// <exclude></exclude>
+	public abstract class QLinSubNode : QLinSodaNode
+	{
+		protected readonly QLinRoot _root;
+
+		public QLinSubNode(QLinRoot root)
+		{
+			_root = root;
+		}
+
+		protected override QLinRoot Root()
+		{
+			return _root;
+		}
+
+		protected virtual IQuery Query()
+		{
+			return Root().Query();
+		}
+
+		public override IQLin Limit(int size)
+		{
+			Root().Limit(size);
+			return this;
+		}
+
+		public override IObjectSet Select()
+		{
+			return Root().Select();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/IDb4oEnhancedFilter.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/IDb4oEnhancedFilter.cs
new file mode 100644
index 0000000..21bb54b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/IDb4oEnhancedFilter.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Query
+{
+	/// <summary>FIXME: Rename to Db4oEnhancedPredicate</summary>
+	public interface IDb4oEnhancedFilter
+	{
+		void OptimizeQuery(IQuery query);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/IDb4oNQOptimizer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/IDb4oNQOptimizer.cs
new file mode 100644
index 0000000..265b112
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/IDb4oNQOptimizer.cs
@@ -0,0 +1,11 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Query
+{
+	public interface IDb4oNQOptimizer
+	{
+		object Optimize(IQuery query, Predicate filter);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/IDb4oQueryExecutionListener.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/IDb4oQueryExecutionListener.cs
new file mode 100644
index 0000000..717c58f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/IDb4oQueryExecutionListener.cs
@@ -0,0 +1,11 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Query;
+
+namespace Db4objects.Db4o.Internal.Query
+{
+	public interface IDb4oQueryExecutionListener
+	{
+		void NotifyQueryExecuted(NQOptimizationInfo info);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/NQOptimizationInfo.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/NQOptimizationInfo.cs
new file mode 100644
index 0000000..adec180
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/NQOptimizationInfo.cs
@@ -0,0 +1,41 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Query
+{
+	public class NQOptimizationInfo
+	{
+		private Db4objects.Db4o.Query.Predicate _predicate;
+
+		private string _message;
+
+		private object _optimized;
+
+		public NQOptimizationInfo(Db4objects.Db4o.Query.Predicate predicate, string message
+			, object optimized)
+		{
+			this._predicate = predicate;
+			this._message = message;
+			this._optimized = optimized;
+		}
+
+		public virtual string Message()
+		{
+			return _message;
+		}
+
+		public virtual object Optimized()
+		{
+			return _optimized;
+		}
+
+		public virtual Db4objects.Db4o.Query.Predicate Predicate()
+		{
+			return _predicate;
+		}
+
+		public override string ToString()
+		{
+			return Message() + "/" + Optimized();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/PredicateEvaluation.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/PredicateEvaluation.cs
new file mode 100644
index 0000000..9d82966
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/PredicateEvaluation.cs
@@ -0,0 +1,28 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Query
+{
+	/// <exclude></exclude>
+	[System.Serializable]
+	public class PredicateEvaluation : IEvaluation
+	{
+		public Predicate _predicate;
+
+		public PredicateEvaluation()
+		{
+		}
+
+		public PredicateEvaluation(Predicate predicate)
+		{
+			// CS
+			_predicate = predicate;
+		}
+
+		public virtual void Evaluate(ICandidate candidate)
+		{
+			candidate.Include(_predicate.AppliesTo(candidate.GetObject()));
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/IInternalQuery.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/IInternalQuery.cs
new file mode 100644
index 0000000..d1f98b5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/IInternalQuery.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <exclude></exclude>
+	public interface IInternalQuery
+	{
+		IInternalObjectContainer Container
+		{
+			get;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QCandidate.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QCandidate.cs
new file mode 100644
index 0000000..21edba2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QCandidate.cs
@@ -0,0 +1,830 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Handlers.Array;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Query;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <summary>Represents an actual object in the database.</summary>
+	/// <remarks>
+	/// Represents an actual object in the database. Forms a tree structure, indexed
+	/// by id. Can have dependents that are doNotInclude'd in the query result when
+	/// this is doNotInclude'd.
+	/// </remarks>
+	/// <exclude></exclude>
+	public class QCandidate : TreeInt, ICandidate
+	{
+		internal ByteArrayBuffer _bytes;
+
+		internal readonly QCandidates _candidates;
+
+		private List4 _dependants;
+
+		internal bool _include = true;
+
+		private object _member;
+
+		private Tree _pendingJoins;
+
+		private Db4objects.Db4o.Internal.Query.Processor.QCandidate _root;
+
+		private Db4objects.Db4o.Internal.ClassMetadata _classMetadata;
+
+		private FieldMetadata _fieldMetadata;
+
+		private int _handlerVersion;
+
+		private QCandidate(QCandidates qcandidates) : base(0)
+		{
+			// db4o ID is stored in _key;
+			// db4o byte stream storing the object
+			// Dependent candidates
+			// whether to include in the result set
+			// may use id for optimisation ???
+			// Possible pending joins on children
+			// The evaluation root to compare all ORs
+			// the ClassMetadata of this object
+			// temporary field and member for one field during evaluation
+			// null denotes null object
+			_candidates = qcandidates;
+		}
+
+		public QCandidate(QCandidates candidates, object member, int id) : base(id)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.CreateCandidate.Log(id);
+			}
+			_candidates = candidates;
+			_member = member;
+			_include = true;
+			if (id == 0)
+			{
+				_key = candidates.GenerateCandidateId();
+			}
+		}
+
+		public override object ShallowClone()
+		{
+			Db4objects.Db4o.Internal.Query.Processor.QCandidate qcan = new Db4objects.Db4o.Internal.Query.Processor.QCandidate
+				(_candidates);
+			qcan.SetBytes(_bytes);
+			qcan._dependants = _dependants;
+			qcan._include = _include;
+			qcan._member = _member;
+			qcan._pendingJoins = _pendingJoins;
+			qcan._root = _root;
+			qcan._classMetadata = _classMetadata;
+			qcan._fieldMetadata = _fieldMetadata;
+			return base.ShallowCloneInternal(qcan);
+		}
+
+		internal virtual void AddDependant(Db4objects.Db4o.Internal.Query.Processor.QCandidate
+			 a_candidate)
+		{
+			_dependants = new List4(_dependants, a_candidate);
+		}
+
+		private void CheckInstanceOfCompare()
+		{
+			if (_member is ICompare)
+			{
+				_member = ((ICompare)_member).Compare();
+				LocalObjectContainer stream = Container();
+				_classMetadata = stream.ClassMetadataForReflectClass(stream.Reflector().ForObject
+					(_member));
+				_key = stream.GetID(Transaction(), _member);
+				if (_key == 0)
+				{
+					SetBytes(null);
+				}
+				else
+				{
+					SetBytes(stream.ReadBufferById(Transaction(), _key));
+				}
+			}
+		}
+
+		internal virtual bool CreateChild(QCandidates a_candidates)
+		{
+			if (!_include)
+			{
+				return false;
+			}
+			if (_fieldMetadata != null)
+			{
+				ITypeHandler4 handler = _fieldMetadata.GetHandler();
+				if (handler != null)
+				{
+					QueryingReadContext queryingReadContext = new QueryingReadContext(Transaction(), 
+						MarshallerFamily().HandlerVersion(), _bytes, _key);
+					ITypeHandler4 arrayElementHandler = Handlers4.ArrayElementHandler(handler, queryingReadContext
+						);
+					if (arrayElementHandler != null)
+					{
+						int offset = queryingReadContext.Offset();
+						bool outerRes = true;
+						// The following construct is worse than not ideal.
+						// For each constraint it completely reads the
+						// underlying structure again. The structure could b
+						// kept fairly easy. TODO: Optimize!
+						IEnumerator i = a_candidates.IterateConstraints();
+						while (i.MoveNext())
+						{
+							QCon qcon = (QCon)i.Current;
+							QField qf = qcon.GetField();
+							if (qf == null || qf.Name().Equals(_fieldMetadata.GetName()))
+							{
+								QCon tempParent = qcon.Parent();
+								qcon.SetParent(null);
+								QCandidates candidates = new QCandidates(a_candidates.i_trans, null, qf);
+								candidates.AddConstraint(qcon);
+								qcon.SetCandidates(candidates);
+								ReadArrayCandidates(handler, queryingReadContext.Buffer(), arrayElementHandler, candidates
+									);
+								queryingReadContext.Seek(offset);
+								bool isNot = qcon.IsNot();
+								if (isNot)
+								{
+									qcon.RemoveNot();
+								}
+								candidates.Evaluate();
+								ByRef pending = ByRef.NewInstance();
+								bool[] innerRes = new bool[] { isNot };
+								candidates.Traverse(new _IVisitor4_160(innerRes, isNot, pending));
+								// Collect all pending subresults.
+								// We need to change
+								// the
+								// constraint here, so
+								// our
+								// pending collector
+								// uses
+								// the right
+								// comparator.
+								// We only keep one
+								// pending result
+								// for
+								// all array
+								// elements.
+								// and memorize,
+								// whether we had a
+								// true or a false
+								// result.
+								// or both.
+								if (isNot)
+								{
+									qcon.Not();
+								}
+								// In case we had pending subresults, we
+								// need to communicate
+								// them up to our root.
+								if (((Tree)pending.value) != null)
+								{
+									((Tree)pending.value).Traverse(new _IVisitor4_229(this));
+								}
+								if (!innerRes[0])
+								{
+									// Again this could be double triggering.
+									// 
+									// We want to clean up the "No route"
+									// at some stage.
+									qcon.Visit(GetRoot(), qcon.Evaluator().Not(false));
+									outerRes = false;
+								}
+								qcon.SetParent(tempParent);
+							}
+						}
+						return outerRes;
+					}
+					// We may get simple types here too, if the YapField was null
+					// in the higher level simple evaluation. Evaluate these
+					// immediately.
+					if (Handlers4.IsQueryLeaf(handler))
+					{
+						a_candidates.i_currentConstraint.Visit(this);
+						return true;
+					}
+				}
+			}
+			if (_fieldMetadata == null)
+			{
+				return false;
+			}
+			if (_fieldMetadata is NullFieldMetadata)
+			{
+				return false;
+			}
+			_classMetadata.SeekToField(Transaction(), _bytes, _fieldMetadata);
+			Db4objects.Db4o.Internal.Query.Processor.QCandidate candidate = ReadSubCandidate(
+				a_candidates);
+			if (candidate == null)
+			{
+				return false;
+			}
+			// fast early check for ClassMetadata
+			if (a_candidates.i_classMetadata != null && a_candidates.i_classMetadata.IsStronglyTyped
+				())
+			{
+				ITypeHandler4 handler = _fieldMetadata.GetHandler();
+				if (Handlers4.IsUntyped(handler))
+				{
+					handler = TypeHandlerFor(candidate);
+				}
+				if (handler == null)
+				{
+					return false;
+				}
+			}
+			AddDependant(a_candidates.Add(candidate));
+			return true;
+		}
+
+		private sealed class _IVisitor4_160 : IVisitor4
+		{
+			public _IVisitor4_160(bool[] innerRes, bool isNot, ByRef pending)
+			{
+				this.innerRes = innerRes;
+				this.isNot = isNot;
+				this.pending = pending;
+			}
+
+			public void Visit(object obj)
+			{
+				Db4objects.Db4o.Internal.Query.Processor.QCandidate cand = (Db4objects.Db4o.Internal.Query.Processor.QCandidate
+					)obj;
+				if (cand.Include())
+				{
+					innerRes[0] = !isNot;
+				}
+				if (cand._pendingJoins != null)
+				{
+					cand._pendingJoins.Traverse(new _IVisitor4_173(pending));
+				}
+			}
+
+			private sealed class _IVisitor4_173 : IVisitor4
+			{
+				public _IVisitor4_173(ByRef pending)
+				{
+					this.pending = pending;
+				}
+
+				public void Visit(object a_object)
+				{
+					QPending newPending = ((QPending)a_object).InternalClonePayload();
+					newPending.ChangeConstraint();
+					QPending oldPending = (QPending)Tree.Find(((Tree)pending.value), newPending);
+					if (oldPending != null)
+					{
+						if (oldPending._result != newPending._result)
+						{
+							oldPending._result = QPending.Both;
+						}
+					}
+					else
+					{
+						pending.value = Tree.Add(((Tree)pending.value), newPending);
+					}
+				}
+
+				private readonly ByRef pending;
+			}
+
+			private readonly bool[] innerRes;
+
+			private readonly bool isNot;
+
+			private readonly ByRef pending;
+		}
+
+		private sealed class _IVisitor4_229 : IVisitor4
+		{
+			public _IVisitor4_229(QCandidate _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Visit(object a_object)
+			{
+				this._enclosing.GetRoot().Evaluate((QPending)a_object);
+			}
+
+			private readonly QCandidate _enclosing;
+		}
+
+		private ITypeHandler4 TypeHandlerFor(Db4objects.Db4o.Internal.Query.Processor.QCandidate
+			 candidate)
+		{
+			Db4objects.Db4o.Internal.ClassMetadata classMetadata = candidate.ReadClassMetadata
+				();
+			if (classMetadata != null)
+			{
+				return classMetadata.TypeHandler();
+			}
+			return null;
+		}
+
+		private void ReadArrayCandidates(ITypeHandler4 typeHandler, IReadBuffer buffer, ITypeHandler4
+			 arrayElementHandler, QCandidates candidates)
+		{
+			if (!Handlers4.IsCascading(arrayElementHandler))
+			{
+				return;
+			}
+			SlotFormat slotFormat = SlotFormat.ForHandlerVersion(_handlerVersion);
+			slotFormat.DoWithSlotIndirection(buffer, typeHandler, new _IClosure4_318(this, arrayElementHandler
+				, buffer, candidates));
+		}
+
+		private sealed class _IClosure4_318 : IClosure4
+		{
+			public _IClosure4_318(QCandidate _enclosing, ITypeHandler4 arrayElementHandler, IReadBuffer
+				 buffer, QCandidates candidates)
+			{
+				this._enclosing = _enclosing;
+				this.arrayElementHandler = arrayElementHandler;
+				this.buffer = buffer;
+				this.candidates = candidates;
+			}
+
+			public object Run()
+			{
+				QueryingReadContext context = null;
+				if (Handlers4.HandleAsObject(arrayElementHandler))
+				{
+					// TODO: Code is similar to FieldMetadata.collectIDs. Try to refactor to one place.
+					int collectionID = buffer.ReadInt();
+					ByteArrayBuffer arrayElementBuffer = this._enclosing.Container().ReadBufferById(this
+						._enclosing.Transaction(), collectionID);
+					ObjectHeader objectHeader = ObjectHeader.ScrollBufferToContent(this._enclosing.Container
+						(), arrayElementBuffer);
+					context = new QueryingReadContext(this._enclosing.Transaction(), candidates, this
+						._enclosing._handlerVersion, arrayElementBuffer, collectionID);
+					objectHeader.ClassMetadata().CollectIDs(context);
+				}
+				else
+				{
+					context = new QueryingReadContext(this._enclosing.Transaction(), candidates, this
+						._enclosing._handlerVersion, buffer, 0);
+					((ICascadingTypeHandler)arrayElementHandler).CollectIDs(context);
+				}
+				Tree.Traverse(context.Ids(), new _IVisitor4_336(candidates));
+				IEnumerator i = context.ObjectsWithoutId();
+				while (i.MoveNext())
+				{
+					object obj = i.Current;
+					candidates.Add(new Db4objects.Db4o.Internal.Query.Processor.QCandidate(candidates
+						, obj, 0));
+				}
+				return null;
+			}
+
+			private sealed class _IVisitor4_336 : IVisitor4
+			{
+				public _IVisitor4_336(QCandidates candidates)
+				{
+					this.candidates = candidates;
+				}
+
+				public void Visit(object obj)
+				{
+					TreeInt idNode = (TreeInt)obj;
+					candidates.Add(new Db4objects.Db4o.Internal.Query.Processor.QCandidate(candidates
+						, null, idNode._key));
+				}
+
+				private readonly QCandidates candidates;
+			}
+
+			private readonly QCandidate _enclosing;
+
+			private readonly ITypeHandler4 arrayElementHandler;
+
+			private readonly IReadBuffer buffer;
+
+			private readonly QCandidates candidates;
+		}
+
+		internal virtual void DoNotInclude()
+		{
+			Include(false);
+			if (_dependants != null)
+			{
+				IEnumerator i = new Iterator4Impl(_dependants);
+				_dependants = null;
+				while (i.MoveNext())
+				{
+					((Db4objects.Db4o.Internal.Query.Processor.QCandidate)i.Current).DoNotInclude();
+				}
+			}
+		}
+
+		internal virtual bool Evaluate(QConObject a_constraint, QE a_evaluator)
+		{
+			if (a_evaluator.Identity())
+			{
+				return a_evaluator.Evaluate(a_constraint, this, null);
+			}
+			if (_member == null)
+			{
+				_member = Value();
+			}
+			return a_evaluator.Evaluate(a_constraint, this, a_constraint.Translate(_member));
+		}
+
+		internal virtual bool Evaluate(QPending a_pending)
+		{
+			QPending oldPending = (QPending)Tree.Find(_pendingJoins, a_pending);
+			if (oldPending == null)
+			{
+				a_pending.ChangeConstraint();
+				_pendingJoins = Tree.Add(_pendingJoins, a_pending.InternalClonePayload());
+				return true;
+			}
+			_pendingJoins = _pendingJoins.RemoveNode(oldPending);
+			oldPending._join.EvaluatePending(this, oldPending, a_pending._result);
+			return false;
+		}
+
+		internal virtual IReflectClass ClassReflector()
+		{
+			ReadClassMetadata();
+			if (_classMetadata == null)
+			{
+				return null;
+			}
+			return _classMetadata.ClassReflector();
+		}
+
+		internal virtual bool FieldIsAvailable()
+		{
+			return ClassReflector() != null;
+		}
+
+		// / ***<Candidate interface code>***
+		public virtual IObjectContainer ObjectContainer()
+		{
+			return Container();
+		}
+
+		public virtual object GetObject()
+		{
+			object obj = Value(true);
+			if (obj is ByteArrayBuffer)
+			{
+				ByteArrayBuffer reader = (ByteArrayBuffer)obj;
+				int offset = reader._offset;
+				obj = ReadString(reader);
+				reader._offset = offset;
+			}
+			return obj;
+		}
+
+		public virtual string ReadString(ByteArrayBuffer buffer)
+		{
+			return StringHandler.ReadString(Transaction().Context(), buffer);
+		}
+
+		internal virtual Db4objects.Db4o.Internal.Query.Processor.QCandidate GetRoot()
+		{
+			return _root == null ? this : _root;
+		}
+
+		internal LocalObjectContainer Container()
+		{
+			return Transaction().LocalContainer();
+		}
+
+		internal LocalTransaction Transaction()
+		{
+			return _candidates.i_trans;
+		}
+
+		public virtual bool Include()
+		{
+			return _include;
+		}
+
+		/// <summary>For external interface use only.</summary>
+		/// <remarks>
+		/// For external interface use only. Call doNotInclude() internally so
+		/// dependancies can be checked.
+		/// </remarks>
+		public virtual void Include(bool flag)
+		{
+			// TODO:
+			// Internal and external flag may need to be handled seperately.
+			_include = flag;
+		}
+
+		public override Tree OnAttemptToAddDuplicate(Tree oldNode)
+		{
+			_size = 0;
+			_root = (Db4objects.Db4o.Internal.Query.Processor.QCandidate)oldNode;
+			return oldNode;
+		}
+
+		private IReflectClass MemberClass()
+		{
+			return Transaction().Reflector().ForObject(_member);
+		}
+
+		internal virtual IPreparedComparison PrepareComparison(ObjectContainerBase container
+			, object constraint)
+		{
+			IContext context = container.Transaction.Context();
+			if (_fieldMetadata != null)
+			{
+				return _fieldMetadata.PrepareComparison(context, constraint);
+			}
+			if (_classMetadata != null)
+			{
+				return _classMetadata.PrepareComparison(context, constraint);
+			}
+			IReflector reflector = container.Reflector();
+			Db4objects.Db4o.Internal.ClassMetadata classMetadata = null;
+			if (_bytes != null)
+			{
+				classMetadata = container.ProduceClassMetadata(reflector.ForObject(constraint));
+			}
+			else
+			{
+				if (_member != null)
+				{
+					classMetadata = container.ClassMetadataForReflectClass(reflector.ForObject(_member
+						));
+				}
+			}
+			if (classMetadata != null)
+			{
+				if (_member != null && _member.GetType().IsArray)
+				{
+					ITypeHandler4 arrayElementTypehandler = classMetadata.TypeHandler();
+					if (reflector.Array().IsNDimensional(MemberClass()))
+					{
+						MultidimensionalArrayHandler mah = new MultidimensionalArrayHandler(arrayElementTypehandler
+							, false);
+						return mah.PrepareComparison(context, _member);
+					}
+					ArrayHandler ya = new ArrayHandler(arrayElementTypehandler, false);
+					return ya.PrepareComparison(context, _member);
+				}
+				return classMetadata.PrepareComparison(context, constraint);
+			}
+			return null;
+		}
+
+		private void Read()
+		{
+			if (_include)
+			{
+				if (_bytes == null)
+				{
+					if (_key > 0)
+					{
+						if (DTrace.enabled)
+						{
+							DTrace.CandidateRead.Log(_key);
+						}
+						SetBytes(Container().ReadBufferById(Transaction(), _key));
+						if (_bytes == null)
+						{
+							Include(false);
+						}
+					}
+					else
+					{
+						Include(false);
+					}
+				}
+			}
+		}
+
+		private int CurrentOffSet()
+		{
+			return _bytes._offset;
+		}
+
+		private Db4objects.Db4o.Internal.Query.Processor.QCandidate ReadSubCandidate(QCandidates
+			 candidateCollection)
+		{
+			Read();
+			if (_bytes == null || _fieldMetadata == null)
+			{
+				return null;
+			}
+			int offset = CurrentOffSet();
+			QueryingReadContext context = NewQueryingReadContext();
+			ITypeHandler4 handler = HandlerRegistry.CorrectHandlerVersion(context, _fieldMetadata
+				.GetHandler());
+			Db4objects.Db4o.Internal.Query.Processor.QCandidate subCandidate = candidateCollection
+				.ReadSubCandidate(context, handler);
+			Seek(offset);
+			if (subCandidate != null)
+			{
+				subCandidate._root = GetRoot();
+				return subCandidate;
+			}
+			return null;
+		}
+
+		private void Seek(int offset)
+		{
+			_bytes._offset = offset;
+		}
+
+		private QueryingReadContext NewQueryingReadContext()
+		{
+			return new QueryingReadContext(Transaction(), _handlerVersion, _bytes, _key);
+		}
+
+		private void ReadThis(bool a_activate)
+		{
+			Read();
+			ObjectContainerBase container = Transaction().Container();
+			_member = container.TryGetByID(Transaction(), _key);
+			if (_member != null && (a_activate || _member is ICompare))
+			{
+				container.Activate(Transaction(), _member);
+				CheckInstanceOfCompare();
+			}
+		}
+
+		internal virtual Db4objects.Db4o.Internal.ClassMetadata ReadClassMetadata()
+		{
+			if (_classMetadata == null)
+			{
+				Read();
+				if (_bytes != null)
+				{
+					Seek(0);
+					ObjectContainerBase stream = Container();
+					ObjectHeader objectHeader = new ObjectHeader(stream, _bytes);
+					_classMetadata = objectHeader.ClassMetadata();
+					if (_classMetadata != null)
+					{
+						if (stream._handlers.IclassCompare.IsAssignableFrom(_classMetadata.ClassReflector
+							()))
+						{
+							ReadThis(false);
+						}
+					}
+				}
+			}
+			return _classMetadata;
+		}
+
+		public override string ToString()
+		{
+			string str = "QCandidate ";
+			if (_classMetadata != null)
+			{
+				str += "\n   YapClass " + _classMetadata.GetName();
+			}
+			if (_fieldMetadata != null)
+			{
+				str += "\n   YapField " + _fieldMetadata.GetName();
+			}
+			if (_member != null)
+			{
+				str += "\n   Member " + _member.ToString();
+			}
+			if (_root != null)
+			{
+				str += "\n  rooted by:\n";
+				str += _root.ToString();
+			}
+			else
+			{
+				str += "\n  ROOT";
+			}
+			return str;
+		}
+
+		internal virtual void UseField(QField a_field)
+		{
+			Read();
+			if (_bytes == null)
+			{
+				_fieldMetadata = null;
+				return;
+			}
+			ReadClassMetadata();
+			_member = null;
+			if (a_field == null)
+			{
+				_fieldMetadata = null;
+				return;
+			}
+			if (_classMetadata == null)
+			{
+				_fieldMetadata = null;
+				return;
+			}
+			_fieldMetadata = FieldMetadataFrom(a_field, _classMetadata);
+			if (_fieldMetadata == null)
+			{
+				FieldNotFound();
+				return;
+			}
+			HandlerVersion handlerVersion = _classMetadata.SeekToField(Transaction(), _bytes, 
+				_fieldMetadata);
+			if (handlerVersion == HandlerVersion.Invalid)
+			{
+				FieldNotFound();
+				return;
+			}
+			_handlerVersion = handlerVersion._number;
+		}
+
+		private FieldMetadata FieldMetadataFrom(QField qField, Db4objects.Db4o.Internal.ClassMetadata
+			 type)
+		{
+			FieldMetadata existingField = qField.GetFieldMetadata();
+			if (existingField != null)
+			{
+				return existingField;
+			}
+			FieldMetadata field = type.FieldMetadataForName(qField.Name());
+			if (field != null)
+			{
+				field.Alive();
+			}
+			return field;
+		}
+
+		private void FieldNotFound()
+		{
+			if (_classMetadata.HoldsAnyClass())
+			{
+				// retry finding the field on reading the value 
+				_fieldMetadata = null;
+			}
+			else
+			{
+				// we can't get a value for the field, comparisons should definitely run against null
+				_fieldMetadata = new NullFieldMetadata();
+			}
+			_handlerVersion = HandlerRegistry.HandlerVersion;
+		}
+
+		internal virtual object Value()
+		{
+			return Value(false);
+		}
+
+		// TODO: This is only used for Evaluations. Handling may need
+		// to be different for collections also.
+		internal virtual object Value(bool a_activate)
+		{
+			if (_member == null)
+			{
+				if (_fieldMetadata == null)
+				{
+					ReadThis(a_activate);
+				}
+				else
+				{
+					int offset = CurrentOffSet();
+					_member = _fieldMetadata.Read(NewQueryingReadContext());
+					Seek(offset);
+					CheckInstanceOfCompare();
+				}
+			}
+			return _member;
+		}
+
+		internal virtual void SetBytes(ByteArrayBuffer bytes)
+		{
+			_bytes = bytes;
+		}
+
+		private Db4objects.Db4o.Internal.Marshall.MarshallerFamily MarshallerFamily()
+		{
+			return Db4objects.Db4o.Internal.Marshall.MarshallerFamily.Version(_handlerVersion
+				);
+		}
+
+		public override bool Duplicates()
+		{
+			return _root != null;
+		}
+
+		public virtual void ClassMetadata(Db4objects.Db4o.Internal.ClassMetadata classMetadata
+			)
+		{
+			_classMetadata = classMetadata;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QCandidates.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QCandidates.cs
new file mode 100644
index 0000000..8fb86c4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QCandidates.cs
@@ -0,0 +1,659 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using System.Text;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Classindex;
+using Db4objects.Db4o.Internal.Diagnostic;
+using Db4objects.Db4o.Internal.Fieldindex;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <summary>
+	/// Holds the tree of
+	/// <see cref="QCandidate">QCandidate</see>
+	/// objects and the list of
+	/// <see cref="QCon">QCon</see>
+	/// during query evaluation.
+	/// The query work (adding and removing nodes) happens here.
+	/// Candidates during query evaluation.
+	/// <see cref="QCandidate">QCandidate</see>
+	/// objects are stored in i_root
+	/// </summary>
+	/// <exclude></exclude>
+	public sealed class QCandidates : IVisitor4
+	{
+		public readonly LocalTransaction i_trans;
+
+		public Tree i_root;
+
+		private List4 _constraints;
+
+		internal ClassMetadata i_classMetadata;
+
+		private QField _field;
+
+		internal QCon i_currentConstraint;
+
+		private IDGenerator _idGenerator;
+
+		private bool _loadedFromClassIndex;
+
+		internal QCandidates(LocalTransaction a_trans, ClassMetadata a_classMetadata, QField
+			 a_field)
+		{
+			// Transaction necessary as reference to stream
+			// root of the QCandidate tree
+			// collection of all constraints
+			// possible class information
+			// possible field information
+			// current executing constraint, only set where needed
+			i_trans = a_trans;
+			i_classMetadata = a_classMetadata;
+			_field = a_field;
+			if (a_field == null || a_field._fieldMetadata == null || !(a_field._fieldMetadata
+				.GetHandler() is StandardReferenceTypeHandler))
+			{
+				return;
+			}
+			ClassMetadata yc = ((StandardReferenceTypeHandler)a_field._fieldMetadata.GetHandler
+				()).ClassMetadata();
+			if (i_classMetadata == null)
+			{
+				i_classMetadata = yc;
+			}
+			else
+			{
+				yc = i_classMetadata.GetHigherOrCommonHierarchy(yc);
+				if (yc != null)
+				{
+					i_classMetadata = yc;
+				}
+			}
+		}
+
+		public QCandidate Add(QCandidate candidate)
+		{
+			i_root = Tree.Add(i_root, candidate);
+			if (candidate._size == 0)
+			{
+				// This means that the candidate was already present
+				// and QCandidate does not allow duplicates.
+				// In this case QCandidate#isDuplicateOf will have
+				// placed the existing QCandidate in the i_root
+				// variable of the new candidate. We return it here: 
+				return candidate.GetRoot();
+			}
+			return candidate;
+		}
+
+		internal void AddConstraint(QCon a_constraint)
+		{
+			_constraints = new List4(_constraints, a_constraint);
+		}
+
+		public QCandidate ReadSubCandidate(QueryingReadContext context, ITypeHandler4 handler
+			)
+		{
+			ObjectID objectID = ObjectID.NotPossible;
+			try
+			{
+				int offset = context.Offset();
+				if (handler is IReadsObjectIds)
+				{
+					objectID = ((IReadsObjectIds)handler).ReadObjectID(context);
+				}
+				if (objectID.IsValid())
+				{
+					return new QCandidate(this, null, objectID._id);
+				}
+				if (objectID == ObjectID.NotPossible)
+				{
+					context.Seek(offset);
+					object obj = context.Read(handler);
+					if (obj != null)
+					{
+						QCandidate candidate = new QCandidate(this, obj, context.Container().GetID(context
+							.Transaction(), obj));
+						candidate.ClassMetadata(context.Container().ClassMetadataForObject(obj));
+						return candidate;
+					}
+				}
+			}
+			catch (Exception)
+			{
+			}
+			// FIXME: Catchall
+			return null;
+		}
+
+		internal void Collect(Db4objects.Db4o.Internal.Query.Processor.QCandidates a_candidates
+			)
+		{
+			IEnumerator i = IterateConstraints();
+			while (i.MoveNext())
+			{
+				QCon qCon = (QCon)i.Current;
+				SetCurrentConstraint(qCon);
+				qCon.Collect(a_candidates);
+			}
+			SetCurrentConstraint(null);
+		}
+
+		internal void Execute()
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.QueryProcess.Log();
+			}
+			FieldIndexProcessorResult result = ProcessFieldIndexes();
+			if (result.FoundIndex())
+			{
+				i_root = result.ToQCandidate(this);
+			}
+			else
+			{
+				LoadFromClassIndex();
+			}
+			Evaluate();
+		}
+
+		public IEnumerator ExecuteSnapshot(Collection4 executionPath)
+		{
+			IIntIterator4 indexIterator = new IntIterator4Adaptor(IterateIndex(ProcessFieldIndexes
+				()));
+			Tree idRoot = TreeInt.AddAll(null, indexIterator);
+			IEnumerator snapshotIterator = new TreeKeyIterator(idRoot);
+			IEnumerator singleObjectQueryIterator = SingleObjectSodaProcessor(snapshotIterator
+				);
+			return MapIdsToExecutionPath(singleObjectQueryIterator, executionPath);
+		}
+
+		private IEnumerator SingleObjectSodaProcessor(IEnumerator indexIterator)
+		{
+			return Iterators.Map(indexIterator, new _IFunction4_159(this));
+		}
+
+		private sealed class _IFunction4_159 : IFunction4
+		{
+			public _IFunction4_159(QCandidates _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Apply(object current)
+			{
+				int id = ((int)current);
+				QCandidate candidate = new QCandidate(this._enclosing, null, id);
+				this._enclosing.i_root = candidate;
+				this._enclosing.Evaluate();
+				if (!candidate.Include())
+				{
+					return Iterators.Skip;
+				}
+				return current;
+			}
+
+			private readonly QCandidates _enclosing;
+		}
+
+		public IEnumerator ExecuteLazy(Collection4 executionPath)
+		{
+			IEnumerator indexIterator = IterateIndex(ProcessFieldIndexes());
+			IEnumerator singleObjectQueryIterator = SingleObjectSodaProcessor(indexIterator);
+			return MapIdsToExecutionPath(singleObjectQueryIterator, executionPath);
+		}
+
+		private IEnumerator IterateIndex(FieldIndexProcessorResult result)
+		{
+			if (result.NoMatch())
+			{
+				return Iterators.EmptyIterator;
+			}
+			if (result.FoundIndex())
+			{
+				return result.IterateIDs();
+			}
+			if (!i_classMetadata.HasClassIndex())
+			{
+				return Iterators.EmptyIterator;
+			}
+			return BTreeClassIndexStrategy.Iterate(i_classMetadata, i_trans);
+		}
+
+		private IEnumerator MapIdsToExecutionPath(IEnumerator singleObjectQueryIterator, 
+			Collection4 executionPath)
+		{
+			if (executionPath == null)
+			{
+				return singleObjectQueryIterator;
+			}
+			IEnumerator res = singleObjectQueryIterator;
+			IEnumerator executionPathIterator = executionPath.GetEnumerator();
+			while (executionPathIterator.MoveNext())
+			{
+				string fieldName = (string)executionPathIterator.Current;
+				res = Iterators.Concat(Iterators.Map(res, new _IFunction4_205(this, fieldName)));
+			}
+			return res;
+		}
+
+		private sealed class _IFunction4_205 : IFunction4
+		{
+			public _IFunction4_205(QCandidates _enclosing, string fieldName)
+			{
+				this._enclosing = _enclosing;
+				this.fieldName = fieldName;
+			}
+
+			public object Apply(object current)
+			{
+				int id = ((int)current);
+				CollectIdContext context = CollectIdContext.ForID(this._enclosing.i_trans, id);
+				if (context == null)
+				{
+					return Iterators.Skip;
+				}
+				context.ClassMetadata().CollectIDs(context, fieldName);
+				return new TreeKeyIterator(context.Ids());
+			}
+
+			private readonly QCandidates _enclosing;
+
+			private readonly string fieldName;
+		}
+
+		public ObjectContainerBase Stream()
+		{
+			return i_trans.Container();
+		}
+
+		public int ClassIndexEntryCount()
+		{
+			return i_classMetadata.IndexEntryCount(i_trans);
+		}
+
+		private FieldIndexProcessorResult ProcessFieldIndexes()
+		{
+			if (_constraints == null)
+			{
+				return FieldIndexProcessorResult.NoIndexFound;
+			}
+			return new FieldIndexProcessor(this).Run();
+		}
+
+		internal void Evaluate()
+		{
+			if (_constraints == null)
+			{
+				return;
+			}
+			ForEachConstraint(new _IProcedure4_243(this));
+			ForEachConstraint(new _IProcedure4_251());
+			ForEachConstraint(new _IProcedure4_257());
+			ForEachConstraint(new _IProcedure4_263());
+			ForEachConstraint(new _IProcedure4_269());
+			ForEachConstraint(new _IProcedure4_275());
+		}
+
+		private sealed class _IProcedure4_243 : IProcedure4
+		{
+			public _IProcedure4_243(QCandidates _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Apply(object arg)
+			{
+				QCon qCon = (QCon)arg;
+				qCon.SetCandidates(this._enclosing);
+				qCon.EvaluateSelf();
+			}
+
+			private readonly QCandidates _enclosing;
+		}
+
+		private sealed class _IProcedure4_251 : IProcedure4
+		{
+			public _IProcedure4_251()
+			{
+			}
+
+			public void Apply(object arg)
+			{
+				((QCon)arg).EvaluateSimpleChildren();
+			}
+		}
+
+		private sealed class _IProcedure4_257 : IProcedure4
+		{
+			public _IProcedure4_257()
+			{
+			}
+
+			public void Apply(object arg)
+			{
+				((QCon)arg).EvaluateEvaluations();
+			}
+		}
+
+		private sealed class _IProcedure4_263 : IProcedure4
+		{
+			public _IProcedure4_263()
+			{
+			}
+
+			public void Apply(object arg)
+			{
+				((QCon)arg).EvaluateCreateChildrenCandidates();
+			}
+		}
+
+		private sealed class _IProcedure4_269 : IProcedure4
+		{
+			public _IProcedure4_269()
+			{
+			}
+
+			public void Apply(object arg)
+			{
+				((QCon)arg).EvaluateCollectChildren();
+			}
+		}
+
+		private sealed class _IProcedure4_275 : IProcedure4
+		{
+			public _IProcedure4_275()
+			{
+			}
+
+			public void Apply(object arg)
+			{
+				((QCon)arg).EvaluateChildren();
+			}
+		}
+
+		private void ForEachConstraint(IProcedure4 proc)
+		{
+			IEnumerator i = IterateConstraints();
+			while (i.MoveNext())
+			{
+				QCon constraint = (QCon)i.Current;
+				if (!constraint.ProcessedByIndex())
+				{
+					proc.Apply(constraint);
+				}
+			}
+		}
+
+		internal bool IsEmpty()
+		{
+			bool[] ret = new bool[] { true };
+			Traverse(new _IVisitor4_295(ret));
+			return ret[0];
+		}
+
+		private sealed class _IVisitor4_295 : IVisitor4
+		{
+			public _IVisitor4_295(bool[] ret)
+			{
+				this.ret = ret;
+			}
+
+			public void Visit(object obj)
+			{
+				if (((QCandidate)obj)._include)
+				{
+					ret[0] = false;
+				}
+			}
+
+			private readonly bool[] ret;
+		}
+
+		internal bool Filter(IVisitor4 a_host)
+		{
+			if (i_root != null)
+			{
+				i_root.Traverse(a_host);
+				i_root = i_root.Filter(new _IPredicate4_308());
+			}
+			return i_root != null;
+		}
+
+		private sealed class _IPredicate4_308 : IPredicate4
+		{
+			public _IPredicate4_308()
+			{
+			}
+
+			public bool Match(object a_candidate)
+			{
+				return ((QCandidate)a_candidate)._include;
+			}
+		}
+
+		internal int GenerateCandidateId()
+		{
+			if (_idGenerator == null)
+			{
+				_idGenerator = new IDGenerator();
+			}
+			return -_idGenerator.Next();
+		}
+
+		public IEnumerator IterateConstraints()
+		{
+			if (_constraints == null)
+			{
+				return Iterators.EmptyIterator;
+			}
+			return new Iterator4Impl(_constraints);
+		}
+
+		internal sealed class TreeIntBuilder
+		{
+			public TreeInt tree;
+
+			public void Add(TreeInt node)
+			{
+				tree = (TreeInt)((TreeInt)Tree.Add(tree, node));
+			}
+		}
+
+		internal void LoadFromClassIndex()
+		{
+			if (!IsEmpty())
+			{
+				return;
+			}
+			QCandidates.TreeIntBuilder result = new QCandidates.TreeIntBuilder();
+			IClassIndexStrategy index = i_classMetadata.Index();
+			index.TraverseAll(i_trans, new _IVisitor4_346(this, result));
+			i_root = result.tree;
+			DiagnosticProcessor dp = i_trans.Container()._handlers.DiagnosticProcessor();
+			if (dp.Enabled() && !IsClassOnlyQuery())
+			{
+				dp.LoadedFromClassIndex(i_classMetadata);
+			}
+			_loadedFromClassIndex = true;
+		}
+
+		private sealed class _IVisitor4_346 : IVisitor4
+		{
+			public _IVisitor4_346(QCandidates _enclosing, QCandidates.TreeIntBuilder result)
+			{
+				this._enclosing = _enclosing;
+				this.result = result;
+			}
+
+			public void Visit(object obj)
+			{
+				result.Add(new QCandidate(this._enclosing, null, ((int)obj)));
+			}
+
+			private readonly QCandidates _enclosing;
+
+			private readonly QCandidates.TreeIntBuilder result;
+		}
+
+		internal void SetCurrentConstraint(QCon a_constraint)
+		{
+			i_currentConstraint = a_constraint;
+		}
+
+		internal void Traverse(IVisitor4 a_visitor)
+		{
+			if (i_root != null)
+			{
+				i_root.Traverse(a_visitor);
+			}
+		}
+
+		// FIXME: This method should go completely.
+		//        We changed the code to create the QCandidates graph in two steps:
+		//        (1) call fitsIntoExistingConstraintHierarchy to determine whether
+		//            or not we need more QCandidates objects
+		//        (2) add all constraints
+		//        This method tries to do both in one, which results in missing
+		//        constraints. Not all are added to all QCandiates.
+		//        Right methodology is in 
+		//        QQueryBase#createCandidateCollection
+		//        and
+		//        QQueryBase#createQCandidatesList
+		internal bool TryAddConstraint(QCon a_constraint)
+		{
+			if (_field != null)
+			{
+				QField qf = a_constraint.GetField();
+				if (qf != null)
+				{
+					if (_field.Name() != null && !_field.Name().Equals(qf.Name()))
+					{
+						return false;
+					}
+				}
+			}
+			if (i_classMetadata == null || a_constraint.IsNullConstraint())
+			{
+				AddConstraint(a_constraint);
+				return true;
+			}
+			ClassMetadata yc = a_constraint.GetYapClass();
+			if (yc != null)
+			{
+				yc = i_classMetadata.GetHigherOrCommonHierarchy(yc);
+				if (yc != null)
+				{
+					i_classMetadata = yc;
+					AddConstraint(a_constraint);
+					return true;
+				}
+			}
+			AddConstraint(a_constraint);
+			return false;
+		}
+
+		public void Visit(object a_tree)
+		{
+			QCandidate parent = (QCandidate)a_tree;
+			if (parent.CreateChild(this))
+			{
+				return;
+			}
+			// No object found.
+			// All children constraints are necessarily false.
+			// Check immediately.
+			IEnumerator i = IterateConstraints();
+			while (i.MoveNext())
+			{
+				((QCon)i.Current).VisitOnNull(parent.GetRoot());
+			}
+		}
+
+		public override string ToString()
+		{
+			StringBuilder sb = new StringBuilder();
+			i_root.Traverse(new _IVisitor4_430(sb));
+			return sb.ToString();
+		}
+
+		private sealed class _IVisitor4_430 : IVisitor4
+		{
+			public _IVisitor4_430(StringBuilder sb)
+			{
+				this.sb = sb;
+			}
+
+			public void Visit(object obj)
+			{
+				QCandidate candidate = (QCandidate)obj;
+				sb.Append(" ");
+				sb.Append(candidate._key);
+			}
+
+			private readonly StringBuilder sb;
+		}
+
+		public Transaction Transaction()
+		{
+			return i_trans;
+		}
+
+		public bool WasLoadedFromClassIndex()
+		{
+			return _loadedFromClassIndex;
+		}
+
+		public bool FitsIntoExistingConstraintHierarchy(QCon constraint)
+		{
+			if (_field != null)
+			{
+				QField qf = constraint.GetField();
+				if (qf != null)
+				{
+					if (_field.Name() != null && !_field.Name().Equals(qf.Name()))
+					{
+						return false;
+					}
+				}
+			}
+			if (i_classMetadata == null || constraint.IsNullConstraint())
+			{
+				return true;
+			}
+			ClassMetadata classMetadata = constraint.GetYapClass();
+			if (classMetadata == null)
+			{
+				return false;
+			}
+			classMetadata = i_classMetadata.GetHigherOrCommonHierarchy(classMetadata);
+			if (classMetadata == null)
+			{
+				return false;
+			}
+			i_classMetadata = classMetadata;
+			return true;
+		}
+
+		private bool IsClassOnlyQuery()
+		{
+			if (((List4)_constraints._next) != null)
+			{
+				return false;
+			}
+			if (!(_constraints._element is QConClass))
+			{
+				return false;
+			}
+			return !((QCon)_constraints._element).HasChildren();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QCon.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QCon.cs
new file mode 100644
index 0000000..8866335
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QCon.cs
@@ -0,0 +1,894 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Query;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Types;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <summary>Base class for all constraints on queries.</summary>
+	/// <remarks>Base class for all constraints on queries.</remarks>
+	/// <exclude></exclude>
+	public abstract class QCon : IConstraint, IVisitor4, IUnversioned
+	{
+		internal static readonly IDGenerator idGenerator = new IDGenerator();
+
+		[System.NonSerialized]
+		internal QCandidates i_candidates;
+
+		private Collection4 i_childrenCandidates;
+
+		protected List4 _children;
+
+		protected QE i_evaluator = QE.Default;
+
+		private int i_id;
+
+		internal Collection4 i_joins;
+
+		protected Db4objects.Db4o.Internal.Query.Processor.QCon i_parent;
+
+		private bool i_removed = false;
+
+		[System.NonSerialized]
+		internal Db4objects.Db4o.Internal.Transaction i_trans;
+
+		[System.NonSerialized]
+		private bool _processedByIndex;
+
+		public QCon()
+		{
+		}
+
+		internal QCon(Db4objects.Db4o.Internal.Transaction a_trans)
+		{
+			//Used for query debug only.
+			// our candidate object tree
+			// collection of QCandidates to collect children elements and to
+			// execute children. For convenience we hold them in the constraint,
+			// so we can do collection and execution in two steps
+			// all subconstraints
+			// for evaluation
+			// ID handling for fast find of QConstraint objects in 
+			// pending OR evaluations
+			// ANDs and ORs on this constraint
+			// the parent of this constraint or null, if this is a root
+			// prevents circular calls on removal
+			// our transaction to get a stream object anywhere
+			// whether or not this constraint was used to get the initial set
+			// in the FieldIndexProcessor
+			// C/S only
+			i_id = idGenerator.Next();
+			i_trans = a_trans;
+		}
+
+		internal virtual Db4objects.Db4o.Internal.Query.Processor.QCon AddConstraint(Db4objects.Db4o.Internal.Query.Processor.QCon
+			 a_child)
+		{
+			_children = new List4(_children, a_child);
+			return a_child;
+		}
+
+		public virtual ObjectContainerBase Container()
+		{
+			return Transaction().Container();
+		}
+
+		public virtual Db4objects.Db4o.Internal.Transaction Transaction()
+		{
+			return i_trans;
+		}
+
+		internal virtual void AddJoin(QConJoin a_join)
+		{
+			if (i_joins == null)
+			{
+				i_joins = new Collection4();
+			}
+			i_joins.Add(a_join);
+		}
+
+		internal virtual Db4objects.Db4o.Internal.Query.Processor.QCon AddSharedConstraint
+			(QField a_field, object a_object)
+		{
+			QConObject newConstraint = new QConObject(i_trans, this, a_field, a_object);
+			AddConstraint(newConstraint);
+			return newConstraint;
+		}
+
+		public virtual IConstraint And(IConstraint andWith)
+		{
+			lock (StreamLock())
+			{
+				return Join(andWith, true);
+			}
+		}
+
+		internal virtual bool Attach(QQuery query, string a_field)
+		{
+			Db4objects.Db4o.Internal.Query.Processor.QCon qcon = this;
+			ClassMetadata yc = GetYapClass();
+			bool[] foundField = new bool[] { false };
+			ForEachChildField(a_field, new _IVisitor4_104(foundField, query));
+			if (foundField[0])
+			{
+				return true;
+			}
+			QField qf = null;
+			if (yc == null || yc.HoldsAnyClass())
+			{
+				int[] count = new int[] { 0 };
+				FieldMetadata[] yfs = new FieldMetadata[] { null };
+				i_trans.Container().ClassCollection().AttachQueryNode(a_field, new _IVisitor4_122
+					(yfs, count));
+				if (count[0] == 0)
+				{
+					return false;
+				}
+				if (count[0] == 1)
+				{
+					qf = yfs[0].QField(i_trans);
+				}
+				else
+				{
+					qf = new QField(i_trans, a_field, null, 0, 0);
+				}
+			}
+			else
+			{
+				if (yc.IsTranslated())
+				{
+					i_trans.Container()._handlers.DiagnosticProcessor().DescendIntoTranslator(yc, a_field
+						);
+				}
+				FieldMetadata yf = yc.FieldMetadataForName(a_field);
+				if (yf != null)
+				{
+					qf = yf.QField(i_trans);
+				}
+				if (qf == null)
+				{
+					qf = new QField(i_trans, a_field, null, 0, 0);
+				}
+			}
+			QConPath qcp = new QConPath(i_trans, qcon, qf);
+			query.AddConstraint(qcp);
+			qcon.AddConstraint(qcp);
+			return true;
+		}
+
+		private sealed class _IVisitor4_104 : IVisitor4
+		{
+			public _IVisitor4_104(bool[] foundField, QQuery query)
+			{
+				this.foundField = foundField;
+				this.query = query;
+			}
+
+			public void Visit(object obj)
+			{
+				foundField[0] = true;
+				query.AddConstraint((Db4objects.Db4o.Internal.Query.Processor.QCon)obj);
+			}
+
+			private readonly bool[] foundField;
+
+			private readonly QQuery query;
+		}
+
+		private sealed class _IVisitor4_122 : IVisitor4
+		{
+			public _IVisitor4_122(FieldMetadata[] yfs, int[] count)
+			{
+				this.yfs = yfs;
+				this.count = count;
+			}
+
+			public void Visit(object obj)
+			{
+				yfs[0] = (FieldMetadata)((object[])obj)[1];
+				count[0]++;
+			}
+
+			private readonly FieldMetadata[] yfs;
+
+			private readonly int[] count;
+		}
+
+		public virtual bool CanBeIndexLeaf()
+		{
+			return false;
+		}
+
+		public virtual bool CanLoadByIndex()
+		{
+			// virtual
+			return false;
+		}
+
+		internal virtual void CheckLastJoinRemoved()
+		{
+			if (i_joins.Size() == 0)
+			{
+				i_joins = null;
+			}
+		}
+
+		/// <param name="candidates"></param>
+		internal virtual void Collect(QCandidates candidates)
+		{
+		}
+
+		// virtual
+		public virtual IConstraint Contains()
+		{
+			throw NotSupported();
+		}
+
+		internal virtual void CreateCandidates(Collection4 a_candidateCollection)
+		{
+			IEnumerator j = a_candidateCollection.GetEnumerator();
+			while (j.MoveNext())
+			{
+				QCandidates candidates = (QCandidates)j.Current;
+				if (candidates.TryAddConstraint(this))
+				{
+					i_candidates = candidates;
+					return;
+				}
+			}
+			i_candidates = new QCandidates((LocalTransaction)i_trans, GetYapClass(), GetField
+				());
+			i_candidates.AddConstraint(this);
+			a_candidateCollection.Add(i_candidates);
+		}
+
+		internal virtual void DoNotInclude(QCandidate a_root)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.Donotinclude.Log(Id());
+			}
+			if (i_parent != null)
+			{
+				i_parent.Visit1(a_root, this, false);
+			}
+			else
+			{
+				a_root.DoNotInclude();
+			}
+		}
+
+		public virtual IConstraint Equal()
+		{
+			throw NotSupported();
+		}
+
+		/// <param name="candidate"></param>
+		internal virtual bool Evaluate(QCandidate candidate)
+		{
+			throw Exceptions4.VirtualException();
+		}
+
+		internal virtual void EvaluateChildren()
+		{
+			IEnumerator i = i_childrenCandidates.GetEnumerator();
+			while (i.MoveNext())
+			{
+				((QCandidates)i.Current).Evaluate();
+			}
+		}
+
+		internal virtual void EvaluateCollectChildren()
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.CollectChildren.Log(Id());
+			}
+			IEnumerator i = i_childrenCandidates.GetEnumerator();
+			while (i.MoveNext())
+			{
+				((QCandidates)i.Current).Collect(i_candidates);
+			}
+		}
+
+		internal virtual void EvaluateCreateChildrenCandidates()
+		{
+			i_childrenCandidates = new Collection4();
+			IEnumerator i = IterateChildren();
+			while (i.MoveNext())
+			{
+				((Db4objects.Db4o.Internal.Query.Processor.QCon)i.Current).CreateCandidates(i_childrenCandidates
+					);
+			}
+		}
+
+		internal virtual void EvaluateEvaluations()
+		{
+			IEnumerator i = IterateChildren();
+			while (i.MoveNext())
+			{
+				((Db4objects.Db4o.Internal.Query.Processor.QCon)i.Current).EvaluateEvaluationsExec
+					(i_candidates, true);
+			}
+		}
+
+		/// <param name="candidates"></param>
+		/// <param name="rereadObject"></param>
+		internal virtual void EvaluateEvaluationsExec(QCandidates candidates, bool rereadObject
+			)
+		{
+		}
+
+		// virtual
+		internal virtual void EvaluateSelf()
+		{
+			i_candidates.Filter(this);
+		}
+
+		internal virtual void EvaluateSimpleChildren()
+		{
+			// TODO: sort the constraints for YapFields first,
+			// so we stay with the same YapField
+			if (_children == null)
+			{
+				return;
+			}
+			IEnumerator i = IterateChildren();
+			while (i.MoveNext())
+			{
+				Db4objects.Db4o.Internal.Query.Processor.QCon qcon = (Db4objects.Db4o.Internal.Query.Processor.QCon
+					)i.Current;
+				i_candidates.SetCurrentConstraint(qcon);
+				qcon.SetCandidates(i_candidates);
+				qcon.EvaluateSimpleExec(i_candidates);
+			}
+			i_candidates.SetCurrentConstraint(null);
+		}
+
+		/// <param name="candidates"></param>
+		internal virtual void EvaluateSimpleExec(QCandidates candidates)
+		{
+		}
+
+		// virtual
+		internal virtual void ExchangeConstraint(Db4objects.Db4o.Internal.Query.Processor.QCon
+			 a_exchange, Db4objects.Db4o.Internal.Query.Processor.QCon a_with)
+		{
+			List4 previous = null;
+			List4 current = _children;
+			while (current != null)
+			{
+				if (current._element == a_exchange)
+				{
+					if (previous == null)
+					{
+						_children = ((List4)current._next);
+					}
+					else
+					{
+						previous._next = ((List4)current._next);
+					}
+				}
+				previous = current;
+				current = ((List4)current._next);
+			}
+			_children = new List4(_children, a_with);
+		}
+
+		internal virtual void ForEachChildField(string name, IVisitor4 visitor)
+		{
+			IEnumerator i = IterateChildren();
+			while (i.MoveNext())
+			{
+				object obj = i.Current;
+				if (obj is QConObject)
+				{
+					if (((QConObject)obj).GetField().Name().Equals(name))
+					{
+						visitor.Visit(obj);
+					}
+				}
+			}
+		}
+
+		public virtual QField GetField()
+		{
+			return null;
+		}
+
+		public virtual object GetObject()
+		{
+			throw NotSupported();
+		}
+
+		internal virtual Db4objects.Db4o.Internal.Query.Processor.QCon GetRoot()
+		{
+			if (i_parent != null)
+			{
+				return i_parent.GetRoot();
+			}
+			return this;
+		}
+
+		internal virtual Db4objects.Db4o.Internal.Query.Processor.QCon ProduceTopLevelJoin
+			()
+		{
+			if (!HasJoins())
+			{
+				return this;
+			}
+			IEnumerator i = IterateJoins();
+			if (i_joins.Size() == 1)
+			{
+				i.MoveNext();
+				return ((Db4objects.Db4o.Internal.Query.Processor.QCon)i.Current).ProduceTopLevelJoin
+					();
+			}
+			Collection4 col = new Collection4();
+			while (i.MoveNext())
+			{
+				col.Ensure(((Db4objects.Db4o.Internal.Query.Processor.QCon)i.Current).ProduceTopLevelJoin
+					());
+			}
+			i = col.GetEnumerator();
+			i.MoveNext();
+			Db4objects.Db4o.Internal.Query.Processor.QCon qcon = (Db4objects.Db4o.Internal.Query.Processor.QCon
+				)i.Current;
+			if (col.Size() == 1)
+			{
+				return qcon;
+			}
+			while (i.MoveNext())
+			{
+				qcon = (Db4objects.Db4o.Internal.Query.Processor.QCon)qcon.And((IConstraint)i.Current
+					);
+			}
+			return qcon;
+		}
+
+		internal virtual ClassMetadata GetYapClass()
+		{
+			return null;
+		}
+
+		public virtual IConstraint Greater()
+		{
+			throw NotSupported();
+		}
+
+		public virtual bool HasChildren()
+		{
+			return _children != null;
+		}
+
+		public virtual bool HasParent()
+		{
+			return i_parent != null;
+		}
+
+		public virtual Db4objects.Db4o.Internal.Query.Processor.QCon Parent()
+		{
+			return i_parent;
+		}
+
+		public virtual bool HasJoins()
+		{
+			if (i_joins == null)
+			{
+				return false;
+			}
+			return i_joins.Size() > 0;
+		}
+
+		public virtual bool HasObjectInParentPath(object obj)
+		{
+			if (i_parent != null)
+			{
+				return i_parent.HasObjectInParentPath(obj);
+			}
+			return false;
+		}
+
+		public virtual IConstraint Identity()
+		{
+			throw NotSupported();
+		}
+
+		public virtual IConstraint ByExample()
+		{
+			throw NotSupported();
+		}
+
+		public virtual int IdentityID()
+		{
+			return 0;
+		}
+
+		internal virtual bool IsNot()
+		{
+			return i_evaluator is QENot;
+		}
+
+		internal virtual bool IsNullConstraint()
+		{
+			return false;
+		}
+
+		public virtual IEnumerator IterateJoins()
+		{
+			if (i_joins == null)
+			{
+				return Iterators.EmptyIterator;
+			}
+			return i_joins.GetEnumerator();
+		}
+
+		public virtual IEnumerator IterateChildren()
+		{
+			if (_children == null)
+			{
+				return Iterators.EmptyIterator;
+			}
+			return new Iterator4Impl(_children);
+		}
+
+		internal virtual IConstraint Join(IConstraint a_with, bool a_and)
+		{
+			if (!(a_with is Db4objects.Db4o.Internal.Query.Processor.QCon))
+			{
+				// TODO: one of our STOr test cases somehow carries 
+				// the same constraint twice. This may be a result
+				// of a funny AND. Check!
+				return null;
+			}
+			if (a_with == this)
+			{
+				return this;
+			}
+			return Join1((Db4objects.Db4o.Internal.Query.Processor.QCon)a_with, a_and);
+		}
+
+		internal virtual IConstraint Join1(Db4objects.Db4o.Internal.Query.Processor.QCon 
+			a_with, bool a_and)
+		{
+			if (a_with is QConstraints)
+			{
+				int j = 0;
+				Collection4 joinHooks = new Collection4();
+				IConstraint[] constraints = ((QConstraints)a_with).ToArray();
+				for (j = 0; j < constraints.Length; j++)
+				{
+					joinHooks.Ensure(((Db4objects.Db4o.Internal.Query.Processor.QCon)constraints[j]).
+						JoinHook());
+				}
+				IConstraint[] joins = new IConstraint[joinHooks.Size()];
+				j = 0;
+				IEnumerator i = joinHooks.GetEnumerator();
+				while (i.MoveNext())
+				{
+					joins[j++] = Join((IConstraint)i.Current, a_and);
+				}
+				return new QConstraints(i_trans, joins);
+			}
+			Db4objects.Db4o.Internal.Query.Processor.QCon myHook = JoinHook();
+			Db4objects.Db4o.Internal.Query.Processor.QCon otherHook = a_with.JoinHook();
+			if (myHook == otherHook)
+			{
+				// You might like to check out, what happens, if you
+				// remove this line. It seems to open a bug in an
+				// StOr testcase.
+				return myHook;
+			}
+			QConJoin cj = new QConJoin(i_trans, myHook, otherHook, a_and);
+			myHook.AddJoin(cj);
+			otherHook.AddJoin(cj);
+			return cj;
+		}
+
+		internal virtual Db4objects.Db4o.Internal.Query.Processor.QCon JoinHook()
+		{
+			return ProduceTopLevelJoin();
+		}
+
+		public virtual IConstraint Like()
+		{
+			throw NotSupported();
+		}
+
+		public virtual IConstraint StartsWith(bool caseSensitive)
+		{
+			throw NotSupported();
+		}
+
+		public virtual IConstraint EndsWith(bool caseSensitive)
+		{
+			throw NotSupported();
+		}
+
+		internal virtual void Log(string indent)
+		{
+		}
+
+		// System.out.println(indent + "JOINS");
+		// joins += join.i_id + " ";
+		//		System.out.println(joins);
+		//		System.out.println(indent + getClass().getName() + " " + i_id + " " + i_debugField + " " + joins );
+		// System.out.println(indent + "CONSTRAINTS");
+		internal virtual string LogObject()
+		{
+			return string.Empty;
+		}
+
+		internal virtual void Marshall()
+		{
+			IEnumerator i = IterateChildren();
+			while (i.MoveNext())
+			{
+				((Db4objects.Db4o.Internal.Query.Processor.QCon)i.Current).Marshall();
+			}
+		}
+
+		public virtual IConstraint Not()
+		{
+			lock (StreamLock())
+			{
+				if (!(i_evaluator is QENot))
+				{
+					i_evaluator = new QENot(i_evaluator);
+				}
+				return this;
+			}
+		}
+
+		private Exception NotSupported()
+		{
+			return new Exception("Not supported.");
+		}
+
+		/// <param name="other"></param>
+		public virtual bool OnSameFieldAs(Db4objects.Db4o.Internal.Query.Processor.QCon other
+			)
+		{
+			return false;
+		}
+
+		public virtual IConstraint Or(IConstraint orWith)
+		{
+			lock (StreamLock())
+			{
+				return Join(orWith, false);
+			}
+		}
+
+		internal virtual bool Remove()
+		{
+			if (!i_removed)
+			{
+				i_removed = true;
+				RemoveChildrenJoins();
+				return true;
+			}
+			return false;
+		}
+
+		internal virtual void RemoveChildrenJoins()
+		{
+			if (!HasJoins())
+			{
+				return;
+			}
+			Collection4 toBeRemoved = CollectJoinsToBeRemoved();
+			i_joins.RemoveAll(toBeRemoved);
+			CheckLastJoinRemoved();
+		}
+
+		private Collection4 CollectJoinsToBeRemoved()
+		{
+			Collection4 toBeRemoved = new Collection4();
+			IEnumerator joinIter = IterateJoins();
+			while (joinIter.MoveNext())
+			{
+				QConJoin join = (QConJoin)joinIter.Current;
+				if (join.RemoveForParent(this))
+				{
+					toBeRemoved.Add(join);
+				}
+			}
+			return toBeRemoved;
+		}
+
+		internal virtual void RemoveJoin(QConJoin a_join)
+		{
+			i_joins.Remove(a_join);
+			CheckLastJoinRemoved();
+		}
+
+		internal virtual void RemoveNot()
+		{
+			if (IsNot())
+			{
+				i_evaluator = ((QENot)i_evaluator).Evaluator();
+			}
+		}
+
+		public virtual void SetCandidates(QCandidates a_candidates)
+		{
+			i_candidates = a_candidates;
+		}
+
+		internal virtual void SetParent(Db4objects.Db4o.Internal.Query.Processor.QCon a_newParent
+			)
+		{
+			i_parent = a_newParent;
+		}
+
+		/// <param name="obj"></param>
+		/// <param name="removeExisting"></param>
+		internal virtual Db4objects.Db4o.Internal.Query.Processor.QCon ShareParent(object
+			 obj, BooleanByRef removeExisting)
+		{
+			// virtual
+			return null;
+		}
+
+		/// <param name="claxx"></param>
+		/// <param name="removeExisting"></param>
+		internal virtual QConClass ShareParentForClass(IReflectClass claxx, BooleanByRef 
+			removeExisting)
+		{
+			// virtual
+			return null;
+		}
+
+		public virtual IConstraint Smaller()
+		{
+			throw NotSupported();
+		}
+
+		protected virtual object StreamLock()
+		{
+			return i_trans.Container().Lock();
+		}
+
+		internal virtual void Unmarshall(Db4objects.Db4o.Internal.Transaction a_trans)
+		{
+			if (i_trans != null)
+			{
+				return;
+			}
+			i_trans = a_trans;
+			UnmarshallParent(a_trans);
+			UnmarshallJoins(a_trans);
+			UnmarshallChildren(a_trans);
+		}
+
+		private void UnmarshallParent(Db4objects.Db4o.Internal.Transaction a_trans)
+		{
+			if (i_parent != null)
+			{
+				i_parent.Unmarshall(a_trans);
+			}
+		}
+
+		private void UnmarshallChildren(Db4objects.Db4o.Internal.Transaction a_trans)
+		{
+			IEnumerator i = IterateChildren();
+			while (i.MoveNext())
+			{
+				((Db4objects.Db4o.Internal.Query.Processor.QCon)i.Current).Unmarshall(a_trans);
+			}
+		}
+
+		private void UnmarshallJoins(Db4objects.Db4o.Internal.Transaction a_trans)
+		{
+			if (HasJoins())
+			{
+				IEnumerator i = IterateJoins();
+				while (i.MoveNext())
+				{
+					((Db4objects.Db4o.Internal.Query.Processor.QCon)i.Current).Unmarshall(a_trans);
+				}
+			}
+		}
+
+		public virtual void Visit(object obj)
+		{
+			QCandidate qc = (QCandidate)obj;
+			Visit1(qc.GetRoot(), this, Evaluate(qc));
+		}
+
+		internal virtual void Visit(QCandidate a_root, bool res)
+		{
+			Visit1(a_root, this, i_evaluator.Not(res));
+		}
+
+		internal virtual void Visit1(QCandidate root, Db4objects.Db4o.Internal.Query.Processor.QCon
+			 reason, bool res)
+		{
+			// The a_reason parameter makes it eays to distinguish
+			// between calls from above (a_reason == this) and below.
+			if (HasJoins())
+			{
+				// this should probably be on the Join
+				IEnumerator i = IterateJoins();
+				while (i.MoveNext())
+				{
+					root.Evaluate(new QPending((QConJoin)i.Current, this, res));
+				}
+			}
+			else
+			{
+				if (!res)
+				{
+					DoNotInclude(root);
+				}
+			}
+		}
+
+		internal void VisitOnNull(QCandidate a_root)
+		{
+			// TODO: It may be more efficient to rule out 
+			// all possible keepOnNull issues when starting
+			// evaluation.
+			IEnumerator i = IterateChildren();
+			while (i.MoveNext())
+			{
+				((Db4objects.Db4o.Internal.Query.Processor.QCon)i.Current).VisitOnNull(a_root);
+			}
+			if (VisitSelfOnNull())
+			{
+				Visit(a_root, IsNullConstraint());
+			}
+		}
+
+		internal virtual bool VisitSelfOnNull()
+		{
+			return true;
+		}
+
+		public virtual QE Evaluator()
+		{
+			return i_evaluator;
+		}
+
+		public virtual void SetProcessedByIndex()
+		{
+			InternalSetProcessedByIndex();
+		}
+
+		protected virtual void InternalSetProcessedByIndex()
+		{
+			_processedByIndex = true;
+			if (i_joins != null)
+			{
+				IEnumerator i = i_joins.GetEnumerator();
+				while (i.MoveNext())
+				{
+					((QConJoin)i.Current).SetProcessedByIndex();
+				}
+			}
+		}
+
+		public virtual bool ProcessedByIndex()
+		{
+			return _processedByIndex;
+		}
+
+		public virtual int ChildrenCount()
+		{
+			return List4.Size(_children);
+		}
+
+		public virtual int Id()
+		{
+			return i_id;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConClass.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConClass.cs
new file mode 100644
index 0000000..1c55446
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConClass.cs
@@ -0,0 +1,166 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Query;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <summary>Class constraint on queries</summary>
+	/// <exclude></exclude>
+	public class QConClass : QConObject
+	{
+		[System.NonSerialized]
+		private IReflectClass _claxx;
+
+		private string _className;
+
+		private bool i_equal;
+
+		public QConClass()
+		{
+		}
+
+		internal QConClass(Transaction a_trans, QCon a_parent, QField a_field, IReflectClass
+			 claxx) : base(a_trans, a_parent, a_field, null)
+		{
+			// C/S
+			if (claxx != null)
+			{
+				_classMetadata = a_trans.Container().ProduceClassMetadata(claxx);
+				if (claxx.Equals(a_trans.Container()._handlers.IclassObject))
+				{
+					_classMetadata = (ClassMetadata)_classMetadata.TypeHandler();
+				}
+			}
+			_claxx = claxx;
+		}
+
+		internal QConClass(Transaction trans, IReflectClass claxx) : this(trans, null, null
+			, claxx)
+		{
+		}
+
+		public virtual string GetClassName()
+		{
+			return _claxx == null ? null : _claxx.GetName();
+		}
+
+		public override bool CanBeIndexLeaf()
+		{
+			return false;
+		}
+
+		internal override bool Evaluate(QCandidate a_candidate)
+		{
+			bool res = true;
+			IReflectClass claxx = a_candidate.ClassReflector();
+			if (claxx == null)
+			{
+				res = false;
+			}
+			else
+			{
+				res = i_equal ? _claxx.Equals(claxx) : _claxx.IsAssignableFrom(claxx);
+			}
+			return i_evaluator.Not(res);
+		}
+
+		internal override void EvaluateSelf()
+		{
+			// optimization for simple class queries: 
+			// No instantiation of objects, if not necessary.
+			// Does not handle the special comparison of the
+			// Compare interface.
+			//
+			if (i_candidates.WasLoadedFromClassIndex())
+			{
+				if (i_evaluator.IsDefault())
+				{
+					if (!HasJoins())
+					{
+						if (_classMetadata != null && i_candidates.i_classMetadata != null)
+						{
+							if (_classMetadata.GetHigherHierarchy(i_candidates.i_classMetadata) == _classMetadata)
+							{
+								return;
+							}
+						}
+					}
+				}
+			}
+			i_candidates.Filter(this);
+		}
+
+		public override IConstraint Equal()
+		{
+			lock (StreamLock())
+			{
+				i_equal = true;
+				return this;
+			}
+		}
+
+		internal override bool IsNullConstraint()
+		{
+			return false;
+		}
+
+		internal override string LogObject()
+		{
+			return string.Empty;
+		}
+
+		internal override void Marshall()
+		{
+			base.Marshall();
+			if (_claxx != null)
+			{
+				_className = Container().Config().ResolveAliasRuntimeName(_claxx.GetName());
+			}
+		}
+
+		public override string ToString()
+		{
+			string str = "QConClass ";
+			if (_claxx != null)
+			{
+				str += _claxx.GetName() + " ";
+			}
+			return str + base.ToString();
+		}
+
+		internal override void Unmarshall(Transaction a_trans)
+		{
+			if (i_trans == null)
+			{
+				base.Unmarshall(a_trans);
+				if (_className != null)
+				{
+					_className = Container().Config().ResolveAliasStoredName(_className);
+					_claxx = a_trans.Reflector().ForName(_className);
+				}
+			}
+		}
+
+		internal override void SetEvaluationMode()
+		{
+			IEnumerator children = IterateChildren();
+			while (children.MoveNext())
+			{
+				object child = children.Current;
+				if (child is QConObject)
+				{
+					((QConObject)child).SetEvaluationMode();
+				}
+			}
+		}
+
+		public override void SetProcessedByIndex()
+		{
+		}
+		// do nothing, QConClass needs to stay in the evaluation graph.
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConEvaluation.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConEvaluation.cs
new file mode 100644
index 0000000..58d4eeb
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConEvaluation.cs
@@ -0,0 +1,128 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <exclude></exclude>
+	public class QConEvaluation : QCon
+	{
+		[System.NonSerialized]
+		private object i_evaluation;
+
+		private byte[] i_marshalledEvaluation;
+
+		private int i_marshalledID;
+
+		public QConEvaluation()
+		{
+		}
+
+		public QConEvaluation(Transaction a_trans, object a_evaluation) : base(a_trans)
+		{
+			// C/S only
+			i_evaluation = a_evaluation;
+		}
+
+		internal override void EvaluateEvaluationsExec(QCandidates a_candidates, bool rereadObject
+			)
+		{
+			if (rereadObject)
+			{
+				a_candidates.Traverse(new _IVisitor4_31());
+			}
+			a_candidates.Filter(this);
+		}
+
+		private sealed class _IVisitor4_31 : IVisitor4
+		{
+			public _IVisitor4_31()
+			{
+			}
+
+			public void Visit(object a_object)
+			{
+				((QCandidate)a_object).UseField(null);
+			}
+		}
+
+		internal override void Marshall()
+		{
+			base.Marshall();
+			if (!Platform4.UseNativeSerialization())
+			{
+				MarshallUsingDb4oFormat();
+			}
+			else
+			{
+				try
+				{
+					i_marshalledEvaluation = Platform4.Serialize(i_evaluation);
+				}
+				catch (Exception)
+				{
+					MarshallUsingDb4oFormat();
+				}
+			}
+		}
+
+		private void MarshallUsingDb4oFormat()
+		{
+			SerializedGraph serialized = Serializer.Marshall(Container(), i_evaluation);
+			i_marshalledEvaluation = serialized._bytes;
+			i_marshalledID = serialized._id;
+		}
+
+		internal override void Unmarshall(Transaction a_trans)
+		{
+			if (i_trans == null)
+			{
+				base.Unmarshall(a_trans);
+				if (i_marshalledID > 0 || !Platform4.UseNativeSerialization())
+				{
+					i_evaluation = Serializer.Unmarshall(Container(), i_marshalledEvaluation, i_marshalledID
+						);
+				}
+				else
+				{
+					i_evaluation = Platform4.Deserialize(i_marshalledEvaluation);
+				}
+			}
+		}
+
+		public override void Visit(object obj)
+		{
+			QCandidate candidate = (QCandidate)obj;
+			// force activation outside the try block
+			// so any activation errors bubble up
+			ForceActivation(candidate);
+			try
+			{
+				Platform4.EvaluationEvaluate(i_evaluation, candidate);
+			}
+			catch (Exception)
+			{
+				candidate.Include(false);
+			}
+			// TODO: implement Exception callback for the user coder
+			// at least for test cases
+			if (!candidate._include)
+			{
+				DoNotInclude(candidate.GetRoot());
+			}
+		}
+
+		private void ForceActivation(QCandidate candidate)
+		{
+			candidate.GetObject();
+		}
+
+		internal virtual bool SupportsIndex()
+		{
+			return false;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConJoin.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConJoin.cs
new file mode 100644
index 0000000..bdfcb3a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConJoin.cs
@@ -0,0 +1,152 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <summary>Join constraint on queries</summary>
+	/// <exclude></exclude>
+	public class QConJoin : QCon
+	{
+		private bool i_and;
+
+		private QCon i_constraint1;
+
+		private QCon i_constraint2;
+
+		public QConJoin()
+		{
+		}
+
+		internal QConJoin(Transaction a_trans, QCon a_c1, QCon a_c2, bool a_and) : base(a_trans
+			)
+		{
+			// FIELDS MUST BE PUBLIC TO BE REFLECTED ON UNDER JDK <= 1.1
+			// C/S
+			i_constraint1 = a_c1;
+			i_constraint2 = a_c2;
+			i_and = a_and;
+		}
+
+		public virtual QCon Constraint2()
+		{
+			return i_constraint2;
+		}
+
+		public virtual QCon Constraint1()
+		{
+			return i_constraint1;
+		}
+
+		internal override void DoNotInclude(QCandidate a_root)
+		{
+			Constraint1().DoNotInclude(a_root);
+			Constraint2().DoNotInclude(a_root);
+		}
+
+		internal override void ExchangeConstraint(QCon a_exchange, QCon a_with)
+		{
+			base.ExchangeConstraint(a_exchange, a_with);
+			if (a_exchange == Constraint1())
+			{
+				i_constraint1 = a_with;
+			}
+			if (a_exchange == Constraint2())
+			{
+				i_constraint2 = a_with;
+			}
+		}
+
+		internal virtual void EvaluatePending(QCandidate a_root, QPending a_pending, int 
+			a_secondResult)
+		{
+			bool res = i_evaluator.Not(i_and ? ((a_pending._result + a_secondResult) > 0) : (
+				a_pending._result + a_secondResult) > QPending.False);
+			if (HasJoins())
+			{
+				IEnumerator i = IterateJoins();
+				while (i.MoveNext())
+				{
+					Db4objects.Db4o.Internal.Query.Processor.QConJoin qcj = (Db4objects.Db4o.Internal.Query.Processor.QConJoin
+						)i.Current;
+					a_root.Evaluate(new QPending(qcj, this, res));
+				}
+			}
+			else
+			{
+				if (!res)
+				{
+					Constraint1().DoNotInclude(a_root);
+					Constraint2().DoNotInclude(a_root);
+				}
+			}
+		}
+
+		public virtual QCon GetOtherConstraint(QCon a_constraint)
+		{
+			if (a_constraint == Constraint1())
+			{
+				return Constraint2();
+			}
+			else
+			{
+				if (a_constraint == Constraint2())
+				{
+					return Constraint1();
+				}
+			}
+			throw new ArgumentException();
+		}
+
+		internal override string LogObject()
+		{
+			return string.Empty;
+		}
+
+		internal virtual bool RemoveForParent(QCon a_constraint)
+		{
+			if (i_and)
+			{
+				QCon other = GetOtherConstraint(a_constraint);
+				other.RemoveJoin(this);
+				// prevents circular call
+				other.Remove();
+				return true;
+			}
+			return false;
+		}
+
+		public override string ToString()
+		{
+			string str = "QConJoin " + (i_and ? "AND " : "OR");
+			if (Constraint1() != null)
+			{
+				str += "\n   " + Constraint1();
+			}
+			if (Constraint2() != null)
+			{
+				str += "\n   " + Constraint2();
+			}
+			return str;
+		}
+
+		public virtual bool IsOr()
+		{
+			return !i_and;
+		}
+
+		public override void SetProcessedByIndex()
+		{
+			if (ProcessedByIndex())
+			{
+				return;
+			}
+			base.SetProcessedByIndex();
+			Constraint1().SetProcessedByIndex();
+			Constraint2().SetProcessedByIndex();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConObject.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConObject.cs
new file mode 100644
index 0000000..f22ea87
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConObject.cs
@@ -0,0 +1,561 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Query;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <summary>Object constraint on queries</summary>
+	/// <exclude></exclude>
+	public class QConObject : QCon
+	{
+		private object i_object;
+
+		private int i_objectID;
+
+		[System.NonSerialized]
+		internal ClassMetadata _classMetadata;
+
+		private int i_classMetadataID;
+
+		private QField i_field;
+
+		[System.NonSerialized]
+		internal IPreparedComparison _preparedComparison;
+
+		private IObjectAttribute i_attributeProvider;
+
+		[System.NonSerialized]
+		private bool _checkClassMetadataOnly = false;
+
+		public QConObject()
+		{
+		}
+
+		public QConObject(Transaction a_trans, QCon a_parent, QField a_field, object a_object
+			) : base(a_trans)
+		{
+			// the constraining object
+			// cache for the db4o object ID
+			// the YapClass
+			// needed for marshalling the request
+			// C/S only
+			i_parent = a_parent;
+			if (a_object is ICompare)
+			{
+				a_object = ((ICompare)a_object).Compare();
+			}
+			i_object = a_object;
+			i_field = a_field;
+		}
+
+		private void AssociateYapClass(Transaction a_trans, object a_object)
+		{
+			if (a_object == null)
+			{
+			}
+			else
+			{
+				//It seems that we need not result the following field
+				//i_object = null;
+				//i_comparator = Null.INSTANCE;
+				//i_classMetadata = null;
+				// FIXME: Setting the YapClass to null will prevent index use
+				// If the field is typed we can guess the right one with the
+				// following line. However this does break some SODA test cases.
+				// Revisit!
+				//            if(i_field != null){
+				//                i_classMetadata = i_field.getYapClass();
+				//            }
+				_classMetadata = a_trans.Container().ProduceClassMetadata(a_trans.Reflector().ForObject
+					(a_object));
+				if (_classMetadata != null)
+				{
+					i_object = _classMetadata.GetComparableObject(a_object);
+					if (a_object != i_object)
+					{
+						i_attributeProvider = _classMetadata.Config().QueryAttributeProvider();
+						_classMetadata = a_trans.Container().ProduceClassMetadata(a_trans.Reflector().ForObject
+							(i_object));
+					}
+					if (_classMetadata != null)
+					{
+						_classMetadata.CollectConstraints(a_trans, this, i_object, new _IVisitor4_84(this
+							));
+					}
+					else
+					{
+						AssociateYapClass(a_trans, null);
+					}
+				}
+				else
+				{
+					AssociateYapClass(a_trans, null);
+				}
+			}
+		}
+
+		private sealed class _IVisitor4_84 : IVisitor4
+		{
+			public _IVisitor4_84(QConObject _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Visit(object obj)
+			{
+				this._enclosing.AddConstraint((QCon)obj);
+			}
+
+			private readonly QConObject _enclosing;
+		}
+
+		public override bool CanBeIndexLeaf()
+		{
+			return i_object == null || ((_classMetadata != null && _classMetadata.IsValueType
+				()) || Evaluator().Identity());
+		}
+
+		public override bool CanLoadByIndex()
+		{
+			if (i_field == null)
+			{
+				return false;
+			}
+			if (i_field._fieldMetadata == null)
+			{
+				return false;
+			}
+			if (!i_field._fieldMetadata.HasIndex())
+			{
+				return false;
+			}
+			if (!i_evaluator.SupportsIndex())
+			{
+				return false;
+			}
+			return i_field._fieldMetadata.CanLoadByIndex();
+		}
+
+		internal override bool Evaluate(QCandidate a_candidate)
+		{
+			try
+			{
+				return a_candidate.Evaluate(this, i_evaluator);
+			}
+			catch (Exception e)
+			{
+				return false;
+			}
+		}
+
+		internal override void EvaluateEvaluationsExec(QCandidates a_candidates, bool rereadObject
+			)
+		{
+			if (i_field.IsQueryLeaf())
+			{
+				bool hasEvaluation = false;
+				IEnumerator i = IterateChildren();
+				while (i.MoveNext())
+				{
+					if (i.Current is QConEvaluation)
+					{
+						hasEvaluation = true;
+						break;
+					}
+				}
+				if (hasEvaluation)
+				{
+					a_candidates.Traverse(i_field);
+					IEnumerator j = IterateChildren();
+					while (j.MoveNext())
+					{
+						((QCon)j.Current).EvaluateEvaluationsExec(a_candidates, false);
+					}
+				}
+			}
+		}
+
+		internal override void EvaluateSelf()
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.EvaluateSelf.Log(Id());
+			}
+			if (_classMetadata != null)
+			{
+				if (!(_classMetadata is PrimitiveTypeMetadata))
+				{
+					if (!i_evaluator.Identity() && (_classMetadata.TypeHandler() is StandardReferenceTypeHandler
+						))
+					{
+						_checkClassMetadataOnly = true;
+					}
+					object transactionalObject = _classMetadata.WrapWithTransactionContext(Transaction
+						(), i_object);
+					_preparedComparison = _classMetadata.PrepareComparison(Context(), transactionalObject
+						);
+				}
+			}
+			base.EvaluateSelf();
+			_checkClassMetadataOnly = false;
+		}
+
+		private IContext Context()
+		{
+			return Transaction().Context();
+		}
+
+		internal override void Collect(QCandidates a_candidates)
+		{
+			if (i_field.IsClass())
+			{
+				a_candidates.Traverse(i_field);
+				a_candidates.Filter(i_candidates);
+			}
+		}
+
+		internal override void EvaluateSimpleExec(QCandidates a_candidates)
+		{
+			// TODO: The following can be skipped if we used the index on
+			//       this field to load the objects, if hasOrdering() is false
+			if (i_field.IsQueryLeaf() || IsNullConstraint())
+			{
+				a_candidates.Traverse(i_field);
+				PrepareComparison(i_field);
+				a_candidates.Filter(this);
+			}
+		}
+
+		internal virtual IPreparedComparison PrepareComparison(QCandidate candidate)
+		{
+			if (_preparedComparison != null)
+			{
+				return _preparedComparison;
+			}
+			return candidate.PrepareComparison(Container(), i_object);
+		}
+
+		internal override ClassMetadata GetYapClass()
+		{
+			return _classMetadata;
+		}
+
+		public override QField GetField()
+		{
+			return i_field;
+		}
+
+		internal virtual int GetObjectID()
+		{
+			if (i_objectID == 0)
+			{
+				i_objectID = i_trans.Container().GetID(i_trans, i_object);
+				if (i_objectID == 0)
+				{
+					i_objectID = -1;
+				}
+			}
+			return i_objectID;
+		}
+
+		public override bool HasObjectInParentPath(object obj)
+		{
+			if (obj == i_object)
+			{
+				return true;
+			}
+			return base.HasObjectInParentPath(obj);
+		}
+
+		public override int IdentityID()
+		{
+			if (i_evaluator.Identity())
+			{
+				int id = GetObjectID();
+				if (id != 0)
+				{
+					if (!(i_evaluator is QENot))
+					{
+						return id;
+					}
+				}
+			}
+			return 0;
+		}
+
+		internal override bool IsNullConstraint()
+		{
+			return i_object == null;
+		}
+
+		internal override void Log(string indent)
+		{
+		}
+
+		internal override string LogObject()
+		{
+			return string.Empty;
+		}
+
+		internal override void Marshall()
+		{
+			base.Marshall();
+			GetObjectID();
+			if (_classMetadata != null)
+			{
+				i_classMetadataID = _classMetadata.GetID();
+			}
+		}
+
+		public override bool OnSameFieldAs(QCon other)
+		{
+			if (!(other is Db4objects.Db4o.Internal.Query.Processor.QConObject))
+			{
+				return false;
+			}
+			return i_field == ((Db4objects.Db4o.Internal.Query.Processor.QConObject)other).i_field;
+		}
+
+		internal virtual void PrepareComparison(QField a_field)
+		{
+			if (IsNullConstraint() & !a_field.IsArray())
+			{
+				_preparedComparison = Null.Instance;
+			}
+			else
+			{
+				_preparedComparison = a_field.PrepareComparison(Context(), i_object);
+			}
+		}
+
+		internal override void RemoveChildrenJoins()
+		{
+			base.RemoveChildrenJoins();
+			_children = null;
+		}
+
+		internal override QCon ShareParent(object a_object, BooleanByRef removeExisting)
+		{
+			if (i_parent == null)
+			{
+				return null;
+			}
+			object obj = i_field.Coerce(a_object);
+			if (obj == No4.Instance)
+			{
+				return null;
+			}
+			return i_parent.AddSharedConstraint(i_field, obj);
+		}
+
+		internal override QConClass ShareParentForClass(IReflectClass a_class, BooleanByRef
+			 removeExisting)
+		{
+			if (i_parent == null)
+			{
+				return null;
+			}
+			QConClass newConstraint = new QConClass(i_trans, i_parent, i_field, a_class);
+			i_parent.AddConstraint(newConstraint);
+			return newConstraint;
+		}
+
+		internal object Translate(object candidate)
+		{
+			if (i_attributeProvider != null)
+			{
+				i_candidates.i_trans.Container().Activate(i_candidates.i_trans, candidate);
+				return i_attributeProvider.Attribute(candidate);
+			}
+			return candidate;
+		}
+
+		internal override void Unmarshall(Transaction trans)
+		{
+			if (i_trans != null)
+			{
+				return;
+			}
+			base.Unmarshall(trans);
+			if (i_object == null)
+			{
+				_preparedComparison = Null.Instance;
+			}
+			if (i_classMetadataID != 0)
+			{
+				_classMetadata = trans.Container().ClassMetadataForID(i_classMetadataID);
+			}
+			if (i_field != null)
+			{
+				i_field.Unmarshall(trans);
+			}
+			if (i_objectID > 0)
+			{
+				object obj = trans.Container().TryGetByID(trans, i_objectID);
+				if (obj != null)
+				{
+					i_object = obj;
+				}
+			}
+		}
+
+		public override void Visit(object obj)
+		{
+			QCandidate qc = (QCandidate)obj;
+			bool res = true;
+			bool processed = false;
+			if (_checkClassMetadataOnly)
+			{
+				ClassMetadata yc = qc.ReadClassMetadata();
+				if (yc != null)
+				{
+					res = i_evaluator.Not(_classMetadata.GetHigherHierarchy(yc) == _classMetadata);
+					processed = true;
+				}
+			}
+			if (!processed)
+			{
+				res = Evaluate(qc);
+			}
+			Visit1(qc.GetRoot(), this, res);
+		}
+
+		public override IConstraint Contains()
+		{
+			lock (StreamLock())
+			{
+				i_evaluator = i_evaluator.Add(new QEContains(true));
+				return this;
+			}
+		}
+
+		public override IConstraint Equal()
+		{
+			lock (StreamLock())
+			{
+				i_evaluator = i_evaluator.Add(new QEEqual());
+				return this;
+			}
+		}
+
+		public override object GetObject()
+		{
+			return i_object;
+		}
+
+		public override IConstraint Greater()
+		{
+			lock (StreamLock())
+			{
+				i_evaluator = i_evaluator.Add(new QEGreater());
+				return this;
+			}
+		}
+
+		public override IConstraint Identity()
+		{
+			lock (StreamLock())
+			{
+				if (i_object == null)
+				{
+					return this;
+				}
+				GetObjectID();
+				// TODO: this may not be correct for NOT
+				// It may be necessary to add an if(i_evaluator.identity())
+				RemoveChildrenJoins();
+				i_evaluator = i_evaluator.Add(new QEIdentity());
+				return this;
+			}
+		}
+
+		public override IConstraint ByExample()
+		{
+			lock (StreamLock())
+			{
+				AssociateYapClass(i_trans, i_object);
+				return this;
+			}
+		}
+
+		internal virtual void SetEvaluationMode()
+		{
+			if ((i_object == null) || EvaluationModeAlreadySet())
+			{
+				return;
+			}
+			int id = GetObjectID();
+			if (id < 0)
+			{
+				ByExample();
+			}
+			else
+			{
+				_classMetadata = i_trans.Container().ProduceClassMetadata(i_trans.Reflector().ForObject
+					(i_object));
+				Identity();
+			}
+		}
+
+		internal virtual bool EvaluationModeAlreadySet()
+		{
+			return _classMetadata != null;
+		}
+
+		public override IConstraint Like()
+		{
+			lock (StreamLock())
+			{
+				i_evaluator = i_evaluator.Add(new QEContains(false));
+				return this;
+			}
+		}
+
+		public override IConstraint Smaller()
+		{
+			lock (StreamLock())
+			{
+				i_evaluator = i_evaluator.Add(new QESmaller());
+				return this;
+			}
+		}
+
+		public override IConstraint StartsWith(bool caseSensitive)
+		{
+			lock (StreamLock())
+			{
+				i_evaluator = i_evaluator.Add(new QEStartsWith(caseSensitive));
+				return this;
+			}
+		}
+
+		public override IConstraint EndsWith(bool caseSensitive)
+		{
+			lock (StreamLock())
+			{
+				i_evaluator = i_evaluator.Add(new QEEndsWith(caseSensitive));
+				return this;
+			}
+		}
+
+		public override string ToString()
+		{
+			string str = "QConObject ";
+			if (i_object != null)
+			{
+				str += i_object.ToString();
+			}
+			return str;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConPath.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConPath.cs
new file mode 100644
index 0000000..516f01f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConPath.cs
@@ -0,0 +1,166 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <summary>
+	/// Placeholder for a constraint, only necessary to attach children
+	/// to the query graph.
+	/// </summary>
+	/// <remarks>
+	/// Placeholder for a constraint, only necessary to attach children
+	/// to the query graph.
+	/// Added upon a call to Query#descend(), if there is no
+	/// other place to hook up a new constraint.
+	/// </remarks>
+	/// <exclude></exclude>
+	public class QConPath : QConClass
+	{
+		public QConPath()
+		{
+		}
+
+		internal QConPath(Transaction a_trans, QCon a_parent, QField a_field) : base(a_trans
+			, a_parent, a_field, null)
+		{
+			if (a_field != null)
+			{
+				_classMetadata = a_field.GetFieldType();
+			}
+		}
+
+		public override bool CanLoadByIndex()
+		{
+			return false;
+		}
+
+		internal override bool Evaluate(QCandidate a_candidate)
+		{
+			if (!a_candidate.FieldIsAvailable())
+			{
+				VisitOnNull(a_candidate.GetRoot());
+			}
+			return true;
+		}
+
+		internal override void EvaluateSelf()
+		{
+		}
+
+		// do nothing
+		internal override bool IsNullConstraint()
+		{
+			return !HasChildren();
+		}
+
+		internal override QConClass ShareParentForClass(IReflectClass a_class, BooleanByRef
+			 removeExisting)
+		{
+			if (i_parent == null)
+			{
+				return null;
+			}
+			QConClass newConstraint = new QConClass(i_trans, i_parent, GetField(), a_class);
+			Morph(removeExisting, newConstraint, a_class);
+			return newConstraint;
+		}
+
+		internal override QCon ShareParent(object a_object, BooleanByRef removeExisting)
+		{
+			if (i_parent == null)
+			{
+				return null;
+			}
+			object obj = GetField().Coerce(a_object);
+			if (obj == No4.Instance)
+			{
+				QCon falseConstraint = new QConUnconditional(i_trans, false);
+				Morph(removeExisting, falseConstraint, ReflectClassForObject(obj));
+				return falseConstraint;
+			}
+			QConObject newConstraint = new QConObject(i_trans, i_parent, GetField(), obj);
+			Morph(removeExisting, newConstraint, ReflectClassForObject(obj));
+			return newConstraint;
+		}
+
+		private IReflectClass ReflectClassForObject(object obj)
+		{
+			return i_trans.Reflector().ForObject(obj);
+		}
+
+		// Our QConPath objects are just placeholders to fields,
+		// so the parents are reachable.
+		// If we find a "real" constraint, we throw the QPath
+		// out and replace it with the other constraint. 
+		private void Morph(BooleanByRef removeExisting, QCon newConstraint, IReflectClass
+			 claxx)
+		{
+			bool mayMorph = true;
+			if (claxx != null)
+			{
+				ClassMetadata yc = i_trans.Container().ProduceClassMetadata(claxx);
+				if (yc != null)
+				{
+					IEnumerator i = IterateChildren();
+					while (i.MoveNext())
+					{
+						QField qf = ((QCon)i.Current).GetField();
+						if (!yc.HasField(i_trans.Container(), qf.Name()))
+						{
+							mayMorph = false;
+							break;
+						}
+					}
+				}
+			}
+			// }
+			if (mayMorph)
+			{
+				IEnumerator j = IterateChildren();
+				while (j.MoveNext())
+				{
+					newConstraint.AddConstraint((QCon)j.Current);
+				}
+				if (HasJoins())
+				{
+					IEnumerator k = IterateJoins();
+					while (k.MoveNext())
+					{
+						QConJoin qcj = (QConJoin)k.Current;
+						qcj.ExchangeConstraint(this, newConstraint);
+						newConstraint.AddJoin(qcj);
+					}
+				}
+				i_parent.ExchangeConstraint(this, newConstraint);
+				removeExisting.value = true;
+			}
+			else
+			{
+				i_parent.AddConstraint(newConstraint);
+			}
+		}
+
+		internal sealed override bool VisitSelfOnNull()
+		{
+			return false;
+		}
+
+		public override string ToString()
+		{
+			return "QConPath " + base.ToString();
+		}
+
+		public override void SetProcessedByIndex()
+		{
+			if (ChildrenCount() <= 1)
+			{
+				InternalSetProcessedByIndex();
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConUnconditional.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConUnconditional.cs
new file mode 100644
index 0000000..7fb5f34
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConUnconditional.cs
@@ -0,0 +1,34 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <exclude></exclude>
+	public class QConUnconditional : QCon
+	{
+		private bool _value;
+
+		public QConUnconditional()
+		{
+		}
+
+		public QConUnconditional(Transaction trans, bool value) : base(trans)
+		{
+			// cannot be final for C/S unmarshalling
+			// C/S only
+			_value = value;
+		}
+
+		internal override void EvaluateSimpleExec(QCandidates a_candidates)
+		{
+			a_candidates.Filter(this);
+		}
+
+		internal override bool Evaluate(QCandidate a_candidate)
+		{
+			return _value;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConstraints.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConstraints.cs
new file mode 100644
index 0000000..2e7bd9e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QConstraints.cs
@@ -0,0 +1,168 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <summary>Array of constraints for queries.</summary>
+	/// <remarks>
+	/// Array of constraints for queries.
+	/// Necessary to be returned to Query#constraints()
+	/// </remarks>
+	/// <exclude></exclude>
+	public class QConstraints : QCon, IConstraints
+	{
+		private IConstraint[] i_constraints;
+
+		internal QConstraints(Transaction a_trans, IConstraint[] constraints) : base(a_trans
+			)
+		{
+			i_constraints = constraints;
+		}
+
+		internal override IConstraint Join(IConstraint a_with, bool a_and)
+		{
+			lock (StreamLock())
+			{
+				if (!(a_with is QCon))
+				{
+					return null;
+				}
+				// resolving multiple constraints happens in QCon for
+				// a_with, so we simply turn things around
+				return ((QCon)a_with).Join1(this, a_and);
+			}
+		}
+
+		public virtual IConstraint[] ToArray()
+		{
+			lock (StreamLock())
+			{
+				return i_constraints;
+			}
+		}
+
+		public override IConstraint Contains()
+		{
+			lock (StreamLock())
+			{
+				for (int i = 0; i < i_constraints.Length; i++)
+				{
+					i_constraints[i].Contains();
+				}
+				return this;
+			}
+		}
+
+		public override IConstraint Equal()
+		{
+			lock (StreamLock())
+			{
+				for (int i = 0; i < i_constraints.Length; i++)
+				{
+					i_constraints[i].Equal();
+				}
+				return this;
+			}
+		}
+
+		public override IConstraint Greater()
+		{
+			lock (StreamLock())
+			{
+				for (int i = 0; i < i_constraints.Length; i++)
+				{
+					i_constraints[i].Greater();
+				}
+				return this;
+			}
+		}
+
+		public override IConstraint Identity()
+		{
+			lock (StreamLock())
+			{
+				for (int i = 0; i < i_constraints.Length; i++)
+				{
+					i_constraints[i].Identity();
+				}
+				return this;
+			}
+		}
+
+		public override IConstraint Not()
+		{
+			lock (StreamLock())
+			{
+				for (int i = 0; i < i_constraints.Length; i++)
+				{
+					i_constraints[i].Not();
+				}
+				return this;
+			}
+		}
+
+		public override IConstraint Like()
+		{
+			lock (StreamLock())
+			{
+				for (int i = 0; i < i_constraints.Length; i++)
+				{
+					i_constraints[i].Like();
+				}
+				return this;
+			}
+		}
+
+		public override IConstraint StartsWith(bool caseSensitive)
+		{
+			lock (StreamLock())
+			{
+				for (int i = 0; i < i_constraints.Length; i++)
+				{
+					i_constraints[i].StartsWith(caseSensitive);
+				}
+				return this;
+			}
+		}
+
+		public override IConstraint EndsWith(bool caseSensitive)
+		{
+			lock (StreamLock())
+			{
+				for (int i = 0; i < i_constraints.Length; i++)
+				{
+					i_constraints[i].EndsWith(caseSensitive);
+				}
+				return this;
+			}
+		}
+
+		public override IConstraint Smaller()
+		{
+			lock (StreamLock())
+			{
+				for (int i = 0; i < i_constraints.Length; i++)
+				{
+					i_constraints[i].Smaller();
+				}
+				return this;
+			}
+		}
+
+		public override object GetObject()
+		{
+			lock (StreamLock())
+			{
+				object[] objects = new object[i_constraints.Length];
+				for (int i = 0; i < i_constraints.Length; i++)
+				{
+					objects[i] = i_constraints[i].GetObject();
+				}
+				return objects;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QE.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QE.cs
new file mode 100644
index 0000000..7fb7013
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QE.cs
@@ -0,0 +1,93 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Types;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <summary>Query Evaluator - Represents such things as >, >=, <, <=, EQUAL, LIKE, etc.
+	/// 	</summary>
+	/// <remarks>Query Evaluator - Represents such things as >, >=, <, <=, EQUAL, LIKE, etc.
+	/// 	</remarks>
+	/// <exclude></exclude>
+	public class QE : IUnversioned
+	{
+		internal static readonly QE Default = new QE();
+
+		public const int Nulls = 0;
+
+		public const int Smaller = 1;
+
+		public const int Equal = 2;
+
+		public const int Greater = 3;
+
+		internal virtual QE Add(QE evaluator)
+		{
+			return evaluator;
+		}
+
+		public virtual bool Identity()
+		{
+			return false;
+		}
+
+		internal virtual bool IsDefault()
+		{
+			return true;
+		}
+
+		internal virtual bool Evaluate(QConObject constraint, QCandidate candidate, object
+			 obj)
+		{
+			IPreparedComparison prepareComparison = constraint.PrepareComparison(candidate);
+			if (obj == null)
+			{
+				return prepareComparison is Null;
+			}
+			if (prepareComparison is PreparedArrayContainsComparison)
+			{
+				return ((PreparedArrayContainsComparison)prepareComparison).IsEqual(obj);
+			}
+			return prepareComparison.CompareTo(obj) == 0;
+		}
+
+		public override bool Equals(object obj)
+		{
+			return obj != null && obj.GetType() == this.GetType();
+		}
+
+		public override int GetHashCode()
+		{
+			return GetType().GetHashCode();
+		}
+
+		// overridden in QENot 
+		internal virtual bool Not(bool res)
+		{
+			return res;
+		}
+
+		/// <summary>Specifies which part of the index to take.</summary>
+		/// <remarks>
+		/// Specifies which part of the index to take.
+		/// Array elements:
+		/// [0] - smaller
+		/// [1] - equal
+		/// [2] - greater
+		/// [3] - nulls
+		/// </remarks>
+		/// <param name="bits"></param>
+		public virtual void IndexBitMap(bool[] bits)
+		{
+			bits[QE.Equal] = true;
+		}
+
+		public virtual bool SupportsIndex()
+		{
+			return true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEAbstract.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEAbstract.cs
new file mode 100644
index 0000000..b78b7b4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEAbstract.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <exclude></exclude>
+	public abstract class QEAbstract : QE
+	{
+		internal override QE Add(QE evaluator)
+		{
+			QE qe = new QEMulti();
+			qe.Add(this);
+			qe.Add(evaluator);
+			return qe;
+		}
+
+		internal override bool IsDefault()
+		{
+			return false;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEContains.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEContains.cs
new file mode 100644
index 0000000..7331380
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEContains.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <exclude></exclude>
+	public class QEContains : QEStringCmp
+	{
+		/// <summary>for C/S messaging only</summary>
+		public QEContains()
+		{
+		}
+
+		public QEContains(bool caseSensitive_) : base(caseSensitive_)
+		{
+		}
+
+		protected override bool CompareStrings(string candidate, string constraint)
+		{
+			return candidate.IndexOf(constraint) > -1;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEEndsWith.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEEndsWith.cs
new file mode 100644
index 0000000..0615d71
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEEndsWith.cs
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <exclude></exclude>
+	public class QEEndsWith : QEStringCmp
+	{
+		/// <summary>for C/S messaging only</summary>
+		public QEEndsWith()
+		{
+		}
+
+		public QEEndsWith(bool caseSensitive_) : base(caseSensitive_)
+		{
+		}
+
+		protected override bool CompareStrings(string candidate, string constraint)
+		{
+			int lastIndex = candidate.LastIndexOf(constraint);
+			if (lastIndex == -1)
+			{
+				return false;
+			}
+			return lastIndex == candidate.Length - constraint.Length;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEEqual.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEEqual.cs
new file mode 100644
index 0000000..5719435
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEEqual.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <exclude></exclude>
+	public class QEEqual : QEAbstract
+	{
+		public override void IndexBitMap(bool[] bits)
+		{
+			bits[QE.Equal] = true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEGreater.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEGreater.cs
new file mode 100644
index 0000000..484b5b9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEGreater.cs
@@ -0,0 +1,32 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <exclude></exclude>
+	public class QEGreater : QEAbstract
+	{
+		internal override bool Evaluate(QConObject constraint, QCandidate candidate, object
+			 obj)
+		{
+			if (obj == null)
+			{
+				return false;
+			}
+			IPreparedComparison preparedComparison = constraint.PrepareComparison(candidate);
+			if (preparedComparison is PreparedArrayContainsComparison)
+			{
+				return ((PreparedArrayContainsComparison)preparedComparison).IsSmallerThan(obj);
+			}
+			return preparedComparison.CompareTo(obj) < 0;
+		}
+
+		public override void IndexBitMap(bool[] bits)
+		{
+			bits[QE.Greater] = true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEIdentity.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEIdentity.cs
new file mode 100644
index 0000000..3f5ac9e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEIdentity.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <exclude></exclude>
+	public class QEIdentity : QEEqual
+	{
+		private int i_objectID;
+
+		public override bool Identity()
+		{
+			return true;
+		}
+
+		internal override bool Evaluate(QConObject a_constraint, QCandidate a_candidate, 
+			object a_value)
+		{
+			if (i_objectID == 0)
+			{
+				i_objectID = a_constraint.GetObjectID();
+			}
+			return a_candidate._key == i_objectID;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEMulti.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEMulti.cs
new file mode 100644
index 0000000..a98fc46
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEMulti.cs
@@ -0,0 +1,85 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <exclude></exclude>
+	public class QEMulti : QE
+	{
+		private Collection4 i_evaluators = new Collection4();
+
+		// used by .net LINQ tests
+		public virtual IEnumerable Evaluators()
+		{
+			return i_evaluators;
+		}
+
+		internal override QE Add(QE evaluator)
+		{
+			i_evaluators.Ensure(evaluator);
+			return this;
+		}
+
+		public override bool Identity()
+		{
+			bool ret = false;
+			IEnumerator i = i_evaluators.GetEnumerator();
+			while (i.MoveNext())
+			{
+				if (((QE)i.Current).Identity())
+				{
+					ret = true;
+				}
+				else
+				{
+					return false;
+				}
+			}
+			return ret;
+		}
+
+		internal override bool IsDefault()
+		{
+			return false;
+		}
+
+		internal override bool Evaluate(QConObject a_constraint, QCandidate a_candidate, 
+			object a_value)
+		{
+			IEnumerator i = i_evaluators.GetEnumerator();
+			while (i.MoveNext())
+			{
+				if (((QE)i.Current).Evaluate(a_constraint, a_candidate, a_value))
+				{
+					return true;
+				}
+			}
+			return false;
+		}
+
+		public override void IndexBitMap(bool[] bits)
+		{
+			IEnumerator i = i_evaluators.GetEnumerator();
+			while (i.MoveNext())
+			{
+				((QE)i.Current).IndexBitMap(bits);
+			}
+		}
+
+		public override bool SupportsIndex()
+		{
+			IEnumerator i = i_evaluators.GetEnumerator();
+			while (i.MoveNext())
+			{
+				if (!((QE)i.Current).SupportsIndex())
+				{
+					return false;
+				}
+			}
+			return true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QENot.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QENot.cs
new file mode 100644
index 0000000..354a168
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QENot.cs
@@ -0,0 +1,71 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <exclude></exclude>
+	public class QENot : QE
+	{
+		private QE i_evaluator;
+
+		public QENot()
+		{
+		}
+
+		internal QENot(QE a_evaluator)
+		{
+			// CS
+			i_evaluator = a_evaluator;
+		}
+
+		internal override QE Add(QE evaluator)
+		{
+			if (!(evaluator is Db4objects.Db4o.Internal.Query.Processor.QENot))
+			{
+				i_evaluator = i_evaluator.Add(evaluator);
+			}
+			return this;
+		}
+
+		public virtual QE Evaluator()
+		{
+			return i_evaluator;
+		}
+
+		public override bool Identity()
+		{
+			return i_evaluator.Identity();
+		}
+
+		internal override bool IsDefault()
+		{
+			return false;
+		}
+
+		internal override bool Evaluate(QConObject a_constraint, QCandidate a_candidate, 
+			object a_value)
+		{
+			return !i_evaluator.Evaluate(a_constraint, a_candidate, a_value);
+		}
+
+		internal override bool Not(bool res)
+		{
+			return !res;
+		}
+
+		public override void IndexBitMap(bool[] bits)
+		{
+			i_evaluator.IndexBitMap(bits);
+			for (int i = 0; i < 4; i++)
+			{
+				bits[i] = !bits[i];
+			}
+		}
+
+		public override bool SupportsIndex()
+		{
+			return i_evaluator.SupportsIndex();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QESmaller.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QESmaller.cs
new file mode 100644
index 0000000..bb5026a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QESmaller.cs
@@ -0,0 +1,32 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <exclude></exclude>
+	public class QESmaller : QEAbstract
+	{
+		internal override bool Evaluate(QConObject constraint, QCandidate candidate, object
+			 obj)
+		{
+			if (obj == null)
+			{
+				return false;
+			}
+			IPreparedComparison preparedComparison = constraint.PrepareComparison(candidate);
+			if (preparedComparison is PreparedArrayContainsComparison)
+			{
+				return ((PreparedArrayContainsComparison)preparedComparison).IsGreaterThan(obj);
+			}
+			return preparedComparison.CompareTo(obj) > 0;
+		}
+
+		public override void IndexBitMap(bool[] bits)
+		{
+			bits[QE.Smaller] = true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEStartsWith.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEStartsWith.cs
new file mode 100644
index 0000000..bc862ef
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEStartsWith.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <exclude></exclude>
+	public class QEStartsWith : QEStringCmp
+	{
+		/// <summary>for C/S messaging only</summary>
+		public QEStartsWith()
+		{
+		}
+
+		public QEStartsWith(bool caseSensitive_) : base(caseSensitive_)
+		{
+		}
+
+		protected override bool CompareStrings(string candidate, string constraint)
+		{
+			return candidate.IndexOf(constraint) == 0;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEStringCmp.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEStringCmp.cs
new file mode 100644
index 0000000..c1f428a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QEStringCmp.cs
@@ -0,0 +1,51 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <exclude></exclude>
+	public abstract class QEStringCmp : QEAbstract
+	{
+		private bool caseSensitive;
+
+		/// <summary>for C/S messaging only</summary>
+		public QEStringCmp()
+		{
+		}
+
+		public QEStringCmp(bool caseSensitive_)
+		{
+			caseSensitive = caseSensitive_;
+		}
+
+		internal override bool Evaluate(QConObject constraint, QCandidate candidate, object
+			 obj)
+		{
+			if (obj != null)
+			{
+				if (obj is ByteArrayBuffer)
+				{
+					obj = candidate.ReadString((ByteArrayBuffer)obj);
+				}
+				string candidateStringValue = obj.ToString();
+				string stringConstraint = constraint.GetObject().ToString();
+				if (!caseSensitive)
+				{
+					candidateStringValue = candidateStringValue.ToLower();
+					stringConstraint = stringConstraint.ToLower();
+				}
+				return CompareStrings(candidateStringValue, stringConstraint);
+			}
+			return constraint.GetObject() == null;
+		}
+
+		public override bool SupportsIndex()
+		{
+			return false;
+		}
+
+		protected abstract bool CompareStrings(string candidate, string constraint);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QField.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QField.cs
new file mode 100644
index 0000000..548b763
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QField.cs
@@ -0,0 +1,156 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Types;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <exclude></exclude>
+	public class QField : IVisitor4, IUnversioned
+	{
+		[System.NonSerialized]
+		internal Transaction i_trans;
+
+		private string i_name;
+
+		[System.NonSerialized]
+		internal FieldMetadata _fieldMetadata;
+
+		private int i_classMetadataID;
+
+		private int _fieldHandle;
+
+		public QField()
+		{
+		}
+
+		public QField(Transaction a_trans, string name, FieldMetadata fieldMetadata, int 
+			classMetadataID, int a_index)
+		{
+			// C/S only	
+			i_trans = a_trans;
+			i_name = name;
+			_fieldMetadata = fieldMetadata;
+			i_classMetadataID = classMetadataID;
+			_fieldHandle = a_index;
+			if (_fieldMetadata != null)
+			{
+				if (!_fieldMetadata.Alive())
+				{
+					_fieldMetadata = null;
+				}
+			}
+		}
+
+		public virtual string Name()
+		{
+			return i_name;
+		}
+
+		internal virtual object Coerce(object a_object)
+		{
+			IReflectClass claxx = null;
+			if (a_object != null)
+			{
+				if (a_object is IReflectClass)
+				{
+					claxx = (IReflectClass)a_object;
+				}
+				else
+				{
+					claxx = i_trans.Reflector().ForObject(a_object);
+				}
+			}
+			else
+			{
+				// TODO: Review this line for NullableArrayHandling 
+				return a_object;
+			}
+			if (_fieldMetadata == null)
+			{
+				return a_object;
+			}
+			return _fieldMetadata.Coerce(claxx, a_object);
+		}
+
+		internal virtual ClassMetadata GetFieldType()
+		{
+			if (_fieldMetadata != null)
+			{
+				return _fieldMetadata.FieldType();
+			}
+			return null;
+		}
+
+		public virtual FieldMetadata GetFieldMetadata()
+		{
+			return _fieldMetadata;
+		}
+
+		internal virtual bool IsArray()
+		{
+			return _fieldMetadata != null && Handlers4.HandlesArray(_fieldMetadata.GetHandler
+				());
+		}
+
+		internal virtual bool IsClass()
+		{
+			return _fieldMetadata == null || Handlers4.HandlesClass(_fieldMetadata.GetHandler
+				());
+		}
+
+		internal virtual bool IsQueryLeaf()
+		{
+			return _fieldMetadata != null && Handlers4.IsQueryLeaf(_fieldMetadata.GetHandler(
+				));
+		}
+
+		internal virtual IPreparedComparison PrepareComparison(IContext context, object obj
+			)
+		{
+			if (_fieldMetadata != null)
+			{
+				return _fieldMetadata.PrepareComparison(context, obj);
+			}
+			if (obj == null)
+			{
+				return Null.Instance;
+			}
+			ClassMetadata yc = i_trans.Container().ProduceClassMetadata(i_trans.Reflector().ForObject
+				(obj));
+			FieldMetadata yf = yc.FieldMetadataForName(Name());
+			if (yf != null)
+			{
+				return yf.PrepareComparison(context, obj);
+			}
+			return null;
+		}
+
+		internal virtual void Unmarshall(Transaction a_trans)
+		{
+			if (i_classMetadataID != 0)
+			{
+				ClassMetadata yc = a_trans.Container().ClassMetadataForID(i_classMetadataID);
+				_fieldMetadata = (FieldMetadata)yc._aspects[_fieldHandle];
+			}
+		}
+
+		public virtual void Visit(object obj)
+		{
+			((QCandidate)obj).UseField(this);
+		}
+
+		public override string ToString()
+		{
+			if (_fieldMetadata != null)
+			{
+				return "QField " + _fieldMetadata.ToString();
+			}
+			return base.ToString();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QPending.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QPending.cs
new file mode 100644
index 0000000..0f37045
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QPending.cs
@@ -0,0 +1,65 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <exclude></exclude>
+	internal class QPending : Tree
+	{
+		internal readonly QConJoin _join;
+
+		internal QCon _constraint;
+
+		internal int _result;
+
+		internal const int False = -4;
+
+		internal const int Both = 1;
+
+		internal const int True = 2;
+
+		internal QPending(QConJoin a_join, QCon a_constraint, bool a_firstResult)
+		{
+			// Constants, so QConJoin.evaluatePending is made easy:
+			_join = a_join;
+			_constraint = a_constraint;
+			_result = a_firstResult ? True : False;
+		}
+
+		public override int Compare(Tree a_to)
+		{
+			return _constraint.Id() - ((Db4objects.Db4o.Internal.Query.Processor.QPending)a_to
+				)._constraint.Id();
+		}
+
+		internal virtual void ChangeConstraint()
+		{
+			_constraint = _join.GetOtherConstraint(_constraint);
+		}
+
+		public override object ShallowClone()
+		{
+			Db4objects.Db4o.Internal.Query.Processor.QPending pending = InternalClonePayload(
+				);
+			base.ShallowCloneInternal(pending);
+			return pending;
+		}
+
+		internal virtual Db4objects.Db4o.Internal.Query.Processor.QPending InternalClonePayload
+			()
+		{
+			Db4objects.Db4o.Internal.Query.Processor.QPending pending = new Db4objects.Db4o.Internal.Query.Processor.QPending
+				(_join, _constraint, false);
+			pending._result = _result;
+			return pending;
+		}
+
+		public override object Key()
+		{
+			throw new NotImplementedException();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QQuery.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QQuery.cs
new file mode 100644
index 0000000..a52a68d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QQuery.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <summary>QQuery is the users hook on our graph.</summary>
+	/// <remarks>
+	/// QQuery is the users hook on our graph.
+	/// A QQuery is defined by it's constraints.
+	/// </remarks>
+	/// <exclude></exclude>
+	public class QQuery : QQueryBase, IQuery
+	{
+		public QQuery()
+		{
+		}
+
+		public QQuery(Transaction a_trans, Db4objects.Db4o.Internal.Query.Processor.QQuery
+			 a_parent, string a_field) : base(a_trans, a_parent, a_field)
+		{
+		}
+		// C/S only
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QQueryBase.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QQueryBase.cs
new file mode 100644
index 0000000..85c7162
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Processor/QQueryBase.cs
@@ -0,0 +1,1206 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using System.Text;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Query;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Internal.Query.Result;
+using Db4objects.Db4o.Query;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Types;
+using Sharpen.Util;
+
+namespace Db4objects.Db4o.Internal.Query.Processor
+{
+	/// <summary>QQuery is the users hook on our graph.</summary>
+	/// <remarks>
+	/// QQuery is the users hook on our graph.
+	/// A QQuery is defined by it's constraints.
+	/// NOTE: This is just a 'partial' base class to allow for variant implementations
+	/// in db4oj and db4ojdk1.2. It assumes that itself is an instance of QQuery
+	/// and should never be used explicitly.
+	/// </remarks>
+	/// <exclude></exclude>
+	public abstract class QQueryBase : IInternalQuery, IUnversioned
+	{
+		[System.NonSerialized]
+		internal Db4objects.Db4o.Internal.Transaction _trans;
+
+		private Collection4 i_constraints = new Collection4();
+
+		private QQuery i_parent;
+
+		private string i_field;
+
+		[System.NonSerialized]
+		private QueryEvaluationMode _evaluationMode;
+
+		private int _prefetchDepth;
+
+		private int _prefetchCount;
+
+		private int _evaluationModeAsInt;
+
+		private IQueryComparator _comparator;
+
+		[System.NonSerialized]
+		private readonly QQuery _this;
+
+		private IList _orderings;
+
+		protected QQueryBase()
+		{
+			// C/S only
+			_this = Cast(this);
+		}
+
+		protected QQueryBase(Db4objects.Db4o.Internal.Transaction a_trans, QQuery a_parent
+			, string a_field)
+		{
+			_this = Cast(this);
+			_trans = a_trans;
+			i_parent = a_parent;
+			i_field = a_field;
+		}
+
+		public virtual void CaptureQueryResultConfig()
+		{
+			Config4Impl config = _trans.Container().Config();
+			_evaluationMode = config.EvaluationMode();
+			_prefetchDepth = config.PrefetchDepth();
+			_prefetchCount = config.PrefetchObjectCount();
+		}
+
+		internal virtual void AddConstraint(QCon a_constraint)
+		{
+			i_constraints.Add(a_constraint);
+		}
+
+		private void AddConstraint(Collection4 col, object obj)
+		{
+			if (AttachToExistingConstraints(col, obj, true))
+			{
+				return;
+			}
+			if (AttachToExistingConstraints(col, obj, false))
+			{
+				return;
+			}
+			QConObject newConstraint = new QConObject(_trans, null, null, obj);
+			AddConstraint(newConstraint);
+			col.Add(newConstraint);
+		}
+
+		private bool AttachToExistingConstraints(Collection4 newConstraintsCollector, object
+			 obj, bool onlyForPaths)
+		{
+			bool found = false;
+			IEnumerator j = IterateConstraints();
+			while (j.MoveNext())
+			{
+				QCon existingConstraint = (QCon)j.Current;
+				BooleanByRef removeExisting = new BooleanByRef(false);
+				if (!onlyForPaths || (existingConstraint is QConPath))
+				{
+					QCon newConstraint = existingConstraint.ShareParent(obj, removeExisting);
+					if (newConstraint != null)
+					{
+						newConstraintsCollector.Add(newConstraint);
+						AddConstraint(newConstraint);
+						if (removeExisting.value)
+						{
+							RemoveConstraint(existingConstraint);
+						}
+						found = true;
+						if (!onlyForPaths)
+						{
+							break;
+						}
+					}
+				}
+			}
+			return found;
+		}
+
+		/// <summary>Search for slot that corresponds to class.</summary>
+		/// <remarks>
+		/// Search for slot that corresponds to class. <br />If not found add it.
+		/// <br />Constrain it. <br />
+		/// </remarks>
+		public virtual IConstraint Constrain(object example)
+		{
+			lock (StreamLock())
+			{
+				IReflectClass claxx = ReflectClassForClass(example);
+				if (claxx != null)
+				{
+					return AddClassConstraint(claxx);
+				}
+				QConEvaluation eval = Platform4.EvaluationCreate(_trans, example);
+				if (eval != null)
+				{
+					return AddEvaluationToAllConstraints(eval);
+				}
+				Collection4 constraints = new Collection4();
+				AddConstraint(constraints, example);
+				return ToConstraint(constraints);
+			}
+		}
+
+		private IConstraint AddEvaluationToAllConstraints(QConEvaluation eval)
+		{
+			if (i_constraints.Size() == 0)
+			{
+				_trans.Container().ClassCollection().IterateTopLevelClasses(new _IVisitor4_139(this
+					));
+			}
+			IEnumerator i = IterateConstraints();
+			while (i.MoveNext())
+			{
+				((QCon)i.Current).AddConstraint(eval);
+			}
+			// FIXME: should return valid Constraint object
+			return null;
+		}
+
+		private sealed class _IVisitor4_139 : IVisitor4
+		{
+			public _IVisitor4_139(QQueryBase _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Visit(object obj)
+			{
+				ClassMetadata classMetadata = (ClassMetadata)obj;
+				QConClass qcc = new QConClass(this._enclosing._trans, classMetadata.ClassReflector
+					());
+				this._enclosing.AddConstraint(qcc);
+				this._enclosing.ToConstraint(this._enclosing.i_constraints).Or(qcc);
+			}
+
+			private readonly QQueryBase _enclosing;
+		}
+
+		private IConstraint AddClassConstraint(IReflectClass claxx)
+		{
+			if (IsTheObjectClass(claxx))
+			{
+				return null;
+			}
+			if (claxx.IsInterface())
+			{
+				return AddInterfaceConstraint(claxx);
+			}
+			Collection4 newConstraints = IntroduceClassConstrain(claxx);
+			if (newConstraints.IsEmpty())
+			{
+				QConClass qcc = new QConClass(_trans, claxx);
+				AddConstraint(qcc);
+				return qcc;
+			}
+			return ToConstraint(newConstraints);
+		}
+
+		private Collection4 IntroduceClassConstrain(IReflectClass claxx)
+		{
+			Collection4 newConstraints = new Collection4();
+			IEnumerator existingConstraints = IterateConstraints();
+			while (existingConstraints.MoveNext())
+			{
+				QCon existingConstraint = (QConObject)existingConstraints.Current;
+				BooleanByRef removeExisting = new BooleanByRef(false);
+				QCon newConstraint = existingConstraint.ShareParentForClass(claxx, removeExisting
+					);
+				if (newConstraint != null)
+				{
+					newConstraints.Add(newConstraint);
+					AddConstraint(newConstraint);
+					if (removeExisting.value)
+					{
+						RemoveConstraint(existingConstraint);
+					}
+				}
+			}
+			return newConstraints;
+		}
+
+		private bool IsTheObjectClass(IReflectClass claxx)
+		{
+			return claxx.Equals(Stream()._handlers.IclassObject);
+		}
+
+		private IConstraint AddInterfaceConstraint(IReflectClass claxx)
+		{
+			Collection4 classes = Stream().ClassCollection().ForInterface(claxx);
+			if (classes.Size() == 0)
+			{
+				QConClass qcc = new QConClass(_trans, null, null, claxx);
+				AddConstraint(qcc);
+				return qcc;
+			}
+			IEnumerator i = classes.GetEnumerator();
+			IConstraint constr = null;
+			while (i.MoveNext())
+			{
+				ClassMetadata classMetadata = (ClassMetadata)i.Current;
+				IReflectClass classMetadataClaxx = classMetadata.ClassReflector();
+				if (classMetadataClaxx != null)
+				{
+					if (!classMetadataClaxx.IsInterface())
+					{
+						if (constr == null)
+						{
+							constr = Constrain(classMetadataClaxx);
+						}
+						else
+						{
+							constr = constr.Or(Constrain(classMetadata.ClassReflector()));
+						}
+					}
+				}
+			}
+			return constr;
+		}
+
+		private IReflectClass ReflectClassForClass(object example)
+		{
+			if (example is IReflectClass)
+			{
+				return (IReflectClass)example;
+			}
+			if (example is Type)
+			{
+				return _trans.Reflector().ForClass((Type)example);
+			}
+			return null;
+		}
+
+		public virtual IConstraints Constraints()
+		{
+			lock (StreamLock())
+			{
+				IConstraint[] constraints = new IConstraint[i_constraints.Size()];
+				i_constraints.ToArray(constraints);
+				return new QConstraints(_trans, constraints);
+			}
+		}
+
+		public virtual IQuery Descend(string a_field)
+		{
+			lock (StreamLock())
+			{
+				QQuery query = new QQuery(_trans, _this, a_field);
+				IntByRef run = new IntByRef(1);
+				if (!Descend1(query, a_field, run))
+				{
+					// try to add unparented nodes on the second run,
+					// if not added in the first run and a descendant
+					// was not found
+					if (run.value == 1)
+					{
+						run.value = 2;
+						if (!Descend1(query, a_field, run))
+						{
+							new QConUnconditional(_trans, false).Attach(query, a_field);
+						}
+					}
+				}
+				return query;
+			}
+		}
+
+		private bool Descend1(QQuery query, string fieldName, IntByRef run)
+		{
+			if (run.value == 2 || i_constraints.Size() == 0)
+			{
+				// On the second run we are really creating a second independant
+				// query network that is not joined to other higher level
+				// constraints.
+				// Let's see how this works out. We may need to join networks.
+				run.value = 0;
+				// prevent a double run of this code
+				Stream().ClassCollection().AttachQueryNode(fieldName, new _IVisitor4_275(this));
+			}
+			CheckConstraintsEvaluationMode();
+			BooleanByRef foundClass = new BooleanByRef(false);
+			IEnumerator i = IterateConstraints();
+			while (i.MoveNext())
+			{
+				if (((QCon)i.Current).Attach(query, fieldName))
+				{
+					foundClass.value = true;
+				}
+			}
+			return foundClass.value;
+		}
+
+		private sealed class _IVisitor4_275 : IVisitor4
+		{
+			public _IVisitor4_275(QQueryBase _enclosing)
+			{
+				this._enclosing = _enclosing;
+				this.untypedFieldConstraintCollected = false;
+			}
+
+			internal bool untypedFieldConstraintCollected;
+
+			public void Visit(object obj)
+			{
+				object[] pair = ((object[])obj);
+				ClassMetadata containingClass = (ClassMetadata)pair[0];
+				FieldMetadata field = (FieldMetadata)pair[1];
+				if (this.IsTyped(field))
+				{
+					this.AddFieldConstraint(containingClass, field);
+					return;
+				}
+				if (this.untypedFieldConstraintCollected)
+				{
+					return;
+				}
+				this.AddFieldConstraint(containingClass, field);
+				this.untypedFieldConstraintCollected = true;
+			}
+
+			private bool IsTyped(FieldMetadata field)
+			{
+				return !Handlers4.IsUntyped(field.GetHandler());
+			}
+
+			private void AddFieldConstraint(ClassMetadata containingClass, FieldMetadata field
+				)
+			{
+				QConClass qcc = new QConClass(this._enclosing._trans, null, field.QField(this._enclosing
+					._trans), containingClass.ClassReflector());
+				this._enclosing.AddConstraint(qcc);
+				this._enclosing.ToConstraint(this._enclosing.i_constraints).Or(qcc);
+			}
+
+			private readonly QQueryBase _enclosing;
+		}
+
+		public virtual IObjectSet Execute()
+		{
+			lock (StreamLock())
+			{
+				return ((IObjectSet)TriggeringQueryEvents(new _IClosure4_331(this)));
+			}
+		}
+
+		private sealed class _IClosure4_331 : IClosure4
+		{
+			public _IClosure4_331(QQueryBase _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Run()
+			{
+				return new ObjectSetFacade(this._enclosing.GetQueryResult());
+			}
+
+			private readonly QQueryBase _enclosing;
+		}
+
+		public virtual void ExecuteLocal(IdListQueryResult result)
+		{
+			CheckConstraintsEvaluationMode();
+			QQueryBase.CreateCandidateCollectionResult r = CreateCandidateCollection();
+			bool checkDuplicates = r.checkDuplicates;
+			bool topLevel = r.topLevel;
+			List4 candidateCollection = r.candidateCollection;
+			if (candidateCollection != null)
+			{
+				Collection4 executionPath = topLevel ? null : FieldPathFromTop();
+				IEnumerator i = new Iterator4Impl(candidateCollection);
+				while (i.MoveNext())
+				{
+					((QCandidates)i.Current).Execute();
+				}
+				if (((List4)candidateCollection._next) != null)
+				{
+					checkDuplicates = true;
+				}
+				if (checkDuplicates)
+				{
+					result.CheckDuplicates();
+				}
+				ObjectContainerBase stream = Stream();
+				i = new Iterator4Impl(candidateCollection);
+				while (i.MoveNext())
+				{
+					QCandidates candidates = (QCandidates)i.Current;
+					if (topLevel)
+					{
+						candidates.Traverse(result);
+					}
+					else
+					{
+						candidates.Traverse(new _IVisitor4_374(this, executionPath, stream, result));
+					}
+				}
+			}
+			Sort(result);
+		}
+
+		private sealed class _IVisitor4_374 : IVisitor4
+		{
+			public _IVisitor4_374(QQueryBase _enclosing, Collection4 executionPath, ObjectContainerBase
+				 stream, IdListQueryResult result)
+			{
+				this._enclosing = _enclosing;
+				this.executionPath = executionPath;
+				this.stream = stream;
+				this.result = result;
+			}
+
+			public void Visit(object a_object)
+			{
+				QCandidate candidate = (QCandidate)a_object;
+				if (candidate.Include())
+				{
+					TreeInt ids = new TreeInt(candidate._key);
+					ByRef idsNew = new ByRef();
+					IEnumerator itPath = executionPath.GetEnumerator();
+					while (itPath.MoveNext())
+					{
+						idsNew.value = null;
+						string fieldName = (string)(itPath.Current);
+						if (ids != null)
+						{
+							ids.Traverse(new _IVisitor4_385(this, stream, fieldName, idsNew));
+						}
+						ids = (TreeInt)((TreeInt)idsNew.value);
+					}
+					if (ids != null)
+					{
+						ids.Traverse(new _IVisitor4_406(result));
+					}
+				}
+			}
+
+			private sealed class _IVisitor4_385 : IVisitor4
+			{
+				public _IVisitor4_385(_IVisitor4_374 _enclosing, ObjectContainerBase stream, string
+					 fieldName, ByRef idsNew)
+				{
+					this._enclosing = _enclosing;
+					this.stream = stream;
+					this.fieldName = fieldName;
+					this.idsNew = idsNew;
+				}
+
+				public void Visit(object treeInt)
+				{
+					int id = ((TreeInt)treeInt)._key;
+					StatefulBuffer reader = stream.ReadStatefulBufferById(this._enclosing._enclosing.
+						_trans, id);
+					if (reader != null)
+					{
+						ObjectHeader oh = new ObjectHeader(stream, reader);
+						CollectIdContext context = new CollectIdContext(this._enclosing._enclosing._trans
+							, oh, reader);
+						oh.ClassMetadata().CollectIDs(context, fieldName);
+						Tree.Traverse(context.Ids(), new _IVisitor4_394(idsNew));
+					}
+				}
+
+				private sealed class _IVisitor4_394 : IVisitor4
+				{
+					public _IVisitor4_394(ByRef idsNew)
+					{
+						this.idsNew = idsNew;
+					}
+
+					public void Visit(object node)
+					{
+						idsNew.value = TreeInt.Add(((TreeInt)idsNew.value), ((TreeInt)node)._key);
+					}
+
+					private readonly ByRef idsNew;
+				}
+
+				private readonly _IVisitor4_374 _enclosing;
+
+				private readonly ObjectContainerBase stream;
+
+				private readonly string fieldName;
+
+				private readonly ByRef idsNew;
+			}
+
+			private sealed class _IVisitor4_406 : IVisitor4
+			{
+				public _IVisitor4_406(IdListQueryResult result)
+				{
+					this.result = result;
+				}
+
+				public void Visit(object treeInt)
+				{
+					result.AddKeyCheckDuplicates(((TreeInt)treeInt)._key);
+				}
+
+				private readonly IdListQueryResult result;
+			}
+
+			private readonly QQueryBase _enclosing;
+
+			private readonly Collection4 executionPath;
+
+			private readonly ObjectContainerBase stream;
+
+			private readonly IdListQueryResult result;
+		}
+
+		private void TriggerQueryOnFinished()
+		{
+			Stream().Callbacks().QueryOnFinished(_trans, Cast(this));
+		}
+
+		private void TriggerQueryOnStarted()
+		{
+			Stream().Callbacks().QueryOnStarted(_trans, Cast(this));
+		}
+
+		public virtual IEnumerator ExecuteLazy()
+		{
+			CheckConstraintsEvaluationMode();
+			QQueryBase.CreateCandidateCollectionResult r = CreateCandidateCollection();
+			Collection4 executionPath = ExecutionPath(r);
+			IEnumerator candidateCollection = new Iterator4Impl(r.candidateCollection);
+			MappingIterator executeCandidates = new _MappingIterator_438(executionPath, candidateCollection
+				);
+			CompositeIterator4 resultingIDs = new CompositeIterator4(executeCandidates);
+			if (!r.checkDuplicates)
+			{
+				return resultingIDs;
+			}
+			return CheckDuplicates(resultingIDs);
+		}
+
+		private sealed class _MappingIterator_438 : MappingIterator
+		{
+			public _MappingIterator_438(Collection4 executionPath, IEnumerator baseArg1) : base
+				(baseArg1)
+			{
+				this.executionPath = executionPath;
+			}
+
+			protected override object Map(object current)
+			{
+				return ((QCandidates)current).ExecuteLazy(executionPath);
+			}
+
+			private readonly Collection4 executionPath;
+		}
+
+		public virtual IQueryResult GetQueryResult()
+		{
+			lock (StreamLock())
+			{
+				if (i_constraints.Size() == 0)
+				{
+					return ExecuteAllObjectsQuery();
+				}
+				IQueryResult result = ExecuteClassOnlyQuery();
+				if (result != null)
+				{
+					return result;
+				}
+				OptimizeJoins();
+				return ExecuteQuery();
+			}
+		}
+
+		protected IQueryResult ExecuteQuery()
+		{
+			return Stream().ExecuteQuery(_this);
+		}
+
+		private IQueryResult ExecuteAllObjectsQuery()
+		{
+			return Stream().QueryAllObjects(_trans);
+		}
+
+		protected virtual ObjectContainerBase Stream()
+		{
+			return _trans.Container();
+		}
+
+		public virtual IInternalObjectContainer Container
+		{
+			get
+			{
+				return Stream();
+			}
+		}
+
+		private IQueryResult ExecuteClassOnlyQuery()
+		{
+			ClassMetadata clazz = SingleClassConstraint();
+			if (null == clazz)
+			{
+				return null;
+			}
+			IQueryResult queryResult = Stream().ClassOnlyQuery(this, clazz);
+			Sort(queryResult);
+			return queryResult;
+		}
+
+		private ClassMetadata SingleClassConstraint()
+		{
+			if (RequiresSort())
+			{
+				return null;
+			}
+			QConClass clazzconstr = ClassConstraint();
+			if (clazzconstr == null)
+			{
+				return null;
+			}
+			ClassMetadata clazz = clazzconstr._classMetadata;
+			if (clazz == null)
+			{
+				return null;
+			}
+			if (clazzconstr.HasChildren() || clazz.IsArray())
+			{
+				return null;
+			}
+			return clazz;
+		}
+
+		private QConClass ClassConstraint()
+		{
+			if (i_constraints.Size() != 1)
+			{
+				return null;
+			}
+			IConstraint constr = SingleConstraint();
+			if (constr.GetType() != typeof(QConClass))
+			{
+				return null;
+			}
+			return (QConClass)constr;
+		}
+
+		private IConstraint SingleConstraint()
+		{
+			return (IConstraint)i_constraints.SingleElement();
+		}
+
+		public class CreateCandidateCollectionResult
+		{
+			public readonly bool checkDuplicates;
+
+			public readonly bool topLevel;
+
+			public readonly List4 candidateCollection;
+
+			public CreateCandidateCollectionResult(List4 candidateCollection_, bool checkDuplicates_
+				, bool topLevel_)
+			{
+				candidateCollection = candidateCollection_;
+				topLevel = topLevel_;
+				checkDuplicates = checkDuplicates_;
+			}
+		}
+
+		public virtual IEnumerator ExecuteSnapshot()
+		{
+			QQueryBase.CreateCandidateCollectionResult r = CreateCandidateCollection();
+			Collection4 executionPath = ExecutionPath(r);
+			IEnumerator candidatesIterator = new Iterator4Impl(r.candidateCollection);
+			Collection4 snapshots = new Collection4();
+			while (candidatesIterator.MoveNext())
+			{
+				QCandidates candidates = (QCandidates)candidatesIterator.Current;
+				snapshots.Add(candidates.ExecuteSnapshot(executionPath));
+			}
+			IEnumerator snapshotsIterator = snapshots.GetEnumerator();
+			CompositeIterator4 resultingIDs = new CompositeIterator4(snapshotsIterator);
+			if (!r.checkDuplicates)
+			{
+				return resultingIDs;
+			}
+			return CheckDuplicates(resultingIDs);
+		}
+
+		public virtual object TriggeringQueryEvents(IClosure4 closure)
+		{
+			TriggerQueryOnStarted();
+			try
+			{
+				return closure.Run();
+			}
+			finally
+			{
+				TriggerQueryOnFinished();
+			}
+		}
+
+		private IEnumerator CheckDuplicates(CompositeIterator4 executeAllCandidates)
+		{
+			return Iterators.Filter(executeAllCandidates, new _IPredicate4_573());
+		}
+
+		private sealed class _IPredicate4_573 : IPredicate4
+		{
+			public _IPredicate4_573()
+			{
+				this.ids = new TreeInt(0);
+			}
+
+			private TreeInt ids;
+
+			public bool Match(object current)
+			{
+				int id = ((int)current);
+				if (this.ids.Find(id) != null)
+				{
+					return false;
+				}
+				this.ids = (TreeInt)((TreeInt)this.ids.Add(new TreeInt(id)));
+				return true;
+			}
+		}
+
+		private Collection4 ExecutionPath(QQueryBase.CreateCandidateCollectionResult r)
+		{
+			return r.topLevel ? null : FieldPathFromTop();
+		}
+
+		public virtual void CheckConstraintsEvaluationMode()
+		{
+			IEnumerator constraints = IterateConstraints();
+			while (constraints.MoveNext())
+			{
+				((QConObject)constraints.Current).SetEvaluationMode();
+			}
+		}
+
+		private Collection4 FieldPathFromTop()
+		{
+			QQueryBase q = this;
+			Collection4 fieldPath = new Collection4();
+			while (q.i_parent != null)
+			{
+				fieldPath.Prepend(q.i_field);
+				q = q.i_parent;
+			}
+			return fieldPath;
+		}
+
+		private void LogConstraints()
+		{
+		}
+
+		public virtual QQueryBase.CreateCandidateCollectionResult CreateCandidateCollection
+			()
+		{
+			List4 candidatesList = CreateQCandidatesList();
+			bool checkDuplicates = false;
+			bool topLevel = true;
+			IEnumerator i = IterateConstraints();
+			while (i.MoveNext())
+			{
+				QCon constraint = (QCon)i.Current;
+				QCon old = constraint;
+				constraint = constraint.GetRoot();
+				if (constraint != old)
+				{
+					checkDuplicates = true;
+					topLevel = false;
+				}
+				ClassMetadata classMetadata = constraint.GetYapClass();
+				if (classMetadata == null)
+				{
+					break;
+				}
+				AddConstraintToCandidatesList(candidatesList, constraint);
+			}
+			return new QQueryBase.CreateCandidateCollectionResult(candidatesList, checkDuplicates
+				, topLevel);
+		}
+
+		private void AddConstraintToCandidatesList(List4 candidatesList, QCon qcon)
+		{
+			if (candidatesList == null)
+			{
+				return;
+			}
+			IEnumerator j = new Iterator4Impl(candidatesList);
+			while (j.MoveNext())
+			{
+				QCandidates candidates = (QCandidates)j.Current;
+				candidates.AddConstraint(qcon);
+			}
+		}
+
+		private List4 CreateQCandidatesList()
+		{
+			List4 candidatesList = null;
+			IEnumerator i = IterateConstraints();
+			while (i.MoveNext())
+			{
+				QCon constraint = (QCon)i.Current;
+				constraint = constraint.GetRoot();
+				ClassMetadata classMetadata = constraint.GetYapClass();
+				if (classMetadata == null)
+				{
+					continue;
+				}
+				if (ConstraintCanBeAddedToExisting(candidatesList, constraint))
+				{
+					continue;
+				}
+				QCandidates candidates = new QCandidates((LocalTransaction)_trans, classMetadata, 
+					null);
+				candidatesList = new List4(candidatesList, candidates);
+			}
+			return candidatesList;
+		}
+
+		private bool ConstraintCanBeAddedToExisting(List4 candidatesList, QCon constraint
+			)
+		{
+			IEnumerator j = new Iterator4Impl(candidatesList);
+			while (j.MoveNext())
+			{
+				QCandidates candidates = (QCandidates)j.Current;
+				if (candidates.FitsIntoExistingConstraintHierarchy(constraint))
+				{
+					return true;
+				}
+			}
+			return false;
+		}
+
+		public Transaction Transaction()
+		{
+			return _trans;
+		}
+
+		public virtual IEnumerator IterateConstraints()
+		{
+			// clone the collection first to avoid
+			// InvalidIteratorException as i_constraints might be 
+			// modified during the execution of callee
+			return new Collection4(i_constraints).GetEnumerator();
+		}
+
+		public virtual IQuery OrderAscending()
+		{
+			if (i_parent == null)
+			{
+				throw new InvalidOperationException("Cannot apply ordering at top level.");
+			}
+			lock (StreamLock())
+			{
+				AddOrdering(SodaQueryComparator.Direction.Ascending);
+				return _this;
+			}
+		}
+
+		public virtual IQuery OrderDescending()
+		{
+			if (i_parent == null)
+			{
+				throw new InvalidOperationException("Cannot apply ordering at top level.");
+			}
+			lock (StreamLock())
+			{
+				AddOrdering(SodaQueryComparator.Direction.Descending);
+				return _this;
+			}
+		}
+
+		private void AddOrdering(SodaQueryComparator.Direction direction)
+		{
+			AddOrdering(direction, new ArrayList());
+		}
+
+		protected void AddOrdering(SodaQueryComparator.Direction direction, IList path)
+		{
+			if (i_field != null)
+			{
+				path.Add(i_field);
+			}
+			if (i_parent != null)
+			{
+				i_parent.AddOrdering(direction, path);
+				return;
+			}
+			string[] fieldPath = ReverseFieldPath(path);
+			RemoveExistingOrderingFor(fieldPath);
+			Orderings().Add(new SodaQueryComparator.Ordering(direction, fieldPath));
+		}
+
+		private void RemoveExistingOrderingFor(string[] fieldPath)
+		{
+			for (IEnumerator orderingIter = Orderings().GetEnumerator(); orderingIter.MoveNext
+				(); )
+			{
+				SodaQueryComparator.Ordering ordering = ((SodaQueryComparator.Ordering)orderingIter
+					.Current);
+				if (Arrays.Equals(ordering.FieldPath(), fieldPath))
+				{
+					Orderings().Remove(ordering);
+					break;
+				}
+			}
+		}
+
+		/// <summary>Public so it can be used by the LINQ test cases.</summary>
+		/// <remarks>Public so it can be used by the LINQ test cases.</remarks>
+		public IList Orderings()
+		{
+			if (null == _orderings)
+			{
+				_orderings = new ArrayList();
+			}
+			return _orderings;
+		}
+
+		private string[] ReverseFieldPath(IList path)
+		{
+			string[] reversedPath = new string[path.Count];
+			for (int i = 0; i < reversedPath.Length; i++)
+			{
+				reversedPath[i] = ((string)path[path.Count - i - 1]);
+			}
+			return reversedPath;
+		}
+
+		public virtual void Marshall()
+		{
+			CheckConstraintsEvaluationMode();
+			_evaluationModeAsInt = _evaluationMode.AsInt();
+			IEnumerator i = IterateConstraints();
+			while (i.MoveNext())
+			{
+				((QCon)i.Current).GetRoot().Marshall();
+			}
+		}
+
+		public virtual void Unmarshall(Transaction a_trans)
+		{
+			_evaluationMode = QueryEvaluationMode.FromInt(_evaluationModeAsInt);
+			_trans = a_trans;
+			IEnumerator i = IterateConstraints();
+			while (i.MoveNext())
+			{
+				((QCon)i.Current).Unmarshall(a_trans);
+			}
+		}
+
+		internal virtual void RemoveConstraint(QCon a_constraint)
+		{
+			i_constraints.Remove(a_constraint);
+		}
+
+		internal virtual IConstraint ToConstraint(Collection4 constraints)
+		{
+			if (constraints.Size() == 1)
+			{
+				return (IConstraint)constraints.SingleElement();
+			}
+			else
+			{
+				if (constraints.Size() > 0)
+				{
+					IConstraint[] constraintArray = new IConstraint[constraints.Size()];
+					constraints.ToArray(constraintArray);
+					return new QConstraints(_trans, constraintArray);
+				}
+			}
+			return null;
+		}
+
+		protected virtual object StreamLock()
+		{
+			return Stream().Lock();
+		}
+
+		public virtual IQuery SortBy(IQueryComparator comparator)
+		{
+			_comparator = comparator;
+			return _this;
+		}
+
+		private void Sort(IQueryResult result)
+		{
+			if (_orderings != null)
+			{
+				result.SortIds(NewSodaQueryComparator());
+			}
+			if (_comparator != null)
+			{
+				result.Sort(_comparator);
+			}
+		}
+
+		private IIntComparator NewSodaQueryComparator()
+		{
+			return new SodaQueryComparator((LocalObjectContainer)this.Transaction().Container
+				(), ExtentType(), ((SodaQueryComparator.Ordering[])Sharpen.Collections.ToArray(_orderings
+				, new SodaQueryComparator.Ordering[_orderings.Count])));
+		}
+
+		private ClassMetadata ExtentType()
+		{
+			return ClassConstraint().GetYapClass();
+		}
+
+		// cheat emulating '(QQuery)this'
+		private static QQuery Cast(QQueryBase obj)
+		{
+			return (QQuery)obj;
+		}
+
+		public virtual bool RequiresSort()
+		{
+			if (_comparator != null || _orderings != null)
+			{
+				return true;
+			}
+			return false;
+		}
+
+		public virtual IQueryComparator Comparator()
+		{
+			return _comparator;
+		}
+
+		public virtual QueryEvaluationMode EvaluationMode()
+		{
+			return _evaluationMode;
+		}
+
+		public virtual void EvaluationMode(QueryEvaluationMode mode)
+		{
+			_evaluationMode = mode;
+		}
+
+		private void OptimizeJoins()
+		{
+			if (!HasOrJoins())
+			{
+				RemoveJoins();
+			}
+		}
+
+		private bool HasOrJoins()
+		{
+			return ForEachConstraintRecursively(new _IFunction4_855());
+		}
+
+		private sealed class _IFunction4_855 : IFunction4
+		{
+			public _IFunction4_855()
+			{
+			}
+
+			public object Apply(object obj)
+			{
+				QCon constr = (QCon)obj;
+				IEnumerator joinIter = constr.IterateJoins();
+				while (joinIter.MoveNext())
+				{
+					QConJoin join = (QConJoin)joinIter.Current;
+					if (join.IsOr())
+					{
+						return true;
+					}
+				}
+				return false;
+			}
+		}
+
+		private void RemoveJoins()
+		{
+			ForEachConstraintRecursively(new _IFunction4_871());
+		}
+
+		private sealed class _IFunction4_871 : IFunction4
+		{
+			public _IFunction4_871()
+			{
+			}
+
+			public object Apply(object obj)
+			{
+				QCon constr = (QCon)obj;
+				constr.i_joins = null;
+				return false;
+			}
+		}
+
+		private bool ForEachConstraintRecursively(IFunction4 block)
+		{
+			IQueue4 queue = new NoDuplicatesQueue(new NonblockingQueue());
+			IEnumerator constrIter = IterateConstraints();
+			while (constrIter.MoveNext())
+			{
+				queue.Add(constrIter.Current);
+			}
+			while (queue.HasNext())
+			{
+				QCon constr = (QCon)queue.Next();
+				bool cancel = (bool)block.Apply(constr);
+				if (cancel)
+				{
+					return true;
+				}
+				IEnumerator childIter = constr.IterateChildren();
+				while (childIter.MoveNext())
+				{
+					queue.Add(childIter.Current);
+				}
+				IEnumerator joinIter = constr.IterateJoins();
+				while (joinIter.MoveNext())
+				{
+					queue.Add(joinIter.Current);
+				}
+			}
+			return false;
+		}
+
+		public virtual int PrefetchDepth()
+		{
+			return _prefetchDepth;
+		}
+
+		public virtual int PrefetchCount()
+		{
+			return _prefetchCount;
+		}
+
+		public override string ToString()
+		{
+			StringBuilder sb = new StringBuilder();
+			sb.Append("QQueryBase\n");
+			IEnumerator i = IterateConstraints();
+			while (i.MoveNext())
+			{
+				QCon constraint = (QCon)i.Current;
+				sb.Append(constraint);
+				sb.Append("\n");
+			}
+			return sb.ToString();
+		}
+
+		public virtual QQuery Parent()
+		{
+			return i_parent;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/AbstractLateQueryResult.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/AbstractLateQueryResult.cs
new file mode 100644
index 0000000..7734602
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/AbstractLateQueryResult.cs
@@ -0,0 +1,125 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Classindex;
+using Db4objects.Db4o.Internal.Query.Result;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Query.Result
+{
+	/// <exclude></exclude>
+	public abstract class AbstractLateQueryResult : AbstractQueryResult
+	{
+		protected IEnumerable _iterable;
+
+		public AbstractLateQueryResult(Transaction transaction) : base(transaction)
+		{
+		}
+
+		public override AbstractQueryResult SupportSize()
+		{
+			return ToIdTree();
+		}
+
+		public override AbstractQueryResult SupportSort()
+		{
+			return ToIdList();
+		}
+
+		public override AbstractQueryResult SupportElementAccess()
+		{
+			return ToIdList();
+		}
+
+		protected override int KnownSize()
+		{
+			return 0;
+		}
+
+		public override IIntIterator4 IterateIDs()
+		{
+			if (_iterable == null)
+			{
+				throw new InvalidOperationException();
+			}
+			return new IntIterator4Adaptor(_iterable);
+		}
+
+		public override AbstractQueryResult ToIdList()
+		{
+			return ToIdTree().ToIdList();
+		}
+
+		public virtual bool SkipClass(ClassMetadata classMetadata)
+		{
+			if (classMetadata.GetName() == null)
+			{
+				return true;
+			}
+			IReflectClass claxx = classMetadata.ClassReflector();
+			if (Stream()._handlers.IclassInternal.IsAssignableFrom(claxx))
+			{
+				return true;
+			}
+			return false;
+		}
+
+		protected virtual IEnumerable ClassIndexesIterable(ClassMetadataIterator classCollectionIterator
+			)
+		{
+			return Iterators.ConcatMap(Iterators.Iterable(classCollectionIterator), new _IFunction4_61
+				(this));
+		}
+
+		private sealed class _IFunction4_61 : IFunction4
+		{
+			public _IFunction4_61(AbstractLateQueryResult _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Apply(object current)
+			{
+				ClassMetadata classMetadata = (ClassMetadata)current;
+				if (this._enclosing.SkipClass(classMetadata))
+				{
+					return Iterators.Skip;
+				}
+				return this._enclosing.ClassIndexIterable(classMetadata);
+			}
+
+			private readonly AbstractLateQueryResult _enclosing;
+		}
+
+		protected virtual IEnumerable ClassIndexIterable(ClassMetadata clazz)
+		{
+			return new _IEnumerable_73(this, clazz);
+		}
+
+		private sealed class _IEnumerable_73 : IEnumerable
+		{
+			public _IEnumerable_73(AbstractLateQueryResult _enclosing, ClassMetadata clazz)
+			{
+				this._enclosing = _enclosing;
+				this.clazz = clazz;
+			}
+
+			public IEnumerator GetEnumerator()
+			{
+				return this._enclosing.ClassIndexIterator(clazz);
+			}
+
+			private readonly AbstractLateQueryResult _enclosing;
+
+			private readonly ClassMetadata clazz;
+		}
+
+		public virtual IEnumerator ClassIndexIterator(ClassMetadata clazz)
+		{
+			return BTreeClassIndexStrategy.Iterate(clazz, Transaction());
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/AbstractQueryResult.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/AbstractQueryResult.cs
new file mode 100644
index 0000000..0745f8e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/AbstractQueryResult.cs
@@ -0,0 +1,199 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Internal.Query.Result;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Query.Result
+{
+	/// <exclude></exclude>
+	public abstract class AbstractQueryResult : IQueryResult
+	{
+		protected readonly Db4objects.Db4o.Internal.Transaction _transaction;
+
+		public AbstractQueryResult(Db4objects.Db4o.Internal.Transaction transaction)
+		{
+			_transaction = transaction;
+		}
+
+		public object Activate(object obj)
+		{
+			Stream().Activate(_transaction, obj);
+			return obj;
+		}
+
+		public object ActivatedObject(int id)
+		{
+			ObjectContainerBase stream = Stream();
+			object ret = stream.GetActivatedObjectFromCache(_transaction, id);
+			if (ret != null)
+			{
+				return ret;
+			}
+			return stream.ReadActivatedObjectNotInCache(_transaction, id);
+		}
+
+		public virtual object Lock()
+		{
+			ObjectContainerBase stream = Stream();
+			stream.CheckClosed();
+			return stream.Lock();
+		}
+
+		public virtual ObjectContainerBase Stream()
+		{
+			return _transaction.Container();
+		}
+
+		public virtual Db4objects.Db4o.Internal.Transaction Transaction()
+		{
+			return _transaction;
+		}
+
+		public virtual IExtObjectContainer ObjectContainer()
+		{
+			return Transaction().ObjectContainer().Ext();
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			return new _MappingIterator_56(this, IterateIDs());
+		}
+
+		private sealed class _MappingIterator_56 : MappingIterator
+		{
+			public _MappingIterator_56(AbstractQueryResult _enclosing, IEnumerator baseArg1) : 
+				base(baseArg1)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			protected override object Map(object current)
+			{
+				if (current == null)
+				{
+					return Iterators.Skip;
+				}
+				lock (this._enclosing.Lock())
+				{
+					object obj = this._enclosing.ActivatedObject(((int)current));
+					if (obj == null)
+					{
+						return Iterators.Skip;
+					}
+					return obj;
+				}
+			}
+
+			private readonly AbstractQueryResult _enclosing;
+		}
+
+		public virtual Db4objects.Db4o.Internal.Query.Result.AbstractQueryResult SupportSize
+			()
+		{
+			return this;
+		}
+
+		public virtual Db4objects.Db4o.Internal.Query.Result.AbstractQueryResult SupportSort
+			()
+		{
+			return this;
+		}
+
+		public virtual Db4objects.Db4o.Internal.Query.Result.AbstractQueryResult SupportElementAccess
+			()
+		{
+			return this;
+		}
+
+		protected virtual int KnownSize()
+		{
+			return Size();
+		}
+
+		public virtual Db4objects.Db4o.Internal.Query.Result.AbstractQueryResult ToIdList
+			()
+		{
+			IdListQueryResult res = new IdListQueryResult(Transaction(), KnownSize());
+			IIntIterator4 i = IterateIDs();
+			while (i.MoveNext())
+			{
+				res.Add(i.CurrentInt());
+			}
+			return res;
+		}
+
+		protected virtual Db4objects.Db4o.Internal.Query.Result.AbstractQueryResult ToIdTree
+			()
+		{
+			return new IdTreeQueryResult(Transaction(), IterateIDs());
+		}
+
+		public virtual Config4Impl Config()
+		{
+			return Stream().Config();
+		}
+
+		public virtual int Size()
+		{
+			throw new NotImplementedException();
+		}
+
+		public virtual void Sort(IQueryComparator cmp)
+		{
+			throw new NotImplementedException();
+		}
+
+		public virtual void SortIds(IIntComparator cmp)
+		{
+			throw new NotImplementedException();
+		}
+
+		public virtual object Get(int index)
+		{
+			throw new NotImplementedException();
+		}
+
+		/// <param name="i"></param>
+		public virtual int GetId(int i)
+		{
+			throw new NotImplementedException();
+		}
+
+		public virtual int IndexOf(int id)
+		{
+			throw new NotImplementedException();
+		}
+
+		/// <param name="c"></param>
+		public virtual void LoadFromClassIndex(ClassMetadata c)
+		{
+			throw new NotImplementedException();
+		}
+
+		/// <param name="i"></param>
+		public virtual void LoadFromClassIndexes(ClassMetadataIterator i)
+		{
+			throw new NotImplementedException();
+		}
+
+		/// <param name="ids"></param>
+		public virtual void LoadFromIdReader(IEnumerator ids)
+		{
+			throw new NotImplementedException();
+		}
+
+		/// <param name="q"></param>
+		public virtual void LoadFromQuery(QQuery q)
+		{
+			throw new NotImplementedException();
+		}
+
+		public abstract IIntIterator4 IterateIDs();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/HybridQueryResult.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/HybridQueryResult.cs
new file mode 100644
index 0000000..cf4a52f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/HybridQueryResult.cs
@@ -0,0 +1,108 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Internal.Query.Result;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Query.Result
+{
+	/// <exclude></exclude>
+	public class HybridQueryResult : AbstractQueryResult
+	{
+		private AbstractQueryResult _delegate;
+
+		public HybridQueryResult(Transaction transaction, QueryEvaluationMode mode) : base
+			(transaction)
+		{
+			_delegate = ForMode(transaction, mode);
+		}
+
+		private static AbstractQueryResult ForMode(Transaction transaction, QueryEvaluationMode
+			 mode)
+		{
+			if (mode == QueryEvaluationMode.Lazy)
+			{
+				return new LazyQueryResult(transaction);
+			}
+			if (mode == QueryEvaluationMode.Snapshot)
+			{
+				return new SnapShotQueryResult(transaction);
+			}
+			return new IdListQueryResult(transaction);
+		}
+
+		public override object Get(int index)
+		{
+			_delegate = _delegate.SupportElementAccess();
+			return _delegate.Get(index);
+		}
+
+		public override int GetId(int index)
+		{
+			_delegate = _delegate.SupportElementAccess();
+			return _delegate.GetId(index);
+		}
+
+		public override int IndexOf(int id)
+		{
+			_delegate = _delegate.SupportElementAccess();
+			return _delegate.IndexOf(id);
+		}
+
+		public override IIntIterator4 IterateIDs()
+		{
+			return _delegate.IterateIDs();
+		}
+
+		public override IEnumerator GetEnumerator()
+		{
+			return _delegate.GetEnumerator();
+		}
+
+		public override void LoadFromClassIndex(ClassMetadata clazz)
+		{
+			_delegate.LoadFromClassIndex(clazz);
+		}
+
+		public override void LoadFromClassIndexes(ClassMetadataIterator iterator)
+		{
+			_delegate.LoadFromClassIndexes(iterator);
+		}
+
+		public override void LoadFromIdReader(IEnumerator reader)
+		{
+			_delegate.LoadFromIdReader(reader);
+		}
+
+		public override void LoadFromQuery(QQuery query)
+		{
+			if (query.RequiresSort())
+			{
+				_delegate = new IdListQueryResult(Transaction());
+			}
+			_delegate.LoadFromQuery(query);
+		}
+
+		public override int Size()
+		{
+			_delegate = _delegate.SupportSize();
+			return _delegate.Size();
+		}
+
+		public override void Sort(IQueryComparator cmp)
+		{
+			_delegate = _delegate.SupportSort();
+			_delegate.Sort(cmp);
+		}
+
+		public override void SortIds(IIntComparator cmp)
+		{
+			_delegate = _delegate.SupportSort();
+			_delegate.SortIds(cmp);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/IQueryResult.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/IQueryResult.cs
new file mode 100644
index 0000000..069c5e1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/IQueryResult.cs
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Query.Result
+{
+	/// <exclude></exclude>
+	public interface IQueryResult : IEnumerable
+	{
+		object Get(int index);
+
+		IIntIterator4 IterateIDs();
+
+		object Lock();
+
+		IExtObjectContainer ObjectContainer();
+
+		int IndexOf(int id);
+
+		int Size();
+
+		void Sort(IQueryComparator cmp);
+
+		void SortIds(IIntComparator cmp);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/IdListQueryResult.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/IdListQueryResult.cs
new file mode 100644
index 0000000..e7f94a1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/IdListQueryResult.cs
@@ -0,0 +1,250 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Classindex;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Internal.Query.Result;
+using Db4objects.Db4o.Query;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Query.Result
+{
+	/// <exclude></exclude>
+	public class IdListQueryResult : AbstractQueryResult, IVisitor4
+	{
+		private Tree _candidates;
+
+		private bool _checkDuplicates;
+
+		public IntArrayList _ids;
+
+		public IdListQueryResult(Transaction trans, int initialSize) : base(trans)
+		{
+			_ids = new IntArrayList(initialSize);
+		}
+
+		public IdListQueryResult(Transaction trans) : this(trans, 0)
+		{
+		}
+
+		public override IIntIterator4 IterateIDs()
+		{
+			return _ids.IntIterator();
+		}
+
+		public override object Get(int index)
+		{
+			lock (Lock())
+			{
+				return ActivatedObject(GetId(index));
+			}
+		}
+
+		public override int GetId(int index)
+		{
+			if (index < 0 || index >= Size())
+			{
+				throw new Db4oRecoverableException(new IndexOutOfRangeException());
+			}
+			return _ids.Get(index);
+		}
+
+		public void CheckDuplicates()
+		{
+			_checkDuplicates = true;
+		}
+
+		public virtual void Visit(object a_tree)
+		{
+			QCandidate candidate = (QCandidate)a_tree;
+			if (candidate.Include())
+			{
+				AddKeyCheckDuplicates(candidate._key);
+			}
+		}
+
+		public virtual void AddKeyCheckDuplicates(int a_key)
+		{
+			if (_checkDuplicates)
+			{
+				TreeInt newNode = new TreeInt(a_key);
+				_candidates = Tree.Add(_candidates, newNode);
+				if (newNode._size == 0)
+				{
+					return;
+				}
+			}
+			Add(a_key);
+		}
+
+		public override void Sort(IQueryComparator cmp)
+		{
+			Algorithms4.Sort(new _ISortable4_74(this, cmp));
+		}
+
+		private sealed class _ISortable4_74 : ISortable4
+		{
+			public _ISortable4_74(IdListQueryResult _enclosing, IQueryComparator cmp)
+			{
+				this._enclosing = _enclosing;
+				this.cmp = cmp;
+			}
+
+			public void Swap(int leftIndex, int rightIndex)
+			{
+				this._enclosing._ids.Swap(leftIndex, rightIndex);
+			}
+
+			public int Size()
+			{
+				return this._enclosing.Size();
+			}
+
+			public int Compare(int leftIndex, int rightIndex)
+			{
+				return cmp.Compare(this._enclosing.Get(leftIndex), this._enclosing.Get(rightIndex
+					));
+			}
+
+			private readonly IdListQueryResult _enclosing;
+
+			private readonly IQueryComparator cmp;
+		}
+
+		public override void SortIds(IIntComparator cmp)
+		{
+			Algorithms4.Sort(new _ISortable4_88(this, cmp));
+		}
+
+		private sealed class _ISortable4_88 : ISortable4
+		{
+			public _ISortable4_88(IdListQueryResult _enclosing, IIntComparator cmp)
+			{
+				this._enclosing = _enclosing;
+				this.cmp = cmp;
+			}
+
+			public void Swap(int leftIndex, int rightIndex)
+			{
+				this._enclosing._ids.Swap(leftIndex, rightIndex);
+			}
+
+			public int Size()
+			{
+				return this._enclosing.Size();
+			}
+
+			public int Compare(int leftIndex, int rightIndex)
+			{
+				return cmp.Compare(this._enclosing._ids.Get(leftIndex), this._enclosing._ids.Get(
+					rightIndex));
+			}
+
+			private readonly IdListQueryResult _enclosing;
+
+			private readonly IIntComparator cmp;
+		}
+
+		public override void LoadFromClassIndex(ClassMetadata clazz)
+		{
+			IClassIndexStrategy index = clazz.Index();
+			if (index is BTreeClassIndexStrategy)
+			{
+				BTree btree = ((BTreeClassIndexStrategy)index).Btree();
+				_ids = new IntArrayList(btree.Size(Transaction()));
+			}
+			index.TraverseAll(_transaction, new _IVisitor4_107(this));
+		}
+
+		private sealed class _IVisitor4_107 : IVisitor4
+		{
+			public _IVisitor4_107(IdListQueryResult _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Visit(object a_object)
+			{
+				this._enclosing.Add(((int)a_object));
+			}
+
+			private readonly IdListQueryResult _enclosing;
+		}
+
+		public override void LoadFromQuery(QQuery query)
+		{
+			query.ExecuteLocal(this);
+		}
+
+		public override void LoadFromClassIndexes(ClassMetadataIterator iter)
+		{
+			// duplicates because of inheritance hierarchies
+			ByRef duplicates = new ByRef();
+			while (iter.MoveNext())
+			{
+				ClassMetadata classMetadata = iter.CurrentClass();
+				if (classMetadata.GetName() != null)
+				{
+					IReflectClass claxx = classMetadata.ClassReflector();
+					if (claxx == null || !(Stream()._handlers.IclassInternal.IsAssignableFrom(claxx)))
+					{
+						IClassIndexStrategy index = classMetadata.Index();
+						index.TraverseAll(_transaction, new _IVisitor4_130(this, duplicates));
+					}
+				}
+			}
+		}
+
+		private sealed class _IVisitor4_130 : IVisitor4
+		{
+			public _IVisitor4_130(IdListQueryResult _enclosing, ByRef duplicates)
+			{
+				this._enclosing = _enclosing;
+				this.duplicates = duplicates;
+			}
+
+			public void Visit(object obj)
+			{
+				int id = ((int)obj);
+				TreeInt newNode = new TreeInt(id);
+				duplicates.value = Tree.Add(((Tree)duplicates.value), newNode);
+				if (newNode.Size() != 0)
+				{
+					this._enclosing.Add(id);
+				}
+			}
+
+			private readonly IdListQueryResult _enclosing;
+
+			private readonly ByRef duplicates;
+		}
+
+		public override void LoadFromIdReader(IEnumerator ids)
+		{
+			while (ids.MoveNext())
+			{
+				Add(((int)ids.Current));
+			}
+		}
+
+		public virtual void Add(int id)
+		{
+			_ids.Add(id);
+		}
+
+		public override int IndexOf(int id)
+		{
+			return _ids.IndexOf(id);
+		}
+
+		public override int Size()
+		{
+			return _ids.Size();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/IdTreeQueryResult.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/IdTreeQueryResult.cs
new file mode 100644
index 0000000..17d3e89
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/IdTreeQueryResult.cs
@@ -0,0 +1,44 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Result;
+
+namespace Db4objects.Db4o.Internal.Query.Result
+{
+	/// <exclude></exclude>
+	public class IdTreeQueryResult : AbstractQueryResult
+	{
+		private Tree _ids;
+
+		public IdTreeQueryResult(Transaction transaction, IIntIterator4 ids) : base(transaction
+			)
+		{
+			_ids = TreeInt.AddAll(null, ids);
+		}
+
+		public override IIntIterator4 IterateIDs()
+		{
+			return new IntIterator4Adaptor(new TreeKeyIterator(_ids));
+		}
+
+		public override int Size()
+		{
+			if (_ids == null)
+			{
+				return 0;
+			}
+			return _ids.Size();
+		}
+
+		public override AbstractQueryResult SupportSort()
+		{
+			return ToIdList();
+		}
+
+		public override AbstractQueryResult SupportElementAccess()
+		{
+			return ToIdList();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/LazyQueryResult.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/LazyQueryResult.cs
new file mode 100644
index 0000000..3c8f3f3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/LazyQueryResult.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Internal.Query.Result;
+
+namespace Db4objects.Db4o.Internal.Query.Result
+{
+	/// <exclude></exclude>
+	public class LazyQueryResult : AbstractLateQueryResult
+	{
+		public LazyQueryResult(Transaction trans) : base(trans)
+		{
+		}
+
+		public override void LoadFromClassIndex(ClassMetadata clazz)
+		{
+			_iterable = ClassIndexIterable(clazz);
+		}
+
+		public override void LoadFromClassIndexes(ClassMetadataIterator classCollectionIterator
+			)
+		{
+			_iterable = ClassIndexesIterable(classCollectionIterator);
+		}
+
+		public override void LoadFromQuery(QQuery query)
+		{
+			_iterable = new _IEnumerable_28(query);
+		}
+
+		private sealed class _IEnumerable_28 : IEnumerable
+		{
+			public _IEnumerable_28(QQuery query)
+			{
+				this.query = query;
+			}
+
+			public IEnumerator GetEnumerator()
+			{
+				return query.ExecuteLazy();
+			}
+
+			private readonly QQuery query;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/SnapShotQueryResult.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/SnapShotQueryResult.cs
new file mode 100644
index 0000000..9d31abc
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/SnapShotQueryResult.cs
@@ -0,0 +1,72 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Internal.Query.Result;
+
+namespace Db4objects.Db4o.Internal.Query.Result
+{
+	/// <exclude></exclude>
+	public class SnapShotQueryResult : AbstractLateQueryResult
+	{
+		public SnapShotQueryResult(Transaction transaction) : base(transaction)
+		{
+		}
+
+		public override void LoadFromClassIndex(ClassMetadata clazz)
+		{
+			CreateSnapshot(ClassIndexIterable(clazz));
+		}
+
+		public override void LoadFromClassIndexes(ClassMetadataIterator classCollectionIterator
+			)
+		{
+			CreateSnapshot(ClassIndexesIterable(classCollectionIterator));
+		}
+
+		public override void LoadFromQuery(QQuery query)
+		{
+			IEnumerator _iterator = query.ExecuteSnapshot();
+			_iterable = new _IEnumerable_29(_iterator);
+		}
+
+		private sealed class _IEnumerable_29 : IEnumerable
+		{
+			public _IEnumerable_29(IEnumerator _iterator)
+			{
+				this._iterator = _iterator;
+			}
+
+			public IEnumerator GetEnumerator()
+			{
+				_iterator.Reset();
+				return _iterator;
+			}
+
+			private readonly IEnumerator _iterator;
+		}
+
+		private void CreateSnapshot(IEnumerable iterable)
+		{
+			Tree ids = TreeInt.AddAll(null, new IntIterator4Adaptor(iterable));
+			_iterable = new _IEnumerable_39(ids);
+		}
+
+		private sealed class _IEnumerable_39 : IEnumerable
+		{
+			public _IEnumerable_39(Tree ids)
+			{
+				this.ids = ids;
+			}
+
+			public IEnumerator GetEnumerator()
+			{
+				return new TreeKeyIterator(ids);
+			}
+
+			private readonly Tree ids;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/StatefulQueryResult.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/StatefulQueryResult.cs
new file mode 100644
index 0000000..7936910
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/Result/StatefulQueryResult.cs
@@ -0,0 +1,126 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Query.Result;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Query.Result
+{
+	/// <exclude></exclude>
+	public class StatefulQueryResult : IEnumerable
+	{
+		private readonly IQueryResult _delegate;
+
+		private readonly Iterable4Adaptor _iterable;
+
+		public StatefulQueryResult(IQueryResult queryResult)
+		{
+			_delegate = queryResult;
+			_iterable = new Iterable4Adaptor(queryResult);
+		}
+
+		public virtual object Get(int index)
+		{
+			lock (Lock())
+			{
+				return _delegate.Get(index);
+			}
+		}
+
+		public virtual long[] GetIDs()
+		{
+			lock (Lock())
+			{
+				long[] ids = new long[Size()];
+				int i = 0;
+				IIntIterator4 iterator = _delegate.IterateIDs();
+				while (iterator.MoveNext())
+				{
+					ids[i++] = iterator.CurrentInt();
+				}
+				return ids;
+			}
+		}
+
+		public virtual bool HasNext()
+		{
+			lock (Lock())
+			{
+				return _iterable.HasNext();
+			}
+		}
+
+		public virtual object Next()
+		{
+			lock (Lock())
+			{
+				return _iterable.Next();
+			}
+		}
+
+		public virtual void Reset()
+		{
+			lock (Lock())
+			{
+				_iterable.Reset();
+			}
+		}
+
+		public virtual int Size()
+		{
+			lock (Lock())
+			{
+				return _delegate.Size();
+			}
+		}
+
+		public virtual void Sort(IQueryComparator cmp)
+		{
+			lock (Lock())
+			{
+				_delegate.Sort(cmp);
+			}
+		}
+
+		public virtual object Lock()
+		{
+			return _delegate.Lock();
+		}
+
+		internal virtual IExtObjectContainer ObjectContainer()
+		{
+			return _delegate.ObjectContainer();
+		}
+
+		public virtual int IndexOf(object a_object)
+		{
+			lock (Lock())
+			{
+				int id = (int)ObjectContainer().GetID(a_object);
+				if (id <= 0)
+				{
+					return -1;
+				}
+				return _delegate.IndexOf(id);
+			}
+		}
+
+		public virtual IEnumerator IterateIDs()
+		{
+			lock (Lock())
+			{
+				return _delegate.IterateIDs();
+			}
+		}
+
+		public virtual IEnumerator GetEnumerator()
+		{
+			lock (Lock())
+			{
+				return _delegate.GetEnumerator();
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/SodaQueryComparator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/SodaQueryComparator.cs
new file mode 100644
index 0000000..fc19e88
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Query/SodaQueryComparator.cs
@@ -0,0 +1,247 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Query;
+
+namespace Db4objects.Db4o.Internal.Query
+{
+	public class SodaQueryComparator : IComparer, IIntComparator
+	{
+		public class Ordering
+		{
+			private SodaQueryComparator.Direction _direction;
+
+			private string[] _fieldPath;
+
+			[System.NonSerialized]
+			internal IList _resolvedPath;
+
+			public Ordering(SodaQueryComparator.Direction direction, string[] fieldPath)
+			{
+				_direction = direction;
+				_fieldPath = fieldPath;
+			}
+
+			public virtual SodaQueryComparator.Direction Direction()
+			{
+				return _direction;
+			}
+
+			public virtual string[] FieldPath()
+			{
+				return _fieldPath;
+			}
+		}
+
+		public class Direction
+		{
+			public static readonly SodaQueryComparator.Direction Ascending = new SodaQueryComparator.Direction
+				(0);
+
+			public static readonly SodaQueryComparator.Direction Descending = new SodaQueryComparator.Direction
+				(1);
+
+			private int value;
+
+			private Direction()
+			{
+			}
+
+			private Direction(int value)
+			{
+				this.value = value;
+			}
+
+			public override bool Equals(object obj)
+			{
+				return ((SodaQueryComparator.Direction)obj).value == value;
+			}
+
+			public override string ToString()
+			{
+				return this.Equals(Ascending) ? "ASCENDING" : "DESCENDING";
+			}
+		}
+
+		private readonly LocalObjectContainer _container;
+
+		private readonly LocalTransaction _transaction;
+
+		private readonly ClassMetadata _extentType;
+
+		private readonly SodaQueryComparator.Ordering[] _orderings;
+
+		private readonly IDictionary _bufferCache = new Hashtable();
+
+		private readonly IDictionary _fieldValueCache = new Hashtable();
+
+		public SodaQueryComparator(LocalObjectContainer container, Type extentType, SodaQueryComparator.Ordering
+			[] orderings) : this(container, container.ProduceClassMetadata(container.Reflector
+			().ForClass(extentType)), orderings)
+		{
+		}
+
+		public SodaQueryComparator(LocalObjectContainer container, ClassMetadata extent, 
+			SodaQueryComparator.Ordering[] orderings)
+		{
+			_container = container;
+			_transaction = ((LocalTransaction)_container.Transaction);
+			_extentType = extent;
+			_orderings = orderings;
+			ResolveFieldPaths(orderings);
+		}
+
+		private void ResolveFieldPaths(SodaQueryComparator.Ordering[] orderings)
+		{
+			for (int fieldPathIndex = 0; fieldPathIndex < orderings.Length; ++fieldPathIndex)
+			{
+				SodaQueryComparator.Ordering fieldPath = orderings[fieldPathIndex];
+				fieldPath._resolvedPath = ResolveFieldPath(fieldPath.FieldPath());
+			}
+		}
+
+		public virtual IList Sort(long[] ids)
+		{
+			ArrayList idList = ListFrom(ids);
+			idList.Sort(this);
+			return idList;
+		}
+
+		private ArrayList ListFrom(long[] ids)
+		{
+			ArrayList idList = new ArrayList(ids.Length);
+			for (int idIndex = 0; idIndex < ids.Length; ++idIndex)
+			{
+				long id = ids[idIndex];
+				idList.Add((int)id);
+			}
+			return idList;
+		}
+
+		private IList ResolveFieldPath(string[] fieldPath)
+		{
+			IList fields = new ArrayList(fieldPath.Length);
+			ClassMetadata currentType = _extentType;
+			for (int fieldNameIndex = 0; fieldNameIndex < fieldPath.Length; ++fieldNameIndex)
+			{
+				string fieldName = fieldPath[fieldNameIndex];
+				FieldMetadata field = currentType.FieldMetadataForName(fieldName);
+				currentType = field.FieldType();
+				fields.Add(field);
+			}
+			return fields;
+		}
+
+		public virtual int Compare(object x, object y)
+		{
+			return Compare(((int)x), ((int)y));
+		}
+
+		public virtual int Compare(int x, int y)
+		{
+			for (int orderingIndex = 0; orderingIndex < _orderings.Length; ++orderingIndex)
+			{
+				SodaQueryComparator.Ordering ordering = _orderings[orderingIndex];
+				int result = CompareByField(x, y, ordering._resolvedPath);
+				if (result != 0)
+				{
+					return ordering.Direction().Equals(SodaQueryComparator.Direction.Ascending) ? result
+						 : -result;
+				}
+			}
+			return 0;
+		}
+
+		private int CompareByField(int x, int y, IList path)
+		{
+			object xFieldValue = GetFieldValue(x, path);
+			object yFieldValue = GetFieldValue(y, path);
+			FieldMetadata field = ((FieldMetadata)path[path.Count - 1]);
+			return field.PrepareComparison(_transaction.Context(), xFieldValue).CompareTo(yFieldValue
+				);
+		}
+
+		private object GetFieldValue(int id, IList path)
+		{
+			for (int i = 0; i < path.Count - 1; ++i)
+			{
+				object obj = GetFieldValue(id, ((FieldMetadata)path[i]));
+				if (null == obj)
+				{
+					return null;
+				}
+				id = _container.GetID(_transaction, obj);
+			}
+			return GetFieldValue(id, ((FieldMetadata)path[path.Count - 1]));
+		}
+
+		internal class FieldValueKey
+		{
+			private int _id;
+
+			private FieldMetadata _field;
+
+			public FieldValueKey(int id, FieldMetadata field)
+			{
+				_id = id;
+				_field = field;
+			}
+
+			public override int GetHashCode()
+			{
+				return _field.GetHashCode() ^ _id;
+			}
+
+			public override bool Equals(object obj)
+			{
+				SodaQueryComparator.FieldValueKey other = (SodaQueryComparator.FieldValueKey)obj;
+				return _field == other._field && _id == other._id;
+			}
+		}
+
+		private object GetFieldValue(int id, FieldMetadata field)
+		{
+			SodaQueryComparator.FieldValueKey key = new SodaQueryComparator.FieldValueKey(id, 
+				field);
+			object cachedValue = _fieldValueCache[key];
+			if (null != cachedValue)
+			{
+				return cachedValue;
+			}
+			object fieldValue = ReadFieldValue(id, field);
+			_fieldValueCache[key] = fieldValue;
+			return fieldValue;
+		}
+
+		private object ReadFieldValue(int id, FieldMetadata field)
+		{
+			ByteArrayBuffer buffer = BufferFor(id);
+			HandlerVersion handlerVersion = field.ContainingClass().SeekToField(_transaction, 
+				buffer, field);
+			if (handlerVersion == HandlerVersion.Invalid)
+			{
+				return null;
+			}
+			QueryingReadContext context = new QueryingReadContext(_transaction, handlerVersion
+				._number, buffer, id);
+			return field.Read(context);
+		}
+
+		private ByteArrayBuffer BufferFor(int id)
+		{
+			ByteArrayBuffer cachedBuffer = ((ByteArrayBuffer)_bufferCache[id]);
+			if (null != cachedBuffer)
+			{
+				return cachedBuffer;
+			}
+			ByteArrayBuffer buffer = _container.ReadBufferById(_transaction, id);
+			_bufferCache[id] = buffer;
+			return buffer;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/HashcodeReferenceSystem.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/HashcodeReferenceSystem.cs
new file mode 100644
index 0000000..b80b996
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/HashcodeReferenceSystem.cs
@@ -0,0 +1,158 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Text;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.References;
+
+namespace Db4objects.Db4o.Internal.References
+{
+	/// <exclude></exclude>
+	public class HashcodeReferenceSystem : IReferenceSystem
+	{
+		private ObjectReference _hashCodeTree;
+
+		private ObjectReference _idTree;
+
+		public virtual void AddNewReference(ObjectReference @ref)
+		{
+			AddReference(@ref);
+		}
+
+		public virtual void AddExistingReference(ObjectReference @ref)
+		{
+			AddReference(@ref);
+		}
+
+		private void AddReference(ObjectReference @ref)
+		{
+			@ref.Ref_init();
+			IdAdd(@ref);
+			HashCodeAdd(@ref);
+		}
+
+		public virtual void Commit()
+		{
+		}
+
+		// do nothing
+		private void HashCodeAdd(ObjectReference @ref)
+		{
+			if (_hashCodeTree == null)
+			{
+				_hashCodeTree = @ref;
+				return;
+			}
+			_hashCodeTree = _hashCodeTree.Hc_add(@ref);
+		}
+
+		private void IdAdd(ObjectReference @ref)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.IdTreeAdd.Log(@ref.GetID());
+			}
+			if (_idTree == null)
+			{
+				_idTree = @ref;
+				return;
+			}
+			_idTree = _idTree.Id_add(@ref);
+		}
+
+		public virtual ObjectReference ReferenceForId(int id)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.GetYapobject.Log(id);
+			}
+			if (_idTree == null)
+			{
+				return null;
+			}
+			if (!ObjectReference.IsValidId(id))
+			{
+				return null;
+			}
+			return _idTree.Id_find(id);
+		}
+
+		public virtual ObjectReference ReferenceForObject(object obj)
+		{
+			if (_hashCodeTree == null)
+			{
+				return null;
+			}
+			return _hashCodeTree.Hc_find(obj);
+		}
+
+		public virtual void RemoveReference(ObjectReference @ref)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.ReferenceRemoved.Log(@ref.GetID());
+			}
+			if (_hashCodeTree != null)
+			{
+				_hashCodeTree = _hashCodeTree.Hc_remove(@ref);
+			}
+			if (_idTree != null)
+			{
+				_idTree = _idTree.Id_remove(@ref);
+			}
+		}
+
+		public virtual void Rollback()
+		{
+		}
+
+		// do nothing
+		public virtual void TraverseReferences(IVisitor4 visitor)
+		{
+			if (_hashCodeTree == null)
+			{
+				return;
+			}
+			_hashCodeTree.Hc_traverse(visitor);
+		}
+
+		public override string ToString()
+		{
+			BooleanByRef found = new BooleanByRef();
+			StringBuilder str = new StringBuilder("HashcodeReferenceSystem {");
+			TraverseReferences(new _IVisitor4_117(found, str));
+			str.Append("}");
+			return str.ToString();
+		}
+
+		private sealed class _IVisitor4_117 : IVisitor4
+		{
+			public _IVisitor4_117(BooleanByRef found, StringBuilder str)
+			{
+				this.found = found;
+				this.str = str;
+			}
+
+			public void Visit(object obj)
+			{
+				if (found.value)
+				{
+					str.Append(", ");
+				}
+				ObjectReference @ref = (ObjectReference)obj;
+				str.Append(@ref.GetID());
+				found.value = true;
+			}
+
+			private readonly BooleanByRef found;
+
+			private readonly StringBuilder str;
+		}
+
+		public virtual void Discarded()
+		{
+		}
+		// do nothing
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/IReferenceSystem.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/IReferenceSystem.cs
new file mode 100644
index 0000000..36cc097
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/IReferenceSystem.cs
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.References
+{
+	/// <exclude></exclude>
+	public interface IReferenceSystem
+	{
+		void AddNewReference(ObjectReference @ref);
+
+		void AddExistingReference(ObjectReference @ref);
+
+		void Commit();
+
+		ObjectReference ReferenceForId(int id);
+
+		ObjectReference ReferenceForObject(object obj);
+
+		void RemoveReference(ObjectReference @ref);
+
+		void Rollback();
+
+		void TraverseReferences(IVisitor4 visitor);
+
+		void Discarded();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/IReferenceSystemFactory.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/IReferenceSystemFactory.cs
new file mode 100644
index 0000000..9015378
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/IReferenceSystemFactory.cs
@@ -0,0 +1,13 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.References;
+
+namespace Db4objects.Db4o.Internal.References
+{
+	/// <exclude></exclude>
+	public interface IReferenceSystemFactory
+	{
+		IReferenceSystem NewReferenceSystem(IInternalObjectContainer container);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/ReferenceSystemRegistry.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/ReferenceSystemRegistry.cs
new file mode 100644
index 0000000..51210f6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/ReferenceSystemRegistry.cs
@@ -0,0 +1,107 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.References;
+
+namespace Db4objects.Db4o.Internal.References
+{
+	/// <exclude></exclude>
+	public class ReferenceSystemRegistry
+	{
+		private readonly Collection4 _referenceSystems = new Collection4();
+
+		public virtual void RemoveId(int id)
+		{
+			RemoveReference(new _IReferenceSource_17(id));
+		}
+
+		private sealed class _IReferenceSource_17 : ReferenceSystemRegistry.IReferenceSource
+		{
+			public _IReferenceSource_17(int id)
+			{
+				this.id = id;
+			}
+
+			public ObjectReference ReferenceFrom(IReferenceSystem referenceSystem)
+			{
+				return referenceSystem.ReferenceForId(id);
+			}
+
+			private readonly int id;
+		}
+
+		public virtual void RemoveObject(object obj)
+		{
+			RemoveReference(new _IReferenceSource_25(obj));
+		}
+
+		private sealed class _IReferenceSource_25 : ReferenceSystemRegistry.IReferenceSource
+		{
+			public _IReferenceSource_25(object obj)
+			{
+				this.obj = obj;
+			}
+
+			public ObjectReference ReferenceFrom(IReferenceSystem referenceSystem)
+			{
+				return referenceSystem.ReferenceForObject(obj);
+			}
+
+			private readonly object obj;
+		}
+
+		public virtual void RemoveReference(ObjectReference reference)
+		{
+			RemoveReference(new _IReferenceSource_33(reference));
+		}
+
+		private sealed class _IReferenceSource_33 : ReferenceSystemRegistry.IReferenceSource
+		{
+			public _IReferenceSource_33(ObjectReference reference)
+			{
+				this.reference = reference;
+			}
+
+			public ObjectReference ReferenceFrom(IReferenceSystem referenceSystem)
+			{
+				return reference;
+			}
+
+			private readonly ObjectReference reference;
+		}
+
+		private void RemoveReference(ReferenceSystemRegistry.IReferenceSource referenceSource
+			)
+		{
+			IEnumerator i = _referenceSystems.GetEnumerator();
+			while (i.MoveNext())
+			{
+				IReferenceSystem referenceSystem = (IReferenceSystem)i.Current;
+				ObjectReference reference = referenceSource.ReferenceFrom(referenceSystem);
+				if (reference != null)
+				{
+					referenceSystem.RemoveReference(reference);
+				}
+			}
+		}
+
+		public virtual void AddReferenceSystem(IReferenceSystem referenceSystem)
+		{
+			_referenceSystems.Add(referenceSystem);
+		}
+
+		public virtual bool RemoveReferenceSystem(IReferenceSystem referenceSystem)
+		{
+			bool res = _referenceSystems.Remove(referenceSystem);
+			referenceSystem.Discarded();
+			return res;
+		}
+
+		private interface IReferenceSource
+		{
+			ObjectReference ReferenceFrom(IReferenceSystem referenceSystem);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/TransactionalReferenceSystem.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/TransactionalReferenceSystem.cs
new file mode 100644
index 0000000..c7ed3f9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/TransactionalReferenceSystem.cs
@@ -0,0 +1,63 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.References;
+
+namespace Db4objects.Db4o.Internal.References
+{
+	/// <exclude></exclude>
+	public class TransactionalReferenceSystem : TransactionalReferenceSystemBase, IReferenceSystem
+	{
+		public override void Commit()
+		{
+			TraverseNewReferences(new _IVisitor4_16(this));
+			CreateNewReferences();
+		}
+
+		private sealed class _IVisitor4_16 : IVisitor4
+		{
+			public _IVisitor4_16(TransactionalReferenceSystem _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Visit(object obj)
+			{
+				ObjectReference oref = (ObjectReference)obj;
+				if (oref.GetObject() != null)
+				{
+					this._enclosing._committedReferences.AddExistingReference(oref);
+				}
+			}
+
+			private readonly TransactionalReferenceSystem _enclosing;
+		}
+
+		public override void AddExistingReference(ObjectReference @ref)
+		{
+			_committedReferences.AddExistingReference(@ref);
+		}
+
+		public override void AddNewReference(ObjectReference @ref)
+		{
+			_newReferences.AddNewReference(@ref);
+		}
+
+		public override void RemoveReference(ObjectReference @ref)
+		{
+			_newReferences.RemoveReference(@ref);
+			_committedReferences.RemoveReference(@ref);
+		}
+
+		public override void Rollback()
+		{
+			CreateNewReferences();
+		}
+
+		public virtual void Discarded()
+		{
+		}
+		// do nothing;
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/TransactionalReferenceSystemBase.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/TransactionalReferenceSystemBase.cs
new file mode 100644
index 0000000..df3180e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/References/TransactionalReferenceSystemBase.cs
@@ -0,0 +1,73 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.References;
+
+namespace Db4objects.Db4o.Internal.References
+{
+	/// <exclude></exclude>
+	public abstract class TransactionalReferenceSystemBase
+	{
+		protected readonly IReferenceSystem _committedReferences;
+
+		protected IReferenceSystem _newReferences;
+
+		public TransactionalReferenceSystemBase()
+		{
+			CreateNewReferences();
+			_committedReferences = NewReferenceSystem();
+		}
+
+		private IReferenceSystem NewReferenceSystem()
+		{
+			return new HashcodeReferenceSystem();
+		}
+
+		public abstract void AddExistingReference(ObjectReference @ref);
+
+		public abstract void AddNewReference(ObjectReference @ref);
+
+		public abstract void Commit();
+
+		protected virtual void TraverseNewReferences(IVisitor4 visitor)
+		{
+			_newReferences.TraverseReferences(visitor);
+		}
+
+		protected virtual void CreateNewReferences()
+		{
+			_newReferences = NewReferenceSystem();
+		}
+
+		public virtual ObjectReference ReferenceForId(int id)
+		{
+			ObjectReference @ref = _newReferences.ReferenceForId(id);
+			if (@ref != null)
+			{
+				return @ref;
+			}
+			return _committedReferences.ReferenceForId(id);
+		}
+
+		public virtual ObjectReference ReferenceForObject(object obj)
+		{
+			ObjectReference @ref = _newReferences.ReferenceForObject(obj);
+			if (@ref != null)
+			{
+				return @ref;
+			}
+			return _committedReferences.ReferenceForObject(obj);
+		}
+
+		public abstract void RemoveReference(ObjectReference @ref);
+
+		public abstract void Rollback();
+
+		public virtual void TraverseReferences(IVisitor4 visitor)
+		{
+			TraverseNewReferences(visitor);
+			_committedReferences.TraverseReferences(visitor);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflect/Generic/KnownClassesCollector.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflect/Generic/KnownClassesCollector.cs
new file mode 100644
index 0000000..1bc7440
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflect/Generic/KnownClassesCollector.cs
@@ -0,0 +1,105 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Generic;
+
+namespace Db4objects.Db4o.Internal.Reflect.Generic
+{
+	public class KnownClassesCollector
+	{
+		private readonly ObjectContainerBase _container;
+
+		private readonly KnownClassesRepository _repository;
+
+		public KnownClassesCollector(ObjectContainerBase container, KnownClassesRepository
+			 repository)
+		{
+			_container = container;
+			_repository = repository;
+		}
+
+		public virtual IReflectClass[] Collect()
+		{
+			Collection4 classes = new Collection4();
+			CollectKnownClasses(classes);
+			return (IReflectClass[])classes.ToArray(new IReflectClass[classes.Size()]);
+		}
+
+		private void CollectKnownClasses(Collection4 classes)
+		{
+			IListener4 collectingListener = NewCollectingClassListener(classes);
+			_repository.AddListener(collectingListener);
+			try
+			{
+				CollectKnownClasses(classes, Iterators.Copy(_repository.Classes()));
+			}
+			finally
+			{
+				_repository.RemoveListener(collectingListener);
+			}
+		}
+
+		private IListener4 NewCollectingClassListener(Collection4 classes)
+		{
+			return new _IListener4_37(this, classes);
+		}
+
+		private sealed class _IListener4_37 : IListener4
+		{
+			public _IListener4_37(KnownClassesCollector _enclosing, Collection4 classes)
+			{
+				this._enclosing = _enclosing;
+				this.classes = classes;
+			}
+
+			public void OnEvent(object addedClass)
+			{
+				this._enclosing.CollectKnownClass(classes, ((IReflectClass)addedClass));
+			}
+
+			private readonly KnownClassesCollector _enclosing;
+
+			private readonly Collection4 classes;
+		}
+
+		private void CollectKnownClasses(Collection4 collector, IEnumerator knownClasses)
+		{
+			while (knownClasses.MoveNext())
+			{
+				IReflectClass clazz = (IReflectClass)knownClasses.Current;
+				CollectKnownClass(collector, clazz);
+			}
+		}
+
+		private void CollectKnownClass(Collection4 classes, IReflectClass clazz)
+		{
+			if (IsInternalClass(clazz))
+			{
+				return;
+			}
+			if (!HasIdentity(clazz))
+			{
+				return;
+			}
+			if (clazz.IsArray())
+			{
+				return;
+			}
+			classes.Add(clazz);
+		}
+
+		private bool IsInternalClass(IReflectClass clazz)
+		{
+			return _container._handlers.IclassInternal.IsAssignableFrom(clazz);
+		}
+
+		private bool HasIdentity(IReflectClass clazz)
+		{
+			ClassMetadata clazzMeta = _container.ClassMetadataForReflectClass(clazz);
+			return clazzMeta == null || clazzMeta.HasIdentity();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflect/IFieldAccessor.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflect/IFieldAccessor.cs
new file mode 100644
index 0000000..c0ec8e9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflect/IFieldAccessor.cs
@@ -0,0 +1,14 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Reflect
+{
+	/// <since>7.7</since>
+	public interface IFieldAccessor
+	{
+		void Set(IReflectField field, object onObject, object value);
+
+		object Get(IReflectField field, object onObject);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflect/LenientFieldAccessor.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflect/LenientFieldAccessor.cs
new file mode 100644
index 0000000..3f4e0af
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflect/LenientFieldAccessor.cs
@@ -0,0 +1,35 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal.Reflect;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Reflect
+{
+	/// <since>7.7</since>
+	public class LenientFieldAccessor : IFieldAccessor
+	{
+		public virtual object Get(IReflectField field, object onObject)
+		{
+			try
+			{
+				return field.Get(onObject);
+			}
+			catch (Db4oException)
+			{
+				return null;
+			}
+		}
+
+		public virtual void Set(IReflectField field, object onObject, object value)
+		{
+			try
+			{
+				field.Set(onObject, value);
+			}
+			catch (Db4oException)
+			{
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflect/ReflectClasses.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflect/ReflectClasses.cs
new file mode 100644
index 0000000..6ad48f3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflect/ReflectClasses.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Reflect
+{
+	public class ReflectClasses
+	{
+		public static bool AreEqual(Type expected, IReflectClass actual)
+		{
+			return actual.Reflector().ForClass(expected) == actual;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflect/StrictFieldAccessor.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflect/StrictFieldAccessor.cs
new file mode 100644
index 0000000..de7d108
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflect/StrictFieldAccessor.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Reflect;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Reflect
+{
+	/// <since>7.7</since>
+	public class StrictFieldAccessor : IFieldAccessor
+	{
+		public virtual object Get(IReflectField field, object onObject)
+		{
+			return field.Get(onObject);
+		}
+
+		public virtual void Set(IReflectField field, object onObject, object value)
+		{
+			field.Set(onObject, value);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ReflectException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ReflectException.cs
new file mode 100644
index 0000000..e4aa78d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ReflectException.cs
@@ -0,0 +1,38 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <summary>
+	/// db4o-specific exception.<br />
+	/// <br />
+	/// This exception is thrown when one of the db4o reflection methods fails.
+	/// </summary>
+	/// <remarks>
+	/// db4o-specific exception.<br />
+	/// <br />
+	/// This exception is thrown when one of the db4o reflection methods fails.
+	/// </remarks>
+	/// <seealso cref="Db4objects.Db4o.Reflect">Db4objects.Db4o.Reflect</seealso>
+	[System.Serializable]
+	public class ReflectException : Db4oRecoverableException
+	{
+		public ReflectException(string msg, Exception cause) : base(msg, cause)
+		{
+		}
+
+		/// <summary>Constructor with the cause exception</summary>
+		/// <param name="cause">cause exception</param>
+		public ReflectException(Exception cause) : base(cause)
+		{
+		}
+
+		/// <summary>Constructor with message</summary>
+		/// <param name="message">detailed explanation</param>
+		public ReflectException(string message) : base(message)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflection4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflection4.cs
new file mode 100644
index 0000000..e984439
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Reflection4.cs
@@ -0,0 +1,241 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Reflection;
+using System.Text;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Sharpen;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude>
+	/// Use the methods in this class for system classes only, since they
+	/// are not ClassLoader or Reflector-aware.
+	/// TODO: this class should go to foundation.reflect, along with ReflectException and ReflectPlatform
+	/// </exclude>
+	public class Reflection4
+	{
+		public static object InvokeStatic(Type clazz, string methodName)
+		{
+			return Invoke(clazz, methodName, null, null, null);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.ReflectException"></exception>
+		public static object Invoke(object obj, string methodName)
+		{
+			return Invoke(obj.GetType(), methodName, null, null, obj);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.ReflectException"></exception>
+		public static object Invoke(object obj, string methodName, object[] @params)
+		{
+			Type[] paramClasses = new Type[@params.Length];
+			for (int i = 0; i < @params.Length; i++)
+			{
+				paramClasses[i] = @params[i].GetType();
+			}
+			return Invoke(obj.GetType(), methodName, paramClasses, @params, obj);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.ReflectException"></exception>
+		public static object Invoke(object obj, string methodName, Type[] paramClasses, object
+			[] @params)
+		{
+			return Invoke(obj.GetType(), methodName, paramClasses, @params, obj);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.ReflectException"></exception>
+		public static object Invoke(Type clazz, string methodName, Type[] paramClasses, object
+			[] @params)
+		{
+			return Invoke(clazz, methodName, paramClasses, @params, null);
+		}
+
+		private static object Invoke(Type clazz, string methodName, Type[] paramClasses, 
+			object[] @params, object onObject)
+		{
+			return Invoke(@params, onObject, GetMethod(clazz, methodName, paramClasses));
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.ReflectException"></exception>
+		public static object Invoke(string className, string methodName, Type[] paramClasses
+			, object[] @params, object onObject)
+		{
+			MethodInfo method = GetMethod(className, methodName, paramClasses);
+			return Invoke(@params, onObject, method);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.ReflectException"></exception>
+		public static object Invoke(object[] @params, object onObject, MethodInfo method)
+		{
+			if (method == null)
+			{
+				return null;
+			}
+			Platform4.SetAccessible(method);
+			try
+			{
+				return method.Invoke(onObject, @params);
+			}
+			catch (TargetInvocationException e)
+			{
+				throw new ReflectException(e.InnerException);
+			}
+			catch (ArgumentException e)
+			{
+				throw new ReflectException(e);
+			}
+			catch (MemberAccessException e)
+			{
+				throw new ReflectException(e);
+			}
+		}
+
+		/// <summary>calling this method "method" will break C# conversion with the old converter
+		/// 	</summary>
+		public static MethodInfo GetMethod(string className, string methodName, Type[] paramClasses
+			)
+		{
+			Type clazz = ReflectPlatform.ForName(className);
+			if (clazz == null)
+			{
+				return null;
+			}
+			return GetMethod(clazz, methodName, paramClasses);
+		}
+
+		public static MethodInfo GetMethod(Type clazz, string methodName, Type[] paramClasses
+			)
+		{
+			Type curclazz = clazz;
+			while (curclazz != null)
+			{
+				try
+				{
+					return Sharpen.Runtime.GetDeclaredMethod(curclazz, methodName, paramClasses);
+				}
+				catch (Exception)
+				{
+				}
+				curclazz = curclazz.BaseType;
+			}
+			return null;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.ReflectException"></exception>
+		public static object Invoke(object obj, string methodName, Type signature, object
+			 value)
+		{
+			return Invoke(obj, methodName, new Type[] { signature }, new object[] { value });
+		}
+
+		public static FieldInfo GetField(Type clazz, string name)
+		{
+			Type curclazz = clazz;
+			while (curclazz != null)
+			{
+				try
+				{
+					FieldInfo field = Sharpen.Runtime.GetDeclaredField(curclazz, name);
+					Platform4.SetAccessible(field);
+					if (field != null)
+					{
+						return field;
+					}
+				}
+				catch (Exception)
+				{
+				}
+				curclazz = curclazz.BaseType;
+			}
+			return null;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.ReflectException"></exception>
+		public static object GetFieldValue(object obj, string fieldName)
+		{
+			try
+			{
+				return GetField(obj.GetType(), fieldName).GetValue(obj);
+			}
+			catch (Exception e)
+			{
+				throw new ReflectException(e);
+			}
+		}
+
+		public static object NewInstance(object template)
+		{
+			try
+			{
+				return System.Activator.CreateInstance(template.GetType());
+			}
+			catch (Exception e)
+			{
+				throw new ReflectException(e);
+			}
+		}
+
+		public static string Dump(object obj)
+		{
+			return DumpPreventRecursion(obj, new IdentitySet4(), 2);
+		}
+
+		private static string DumpPreventRecursion(object obj, IdentitySet4 dumped, int stackLimit
+			)
+		{
+			stackLimit--;
+			if (obj == null)
+			{
+				return "null";
+			}
+			Type clazz = obj.GetType();
+			if (Platform4.IsSimple(clazz))
+			{
+				return obj.ToString();
+			}
+			StringBuilder sb = new StringBuilder();
+			sb.Append(clazz.FullName);
+			sb.Append(" (");
+			sb.Append(Runtime.IdentityHashCode(obj));
+			sb.Append(")");
+			if (dumped.Contains(obj) || stackLimit <= 0)
+			{
+				return sb.ToString();
+			}
+			dumped.Add(obj);
+			FieldInfo[] fields = Sharpen.Runtime.GetDeclaredFields(clazz);
+			for (int fieldIndex = 0; fieldIndex < fields.Length; ++fieldIndex)
+			{
+				FieldInfo field = fields[fieldIndex];
+				Platform4.SetAccessible(field);
+				try
+				{
+					if (field.GetValue(null) == field.GetValue(obj))
+					{
+						continue;
+					}
+				}
+				catch (Exception)
+				{
+				}
+				// static field.getModifiers() wouldn't sharpen 
+				sb.Append("\n");
+				sb.Append("\t");
+				sb.Append(field.Name);
+				sb.Append(": ");
+				try
+				{
+					sb.Append(DumpPreventRecursion(field.GetValue(obj), dumped, stackLimit));
+				}
+				catch (Exception e)
+				{
+					sb.Append("Exception caught: ");
+					sb.Append(e);
+				}
+			}
+			return sb.ToString();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ReflectorConfigurationImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ReflectorConfigurationImpl.cs
new file mode 100644
index 0000000..60f5358
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ReflectorConfigurationImpl.cs
@@ -0,0 +1,56 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal
+{
+	public class ReflectorConfigurationImpl : IReflectorConfiguration
+	{
+		private Config4Impl _config;
+
+		public ReflectorConfigurationImpl(Config4Impl config)
+		{
+			_config = config;
+		}
+
+		public virtual bool TestConstructors()
+		{
+			return _config.TestConstructors();
+		}
+
+		public virtual bool CallConstructor(IReflectClass clazz)
+		{
+			TernaryBool specialized = CallConstructorSpecialized(clazz);
+			if (!specialized.IsUnspecified())
+			{
+				return specialized.DefiniteYes();
+			}
+			return _config.CallConstructors().DefiniteYes();
+		}
+
+		private TernaryBool CallConstructorSpecialized(IReflectClass clazz)
+		{
+			Config4Class clazzConfig = _config.ConfigClass(clazz.GetName());
+			if (clazzConfig != null)
+			{
+				TernaryBool res = clazzConfig.CallConstructor();
+				if (!res.IsUnspecified())
+				{
+					return res;
+				}
+			}
+			if (Platform4.IsEnum(_config.Reflector(), clazz))
+			{
+				return TernaryBool.No;
+			}
+			IReflectClass ancestor = clazz.GetSuperclass();
+			if (ancestor != null)
+			{
+				return CallConstructorSpecialized(ancestor);
+			}
+			return TernaryBool.Unspecified;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Renames.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Renames.cs
new file mode 100644
index 0000000..880d191
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Renames.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.Internal
+{
+	public class Renames
+	{
+		public static Rename ForField(string className, string name, string newName)
+		{
+			return new Rename(className, name, newName);
+		}
+
+		public static Rename ForClass(string name, string newName)
+		{
+			return new Rename(string.Empty, name, newName);
+		}
+
+		public static Rename ForInverseQBE(Rename ren)
+		{
+			return new Rename(ren.rClass, null, ren.rFrom);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Replication/IDb4oReplicationReference.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Replication/IDb4oReplicationReference.cs
new file mode 100644
index 0000000..c6ec959
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Replication/IDb4oReplicationReference.cs
@@ -0,0 +1,16 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Internal.Replication
+{
+	/// <exclude></exclude>
+	public interface IDb4oReplicationReference
+	{
+		Db4oDatabase SignaturePart();
+
+		long LongPart();
+
+		long Version();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Replication/IDb4oReplicationReferenceProvider.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Replication/IDb4oReplicationReferenceProvider.cs
new file mode 100644
index 0000000..a4095c4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Replication/IDb4oReplicationReferenceProvider.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Replication;
+
+namespace Db4objects.Db4o.Internal.Replication
+{
+	/// <exclude></exclude>
+	public interface IDb4oReplicationReferenceProvider
+	{
+		IDb4oReplicationReference ReferenceFor(object obj);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/SerializedGraph.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/SerializedGraph.cs
new file mode 100644
index 0000000..cf3d1ed
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/SerializedGraph.cs
@@ -0,0 +1,45 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class SerializedGraph
+	{
+		public readonly int _id;
+
+		public readonly byte[] _bytes;
+
+		public SerializedGraph(int id, byte[] bytes)
+		{
+			_id = id;
+			_bytes = bytes;
+		}
+
+		public virtual int Length()
+		{
+			return _bytes.Length;
+		}
+
+		public virtual int MarshalledLength()
+		{
+			return (Const4.IntLength * 2) + Length();
+		}
+
+		public virtual void Write(ByteArrayBuffer buffer)
+		{
+			buffer.WriteInt(_id);
+			buffer.WriteInt(Length());
+			buffer.Append(_bytes);
+		}
+
+		public static Db4objects.Db4o.Internal.SerializedGraph Read(ByteArrayBuffer buffer
+			)
+		{
+			int id = buffer.ReadInt();
+			int length = buffer.ReadInt();
+			return new Db4objects.Db4o.Internal.SerializedGraph(id, buffer.ReadBytes(length));
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Serializer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Serializer.cs
new file mode 100644
index 0000000..0bddc7b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Serializer.cs
@@ -0,0 +1,76 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class Serializer
+	{
+		public static StatefulBuffer Marshall(Transaction ta, object obj)
+		{
+			SerializedGraph serialized = Marshall(ta.Container(), obj);
+			StatefulBuffer buffer = new StatefulBuffer(ta, serialized.Length());
+			buffer.Append(serialized._bytes);
+			buffer.UseSlot(serialized._id, 0, serialized.Length());
+			return buffer;
+		}
+
+		public static SerializedGraph Marshall(ObjectContainerBase serviceProvider, object
+			 obj)
+		{
+			MemoryBin memoryBin = new MemoryBin(223, GrowthStrategy());
+			TransportObjectContainer carrier = NewTransportObjectContainer(serviceProvider, memoryBin
+				);
+			carrier.ProduceClassMetadata(carrier.Reflector().ForObject(obj));
+			carrier.Store(obj);
+			int id = (int)carrier.GetID(obj);
+			carrier.Close();
+			return new SerializedGraph(id, memoryBin.Data());
+		}
+
+		private static ConstantGrowthStrategy GrowthStrategy()
+		{
+			return new ConstantGrowthStrategy(300);
+		}
+
+		private static TransportObjectContainer NewTransportObjectContainer(ObjectContainerBase
+			 serviceProvider, MemoryBin memoryBin)
+		{
+			TransportObjectContainer container = new TransportObjectContainer(serviceProvider
+				, memoryBin);
+			container.DeferredOpen();
+			return container;
+		}
+
+		public static object Unmarshall(ObjectContainerBase serviceProvider, StatefulBuffer
+			 buffer)
+		{
+			return Unmarshall(serviceProvider, buffer._buffer, buffer.GetID());
+		}
+
+		public static object Unmarshall(ObjectContainerBase serviceProvider, SerializedGraph
+			 serialized)
+		{
+			return Unmarshall(serviceProvider, serialized._bytes, serialized._id);
+		}
+
+		public static object Unmarshall(ObjectContainerBase serviceProvider, byte[] bytes
+			, int id)
+		{
+			if (id <= 0)
+			{
+				return null;
+			}
+			MemoryBin memoryBin = new MemoryBin(bytes, GrowthStrategy());
+			TransportObjectContainer carrier = NewTransportObjectContainer(serviceProvider, memoryBin
+				);
+			object obj = carrier.GetByID(id);
+			carrier.Activate(carrier.Transaction, obj, new FullActivationDepth());
+			carrier.Close();
+			return obj;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/SharedIndexedFields.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/SharedIndexedFields.cs
new file mode 100644
index 0000000..5277a92
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/SharedIndexedFields.cs
@@ -0,0 +1,17 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class SharedIndexedFields
+	{
+		public readonly VersionFieldMetadata _version = new VersionFieldMetadata();
+
+		public readonly UUIDFieldMetadata _uUID = new UUIDFieldMetadata();
+
+		public readonly CommitTimestampFieldMetadata _commitTimestamp = new CommitTimestampFieldMetadata
+			();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ShutDownRunnable.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ShutDownRunnable.cs
new file mode 100644
index 0000000..9a9f7a4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/ShutDownRunnable.cs
@@ -0,0 +1,42 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal
+{
+	internal class ShutDownRunnable : IRunnable
+	{
+		private Collection4 _containers = new Collection4();
+
+		public volatile bool dontRemove = false;
+
+		public virtual void Ensure(ObjectContainerBase container)
+		{
+			_containers.Ensure(container);
+		}
+
+		public virtual void Remove(ObjectContainerBase container)
+		{
+			_containers.Remove(container);
+		}
+
+		public virtual void Run()
+		{
+			dontRemove = true;
+			Collection4 copy = new Collection4(_containers);
+			IEnumerator i = copy.GetEnumerator();
+			while (i.MoveNext())
+			{
+				((ObjectContainerBase)i.Current).ShutdownHook();
+			}
+		}
+
+		public virtual int Size()
+		{
+			return _containers.Size();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/FreespaceSlotChange.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/FreespaceSlotChange.cs
new file mode 100644
index 0000000..05dd52b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/FreespaceSlotChange.cs
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Slots
+{
+	/// <exclude></exclude>
+	public class FreespaceSlotChange : IdSystemSlotChange
+	{
+		public FreespaceSlotChange(int id) : base(id)
+		{
+		}
+
+		protected override bool ForFreespace()
+		{
+			return true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/IdSystemSlotChange.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/IdSystemSlotChange.cs
new file mode 100644
index 0000000..36f1135
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/IdSystemSlotChange.cs
@@ -0,0 +1,58 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Slots
+{
+	/// <exclude></exclude>
+	public class IdSystemSlotChange : SystemSlotChange
+	{
+		private Collection4 _freed;
+
+		public IdSystemSlotChange(int id) : base(id)
+		{
+		}
+
+		protected override void Free(IFreespaceManager freespaceManager, Slot slot)
+		{
+			if (slot.IsNull())
+			{
+				return;
+			}
+			if (_freed == null)
+			{
+				_freed = new Collection4();
+			}
+			_freed.Add(slot);
+		}
+
+		public override void AccumulateFreeSlot(TransactionalIdSystemImpl idSystem, FreespaceCommitter
+			 freespaceCommitter, bool forFreespace)
+		{
+			if (ForFreespace() != forFreespace)
+			{
+				return;
+			}
+			base.AccumulateFreeSlot(idSystem, freespaceCommitter, forFreespace);
+			if (_freed == null)
+			{
+				return;
+			}
+			IEnumerator iterator = _freed.GetEnumerator();
+			while (iterator.MoveNext())
+			{
+				freespaceCommitter.DelayedFree((Slot)iterator.Current, FreeToSystemFreespaceSystem
+					());
+			}
+		}
+
+		protected override bool FreeToSystemFreespaceSystem()
+		{
+			return true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/Pointer4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/Pointer4.cs
new file mode 100644
index 0000000..bc3a016
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/Pointer4.cs
@@ -0,0 +1,35 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Slots
+{
+	/// <exclude></exclude>
+	public class Pointer4
+	{
+		public readonly int _id;
+
+		public readonly Slot _slot;
+
+		public Pointer4(int id, Slot slot)
+		{
+			_id = id;
+			_slot = slot;
+		}
+
+		public virtual int Address()
+		{
+			return _slot.Address();
+		}
+
+		public virtual int Id()
+		{
+			return _id;
+		}
+
+		public virtual int Length()
+		{
+			return _slot.Length();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/ReferencedSlot.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/ReferencedSlot.cs
new file mode 100644
index 0000000..f7670ba
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/ReferencedSlot.cs
@@ -0,0 +1,65 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Slots
+{
+	/// <exclude></exclude>
+	public class ReferencedSlot : TreeInt
+	{
+		private Db4objects.Db4o.Internal.Slots.Slot _slot;
+
+		private int _references;
+
+		public ReferencedSlot(int a_key) : base(a_key)
+		{
+		}
+
+		public override object ShallowClone()
+		{
+			Db4objects.Db4o.Internal.Slots.ReferencedSlot rs = new Db4objects.Db4o.Internal.Slots.ReferencedSlot
+				(_key);
+			rs._slot = _slot;
+			rs._references = _references;
+			return base.ShallowCloneInternal(rs);
+		}
+
+		public virtual void PointTo(Db4objects.Db4o.Internal.Slots.Slot slot)
+		{
+			_slot = slot;
+		}
+
+		public virtual Tree Free(LocalObjectContainer file, Tree treeRoot, Db4objects.Db4o.Internal.Slots.Slot
+			 slot)
+		{
+			file.Free(_slot.Address(), _slot.Length());
+			if (RemoveReferenceIsLast())
+			{
+				if (treeRoot != null)
+				{
+					return treeRoot.RemoveNode(this);
+				}
+			}
+			PointTo(slot);
+			return treeRoot;
+		}
+
+		public virtual bool AddReferenceIsFirst()
+		{
+			_references++;
+			return (_references == 1);
+		}
+
+		public virtual bool RemoveReferenceIsLast()
+		{
+			_references--;
+			return _references < 1;
+		}
+
+		public virtual Db4objects.Db4o.Internal.Slots.Slot Slot()
+		{
+			return _slot;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/Slot.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/Slot.cs
new file mode 100644
index 0000000..72755a0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/Slot.cs
@@ -0,0 +1,132 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Slots
+{
+	/// <exclude></exclude>
+	public class Slot
+	{
+		private readonly int _address;
+
+		private readonly int _length;
+
+		public static readonly Db4objects.Db4o.Internal.Slots.Slot Zero = new Db4objects.Db4o.Internal.Slots.Slot
+			(0, 0);
+
+		public const int New = -1;
+
+		public const int Update = -2;
+
+		public Slot(int address, int length)
+		{
+			_address = address;
+			_length = length;
+		}
+
+		public virtual int Address()
+		{
+			return _address;
+		}
+
+		public virtual int Length()
+		{
+			return _length;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (obj == this)
+			{
+				return true;
+			}
+			if (!(obj is Db4objects.Db4o.Internal.Slots.Slot))
+			{
+				return false;
+			}
+			Db4objects.Db4o.Internal.Slots.Slot other = (Db4objects.Db4o.Internal.Slots.Slot)
+				obj;
+			return (_address == other._address) && (Length() == other.Length());
+		}
+
+		public override int GetHashCode()
+		{
+			return _address ^ Length();
+		}
+
+		public virtual Db4objects.Db4o.Internal.Slots.Slot SubSlot(int offset)
+		{
+			return new Db4objects.Db4o.Internal.Slots.Slot(_address + offset, Length() - offset
+				);
+		}
+
+		public override string ToString()
+		{
+			return "[A:" + _address + ",L:" + Length() + "]";
+		}
+
+		public virtual Db4objects.Db4o.Internal.Slots.Slot Truncate(int requiredLength)
+		{
+			return new Db4objects.Db4o.Internal.Slots.Slot(_address, requiredLength);
+		}
+
+		public static int MarshalledLength = Const4.IntLength * 2;
+
+		public virtual int CompareByAddress(Db4objects.Db4o.Internal.Slots.Slot slot)
+		{
+			// FIXME: This is the wrong way around !!!
+			// Fix here and in all referers.
+			int res = slot._address - _address;
+			if (res != 0)
+			{
+				return res;
+			}
+			return slot.Length() - Length();
+		}
+
+		public virtual int CompareByLength(Db4objects.Db4o.Internal.Slots.Slot slot)
+		{
+			// FIXME: This is the wrong way around !!!
+			// Fix here and in all referers.
+			int res = slot.Length() - Length();
+			if (res != 0)
+			{
+				return res;
+			}
+			return slot._address - _address;
+		}
+
+		public virtual bool IsDirectlyPreceding(Db4objects.Db4o.Internal.Slots.Slot other
+			)
+		{
+			return _address + Length() == other._address;
+		}
+
+		public virtual Db4objects.Db4o.Internal.Slots.Slot Append(Db4objects.Db4o.Internal.Slots.Slot
+			 slot)
+		{
+			return new Db4objects.Db4o.Internal.Slots.Slot(Address(), _length + slot.Length()
+				);
+		}
+
+		public virtual bool IsNull()
+		{
+			return Address() == 0 || Length() == 0;
+		}
+
+		public virtual bool IsNew()
+		{
+			return _address == New;
+		}
+
+		public virtual bool IsUpdate()
+		{
+			return _address == Update;
+		}
+
+		public static bool IsNull(Db4objects.Db4o.Internal.Slots.Slot slot)
+		{
+			return slot == null || slot.IsNull();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/SlotChange.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/SlotChange.cs
new file mode 100644
index 0000000..f9766b0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/SlotChange.cs
@@ -0,0 +1,253 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Slots
+{
+	/// <exclude></exclude>
+	public class SlotChange : TreeInt
+	{
+		private class SlotChangeOperation
+		{
+			private readonly string _type;
+
+			public SlotChangeOperation(string type)
+			{
+				_type = type;
+			}
+
+			internal static readonly SlotChange.SlotChangeOperation create = new SlotChange.SlotChangeOperation
+				("create");
+
+			internal static readonly SlotChange.SlotChangeOperation update = new SlotChange.SlotChangeOperation
+				("update");
+
+			internal static readonly SlotChange.SlotChangeOperation delete = new SlotChange.SlotChangeOperation
+				("delete");
+
+			public override string ToString()
+			{
+				return _type;
+			}
+		}
+
+		private SlotChange.SlotChangeOperation _firstOperation;
+
+		private SlotChange.SlotChangeOperation _currentOperation;
+
+		protected Slot _newSlot;
+
+		public SlotChange(int id) : base(id)
+		{
+		}
+
+		public override object ShallowClone()
+		{
+			SlotChange sc = new SlotChange(0);
+			sc.NewSlot(_newSlot);
+			return base.ShallowCloneInternal(sc);
+		}
+
+		public virtual void AccumulateFreeSlot(TransactionalIdSystemImpl idSystem, FreespaceCommitter
+			 freespaceCommitter, bool forFreespace)
+		{
+			if (ForFreespace() != forFreespace)
+			{
+				return;
+			}
+			if (_firstOperation == SlotChange.SlotChangeOperation.create)
+			{
+				return;
+			}
+			if (_currentOperation == SlotChange.SlotChangeOperation.update || _currentOperation
+				 == SlotChange.SlotChangeOperation.delete)
+			{
+				Slot slot = ModifiedSlotInParentIdSystem(idSystem);
+				if (Slot.IsNull(slot))
+				{
+					slot = idSystem.CommittedSlot(_key);
+				}
+				// No old slot at all can be the case if the object
+				// has been deleted by another transaction and we add it again.
+				if (!Slot.IsNull(slot))
+				{
+					freespaceCommitter.DelayedFree(slot, FreeToSystemFreespaceSystem());
+				}
+			}
+		}
+
+		protected virtual bool ForFreespace()
+		{
+			return false;
+		}
+
+		protected virtual Slot ModifiedSlotInParentIdSystem(TransactionalIdSystemImpl idSystem
+			)
+		{
+			return idSystem.ModifiedSlotInParentIdSystem(_key);
+		}
+
+		public virtual bool IsDeleted()
+		{
+			return SlotModified() && _newSlot.IsNull();
+		}
+
+		public virtual bool IsNew()
+		{
+			return _firstOperation == SlotChange.SlotChangeOperation.create;
+		}
+
+		private bool IsFreeOnRollback()
+		{
+			return !Slot.IsNull(_newSlot);
+		}
+
+		public bool SlotModified()
+		{
+			return _newSlot != null;
+		}
+
+		/// <summary>FIXME:	Check where pointers should be freed on commit.</summary>
+		/// <remarks>
+		/// FIXME:	Check where pointers should be freed on commit.
+		/// This should be triggered in this class.
+		/// </remarks>
+		public virtual Slot NewSlot()
+		{
+			//	private final boolean isFreePointerOnCommit() {
+			//		return isBitSet(FREE_POINTER_ON_COMMIT_BIT);
+			//	}
+			return _newSlot;
+		}
+
+		public override object Read(ByteArrayBuffer reader)
+		{
+			SlotChange change = new SlotChange(reader.ReadInt());
+			Slot newSlot = new Slot(reader.ReadInt(), reader.ReadInt());
+			change.NewSlot(newSlot);
+			return change;
+		}
+
+		public virtual void Rollback(IFreespaceManager freespaceManager)
+		{
+			if (IsFreeOnRollback())
+			{
+				freespaceManager.Free(_newSlot);
+			}
+		}
+
+		public override void Write(ByteArrayBuffer writer)
+		{
+			if (SlotModified())
+			{
+				writer.WriteInt(_key);
+				writer.WriteInt(_newSlot.Address());
+				writer.WriteInt(_newSlot.Length());
+			}
+		}
+
+		public void WritePointer(LocalObjectContainer container)
+		{
+			if (SlotModified())
+			{
+				container.WritePointer(_key, _newSlot);
+			}
+		}
+
+		private void NewSlot(Slot slot)
+		{
+			_newSlot = slot;
+		}
+
+		public virtual void NotifySlotUpdated(IFreespaceManager freespaceManager, Slot slot
+			)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.NotifySlotUpdated.LogLength(_key, slot);
+			}
+			FreePreviouslyModifiedSlot(freespaceManager);
+			_newSlot = slot;
+			Operation(SlotChange.SlotChangeOperation.update);
+		}
+
+		protected virtual void FreePreviouslyModifiedSlot(IFreespaceManager freespaceManager
+			)
+		{
+			if (Slot.IsNull(_newSlot))
+			{
+				return;
+			}
+			Free(freespaceManager, _newSlot);
+			_newSlot = null;
+		}
+
+		protected virtual void Free(IFreespaceManager freespaceManager, Slot slot)
+		{
+			if (slot.IsNull())
+			{
+				return;
+			}
+			if (freespaceManager == null)
+			{
+				return;
+			}
+			freespaceManager.Free(slot);
+		}
+
+		private void Operation(SlotChange.SlotChangeOperation operation)
+		{
+			if (_firstOperation == null)
+			{
+				_firstOperation = operation;
+			}
+			_currentOperation = operation;
+		}
+
+		public virtual void NotifySlotCreated(Slot slot)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.NotifySlotCreated.Log(_key);
+				DTrace.NotifySlotCreated.LogLength(slot);
+			}
+			Operation(SlotChange.SlotChangeOperation.create);
+			_newSlot = slot;
+		}
+
+		public virtual void NotifyDeleted(IFreespaceManager freespaceManager)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.NotifySlotDeleted.Log(_key);
+			}
+			Operation(SlotChange.SlotChangeOperation.delete);
+			FreePreviouslyModifiedSlot(freespaceManager);
+			_newSlot = Slot.Zero;
+		}
+
+		public virtual bool RemoveId()
+		{
+			return false;
+		}
+
+		public override string ToString()
+		{
+			string str = "id: " + _key;
+			if (_newSlot != null)
+			{
+				str += " newSlot: " + _newSlot;
+			}
+			return str;
+		}
+
+		protected virtual bool FreeToSystemFreespaceSystem()
+		{
+			return false;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/SlotChangeFactory.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/SlotChangeFactory.cs
new file mode 100644
index 0000000..0183d79
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/SlotChangeFactory.cs
@@ -0,0 +1,67 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Slots
+{
+	/// <exclude></exclude>
+	public class SlotChangeFactory
+	{
+		private SlotChangeFactory()
+		{
+		}
+
+		public virtual SlotChange NewInstance(int id)
+		{
+			return new SlotChange(id);
+		}
+
+		public static readonly Db4objects.Db4o.Internal.Slots.SlotChangeFactory UserObjects
+			 = new Db4objects.Db4o.Internal.Slots.SlotChangeFactory();
+
+		private sealed class _SlotChangeFactory_20 : Db4objects.Db4o.Internal.Slots.SlotChangeFactory
+		{
+			public _SlotChangeFactory_20()
+			{
+			}
+
+			public override SlotChange NewInstance(int id)
+			{
+				return new SystemSlotChange(id);
+			}
+		}
+
+		public static readonly Db4objects.Db4o.Internal.Slots.SlotChangeFactory SystemObjects
+			 = new _SlotChangeFactory_20();
+
+		private sealed class _SlotChangeFactory_26 : Db4objects.Db4o.Internal.Slots.SlotChangeFactory
+		{
+			public _SlotChangeFactory_26()
+			{
+			}
+
+			public override SlotChange NewInstance(int id)
+			{
+				return new IdSystemSlotChange(id);
+			}
+		}
+
+		public static readonly Db4objects.Db4o.Internal.Slots.SlotChangeFactory IdSystem = 
+			new _SlotChangeFactory_26();
+
+		private sealed class _SlotChangeFactory_32 : Db4objects.Db4o.Internal.Slots.SlotChangeFactory
+		{
+			public _SlotChangeFactory_32()
+			{
+			}
+
+			public override SlotChange NewInstance(int id)
+			{
+				return new FreespaceSlotChange(id);
+			}
+		}
+
+		public static readonly Db4objects.Db4o.Internal.Slots.SlotChangeFactory FreeSpace
+			 = new _SlotChangeFactory_32();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/SystemSlotChange.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/SystemSlotChange.cs
new file mode 100644
index 0000000..858a5a9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Slots/SystemSlotChange.cs
@@ -0,0 +1,33 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Slots
+{
+	/// <exclude></exclude>
+	public class SystemSlotChange : SlotChange
+	{
+		public SystemSlotChange(int id) : base(id)
+		{
+		}
+
+		public override void AccumulateFreeSlot(TransactionalIdSystemImpl idSystem, FreespaceCommitter
+			 freespaceCommitter, bool forFreespace)
+		{
+			base.AccumulateFreeSlot(idSystem, freespaceCommitter, forFreespace);
+		}
+
+		// FIXME: If we are doing a delete, we should also free our pointer here.
+		protected override Slot ModifiedSlotInParentIdSystem(TransactionalIdSystemImpl idSystem
+			)
+		{
+			return null;
+		}
+
+		public override bool RemoveId()
+		{
+			return _newSlot == Slot.Zero;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/StatefulBuffer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/StatefulBuffer.cs
new file mode 100644
index 0000000..e34e577
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/StatefulBuffer.cs
@@ -0,0 +1,238 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Slots;
+using Sharpen;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <summary>
+	/// public for .NET conversion reasons
+	/// TODO: Split this class for individual usecases.
+	/// </summary>
+	/// <remarks>
+	/// public for .NET conversion reasons
+	/// TODO: Split this class for individual usecases. Only use the member
+	/// variables needed for the respective usecase.
+	/// </remarks>
+	/// <exclude></exclude>
+	public sealed class StatefulBuffer : ByteArrayBuffer
+	{
+		internal Db4objects.Db4o.Internal.Transaction _trans;
+
+		private int _address;
+
+		private int _addressOffset;
+
+		private int _cascadeDelete;
+
+		private int _id;
+
+		private int _length;
+
+		public StatefulBuffer(Db4objects.Db4o.Internal.Transaction trans, int initialBufferSize
+			)
+		{
+			_trans = trans;
+			_length = initialBufferSize;
+			_buffer = new byte[_length];
+		}
+
+		public StatefulBuffer(Db4objects.Db4o.Internal.Transaction trans, int address, int
+			 length) : this(trans, length)
+		{
+			_address = address;
+		}
+
+		public StatefulBuffer(Db4objects.Db4o.Internal.Transaction trans, Db4objects.Db4o.Internal.Slots.Slot
+			 slot) : this(trans, slot.Address(), slot.Length())
+		{
+		}
+
+		public StatefulBuffer(Db4objects.Db4o.Internal.Transaction trans, Pointer4 pointer
+			) : this(trans, pointer._slot)
+		{
+			_id = pointer._id;
+		}
+
+		public void DebugCheckBytes()
+		{
+		}
+
+		// Db4o.log("!!! YapBytes.debugCheckBytes not all bytes used");
+		// This is normal for writing The FreeSlotArray, becauce one
+		// slot is possibly reserved by it's own pointer.
+		public int GetAddress()
+		{
+			return _address;
+		}
+
+		public int GetID()
+		{
+			return _id;
+		}
+
+		public override int Length()
+		{
+			return _length;
+		}
+
+		public ObjectContainerBase Container()
+		{
+			return _trans.Container();
+		}
+
+		public LocalObjectContainer File()
+		{
+			return ((LocalTransaction)_trans).LocalContainer();
+		}
+
+		public Db4objects.Db4o.Internal.Transaction Transaction()
+		{
+			return _trans;
+		}
+
+		public byte[] GetWrittenBytes()
+		{
+			byte[] bytes = new byte[_offset];
+			System.Array.Copy(_buffer, 0, bytes, 0, _offset);
+			return bytes;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public void Read()
+		{
+			Container().ReadBytes(_buffer, _address, _addressOffset, _length);
+		}
+
+		public Db4objects.Db4o.Internal.StatefulBuffer ReadStatefulBuffer()
+		{
+			int length = ReadInt();
+			if (length == 0)
+			{
+				return null;
+			}
+			Db4objects.Db4o.Internal.StatefulBuffer yb = new Db4objects.Db4o.Internal.StatefulBuffer
+				(_trans, length);
+			System.Array.Copy(_buffer, _offset, yb._buffer, 0, length);
+			_offset += length;
+			return yb;
+		}
+
+		public void RemoveFirstBytes(int aLength)
+		{
+			_length -= aLength;
+			byte[] temp = new byte[_length];
+			System.Array.Copy(_buffer, aLength, temp, 0, _length);
+			_buffer = temp;
+			_offset -= aLength;
+			if (_offset < 0)
+			{
+				_offset = 0;
+			}
+		}
+
+		public void Address(int address)
+		{
+			_address = address;
+		}
+
+		public void SetID(int id)
+		{
+			_id = id;
+		}
+
+		public void SetTransaction(Db4objects.Db4o.Internal.Transaction aTrans)
+		{
+			_trans = aTrans;
+		}
+
+		public void UseSlot(int adress)
+		{
+			_address = adress;
+			_offset = 0;
+		}
+
+		// FIXME: FB remove
+		public void UseSlot(int address, int length)
+		{
+			UseSlot(new Db4objects.Db4o.Internal.Slots.Slot(address, length));
+		}
+
+		public void UseSlot(Db4objects.Db4o.Internal.Slots.Slot slot)
+		{
+			_address = slot.Address();
+			_offset = 0;
+			if (slot.Length() > _buffer.Length)
+			{
+				_buffer = new byte[slot.Length()];
+			}
+			_length = slot.Length();
+		}
+
+		// FIXME: FB remove
+		public void UseSlot(int id, int adress, int length)
+		{
+			_id = id;
+			UseSlot(adress, length);
+		}
+
+		public void Write()
+		{
+			File().WriteBytes(this, _address, _addressOffset);
+		}
+
+		public void WriteEncrypt()
+		{
+			File().WriteEncrypt(this, _address, _addressOffset);
+		}
+
+		public ByteArrayBuffer ReadPayloadWriter(int offset, int length)
+		{
+			Db4objects.Db4o.Internal.StatefulBuffer payLoad = new Db4objects.Db4o.Internal.StatefulBuffer
+				(_trans, 0, length);
+			System.Array.Copy(_buffer, offset, payLoad._buffer, 0, length);
+			TransferPayLoadAddress(payLoad, offset);
+			return payLoad;
+		}
+
+		private void TransferPayLoadAddress(Db4objects.Db4o.Internal.StatefulBuffer toWriter
+			, int offset)
+		{
+			int blockedOffset = offset / Container().BlockSize();
+			toWriter._address = _address + blockedOffset;
+			toWriter._id = toWriter._address;
+			toWriter._addressOffset = _addressOffset;
+		}
+
+		public void MoveForward(int length)
+		{
+			_addressOffset += length;
+		}
+
+		public override string ToString()
+		{
+			return "id " + _id + " adr " + _address + " len " + _length;
+		}
+
+		public Db4objects.Db4o.Internal.Slots.Slot Slot()
+		{
+			return new Db4objects.Db4o.Internal.Slots.Slot(_address, _length);
+		}
+
+		public Pointer4 Pointer()
+		{
+			return new Pointer4(_id, Slot());
+		}
+
+		public int CascadeDeletes()
+		{
+			return _cascadeDelete;
+		}
+
+		public void SetCascadeDeletes(int depth)
+		{
+			_cascadeDelete = depth;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/StoredClassImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/StoredClassImpl.cs
new file mode 100644
index 0000000..2f6dd79
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/StoredClassImpl.cs
@@ -0,0 +1,131 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class StoredClassImpl : IStoredClass
+	{
+		private readonly Transaction _transaction;
+
+		private readonly ClassMetadata _classMetadata;
+
+		public StoredClassImpl(Transaction transaction, ClassMetadata classMetadata)
+		{
+			if (classMetadata == null)
+			{
+				throw new ArgumentException();
+			}
+			_transaction = transaction;
+			_classMetadata = classMetadata;
+		}
+
+		public virtual long[] GetIDs()
+		{
+			return _classMetadata.GetIDs(_transaction);
+		}
+
+		public virtual string GetName()
+		{
+			return _classMetadata.GetName();
+		}
+
+		public virtual IStoredClass GetParentStoredClass()
+		{
+			ClassMetadata parentClassMetadata = _classMetadata.GetAncestor();
+			if (parentClassMetadata == null)
+			{
+				return null;
+			}
+			return new Db4objects.Db4o.Internal.StoredClassImpl(_transaction, parentClassMetadata
+				);
+		}
+
+		public virtual IStoredField[] GetStoredFields()
+		{
+			IStoredField[] fieldMetadata = _classMetadata.GetStoredFields();
+			IStoredField[] storedFields = new IStoredField[fieldMetadata.Length];
+			for (int i = 0; i < fieldMetadata.Length; i++)
+			{
+				storedFields[i] = new StoredFieldImpl(_transaction, (FieldMetadata)fieldMetadata[
+					i]);
+			}
+			return storedFields;
+		}
+
+		public virtual bool HasClassIndex()
+		{
+			return _classMetadata.HasClassIndex();
+		}
+
+		public virtual void Rename(string newName)
+		{
+			IInternalObjectContainer container = (IInternalObjectContainer)_transaction.ObjectContainer
+				();
+			container.SyncExec(new _IClosure4_56(this, newName));
+		}
+
+		private sealed class _IClosure4_56 : IClosure4
+		{
+			public _IClosure4_56(StoredClassImpl _enclosing, string newName)
+			{
+				this._enclosing = _enclosing;
+				this.newName = newName;
+			}
+
+			public object Run()
+			{
+				this._enclosing._classMetadata.Rename(newName);
+				return null;
+			}
+
+			private readonly StoredClassImpl _enclosing;
+
+			private readonly string newName;
+		}
+
+		public virtual IStoredField StoredField(string name, object type)
+		{
+			FieldMetadata fieldMetadata = (FieldMetadata)_classMetadata.StoredField(name, type
+				);
+			if (fieldMetadata == null)
+			{
+				return null;
+			}
+			return new StoredFieldImpl(_transaction, fieldMetadata);
+		}
+
+		public override int GetHashCode()
+		{
+			return _classMetadata.GetHashCode();
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (obj == null)
+			{
+				return false;
+			}
+			if (GetType() != obj.GetType())
+			{
+				return false;
+			}
+			return _classMetadata.Equals(((Db4objects.Db4o.Internal.StoredClassImpl)obj)._classMetadata
+				);
+		}
+
+		public override string ToString()
+		{
+			return "StoredClass(" + _classMetadata + ")";
+		}
+
+		public virtual int InstanceCount()
+		{
+			return _classMetadata.InstanceCount(_transaction);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/StoredFieldImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/StoredFieldImpl.cs
new file mode 100644
index 0000000..44da8f6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/StoredFieldImpl.cs
@@ -0,0 +1,107 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class StoredFieldImpl : IStoredField
+	{
+		private readonly Transaction _transaction;
+
+		private readonly Db4objects.Db4o.Internal.FieldMetadata _fieldMetadata;
+
+		public StoredFieldImpl(Transaction transaction, Db4objects.Db4o.Internal.FieldMetadata
+			 fieldMetadata)
+		{
+			_transaction = transaction;
+			_fieldMetadata = fieldMetadata;
+		}
+
+		public virtual void CreateIndex()
+		{
+			lock (Lock())
+			{
+				_fieldMetadata.CreateIndex();
+			}
+		}
+
+		public virtual void DropIndex()
+		{
+			lock (Lock())
+			{
+				_fieldMetadata.DropIndex();
+			}
+		}
+
+		private object Lock()
+		{
+			return _transaction.Container().Lock();
+		}
+
+		public virtual Db4objects.Db4o.Internal.FieldMetadata FieldMetadata()
+		{
+			return _fieldMetadata;
+		}
+
+		public virtual object Get(object onObject)
+		{
+			return _fieldMetadata.Get(_transaction, onObject);
+		}
+
+		public virtual string GetName()
+		{
+			return _fieldMetadata.GetName();
+		}
+
+		public virtual IReflectClass GetStoredType()
+		{
+			return _fieldMetadata.GetStoredType();
+		}
+
+		public virtual bool HasIndex()
+		{
+			return _fieldMetadata.HasIndex();
+		}
+
+		public virtual bool IsArray()
+		{
+			return _fieldMetadata.IsArray();
+		}
+
+		public virtual void Rename(string name)
+		{
+			lock (Lock())
+			{
+				_fieldMetadata.Rename(name);
+			}
+		}
+
+		public virtual void TraverseValues(IVisitor4 visitor)
+		{
+			_fieldMetadata.TraverseValues(_transaction, visitor);
+		}
+
+		public override int GetHashCode()
+		{
+			return _fieldMetadata.GetHashCode();
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (obj == null)
+			{
+				return false;
+			}
+			if (GetType() != obj.GetType())
+			{
+				return false;
+			}
+			return _fieldMetadata.Equals(((Db4objects.Db4o.Internal.StoredFieldImpl)obj)._fieldMetadata
+				);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/SystemData.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/SystemData.cs
new file mode 100644
index 0000000..7698f82
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/SystemData.cs
@@ -0,0 +1,217 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class SystemData
+	{
+		private int _classCollectionID;
+
+		private int _converterVersion;
+
+		private Slot _inMemoryFreespaceSlot;
+
+		private int _bTreeFreespaceId;
+
+		private byte _freespaceSystem;
+
+		private Db4oDatabase _identity;
+
+		private int _identityId;
+
+		private long _lastTimeStampID;
+
+		private byte _stringEncoding;
+
+		private int _uuidIndexId;
+
+		private byte _idSystemType;
+
+		private int _transactionPointer1;
+
+		private int _transactionPointer2;
+
+		private Slot _idSystemSlot;
+
+		private int _idToTimestampIndexId;
+
+		private int _timestampToIdIndexId;
+
+		public virtual Slot IdSystemSlot()
+		{
+			return _idSystemSlot;
+		}
+
+		public virtual void IdSystemSlot(Slot slot)
+		{
+			_idSystemSlot = slot;
+		}
+
+		private ITransactionalIdSystem _freespaceIdSystem;
+
+		public virtual void IdSystemType(byte idSystem)
+		{
+			_idSystemType = idSystem;
+		}
+
+		public virtual byte IdSystemType()
+		{
+			return _idSystemType;
+		}
+
+		public virtual int ClassCollectionID()
+		{
+			return _classCollectionID;
+		}
+
+		public virtual void ClassCollectionID(int id)
+		{
+			_classCollectionID = id;
+		}
+
+		public virtual int ConverterVersion()
+		{
+			return _converterVersion;
+		}
+
+		public virtual void ConverterVersion(int version)
+		{
+			_converterVersion = version;
+		}
+
+		public virtual int BTreeFreespaceId()
+		{
+			return _bTreeFreespaceId;
+		}
+
+		public virtual void BTreeFreespaceId(int id)
+		{
+			_bTreeFreespaceId = id;
+		}
+
+		public virtual Slot InMemoryFreespaceSlot()
+		{
+			return _inMemoryFreespaceSlot;
+		}
+
+		public virtual void InMemoryFreespaceSlot(Slot slot)
+		{
+			_inMemoryFreespaceSlot = slot;
+		}
+
+		public virtual byte FreespaceSystem()
+		{
+			return _freespaceSystem;
+		}
+
+		public virtual void FreespaceSystem(byte freespaceSystemtype)
+		{
+			_freespaceSystem = freespaceSystemtype;
+		}
+
+		public virtual Db4oDatabase Identity()
+		{
+			return _identity;
+		}
+
+		public virtual void Identity(Db4oDatabase identityObject)
+		{
+			_identity = identityObject;
+		}
+
+		public virtual long LastTimeStampID()
+		{
+			return _lastTimeStampID;
+		}
+
+		public virtual void LastTimeStampID(long id)
+		{
+			_lastTimeStampID = id;
+		}
+
+		public virtual byte StringEncoding()
+		{
+			return _stringEncoding;
+		}
+
+		public virtual void StringEncoding(byte encodingByte)
+		{
+			_stringEncoding = encodingByte;
+		}
+
+		public virtual int UuidIndexId()
+		{
+			return _uuidIndexId;
+		}
+
+		public virtual void UuidIndexId(int id)
+		{
+			_uuidIndexId = id;
+		}
+
+		public virtual void IdentityId(int id)
+		{
+			_identityId = id;
+		}
+
+		public virtual int IdentityId()
+		{
+			return _identityId;
+		}
+
+		public virtual void TransactionPointer1(int pointer)
+		{
+			_transactionPointer1 = pointer;
+		}
+
+		public virtual void TransactionPointer2(int pointer)
+		{
+			_transactionPointer2 = pointer;
+		}
+
+		public virtual int TransactionPointer1()
+		{
+			return _transactionPointer1;
+		}
+
+		public virtual int TransactionPointer2()
+		{
+			return _transactionPointer2;
+		}
+
+		public virtual void FreespaceIdSystem(ITransactionalIdSystem transactionalIdSystem
+			)
+		{
+			_freespaceIdSystem = transactionalIdSystem;
+		}
+
+		public virtual ITransactionalIdSystem FreespaceIdSystem()
+		{
+			return _freespaceIdSystem;
+		}
+
+		public virtual void IdToTimestampIndexId(int idToTimestampIndexId)
+		{
+			_idToTimestampIndexId = idToTimestampIndexId;
+		}
+
+		public virtual int IdToTimestampIndexId()
+		{
+			return _idToTimestampIndexId;
+		}
+
+		public virtual void TimestampToIdIndexId(int timestampToIdIndexId)
+		{
+			_timestampToIdIndexId = timestampToIdIndexId;
+		}
+
+		public virtual int TimestampToIdIndexId()
+		{
+			return _timestampToIdIndexId;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/SystemInfoFileImpl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/SystemInfoFileImpl.cs
new file mode 100644
index 0000000..f05a21f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/SystemInfoFileImpl.cs
@@ -0,0 +1,54 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Freespace;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class SystemInfoFileImpl : ISystemInfo
+	{
+		private LocalObjectContainer _file;
+
+		public SystemInfoFileImpl(LocalObjectContainer file)
+		{
+			_file = file;
+		}
+
+		public virtual int FreespaceEntryCount()
+		{
+			if (!HasFreespaceManager())
+			{
+				return 0;
+			}
+			return FreespaceManager().SlotCount();
+		}
+
+		private bool HasFreespaceManager()
+		{
+			return FreespaceManager() != null;
+		}
+
+		private IFreespaceManager FreespaceManager()
+		{
+			return _file.FreespaceManager();
+		}
+
+		public virtual long FreespaceSize()
+		{
+			if (!HasFreespaceManager())
+			{
+				return 0;
+			}
+			long blockSize = _file.BlockSize();
+			long blockedSize = FreespaceManager().TotalFreespace();
+			return blockSize * blockedSize;
+		}
+
+		public virtual long TotalSize()
+		{
+			return _file.FileLength();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Threading/IThreadPool4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Threading/IThreadPool4.cs
new file mode 100644
index 0000000..19d8a0a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Threading/IThreadPool4.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal.Threading
+{
+	public interface IThreadPool4
+	{
+		void Start(string taskName, IRunnable task);
+
+		void StartLowPriority(string taskName, IRunnable task);
+
+		event System.EventHandler<UncaughtExceptionEventArgs> UncaughtException;
+
+		/// <exception cref="System.Exception"></exception>
+		void Join(int timeoutMilliseconds);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Threading/ThreadPool4Impl.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Threading/ThreadPool4Impl.cs
new file mode 100644
index 0000000..24a5c04
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Threading/ThreadPool4Impl.cs
@@ -0,0 +1,124 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections.Generic;
+using Db4objects.Db4o.Internal.Threading;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal.Threading
+{
+	public class ThreadPool4Impl : IThreadPool4
+	{
+		private System.EventHandler<UncaughtExceptionEventArgs> _uncaughtException;
+
+		private readonly IList<Thread> _activeThreads = new List<Thread>();
+
+		/// <exception cref="System.Exception"></exception>
+		public virtual void Join(int timeoutMilliseconds)
+		{
+			foreach (Thread thread in ActiveThreads())
+			{
+				thread.Join(timeoutMilliseconds);
+			}
+		}
+
+		public virtual void StartLowPriority(string taskName, IRunnable task)
+		{
+			Thread thread = ThreadFor(taskName, task);
+			ActivateThread(thread);
+		}
+
+		public virtual void Start(string taskName, IRunnable task)
+		{
+			Thread thread = ThreadFor(taskName, task);
+			ActivateThread(thread);
+		}
+
+		private Thread ThreadFor(string threadName, IRunnable task)
+		{
+			Thread thread = new Thread(new _IRunnable_41(this, task), threadName);
+			thread.SetDaemon(true);
+			return thread;
+		}
+
+		private sealed class _IRunnable_41 : IRunnable
+		{
+			public _IRunnable_41(ThreadPool4Impl _enclosing, IRunnable task)
+			{
+				this._enclosing = _enclosing;
+				this.task = task;
+			}
+
+			public void Run()
+			{
+				try
+				{
+					task.Run();
+				}
+				catch (Exception e)
+				{
+					this._enclosing.TriggerUncaughtExceptionEvent(e);
+				}
+				finally
+				{
+					this._enclosing.Dispose(Thread.CurrentThread());
+				}
+			}
+
+			private readonly ThreadPool4Impl _enclosing;
+
+			private readonly IRunnable task;
+		}
+
+		private void ActivateThread(Thread thread)
+		{
+			AddActiveThread(thread);
+			thread.Start();
+		}
+
+		private Thread[] ActiveThreads()
+		{
+			lock (_activeThreads)
+			{
+				return Sharpen.Collections.ToArray(_activeThreads, new Thread[_activeThreads.Count
+					]);
+			}
+		}
+
+		private void AddActiveThread(Thread thread)
+		{
+			lock (_activeThreads)
+			{
+				_activeThreads.Add(thread);
+			}
+		}
+
+		protected virtual void Dispose(Thread thread)
+		{
+			lock (_activeThreads)
+			{
+				_activeThreads.Remove(thread);
+			}
+		}
+
+		protected virtual void TriggerUncaughtExceptionEvent(Exception e)
+		{
+			if (null != _uncaughtException) _uncaughtException(null, new UncaughtExceptionEventArgs
+				(e));
+		}
+
+		public virtual event System.EventHandler<UncaughtExceptionEventArgs> UncaughtException
+		{
+			add
+			{
+				_uncaughtException = (System.EventHandler<UncaughtExceptionEventArgs>)System.Delegate.Combine
+					(_uncaughtException, value);
+			}
+			remove
+			{
+				_uncaughtException = (System.EventHandler<UncaughtExceptionEventArgs>)System.Delegate.Remove
+					(_uncaughtException, value);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Threading/UncaughtExceptionEventArgs.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Threading/UncaughtExceptionEventArgs.cs
new file mode 100644
index 0000000..61b88bc
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Threading/UncaughtExceptionEventArgs.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Internal.Threading
+{
+	public class UncaughtExceptionEventArgs : EventArgs
+	{
+		private System.Exception _exception;
+
+		public UncaughtExceptionEventArgs(System.Exception e)
+		{
+			_exception = e;
+		}
+
+		public virtual System.Exception Exception
+		{
+			get
+			{
+				return _exception;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Transaction.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Transaction.cs
new file mode 100644
index 0000000..c05ce9b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Transaction.cs
@@ -0,0 +1,402 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.References;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public abstract class Transaction
+	{
+		private IContext _context;
+
+		internal Tree _delete;
+
+		protected readonly Db4objects.Db4o.Internal.Transaction _systemTransaction;
+
+		/// <summary>
+		/// This is the inside representation to operate against, the actual
+		/// file-based ObjectContainerBase or the client.
+		/// </summary>
+		/// <remarks>
+		/// This is the inside representation to operate against, the actual
+		/// file-based ObjectContainerBase or the client. For all calls
+		/// against this ObjectContainerBase the method signatures that take
+		/// a transaction have to be used.
+		/// </remarks>
+		private readonly ObjectContainerBase _container;
+
+		/// <summary>This is the outside representation to the user.</summary>
+		/// <remarks>
+		/// This is the outside representation to the user. This ObjectContainer
+		/// should use this transaction as it's main user transation, so it also
+		/// allows using the method signatures on ObjectContainer without a
+		/// transaction.
+		/// </remarks>
+		private IObjectContainer _objectContainer;
+
+		private List4 _transactionListeners;
+
+		private readonly IReferenceSystem _referenceSystem;
+
+		private readonly IDictionary _locals = new Hashtable();
+
+		public Transaction(ObjectContainerBase container, Db4objects.Db4o.Internal.Transaction
+			 systemTransaction, IReferenceSystem referenceSystem)
+		{
+			// contains DeleteInfo nodes
+			_container = container;
+			_systemTransaction = systemTransaction;
+			_referenceSystem = referenceSystem;
+		}
+
+		/// <summary>Retrieves the value of a transaction local variables.</summary>
+		/// <remarks>
+		/// Retrieves the value of a transaction local variables.
+		/// If this is the first time the variable is accessed
+		/// <see cref="TransactionLocal.InitialValueFor(Transaction)">TransactionLocal.InitialValueFor(Transaction)
+		/// 	</see>
+		/// will provide the initial value.
+		/// </remarks>
+		public virtual ByRef Get(TransactionLocal local)
+		{
+			ByRef existing = (ByRef)_locals[local];
+			if (null != existing)
+			{
+				return existing;
+			}
+			ByRef initialValue = ByRef.NewInstance(local.InitialValueFor(this));
+			_locals[local] = initialValue;
+			return initialValue;
+		}
+
+		public void CheckSynchronization()
+		{
+		}
+
+		public virtual void AddTransactionListener(ITransactionListener listener)
+		{
+			_transactionListeners = new List4(_transactionListeners, listener);
+		}
+
+		protected void ClearAll()
+		{
+			Clear();
+			_transactionListeners = null;
+			_locals.Clear();
+		}
+
+		protected abstract void Clear();
+
+		public virtual void Close(bool rollbackOnClose)
+		{
+			if (Container() != null)
+			{
+				CheckSynchronization();
+				Container().ReleaseSemaphores(this);
+				DiscardReferenceSystem();
+			}
+			if (rollbackOnClose)
+			{
+				Rollback();
+			}
+			ITransactionalIdSystem idSystem = IdSystem();
+			if (idSystem != null)
+			{
+				idSystem.Close();
+			}
+		}
+
+		protected virtual void DiscardReferenceSystem()
+		{
+			if (_referenceSystem != null)
+			{
+				Container().ReferenceSystemRegistry().RemoveReferenceSystem(_referenceSystem);
+			}
+		}
+
+		public abstract void Commit();
+
+		protected virtual void CommitTransactionListeners()
+		{
+			CheckSynchronization();
+			if (_transactionListeners != null)
+			{
+				IEnumerator i = new Iterator4Impl(_transactionListeners);
+				while (i.MoveNext())
+				{
+					((ITransactionListener)i.Current).PreCommit();
+				}
+				_transactionListeners = null;
+			}
+		}
+
+		protected virtual bool IsSystemTransaction()
+		{
+			return _systemTransaction == null;
+		}
+
+		public virtual bool Delete(ObjectReference @ref, int id, int cascade)
+		{
+			CheckSynchronization();
+			if (@ref != null)
+			{
+				if (!_container.FlagForDelete(@ref))
+				{
+					return false;
+				}
+			}
+			if (DTrace.enabled)
+			{
+				DTrace.TransDelete.Log(id);
+			}
+			DeleteInfo info = (DeleteInfo)TreeInt.Find(_delete, id);
+			if (info == null)
+			{
+				info = new DeleteInfo(id, @ref, cascade);
+				_delete = Tree.Add(_delete, info);
+				return true;
+			}
+			info._reference = @ref;
+			if (cascade > info._cascade)
+			{
+				info._cascade = cascade;
+			}
+			return true;
+		}
+
+		public virtual void DontDelete(int a_id)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.TransDontDelete.Log(a_id);
+			}
+			if (_delete == null)
+			{
+				return;
+			}
+			_delete = TreeInt.RemoveLike((TreeInt)_delete, a_id);
+		}
+
+		public abstract void ProcessDeletes();
+
+		public virtual IReferenceSystem ReferenceSystem()
+		{
+			if (_referenceSystem != null)
+			{
+				return _referenceSystem;
+			}
+			return ParentTransaction().ReferenceSystem();
+		}
+
+		public IReflector Reflector()
+		{
+			return Container().Reflector();
+		}
+
+		public abstract void Rollback();
+
+		protected virtual void RollBackTransactionListeners()
+		{
+			CheckSynchronization();
+			if (_transactionListeners != null)
+			{
+				IEnumerator i = new Iterator4Impl(_transactionListeners);
+				while (i.MoveNext())
+				{
+					((ITransactionListener)i.Current).PostRollback();
+				}
+				_transactionListeners = null;
+			}
+		}
+
+		internal virtual bool SupportsVirtualFields()
+		{
+			return true;
+		}
+
+		public virtual Db4objects.Db4o.Internal.Transaction SystemTransaction()
+		{
+			if (_systemTransaction != null)
+			{
+				return _systemTransaction;
+			}
+			return this;
+		}
+
+		public override string ToString()
+		{
+			return Container().ToString();
+		}
+
+		public abstract void WriteUpdateAdjustIndexes(int id, ClassMetadata clazz, ArrayType
+			 typeInfo);
+
+		public ObjectContainerBase Container()
+		{
+			return _container;
+		}
+
+		public virtual Db4objects.Db4o.Internal.Transaction ParentTransaction()
+		{
+			return _systemTransaction;
+		}
+
+		public virtual void RollbackReferenceSystem()
+		{
+			ReferenceSystem().Rollback();
+		}
+
+		public virtual void CommitReferenceSystem()
+		{
+			ReferenceSystem().Commit();
+		}
+
+		public virtual void AddNewReference(ObjectReference @ref)
+		{
+			ReferenceSystem().AddNewReference(@ref);
+		}
+
+		public object ObjectForIdFromCache(int id)
+		{
+			ObjectReference @ref = ReferenceForId(id);
+			if (@ref == null)
+			{
+				return null;
+			}
+			object candidate = @ref.GetObject();
+			if (candidate == null)
+			{
+				RemoveReference(@ref);
+			}
+			return candidate;
+		}
+
+		public ObjectReference ReferenceForId(int id)
+		{
+			ObjectReference @ref = ReferenceSystem().ReferenceForId(id);
+			if (@ref != null)
+			{
+				if (@ref.GetObject() == null)
+				{
+					RemoveReference(@ref);
+					return null;
+				}
+				return @ref;
+			}
+			if (ParentTransaction() != null)
+			{
+				return ParentTransaction().ReferenceForId(id);
+			}
+			return null;
+		}
+
+		public ObjectReference ReferenceForObject(object obj)
+		{
+			ObjectReference @ref = ReferenceSystem().ReferenceForObject(obj);
+			if (@ref != null)
+			{
+				return @ref;
+			}
+			if (ParentTransaction() != null)
+			{
+				return ParentTransaction().ReferenceForObject(obj);
+			}
+			return null;
+		}
+
+		public void RemoveReference(ObjectReference @ref)
+		{
+			ReferenceSystem().RemoveReference(@ref);
+			// setting the ID to minus 1 ensures that the
+			// gc mechanism does not kill the new YapObject
+			@ref.SetID(-1);
+			Platform4.KillYapRef(@ref.GetObjectReference());
+		}
+
+		public void RemoveObjectFromReferenceSystem(object obj)
+		{
+			ObjectReference @ref = ReferenceForObject(obj);
+			if (@ref != null)
+			{
+				RemoveReference(@ref);
+			}
+		}
+
+		public virtual void SetOutSideRepresentation(IObjectContainer objectContainer)
+		{
+			_objectContainer = objectContainer;
+		}
+
+		public virtual IObjectContainer ObjectContainer()
+		{
+			if (_objectContainer != null)
+			{
+				return _objectContainer;
+			}
+			return _container;
+		}
+
+		public virtual IContext Context()
+		{
+			if (_context == null)
+			{
+				_context = new _IContext_295(this);
+			}
+			return _context;
+		}
+
+		private sealed class _IContext_295 : IContext
+		{
+			public _IContext_295(Transaction _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public IObjectContainer ObjectContainer()
+			{
+				return this._enclosing.ObjectContainer();
+			}
+
+			public Db4objects.Db4o.Internal.Transaction Transaction()
+			{
+				return this._enclosing;
+			}
+
+			private readonly Transaction _enclosing;
+		}
+
+		protected virtual void TraverseDelete(IVisitor4 deleteVisitor)
+		{
+			if (_delete == null)
+			{
+				return;
+			}
+			_delete.Traverse(deleteVisitor);
+			_delete = null;
+		}
+
+		public virtual object Wrap(object value)
+		{
+			if (value is int)
+			{
+				return value;
+			}
+			return new TransactionContext(this, value);
+		}
+
+		public abstract ITransactionalIdSystem IdSystem();
+
+		public abstract long VersionForId(int id);
+
+		public abstract long GenerateTransactionTimestamp(long forcedTimeStamp);
+
+		public abstract void UseDefaultTransactionTimestamp();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TransactionContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TransactionContext.cs
new file mode 100644
index 0000000..5b323cb
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TransactionContext.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class TransactionContext
+	{
+		public readonly Transaction _transaction;
+
+		public readonly object _object;
+
+		public TransactionContext(Transaction transaction, object obj)
+		{
+			_transaction = transaction;
+			_object = obj;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TransactionLocal.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TransactionLocal.cs
new file mode 100644
index 0000000..ac681f2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TransactionLocal.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <summary>A transaction local variable.</summary>
+	/// <remarks>A transaction local variable.</remarks>
+	/// <seealso cref="Transaction.Get(TransactionLocal)">Transaction.Get(TransactionLocal)
+	/// 	</seealso>
+	public class TransactionLocal
+	{
+		public virtual object InitialValueFor(Transaction transaction)
+		{
+			return null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TransactionObjectCarrier.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TransactionObjectCarrier.cs
new file mode 100644
index 0000000..b66d0ea
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TransactionObjectCarrier.cs
@@ -0,0 +1,42 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.References;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <summary>TODO: Check if all time-consuming stuff is overridden!</summary>
+	internal class TransactionObjectCarrier : LocalTransaction
+	{
+		private readonly ITransactionalIdSystem _idSystem;
+
+		internal TransactionObjectCarrier(ObjectContainerBase container, Transaction parentTransaction
+			, ITransactionalIdSystem idSystem, IReferenceSystem referenceSystem) : base(container
+			, parentTransaction, idSystem, referenceSystem)
+		{
+			_idSystem = idSystem;
+		}
+
+		public override void Commit()
+		{
+		}
+
+		// do nothing
+		internal override bool SupportsVirtualFields()
+		{
+			return false;
+		}
+
+		public override long VersionForId(int id)
+		{
+			return 0;
+		}
+
+		public override Db4objects.Db4o.Internal.CommitTimestampSupport CommitTimestampSupport
+			()
+		{
+			return null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Transactionlog/EmbeddedTransactionLogHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Transactionlog/EmbeddedTransactionLogHandler.cs
new file mode 100644
index 0000000..0297804
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Transactionlog/EmbeddedTransactionLogHandler.cs
@@ -0,0 +1,113 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Freespace;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Internal.Transactionlog;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal.Transactionlog
+{
+	/// <exclude></exclude>
+	public class EmbeddedTransactionLogHandler : TransactionLogHandler
+	{
+		public EmbeddedTransactionLogHandler(LocalObjectContainer container) : base(container
+			)
+		{
+		}
+
+		public override void CompleteInterruptedTransaction(int transactionId1, int transactionId2
+			)
+		{
+			if (transactionId1 <= 0 || transactionId1 != transactionId2)
+			{
+				return;
+			}
+			StatefulBuffer bytes = new StatefulBuffer(_container.SystemTransaction(), transactionId1
+				, Const4.IntLength);
+			bytes.Read();
+			int length = bytes.ReadInt();
+			if (length > 0)
+			{
+				bytes = new StatefulBuffer(_container.SystemTransaction(), transactionId1, length
+					);
+				bytes.Read();
+				bytes.IncrementOffset(Const4.IntLength);
+				ReadWriteSlotChanges(bytes);
+			}
+			_container.WriteTransactionPointer(0);
+			FlushDatabaseFile();
+		}
+
+		public override Slot AllocateSlot(bool appendToFile, int slotChangeCount)
+		{
+			int transactionLogByteCount = TransactionLogSlotLength(slotChangeCount);
+			IFreespaceManager freespaceManager = _container.FreespaceManager();
+			if (!appendToFile && freespaceManager != null)
+			{
+				Slot slot = freespaceManager.AllocateTransactionLogSlot(transactionLogByteCount);
+				if (slot != null)
+				{
+					return slot;
+				}
+			}
+			return _container.AppendBytes(transactionLogByteCount);
+		}
+
+		private void FreeSlot(Slot slot)
+		{
+			if (slot == null)
+			{
+				return;
+			}
+			if (_container.FreespaceManager() == null)
+			{
+				return;
+			}
+			_container.FreespaceManager().FreeSafeSlot(slot);
+		}
+
+		public override void ApplySlotChanges(IVisitable slotChangeTree, int slotChangeCount
+			, Slot reservedSlot)
+		{
+			if (slotChangeCount > 0)
+			{
+				Slot transactionLogSlot = SlotLongEnoughForLog(slotChangeCount, reservedSlot) ? reservedSlot
+					 : AllocateSlot(true, slotChangeCount);
+				StatefulBuffer buffer = new StatefulBuffer(_container.SystemTransaction(), transactionLogSlot
+					);
+				buffer.WriteInt(transactionLogSlot.Length());
+				buffer.WriteInt(slotChangeCount);
+				AppendSlotChanges(buffer, slotChangeTree);
+				buffer.Write();
+				IRunnable commitHook = _container.CommitHook();
+				FlushDatabaseFile();
+				_container.WriteTransactionPointer(transactionLogSlot.Address());
+				FlushDatabaseFile();
+				if (WriteSlots(slotChangeTree))
+				{
+					FlushDatabaseFile();
+				}
+				_container.WriteTransactionPointer(0);
+				commitHook.Run();
+				FlushDatabaseFile();
+				if (transactionLogSlot != reservedSlot)
+				{
+					FreeSlot(transactionLogSlot);
+				}
+			}
+			FreeSlot(reservedSlot);
+		}
+
+		private bool SlotLongEnoughForLog(int slotChangeCount, Slot slot)
+		{
+			return slot != null && slot.Length() >= TransactionLogSlotLength(slotChangeCount);
+		}
+
+		public override void Close()
+		{
+		}
+		// do nothing
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Transactionlog/FileBasedTransactionLogHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Transactionlog/FileBasedTransactionLogHandler.cs
new file mode 100644
index 0000000..c824c16
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Transactionlog/FileBasedTransactionLogHandler.cs
@@ -0,0 +1,225 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Foundation.IO;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Internal.Transactionlog;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal.Transactionlog
+{
+	/// <exclude></exclude>
+	public class FileBasedTransactionLogHandler : TransactionLogHandler
+	{
+		internal const int LockInt = int.MaxValue - 1;
+
+		private IBin _lockFile;
+
+		private IBin _logFile;
+
+		private readonly string _fileName;
+
+		public FileBasedTransactionLogHandler(LocalObjectContainer container, string fileName
+			) : base(container)
+		{
+			_fileName = fileName;
+		}
+
+		public static string LogFileName(string fileName)
+		{
+			return fileName + ".log";
+		}
+
+		public static string LockFileName(string fileName)
+		{
+			return fileName + ".lock";
+		}
+
+		private IBin OpenBin(string fileName)
+		{
+			return new FileStorage().Open(new BinConfiguration(fileName, _container.Config().
+				LockFile(), 0, false));
+		}
+
+		public override void CompleteInterruptedTransaction(int transactionId1, int transactionId2
+			)
+		{
+			if (!System.IO.File.Exists(LockFileName(_fileName)))
+			{
+				return;
+			}
+			if (!LockFileSignalsInterruptedTransaction())
+			{
+				return;
+			}
+			ByteArrayBuffer buffer = new ByteArrayBuffer(Const4.IntLength);
+			OpenLogFile();
+			Read(_logFile, buffer);
+			int length = buffer.ReadInt();
+			if (length > 0)
+			{
+				buffer = new ByteArrayBuffer(length);
+				Read(_logFile, buffer);
+				buffer.IncrementOffset(Const4.IntLength);
+				ReadWriteSlotChanges(buffer);
+			}
+			DeleteLockFile();
+			CloseLogFile();
+			DeleteLogFile();
+		}
+
+		private bool LockFileSignalsInterruptedTransaction()
+		{
+			OpenLockFile();
+			ByteArrayBuffer buffer = NewLockFileBuffer();
+			Read(_lockFile, buffer);
+			for (int i = 0; i < 2; i++)
+			{
+				int checkInt = buffer.ReadInt();
+				if (checkInt != LockInt)
+				{
+					CloseLockFile();
+					return false;
+				}
+			}
+			CloseLockFile();
+			return true;
+		}
+
+		public override void Close()
+		{
+			if (!LogsOpened())
+			{
+				return;
+			}
+			CloseLockFile();
+			CloseLogFile();
+			DeleteLockFile();
+			DeleteLogFile();
+		}
+
+		private void CloseLockFile()
+		{
+			SyncAndClose(_lockFile);
+			_lockFile = null;
+		}
+
+		private void SyncAndClose(IBin bin)
+		{
+			try
+			{
+				bin.Sync();
+			}
+			finally
+			{
+				bin.Close();
+			}
+		}
+
+		private void CloseLogFile()
+		{
+			SyncAndClose(_logFile);
+			_logFile = null;
+		}
+
+		private void DeleteLockFile()
+		{
+			File4.Delete(LockFileName(_fileName));
+		}
+
+		private void DeleteLogFile()
+		{
+			File4.Delete(LogFileName(_fileName));
+		}
+
+		public override Slot AllocateSlot(bool append, int slotChangeCount)
+		{
+			// do nothing
+			return null;
+		}
+
+		public override void ApplySlotChanges(IVisitable slotChangeTree, int slotChangeCount
+			, Slot reservedSlot)
+		{
+			if (slotChangeCount < 1)
+			{
+				return;
+			}
+			IRunnable commitHook = _container.CommitHook();
+			FlushDatabaseFile();
+			EnsureLogAndLock();
+			int length = TransactionLogSlotLength(slotChangeCount);
+			ByteArrayBuffer logBuffer = new ByteArrayBuffer(length);
+			logBuffer.WriteInt(length);
+			logBuffer.WriteInt(slotChangeCount);
+			AppendSlotChanges(logBuffer, slotChangeTree);
+			Write(_logFile, logBuffer);
+			_logFile.Sync();
+			WriteToLockFile(LockInt);
+			WriteSlots(slotChangeTree);
+			commitHook.Run();
+			FlushDatabaseFile();
+			WriteToLockFile(0);
+		}
+
+		private void WriteToLockFile(int lockSignal)
+		{
+			ByteArrayBuffer lockBuffer = NewLockFileBuffer();
+			lockBuffer.WriteInt(lockSignal);
+			lockBuffer.WriteInt(lockSignal);
+			Write(_lockFile, lockBuffer);
+			_lockFile.Sync();
+		}
+
+		private ByteArrayBuffer NewLockFileBuffer()
+		{
+			return new ByteArrayBuffer(LockFileBufferLength());
+		}
+
+		private int LockFileBufferLength()
+		{
+			return Const4.LongLength * 2;
+		}
+
+		private void EnsureLogAndLock()
+		{
+			if (_container.Config().IsReadOnly())
+			{
+				return;
+			}
+			if (LogsOpened())
+			{
+				return;
+			}
+			OpenLockFile();
+			OpenLogFile();
+		}
+
+		private void OpenLogFile()
+		{
+			_logFile = OpenBin(LogFileName(_fileName));
+		}
+
+		private void OpenLockFile()
+		{
+			_lockFile = OpenBin(LockFileName(_fileName));
+		}
+
+		private bool LogsOpened()
+		{
+			return _lockFile != null;
+		}
+
+		private void Read(IBin storage, ByteArrayBuffer buffer)
+		{
+			storage.Read(0, buffer._buffer, buffer.Length());
+		}
+
+		private void Write(IBin storage, ByteArrayBuffer buffer)
+		{
+			storage.Write(0, buffer._buffer, buffer.Length());
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Transactionlog/TransactionLogHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Transactionlog/TransactionLogHandler.cs
new file mode 100644
index 0000000..6a4def1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Transactionlog/TransactionLogHandler.cs
@@ -0,0 +1,118 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal.Transactionlog
+{
+	/// <exclude></exclude>
+	public abstract class TransactionLogHandler
+	{
+		protected readonly LocalObjectContainer _container;
+
+		protected TransactionLogHandler(LocalObjectContainer container)
+		{
+			_container = container;
+		}
+
+		protected virtual LocalObjectContainer LocalContainer()
+		{
+			return _container;
+		}
+
+		protected void FlushDatabaseFile()
+		{
+			_container.SyncFiles();
+		}
+
+		protected void AppendSlotChanges(ByteArrayBuffer writer, IVisitable slotChangeVisitable
+			)
+		{
+			slotChangeVisitable.Accept(new _IVisitor4_30(writer));
+		}
+
+		private sealed class _IVisitor4_30 : IVisitor4
+		{
+			public _IVisitor4_30(ByteArrayBuffer writer)
+			{
+				this.writer = writer;
+			}
+
+			public void Visit(object obj)
+			{
+				((SlotChange)obj).Write(writer);
+			}
+
+			private readonly ByteArrayBuffer writer;
+		}
+
+		protected virtual bool WriteSlots(IVisitable slotChangeTree)
+		{
+			BooleanByRef ret = new BooleanByRef();
+			slotChangeTree.Accept(new _IVisitor4_39(this, ret));
+			return ret.value;
+		}
+
+		private sealed class _IVisitor4_39 : IVisitor4
+		{
+			public _IVisitor4_39(TransactionLogHandler _enclosing, BooleanByRef ret)
+			{
+				this._enclosing = _enclosing;
+				this.ret = ret;
+			}
+
+			public void Visit(object obj)
+			{
+				((SlotChange)obj).WritePointer(this._enclosing._container);
+				ret.value = true;
+			}
+
+			private readonly TransactionLogHandler _enclosing;
+
+			private readonly BooleanByRef ret;
+		}
+
+		protected int TransactionLogSlotLength(int slotChangeCount)
+		{
+			// slotchanges * 3 for ID, address, length
+			// 2 ints for slotlength and count
+			return ((slotChangeCount * 3) + 2) * Const4.IntLength;
+		}
+
+		public abstract Slot AllocateSlot(bool append, int slotChangeCount);
+
+		public abstract void ApplySlotChanges(IVisitable slotChangeTree, int slotChangeCount
+			, Slot reservedSlot);
+
+		public abstract void CompleteInterruptedTransaction(int transactionId1, int transactionId2
+			);
+
+		public abstract void Close();
+
+		protected virtual void ReadWriteSlotChanges(ByteArrayBuffer buffer)
+		{
+			LockedTree slotChanges = new LockedTree();
+			slotChanges.Read(buffer, new SlotChange(0));
+			if (WriteSlots(new _IVisitable_65(slotChanges)))
+			{
+				FlushDatabaseFile();
+			}
+		}
+
+		private sealed class _IVisitable_65 : IVisitable
+		{
+			public _IVisitable_65(LockedTree slotChanges)
+			{
+				this.slotChanges = slotChanges;
+			}
+
+			public void Accept(IVisitor4 visitor)
+			{
+				slotChanges.TraverseMutable(visitor);
+			}
+
+			private readonly LockedTree slotChanges;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TranslatedAspect.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TranslatedAspect.cs
new file mode 100644
index 0000000..fdd3535
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TranslatedAspect.cs
@@ -0,0 +1,199 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	public sealed class TranslatedAspect : FieldMetadata
+	{
+		private IObjectTranslator _translator;
+
+		public TranslatedAspect(ClassMetadata containingClass, string name) : this(containingClass
+			)
+		{
+			Init(name);
+		}
+
+		public TranslatedAspect(ClassMetadata containingClass, IObjectTranslator translator
+			) : this(containingClass)
+		{
+			InitializeTranslator(translator);
+		}
+
+		private TranslatedAspect(ClassMetadata containingClass) : base(containingClass)
+		{
+			SetAvailable();
+		}
+
+		public void InitializeTranslator(IObjectTranslator translator)
+		{
+			_translator = translator;
+			InitializeFieldName();
+			InitializeFieldType();
+		}
+
+		public override bool Alive()
+		{
+			return true;
+		}
+
+		private void InitializeFieldName()
+		{
+			Init(FieldNameFor(_translator));
+		}
+
+		private void InitializeFieldType()
+		{
+			ObjectContainerBase stream = ContainingClass().Container();
+			IReflectClass storedClass = stream.Reflector().ForClass(TranslatorStoredClass(_translator
+				));
+			Configure(storedClass, false);
+			IReflectClass baseType = Handlers4.BaseType(storedClass);
+			stream.ShowInternalClasses(true);
+			try
+			{
+				_fieldType = stream.ProduceClassMetadata(baseType);
+			}
+			finally
+			{
+				stream.ShowInternalClasses(false);
+			}
+			if (null == _fieldType)
+			{
+				throw new InvalidOperationException("Cannot produce class metadata for " + baseType
+					 + "!");
+			}
+		}
+
+		public static string FieldNameFor(IObjectTranslator translator)
+		{
+			return translator.GetType().FullName;
+		}
+
+		public override bool CanUseNullBitmap()
+		{
+			return false;
+		}
+
+		public override void Deactivate(IActivationContext context)
+		{
+			if (context.Depth().RequiresActivation())
+			{
+				CascadeActivation(context);
+			}
+			SetOn(context.Transaction(), context.TargetObject(), null);
+		}
+
+		public override object GetOn(Transaction a_trans, object a_OnObject)
+		{
+			try
+			{
+				return _translator.OnStore(a_trans.ObjectContainer(), a_OnObject);
+			}
+			catch (ReflectException e)
+			{
+				throw;
+			}
+			catch (Exception e)
+			{
+				throw new ReflectException(e);
+			}
+		}
+
+		public override object GetOrCreate(Transaction a_trans, object a_OnObject)
+		{
+			return GetOn(a_trans, a_OnObject);
+		}
+
+		public override void Activate(UnmarshallingContext context)
+		{
+			object obj = Read(context);
+			// Activation of members is necessary on purpose here.
+			// Classes like Hashtable need fully activated members
+			// to be able to calculate hashCode()
+			if (obj != null)
+			{
+				context.Container().Activate(context.Transaction(), obj, context.ActivationDepth(
+					));
+			}
+			SetOn(context.Transaction(), context.PersistentObject(), obj);
+		}
+
+		internal override void Refresh()
+		{
+		}
+
+		// do nothing
+		private void SetOn(Transaction trans, object a_onObject, object toSet)
+		{
+			try
+			{
+				_translator.OnActivate(trans.ObjectContainer(), a_onObject, toSet);
+			}
+			catch (Exception e)
+			{
+				throw new ReflectException(e);
+			}
+		}
+
+		protected override object IndexEntryFor(object indexEntry)
+		{
+			return indexEntry;
+		}
+
+		protected override IIndexable4 IndexHandler(ObjectContainerBase stream)
+		{
+			return (IIndexable4)GetHandler();
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (obj == this)
+			{
+				return true;
+			}
+			if (obj == null || obj.GetType() != GetType())
+			{
+				return false;
+			}
+			Db4objects.Db4o.Internal.TranslatedAspect other = (Db4objects.Db4o.Internal.TranslatedAspect
+				)obj;
+			return _translator.Equals(other._translator);
+		}
+
+		public override int GetHashCode()
+		{
+			return _translator.GetHashCode();
+		}
+
+		public override Db4objects.Db4o.Internal.Marshall.AspectType AspectType()
+		{
+			return Db4objects.Db4o.Internal.Marshall.AspectType.Translator;
+		}
+
+		public bool IsObjectConstructor()
+		{
+			return _translator is IObjectConstructor;
+		}
+
+		public object Construct(ObjectReferenceContext context)
+		{
+			ContextState contextState = context.SaveState();
+			bool fieldHasValue = ContainingClass().SeekToField(context, this);
+			try
+			{
+				return ((IObjectConstructor)_translator).OnInstantiate(context.Container(), fieldHasValue
+					 ? Read(context) : null);
+			}
+			finally
+			{
+				context.RestoreState(contextState);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TransportObjectContainer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TransportObjectContainer.cs
new file mode 100644
index 0000000..52ca85c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TransportObjectContainer.cs
@@ -0,0 +1,380 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.IO;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Convert;
+using Db4objects.Db4o.Internal.Ids;
+using Db4objects.Db4o.Internal.References;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Internal.Weakref;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Types;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <summary>
+	/// no reading
+	/// no writing
+	/// no updates
+	/// no weak references
+	/// navigation by ID only both sides need synchronised ClassCollections and
+	/// MetaInformationCaches
+	/// </summary>
+	/// <exclude></exclude>
+	public class TransportObjectContainer : LocalObjectContainer
+	{
+		private readonly ObjectContainerBase _parent;
+
+		private readonly MemoryBin _memoryBin;
+
+		public TransportObjectContainer(ObjectContainerBase parent, MemoryBin memoryFile)
+			 : base(parent.Config())
+		{
+			_memoryBin = memoryFile;
+			_parent = parent;
+			_lock = parent.Lock();
+			_showInternalClasses = parent._showInternalClasses;
+			Open();
+		}
+
+		protected override void Initialize1(IConfiguration config)
+		{
+			_handlers = _parent._handlers;
+			_classCollection = _parent.ClassCollection();
+			_config = _parent.ConfigImpl;
+			_references = WeakReferenceSupportFactory.DisabledWeakReferenceSupport();
+		}
+
+		protected override void InitializeClassMetadataRepository()
+		{
+		}
+
+		// do nothing, it's passed from the parent ObjectContainer
+		protected override void InitalizeWeakReferenceSupport()
+		{
+		}
+
+		// do nothing, no Weak references
+		internal override void InitializeEssentialClasses()
+		{
+		}
+
+		// do nothing
+		protected override void InitializePostOpenExcludingTransportObjectContainer()
+		{
+		}
+
+		// do nothing
+		internal override void InitNewClassCollection()
+		{
+		}
+
+		// do nothing
+		internal override bool CanUpdate()
+		{
+			return false;
+		}
+
+		public override ClassMetadata ClassMetadataForID(int id)
+		{
+			return _parent.ClassMetadataForID(id);
+		}
+
+		internal override void ConfigureNewFile()
+		{
+		}
+
+		// do nothing
+		public override int ConverterVersion()
+		{
+			return Converter.Version;
+		}
+
+		protected virtual void DropReferences()
+		{
+			_config = null;
+		}
+
+		protected override void HandleExceptionOnClose(Exception exc)
+		{
+		}
+
+		// do nothing here
+		public sealed override Transaction NewTransaction(Transaction parentTransaction, 
+			IReferenceSystem referenceSystem, bool isSystemTransaction)
+		{
+			if (null != parentTransaction)
+			{
+				return parentTransaction;
+			}
+			return new TransactionObjectCarrier(this, null, new TransportIdSystem(this), referenceSystem
+				);
+		}
+
+		public override long CurrentVersion()
+		{
+			return 0;
+		}
+
+		public override IDb4oType Db4oTypeStored(Transaction a_trans, object a_object)
+		{
+			return null;
+		}
+
+		public override bool DispatchsEvents()
+		{
+			return false;
+		}
+
+		~TransportObjectContainer()
+		{
+		}
+
+		// do nothing
+		public sealed override void Free(int a_address, int a_length)
+		{
+		}
+
+		// do nothing
+		public sealed override void Free(Slot slot)
+		{
+		}
+
+		// do nothing
+		public override Slot AllocateSlot(int length)
+		{
+			return AppendBytes(length);
+		}
+
+		protected override bool IsValidPointer(int id)
+		{
+			return id != 0 && base.IsValidPointer(id);
+		}
+
+		public override Db4oDatabase Identity()
+		{
+			return ((ExternalObjectContainer)_parent).Identity();
+		}
+
+		public override bool MaintainsIndices()
+		{
+			return false;
+		}
+
+		public override long GenerateTimeStampId()
+		{
+			return _parent.GenerateTimeStampId();
+		}
+
+		internal override void Message(string msg)
+		{
+		}
+
+		// do nothing
+		public override ClassMetadata ProduceClassMetadata(IReflectClass claxx)
+		{
+			return _parent.ProduceClassMetadata(claxx);
+		}
+
+		public override void RaiseCommitTimestamp(long a_minimumVersion)
+		{
+		}
+
+		// do nothing
+		internal override void ReadThis()
+		{
+		}
+
+		// do nothing
+		internal override bool StateMessages()
+		{
+			return false;
+		}
+
+		// overridden to do nothing in YapObjectCarrier
+		public override void Shutdown()
+		{
+			ProcessPendingClassUpdates();
+			WriteDirtyClassMetadata();
+			Transaction.Commit();
+		}
+
+		public sealed override void WriteHeader(bool startFileLockingThread, bool shuttingDown
+			)
+		{
+		}
+
+		public class KnownObjectIdentity
+		{
+			public int _id;
+
+			public KnownObjectIdentity(int id)
+			{
+				// do nothing
+				_id = id;
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseClosedException"></exception>
+		/// <exception cref="Db4objects.Db4o.Ext.DatabaseReadOnlyException"></exception>
+		public override int StoreInternal(Transaction trans, object obj, IUpdateDepth depth
+			, bool checkJustSet)
+		{
+			int id = _parent.GetID(null, obj);
+			if (id > 0)
+			{
+				return base.StoreInternal(trans, new TransportObjectContainer.KnownObjectIdentity
+					(id), depth, checkJustSet);
+			}
+			return base.StoreInternal(trans, obj, depth, checkJustSet);
+		}
+
+		public override object GetByID2(Transaction ta, int id)
+		{
+			object obj = base.GetByID2(ta, id);
+			if (obj is TransportObjectContainer.KnownObjectIdentity)
+			{
+				TransportObjectContainer.KnownObjectIdentity oi = (TransportObjectContainer.KnownObjectIdentity
+					)obj;
+				Activate(oi);
+				obj = _parent.GetByID(null, oi._id);
+			}
+			return obj;
+		}
+
+		public virtual void DeferredOpen()
+		{
+			Open();
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.OldFormatException"></exception>
+		protected sealed override void OpenImpl()
+		{
+			CreateIdSystem();
+			if (_memoryBin.Length() == 0)
+			{
+				ConfigureNewFile();
+				CommitTransaction();
+			}
+			else
+			{
+				ReadThis();
+			}
+		}
+
+		/// <exception cref="System.NotSupportedException"></exception>
+		public override void Backup(IStorage targetStorage, string path)
+		{
+			throw new NotSupportedException();
+		}
+
+		public override void BlockSize(int size)
+		{
+		}
+
+		// do nothing, blocksize is always 1
+		public override void CloseTransaction(Transaction transaction, bool isSystemTransaction
+			, bool rollbackOnClose)
+		{
+		}
+
+		// do nothing	
+		protected override void ShutdownDataStorage()
+		{
+			DropReferences();
+		}
+
+		public override long FileLength()
+		{
+			return _memoryBin.Length();
+		}
+
+		public override string FileName()
+		{
+			return "Memory File";
+		}
+
+		protected override bool HasShutDownHook()
+		{
+			return false;
+		}
+
+		public sealed override bool NeedsLockFileThread()
+		{
+			return false;
+		}
+
+		public override void ReadBytes(byte[] bytes, int address, int length)
+		{
+			try
+			{
+				_memoryBin.Read(address, bytes, length);
+			}
+			catch (Exception e)
+			{
+				Exceptions4.ThrowRuntimeException(13, e);
+			}
+		}
+
+		public override void ReadBytes(byte[] bytes, int address, int addressOffset, int 
+			length)
+		{
+			ReadBytes(bytes, address + addressOffset, length);
+		}
+
+		public override void SyncFiles()
+		{
+		}
+
+		public override void WriteBytes(ByteArrayBuffer buffer, int address, int addressOffset
+			)
+		{
+			_memoryBin.Write(address + addressOffset, buffer._buffer, buffer.Length());
+		}
+
+		public override void OverwriteDeletedBytes(int a_address, int a_length)
+		{
+		}
+
+		public override void Reserve(int byteCount)
+		{
+			throw new NotSupportedException();
+		}
+
+		public override byte BlockSize()
+		{
+			return 1;
+		}
+
+		protected override void FatalStorageShutdown()
+		{
+			ShutdownDataStorage();
+		}
+
+		public override IReferenceSystem CreateReferenceSystem()
+		{
+			return new HashcodeReferenceSystem();
+		}
+
+		protected override void CreateIdSystem()
+		{
+		}
+
+		// do nothing
+		public override IRunnable CommitHook()
+		{
+			return Runnable4.DoNothing;
+		}
+
+		public override void SyncFiles(IRunnable runnable)
+		{
+			runnable.Run();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TreeInt.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TreeInt.cs
new file mode 100644
index 0000000..c01f130
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TreeInt.cs
@@ -0,0 +1,247 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Query.Processor;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <summary>Base class for balanced trees.</summary>
+	/// <remarks>Base class for balanced trees.</remarks>
+	/// <exclude></exclude>
+	public class TreeInt : Tree, IReadWriteable
+	{
+		public static Db4objects.Db4o.Internal.TreeInt Add(Db4objects.Db4o.Internal.TreeInt
+			 tree, int value)
+		{
+			return (Db4objects.Db4o.Internal.TreeInt)((Db4objects.Db4o.Internal.TreeInt)Tree.
+				Add(tree, new Db4objects.Db4o.Internal.TreeInt(value)));
+		}
+
+		public static Db4objects.Db4o.Internal.TreeInt RemoveLike(Db4objects.Db4o.Internal.TreeInt
+			 tree, int value)
+		{
+			return (Db4objects.Db4o.Internal.TreeInt)Tree.RemoveLike(tree, new Db4objects.Db4o.Internal.TreeInt
+				(value));
+		}
+
+		public static Tree AddAll(Tree tree, IIntIterator4 iter)
+		{
+			if (!iter.MoveNext())
+			{
+				return tree;
+			}
+			Db4objects.Db4o.Internal.TreeInt firstAdded = new Db4objects.Db4o.Internal.TreeInt
+				(iter.CurrentInt());
+			tree = Tree.Add(tree, firstAdded);
+			while (iter.MoveNext())
+			{
+				tree = tree.Add(new Db4objects.Db4o.Internal.TreeInt(iter.CurrentInt()));
+			}
+			return tree;
+		}
+
+		public int _key;
+
+		public TreeInt(int a_key)
+		{
+			this._key = a_key;
+		}
+
+		public override int Compare(Tree a_to)
+		{
+			return _key - ((Db4objects.Db4o.Internal.TreeInt)a_to)._key;
+		}
+
+		internal virtual Tree DeepClone()
+		{
+			return new Db4objects.Db4o.Internal.TreeInt(_key);
+		}
+
+		public override bool Duplicates()
+		{
+			return false;
+		}
+
+		public static Db4objects.Db4o.Internal.TreeInt Find(Tree a_in, int a_key)
+		{
+			if (a_in == null)
+			{
+				return null;
+			}
+			return ((Db4objects.Db4o.Internal.TreeInt)a_in).Find(a_key);
+		}
+
+		public Db4objects.Db4o.Internal.TreeInt Find(int a_key)
+		{
+			int cmp = _key - a_key;
+			if (cmp < 0)
+			{
+				if (((Tree)_subsequent) != null)
+				{
+					return ((Db4objects.Db4o.Internal.TreeInt)((Tree)_subsequent)).Find(a_key);
+				}
+			}
+			else
+			{
+				if (cmp > 0)
+				{
+					if (((Tree)_preceding) != null)
+					{
+						return ((Db4objects.Db4o.Internal.TreeInt)((Tree)_preceding)).Find(a_key);
+					}
+				}
+				else
+				{
+					return this;
+				}
+			}
+			return null;
+		}
+
+		public virtual object Read(ByteArrayBuffer buffer)
+		{
+			return new Db4objects.Db4o.Internal.TreeInt(buffer.ReadInt());
+		}
+
+		public virtual void Write(ByteArrayBuffer buffer)
+		{
+			buffer.WriteInt(_key);
+		}
+
+		public static void Write(ByteArrayBuffer buffer, Db4objects.Db4o.Internal.TreeInt
+			 tree)
+		{
+			Write(buffer, tree, tree == null ? 0 : tree.Size());
+		}
+
+		public static void Write(ByteArrayBuffer buffer, Db4objects.Db4o.Internal.TreeInt
+			 tree, int size)
+		{
+			if (tree == null)
+			{
+				buffer.WriteInt(0);
+				return;
+			}
+			buffer.WriteInt(size);
+			tree.Traverse(new _IVisitor4_97(buffer));
+		}
+
+		private sealed class _IVisitor4_97 : IVisitor4
+		{
+			public _IVisitor4_97(ByteArrayBuffer buffer)
+			{
+				this.buffer = buffer;
+			}
+
+			public void Visit(object a_object)
+			{
+				((Db4objects.Db4o.Internal.TreeInt)a_object).Write(buffer);
+			}
+
+			private readonly ByteArrayBuffer buffer;
+		}
+
+		public virtual int OwnLength()
+		{
+			return Const4.IntLength;
+		}
+
+		internal virtual bool VariableLength()
+		{
+			return false;
+		}
+
+		internal virtual QCandidate ToQCandidate(QCandidates candidates)
+		{
+			QCandidate qc = new QCandidate(candidates, null, _key);
+			qc._preceding = ToQCandidate((Db4objects.Db4o.Internal.TreeInt)((Tree)_preceding)
+				, candidates);
+			qc._subsequent = ToQCandidate((Db4objects.Db4o.Internal.TreeInt)((Tree)_subsequent
+				), candidates);
+			qc._size = _size;
+			return qc;
+		}
+
+		public static QCandidate ToQCandidate(Db4objects.Db4o.Internal.TreeInt tree, QCandidates
+			 candidates)
+		{
+			if (tree == null)
+			{
+				return null;
+			}
+			return tree.ToQCandidate(candidates);
+		}
+
+		public override string ToString()
+		{
+			return string.Empty + _key;
+		}
+
+		protected override Tree ShallowCloneInternal(Tree tree)
+		{
+			Db4objects.Db4o.Internal.TreeInt treeint = (Db4objects.Db4o.Internal.TreeInt)base
+				.ShallowCloneInternal(tree);
+			treeint._key = _key;
+			return treeint;
+		}
+
+		public override object ShallowClone()
+		{
+			Db4objects.Db4o.Internal.TreeInt treeint = new Db4objects.Db4o.Internal.TreeInt(_key
+				);
+			return ShallowCloneInternal(treeint);
+		}
+
+		public static int MarshalledLength(Db4objects.Db4o.Internal.TreeInt a_tree)
+		{
+			if (a_tree == null)
+			{
+				return Const4.IntLength;
+			}
+			return a_tree.MarshalledLength();
+		}
+
+		public int MarshalledLength()
+		{
+			if (VariableLength())
+			{
+				IntByRef length = new IntByRef(Const4.IntLength);
+				Traverse(new _IVisitor4_152(length));
+				return length.value;
+			}
+			return MarshalledLength(Size());
+		}
+
+		private sealed class _IVisitor4_152 : IVisitor4
+		{
+			public _IVisitor4_152(IntByRef length)
+			{
+				this.length = length;
+			}
+
+			public void Visit(object obj)
+			{
+				length.value += ((Db4objects.Db4o.Internal.TreeInt)obj).OwnLength();
+			}
+
+			private readonly IntByRef length;
+		}
+
+		public int MarshalledLength(int size)
+		{
+			return Const4.IntLength + (size * OwnLength());
+		}
+
+		public override object Key()
+		{
+			return _key;
+		}
+
+		public override bool Equals(object obj)
+		{
+			Db4objects.Db4o.Internal.TreeInt other = (Db4objects.Db4o.Internal.TreeInt)obj;
+			return other._key == _key;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TreeIntObject.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TreeIntObject.cs
new file mode 100644
index 0000000..7e43b79
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TreeIntObject.cs
@@ -0,0 +1,101 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class TreeIntObject : TreeInt
+	{
+		public object _object;
+
+		public TreeIntObject(int a_key) : base(a_key)
+		{
+		}
+
+		public TreeIntObject(int a_key, object a_object) : base(a_key)
+		{
+			_object = a_object;
+		}
+
+		public override object ShallowClone()
+		{
+			return ShallowCloneInternal(new Db4objects.Db4o.Internal.TreeIntObject(_key));
+		}
+
+		protected override Tree ShallowCloneInternal(Tree tree)
+		{
+			Db4objects.Db4o.Internal.TreeIntObject tio = (Db4objects.Db4o.Internal.TreeIntObject
+				)base.ShallowCloneInternal(tree);
+			tio._object = _object;
+			return tio;
+		}
+
+		public virtual object GetObject()
+		{
+			return _object;
+		}
+
+		public virtual void SetObject(object obj)
+		{
+			_object = obj;
+		}
+
+		public override object Read(ByteArrayBuffer a_bytes)
+		{
+			int key = a_bytes.ReadInt();
+			object obj = null;
+			if (_object is TreeInt)
+			{
+				obj = new TreeReader(a_bytes, (IReadable)_object).Read();
+			}
+			else
+			{
+				obj = ((IReadable)_object).Read(a_bytes);
+			}
+			return new Db4objects.Db4o.Internal.TreeIntObject(key, obj);
+		}
+
+		public override void Write(ByteArrayBuffer a_writer)
+		{
+			a_writer.WriteInt(_key);
+			if (_object == null)
+			{
+				a_writer.WriteInt(0);
+			}
+			else
+			{
+				if (_object is TreeInt)
+				{
+					TreeInt.Write(a_writer, (TreeInt)_object);
+				}
+				else
+				{
+					((IReadWriteable)_object).Write(a_writer);
+				}
+			}
+		}
+
+		public override int OwnLength()
+		{
+			if (_object == null)
+			{
+				return Const4.IntLength * 2;
+			}
+			return Const4.IntLength + ((IReadable)_object).MarshalledLength();
+		}
+
+		internal override bool VariableLength()
+		{
+			return true;
+		}
+
+		public static Db4objects.Db4o.Internal.TreeIntObject Add(Db4objects.Db4o.Internal.TreeIntObject
+			 tree, int key, object value)
+		{
+			return ((Db4objects.Db4o.Internal.TreeIntObject)Tree.Add(tree, new Db4objects.Db4o.Internal.TreeIntObject
+				(key, value)));
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TreeReader.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TreeReader.cs
new file mode 100644
index 0000000..51bf384
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TreeReader.cs
@@ -0,0 +1,97 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public sealed class TreeReader
+	{
+		private readonly IReadable i_template;
+
+		private readonly ByteArrayBuffer i_bytes;
+
+		private int i_current = 0;
+
+		private int i_levels = 0;
+
+		private int i_size;
+
+		private bool i_orderOnRead;
+
+		public TreeReader(ByteArrayBuffer a_bytes, IReadable a_template) : this(a_bytes, 
+			a_template, false)
+		{
+		}
+
+		public TreeReader(ByteArrayBuffer a_bytes, IReadable a_template, bool a_orderOnRead
+			)
+		{
+			i_template = a_template;
+			i_bytes = a_bytes;
+			i_orderOnRead = a_orderOnRead;
+		}
+
+		public Tree Read()
+		{
+			return Read(i_bytes.ReadInt());
+		}
+
+		public Tree Read(int a_size)
+		{
+			i_size = a_size;
+			if (i_size > 0)
+			{
+				if (i_orderOnRead)
+				{
+					Tree tree = null;
+					for (int i = 0; i < i_size; i++)
+					{
+						tree = Tree.Add(tree, (Tree)i_template.Read(i_bytes));
+					}
+					return tree;
+				}
+				while ((1 << i_levels) < (i_size + 1))
+				{
+					i_levels++;
+				}
+				return LinkUp(null, i_levels);
+			}
+			return null;
+		}
+
+		private Tree LinkUp(Tree a_preceding, int a_level)
+		{
+			Tree node = (Tree)i_template.Read(i_bytes);
+			i_current++;
+			node._preceding = a_preceding;
+			node._subsequent = LinkDown(a_level + 1);
+			node.CalculateSize();
+			if (i_current < i_size)
+			{
+				return LinkUp(node, a_level - 1);
+			}
+			return node;
+		}
+
+		private Tree LinkDown(int a_level)
+		{
+			if (i_current < i_size)
+			{
+				i_current++;
+				if (a_level < i_levels)
+				{
+					Tree preceding = LinkDown(a_level + 1);
+					Tree node = (Tree)i_template.Read(i_bytes);
+					node._preceding = preceding;
+					node._subsequent = LinkDown(a_level + 1);
+					node.CalculateSize();
+					return node;
+				}
+				return (Tree)i_template.Read(i_bytes);
+			}
+			return null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TypeHandlerAspect.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TypeHandlerAspect.cs
new file mode 100644
index 0000000..7b59d66
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TypeHandlerAspect.cs
@@ -0,0 +1,220 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class TypeHandlerAspect : ClassAspect
+	{
+		public readonly ITypeHandler4 _typeHandler;
+
+		private readonly ClassMetadata _ownerMetadata;
+
+		public TypeHandlerAspect(ClassMetadata classMetadata, ITypeHandler4 typeHandler)
+		{
+			if (Handlers4.IsValueType(typeHandler))
+			{
+				throw new InvalidOperationException();
+			}
+			_ownerMetadata = classMetadata;
+			_typeHandler = typeHandler;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (obj == this)
+			{
+				return true;
+			}
+			if (obj == null || obj.GetType() != GetType())
+			{
+				return false;
+			}
+			Db4objects.Db4o.Internal.TypeHandlerAspect other = (Db4objects.Db4o.Internal.TypeHandlerAspect
+				)obj;
+			return _typeHandler.Equals(other._typeHandler);
+		}
+
+		public override int GetHashCode()
+		{
+			return _typeHandler.GetHashCode();
+		}
+
+		public override string GetName()
+		{
+			return _typeHandler.GetType().FullName;
+		}
+
+		public override void CascadeActivation(IActivationContext context)
+		{
+			if (!Handlers4.IsCascading(_typeHandler))
+			{
+				return;
+			}
+			Handlers4.CascadeActivation(context, _typeHandler);
+		}
+
+		public override void CollectIDs(CollectIdContext context)
+		{
+			if (!Handlers4.IsCascading(_typeHandler))
+			{
+				IncrementOffset(context);
+				return;
+			}
+			context.SlotFormat().DoWithSlotIndirection(context, new _IClosure4_58(this, context
+				));
+		}
+
+		private sealed class _IClosure4_58 : IClosure4
+		{
+			public _IClosure4_58(TypeHandlerAspect _enclosing, CollectIdContext context)
+			{
+				this._enclosing = _enclosing;
+				this.context = context;
+			}
+
+			public object Run()
+			{
+				QueryingReadContext queryingReadContext = new QueryingReadContext(context.Transaction
+					(), context.HandlerVersion(), context.Buffer(), 0, context.Collector());
+				((ICascadingTypeHandler)this._enclosing._typeHandler).CollectIDs(queryingReadContext
+					);
+				return null;
+			}
+
+			private readonly TypeHandlerAspect _enclosing;
+
+			private readonly CollectIdContext context;
+		}
+
+		public override void DefragAspect(IDefragmentContext context)
+		{
+			context.SlotFormat().DoWithSlotIndirection(context, new _IClosure4_68(this, context
+				));
+		}
+
+		private sealed class _IClosure4_68 : IClosure4
+		{
+			public _IClosure4_68(TypeHandlerAspect _enclosing, IDefragmentContext context)
+			{
+				this._enclosing = _enclosing;
+				this.context = context;
+			}
+
+			public object Run()
+			{
+				this._enclosing._typeHandler.Defragment(context);
+				return null;
+			}
+
+			private readonly TypeHandlerAspect _enclosing;
+
+			private readonly IDefragmentContext context;
+		}
+
+		public override int LinkLength()
+		{
+			return Const4.IndirectionLength;
+		}
+
+		public override void Marshall(MarshallingContext context, object obj)
+		{
+			context.CreateIndirectionWithinSlot();
+			if (IsNotHandlingConcreteType(context))
+			{
+				_typeHandler.Write(context, obj);
+				return;
+			}
+			if (_typeHandler is IInstantiatingTypeHandler)
+			{
+				IInstantiatingTypeHandler instantiating = (IInstantiatingTypeHandler)_typeHandler;
+				instantiating.WriteInstantiation(context, obj);
+				instantiating.Write(context, obj);
+			}
+			else
+			{
+				_typeHandler.Write(context, obj);
+			}
+		}
+
+		private bool IsNotHandlingConcreteType(MarshallingContext context)
+		{
+			return context.ClassMetadata() != _ownerMetadata;
+		}
+
+		public override Db4objects.Db4o.Internal.Marshall.AspectType AspectType()
+		{
+			return Db4objects.Db4o.Internal.Marshall.AspectType.Typehandler;
+		}
+
+		public override void Activate(UnmarshallingContext context)
+		{
+			if (!CheckEnabled(context))
+			{
+				return;
+			}
+			context.SlotFormat().DoWithSlotIndirection(context, new _IClosure4_110(this, context
+				));
+		}
+
+		private sealed class _IClosure4_110 : IClosure4
+		{
+			public _IClosure4_110(TypeHandlerAspect _enclosing, UnmarshallingContext context)
+			{
+				this._enclosing = _enclosing;
+				this.context = context;
+			}
+
+			public object Run()
+			{
+				Handlers4.Activate(context, this._enclosing._typeHandler);
+				return null;
+			}
+
+			private readonly TypeHandlerAspect _enclosing;
+
+			private readonly UnmarshallingContext context;
+		}
+
+		public override void Delete(DeleteContextImpl context, bool isUpdate)
+		{
+			context.SlotFormat().DoWithSlotIndirection(context, new _IClosure4_119(this, context
+				));
+		}
+
+		private sealed class _IClosure4_119 : IClosure4
+		{
+			public _IClosure4_119(TypeHandlerAspect _enclosing, DeleteContextImpl context)
+			{
+				this._enclosing = _enclosing;
+				this.context = context;
+			}
+
+			public object Run()
+			{
+				this._enclosing._typeHandler.Delete(context);
+				return null;
+			}
+
+			private readonly TypeHandlerAspect _enclosing;
+
+			private readonly DeleteContextImpl context;
+		}
+
+		public override void Deactivate(IActivationContext context)
+		{
+			CascadeActivation(context);
+		}
+
+		public override bool CanBeDisabled()
+		{
+			return true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TypeHandlerCloneContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TypeHandlerCloneContext.cs
new file mode 100644
index 0000000..d86e8f7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TypeHandlerCloneContext.cs
@@ -0,0 +1,30 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class TypeHandlerCloneContext
+	{
+		private readonly HandlerRegistry handlerRegistry;
+
+		public readonly ITypeHandler4 original;
+
+		private readonly int version;
+
+		public TypeHandlerCloneContext(HandlerRegistry handlerRegistry_, ITypeHandler4 original_
+			, int version_)
+		{
+			handlerRegistry = handlerRegistry_;
+			original = original_;
+			version = version_;
+		}
+
+		public virtual ITypeHandler4 CorrectHandlerVersion(ITypeHandler4 typeHandler)
+		{
+			return handlerRegistry.CorrectHandlerVersion(typeHandler, version);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TypeHandlerConfiguration.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TypeHandlerConfiguration.cs
new file mode 100644
index 0000000..873c5fb
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/TypeHandlerConfiguration.cs
@@ -0,0 +1,68 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public abstract class TypeHandlerConfiguration
+	{
+		protected readonly Config4Impl _config;
+
+		private ITypeHandler4 _listTypeHandler;
+
+		private ITypeHandler4 _mapTypeHandler;
+
+		public abstract void Apply();
+
+		public TypeHandlerConfiguration(Config4Impl config)
+		{
+			_config = config;
+		}
+
+		protected virtual void ListTypeHandler(ITypeHandler4 listTypeHandler)
+		{
+			_listTypeHandler = listTypeHandler;
+		}
+
+		protected virtual void MapTypeHandler(ITypeHandler4 mapTypehandler)
+		{
+			_mapTypeHandler = mapTypehandler;
+		}
+
+		protected virtual void RegisterCollection(Type clazz)
+		{
+			RegisterListTypeHandlerFor(clazz);
+		}
+
+		protected virtual void RegisterMap(Type clazz)
+		{
+			RegisterMapTypeHandlerFor(clazz);
+		}
+
+		protected virtual void IgnoreFieldsOn(Type clazz)
+		{
+			_config.RegisterTypeHandler(new SingleClassTypeHandlerPredicate(clazz), IgnoreFieldsTypeHandler
+				.Instance);
+		}
+
+		private void RegisterListTypeHandlerFor(Type clazz)
+		{
+			RegisterTypeHandlerFor(clazz, _listTypeHandler);
+		}
+
+		private void RegisterMapTypeHandlerFor(Type clazz)
+		{
+			RegisterTypeHandlerFor(clazz, _mapTypeHandler);
+		}
+
+		protected virtual void RegisterTypeHandlerFor(Type clazz, ITypeHandler4 typeHandler
+			)
+		{
+			_config.RegisterTypeHandler(new SingleClassTypeHandlerPredicate(clazz), typeHandler
+				);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/UUIDFieldMetadata.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/UUIDFieldMetadata.cs
new file mode 100644
index 0000000..801b3c8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/UUIDFieldMetadata.cs
@@ -0,0 +1,304 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Btree;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Slots;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class UUIDFieldMetadata : VirtualFieldMetadata
+	{
+		internal UUIDFieldMetadata() : base(Handlers4.LongId, new LongHandler())
+		{
+			SetName(Const4.VirtualFieldPrefix + "uuid");
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.FieldIndexException"></exception>
+		public override void AddFieldIndex(ObjectIdContextImpl context)
+		{
+			LocalTransaction transaction = (LocalTransaction)context.Transaction();
+			LocalObjectContainer localContainer = (LocalObjectContainer)transaction.Container
+				();
+			Slot oldSlot = transaction.IdSystem().CommittedSlot(context.ObjectId());
+			int savedOffset = context.Offset();
+			int db4oDatabaseIdentityID = context.ReadInt();
+			long uuid = context.ReadLong();
+			context.Seek(savedOffset);
+			bool isnew = (oldSlot.IsNull());
+			if ((uuid == 0 || db4oDatabaseIdentityID == 0) && context.ObjectId() > 0 && !isnew)
+			{
+				UUIDFieldMetadata.DatabaseIdentityIDAndUUID identityAndUUID = ReadDatabaseIdentityIDAndUUID
+					(localContainer, context.ClassMetadata(), oldSlot, false);
+				db4oDatabaseIdentityID = identityAndUUID.databaseIdentityID;
+				uuid = identityAndUUID.uuid;
+			}
+			if (db4oDatabaseIdentityID == 0)
+			{
+				db4oDatabaseIdentityID = localContainer.Identity().GetID(transaction);
+			}
+			if (uuid == 0)
+			{
+				uuid = localContainer.GenerateTimeStampId();
+			}
+			StatefulBuffer writer = (StatefulBuffer)context.Buffer();
+			writer.WriteInt(db4oDatabaseIdentityID);
+			writer.WriteLong(uuid);
+			if (isnew)
+			{
+				AddIndexEntry(writer, uuid);
+			}
+		}
+
+		internal class DatabaseIdentityIDAndUUID
+		{
+			public int databaseIdentityID;
+
+			public long uuid;
+
+			public DatabaseIdentityIDAndUUID(int databaseIdentityID_, long uuid_)
+			{
+				databaseIdentityID = databaseIdentityID_;
+				uuid = uuid_;
+			}
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		private UUIDFieldMetadata.DatabaseIdentityIDAndUUID ReadDatabaseIdentityIDAndUUID
+			(ObjectContainerBase container, ClassMetadata classMetadata, Slot oldSlot, bool 
+			checkClass)
+		{
+			if (DTrace.enabled)
+			{
+				DTrace.RereadOldUuid.LogLength(oldSlot.Address(), oldSlot.Length());
+			}
+			ByteArrayBuffer reader = container.DecryptedBufferByAddress(oldSlot.Address(), oldSlot
+				.Length());
+			if (checkClass)
+			{
+				ClassMetadata realClass = ClassMetadata.ReadClass(container, reader);
+				if (realClass != classMetadata)
+				{
+					return null;
+				}
+			}
+			if (classMetadata.SeekToField(container.Transaction, reader, this) == HandlerVersion
+				.Invalid)
+			{
+				return null;
+			}
+			return new UUIDFieldMetadata.DatabaseIdentityIDAndUUID(reader.ReadInt(), reader.ReadLong
+				());
+		}
+
+		public override void Delete(DeleteContextImpl context, bool isUpdate)
+		{
+			if (isUpdate)
+			{
+				context.Seek(context.Offset() + LinkLength());
+				return;
+			}
+			context.Seek(context.Offset() + Const4.IntLength);
+			long longPart = context.ReadLong();
+			if (longPart > 0)
+			{
+				if (context.Container().MaintainsIndices())
+				{
+					RemoveIndexEntry(context.Transaction(), context.ObjectId(), longPart);
+				}
+			}
+		}
+
+		public override bool HasIndex()
+		{
+			return true;
+		}
+
+		public override BTree GetIndex(Transaction transaction)
+		{
+			EnsureIndex(transaction);
+			return base.GetIndex(transaction);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.FieldIndexException"></exception>
+		protected override void RebuildIndexForObject(LocalObjectContainer container, ClassMetadata
+			 classMetadata, int objectId)
+		{
+			Slot slot = container.SystemTransaction().IdSystem().CurrentSlot(objectId);
+			UUIDFieldMetadata.DatabaseIdentityIDAndUUID data = ReadDatabaseIdentityIDAndUUID(
+				container, classMetadata, slot, true);
+			if (null == data)
+			{
+				return;
+			}
+			AddIndexEntry(container.LocalSystemTransaction(), objectId, data.uuid);
+		}
+
+		private void EnsureIndex(Transaction transaction)
+		{
+			if (null == transaction)
+			{
+				throw new ArgumentNullException();
+			}
+			if (null != base.GetIndex(transaction))
+			{
+				return;
+			}
+			LocalObjectContainer file = ((LocalObjectContainer)transaction.Container());
+			SystemData sd = file.SystemData();
+			if (sd == null)
+			{
+				// too early, in new file, try again later.
+				return;
+			}
+			InitIndex(transaction, sd.UuidIndexId());
+			if (sd.UuidIndexId() == 0)
+			{
+				sd.UuidIndexId(base.GetIndex(transaction).GetID());
+				file.GetFileHeader().WriteVariablePart(file);
+			}
+		}
+
+		internal override void Instantiate1(ObjectReferenceContext context)
+		{
+			int dbID = context.ReadInt();
+			Transaction trans = context.Transaction();
+			ObjectContainerBase container = trans.Container();
+			container.ShowInternalClasses(true);
+			try
+			{
+				Db4oDatabase db = (Db4oDatabase)container.GetByID2(trans, dbID);
+				if (db != null && db.i_signature == null)
+				{
+					container.Activate(trans, db, new FixedActivationDepth(2));
+				}
+				VirtualAttributes va = context.ObjectReference().VirtualAttributes();
+				va.i_database = db;
+				va.i_uuid = context.ReadLong();
+			}
+			finally
+			{
+				container.ShowInternalClasses(false);
+			}
+		}
+
+		public override int LinkLength()
+		{
+			return Const4.LongLength + Const4.IdLength;
+		}
+
+		internal override void Marshall(Transaction trans, ObjectReference @ref, IWriteBuffer
+			 buffer, bool isMigrating, bool isNew)
+		{
+			VirtualAttributes attr = @ref.VirtualAttributes();
+			ObjectContainerBase container = trans.Container();
+			bool doAddIndexEntry = isNew && container.MaintainsIndices();
+			int dbID = 0;
+			bool linkToDatabase = (attr != null && attr.i_database == null) ? true : !isMigrating;
+			if (linkToDatabase)
+			{
+				Db4oDatabase db = ((IInternalObjectContainer)container).Identity();
+				if (db == null)
+				{
+					// can happen on early classes like Metaxxx, no problem
+					attr = null;
+				}
+				else
+				{
+					if (attr.i_database == null)
+					{
+						attr.i_database = db;
+						// TODO: Should be check for ! client instead of instanceof
+						if (container is LocalObjectContainer)
+						{
+							attr.i_uuid = container.GenerateTimeStampId();
+							doAddIndexEntry = true;
+						}
+					}
+					db = attr.i_database;
+					if (db != null)
+					{
+						dbID = db.GetID(trans);
+					}
+				}
+			}
+			else
+			{
+				if (attr != null)
+				{
+					dbID = attr.i_database.GetID(trans);
+				}
+			}
+			buffer.WriteInt(dbID);
+			if (attr == null)
+			{
+				buffer.WriteLong(0);
+				return;
+			}
+			buffer.WriteLong(attr.i_uuid);
+			if (doAddIndexEntry)
+			{
+				AddIndexEntry(trans, @ref.GetID(), attr.i_uuid);
+			}
+		}
+
+		internal override void MarshallIgnore(IWriteBuffer buffer)
+		{
+			buffer.WriteInt(0);
+			buffer.WriteLong(0);
+		}
+
+		public HardObjectReference GetHardObjectReferenceBySignature(Transaction transaction
+			, long longPart, byte[] signature)
+		{
+			IBTreeRange range = Search(transaction, longPart);
+			IEnumerator keys = range.Keys();
+			while (keys.MoveNext())
+			{
+				IFieldIndexKey current = (IFieldIndexKey)keys.Current;
+				HardObjectReference hardRef = GetHardObjectReferenceById(transaction, current.ParentID
+					(), signature);
+				if (null != hardRef)
+				{
+					return hardRef;
+				}
+			}
+			return HardObjectReference.Invalid;
+		}
+
+		protected HardObjectReference GetHardObjectReferenceById(Transaction transaction, 
+			int parentId, byte[] signature)
+		{
+			HardObjectReference hardRef = transaction.Container().GetHardObjectReferenceById(
+				transaction, parentId);
+			if (hardRef._reference == null)
+			{
+				return null;
+			}
+			VirtualAttributes vad = hardRef._reference.VirtualAttributes(transaction, false);
+			if (!Arrays4.Equals(signature, vad.i_database.i_signature))
+			{
+				return null;
+			}
+			return hardRef;
+		}
+
+		public override void DefragAspect(IDefragmentContext context)
+		{
+			// database id
+			context.CopyID();
+			// uuid
+			context.IncrementOffset(Const4.LongLength);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/VersionFieldMetadata.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/VersionFieldMetadata.cs
new file mode 100644
index 0000000..f69d0c8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/VersionFieldMetadata.cs
@@ -0,0 +1,65 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class VersionFieldMetadata : VirtualFieldMetadata
+	{
+		internal VersionFieldMetadata() : base(Handlers4.LongId, new LongHandler())
+		{
+			SetName(VirtualField.Version);
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.FieldIndexException"></exception>
+		public override void AddFieldIndex(ObjectIdContextImpl context)
+		{
+			StatefulBuffer buffer = (StatefulBuffer)context.Buffer();
+			buffer.WriteLong(context.Transaction().Container().GenerateTimeStampId());
+		}
+
+		public override void Delete(DeleteContextImpl context, bool isUpdate)
+		{
+			context.Seek(context.Offset() + LinkLength());
+		}
+
+		internal override void Instantiate1(ObjectReferenceContext context)
+		{
+			context.ObjectReference().VirtualAttributes().i_version = context.ReadLong();
+		}
+
+		internal override void Marshall(Transaction trans, ObjectReference @ref, IWriteBuffer
+			 buffer, bool isMigrating, bool isNew)
+		{
+			VirtualAttributes attr = @ref.VirtualAttributes();
+			if (!isMigrating)
+			{
+				attr.i_version = trans.Container().GenerateTimeStampId();
+			}
+			if (attr == null)
+			{
+				buffer.WriteLong(0);
+			}
+			else
+			{
+				buffer.WriteLong(attr.i_version);
+			}
+		}
+
+		public override int LinkLength()
+		{
+			return Const4.LongLength;
+		}
+
+		internal override void MarshallIgnore(IWriteBuffer buffer)
+		{
+			buffer.WriteLong(0);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/VirtualAttributes.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/VirtualAttributes.cs
new file mode 100644
index 0000000..23b5746
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/VirtualAttributes.cs
@@ -0,0 +1,33 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	public class VirtualAttributes : IShallowClone
+	{
+		public Db4oDatabase i_database;
+
+		public long i_version;
+
+		public long i_uuid;
+
+		// FIXME: should be named "uuidLongPart" or even better "creationTime" 
+		public virtual object ShallowClone()
+		{
+			VirtualAttributes va = new VirtualAttributes();
+			va.i_database = i_database;
+			va.i_version = i_version;
+			va.i_uuid = i_uuid;
+			return va;
+		}
+
+		internal virtual bool SuppliesUUID()
+		{
+			return i_database != null && i_uuid != 0;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/VirtualFieldMetadata.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/VirtualFieldMetadata.cs
new file mode 100644
index 0000000..fb71d82
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/VirtualFieldMetadata.cs
@@ -0,0 +1,181 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Internal.Replication;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <summary>
+	/// TODO: refactor for symmetric inheritance - don't inherit from YapField and override,
+	/// instead extract an abstract superclass from YapField and let both YapField and this class implement
+	/// </summary>
+	/// <exclude></exclude>
+	public abstract class VirtualFieldMetadata : FieldMetadata
+	{
+		private static readonly object AnyObject = new object();
+
+		private IReflectClass _classReflector;
+
+		private IBuiltinTypeHandler _handler;
+
+		internal VirtualFieldMetadata(int fieldTypeID, IBuiltinTypeHandler handler) : base
+			(fieldTypeID)
+		{
+			_handler = handler;
+		}
+
+		public override ITypeHandler4 GetHandler()
+		{
+			return _handler;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Internal.FieldIndexException"></exception>
+		public abstract override void AddFieldIndex(ObjectIdContextImpl context);
+
+		public override bool Alive()
+		{
+			return true;
+		}
+
+		internal override bool CanAddToQuery(string fieldName)
+		{
+			return fieldName.Equals(GetName());
+		}
+
+		public override bool CanBeDisabled()
+		{
+			return false;
+		}
+
+		public override bool CanUseNullBitmap()
+		{
+			return false;
+		}
+
+		public virtual IReflectClass ClassReflector(IReflector reflector)
+		{
+			if (_classReflector == null)
+			{
+				_classReflector = ((IBuiltinTypeHandler)GetHandler()).ClassReflector();
+			}
+			return _classReflector;
+		}
+
+		internal override void CollectConstraints(Transaction a_trans, QConObject a_parent
+			, object a_template, IVisitor4 a_visitor)
+		{
+		}
+
+		// QBE constraint collection call
+		// There isn't anything useful to do here, since virtual fields
+		// are not on the actual object.
+		public override void Deactivate(IActivationContext context)
+		{
+		}
+
+		// do nothing
+		public abstract override void Delete(DeleteContextImpl context, bool isUpdate);
+
+		public override object GetOrCreate(Transaction a_trans, object a_OnObject)
+		{
+			// This is the first part of marshalling
+			// Virtual fields do it all in #marshall(), the object is never used.
+			// Returning any object here prevents triggering null handling.
+			return AnyObject;
+		}
+
+		public override bool NeedsArrayAndPrimitiveInfo()
+		{
+			return false;
+		}
+
+		public override void Activate(UnmarshallingContext context)
+		{
+			context.ObjectReference().ProduceVirtualAttributes();
+			Instantiate1(context);
+		}
+
+		internal abstract void Instantiate1(ObjectReferenceContext context);
+
+		public override void LoadFieldTypeById()
+		{
+		}
+
+		// do nothing
+		public override void Marshall(MarshallingContext context, object obj)
+		{
+			Marshall(context.Transaction(), context.Reference(), context, context.IsNew());
+		}
+
+		private void Marshall(Transaction trans, ObjectReference @ref, IWriteBuffer buffer
+			, bool isNew)
+		{
+			if (!trans.SupportsVirtualFields())
+			{
+				MarshallIgnore(buffer);
+				return;
+			}
+			ObjectContainerBase stream = trans.Container();
+			HandlerRegistry handlers = stream._handlers;
+			bool migrating = false;
+			if (stream._replicationCallState == Const4.New)
+			{
+				IDb4oReplicationReferenceProvider provider = handlers._replicationReferenceProvider;
+				object parentObject = @ref.GetObject();
+				IDb4oReplicationReference replicationReference = provider.ReferenceFor(parentObject
+					);
+				if (replicationReference != null)
+				{
+					migrating = true;
+					VirtualAttributes va = @ref.ProduceVirtualAttributes();
+					va.i_version = replicationReference.Version();
+					va.i_uuid = replicationReference.LongPart();
+					va.i_database = replicationReference.SignaturePart();
+				}
+			}
+			if (@ref.VirtualAttributes() == null)
+			{
+				@ref.ProduceVirtualAttributes();
+				migrating = false;
+			}
+			Marshall(trans, @ref, buffer, migrating, isNew);
+		}
+
+		internal abstract void Marshall(Transaction trans, ObjectReference @ref, IWriteBuffer
+			 buffer, bool migrating, bool isNew);
+
+		internal abstract void MarshallIgnore(IWriteBuffer writer);
+
+		public virtual void ReadVirtualAttribute(ObjectReferenceContext context)
+		{
+			if (!context.Transaction().SupportsVirtualFields())
+			{
+				IncrementOffset(context);
+				return;
+			}
+			Instantiate1(context);
+		}
+
+		public override bool IsVirtual()
+		{
+			return true;
+		}
+
+		protected override object IndexEntryFor(object indexEntry)
+		{
+			return indexEntry;
+		}
+
+		protected override IIndexable4 IndexHandler(ObjectContainerBase stream)
+		{
+			return (IIndexable4)GetHandler();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Weakref/EnabledWeakReferenceSupport.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Weakref/EnabledWeakReferenceSupport.cs
new file mode 100644
index 0000000..9c238e1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Weakref/EnabledWeakReferenceSupport.cs
@@ -0,0 +1,92 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Weakref;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal.Weakref
+{
+	internal class EnabledWeakReferenceSupport : IWeakReferenceSupport
+	{
+		private readonly object _queue;
+
+		private readonly ObjectContainerBase _container;
+
+		private SimpleTimer _timer;
+
+		internal EnabledWeakReferenceSupport(ObjectContainerBase container)
+		{
+			_container = container;
+			_queue = Platform4.CreateReferenceQueue();
+		}
+
+		public virtual object NewWeakReference(ObjectReference referent, object obj)
+		{
+			return Platform4.CreateActiveObjectReference(_queue, referent, obj);
+		}
+
+		public virtual void Purge()
+		{
+			Platform4.PollReferenceQueue(_container, _queue);
+		}
+
+		public virtual void Start()
+		{
+			if (_timer != null)
+			{
+				return;
+			}
+			if (!_container.ConfigImpl.WeakReferences())
+			{
+				return;
+			}
+			if (_container.ConfigImpl.WeakReferenceCollectionInterval() <= 0)
+			{
+				return;
+			}
+			_timer = new SimpleTimer(new EnabledWeakReferenceSupport.Collector(this), _container
+				.ConfigImpl.WeakReferenceCollectionInterval());
+			_container.ThreadPool().Start("db4o WeakReference collector", _timer);
+		}
+
+		public virtual void Stop()
+		{
+			if (_timer == null)
+			{
+				return;
+			}
+			_timer.Stop();
+			_timer = null;
+		}
+
+		private sealed class Collector : IRunnable
+		{
+			public void Run()
+			{
+				try
+				{
+					this._enclosing.Purge();
+				}
+				catch (DatabaseClosedException)
+				{
+				}
+				catch (Exception e)
+				{
+					// can happen, no stack trace
+					// don't bring down the thread
+					Sharpen.Runtime.PrintStackTrace(e);
+				}
+			}
+
+			internal Collector(EnabledWeakReferenceSupport _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			private readonly EnabledWeakReferenceSupport _enclosing;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Weakref/IWeakReferenceSupport.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Weakref/IWeakReferenceSupport.cs
new file mode 100644
index 0000000..f3f762d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Weakref/IWeakReferenceSupport.cs
@@ -0,0 +1,17 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Internal.Weakref
+{
+	public interface IWeakReferenceSupport
+	{
+		object NewWeakReference(ObjectReference referent, object obj);
+
+		void Purge();
+
+		void Start();
+
+		void Stop();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Weakref/WeakReferenceSupportFactory.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Weakref/WeakReferenceSupportFactory.cs
new file mode 100644
index 0000000..a6ada49
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/Weakref/WeakReferenceSupportFactory.cs
@@ -0,0 +1,53 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Weakref;
+
+namespace Db4objects.Db4o.Internal.Weakref
+{
+	public class WeakReferenceSupportFactory
+	{
+		public static IWeakReferenceSupport ForObjectContainer(ObjectContainerBase container
+			)
+		{
+			if (!Platform4.HasWeakReferences())
+			{
+				return DisabledWeakReferenceSupport();
+			}
+			if (!container.ConfigImpl.WeakReferences())
+			{
+				return DisabledWeakReferenceSupport();
+			}
+			return new EnabledWeakReferenceSupport(container);
+		}
+
+		public static IWeakReferenceSupport DisabledWeakReferenceSupport()
+		{
+			return new _IWeakReferenceSupport_22();
+		}
+
+		private sealed class _IWeakReferenceSupport_22 : IWeakReferenceSupport
+		{
+			public _IWeakReferenceSupport_22()
+			{
+			}
+
+			public void Stop()
+			{
+			}
+
+			public void Start()
+			{
+			}
+
+			public void Purge()
+			{
+			}
+
+			public object NewWeakReference(ObjectReference referent, object obj)
+			{
+				return obj;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/WriteUpdateProcessor.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/WriteUpdateProcessor.cs
new file mode 100644
index 0000000..5ebcb78
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Internal/WriteUpdateProcessor.cs
@@ -0,0 +1,103 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Internal.Slots;
+
+namespace Db4objects.Db4o.Internal
+{
+	/// <exclude></exclude>
+	internal class WriteUpdateProcessor
+	{
+		private readonly LocalTransaction _transaction;
+
+		private readonly int _id;
+
+		private readonly ClassMetadata _clazz;
+
+		private readonly ArrayType _typeInfo;
+
+		private int _cascade = 0;
+
+		public WriteUpdateProcessor(LocalTransaction transaction, int id, ClassMetadata clazz
+			, ArrayType typeInfo)
+		{
+			_transaction = transaction;
+			_id = id;
+			_clazz = clazz;
+			_typeInfo = typeInfo;
+		}
+
+		public virtual void Run()
+		{
+			_transaction.CheckSynchronization();
+			if (DTrace.enabled)
+			{
+				DTrace.WriteUpdateAdjustIndexes.Log(_id);
+			}
+			if (AlreadyHandled())
+			{
+				return;
+			}
+			// TODO: Try to get rid of getting the slot here because it 
+			//       will invoke reading a pointer from the file system.
+			//       It may be possible to figure out the readd case
+			//       by asking the IdSystem in a smarter way.
+			Slot slot = _transaction.IdSystem().CurrentSlot(_id);
+			if (HandledAsReAdd(slot))
+			{
+				return;
+			}
+			if (_clazz.CanUpdateFast())
+			{
+				return;
+			}
+			StatefulBuffer objectBytes = Container().ReadStatefulBufferBySlot(_transaction, _id
+				, slot);
+			DeleteMembers(objectBytes);
+		}
+
+		private LocalObjectContainer Container()
+		{
+			return _transaction.LocalContainer();
+		}
+
+		private void DeleteMembers(StatefulBuffer objectBytes)
+		{
+			ObjectHeader oh = new ObjectHeader(_clazz, objectBytes);
+			DeleteInfo info = (DeleteInfo)TreeInt.Find(_transaction._delete, _id);
+			if (info != null)
+			{
+				if (info._cascade > _cascade)
+				{
+					_cascade = info._cascade;
+				}
+			}
+			objectBytes.SetCascadeDeletes(_cascade);
+			DeleteContextImpl context = new DeleteContextImpl(objectBytes, oh, _clazz.ClassReflector
+				(), null);
+			_clazz.DeleteMembers(context, _typeInfo, true);
+		}
+
+		private bool HandledAsReAdd(Slot slot)
+		{
+			if (!Slot.IsNull(slot))
+			{
+				return false;
+			}
+			_clazz.AddToIndex(_transaction, _id);
+			return true;
+		}
+
+		private bool AlreadyHandled()
+		{
+			TreeInt newNode = new TreeInt(_id);
+			_transaction._writtenUpdateAdjustedIndexes = Tree.Add(_transaction._writtenUpdateAdjustedIndexes
+				, newNode);
+			return !newNode.WasAddedToTree();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IBufferContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IBufferContext.cs
new file mode 100644
index 0000000..18cca31
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IBufferContext.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Marshall
+{
+	/// <exclude></exclude>
+	public interface IBufferContext : IReadBuffer, IContext
+	{
+		IReadBuffer Buffer();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IContext.cs
new file mode 100644
index 0000000..44cc760
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IContext.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.Marshall
+{
+	/// <summary>
+	/// common functionality for
+	/// <see cref="IReadContext">IReadContext</see>
+	/// and
+	/// <see cref="IWriteContext">IWriteContext</see>
+	/// and
+	/// <see cref="Db4objects.Db4o.Internal.Delete.IDeleteContext">Db4objects.Db4o.Internal.Delete.IDeleteContext
+	/// 	</see>
+	/// 
+	/// </summary>
+	public interface IContext
+	{
+		IObjectContainer ObjectContainer();
+
+		Db4objects.Db4o.Internal.Transaction Transaction();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IReadBuffer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IReadBuffer.cs
new file mode 100644
index 0000000..94b705d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IReadBuffer.cs
@@ -0,0 +1,52 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Marshall
+{
+	/// <summary>
+	/// a buffer interface with methods to read and to position
+	/// the read pointer in the buffer.
+	/// </summary>
+	/// <remarks>
+	/// a buffer interface with methods to read and to position
+	/// the read pointer in the buffer.
+	/// </remarks>
+	public interface IReadBuffer
+	{
+		/// <summary>returns the current offset in the buffer</summary>
+		/// <returns>the offset</returns>
+		int Offset();
+
+		BitMap4 ReadBitMap(int bitCount);
+
+		/// <summary>reads a byte from the buffer.</summary>
+		/// <remarks>reads a byte from the buffer.</remarks>
+		/// <returns>the byte</returns>
+		byte ReadByte();
+
+		/// <summary>reads an array of bytes from the buffer.</summary>
+		/// <remarks>
+		/// reads an array of bytes from the buffer.
+		/// The length of the array that is passed as a parameter specifies the
+		/// number of bytes that are to be read. The passed bytes buffer parameter
+		/// is directly filled.
+		/// </remarks>
+		/// <param name="bytes">the byte array to read the bytes into.</param>
+		void ReadBytes(byte[] bytes);
+
+		/// <summary>reads an int from the buffer.</summary>
+		/// <remarks>reads an int from the buffer.</remarks>
+		/// <returns>the int</returns>
+		int ReadInt();
+
+		/// <summary>reads a long from the buffer.</summary>
+		/// <remarks>reads a long from the buffer.</remarks>
+		/// <returns>the long</returns>
+		long ReadLong();
+
+		/// <summary>positions the read pointer at the specified position</summary>
+		/// <param name="offset">the desired position in the buffer</param>
+		void Seek(int offset);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IReadContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IReadContext.cs
new file mode 100644
index 0000000..9d1bc58
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IReadContext.cs
@@ -0,0 +1,35 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Marshall
+{
+	/// <summary>
+	/// this interface is passed to internal class
+	/// <see cref="Db4objects.Db4o.Typehandlers.ITypeHandler4">Db4objects.Db4o.Typehandlers.ITypeHandler4
+	/// 	</see>
+	/// when instantiating objects.
+	/// </summary>
+	public interface IReadContext : IContext, IReadBuffer
+	{
+		/// <summary>
+		/// Interprets the current position in the context as
+		/// an ID and returns the object with this ID.
+		/// </summary>
+		/// <remarks>
+		/// Interprets the current position in the context as
+		/// an ID and returns the object with this ID.
+		/// </remarks>
+		/// <returns>the object</returns>
+		object ReadObject();
+
+		/// <summary>
+		/// reads sub-objects, in cases where the
+		/// <see cref="Db4objects.Db4o.Typehandlers.ITypeHandler4">Db4objects.Db4o.Typehandlers.ITypeHandler4
+		/// 	</see>
+		/// is known.
+		/// </summary>
+		object ReadObject(ITypeHandler4 handler);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IReferenceActivationContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IReferenceActivationContext.cs
new file mode 100644
index 0000000..6e3d560
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IReferenceActivationContext.cs
@@ -0,0 +1,13 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Marshall
+{
+	/// <summary>this interface is passed to reference type handlers.</summary>
+	/// <remarks>this interface is passed to reference type handlers.</remarks>
+	public interface IReferenceActivationContext : IReadContext
+	{
+		object PersistentObject();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IReservedBuffer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IReservedBuffer.cs
new file mode 100644
index 0000000..009778b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IReservedBuffer.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Marshall
+{
+	/// <summary>a reserved buffer within a write buffer.</summary>
+	/// <remarks>
+	/// a reserved buffer within a write buffer.
+	/// The usecase this class was written for: A null bitmap should be at the
+	/// beginning of a slot to allow lazy processing. During writing the content
+	/// of the null bitmap is not yet fully known until all members are processed.
+	/// With the Reservedbuffer the space in the slot can be occupied and writing
+	/// can happen after all members are processed.
+	/// </remarks>
+	public interface IReservedBuffer
+	{
+		/// <summary>writes a byte array to the reserved buffer.</summary>
+		/// <remarks>writes a byte array to the reserved buffer.</remarks>
+		/// <param name="bytes">the byte array.</param>
+		void WriteBytes(byte[] bytes);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IWriteBuffer.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IWriteBuffer.cs
new file mode 100644
index 0000000..59f7546
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IWriteBuffer.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Marshall
+{
+	/// <summary>a buffer interface with write methods.</summary>
+	/// <remarks>a buffer interface with write methods.</remarks>
+	public interface IWriteBuffer
+	{
+		/// <summary>writes a single byte to the buffer.</summary>
+		/// <remarks>writes a single byte to the buffer.</remarks>
+		/// <param name="b">the byte</param>
+		void WriteByte(byte b);
+
+		/// <summary>writes an array of bytes to the buffer</summary>
+		/// <param name="bytes">the byte array</param>
+		void WriteBytes(byte[] bytes);
+
+		/// <summary>writes an int to the buffer.</summary>
+		/// <remarks>writes an int to the buffer.</remarks>
+		/// <param name="i">the int</param>
+		void WriteInt(int i);
+
+		/// <summary>writes a long to the buffer</summary>
+		/// <param name="l">the long</param>
+		void WriteLong(long l);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IWriteContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IWriteContext.cs
new file mode 100644
index 0000000..c8b44e3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Marshall/IWriteContext.cs
@@ -0,0 +1,56 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Marshall
+{
+	/// <summary>
+	/// this interface is passed to internal class
+	/// <see cref="Db4objects.Db4o.Typehandlers.ITypeHandler4">Db4objects.Db4o.Typehandlers.ITypeHandler4
+	/// 	</see>
+	/// during marshaling
+	/// and provides methods to marshal objects.
+	/// </summary>
+	public interface IWriteContext : IContext, IWriteBuffer
+	{
+		/// <summary>
+		/// makes sure the object is stored and writes the ID of
+		/// the object to the context.
+		/// </summary>
+		/// <remarks>
+		/// makes sure the object is stored and writes the ID of
+		/// the object to the context.
+		/// Use this method for first class objects only (objects that
+		/// have an identity in the database). If the object can potentially
+		/// be a primitive type, do not use this method but use
+		/// a matching
+		/// <see cref="IWriteBuffer">IWriteBuffer</see>
+		/// method instead.
+		/// </remarks>
+		/// <param name="obj">the object to write.</param>
+		void WriteObject(object obj);
+
+		/// <summary>
+		/// writes sub-objects, in cases where the
+		/// <see cref="Db4objects.Db4o.Typehandlers.ITypeHandler4">Db4objects.Db4o.Typehandlers.ITypeHandler4
+		/// 	</see>
+		/// is known.
+		/// </summary>
+		/// <param name="handler">typehandler to be used to write the object.</param>
+		/// <param name="obj">the object to write</param>
+		void WriteObject(ITypeHandler4 handler, object obj);
+
+		/// <summary>
+		/// reserves a buffer with a specific length at the current
+		/// position, to be written in a later step.
+		/// </summary>
+		/// <remarks>
+		/// reserves a buffer with a specific length at the current
+		/// position, to be written in a later step.
+		/// </remarks>
+		/// <param name="length">the length to be reserved.</param>
+		/// <returns>the ReservedBuffer</returns>
+		IReservedBuffer Reserve(int length);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Messaging/IMessageContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Messaging/IMessageContext.cs
new file mode 100644
index 0000000..38ab832
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Messaging/IMessageContext.cs
@@ -0,0 +1,36 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Messaging;
+
+namespace Db4objects.Db4o.Messaging
+{
+	/// <summary>Additional message-related information.</summary>
+	/// <remarks>Additional message-related information.</remarks>
+	public interface IMessageContext
+	{
+		/// <summary>The container the message was dispatched to.</summary>
+		/// <remarks>The container the message was dispatched to.</remarks>
+		IObjectContainer Container
+		{
+			get;
+		}
+
+		/// <summary>The sender of the current message.</summary>
+		/// <remarks>
+		/// The sender of the current message.
+		/// The reference can be used to send a reply to it.
+		/// </remarks>
+		IMessageSender Sender
+		{
+			get;
+		}
+
+		/// <summary>The transaction the current message has been sent with.</summary>
+		/// <remarks>The transaction the current message has been sent with.</remarks>
+		Db4objects.Db4o.Internal.Transaction Transaction
+		{
+			get;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Messaging/IMessageRecipient.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Messaging/IMessageRecipient.cs
new file mode 100644
index 0000000..e9c5c8c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Messaging/IMessageRecipient.cs
@@ -0,0 +1,36 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Messaging;
+
+namespace Db4objects.Db4o.Messaging
+{
+	/// <summary>message recipient for client/server messaging.</summary>
+	/// <remarks>
+	/// message recipient for client/server messaging.
+	/// <br /><br />db4o allows using the client/server TCP connection to send
+	/// messages from the client to the server. Any object that can be
+	/// stored to a db4o database file may be used as a message.<br /><br />
+	/// For an example see Reference documentation: <br />
+	/// http://developer.db4o.com/Resources/view.aspx/Reference/Client-Server/Messaging<br />
+	/// http://developer.db4o.com/Resources/view.aspx/Reference/Client-Server/Remote_Code_Execution<br /><br />
+	/// <b>See Also:</b><br />
+	/// <see cref="Db4objects.Db4o.Config.IClientServerConfiguration.SetMessageRecipient(IMessageRecipient)
+	/// 	">ClientServerConfiguration.setMessageRecipient(MessageRecipient)</see>
+	/// , <br />
+	/// <see cref="IMessageSender">IMessageSender</see>
+	/// ,<br />
+	/// <see cref="Db4objects.Db4o.Config.IClientServerConfiguration.GetMessageSender()">Db4objects.Db4o.Config.IClientServerConfiguration.GetMessageSender()
+	/// 	</see>
+	/// ,<br />
+	/// <see cref="MessageRecipientWithContext">MessageRecipientWithContext</see>
+	/// <br />
+	/// </remarks>
+	public interface IMessageRecipient
+	{
+		/// <summary>the method called upon the arrival of messages.</summary>
+		/// <remarks>the method called upon the arrival of messages.</remarks>
+		/// <param name="context">contextual information for the message.</param>
+		/// <param name="message">the message received.</param>
+		void ProcessMessage(IMessageContext context, object message);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Messaging/IMessageSender.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Messaging/IMessageSender.cs
new file mode 100644
index 0000000..d5689a4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Messaging/IMessageSender.cs
@@ -0,0 +1,31 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Messaging
+{
+	/// <summary>message sender for client/server messaging.</summary>
+	/// <remarks>
+	/// message sender for client/server messaging.
+	/// <br /><br />db4o allows using the client/server TCP connection to send
+	/// messages from the client to the server. Any object that can be
+	/// stored to a db4o database file may be used as a message.<br /><br />
+	/// For an example see Reference documentation: <br />
+	/// http://developer.db4o.com/Resources/view.aspx/Reference/Client-Server/Messaging<br />
+	/// http://developer.db4o.com/Resources/view.aspx/Reference/Client-Server/Remote_Code_Execution<br /><br />
+	/// <b>See Also:</b><br />
+	/// <see cref="Db4objects.Db4o.Config.IClientServerConfiguration.GetMessageSender()">Db4objects.Db4o.Config.IClientServerConfiguration.GetMessageSender()
+	/// 	</see>
+	/// ,<br />
+	/// <see cref="IMessageRecipient">IMessageRecipient</see>
+	/// ,<br />
+	/// <see cref="Db4objects.Db4o.Config.IClientServerConfiguration.SetMessageRecipient(IMessageRecipient)
+	/// 	">Db4objects.Db4o.Config.IClientServerConfiguration.SetMessageRecipient(IMessageRecipient)
+	/// 	</see>
+	/// </remarks>
+	public interface IMessageSender
+	{
+		/// <summary>sends a message to the server.</summary>
+		/// <remarks>sends a message to the server.</remarks>
+		/// <param name="obj">the message parameter, any object may be used.</param>
+		void Send(object obj);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/IQLin.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/IQLin.cs
new file mode 100644
index 0000000..94199aa
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/IQLin.cs
@@ -0,0 +1,62 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Qlin;
+
+namespace Db4objects.Db4o.Qlin
+{
+	/// <summary>a node in a QLin ("Coolin") query.</summary>
+	/// <remarks>
+	/// a node in a QLin ("Coolin") query.
+	/// QLin is a new experimental query interface.
+	/// We would really like to have LINQ for Java instead.
+	/// </remarks>
+	/// <since>8.0</since>
+	public interface IQLin
+	{
+		/// <summary>adds a where node to this QLin query.</summary>
+		/// <remarks>adds a where node to this QLin query.</remarks>
+		/// <param name="expression">can be any of the following:</param>
+		IQLin Where(object expression);
+
+		/// <summary>
+		/// executes the QLin query and returns the result
+		/// as an
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// .
+		/// Note that ObjectSet extends List and Iterable
+		/// on the platforms that support these interfaces.
+		/// You may want to use these interfaces instead of
+		/// working directly against an ObjectSet.
+		/// </summary>
+		IObjectSet Select();
+
+		// FIXME: The return value should not be as closely bound to db4o.
+		// Collection is mutable, it's not nice.
+		// Discuss !!!
+		IQLin Equal(object obj);
+
+		IQLin StartsWith(string @string);
+
+		IQLin Limit(int size);
+
+		IQLin Smaller(object obj);
+
+		IQLin Greater(object obj);
+
+		/// <summary>orders the query by the expression.</summary>
+		/// <remarks>
+		/// orders the query by the expression.
+		/// Use the
+		/// <see cref="QLinSupport.Ascending()">QLinSupport.Ascending()</see>
+		/// and
+		/// <see cref="QLinSupport.Descending()">QLinSupport.Descending()</see>
+		/// helper methods to set the direction.
+		/// </remarks>
+		IQLin OrderBy(object expression, QLinOrderByDirection direction);
+
+		object SingleOrDefault(object defaultValue);
+
+		object Single();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/IQLinable.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/IQLinable.cs
new file mode 100644
index 0000000..8056f3e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/IQLinable.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Qlin;
+
+namespace Db4objects.Db4o.Qlin
+{
+	/// <summary>support for the new experimental QLin ("Coolin") query interface.</summary>
+	/// <remarks>
+	/// support for the new experimental QLin ("Coolin") query interface.
+	/// We would really like to have LINQ for Java instead.
+	/// </remarks>
+	/// <since>8.0</since>
+	public interface IQLinable
+	{
+		/// <summary>
+		/// starts a
+		/// <see cref="IQLin">IQLin</see>
+		/// query against a class.
+		/// </summary>
+		IQLin From(Type clazz);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/Prototypes.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/Prototypes.cs
new file mode 100644
index 0000000..0ee43f1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/Prototypes.cs
@@ -0,0 +1,518 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Qlin;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Core;
+using Db4objects.Db4o.Reflect.Generic;
+
+namespace Db4objects.Db4o.Qlin
+{
+	/// <summary>creates prototype objects for classes.</summary>
+	/// <remarks>
+	/// creates prototype objects for classes. Each field on prototype objects is set
+	/// to a newly created object or primitive that can be identified either by it's
+	/// identity or by an int ID that is generated by the system. Creation of fields
+	/// is recursed to the depth specified in the constructor.<br />
+	/// <br />
+	/// Allows analyzing expressions called on prototype objects to find the
+	/// underlying field that delivers the return value of the expression. Passed
+	/// expressions should not have side effects on objects, otherwise the
+	/// "prototype world" will no longer work.<br />
+	/// <br />
+	/// We plan to supply an ImmutableFieldClassLoader to instrument the code to
+	/// throw on every modification. This ClassLoader could also supply information
+	/// about all the method calls involved.<br />
+	/// <br />
+	/// For now our approach only works if expressions are directly backed by a
+	/// single field.<br />
+	/// <br />
+	/// We were inspired for this approach when we saw that Thomas Mueller managed to
+	/// map expressions to fields for his JaQu query interface, Kudos!
+	/// http://www.h2database.com/html/jaqu.html<br />
+	/// <br />
+	/// We took the idea a bit further and made it work for all primitives except for
+	/// boolean and we plan to also get deeper expressions, collections and
+	/// interfaces working nicely.
+	/// </remarks>
+	public class Prototypes
+	{
+		private readonly IReflector _reflector;
+
+		private readonly Hashtable4 _prototypes = new Hashtable4();
+
+		private readonly bool _ignoreTransient;
+
+		private readonly int _recursionDepth;
+
+		public Prototypes(IReflector reflector, int recursionDepth, bool ignoreTransient)
+		{
+			_reflector = reflector;
+			_recursionDepth = recursionDepth;
+			_ignoreTransient = ignoreTransient;
+		}
+
+		public Prototypes() : this(DefaultReflector(), 5, false)
+		{
+		}
+
+		/// <summary>returns a prototype object for a specific class.</summary>
+		/// <remarks>returns a prototype object for a specific class.</remarks>
+		public virtual object PrototypeForClass(Type clazz)
+		{
+			if (clazz == null)
+			{
+				throw new PrototypesException("Class can not be null");
+			}
+			IReflectClass claxx = _reflector.ForClass(clazz);
+			if (claxx == null)
+			{
+				throw new PrototypesException("Not found in the reflector: " + clazz);
+			}
+			string className = claxx.GetName();
+			Prototypes.Prototype prototype = (Prototypes.Prototype)_prototypes.Get(className);
+			if (prototype != null)
+			{
+				return prototype.Object();
+			}
+			prototype = new Prototypes.Prototype(this, claxx);
+			_prototypes.Put(className, prototype);
+			return prototype.Object();
+		}
+
+		/// <summary>
+		/// analyzes the passed expression and tries to find the path to the
+		/// backing field that is accessed.
+		/// </summary>
+		/// <remarks>
+		/// analyzes the passed expression and tries to find the path to the
+		/// backing field that is accessed.
+		/// </remarks>
+		public virtual IEnumerator BackingFieldPath(Type clazz, object expression)
+		{
+			return BackingFieldPath(_reflector.ForClass(clazz), expression);
+		}
+
+		/// <summary>
+		/// analyzes the passed expression and tries to find the path to the
+		/// backing field that is accessed.
+		/// </summary>
+		/// <remarks>
+		/// analyzes the passed expression and tries to find the path to the
+		/// backing field that is accessed.
+		/// </remarks>
+		public virtual IEnumerator BackingFieldPath(IReflectClass claxx, object expression
+			)
+		{
+			return BackingFieldPath(claxx.GetName(), expression);
+		}
+
+		/// <summary>
+		/// analyzes the passed expression and tries to find the path to the
+		/// backing field that is accessed.
+		/// </summary>
+		/// <remarks>
+		/// analyzes the passed expression and tries to find the path to the
+		/// backing field that is accessed.
+		/// </remarks>
+		public virtual IEnumerator BackingFieldPath(string className, object expression)
+		{
+			Prototypes.Prototype prototype = (Prototypes.Prototype)_prototypes.Get(className);
+			if (prototype == null)
+			{
+				return null;
+			}
+			return prototype.BackingFieldPath(_reflector, expression);
+		}
+
+		private class Prototype
+		{
+			private readonly IdentityHashtable4 _fieldsByIdentity = new IdentityHashtable4();
+
+			private readonly Hashtable4 _fieldsByIntId = new Hashtable4();
+
+			private readonly object _object;
+
+			private int intIdGenerator;
+
+			public Prototype(Prototypes _enclosing, IReflectClass claxx)
+			{
+				this._enclosing = _enclosing;
+				this._object = (object)claxx.NewInstance();
+				if (this._object == null)
+				{
+					throw new PrototypesException("Prototype could not be created for class " + claxx
+						.GetName());
+				}
+				this.Analyze(this._object, claxx, this._enclosing._recursionDepth, null);
+			}
+
+			private void Analyze(object @object, IReflectClass claxx, int depth, List4 parentPath
+				)
+			{
+				if (depth < 0)
+				{
+					return;
+				}
+				ReflectorUtils.ForEachField(claxx, new _IProcedure4_130(this, parentPath, claxx, 
+					@object, depth));
+			}
+
+			private sealed class _IProcedure4_130 : IProcedure4
+			{
+				public _IProcedure4_130(Prototype _enclosing, List4 parentPath, IReflectClass claxx
+					, object @object, int depth)
+				{
+					this._enclosing = _enclosing;
+					this.parentPath = parentPath;
+					this.claxx = claxx;
+					this. at object = @object;
+					this.depth = depth;
+				}
+
+				public void Apply(object field)
+				{
+					if (((IReflectField)field).IsStatic())
+					{
+						return;
+					}
+					if (this._enclosing._enclosing._ignoreTransient && ((IReflectField)field).IsTransient
+						())
+					{
+						return;
+					}
+					IReflectClass fieldType = ((IReflectField)field).GetFieldType();
+					List4 path = new List4(parentPath, ((IReflectField)field));
+					Prototypes.IntegerConverter converter = Prototypes.IntegerConverterforClassName(claxx
+						.Reflector(), fieldType.GetName());
+					if (converter != null)
+					{
+						int id = ++this._enclosing.intIdGenerator;
+						object integerRepresentation = converter.FromInteger(id);
+						if (!Prototypes.TrySetField(((IReflectField)field), @object, integerRepresentation
+							))
+						{
+							return;
+						}
+						this._enclosing._fieldsByIntId.Put(id, new Pair(integerRepresentation, path));
+						return;
+					}
+					if (!fieldType.IsPrimitive())
+					{
+						object identityInstance = fieldType.NewInstance();
+						if (identityInstance == null)
+						{
+							return;
+						}
+						if (!Prototypes.TrySetField(((IReflectField)field), @object, identityInstance))
+						{
+							return;
+						}
+						this._enclosing._fieldsByIdentity.Put(identityInstance, path);
+						this._enclosing.Analyze(identityInstance, claxx, depth - 1, path);
+					}
+				}
+
+				private readonly Prototype _enclosing;
+
+				private readonly List4 parentPath;
+
+				private readonly IReflectClass claxx;
+
+				private readonly object @object;
+
+				private readonly int depth;
+			}
+
+			public virtual object Object()
+			{
+				return this._object;
+			}
+
+			public virtual IEnumerator BackingFieldPath(IReflector reflector, object expression
+				)
+			{
+				if (expression == null)
+				{
+					return null;
+				}
+				IReflectClass claxx = reflector.ForObject(expression);
+				if (claxx == null)
+				{
+					return null;
+				}
+				Prototypes.IntegerConverter converter = Prototypes.IntegerConverterforClassName(reflector
+					, claxx.GetName());
+				if (converter != null)
+				{
+					Pair entry = (Pair)this._fieldsByIntId.Get(converter.ToInteger(expression));
+					if (entry == null)
+					{
+						return null;
+					}
+					if (entry.first.Equals(expression))
+					{
+						return this.AsIterator((List4)entry.second);
+					}
+					return null;
+				}
+				if (claxx.IsPrimitive())
+				{
+					return null;
+				}
+				return this.AsIterator((List4)this._fieldsByIdentity.Get(expression));
+			}
+
+			private IEnumerator AsIterator(List4 lastElement)
+			{
+				return Iterators.Revert(Iterators.Map(Iterators.Iterate(lastElement), new _IFunction4_198
+					()));
+			}
+
+			private sealed class _IFunction4_198 : IFunction4
+			{
+				public _IFunction4_198()
+				{
+				}
+
+				public object Apply(object field)
+				{
+					return ((IReflectField)field).GetName();
+				}
+			}
+
+			private readonly Prototypes _enclosing;
+		}
+
+		private static Prototypes.IntegerConverter IntegerConverterforClassName(IReflector
+			 reflector, string className)
+		{
+			if (_integerConverters == null)
+			{
+				_integerConverters = new Hashtable4();
+				Prototypes.IntegerConverter[] converters = new Prototypes.IntegerConverter[] { new 
+					_IntegerConverter_211(), new _IntegerConverter_215(), new _IntegerConverter_219(
+					), new _IntegerConverter_223(), new _IntegerConverter_227(), new _IntegerConverter_231
+					(), new _IntegerConverter_235(), new _IntegerConverter_239() };
+				for (int converterIndex = 0; converterIndex < converters.Length; ++converterIndex)
+				{
+					Prototypes.IntegerConverter converter = converters[converterIndex];
+					_integerConverters.Put(converter.PrimitiveName(), converter);
+					if (!converter.PrimitiveName().Equals(converter.WrapperName(reflector)))
+					{
+						_integerConverters.Put(converter.WrapperName(reflector), converter);
+					}
+				}
+			}
+			return (Prototypes.IntegerConverter)_integerConverters.Get(className);
+		}
+
+		private sealed class _IntegerConverter_211 : Prototypes.IntegerConverter
+		{
+			public _IntegerConverter_211()
+			{
+			}
+
+			public override string PrimitiveName()
+			{
+				return typeof(int).FullName;
+			}
+
+			public override object FromInteger(int i)
+			{
+				return i;
+			}
+		}
+
+		private sealed class _IntegerConverter_215 : Prototypes.IntegerConverter
+		{
+			public _IntegerConverter_215()
+			{
+			}
+
+			public override string PrimitiveName()
+			{
+				return typeof(long).FullName;
+			}
+
+			public override object FromInteger(int i)
+			{
+				return System.Convert.ToInt64(i);
+			}
+		}
+
+		private sealed class _IntegerConverter_219 : Prototypes.IntegerConverter
+		{
+			public _IntegerConverter_219()
+			{
+			}
+
+			public override string PrimitiveName()
+			{
+				return typeof(double).FullName;
+			}
+
+			public override object FromInteger(int i)
+			{
+				return System.Convert.ToDouble(i);
+			}
+		}
+
+		private sealed class _IntegerConverter_223 : Prototypes.IntegerConverter
+		{
+			public _IntegerConverter_223()
+			{
+			}
+
+			public override string PrimitiveName()
+			{
+				return typeof(float).FullName;
+			}
+
+			public override object FromInteger(int i)
+			{
+				return System.Convert.ToSingle(i);
+			}
+		}
+
+		private sealed class _IntegerConverter_227 : Prototypes.IntegerConverter
+		{
+			public _IntegerConverter_227()
+			{
+			}
+
+			public override string PrimitiveName()
+			{
+				return typeof(byte).FullName;
+			}
+
+			public override object FromInteger(int i)
+			{
+				return (byte)i;
+			}
+		}
+
+		private sealed class _IntegerConverter_231 : Prototypes.IntegerConverter
+		{
+			public _IntegerConverter_231()
+			{
+			}
+
+			public override string PrimitiveName()
+			{
+				return typeof(char).FullName;
+			}
+
+			public override object FromInteger(int i)
+			{
+				return (char)i;
+			}
+		}
+
+		private sealed class _IntegerConverter_235 : Prototypes.IntegerConverter
+		{
+			public _IntegerConverter_235()
+			{
+			}
+
+			public override string PrimitiveName()
+			{
+				return typeof(short).FullName;
+			}
+
+			public override object FromInteger(int i)
+			{
+				return (short)i;
+			}
+		}
+
+		private sealed class _IntegerConverter_239 : Prototypes.IntegerConverter
+		{
+			public _IntegerConverter_239()
+			{
+			}
+
+			public override string PrimitiveName()
+			{
+				return typeof(string).FullName;
+			}
+
+			public override object FromInteger(int i)
+			{
+				return Prototypes.StringIdentifier + i;
+			}
+
+			public override int ToInteger(object obj)
+			{
+				if (!(obj is string))
+				{
+					return -1;
+				}
+				string str = (string)obj;
+				if (str.Length < Prototypes.StringIdentifier.Length)
+				{
+					return -1;
+				}
+				if (str.IndexOf(Prototypes.StringIdentifier) != 0)
+				{
+					return -1;
+				}
+				return int.Parse(Sharpen.Runtime.Substring(str, Prototypes.StringIdentifier.Length
+					));
+			}
+		}
+
+		private static Hashtable4 _integerConverters;
+
+		private abstract class IntegerConverter
+		{
+			public virtual string WrapperName(IReflector reflector)
+			{
+				return reflector.ForObject(FromInteger(1)).GetName();
+			}
+
+			public abstract string PrimitiveName();
+
+			public abstract object FromInteger(int i);
+
+			public virtual int ToInteger(object obj)
+			{
+				return int.Parse(((object)obj).ToString());
+			}
+		}
+
+		private static readonly string StringIdentifier = "QLinIdentity";
+
+		// Strings get prepended the following, so we can also use strings 
+		// without restrictions in queries.
+		public virtual IReflector Reflector()
+		{
+			return _reflector;
+		}
+
+		// We could always use this, but we want to make users of this class
+		// aware that they have control over the reflector and that it is
+		// important.
+		public static IReflector DefaultReflector()
+		{
+			return new GenericReflector(Platform4.ReflectorForType(typeof(Prototypes)));
+		}
+
+		private static bool TrySetField(IReflectField field, object onObject, object value
+			)
+		{
+			try
+			{
+				field.Set(onObject, value);
+			}
+			catch
+			{
+				return false;
+			}
+			return true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/PrototypesException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/PrototypesException.cs
new file mode 100644
index 0000000..cbec816
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/PrototypesException.cs
@@ -0,0 +1,16 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Qlin
+{
+	/// <summary>exception for the the Prototypes world.</summary>
+	/// <remarks>exception for the the Prototypes world.</remarks>
+	[System.Serializable]
+	public class PrototypesException : Exception
+	{
+		public PrototypesException(string message) : base(message)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/QLinException.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/QLinException.cs
new file mode 100644
index 0000000..77a2156
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/QLinException.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Qlin
+{
+	/// <summary>
+	/// exceptions to signal improper use of the
+	/// <see cref="IQLin">IQLin</see>
+	/// query interface.
+	/// </summary>
+	[System.Serializable]
+	public class QLinException : Db4oException
+	{
+		public QLinException(string message) : base(message)
+		{
+		}
+
+		public QLinException(Exception cause) : base(cause)
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/QLinOrderByDirection.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/QLinOrderByDirection.cs
new file mode 100644
index 0000000..d99a11b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/QLinOrderByDirection.cs
@@ -0,0 +1,53 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Qlin
+{
+	/// <summary>
+	/// Internal implementation class, access should not be necessary,
+	/// except for implementors.
+	/// </summary>
+	/// <remarks>
+	/// Internal implementation class, access should not be necessary,
+	/// except for implementors.
+	/// Use the static methods in
+	/// <see cref="QLinSupport">QLinSupport</see>
+	/// 
+	/// <see cref="QLinSupport.Ascending()">QLinSupport.Ascending()</see>
+	/// and
+	/// <see cref="QLinSupport.Descending()">QLinSupport.Descending()</see>
+	/// </remarks>
+	/// <exclude></exclude>
+	public class QLinOrderByDirection
+	{
+		private readonly string _direction;
+
+		private readonly bool _ascending;
+
+		private QLinOrderByDirection(string direction, bool ascending)
+		{
+			_direction = direction;
+			_ascending = ascending;
+		}
+
+		internal static readonly Db4objects.Db4o.Qlin.QLinOrderByDirection Ascending = new 
+			Db4objects.Db4o.Qlin.QLinOrderByDirection("ascending", true);
+
+		internal static readonly Db4objects.Db4o.Qlin.QLinOrderByDirection Descending = new 
+			Db4objects.Db4o.Qlin.QLinOrderByDirection("descending", false);
+
+		public virtual bool IsAscending()
+		{
+			return _ascending;
+		}
+
+		public virtual bool IsDescending()
+		{
+			return !_ascending;
+		}
+
+		public override string ToString()
+		{
+			return _direction;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/QLinSupport.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/QLinSupport.cs
new file mode 100644
index 0000000..13e9d44
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Qlin/QLinSupport.cs
@@ -0,0 +1,170 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Qlin;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Core;
+
+namespace Db4objects.Db4o.Qlin
+{
+	/// <summary>
+	/// static import support class for
+	/// <see cref="IQLin">IQLin</see>
+	/// queries.
+	/// </summary>
+	/// <since>8.0</since>
+	public class QLinSupport
+	{
+		/// <summary>
+		/// returns a prototype object for a specific class
+		/// to be passed to the where expression of a QLin
+		/// query.
+		/// </summary>
+		/// <remarks>
+		/// returns a prototype object for a specific class
+		/// to be passed to the where expression of a QLin
+		/// query.
+		/// </remarks>
+		/// <seealso cref="IQLin.Where(object)">IQLin.Where(object)</seealso>
+		public static object Prototype(Type clazz)
+		{
+			try
+			{
+				return _prototypes.PrototypeForClass(clazz);
+			}
+			catch (PrototypesException ex)
+			{
+				throw new QLinException(ex);
+			}
+		}
+
+		/// <summary>sets the context for the next query on this thread.</summary>
+		/// <remarks>
+		/// sets the context for the next query on this thread.
+		/// This method should never have to be called manually.
+		/// The framework should set the context up.
+		/// </remarks>
+		public static void Context(IReflectClass claxx)
+		{
+			_context.Value = claxx;
+		}
+
+		/// <summary>sets the context for the next query on this thread.</summary>
+		/// <remarks>
+		/// sets the context for the next query on this thread.
+		/// This method should never have to be called manually.
+		/// The framework should set the context up.
+		/// </remarks>
+		public static void Context(Type clazz)
+		{
+			_context.Value = ReflectorUtils.ReflectClassFor(_prototypes.Reflector(), clazz);
+		}
+
+		/// <summary>
+		/// shortcut for the
+		/// <see cref="Prototype(System.Type{T})">Prototype(System.Type<T>)</see>
+		/// method.
+		/// </summary>
+		public static object P(Type clazz)
+		{
+			return Prototype(clazz);
+		}
+
+		/// <summary>
+		/// parameter for
+		/// <see cref="IQLin.OrderBy(object, QLinOrderByDirection)">IQLin.OrderBy(object, QLinOrderByDirection)
+		/// 	</see>
+		/// </summary>
+		public static QLinOrderByDirection Ascending()
+		{
+			return QLinOrderByDirection.Ascending;
+		}
+
+		/// <summary>
+		/// parameter for
+		/// <see cref="IQLin.OrderBy(object, QLinOrderByDirection)">IQLin.OrderBy(object, QLinOrderByDirection)
+		/// 	</see>
+		/// </summary>
+		public static QLinOrderByDirection Descending()
+		{
+			return QLinOrderByDirection.Descending;
+		}
+
+		/// <summary>public for implementors, do not use directly</summary>
+		public static IEnumerator BackingFieldPath(object expression)
+		{
+			CheckForNull(expression);
+			if (expression is IReflectField)
+			{
+				return Iterators.Iterate(new string[] { ((IReflectField)expression).GetName() });
+			}
+			IEnumerator path = _prototypes.BackingFieldPath(((IReflectClass)_context.Value), 
+				expression);
+			if (path != null)
+			{
+				return path;
+			}
+			return Iterators.Iterate(new string[] { FieldByFieldName(expression).GetName() });
+		}
+
+		/// <summary>converts an expression to a single field.</summary>
+		/// <remarks>converts an expression to a single field.</remarks>
+		public static IReflectField Field(object expression)
+		{
+			CheckForNull(expression);
+			if (expression is IReflectField)
+			{
+				return (IReflectField)expression;
+			}
+			IEnumerator path = _prototypes.BackingFieldPath(((IReflectClass)_context.Value), 
+				expression);
+			if (path != null)
+			{
+				if (path.MoveNext())
+				{
+					expression = path.Current;
+				}
+				if (path.MoveNext())
+				{
+					path.Reset();
+					throw new QLinException("expression can not be converted to a single field. It evaluates to: "
+						 + Iterators.Join(path, "[", "]", ", "));
+				}
+			}
+			return FieldByFieldName(expression);
+		}
+
+		private static IReflectField FieldByFieldName(object expression)
+		{
+			if (expression is string)
+			{
+				IReflectField field = ReflectorUtils.Field(((IReflectClass)_context.Value), (string
+					)expression);
+				if (field != null)
+				{
+					return field;
+				}
+			}
+			throw new QLinException("expression can not be mapped to a field");
+		}
+
+		private static void CheckForNull(object expression)
+		{
+			if (expression == null)
+			{
+				throw new QLinException("expression can not be null");
+			}
+		}
+
+		private const bool IgnoreTransientFields = true;
+
+		private const int RecursionDepth = 4;
+
+		private static readonly Prototypes _prototypes = new Prototypes(Prototypes.DefaultReflector
+			(), RecursionDepth, IgnoreTransientFields);
+
+		private static readonly DynamicVariable _context = DynamicVariable.NewInstance();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/ICandidate.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/ICandidate.cs
new file mode 100644
index 0000000..f885976
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/ICandidate.cs
@@ -0,0 +1,62 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.Query
+{
+	/// <summary>
+	/// candidate for
+	/// <see cref="IEvaluation">IEvaluation</see>
+	/// callbacks.
+	/// <br /><br />
+	/// During
+	/// <see cref="IQuery.Execute()">query execution</see>
+	/// all registered
+	/// <see cref="IEvaluation">IEvaluation</see>
+	/// callback
+	/// handlers are called with
+	/// <see cref="ICandidate">ICandidate</see>
+	/// proxies that represent the persistent objects that
+	/// meet all other
+	/// <see cref="IQuery">IQuery</see>
+	/// criteria.
+	/// <br /><br />
+	/// A
+	/// <see cref="ICandidate">ICandidate</see>
+	/// provides access to the persistent object it
+	/// represents and allows to specify, whether it is to be included in the
+	/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+	/// resultset.
+	/// </summary>
+	public interface ICandidate
+	{
+		/// <summary>
+		/// returns the persistent object that is represented by this query
+		/// <see cref="ICandidate">ICandidate</see>
+		/// .
+		/// </summary>
+		/// <returns>Object the persistent object.</returns>
+		object GetObject();
+
+		/// <summary>
+		/// specify whether the Candidate is to be included in the
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// resultset.
+		/// <br /><br />
+		/// This method may be called multiple times. The last call prevails.
+		/// </summary>
+		/// <param name="flag">inclusion.</param>
+		void Include(bool flag);
+
+		/// <summary>
+		/// returns the
+		/// <see cref="Db4objects.Db4o.IObjectContainer">Db4objects.Db4o.IObjectContainer</see>
+		/// the Candidate object is stored in.
+		/// </summary>
+		/// <returns>
+		/// the
+		/// <see cref="Db4objects.Db4o.IObjectContainer">Db4objects.Db4o.IObjectContainer</see>
+		/// </returns>
+		IObjectContainer ObjectContainer();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/IConstraint.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/IConstraint.cs
new file mode 100644
index 0000000..88e5c1f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/IConstraint.cs
@@ -0,0 +1,271 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Query
+{
+	/// <summary>
+	/// constraint to limit the objects returned upon
+	/// <see cref="Db4objects.Db4o.Query.IQuery.Execute">query execution</see>
+	/// .
+	/// <br/><br/>
+	/// Constraints are constructed by calling
+	/// <see cref="Db4objects.Db4o.Query.IQuery.Constrain">Db4objects.Db4o.Query.IQuery.Constrain
+	/// </see>
+	/// .
+	/// <br/><br/>
+	/// Constraints can be joined with the methods
+	/// <see cref="Db4objects.Db4o.Query.IConstraint.And">Db4objects.Db4o.Query.IConstraint.And
+	/// </see>
+	/// and
+	/// <see cref="Db4objects.Db4o.Query.IConstraint.Or">Db4objects.Db4o.Query.IConstraint.Or
+	/// </see>
+	/// .
+	/// <br/><br/>
+	/// The methods to modify the constraint evaluation algorithm may
+	/// be merged, to construct combined evaluation rules.
+	/// Examples:
+	/// <ul>
+	/// <li> <code>Constraint.Smaller().Equal()</code> for "smaller or equal" </li>
+	/// <li> <code>Constraint.Not().Like()</code> for "not like" </li>
+	/// <li> <code>Constraint.Not().Greater().Equal()</code> for "not greater or equal" </li>
+	/// </ul>
+	/// </summary>
+	public interface IConstraint
+	{
+		/// <summary>links two Constraints for AND evaluation.</summary>
+		/// <remarks>
+		/// links two Constraints for AND evaluation.
+		/// For example:<br/>
+		/// <code>query.Constrain(typeof(Pilot));</code><br/>
+		/// <code>query.Descend("points").Constrain(101).Smaller().And(query.Descend("name").Constrain("Test Pilot0"));	</code><br/>
+		/// will retrieve all pilots with points less than 101 and name as "Test Pilot0"<br/>
+		/// </remarks>
+		/// <param name="with">
+		/// the other
+		/// <see cref="Db4objects.Db4o.Query.IConstraint">Db4objects.Db4o.Query.IConstraint</see>
+		/// </param>
+		/// <returns>
+		/// a new
+		/// <see cref="Db4objects.Db4o.Query.IConstraint">Db4objects.Db4o.Query.IConstraint</see>
+		/// , that can be used for further calls
+		/// to
+		/// <see cref="Db4objects.Db4o.Query.IConstraint.And">And</see>
+		/// and
+		/// <see cref="Db4objects.Db4o.Query.IConstraint.Or">Or</see>
+		/// </returns>
+		IConstraint And(IConstraint with);
+
+		/// <summary>links two Constraints for OR evaluation.</summary>
+		/// <remarks>
+		/// links two Constraints for OR evaluation.
+		/// For example:<br/><br/>
+		/// <code>query.Constrain(typeof(Pilot));</code><br/>
+		/// <code>query.Descend("points").Constrain(101).Greater().Or(query.Descend("name").Constrain("Test Pilot0"));</code><br/>
+		/// will retrieve all pilots with points more than 101 or pilots with the name "Test Pilot0"<br/>
+		/// </remarks>
+		/// <param name="with">
+		/// the other
+		/// <see cref="Db4objects.Db4o.Query.IConstraint">Db4objects.Db4o.Query.IConstraint</see>
+		/// </param>
+		/// <returns>
+		/// a new
+		/// <see cref="Db4objects.Db4o.Query.IConstraint">Db4objects.Db4o.Query.IConstraint</see>
+		/// , that can be used for further calls
+		/// to
+		/// <see cref="Db4objects.Db4o.Query.IConstraint.And">And</see>
+		/// and
+		/// <see cref="Db4objects.Db4o.Query.IConstraint.Or">Or</see>
+		/// </returns>
+		IConstraint Or(IConstraint with);
+
+		/// <summary>
+		/// Used in conjunction with
+		/// <see cref="Db4objects.Db4o.Query.IConstraint.Smaller">Db4objects.Db4o.Query.IConstraint.Smaller
+		/// </see>
+		/// or
+		/// <see cref="Db4objects.Db4o.Query.IConstraint.Greater">Db4objects.Db4o.Query.IConstraint.Greater
+		/// </see>
+		/// to create constraints
+		/// like "smaller or equal", "greater or equal".
+		/// For example:<br/>
+		/// <code>query.Constrain(typeof(Pilot));</code><br/>
+		/// <code>query.Descend("points").Constrain(101).Smaller().Equal();</code><br/>
+		/// will return all pilots with points <= 101.<br/>
+		/// </summary>
+		/// <returns>
+		/// this
+		/// <see cref="Db4objects.Db4o.Query.IConstraint">Db4objects.Db4o.Query.IConstraint</see>
+		/// to allow the chaining of method calls.
+		/// </returns>
+		IConstraint Equal();
+
+		/// <summary>sets the evaluation mode to <code>></code>.</summary>
+		/// <remarks>
+		/// sets the evaluation mode to <code>></code>.
+		/// For example:<br/>
+		/// <code>query.Constrain(typeof(Pilot));</code><br/>
+		/// <code>query.Descend("points").Constrain(101).Greater()</code><br/>
+		/// will return all pilots with points > 101.<br/>
+		/// </remarks>
+		/// <returns>
+		/// this
+		/// <see cref="Db4objects.Db4o.Query.IConstraint">Db4objects.Db4o.Query.IConstraint</see>
+		/// to allow the chaining of method calls.
+		/// </returns>
+		IConstraint Greater();
+
+		/// <summary>sets the evaluation mode to <code><</code>.</summary>
+		/// <remarks>
+		/// sets the evaluation mode to <code><</code>.
+		/// For example:<br/>
+		/// <code>query.Constrain(typeof(Pilot));</code><br/>
+		/// <code>query.Descend("points").Constrain(101).Smaller()</code><br/>
+		/// will return all pilots with points < 101.<br/>
+		/// </remarks>
+		/// <returns>
+		/// this
+		/// <see cref="Db4objects.Db4o.Query.IConstraint">Db4objects.Db4o.Query.IConstraint</see>
+		/// to allow the chaining of method calls.
+		/// </returns>
+		IConstraint Smaller();
+
+		/// <summary>sets the evaluation mode to identity comparison.</summary>
+		/// <remarks>
+		/// sets the evaluation mode to identity comparison. In this case only
+		/// objects having the same database identity will be included in the result set.
+		/// For example:<br/>
+		/// <code>Pilot pilot = new Pilot("Test Pilot1", 100);</code><br/>
+		/// <code>Car car = new Car("BMW", pilot);</code><br/>
+		/// <code>container.Store(car);</code><br/>
+		/// <code>// Change the name, the pilot instance stays the same</code><br/>
+		/// <code>pilot.SetName("Test Pilot2");</code><br/>
+		/// <code>// create a new car</code><br/>
+		/// <code>car = new Car("Ferrari", pilot);</code><br/>
+		/// <code>container.Store(car);</code><br/>
+		/// <code>IQuery query = container.Query();</code><br/>
+		/// <code>query.Constrain(typeof(Car));</code><br/>
+		/// <code>// All cars having pilot with the same database identity</code><br/>
+		/// <code>// will be retrieved. As we only created Pilot object once</code><br/>
+		/// <code>// it should mean all car objects</code><br/>
+		/// <code>query.Descend("_pilot").Constrain(pilot).Identity();</code><br/><br/>
+		/// </remarks>
+		/// <returns>
+		/// this
+		/// <see cref="Db4objects.Db4o.Query.IConstraint">Db4objects.Db4o.Query.IConstraint</see>
+		/// to allow the chaining of method calls.
+		/// </returns>
+		IConstraint Identity();
+
+		/// <summary>set the evaluation mode to object comparison (query by example).</summary>
+		/// <remarks>set the evaluation mode to object comparison (query by example).</remarks>
+		/// <returns>
+		/// this
+		/// <see cref="IConstraint">IConstraint</see>
+		/// to allow the chaining of method calls.
+		/// </returns>
+		IConstraint ByExample();
+
+		/// <summary>sets the evaluation mode to "like" comparison.</summary>
+		/// <remarks>
+		/// sets the evaluation mode to "like" comparison. This mode will include
+		/// all objects having the constrain expression somewhere inside the string field.
+		/// For example:<br/>
+		/// <code>Pilot pilot = new Pilot("Test Pilot1", 100);</code><br/>
+		/// <code>container.Store(pilot);</code><br/>
+		/// <code> ...</code><br/>
+		/// <code>query.Constrain(typeof(Pilot));</code><br/>
+		/// <code>// All pilots with the name containing "est" will be retrieved</code><br/>
+		/// <code>query.Descend("name").Constrain("est").Like();</code><br/>
+		/// </remarks>
+		/// <returns>
+		/// this
+		/// <see cref="Db4objects.Db4o.Query.IConstraint">Db4objects.Db4o.Query.IConstraint</see>
+		/// to allow the chaining of method calls.
+		/// </returns>
+		IConstraint Like();
+
+		/// <summary>Sets the evaluation mode to string contains comparison.</summary>
+		/// <remarks>
+		/// Sets the evaluation mode to string contains comparison. The contains comparison is case sensitive.<br/>
+		/// For example:<br/>
+		/// <code>Pilot pilot = new Pilot("Test Pilot1", 100);</code><br/>
+		/// <code>container.Store(pilot);</code><br/>
+		/// <code> ...</code><br/>
+		/// <code>query.Constrain(typeof(Pilot));</code><br/>
+		/// <code>// All pilots with the name containing "est" will be retrieved</code><br/>
+		/// <code>query.Descend("name").Constrain("est").Contains();</code><br/>
+		/// <see cref="Db4objects.Db4o.Query.IConstraint.Like">Like() for case insensitive string comparison</see>
+		/// </remarks>
+		/// <returns>
+		/// this
+		/// <see cref="Db4objects.Db4o.Query.IConstraint">Db4objects.Db4o.Query.IConstraint</see>
+		/// to allow the chaining of method calls.
+		/// </returns>
+		IConstraint Contains();
+
+		/// <summary>sets the evaluation mode to string StartsWith comparison.</summary>
+		/// <remarks>
+		/// sets the evaluation mode to string StartsWith comparison.
+		/// For example:<br/>
+		/// <code>Pilot pilot = new Pilot("Test Pilot0", 100);</code><br/>
+		/// <code>container.Store(pilot);</code><br/>
+		/// <code> ...</code><br/>
+		/// <code>query.Constrain(typeof(Pilot));</code><br/>
+		/// <code>query.Descend("name").Constrain("Test").StartsWith(true);</code><br/>
+		/// </remarks>
+		/// <param name="caseSensitive">comparison will be case sensitive if true, case insensitive otherwise
+		/// </param>
+		/// <returns>
+		/// this
+		/// <see cref="Db4objects.Db4o.Query.IConstraint">Db4objects.Db4o.Query.IConstraint</see>
+		/// to allow the chaining of method calls.
+		/// </returns>
+		IConstraint StartsWith(bool caseSensitive);
+
+		/// <summary>sets the evaluation mode to string EndsWith comparison.</summary>
+		/// <remarks>
+		/// sets the evaluation mode to string EndsWith comparison.
+		/// For example:<br/>
+		/// <code>Pilot pilot = new Pilot("Test Pilot0", 100);</code><br/>
+		/// <code>container.Store(pilot);</code><br/>
+		/// <code> ...</code><br/>
+		/// <code>query.Constrain(typeof(Pilot));</code><br/>
+		/// <code>query.Descend("name").Constrain("T0").EndsWith(false);</code><br/>
+		/// </remarks>
+		/// <param name="caseSensitive">comparison will be case sensitive if true, case insensitive otherwise
+		/// </param>
+		/// <returns>
+		/// this
+		/// <see cref="Db4objects.Db4o.Query.IConstraint">Db4objects.Db4o.Query.IConstraint</see>
+		/// to allow the chaining of method calls.
+		/// </returns>
+		IConstraint EndsWith(bool caseSensitive);
+
+		/// <summary>turns on Not() comparison.</summary>
+		/// <remarks>
+		/// turns on Not() comparison. All objects not fullfilling the constrain condition will be returned.
+		/// For example:<br/>
+		/// <code>Pilot pilot = new Pilot("Test Pilot1", 100);</code><br/>
+		/// <code>container.Store(pilot);</code><br/>
+		/// <code> ...</code><br/>
+		/// <code>query.Constrain(typeof(Pilot));</code><br/>
+		/// <code>query.Descend("name").Constrain("t0").EndsWith(true).Not();</code><br/>
+		/// </remarks>
+		/// <returns>
+		/// this
+		/// <see cref="Db4objects.Db4o.Query.IConstraint">Db4objects.Db4o.Query.IConstraint</see>
+		/// to allow the chaining of method calls.
+		/// </returns>
+		IConstraint Not();
+
+		/// <summary>
+		/// returns the Object the query graph was constrained with to
+		/// create this
+		/// <see cref="IConstraint">IConstraint</see>
+		/// .
+		/// </summary>
+		/// <returns>Object the constraining object.</returns>
+		object GetObject();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/IConstraints.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/IConstraints.cs
new file mode 100644
index 0000000..3bc2673
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/IConstraints.cs
@@ -0,0 +1,36 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Query
+{
+	/// <summary>
+	/// set of
+	/// <see cref="IConstraint">IConstraint</see>
+	/// objects.
+	/// <br /><br />This extension of the
+	/// <see cref="IConstraint">IConstraint</see>
+	/// interface allows
+	/// setting the evaluation mode of all contained
+	/// <see cref="IConstraint">IConstraint</see>
+	/// objects with single calls.
+	/// <br /><br />
+	/// See also
+	/// <see cref="IQuery.Constraints()">IQuery.Constraints()</see>
+	/// .
+	/// </summary>
+	public interface IConstraints : IConstraint
+	{
+		/// <summary>
+		/// returns an array of the contained
+		/// <see cref="IConstraint">IConstraint</see>
+		/// objects.
+		/// </summary>
+		/// <returns>
+		/// an array of the contained
+		/// <see cref="IConstraint">IConstraint</see>
+		/// objects.
+		/// </returns>
+		IConstraint[] ToArray();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/IEvaluation.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/IEvaluation.cs
new file mode 100644
index 0000000..6e21347
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/IEvaluation.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Query
+{
+	/// <summary>for implementation of callback evaluations.</summary>
+	/// <remarks>
+	/// for implementation of callback evaluations.
+	/// <br /><br />
+	/// To constrain a
+	/// <see cref="IQuery">IQuery</see>
+	/// node with your own callback
+	/// <code>Evaluation</code>, construct an object that implements the
+	/// <code>Evaluation</code> interface and register it by passing it
+	/// to
+	/// <see cref="IQuery.Constrain(object)">IQuery.Constrain(object)</see>
+	/// .
+	/// <br /><br />
+	/// Evaluations are called as the last step during query execution,
+	/// after all other constraints have been applied. Evaluations in higher
+	/// level
+	/// <see cref="IQuery">IQuery</see>
+	/// nodes in the query graph are called first.
+	/// <br /><br />Java client/server only:<br />
+	/// db4o first attempts to use Java Serialization to allow to pass final
+	/// variables to the server. Please make sure that all variables that are
+	/// used within the
+	/// <see cref="Evaluate(ICandidate)">Evaluate(ICandidate)</see>
+	/// method are Serializable. This may include
+	/// the class an anonymous Evaluation object is created in. If db4o is
+	/// not successful at using Serialization, the Evaluation is transported
+	/// to the server in a db4o
+	/// <see cref="Db4objects.Db4o.IO.MemoryBin">Db4objects.Db4o.IO.MemoryBin</see>
+	/// . In this case final variables can
+	/// not be restored.
+	/// </remarks>
+	public interface IEvaluation
+	{
+		/// <summary>
+		/// callback method during
+		/// <see cref="IQuery.Execute()">query execution</see>
+		/// .
+		/// </summary>
+		/// <param name="candidate">reference to the candidate persistent object.</param>
+		void Evaluate(ICandidate candidate);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/IQuery.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/IQuery.cs
new file mode 100644
index 0000000..85d4ac4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/IQuery.cs
@@ -0,0 +1,177 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Query
+{
+	/// <summary>handle to a node in a S.O.D.A.</summary>
+	/// <remarks>
+	/// handle to a node in a S.O.D.A. query graph.
+	/// <br/><br/>
+	/// A node in the query graph can represent multiple
+	/// classes, one class or an attribute of a class.<br/><br/>The graph
+	/// is automatically extended with attributes of added constraints
+	/// (see
+	/// <see cref="Constrain(object)">Constrain(object)</see>
+	/// ) and upon calls to
+	/// <see cref="Descend(string)">Descend(string)</see>
+	/// that request nodes that do not yet exist.
+	/// <br/><br/>
+	/// References to joined nodes in the query graph can be obtained
+	/// by "walking" along the nodes of the graph with the method
+	/// <see cref="Descend(string)">Descend(string)</see>
+	/// .
+	/// <br/><br/>
+	/// <see cref="Execute()">Execute()</see>
+	/// evaluates the entire graph against all persistent objects.
+	/// <br/><br/>
+	/// <see cref="Execute()">Execute()</see>
+	/// can be called from any
+	/// <see cref="IQuery">IQuery</see>
+	/// node
+	/// of the graph. It will return an
+	/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+	/// filled with
+	/// objects of the class/classes that the node, it was called from,
+	/// represents.<br/><br/>
+	/// <b>Note:<br/>
+	/// <see cref="Predicate">Native queries</see>
+	/// are the recommended main query
+	/// interface of db4o.</b>
+	/// </remarks>
+	public interface IQuery
+	{
+		/// <summary>adds a constraint to this node.</summary>
+		/// <remarks>
+		/// adds a constraint to this node.
+		/// <br/><br/>
+		/// If the constraint contains attributes that are not yet
+		/// present in the query graph, the query graph is extended
+		/// accordingly.
+		/// <br/><br/>
+		/// Special behaviour for:
+		/// <ul>
+		/// <li> class
+		/// <see cref="System.Type{T}">System.Type<T></see>
+		/// : confine the result to objects of one
+		/// class or to objects implementing an interface.</li>
+		/// <li> interface
+		/// <see cref="IEvaluation">IEvaluation</see>
+		/// : run
+		/// evaluation callbacks against all candidates.</li>
+		/// </ul>
+		/// </remarks>
+		/// <param name="constraint">the constraint to be added to this Query.</param>
+		/// <returns>
+		/// 
+		/// <see cref="IConstraint">IConstraint</see>
+		/// a new
+		/// <see cref="IConstraint">IConstraint</see>
+		/// for this
+		/// query node or <code>null</code> for objects implementing the
+		/// <see cref="IEvaluation">IEvaluation</see>
+		/// interface.
+		/// </returns>
+		IConstraint Constrain(object constraint);
+
+		/// <summary>
+		/// returns a
+		/// <see cref="IConstraints">IConstraints</see>
+		/// object that holds an array of all constraints on this node.
+		/// </summary>
+		/// <returns>
+		/// 
+		/// <see cref="IConstraints">IConstraints</see>
+		/// on this query node.
+		/// </returns>
+		IConstraints Constraints();
+
+		/// <summary>returns a reference to a descendant node in the query graph.</summary>
+		/// <remarks>
+		/// returns a reference to a descendant node in the query graph.
+		/// <br/><br/>If the node does not exist, it will be created.
+		/// <br/><br/>
+		/// All classes represented in the query node are tested, whether
+		/// they contain a field with the specified field name. The
+		/// descendant Query node will be created from all possible candidate
+		/// classes.
+		/// </remarks>
+		/// <param name="fieldName">path to the descendant.</param>
+		/// <returns>
+		/// descendant
+		/// <see cref="IQuery">IQuery</see>
+		/// node
+		/// </returns>
+		IQuery Descend(string fieldName);
+
+		/// <summary>
+		/// executes the
+		/// <see cref="IQuery">IQuery</see>
+		/// .
+		/// </summary>
+		/// <returns>
+		/// 
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// - the result of the
+		/// <see cref="IQuery">IQuery</see>
+		/// .
+		/// </returns>
+		IObjectSet Execute();
+
+		/// <summary>
+		/// adds an ascending ordering criteria to this node of
+		/// the query graph.
+		/// </summary>
+		/// <remarks>
+		/// adds an ascending ordering criteria to this node of
+		/// the query graph.
+		/// <p>
+		/// If multiple ordering criteria are applied, the chronological
+		/// order of method calls is relevant: criteria created by 'earlier' calls are
+		/// considered more significant, i.e. 'later' criteria only have an effect
+		/// for elements that are considered equal by all 'earlier' criteria.
+		/// </p>
+		/// <p>
+		/// As an example, consider a type with two int fields, and an instance set
+		/// {(a:1,b:3),(a:2,b:2),(a:1,b:2),(a:2,b:3)}. The call sequence [orderAscending(a),
+		/// orderDescending(b)] will result in [(<b>a:1</b>,b:3),(<b>a:1</b>,b:2),(<b>a:2</b>,b:3),(<b>a:2</b>,b:2)].
+		/// </p>
+		/// </remarks>
+		/// <returns>
+		/// this
+		/// <see cref="IQuery">IQuery</see>
+		/// object to allow the chaining of method calls.
+		/// </returns>
+		IQuery OrderAscending();
+
+		/// <summary>
+		/// adds a descending order criteria to this node of
+		/// the query graph.
+		/// </summary>
+		/// <remarks>
+		/// adds a descending order criteria to this node of
+		/// the query graph.
+		/// <br/><br/>
+		/// For semantics of multiple calls setting ordering criteria, see
+		/// <see cref="OrderAscending()">OrderAscending()</see>
+		/// .
+		/// </remarks>
+		/// <returns>
+		/// this
+		/// <see cref="IQuery">IQuery</see>
+		/// object to allow the chaining of method calls.
+		/// </returns>
+		IQuery OrderDescending();
+
+		/// <summary>Sort the resulting ObjectSet by the given comparator.</summary>
+		/// <remarks>Sort the resulting ObjectSet by the given comparator.</remarks>
+		/// <param name="comparator">The comparator to apply.</param>
+		/// <returns>
+		/// this
+		/// <see cref="IQuery">IQuery</see>
+		/// object to allow the chaining of method calls.
+		/// </returns>
+		IQuery SortBy(IQueryComparator comparator);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/IQueryComparator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/IQueryComparator.cs
new file mode 100644
index 0000000..22cf85c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/IQueryComparator.cs
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Query
+{
+	/// <summary>
+	/// This interface is not used in .NET.
+	/// </summary>
+	public interface IQueryComparator
+	{
+		/// <summary>Implement to compare two arguments for sorting.</summary>
+		/// <remarks>
+		/// Implement to compare two arguments for sorting.
+		/// Return a negative value, zero, or a positive value if
+		/// the first argument is smaller, equal or greater than
+		/// the second.
+		/// </remarks>
+		int Compare(object first, object second);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/Predicate.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/Predicate.cs
new file mode 100644
index 0000000..399a0f8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Query/Predicate.cs
@@ -0,0 +1,168 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Reflection;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Query
+{
+	/// <summary>Base class for native queries.</summary>
+	/// <remarks>
+	/// Base class for native queries.
+	/// <br /><br />Native Queries provide the ability to run one or more lines
+	/// of code against all instances of a class. Native query expressions should
+	/// return true to mark specific instances as part of the result set.
+	/// db4o will  attempt to optimize native query expressions and run them
+	/// against indexes and without instantiating actual objects, where this is
+	/// possible.<br /><br />
+	/// The syntax of the enclosing object for the native query expression varies
+	/// slightly, depending on the language version used. Here are some examples,
+	/// how a simple native query will look like in some of the programming languages and
+	/// dialects that db4o supports:<br /><br />
+	/// <code>
+	/// <b>// C# .NET 2.0</b><br />
+	/// IList <Cat> cats = db.Query <Cat> (delegate(Cat cat) {<br />
+	///    return cat.Name == "Occam";<br />
+	/// });<br />
+	/// <br />
+	/// <br />
+	/// <b>// Java JDK 5</b><br />
+	/// List <Cat> cats = db.query(new Predicate<Cat>() {<br />
+	///    public boolean match(Cat cat) {<br />
+	///       return cat.getName().equals("Occam");<br />
+	///    }<br />
+	/// });<br />
+	/// <br />
+	/// <br />
+	/// <b>// Java JDK 1.2 to 1.4</b><br />
+	/// List cats = db.query(new Predicate() {<br />
+	///    public boolean match(Cat cat) {<br />
+	///       return cat.getName().equals("Occam");<br />
+	///    }<br />
+	/// });<br />
+	/// <br />
+	/// <br />
+	/// <b>// Java JDK 1.1</b><br />
+	/// ObjectSet cats = db.query(new CatOccam());<br />
+	/// <br />
+	/// public static class CatOccam extends Predicate {<br />
+	///    public boolean match(Cat cat) {<br />
+	///       return cat.getName().equals("Occam");<br />
+	///    }<br />
+	/// });<br />
+	/// <br />
+	/// <br />
+	/// <b>// C# .NET 1.1</b><br />
+	/// IList cats = db.Query(new CatOccam());<br />
+	/// <br />
+	/// public class CatOccam : Predicate {<br />
+	///    public boolean Match(Cat cat) {<br />
+	///       return cat.Name == "Occam";<br />
+	///    }<br />
+	/// });<br />
+	/// </code>
+	/// <br />
+	/// Summing up the above:<br />
+	/// In order to run a Native Query, you can<br />
+	/// - use the delegate notation for .NET 2.0.<br />
+	/// - extend the Predicate class for all other language dialects<br /><br />
+	/// A class that extends Predicate is required to
+	/// implement the #match() / #Match() method, following the native query
+	/// conventions:<br />
+	/// - The name of the method is "#match()" (Java) / "#Match()" (.NET).<br />
+	/// - The method must be public public.<br />
+	/// - The method returns a boolean.<br />
+	/// - The method takes one parameter.<br />
+	/// - The Type (.NET) / Class (Java) of the parameter specifies the extent.<br />
+	/// - For all instances of the extent that are to be included into the
+	/// resultset of the query, the match method should return true. For all
+	/// instances that are not to be included, the match method should return
+	/// false.<br /><br />
+	/// </remarks>
+	[System.Serializable]
+	public abstract class Predicate
+	{
+		/// <summary>public for implementation reasons, please ignore.</summary>
+		/// <remarks>public for implementation reasons, please ignore.</remarks>
+		public static readonly string PredicatemethodName = "match";
+
+		private Type _extentType;
+
+		[System.NonSerialized]
+		private MethodInfo cachedFilterMethod = null;
+
+		public Predicate() : this(null)
+		{
+		}
+
+		public Predicate(Type extentType)
+		{
+			_extentType = extentType;
+		}
+
+		public virtual MethodInfo GetFilterMethod()
+		{
+			if (cachedFilterMethod != null)
+			{
+				return cachedFilterMethod;
+			}
+			MethodInfo[] methods = GetType().GetMethods();
+			for (int methodIdx = 0; methodIdx < methods.Length; methodIdx++)
+			{
+				MethodInfo method = methods[methodIdx];
+				if ((!method.Name.Equals(PredicatePlatform.PredicatemethodName)) || Sharpen.Runtime.GetParameterTypes
+					(method).Length != 1)
+				{
+					continue;
+				}
+				cachedFilterMethod = method;
+				string targetName = Sharpen.Runtime.GetParameterTypes(method)[0].FullName;
+				if (!"java.lang.Object".Equals(targetName))
+				{
+					break;
+				}
+			}
+			if (cachedFilterMethod == null)
+			{
+				throw new ArgumentException("Invalid predicate.");
+			}
+			return cachedFilterMethod;
+		}
+
+		/// <summary>public for implementation reasons, please ignore.</summary>
+		/// <remarks>public for implementation reasons, please ignore.</remarks>
+		public virtual Type ExtentType()
+		{
+			if (_extentType == null)
+			{
+				_extentType = FilterParameterType();
+			}
+			return _extentType;
+		}
+
+		private Type FilterParameterType()
+		{
+			return (Type)Sharpen.Runtime.GetParameterTypes(GetFilterMethod())[0];
+		}
+
+		/// <summary>public for implementation reasons, please ignore.</summary>
+		/// <remarks>public for implementation reasons, please ignore.</remarks>
+		public virtual bool AppliesTo(object candidate)
+		{
+			try
+			{
+				MethodInfo filterMethod = GetFilterMethod();
+				Platform4.SetAccessible(filterMethod);
+				object ret = filterMethod.Invoke(this, new object[] { candidate });
+				return ((bool)ret);
+			}
+			catch (Exception)
+			{
+				// TODO: log this exception somewhere?
+				//			e.printStackTrace();
+				return false;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/ArrayInfo.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/ArrayInfo.cs
new file mode 100644
index 0000000..7ba4108
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/ArrayInfo.cs
@@ -0,0 +1,58 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Reflect
+{
+	/// <exclude></exclude>
+	public class ArrayInfo
+	{
+		private int _elementCount;
+
+		private bool _primitive;
+
+		private bool _nullable;
+
+		private IReflectClass _reflectClass;
+
+		public virtual int ElementCount()
+		{
+			return _elementCount;
+		}
+
+		public virtual void ElementCount(int count)
+		{
+			_elementCount = count;
+		}
+
+		public virtual bool Primitive()
+		{
+			return _primitive;
+		}
+
+		public virtual void Primitive(bool flag)
+		{
+			_primitive = flag;
+		}
+
+		public virtual bool Nullable()
+		{
+			return _nullable;
+		}
+
+		public virtual void Nullable(bool flag)
+		{
+			_nullable = flag;
+		}
+
+		public virtual IReflectClass ReflectClass()
+		{
+			return _reflectClass;
+		}
+
+		public virtual void ReflectClass(IReflectClass claxx)
+		{
+			_reflectClass = claxx;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/AbstractReflectArray.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/AbstractReflectArray.cs
new file mode 100644
index 0000000..533d030
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/AbstractReflectArray.cs
@@ -0,0 +1,151 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Reflect;
+using Sharpen.Lang.Reflect;
+
+namespace Db4objects.Db4o.Reflect.Core
+{
+	/// <exclude></exclude>
+	public abstract class AbstractReflectArray : IReflectArray
+	{
+		protected readonly IReflector _reflector;
+
+		public AbstractReflectArray(IReflector reflector)
+		{
+			_reflector = reflector;
+		}
+
+		public abstract object NewInstance(IReflectClass componentType, int[] dimensions);
+
+		public abstract object NewInstance(IReflectClass componentType, int length);
+
+		public virtual int[] Dimensions(object arr)
+		{
+			int count = 0;
+			IReflectClass claxx = _reflector.ForObject(arr);
+			while (claxx.IsArray())
+			{
+				count++;
+				claxx = claxx.GetComponentType();
+			}
+			int[] dim = new int[count];
+			for (int i = 0; i < count; i++)
+			{
+				try
+				{
+					dim[i] = GetLength(arr);
+					arr = Get(arr, 0);
+				}
+				catch (Exception)
+				{
+					return dim;
+				}
+			}
+			return dim;
+		}
+
+		public virtual int Flatten(object a_shaped, int[] a_dimensions, int a_currentDimension
+			, object[] a_flat, int a_flatElement)
+		{
+			if (a_currentDimension == (a_dimensions.Length - 1))
+			{
+				for (int i = 0; i < a_dimensions[a_currentDimension]; i++)
+				{
+					a_flat[a_flatElement++] = GetNoExceptions(a_shaped, i);
+				}
+			}
+			else
+			{
+				for (int i = 0; i < a_dimensions[a_currentDimension]; i++)
+				{
+					a_flatElement = Flatten(GetNoExceptions(a_shaped, i), a_dimensions, a_currentDimension
+						 + 1, a_flat, a_flatElement);
+				}
+			}
+			return a_flatElement;
+		}
+
+		public virtual object Get(object onArray, int index)
+		{
+			return Sharpen.Runtime.GetArrayValue(onArray, index);
+		}
+
+		public virtual IReflectClass GetComponentType(IReflectClass a_class)
+		{
+			while (a_class.IsArray())
+			{
+				a_class = a_class.GetComponentType();
+			}
+			return a_class;
+		}
+
+		public virtual int GetLength(object array)
+		{
+			return Sharpen.Runtime.GetArrayLength(array);
+		}
+
+		private object GetNoExceptions(object onArray, int index)
+		{
+			try
+			{
+				return Get(onArray, index);
+			}
+			catch (Exception)
+			{
+				return null;
+			}
+		}
+
+		public virtual bool IsNDimensional(IReflectClass a_class)
+		{
+			return a_class.GetComponentType().IsArray();
+		}
+
+		public virtual void Set(object onArray, int index, object element)
+		{
+			if (element == null)
+			{
+				try
+				{
+					Sharpen.Runtime.SetArrayValue(onArray, index, element);
+				}
+				catch (Exception)
+				{
+				}
+			}
+			else
+			{
+				// This can happen on primitive arrays
+				// and we are fine with ignoring it.
+				// TODO: check if it's a primitive array first and don't ignore exceptions
+				Sharpen.Runtime.SetArrayValue(onArray, index, element);
+			}
+		}
+
+		public virtual int Shape(object[] a_flat, int a_flatElement, object a_shaped, int
+			[] a_dimensions, int a_currentDimension)
+		{
+			if (a_currentDimension == (a_dimensions.Length - 1))
+			{
+				for (int i = 0; i < a_dimensions[a_currentDimension]; i++)
+				{
+					Set(a_shaped, i, a_flat[a_flatElement++]);
+				}
+			}
+			else
+			{
+				for (int i = 0; i < a_dimensions[a_currentDimension]; i++)
+				{
+					a_flatElement = Shape(a_flat, a_flatElement, Get(a_shaped, i), a_dimensions, a_currentDimension
+						 + 1);
+				}
+			}
+			return a_flatElement;
+		}
+
+		public abstract void Analyze(object arg1, ArrayInfo arg2);
+
+		public abstract object NewInstance(IReflectClass arg1, ArrayInfo arg2);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/ConstructorSupport.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/ConstructorSupport.cs
new file mode 100644
index 0000000..8277671
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/ConstructorSupport.cs
@@ -0,0 +1,123 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Core;
+
+namespace Db4objects.Db4o.Reflect.Core
+{
+	public class ConstructorSupport
+	{
+		public static ReflectConstructorSpec CreateConstructor(IConstructorAwareReflectClass
+			 claxx, Type clazz, IReflectorConfiguration config, IReflectConstructor[] constructors
+			)
+		{
+			if (claxx == null)
+			{
+				return ReflectConstructorSpec.InvalidConstructor;
+			}
+			if (claxx.IsAbstract() || claxx.IsInterface())
+			{
+				return ReflectConstructorSpec.InvalidConstructor;
+			}
+			if (!Platform4.CallConstructor())
+			{
+				bool skipConstructor = !config.CallConstructor(claxx);
+				if (!claxx.IsCollection())
+				{
+					IReflectConstructor serializableConstructor = SkipConstructor(claxx, skipConstructor
+						, config.TestConstructors());
+					if (serializableConstructor != null)
+					{
+						return new ReflectConstructorSpec(serializableConstructor, null);
+					}
+				}
+			}
+			if (!config.TestConstructors())
+			{
+				return new ReflectConstructorSpec(new PlatformReflectConstructor(clazz), null);
+			}
+			if (ReflectPlatform.CreateInstance(clazz) != null)
+			{
+				return new ReflectConstructorSpec(new PlatformReflectConstructor(clazz), null);
+			}
+			Tree sortedConstructors = SortConstructorsByParamsCount(constructors);
+			return FindConstructor(claxx, sortedConstructors);
+		}
+
+		private static ReflectConstructorSpec FindConstructor(IReflectClass claxx, Tree sortedConstructors
+			)
+		{
+			if (sortedConstructors == null)
+			{
+				return ReflectConstructorSpec.InvalidConstructor;
+			}
+			IEnumerator iter = new TreeNodeIterator(sortedConstructors);
+			while (iter.MoveNext())
+			{
+				object current = iter.Current;
+				IReflectConstructor constructor = (IReflectConstructor)((TreeIntObject)current)._object;
+				object[] args = NullArgumentsFor(constructor);
+				object res = constructor.NewInstance(args);
+				if (res != null)
+				{
+					return new ReflectConstructorSpec(constructor, args);
+				}
+			}
+			return ReflectConstructorSpec.InvalidConstructor;
+		}
+
+		private static object[] NullArgumentsFor(IReflectConstructor constructor)
+		{
+			IReflectClass[] paramTypes = constructor.GetParameterTypes();
+			object[] @params = new object[paramTypes.Length];
+			for (int j = 0; j < @params.Length; j++)
+			{
+				@params[j] = paramTypes[j].NullValue();
+			}
+			return @params;
+		}
+
+		private static Tree SortConstructorsByParamsCount(IReflectConstructor[] constructors
+			)
+		{
+			Tree sortedConstructors = null;
+			// sort constructors by parameter count
+			for (int i = 0; i < constructors.Length; i++)
+			{
+				int parameterCount = constructors[i].GetParameterTypes().Length;
+				sortedConstructors = Tree.Add(sortedConstructors, new TreeIntObject(i + constructors
+					.Length * parameterCount, constructors[i]));
+			}
+			return sortedConstructors;
+		}
+
+		public static IReflectConstructor SkipConstructor(IConstructorAwareReflectClass claxx
+			, bool skipConstructor, bool testConstructor)
+		{
+			if (!skipConstructor)
+			{
+				return null;
+			}
+			IReflectConstructor serializableConstructor = claxx.GetSerializableConstructor();
+			if (serializableConstructor == null)
+			{
+				return null;
+			}
+			if (!testConstructor || Deploy.csharp)
+			{
+				return serializableConstructor;
+			}
+			object obj = serializableConstructor.NewInstance((object[])null);
+			if (obj != null)
+			{
+				return serializableConstructor;
+			}
+			return null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/IConstructorAwareReflectClass.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/IConstructorAwareReflectClass.cs
new file mode 100644
index 0000000..c143d55
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/IConstructorAwareReflectClass.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Core;
+
+namespace Db4objects.Db4o.Reflect.Core
+{
+	public interface IConstructorAwareReflectClass : IReflectClass
+	{
+		IReflectConstructor GetSerializableConstructor();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/IReflectConstructor.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/IReflectConstructor.cs
new file mode 100644
index 0000000..19d7be7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/IReflectConstructor.cs
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Reflect.Core
+{
+	/// <summary>Reflection Constructor representation.</summary>
+	/// <remarks>
+	/// Reflection Constructor representation
+	/// <br/><br/>See documentation for System.Reflection API.
+	/// </remarks>
+	/// <seealso cref="IReflector">IReflector</seealso>
+	public interface IReflectConstructor
+	{
+		IReflectClass[] GetParameterTypes();
+
+		object NewInstance(object[] parameters);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/PlatformReflectConstructor.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/PlatformReflectConstructor.cs
new file mode 100644
index 0000000..4a2b544
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/PlatformReflectConstructor.cs
@@ -0,0 +1,31 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Core;
+
+namespace Db4objects.Db4o.Reflect.Core
+{
+	public class PlatformReflectConstructor : IReflectConstructor
+	{
+		private static readonly IReflectClass[] ParameterTypes = new IReflectClass[] {  };
+
+		private Type _clazz;
+
+		public PlatformReflectConstructor(Type clazz)
+		{
+			_clazz = clazz;
+		}
+
+		public virtual IReflectClass[] GetParameterTypes()
+		{
+			return ParameterTypes;
+		}
+
+		public virtual object NewInstance(object[] parameters)
+		{
+			return ReflectPlatform.CreateInstance(_clazz);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/ReflectConstructorSpec.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/ReflectConstructorSpec.cs
new file mode 100644
index 0000000..1a23528
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/ReflectConstructorSpec.cs
@@ -0,0 +1,71 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Reflect.Core;
+
+namespace Db4objects.Db4o.Reflect.Core
+{
+	/// <summary>
+	/// a spec holding a constructor, it's arguments
+	/// and information, if the constructor can instantiate
+	/// objects.
+	/// </summary>
+	/// <remarks>
+	/// a spec holding a constructor, it's arguments
+	/// and information, if the constructor can instantiate
+	/// objects.
+	/// </remarks>
+	public class ReflectConstructorSpec
+	{
+		private IReflectConstructor _constructor;
+
+		private object[] _args;
+
+		private TernaryBool _canBeInstantiated;
+
+		public static readonly Db4objects.Db4o.Reflect.Core.ReflectConstructorSpec UnspecifiedConstructor
+			 = new Db4objects.Db4o.Reflect.Core.ReflectConstructorSpec(TernaryBool.Unspecified
+			);
+
+		public static readonly Db4objects.Db4o.Reflect.Core.ReflectConstructorSpec InvalidConstructor
+			 = new Db4objects.Db4o.Reflect.Core.ReflectConstructorSpec(TernaryBool.No);
+
+		public ReflectConstructorSpec(IReflectConstructor constructor, object[] args)
+		{
+			_constructor = constructor;
+			_args = args;
+			_canBeInstantiated = TernaryBool.Yes;
+		}
+
+		private ReflectConstructorSpec(TernaryBool canBeInstantiated)
+		{
+			_canBeInstantiated = canBeInstantiated;
+			_constructor = null;
+		}
+
+		/// <summary>creates a new instance.</summary>
+		/// <remarks>creates a new instance.</remarks>
+		/// <returns>the newly created instance.</returns>
+		public virtual object NewInstance()
+		{
+			if (_constructor == null)
+			{
+				return null;
+			}
+			return _constructor.NewInstance(_args);
+		}
+
+		/// <summary>
+		/// returns true if an instance can be instantiated
+		/// with the constructor, otherwise false.
+		/// </summary>
+		/// <remarks>
+		/// returns true if an instance can be instantiated
+		/// with the constructor, otherwise false.
+		/// </remarks>
+		public virtual TernaryBool CanBeInstantiated()
+		{
+			return _canBeInstantiated;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/ReflectorUtils.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/ReflectorUtils.cs
new file mode 100644
index 0000000..b870ad4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Core/ReflectorUtils.cs
@@ -0,0 +1,59 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Reflect.Core
+{
+	/// <exclude></exclude>
+	public class ReflectorUtils
+	{
+		public static IReflectClass ReflectClassFor(IReflector reflector, object clazz)
+		{
+			if (clazz is IReflectClass)
+			{
+				return (IReflectClass)clazz;
+			}
+			if (clazz is Type)
+			{
+				return reflector.ForClass((Type)clazz);
+			}
+			if (clazz is string)
+			{
+				return reflector.ForName((string)clazz);
+			}
+			return reflector.ForObject(clazz);
+		}
+
+		public static IReflectField Field(IReflectClass claxx, string name)
+		{
+			while (claxx != null)
+			{
+				try
+				{
+					return claxx.GetDeclaredField(name);
+				}
+				catch (Exception)
+				{
+				}
+				claxx = claxx.GetSuperclass();
+			}
+			return null;
+		}
+
+		public static void ForEachField(IReflectClass claxx, IProcedure4 procedure)
+		{
+			while (claxx != null)
+			{
+				IReflectField[] declaredFields = claxx.GetDeclaredFields();
+				for (int reflectFieldIndex = 0; reflectFieldIndex < declaredFields.Length; ++reflectFieldIndex)
+				{
+					IReflectField reflectField = declaredFields[reflectFieldIndex];
+					procedure.Apply(reflectField);
+				}
+				claxx = claxx.GetSuperclass();
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/CollectionUpdateDepthEntry.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/CollectionUpdateDepthEntry.cs
new file mode 100644
index 0000000..99f399b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/CollectionUpdateDepthEntry.cs
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Reflect.Generic
+{
+	internal class CollectionUpdateDepthEntry
+	{
+		internal readonly IReflectClassPredicate _predicate;
+
+		internal readonly int _depth;
+
+		internal CollectionUpdateDepthEntry(IReflectClassPredicate predicate, int depth)
+		{
+			_predicate = predicate;
+			_depth = depth;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericArray.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericArray.cs
new file mode 100644
index 0000000..9e13234
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericArray.cs
@@ -0,0 +1,41 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Reflect.Generic;
+
+namespace Db4objects.Db4o.Reflect.Generic
+{
+	/// <exclude></exclude>
+	public class GenericArray
+	{
+		internal GenericClass _clazz;
+
+		internal object[] _data;
+
+		public GenericArray(GenericClass clazz, int size)
+		{
+			_clazz = clazz;
+			_data = new object[size];
+		}
+
+		public virtual IEnumerator Iterator()
+		{
+			return Iterators.Iterate(_data);
+		}
+
+		internal virtual int GetLength()
+		{
+			return _data.Length;
+		}
+
+		public override string ToString()
+		{
+			if (_clazz == null)
+			{
+				return base.ToString();
+			}
+			return _clazz.ToString(this);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericArrayClass.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericArrayClass.cs
new file mode 100644
index 0000000..dd23278
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericArrayClass.cs
@@ -0,0 +1,45 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Generic;
+
+namespace Db4objects.Db4o.Reflect.Generic
+{
+	/// <exclude></exclude>
+	public class GenericArrayClass : GenericClass
+	{
+		public GenericArrayClass(GenericReflector reflector, IReflectClass delegateClass, 
+			string name, GenericClass superclass) : base(reflector, delegateClass, name, superclass
+			)
+		{
+		}
+
+		public override IReflectClass GetComponentType()
+		{
+			return GetDelegate();
+		}
+
+		public override bool IsArray()
+		{
+			return true;
+		}
+
+		public override bool IsInstance(object candidate)
+		{
+			if (!(candidate is GenericArray))
+			{
+				return false;
+			}
+			return IsAssignableFrom(((GenericArray)candidate)._clazz);
+		}
+
+		public override string ToString(object obj)
+		{
+			if (_converter == null)
+			{
+				return "(GA) " + GetName();
+			}
+			return _converter.ToString((GenericArray)obj);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericArrayReflector.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericArrayReflector.cs
new file mode 100644
index 0000000..cf97552
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericArrayReflector.cs
@@ -0,0 +1,115 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Generic;
+
+namespace Db4objects.Db4o.Reflect.Generic
+{
+	/// <exclude></exclude>
+	public class GenericArrayReflector : IReflectArray
+	{
+		private readonly IReflectArray _delegate;
+
+		public GenericArrayReflector(GenericReflector reflector)
+		{
+			_delegate = reflector.GetDelegate().Array();
+		}
+
+		public virtual void Analyze(object obj, ArrayInfo info)
+		{
+			_delegate.Analyze(obj, info);
+		}
+
+		public virtual int[] Dimensions(object arr)
+		{
+			return _delegate.Dimensions(arr);
+		}
+
+		public virtual int Flatten(object a_shaped, int[] a_dimensions, int a_currentDimension
+			, object[] a_flat, int a_flatElement)
+		{
+			return _delegate.Flatten(a_shaped, a_dimensions, a_currentDimension, a_flat, a_flatElement
+				);
+		}
+
+		public virtual object Get(object onArray, int index)
+		{
+			if (onArray is GenericArray)
+			{
+				return ((GenericArray)onArray)._data[index];
+			}
+			return _delegate.Get(onArray, index);
+		}
+
+		public virtual IReflectClass GetComponentType(IReflectClass claxx)
+		{
+			claxx = claxx.GetDelegate();
+			if (claxx is GenericClass)
+			{
+				return claxx;
+			}
+			return _delegate.GetComponentType(claxx);
+		}
+
+		public virtual int GetLength(object array)
+		{
+			if (array is GenericArray)
+			{
+				return ((GenericArray)array).GetLength();
+			}
+			return _delegate.GetLength(array);
+		}
+
+		public virtual bool IsNDimensional(IReflectClass a_class)
+		{
+			if (a_class is GenericArrayClass)
+			{
+				return false;
+			}
+			return _delegate.IsNDimensional(a_class.GetDelegate());
+		}
+
+		public virtual object NewInstance(IReflectClass componentType, ArrayInfo info)
+		{
+			componentType = componentType.GetDelegate();
+			if (componentType is GenericClass)
+			{
+				int length = info.ElementCount();
+				return new GenericArray(((GenericClass)componentType).ArrayClass(), length);
+			}
+			return _delegate.NewInstance(componentType, info);
+		}
+
+		public virtual object NewInstance(IReflectClass componentType, int length)
+		{
+			componentType = componentType.GetDelegate();
+			if (componentType is GenericClass)
+			{
+				return new GenericArray(((GenericClass)componentType).ArrayClass(), length);
+			}
+			return _delegate.NewInstance(componentType, length);
+		}
+
+		public virtual object NewInstance(IReflectClass componentType, int[] dimensions)
+		{
+			return _delegate.NewInstance(componentType.GetDelegate(), dimensions);
+		}
+
+		public virtual void Set(object onArray, int index, object element)
+		{
+			if (onArray is GenericArray)
+			{
+				((GenericArray)onArray)._data[index] = element;
+				return;
+			}
+			_delegate.Set(onArray, index, element);
+		}
+
+		public virtual int Shape(object[] a_flat, int a_flatElement, object a_shaped, int
+			[] a_dimensions, int a_currentDimension)
+		{
+			return _delegate.Shape(a_flat, a_flatElement, a_shaped, a_dimensions, a_currentDimension
+				);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericClass.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericClass.cs
new file mode 100644
index 0000000..cd2726c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericClass.cs
@@ -0,0 +1,378 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Generic;
+
+namespace Db4objects.Db4o.Reflect.Generic
+{
+	/// <exclude></exclude>
+	public class GenericClass : IReflectClass, IDeepClone
+	{
+		private static readonly GenericField[] NoFields = new GenericField[0];
+
+		private readonly GenericReflector _reflector;
+
+		private readonly IReflectClass _delegate;
+
+		private readonly string _name;
+
+		private Db4objects.Db4o.Reflect.Generic.GenericClass _superclass;
+
+		private Db4objects.Db4o.Reflect.Generic.GenericClass _array;
+
+		private bool _isPrimitive;
+
+		private int _isCollection;
+
+		protected IGenericConverter _converter;
+
+		private GenericField[] _fields = NoFields;
+
+		private int _declaredFieldCount = -1;
+
+		private int _fieldCount = -1;
+
+		private readonly int _hashCode;
+
+		public GenericClass(GenericReflector reflector, IReflectClass delegateClass, string
+			 name, Db4objects.Db4o.Reflect.Generic.GenericClass superclass)
+		{
+			_reflector = reflector;
+			_delegate = delegateClass;
+			_name = name;
+			_superclass = superclass;
+			_hashCode = _name.GetHashCode();
+		}
+
+		public virtual Db4objects.Db4o.Reflect.Generic.GenericClass ArrayClass()
+		{
+			if (_array != null)
+			{
+				return _array;
+			}
+			_array = new GenericArrayClass(_reflector, this, _name, _superclass);
+			return _array;
+		}
+
+		public virtual object DeepClone(object obj)
+		{
+			GenericReflector reflector = (GenericReflector)obj;
+			Db4objects.Db4o.Reflect.Generic.GenericClass superClass = null;
+			if (_superclass != null)
+			{
+				_superclass = (Db4objects.Db4o.Reflect.Generic.GenericClass)reflector.ForName(_superclass
+					.GetName());
+			}
+			Db4objects.Db4o.Reflect.Generic.GenericClass ret = new Db4objects.Db4o.Reflect.Generic.GenericClass
+				(reflector, _delegate, _name, superClass);
+			GenericField[] fields = new GenericField[_fields.Length];
+			for (int i = 0; i < fields.Length; i++)
+			{
+				fields[i] = (GenericField)_fields[i].DeepClone(reflector);
+			}
+			ret.InitFields(fields);
+			return ret;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj)
+			{
+				return true;
+			}
+			if (obj == null || GetType() != obj.GetType())
+			{
+				return false;
+			}
+			Db4objects.Db4o.Reflect.Generic.GenericClass otherGC = (Db4objects.Db4o.Reflect.Generic.GenericClass
+				)obj;
+			if (_hashCode != otherGC.GetHashCode())
+			{
+				return false;
+			}
+			return _name.Equals(otherGC._name);
+		}
+
+		public virtual IReflectClass GetComponentType()
+		{
+			if (_delegate != null)
+			{
+				return _delegate.GetComponentType();
+			}
+			return null;
+		}
+
+		// TODO: consider that classes may have two fields of
+		// the same name after refactoring.
+		public virtual IReflectField GetDeclaredField(string name)
+		{
+			if (_delegate != null)
+			{
+				return _delegate.GetDeclaredField(name);
+			}
+			for (int i = 0; i < _fields.Length; i++)
+			{
+				if (_fields[i].GetName().Equals(name))
+				{
+					return _fields[i];
+				}
+			}
+			return null;
+		}
+
+		public virtual IReflectField[] GetDeclaredFields()
+		{
+			if (_delegate != null)
+			{
+				return _delegate.GetDeclaredFields();
+			}
+			return _fields;
+		}
+
+		public virtual IReflectClass GetDelegate()
+		{
+			if (_delegate != null)
+			{
+				return _delegate;
+			}
+			return this;
+		}
+
+		internal virtual int GetFieldCount()
+		{
+			if (_fieldCount != -1)
+			{
+				return _fieldCount;
+			}
+			_fieldCount = 0;
+			if (_superclass != null)
+			{
+				_fieldCount = _superclass.GetFieldCount();
+			}
+			if (_declaredFieldCount == -1)
+			{
+				_declaredFieldCount = GetDeclaredFields().Length;
+			}
+			_fieldCount += _declaredFieldCount;
+			return _fieldCount;
+		}
+
+		public virtual IReflectMethod GetMethod(string methodName, IReflectClass[] paramClasses
+			)
+		{
+			if (_delegate != null)
+			{
+				return _delegate.GetMethod(methodName, paramClasses);
+			}
+			return null;
+		}
+
+		public virtual string GetName()
+		{
+			return _name;
+		}
+
+		public virtual IReflectClass GetSuperclass()
+		{
+			if (_superclass != null)
+			{
+				return _superclass;
+			}
+			if (_delegate == null)
+			{
+				return _reflector.ForClass(typeof(object));
+			}
+			IReflectClass delegateSuperclass = _delegate.GetSuperclass();
+			if (delegateSuperclass != null)
+			{
+				_superclass = _reflector.EnsureDelegate(delegateSuperclass);
+			}
+			return _superclass;
+		}
+
+		public override int GetHashCode()
+		{
+			return _hashCode;
+		}
+
+		public virtual void InitFields(GenericField[] fields)
+		{
+			int startIndex = 0;
+			if (_superclass != null)
+			{
+				startIndex = _superclass.GetFieldCount();
+			}
+			_fields = fields;
+			for (int i = 0; i < _fields.Length; i++)
+			{
+				_fields[i].SetIndex(startIndex + i);
+			}
+		}
+
+		// TODO: Consider: Will this method still be necessary 
+		// once constructor logic is pushed into the reflectors?
+		public virtual bool IsAbstract()
+		{
+			if (_delegate != null)
+			{
+				return _delegate.IsAbstract();
+			}
+			return false;
+		}
+
+		public virtual bool IsArray()
+		{
+			if (_delegate != null)
+			{
+				return _delegate.IsArray();
+			}
+			return false;
+		}
+
+		public virtual bool IsAssignableFrom(IReflectClass subclassCandidate)
+		{
+			if (subclassCandidate == null)
+			{
+				return false;
+			}
+			if (Equals(subclassCandidate))
+			{
+				return true;
+			}
+			if (_delegate != null)
+			{
+				if (subclassCandidate is Db4objects.Db4o.Reflect.Generic.GenericClass)
+				{
+					subclassCandidate = ((Db4objects.Db4o.Reflect.Generic.GenericClass)subclassCandidate
+						).GetDelegate();
+				}
+				return _delegate.IsAssignableFrom(subclassCandidate);
+			}
+			if (!(subclassCandidate is Db4objects.Db4o.Reflect.Generic.GenericClass))
+			{
+				return false;
+			}
+			return IsAssignableFrom(subclassCandidate.GetSuperclass());
+		}
+
+		public virtual bool IsCollection()
+		{
+			if (_isCollection == 1)
+			{
+				return true;
+			}
+			if (_isCollection == -1)
+			{
+				return false;
+			}
+			_isCollection = _reflector.IsCollection(this) ? 1 : -1;
+			return IsCollection();
+		}
+
+		public virtual bool IsInstance(object candidate)
+		{
+			if (_delegate != null)
+			{
+				return _delegate.IsInstance(candidate);
+			}
+			if (!(candidate is GenericObject))
+			{
+				return false;
+			}
+			return IsAssignableFrom(((GenericObject)candidate)._class);
+		}
+
+		public virtual bool IsInterface()
+		{
+			if (_delegate != null)
+			{
+				return _delegate.IsInterface();
+			}
+			return false;
+		}
+
+		public virtual bool IsPrimitive()
+		{
+			if (_delegate != null)
+			{
+				return _delegate.IsPrimitive();
+			}
+			return _isPrimitive;
+		}
+
+		public virtual object NewInstance()
+		{
+			if (_delegate != null)
+			{
+				return _delegate.NewInstance();
+			}
+			return new GenericObject(this);
+		}
+
+		public virtual IReflector Reflector()
+		{
+			if (_delegate != null)
+			{
+				return _delegate.Reflector();
+			}
+			return _reflector;
+		}
+
+		internal virtual void SetConverter(IGenericConverter converter)
+		{
+			_converter = converter;
+		}
+
+		internal virtual void SetDeclaredFieldCount(int count)
+		{
+			_declaredFieldCount = count;
+		}
+
+		internal virtual void SetPrimitive()
+		{
+			_isPrimitive = true;
+		}
+
+		public override string ToString()
+		{
+			return "GenericClass " + _name;
+		}
+
+		public virtual string ToString(object obj)
+		{
+			if (_converter == null)
+			{
+				return "(G) " + GetName();
+			}
+			return _converter.ToString((GenericObject)obj);
+		}
+
+		public virtual bool EnsureCanBeInstantiated()
+		{
+			if (_delegate != null)
+			{
+				return _delegate.EnsureCanBeInstantiated();
+			}
+			return true;
+		}
+
+		public virtual object NullValue()
+		{
+			if (_delegate == null)
+			{
+				return null;
+			}
+			return _delegate.NullValue();
+		}
+
+		public virtual bool IsImmutable()
+		{
+			if (_delegate != null)
+			{
+				return _delegate.IsImmutable();
+			}
+			return IsPrimitive();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericClassBuilder.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericClassBuilder.cs
new file mode 100644
index 0000000..d96e288
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericClassBuilder.cs
@@ -0,0 +1,53 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Generic;
+
+namespace Db4objects.Db4o.Reflect.Generic
+{
+	/// <exclude></exclude>
+	public class GenericClassBuilder : IReflectClassBuilder
+	{
+		private GenericReflector _reflector;
+
+		private IReflector _delegate;
+
+		public GenericClassBuilder(GenericReflector reflector, IReflector delegate_) : base
+			()
+		{
+			_reflector = reflector;
+			_delegate = delegate_;
+		}
+
+		public virtual IReflectClass CreateClass(string name, IReflectClass superClass, int
+			 fieldCount)
+		{
+			IReflectClass nativeClass = _delegate.ForName(name);
+			GenericClass clazz = new GenericClass(_reflector, nativeClass, name, (GenericClass
+				)superClass);
+			clazz.SetDeclaredFieldCount(fieldCount);
+			return clazz;
+		}
+
+		public virtual IReflectField CreateField(IReflectClass parentType, string fieldName
+			, IReflectClass fieldType, bool isVirtual, bool isPrimitive, bool isArray, bool 
+			isNArray)
+		{
+			if (isVirtual)
+			{
+				return new GenericVirtualField(fieldName);
+			}
+			return new GenericField(fieldName, fieldType, isPrimitive);
+		}
+
+		public virtual void InitFields(IReflectClass clazz, IReflectField[] fields)
+		{
+			((GenericClass)clazz).InitFields((GenericField[])fields);
+		}
+
+		public virtual IReflectField[] FieldArray(int length)
+		{
+			return new GenericField[length];
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericField.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericField.cs
new file mode 100644
index 0000000..5c0c2a0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericField.cs
@@ -0,0 +1,99 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Generic;
+
+namespace Db4objects.Db4o.Reflect.Generic
+{
+	/// <exclude></exclude>
+	public class GenericField : IReflectField, IDeepClone
+	{
+		private readonly string _name;
+
+		private readonly GenericClass _type;
+
+		private readonly bool _primitive;
+
+		private int _index = -1;
+
+		public GenericField(string name, IReflectClass clazz, bool primitive)
+		{
+			_name = name;
+			_type = (GenericClass)clazz;
+			_primitive = primitive;
+		}
+
+		public virtual object DeepClone(object obj)
+		{
+			IReflector reflector = (IReflector)obj;
+			IReflectClass newReflectClass = null;
+			if (_type != null)
+			{
+				newReflectClass = reflector.ForName(_type.GetName());
+			}
+			return new Db4objects.Db4o.Reflect.Generic.GenericField(_name, newReflectClass, _primitive
+				);
+		}
+
+		public virtual object Get(object onObject)
+		{
+			//TODO Consider: Do we need to check that onObject is an instance of the DataClass this field is a member of? 
+			return ((GenericObject)onObject).Get(_index);
+		}
+
+		public virtual string GetName()
+		{
+			return _name;
+		}
+
+		public virtual IReflectClass GetFieldType()
+		{
+			return _type;
+		}
+
+		public virtual bool IsPublic()
+		{
+			return true;
+		}
+
+		public virtual bool IsPrimitive()
+		{
+			return _primitive;
+		}
+
+		public virtual bool IsStatic()
+		{
+			//FIXME Consider static fields.
+			return false;
+		}
+
+		public virtual bool IsTransient()
+		{
+			return false;
+		}
+
+		public virtual void Set(object onObject, object value)
+		{
+			// FIXME: Consider enabling type checking.
+			// The following will fail with arrays.
+			// if (!_type.isInstance(value)) throw new RuntimeException(); //TODO Consider: is this checking really necessary?
+			((GenericObject)onObject).Set(_index, value);
+		}
+
+		internal virtual void SetIndex(int index)
+		{
+			_index = index;
+		}
+
+		public virtual object IndexEntry(object orig)
+		{
+			return orig;
+		}
+
+		public virtual IReflectClass IndexType()
+		{
+			return GetFieldType();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericObject.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericObject.cs
new file mode 100644
index 0000000..c8bae5c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericObject.cs
@@ -0,0 +1,62 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Reflect.Generic;
+
+namespace Db4objects.Db4o.Reflect.Generic
+{
+	/// <exclude></exclude>
+	public class GenericObject : IComparable
+	{
+		internal readonly GenericClass _class;
+
+		private object[] _values;
+
+		public GenericObject(GenericClass clazz)
+		{
+			_class = clazz;
+		}
+
+		private void EnsureValuesInitialized()
+		{
+			if (_values == null)
+			{
+				_values = new object[_class.GetFieldCount()];
+			}
+		}
+
+		public virtual void Set(int index, object value)
+		{
+			EnsureValuesInitialized();
+			_values[index] = value;
+		}
+
+		/// <param name="index"></param>
+		/// <returns>the value of the field at index, based on the fields obtained GenericClass.getDeclaredFields
+		/// 	</returns>
+		public virtual object Get(int index)
+		{
+			EnsureValuesInitialized();
+			return _values[index];
+		}
+
+		public override string ToString()
+		{
+			if (_class == null)
+			{
+				return base.ToString();
+			}
+			return _class.ToString(this);
+		}
+
+		public virtual GenericClass GetGenericClass()
+		{
+			return _class;
+		}
+
+		public virtual int CompareTo(object o)
+		{
+			return 0;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericReflector.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericReflector.cs
new file mode 100644
index 0000000..4f02dd4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericReflector.cs
@@ -0,0 +1,501 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Reflect.Generic;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Generic;
+
+namespace Db4objects.Db4o.Reflect.Generic
+{
+	/// <summary>
+	/// db4o provides GenericReflector as a wrapper around specific
+	/// reflector (delegate).
+	/// </summary>
+	/// <remarks>
+	/// db4o provides GenericReflector as a wrapper around specific
+	/// reflector (delegate). GenericReflector is set when an
+	/// ObjectContainer is opened. All subsequent reflector
+	/// calls are routed through this interface.<br /><br />
+	/// An instance of GenericReflector can be obtained through
+	/// <see cref="Db4objects.Db4o.Ext.IExtObjectContainer.Reflector()">Db4objects.Db4o.Ext.IExtObjectContainer.Reflector()
+	/// 	</see>
+	/// .<br /><br />
+	/// GenericReflector keeps list of known classes in memory.
+	/// When the GenericReflector is called, it first checks its list of
+	/// known classes. If the class cannot be found, the task is
+	/// transferred to the delegate reflector. If the delegate fails as
+	/// well, generic objects are created, which hold simulated
+	/// "field values" in an array of objects.<br /><br />
+	/// Generic reflector makes possible the following usecases:<ul>
+	/// <li>running a db4o server without deploying application classes;</li>
+	/// <li>running db4o on Java dialects without reflection (J2ME CLDC, MIDP);</li>
+	/// <li>easier access to stored objects where classes or fields are not available;</li>
+	/// <li>running refactorings in the reflector;</li>
+	/// <li>building interfaces to db4o from any programming language.</li></ul>
+	/// <br /><br />
+	/// One of the live usecases is ObjectManager, which uses GenericReflector
+	/// to read C# objects from Java.
+	/// </remarks>
+	public class GenericReflector : IReflector, IDeepClone
+	{
+		private KnownClassesRepository _repository;
+
+		private IReflector _delegate;
+
+		private GenericArrayReflector _array;
+
+		private Collection4 _collectionPredicates = new Collection4();
+
+		private readonly Hashtable4 _classByClass = new Hashtable4();
+
+		private Transaction _trans;
+
+		private ObjectContainerBase _stream;
+
+		/// <summary>Creates an instance of GenericReflector</summary>
+		/// <param name="trans">transaction</param>
+		/// <param name="delegateReflector">
+		/// delegate reflector,
+		/// providing specific reflector functionality. For example
+		/// </param>
+		public GenericReflector(Transaction trans, IReflector delegateReflector)
+		{
+			// todo: Why have this when there is already the _repository by name? Redundant
+			_repository = new KnownClassesRepository(new GenericClassBuilder(this, delegateReflector
+				));
+			SetTransaction(trans);
+			_delegate = delegateReflector;
+			if (_delegate != null)
+			{
+				_delegate.SetParent(this);
+			}
+		}
+
+		public GenericReflector(IReflector delegateReflector) : this(null, delegateReflector
+			)
+		{
+		}
+
+		/// <summary>Creates a clone of provided object</summary>
+		/// <param name="obj">object to copy</param>
+		/// <returns>copy of the submitted object</returns>
+		public virtual object DeepClone(object obj)
+		{
+			Db4objects.Db4o.Reflect.Generic.GenericReflector myClone = new Db4objects.Db4o.Reflect.Generic.GenericReflector
+				(null, (IReflector)_delegate.DeepClone(this));
+			myClone._collectionPredicates = (Collection4)_collectionPredicates.DeepClone(myClone
+				);
+			// Interesting, adding the following messes things up.
+			// Keep the code, since it may make sense to carry the
+			// global reflectors into a running db4o session.
+			//        Iterator4 i = _classes.iterator();
+			//        while(i.hasNext()){
+			//            GenericClass clazz = (GenericClass)i.next();
+			//            clazz = (GenericClass)clazz.deepClone(myClone);
+			//            myClone._classByName.put(clazz.getName(), clazz);
+			//            myClone._classes.add(clazz);
+			//        }
+			return myClone;
+		}
+
+		internal virtual ObjectContainerBase GetStream()
+		{
+			return _stream;
+		}
+
+		/// <summary>If there is a transaction assosiated with the current refector.</summary>
+		/// <remarks>If there is a transaction assosiated with the current refector.</remarks>
+		/// <returns>true if there is a transaction assosiated with the current refector.</returns>
+		public virtual bool HasTransaction()
+		{
+			return _trans != null;
+		}
+
+		/// <summary>Associated a transaction with the current reflector.</summary>
+		/// <remarks>Associated a transaction with the current reflector.</remarks>
+		/// <param name="trans"></param>
+		public virtual void SetTransaction(Transaction trans)
+		{
+			if (trans != null)
+			{
+				_trans = trans;
+				_stream = trans.Container();
+			}
+			_repository.SetTransaction(trans);
+		}
+
+		/// <returns>generic reflect array instance.</returns>
+		public virtual IReflectArray Array()
+		{
+			if (_array == null)
+			{
+				_array = new GenericArrayReflector(this);
+			}
+			return _array;
+		}
+
+		internal virtual Db4objects.Db4o.Reflect.Generic.GenericClass EnsureDelegate(IReflectClass
+			 clazz)
+		{
+			if (clazz == null)
+			{
+				return null;
+			}
+			Db4objects.Db4o.Reflect.Generic.GenericClass claxx = (Db4objects.Db4o.Reflect.Generic.GenericClass
+				)_repository.LookupByName(clazz.GetName());
+			if (claxx == null)
+			{
+				//  We don't have to worry about the superclass, it can be null
+				//  because handling is delegated anyway
+				claxx = GenericClass(clazz);
+				_repository.Register(claxx);
+			}
+			return claxx;
+		}
+
+		private Db4objects.Db4o.Reflect.Generic.GenericClass GenericClass(IReflectClass clazz
+			)
+		{
+			Db4objects.Db4o.Reflect.Generic.GenericClass ret;
+			string name = clazz.GetName();
+			if (name.Equals(ReflectPlatform.FullyQualifiedName(typeof(GenericArray))))
+			{
+				// special case, comparing name because can't compare class == class directly with ReflectClass
+				ret = new GenericArrayClass(this, clazz, name, null);
+			}
+			else
+			{
+				ret = new Db4objects.Db4o.Reflect.Generic.GenericClass(this, clazz, name, null);
+			}
+			return ret;
+		}
+
+		/// <summary>Returns a ReflectClass instance for the specified class</summary>
+		/// <param name="clazz">class</param>
+		/// <returns>a ReflectClass instance for the specified class</returns>
+		/// <seealso cref="Db4objects.Db4o.Reflect.IReflectClass">Db4objects.Db4o.Reflect.IReflectClass
+		/// 	</seealso>
+		public virtual IReflectClass ForClass(Type clazz)
+		{
+			if (clazz == null)
+			{
+				return null;
+			}
+			IReflectClass claxx = (IReflectClass)_classByClass.Get(clazz);
+			if (claxx != null)
+			{
+				return claxx;
+			}
+			if (!clazz.IsArray && ReflectPlatform.IsNamedClass(clazz))
+			{
+				claxx = ForName(ReflectPlatform.FullyQualifiedName(clazz));
+				if (claxx != null)
+				{
+					_classByClass.Put(clazz, claxx);
+					return claxx;
+				}
+			}
+			claxx = _delegate.ForClass(clazz);
+			if (claxx == null)
+			{
+				return null;
+			}
+			claxx = EnsureDelegate(claxx);
+			_classByClass.Put(clazz, claxx);
+			return claxx;
+		}
+
+		/// <summary>Returns a ReflectClass instance for the specified class name</summary>
+		/// <param name="className">class name</param>
+		/// <returns>a ReflectClass instance for the specified class name</returns>
+		/// <seealso cref="Db4objects.Db4o.Reflect.IReflectClass">Db4objects.Db4o.Reflect.IReflectClass
+		/// 	</seealso>
+		public virtual IReflectClass ForName(string className)
+		{
+			return ((IReflectClass)WithLock(new _IClosure4_190(this, className)));
+		}
+
+		private sealed class _IClosure4_190 : IClosure4
+		{
+			public _IClosure4_190(GenericReflector _enclosing, string className)
+			{
+				this._enclosing = _enclosing;
+				this.className = className;
+			}
+
+			public object Run()
+			{
+				IReflectClass clazz = this._enclosing._repository.LookupByName(className);
+				if (clazz != null)
+				{
+					return clazz;
+				}
+				clazz = this._enclosing._delegate.ForName(className);
+				if (clazz != null)
+				{
+					return this._enclosing.EnsureDelegate(clazz);
+				}
+				return this._enclosing._repository.ForName(className);
+			}
+
+			private readonly GenericReflector _enclosing;
+
+			private readonly string className;
+		}
+
+		/// <summary>Returns a ReflectClass instance for the specified class object</summary>
+		/// <param name="obj">class object</param>
+		/// <returns>a ReflectClass instance for the specified class object</returns>
+		/// <seealso cref="Db4objects.Db4o.Reflect.IReflectClass">Db4objects.Db4o.Reflect.IReflectClass
+		/// 	</seealso>
+		public virtual IReflectClass ForObject(object obj)
+		{
+			if (obj is GenericObject)
+			{
+				return ForGenericObject((GenericObject)obj);
+			}
+			if (obj is GenericArray)
+			{
+				return ((GenericArray)obj)._clazz;
+			}
+			return _delegate.ForObject(obj);
+		}
+
+		private IReflectClass ForGenericObject(GenericObject genericObject)
+		{
+			Db4objects.Db4o.Reflect.Generic.GenericClass claxx = genericObject._class;
+			if (claxx == null)
+			{
+				throw new InvalidOperationException();
+			}
+			string name = claxx.GetName();
+			if (name == null)
+			{
+				throw new InvalidOperationException();
+			}
+			Db4objects.Db4o.Reflect.Generic.GenericClass existingClass = (Db4objects.Db4o.Reflect.Generic.GenericClass
+				)ForName(name);
+			if (existingClass == null)
+			{
+				_repository.Register(claxx);
+				return claxx;
+			}
+			// TODO: Using .equals() here would be more consistent with 
+			//       the equals() method in GenericClass.
+			if (existingClass != claxx)
+			{
+				throw new InvalidOperationException();
+			}
+			return claxx;
+		}
+
+		/// <summary>Returns delegate reflector</summary>
+		/// <returns>delegate reflector</returns>
+		public virtual IReflector GetDelegate()
+		{
+			return _delegate;
+		}
+
+		/// <summary>Determines if a candidate ReflectClass is a collection</summary>
+		/// <param name="candidate">candidate ReflectClass</param>
+		/// <returns>true  if a candidate ReflectClass is a collection.</returns>
+		public virtual bool IsCollection(IReflectClass candidate)
+		{
+			//candidate = candidate.getDelegate(); 
+			IEnumerator i = _collectionPredicates.GetEnumerator();
+			while (i.MoveNext())
+			{
+				if (((IReflectClassPredicate)i.Current).Match(candidate))
+				{
+					return true;
+				}
+			}
+			return _delegate.IsCollection(candidate.GetDelegate());
+		}
+
+		//TODO: will need knowledge for .NET collections here
+		// possibility: call registercollection with strings
+		/// <summary>Register a class as a collection</summary>
+		/// <param name="clazz">class to be registered</param>
+		public virtual void RegisterCollection(Type clazz)
+		{
+			RegisterCollection(ClassPredicate(clazz));
+		}
+
+		/// <summary>Register a predicate as a collection</summary>
+		/// <param name="predicate">predicate to be registered</param>
+		public virtual void RegisterCollection(IReflectClassPredicate predicate)
+		{
+			_collectionPredicates.Add(predicate);
+		}
+
+		private IReflectClassPredicate ClassPredicate(Type clazz)
+		{
+			IReflectClass collectionClass = ForClass(clazz);
+			IReflectClassPredicate predicate = new _IReflectClassPredicate_290(collectionClass
+				);
+			return predicate;
+		}
+
+		private sealed class _IReflectClassPredicate_290 : IReflectClassPredicate
+		{
+			public _IReflectClassPredicate_290(IReflectClass collectionClass)
+			{
+				this.collectionClass = collectionClass;
+			}
+
+			public bool Match(IReflectClass candidate)
+			{
+				return collectionClass.IsAssignableFrom(candidate);
+			}
+
+			private readonly IReflectClass collectionClass;
+		}
+
+		/// <summary>Register a class</summary>
+		/// <param name="clazz">class</param>
+		public virtual void Register(Db4objects.Db4o.Reflect.Generic.GenericClass clazz)
+		{
+			WithLock(new _IClosure4_303(this, clazz));
+		}
+
+		private sealed class _IClosure4_303 : IClosure4
+		{
+			public _IClosure4_303(GenericReflector _enclosing, Db4objects.Db4o.Reflect.Generic.GenericClass
+				 clazz)
+			{
+				this._enclosing = _enclosing;
+				this.clazz = clazz;
+			}
+
+			public object Run()
+			{
+				string name = clazz.GetName();
+				if (this._enclosing._repository.LookupByName(name) == null)
+				{
+					this._enclosing._repository.Register(clazz);
+				}
+				return null;
+			}
+
+			private readonly GenericReflector _enclosing;
+
+			private readonly Db4objects.Db4o.Reflect.Generic.GenericClass clazz;
+		}
+
+		/// <summary>Returns an array of classes known to the reflector</summary>
+		/// <returns>an array of classes known to the reflector</returns>
+		public virtual IReflectClass[] KnownClasses()
+		{
+			return ((IReflectClass[])WithLock(new _IClosure4_319(this)));
+		}
+
+		private sealed class _IClosure4_319 : IClosure4
+		{
+			public _IClosure4_319(GenericReflector _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public object Run()
+			{
+				return new KnownClassesCollector(this._enclosing._stream, this._enclosing._repository
+					).Collect();
+			}
+
+			private readonly GenericReflector _enclosing;
+		}
+
+		/// <summary>Registers primitive class</summary>
+		/// <param name="id">class id</param>
+		/// <param name="name">class name</param>
+		/// <param name="converter">class converter</param>
+		public virtual void RegisterPrimitiveClass(int id, string name, IGenericConverter
+			 converter)
+		{
+			WithLock(new _IClosure4_333(this, id, converter, name));
+		}
+
+		private sealed class _IClosure4_333 : IClosure4
+		{
+			public _IClosure4_333(GenericReflector _enclosing, int id, IGenericConverter converter
+				, string name)
+			{
+				this._enclosing = _enclosing;
+				this.id = id;
+				this.converter = converter;
+				this.name = name;
+			}
+
+			public object Run()
+			{
+				Db4objects.Db4o.Reflect.Generic.GenericClass existing = (Db4objects.Db4o.Reflect.Generic.GenericClass
+					)this._enclosing._repository.LookupByID(id);
+				if (existing != null)
+				{
+					if (null != converter)
+					{
+					}
+					else
+					{
+						//						existing.setSecondClass();
+						existing.SetConverter(null);
+					}
+					return null;
+				}
+				IReflectClass clazz = this._enclosing._delegate.ForName(name);
+				Db4objects.Db4o.Reflect.Generic.GenericClass claxx = null;
+				if (clazz != null)
+				{
+					claxx = this._enclosing.EnsureDelegate(clazz);
+				}
+				else
+				{
+					claxx = new Db4objects.Db4o.Reflect.Generic.GenericClass(this._enclosing, null, name
+						, null);
+					this._enclosing.Register(claxx);
+					claxx.InitFields(new GenericField[] { new GenericField(null, null, true) });
+					claxx.SetConverter(converter);
+				}
+				//			    claxx.setSecondClass();
+				claxx.SetPrimitive();
+				this._enclosing._repository.Register(id, claxx);
+				return null;
+			}
+
+			private readonly GenericReflector _enclosing;
+
+			private readonly int id;
+
+			private readonly IGenericConverter converter;
+
+			private readonly string name;
+		}
+
+		/// <summary>method stub: generic reflector does not have a parent</summary>
+		public virtual void SetParent(IReflector reflector)
+		{
+		}
+
+		// do nothing, the generic reflector does not have a parant
+		public virtual void Configuration(IReflectorConfiguration config)
+		{
+			if (_delegate != null)
+			{
+				_delegate.Configuration(config);
+			}
+		}
+
+		private object WithLock(IClosure4 block)
+		{
+			if (_stream == null || _stream.IsClosed())
+			{
+				return block.Run();
+			}
+			return _stream.SyncExec(block);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericVirtualField.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericVirtualField.cs
new file mode 100644
index 0000000..9666448
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/GenericVirtualField.cs
@@ -0,0 +1,50 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Generic;
+
+namespace Db4objects.Db4o.Reflect.Generic
+{
+	/// <exclude></exclude>
+	public class GenericVirtualField : GenericField
+	{
+		public GenericVirtualField(string name) : base(name, null, false)
+		{
+		}
+
+		public override object DeepClone(object obj)
+		{
+			return new Db4objects.Db4o.Reflect.Generic.GenericVirtualField(GetName());
+		}
+
+		public override object Get(object onObject)
+		{
+			return null;
+		}
+
+		public override IReflectClass GetFieldType()
+		{
+			return null;
+		}
+
+		public override bool IsPublic()
+		{
+			return false;
+		}
+
+		public override bool IsStatic()
+		{
+			return true;
+		}
+
+		public override bool IsTransient()
+		{
+			return true;
+		}
+
+		public override void Set(object onObject, object value)
+		{
+		}
+		// do nothing
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/IGenericConverter.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/IGenericConverter.cs
new file mode 100644
index 0000000..2fcc461
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/IGenericConverter.cs
@@ -0,0 +1,14 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect.Generic;
+
+namespace Db4objects.Db4o.Reflect.Generic
+{
+	/// <exclude></exclude>
+	public interface IGenericConverter
+	{
+		string ToString(GenericObject obj);
+
+		string ToString(GenericArray array);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/IReflectClassBuilder.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/IReflectClassBuilder.cs
new file mode 100644
index 0000000..65b407c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/IReflectClassBuilder.cs
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Reflect.Generic
+{
+	/// <exclude></exclude>
+	public interface IReflectClassBuilder
+	{
+		IReflectClass CreateClass(string name, IReflectClass superClass, int fieldCount);
+
+		IReflectField CreateField(IReflectClass parentType, string fieldName, IReflectClass
+			 fieldType, bool isVirtual, bool isPrimitive, bool isArray, bool isNArray);
+
+		void InitFields(IReflectClass clazz, IReflectField[] fields);
+
+		IReflectField[] FieldArray(int length);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/KnownClassesRepository.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/KnownClassesRepository.cs
new file mode 100644
index 0000000..e3824db
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/Generic/KnownClassesRepository.cs
@@ -0,0 +1,373 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Generic;
+
+namespace Db4objects.Db4o.Reflect.Generic
+{
+	/// <exclude></exclude>
+	public class KnownClassesRepository
+	{
+		private static readonly Hashtable4 Primitives;
+
+		static KnownClassesRepository()
+		{
+			Primitives = new Hashtable4();
+			Type[] primitiveArray = Platform4.PrimitiveTypes();
+			for (int primitiveIndex = 0; primitiveIndex < primitiveArray.Length; ++primitiveIndex)
+			{
+				Type primitive = primitiveArray[primitiveIndex];
+				RegisterPrimitive(primitive);
+			}
+		}
+
+		private static void RegisterPrimitive(Type primitive)
+		{
+			Primitives.Put(ReflectPlatform.FullyQualifiedName(Platform4.NullableTypeFor(primitive
+				)), primitive);
+		}
+
+		private ObjectContainerBase _stream;
+
+		private Transaction _trans;
+
+		private IReflectClassBuilder _builder;
+
+		private readonly ListenerRegistry _listeners = ListenerRegistry.NewInstance();
+
+		private readonly Hashtable4 _classByName = new Hashtable4();
+
+		private readonly Hashtable4 _classByID = new Hashtable4();
+
+		private Collection4 _pendingClasses = new Collection4();
+
+		private readonly Collection4 _classes = new Collection4();
+
+		public KnownClassesRepository(IReflectClassBuilder builder)
+		{
+			_builder = builder;
+		}
+
+		public virtual void SetTransaction(Transaction trans)
+		{
+			if (trans != null)
+			{
+				_trans = trans;
+				_stream = trans.Container();
+			}
+		}
+
+		public virtual void Register(IReflectClass clazz)
+		{
+			Register(clazz.GetName(), clazz);
+		}
+
+		public virtual IReflectClass ForID(int id)
+		{
+			lock (_stream.Lock())
+			{
+				if (_stream.Handlers.IsSystemHandler(id))
+				{
+					return _stream.Handlers.ClassForID(id);
+				}
+				return EnsureClassAvailability(id);
+			}
+		}
+
+		public virtual IReflectClass ForName(string className)
+		{
+			IReflectClass clazz = LookupByName(className);
+			if (clazz != null)
+			{
+				return clazz;
+			}
+			if (_stream == null)
+			{
+				return null;
+			}
+			lock (_stream.Lock())
+			{
+				if (_stream.ClassCollection() == null)
+				{
+					return null;
+				}
+				int classID = _stream.ClassMetadataIdForName(className);
+				if (classID <= 0)
+				{
+					return null;
+				}
+				return InitializeClass(classID, className);
+			}
+		}
+
+		private IReflectClass InitializeClass(int classID, string className)
+		{
+			IReflectClass newClazz = EnsureClassInitialised(classID);
+			_classByName.Put(className, newClazz);
+			return newClazz;
+		}
+
+		private void ReadAll()
+		{
+			ForEachClassId(new _IProcedure4_102(this));
+			ForEachClassId(new _IProcedure4_105(this));
+		}
+
+		private sealed class _IProcedure4_102 : IProcedure4
+		{
+			public _IProcedure4_102(KnownClassesRepository _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Apply(object id)
+			{
+				this._enclosing.EnsureClassAvailability((((int)id)));
+			}
+
+			private readonly KnownClassesRepository _enclosing;
+		}
+
+		private sealed class _IProcedure4_105 : IProcedure4
+		{
+			public _IProcedure4_105(KnownClassesRepository _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Apply(object id)
+			{
+				this._enclosing.EnsureClassRead((((int)id)));
+			}
+
+			private readonly KnownClassesRepository _enclosing;
+		}
+
+		private void ForEachClassId(IProcedure4 procedure)
+		{
+			for (IEnumerator ids = _stream.ClassCollection().Ids(); ids.MoveNext(); )
+			{
+				procedure.Apply((int)ids.Current);
+			}
+		}
+
+		private IReflectClass EnsureClassAvailability(int id)
+		{
+			if (id == 0)
+			{
+				return null;
+			}
+			IReflectClass ret = (IReflectClass)_classByID.Get(id);
+			if (ret != null)
+			{
+				return ret;
+			}
+			ByteArrayBuffer classreader = _stream.ReadStatefulBufferById(_trans, id);
+			ClassMarshaller marshaller = MarshallerFamily()._class;
+			RawClassSpec spec = marshaller.ReadSpec(_trans, classreader);
+			string className = spec.Name();
+			ret = LookupByName(className);
+			if (ret != null)
+			{
+				_classByID.Put(id, ret);
+				_pendingClasses.Add(id);
+				return ret;
+			}
+			ReportMissingClass(className);
+			ret = _builder.CreateClass(className, EnsureClassAvailability(spec.SuperClassID()
+				), spec.NumFields());
+			// step 1 only add to _classByID, keep the class out of _classByName and _classes
+			_classByID.Put(id, ret);
+			_pendingClasses.Add(id);
+			return ret;
+		}
+
+		private void ReportMissingClass(string className)
+		{
+			_stream.Handlers.DiagnosticProcessor().ClassMissed(className);
+		}
+
+		private void EnsureClassRead(int id)
+		{
+			IReflectClass clazz = LookupByID(id);
+			ByteArrayBuffer classreader = _stream.ReadStatefulBufferById(_trans, id);
+			ClassMarshaller classMarshaller = MarshallerFamily()._class;
+			RawClassSpec classInfo = classMarshaller.ReadSpec(_trans, classreader);
+			string className = classInfo.Name();
+			// Having the class in the _classByName Map for now indicates
+			// that the class is fully read. This is breakable if we start
+			// returning GenericClass'es in other methods like forName
+			// even if a native class has not been found
+			if (LookupByName(className) != null)
+			{
+				return;
+			}
+			// step 2 add the class to _classByName and _classes to denote reading is completed
+			Register(className, clazz);
+			int numFields = classInfo.NumFields();
+			IReflectField[] fields = _builder.FieldArray(numFields);
+			IFieldMarshaller fieldMarshaller = MarshallerFamily()._field;
+			for (int i = 0; i < numFields; i++)
+			{
+				RawFieldSpec fieldInfo = fieldMarshaller.ReadSpec(_stream, classreader);
+				string fieldName = fieldInfo.Name();
+				IReflectClass fieldClass = ReflectClassForFieldSpec(fieldInfo, _stream.Reflector(
+					));
+				if (null == fieldClass && (fieldInfo.IsField() && !fieldInfo.IsVirtual()))
+				{
+					throw new InvalidOperationException("Could not read field type for '" + className
+						 + "." + fieldName + "'");
+				}
+				fields[i] = _builder.CreateField(clazz, fieldName, fieldClass, fieldInfo.IsVirtual
+					(), fieldInfo.IsPrimitive(), fieldInfo.IsArray(), fieldInfo.IsNArray());
+			}
+			_builder.InitFields(clazz, fields);
+		}
+
+		private void Register(string className, IReflectClass clazz)
+		{
+			if (LookupByName(className) != null)
+			{
+				throw new ArgumentException();
+			}
+			_classByName.Put(className, clazz);
+			_classes.Add(clazz);
+			_listeners.NotifyListeners(clazz);
+		}
+
+		private IReflectClass ReflectClassForFieldSpec(RawFieldSpec fieldInfo, IReflector
+			 reflector)
+		{
+			if (fieldInfo.IsVirtualField())
+			{
+				return VirtualFieldByName(fieldInfo.Name()).ClassReflector(reflector);
+			}
+			int fieldTypeID = fieldInfo.FieldTypeID();
+			switch (fieldTypeID)
+			{
+				case Handlers4.UntypedId:
+				{
+					// need to take care of special handlers here
+					return ObjectClass();
+				}
+
+				case Handlers4.AnyArrayId:
+				{
+					return ArrayClass(ObjectClass());
+				}
+
+				default:
+				{
+					IReflectClass fieldClass = ForID(fieldTypeID);
+					if (null != fieldClass)
+					{
+						return NormalizeFieldClass(fieldInfo, fieldClass);
+					}
+					break;
+					break;
+				}
+			}
+			return null;
+		}
+
+		private IReflectClass NormalizeFieldClass(RawFieldSpec fieldInfo, IReflectClass fieldClass
+			)
+		{
+			// TODO: why the following line is necessary?
+			IReflectClass theClass = _stream.Reflector().ForName(fieldClass.GetName());
+			if (fieldInfo.IsPrimitive())
+			{
+				theClass = PrimitiveClass(theClass);
+			}
+			if (fieldInfo.IsArray())
+			{
+				theClass = ArrayClass(theClass);
+			}
+			return theClass;
+		}
+
+		private IReflectClass ObjectClass()
+		{
+			return _stream.Reflector().ForClass(typeof(object));
+		}
+
+		private VirtualFieldMetadata VirtualFieldByName(string fieldName)
+		{
+			return _stream.Handlers.VirtualFieldByName(fieldName);
+		}
+
+		private Db4objects.Db4o.Internal.Marshall.MarshallerFamily MarshallerFamily()
+		{
+			return Db4objects.Db4o.Internal.Marshall.MarshallerFamily.ForConverterVersion(_stream
+				.ConverterVersion());
+		}
+
+		private IReflectClass EnsureClassInitialised(int id)
+		{
+			IReflectClass ret = EnsureClassAvailability(id);
+			while (_pendingClasses.Size() > 0)
+			{
+				Collection4 pending = _pendingClasses;
+				_pendingClasses = new Collection4();
+				IEnumerator i = pending.GetEnumerator();
+				while (i.MoveNext())
+				{
+					EnsureClassRead(((int)i.Current));
+				}
+			}
+			return ret;
+		}
+
+		public virtual IEnumerator Classes()
+		{
+			ReadAll();
+			return _classes.GetEnumerator();
+		}
+
+		public virtual void Register(int id, IReflectClass clazz)
+		{
+			_classByID.Put(id, clazz);
+		}
+
+		public virtual IReflectClass LookupByID(int id)
+		{
+			return (IReflectClass)_classByID.Get(id);
+		}
+
+		public virtual IReflectClass LookupByName(string name)
+		{
+			return (IReflectClass)_classByName.Get(name);
+		}
+
+		private IReflectClass ArrayClass(IReflectClass clazz)
+		{
+			object proto = clazz.Reflector().Array().NewInstance(clazz, 0);
+			return clazz.Reflector().ForObject(proto);
+		}
+
+		private IReflectClass PrimitiveClass(IReflectClass baseClass)
+		{
+			Type primitive = (Type)Primitives.Get(baseClass.GetName());
+			if (primitive != null)
+			{
+				return baseClass.Reflector().ForClass(primitive);
+			}
+			return baseClass;
+		}
+
+		public virtual void AddListener(IListener4 listener)
+		{
+			_listeners.Register(listener);
+		}
+
+		public virtual void RemoveListener(IListener4 listener)
+		{
+			_listeners.Remove(listener);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectArray.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectArray.cs
new file mode 100644
index 0000000..1b7ef13
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectArray.cs
@@ -0,0 +1,41 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Reflect
+{
+	/// <summary>Reflection Array representation.</summary>
+	/// <remarks>
+	/// Reflection Array representation
+	/// <br/><br/>See documentation for System.Reflection API.
+	/// </remarks>
+	/// <seealso cref="IReflector">IReflector</seealso>
+	public interface IReflectArray
+	{
+		void Analyze(object obj, ArrayInfo info);
+
+		int[] Dimensions(object arr);
+
+		int Flatten(object a_shaped, int[] a_dimensions, int a_currentDimension, object[]
+			 a_flat, int a_flatElement);
+
+		object Get(object onArray, int index);
+
+		IReflectClass GetComponentType(IReflectClass a_class);
+
+		int GetLength(object array);
+
+		bool IsNDimensional(IReflectClass a_class);
+
+		object NewInstance(IReflectClass componentType, ArrayInfo info);
+
+		object NewInstance(IReflectClass componentType, int length);
+
+		object NewInstance(IReflectClass componentType, int[] dimensions);
+
+		void Set(object onArray, int index, object element);
+
+		int Shape(object[] a_flat, int a_flatElement, object a_shaped, int[] a_dimensions
+			, int a_currentDimension);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectClass.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectClass.cs
new file mode 100644
index 0000000..1bcfe1c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectClass.cs
@@ -0,0 +1,82 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Reflect
+{
+	/// <summary>Reflection Class representation.</summary>
+	/// <remarks>
+	/// Reflection Class representation
+	/// <br/><br/>See documentation for System.Reflection API.
+	/// </remarks>
+	/// <seealso cref="IReflector">IReflector</seealso>
+	public interface IReflectClass
+	{
+		IReflectClass GetComponentType();
+
+		IReflectField[] GetDeclaredFields();
+
+		IReflectField GetDeclaredField(string name);
+
+		/// <summary>Returns the ReflectClass instance being delegated to.</summary>
+		/// <remarks>
+		/// Returns the ReflectClass instance being delegated to.
+		/// If there's no delegation it should return this.
+		/// </remarks>
+		/// <returns>delegate or this</returns>
+		IReflectClass GetDelegate();
+
+		IReflectMethod GetMethod(string methodName, IReflectClass[] paramClasses);
+
+		string GetName();
+
+		IReflectClass GetSuperclass();
+
+		bool IsAbstract();
+
+		bool IsArray();
+
+		bool IsAssignableFrom(IReflectClass type);
+
+		bool IsCollection();
+
+		bool IsInstance(object obj);
+
+		bool IsInterface();
+
+		bool IsPrimitive();
+
+		object NewInstance();
+
+		IReflector Reflector();
+
+		object NullValue();
+
+		/// <summary>
+		/// Calling this method may change the internal state of the class, even if a usable
+		/// constructor has been found on earlier invocations.
+		/// </summary>
+		/// <remarks>
+		/// Calling this method may change the internal state of the class, even if a usable
+		/// constructor has been found on earlier invocations.
+		/// </remarks>
+		/// <returns>true, if instances of this class can be created, false otherwise</returns>
+		bool EnsureCanBeInstantiated();
+
+		/// <summary>
+		/// We need this for replication, to find out if a class needs to be traversed
+		/// or if it simply can be copied across.
+		/// </summary>
+		/// <remarks>
+		/// We need this for replication, to find out if a class needs to be traversed
+		/// or if it simply can be copied across. For now we will simply return
+		/// the classes that are
+		/// <see cref="IsPrimitive()">IsPrimitive()</see>
+		/// and
+		/// <see cref="Db4objects.Db4o.Internal.Platform4.IsSimple(System.Type{T})">Db4objects.Db4o.Internal.Platform4.IsSimple(System.Type<T>)
+		/// 	</see>
+		/// We can think about letting users add an Immutable annotation.
+		/// </remarks>
+		bool IsImmutable();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectClassPredicate.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectClassPredicate.cs
new file mode 100644
index 0000000..00e6e8c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectClassPredicate.cs
@@ -0,0 +1,22 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Reflect
+{
+	/// <summary>Predicate representation.</summary>
+	/// <remarks>Predicate representation.</remarks>
+	/// <seealso cref="Db4objects.Db4o.Query.Predicate">Db4objects.Db4o.Query.Predicate</seealso>
+	/// <seealso cref="IReflector">IReflector</seealso>
+	public interface IReflectClassPredicate
+	{
+		/// <summary>Match method definition.</summary>
+		/// <remarks>
+		/// Match method definition. Used to select correct
+		/// results from an object set.
+		/// </remarks>
+		/// <param name="item">item to be matched to the criteria</param>
+		/// <returns>true, if the requirements are met</returns>
+		bool Match(IReflectClass item);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectField.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectField.cs
new file mode 100644
index 0000000..6f415de
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectField.cs
@@ -0,0 +1,53 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Reflect
+{
+	/// <summary>Reflection Field representation.</summary>
+	/// <remarks>
+	/// Reflection Field representation
+	/// <br/><br/>See documentation for System.Reflection API.
+	/// </remarks>
+	/// <seealso cref="IReflector">IReflector</seealso>
+	public interface IReflectField
+	{
+		object Get(object onObject);
+
+		string GetName();
+
+		/// <summary>
+		/// The ReflectClass returned by this method should have been
+		/// provided by the parent reflector.
+		/// </summary>
+		/// <remarks>
+		/// The ReflectClass returned by this method should have been
+		/// provided by the parent reflector.
+		/// </remarks>
+		/// <returns>the ReflectClass representing the field type as provided by the parent reflector
+		/// 	</returns>
+		IReflectClass GetFieldType();
+
+		bool IsPublic();
+
+		bool IsStatic();
+
+		bool IsTransient();
+
+		void Set(object onObject, object value);
+
+		/// <summary>
+		/// The ReflectClass returned by this method should have been
+		/// provided by the parent reflector.
+		/// </summary>
+		/// <remarks>
+		/// The ReflectClass returned by this method should have been
+		/// provided by the parent reflector.
+		/// </remarks>
+		/// <returns>the ReflectClass representing the index type as provided by the parent reflector
+		/// 	</returns>
+		IReflectClass IndexType();
+
+		object IndexEntry(object orig);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectMethod.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectMethod.cs
new file mode 100644
index 0000000..a8764e0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectMethod.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Reflect
+{
+	/// <summary>Reflection Method representation.</summary>
+	/// <remarks>
+	/// Reflection Method representation
+	/// <br/><br/>See documentation for System.Reflection API.
+	/// </remarks>
+	/// <seealso cref="IReflector">IReflector</seealso>
+	public interface IReflectMethod
+	{
+		/// <exception cref="Db4objects.Db4o.Internal.ReflectException"></exception>
+		object Invoke(object onObject, object[] parameters);
+
+		IReflectClass GetReturnType();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflector.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflector.cs
new file mode 100644
index 0000000..746118e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflector.cs
@@ -0,0 +1,52 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Reflect
+{
+	/// <summary>root of the reflection implementation API.</summary>
+	/// <remarks>
+	/// root of the reflection implementation API.
+	/// <br/><br/>The open reflection interface is supplied to allow to implement
+	/// custom reflection functionality.<br/><br/>
+	/// Use
+	/// <see cref="IConfiguration.ReflectWith">
+	/// Db4o.Configure().ReflectWith(IReflect reflector)
+	/// </see>
+	/// to register the use of your implementation before opening database
+	/// files.
+	/// </remarks>
+	public interface IReflector : IDeepClone
+	{
+		void Configuration(IReflectorConfiguration config);
+
+		/// <summary>
+		/// returns an ReflectArray object.
+		/// </summary>
+		/// <remarks>
+		/// returns an ReflectArray object.
+		/// </remarks>
+		IReflectArray Array();
+
+		/// <summary>returns an ReflectClass for a Class</summary>
+		IReflectClass ForClass(Type clazz);
+
+		/// <summary>
+		/// returns an ReflectClass class reflector for a class name or null
+		/// if no such class is found
+		/// </summary>
+		IReflectClass ForName(string className);
+
+		/// <summary>returns an ReflectClass for an object or null if the passed object is null.
+		/// 	</summary>
+		/// <remarks>returns an ReflectClass for an object or null if the passed object is null.
+		/// 	</remarks>
+		IReflectClass ForObject(object obj);
+
+		bool IsCollection(IReflectClass clazz);
+
+		void SetParent(IReflector reflector);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectorConfiguration.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectorConfiguration.cs
new file mode 100644
index 0000000..ed83b34
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/IReflectorConfiguration.cs
@@ -0,0 +1,13 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Reflect
+{
+	public interface IReflectorConfiguration
+	{
+		bool TestConstructors();
+
+		bool CallConstructor(IReflectClass clazz);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/MultidimensionalArrayInfo.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/MultidimensionalArrayInfo.cs
new file mode 100644
index 0000000..fe6375a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Reflect/MultidimensionalArrayInfo.cs
@@ -0,0 +1,22 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Reflect
+{
+	/// <exclude></exclude>
+	public class MultidimensionalArrayInfo : ArrayInfo
+	{
+		private int[] _dimensions;
+
+		public virtual void Dimensions(int[] dim)
+		{
+			_dimensions = dim;
+		}
+
+		public virtual int[] Dimensions()
+		{
+			return _dimensions;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Rename.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Rename.cs
new file mode 100644
index 0000000..a44ddb6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Rename.cs
@@ -0,0 +1,41 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o
+{
+	/// <summary>
+	/// Renaming actions are stored to the database file to make
+	/// sure that they are only performed once.
+	/// </summary>
+	/// <remarks>
+	/// Renaming actions are stored to the database file to make
+	/// sure that they are only performed once.
+	/// </remarks>
+	/// <exclude></exclude>
+	/// <persistent></persistent>
+	public sealed class Rename : IInternal4
+	{
+		public string rClass;
+
+		public string rFrom;
+
+		public string rTo;
+
+		public Rename()
+		{
+		}
+
+		public Rename(string aClass, string aFrom, string aTo)
+		{
+			rClass = aClass;
+			rFrom = aFrom;
+			rTo = aTo;
+		}
+
+		public bool IsField()
+		{
+			return rClass.Length != 0;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/StaticClass.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/StaticClass.cs
new file mode 100644
index 0000000..3c1f479
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/StaticClass.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o
+{
+	/// <exclude></exclude>
+	/// <persistent></persistent>
+	public class StaticClass : IInternal4
+	{
+		public string name;
+
+		public StaticField[] fields;
+
+		public StaticClass()
+		{
+		}
+
+		public StaticClass(string name_, StaticField[] fields_)
+		{
+			name = name_;
+			fields = fields_;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/StaticField.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/StaticField.cs
new file mode 100644
index 0000000..9392d4b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/StaticField.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o
+{
+	/// <exclude></exclude>
+	/// <persistent></persistent>
+	public class StaticField : IInternal4
+	{
+		public string name;
+
+		public object value;
+
+		public StaticField()
+		{
+		}
+
+		public StaticField(string name_, object value_)
+		{
+			name = name_;
+			value = value_;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/DeactivatingRollbackStrategy.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/DeactivatingRollbackStrategy.cs
new file mode 100644
index 0000000..f08bf04
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/DeactivatingRollbackStrategy.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+using Db4objects.Db4o.TA;
+
+namespace Db4objects.Db4o.TA
+{
+	/// <summary>RollbackStrategy to deactivate all activated objects on rollback.</summary>
+	/// <remarks>RollbackStrategy to deactivate all activated objects on rollback.</remarks>
+	/// <seealso cref="TransparentPersistenceSupport">TransparentPersistenceSupport</seealso>
+	public class DeactivatingRollbackStrategy : IRollbackStrategy
+	{
+		/// <summary>deactivates each object.</summary>
+		/// <remarks>deactivates each object.</remarks>
+		public virtual void Rollback(IObjectContainer container, object obj)
+		{
+			container.Ext().Deactivate(obj);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/IActivatable.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/IActivatable.cs
new file mode 100644
index 0000000..a0d1092
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/IActivatable.cs
@@ -0,0 +1,135 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Activation;
+
+namespace Db4objects.Db4o.TA
+{
+	/// <summary>
+	/// IActivatable must be implemented by classes in order to support
+	/// Transparent Activation.
+	/// <br/>
+	/// <br/>
+	/// The IActivatable interface may be added to persistent classes by hand
+	/// or by using the db4o instrumentation (Db4oTools).
+	/// </summary>
+	/// <remarks>
+	/// IActivatable must be implemented by classes in order to support
+	/// Transparent Activation.
+	/// <br/>
+	/// <br/>
+	/// The IActivatable interface may be added to persistent classes by hand
+	/// or by using the db4o instrumentation (Db4oTools). For further
+	/// information on the enhancer see:
+	/// <br/>
+	/// <br/>
+	/// http://developer.db4o.com/Resources/view.aspx/Reference/Implementation_Strategies/Enhancement_Tools/Enhancement_For_.NET.
+	/// <br/>
+	/// <br/>
+	/// The basic idea for Transparent Activation is as follows:
+	/// <br/>
+	/// Objects have an activation depth of 0, i.e. by default they are not
+	/// activated at all. Whenever a method is called on such an object, the
+	/// first thing to do before actually executing the method body is to
+	/// activate the object to level 1, i.e. populating its direct members.
+	/// <br/>
+	/// <br/>
+	/// To illustrate this approach, we will use the following simple class.
+	/// <br/>
+	/// <br/>
+	/// <code>
+	/// public class Item {
+	/// <br/>   private Item _next;<br/><br/>
+	///    public Item(Item next) {<br/>
+	///       _next = next;<br/>
+	///    }<br/><br/>
+	///    public Item Next {<br/>
+	///      get {<br/>
+	///       return _next;<br/>
+	///      }<br/>
+	///    }<br/>
+	/// }<br/><br/></code>
+	/// The basic sequence of actions to get the above scheme to work is the
+	/// following:<br/>
+	/// <br/>
+	/// - Whenever an object is instantiated from db4o, the database registers an
+	/// activator for this object. To enable this, the object has to implement the
+	/// IActivatable interface and provide the according Bind(IActivator) method. The
+	/// default implementation of the bind method will simply store the given
+	/// activator reference for later use.<br/>
+	/// <br/>
+	/// <code>
+	/// public class Item implements IActivatable {<br/>
+	///    transient IActivator _activator;<br/><br/>
+	///    public void Bind(IActivator activator) {<br/>
+	///       if (null != _activator) {<br/>
+	///          throw new IllegalStateException();<br/>
+	///       }<br/>
+	///       _activator = activator;<br/>
+	///    }<br/><br/>
+	///    // ...<br/>
+	/// }<br/><br/></code>
+	/// - The first action in every method body of an activatable object should be a
+	/// call to the corresponding IActivator's Activate() method. (Note that this is
+	/// not enforced by any interface, it is rather a convention, and other
+	/// implementations are possible.)<br/>
+	/// <br/>
+	/// <code>
+	/// public class Item implements IActivatable {<br/>
+	///    public void Activate() {<br/>
+	///       if (_activator == null) return;<br/>
+	///       _activator.Activate();<br/>
+	///    }<br/><br/>
+	///    public Item Next() {<br/>
+	///      get {<br/>
+	///       Activate();<br/>
+	///       return _next;<br/>
+	///      }<br/>
+	///    }<br/>
+	/// }<br/><br/></code>
+	/// - The Activate() method will check whether the object is already activated.
+	/// If this is not the case, it will request the container to activate the object
+	/// to level 1 and set the activated flag accordingly.<br/>
+	/// <br/>
+	/// To instruct db4o to actually use these hooks (i.e. to register the database
+	/// when instantiating an object), TransparentActivationSupport has to be
+	/// registered with the db4o configuration.<br/>
+	/// <br/>
+	/// <code>
+	/// ICommonConfiguration config = ...<br/>
+	/// config.Add(new TransparentActivationSupport());<br/><br/>
+	/// </code>
+	/// </remarks>
+	public interface IActivatable
+	{
+		/// <summary>called by db4o upon instantiation.</summary>
+		/// <remarks>
+		/// called by db4o upon instantiation. <br />
+		/// <br />
+		/// The recommended implementation of this method is to store the passed
+		/// <see cref="Db4objects.Db4o.Activation.IActivator">Db4objects.Db4o.Activation.IActivator
+		/// 	</see>
+		/// in a transient field of the object.
+		/// </remarks>
+		/// <param name="activator">the Activator</param>
+		void Bind(IActivator activator);
+
+		/// <summary>should be called by every reading field access of an object.</summary>
+		/// <remarks>
+		/// should be called by every reading field access of an object. <br />
+		/// <br />
+		/// The recommended implementation of this method is to call
+		/// <see cref="Db4objects.Db4o.Activation.IActivator.Activate(Db4objects.Db4o.Activation.ActivationPurpose)
+		/// 	">Db4objects.Db4o.Activation.IActivator.Activate(Db4objects.Db4o.Activation.ActivationPurpose)
+		/// 	</see>
+		/// on the
+		/// <see cref="Db4objects.Db4o.Activation.IActivator">Db4objects.Db4o.Activation.IActivator
+		/// 	</see>
+		/// that was previously passed to
+		/// <see cref="Bind(Db4objects.Db4o.Activation.IActivator)">Bind(Db4objects.Db4o.Activation.IActivator)
+		/// 	</see>
+		/// .
+		/// </remarks>
+		/// <param name="purpose">TODO</param>
+		void Activate(ActivationPurpose purpose);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/IActivatableInstrumented.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/IActivatableInstrumented.cs
new file mode 100644
index 0000000..4befac9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/IActivatableInstrumented.cs
@@ -0,0 +1,16 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.TA
+{
+	/// <summary>
+	/// Marker interface to declare a class already implements the required TA/TP hooks
+	/// and does not want to be instrumented further.
+	/// </summary>
+	/// <remarks>
+	/// Marker interface to declare a class already implements the required TA/TP hooks
+	/// and does not want to be instrumented further.
+	/// </remarks>
+	public interface IActivatableInstrumented
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/IRollbackStrategy.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/IRollbackStrategy.cs
new file mode 100644
index 0000000..b366a72
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/IRollbackStrategy.cs
@@ -0,0 +1,22 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.TA
+{
+	/// <summary>Interface defining rollback behavior when Transparent Persistence mode is on.
+	/// 	</summary>
+	/// <remarks>Interface defining rollback behavior when Transparent Persistence mode is on.
+	/// 	</remarks>
+	/// <seealso cref="TransparentPersistenceSupport">TransparentPersistenceSupport</seealso>
+	public interface IRollbackStrategy
+	{
+		/// <summary>Method to be called per TP-enabled object when the transaction is rolled back.
+		/// 	</summary>
+		/// <remarks>Method to be called per TP-enabled object when the transaction is rolled back.
+		/// 	</remarks>
+		/// <param name="container">current ObjectContainer</param>
+		/// <param name="obj">TP-enabled object</param>
+		void Rollback(IObjectContainer container, object obj);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/NotTransparentActivationEnabled.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/NotTransparentActivationEnabled.cs
new file mode 100644
index 0000000..5035a67
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/NotTransparentActivationEnabled.cs
@@ -0,0 +1,34 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Diagnostic;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.TA;
+
+namespace Db4objects.Db4o.TA
+{
+	public class NotTransparentActivationEnabled : DiagnosticBase
+	{
+		private ClassMetadata _class;
+
+		public NotTransparentActivationEnabled(ClassMetadata clazz)
+		{
+			_class = clazz;
+		}
+
+		public override string Problem()
+		{
+			return "An object of class " + _class + " was stored. Instances of this class very likely are not subject to transparent activation.";
+		}
+
+		public override object Reason()
+		{
+			return _class;
+		}
+
+		public override string Solution()
+		{
+			return "Use a TA aware class with equivalent functionality or ensure that this class provides a sensible implementation of the "
+				 + typeof(IActivatable).FullName + " interface and the implicit TA hooks, either manually or by applying instrumentation.";
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/TransactionalActivator.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/TransactionalActivator.cs
new file mode 100644
index 0000000..0431e1a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/TransactionalActivator.cs
@@ -0,0 +1,34 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Activation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.TA
+{
+	/// <summary>
+	/// An
+	/// <see cref="Db4objects.Db4o.Activation.IActivator">Db4objects.Db4o.Activation.IActivator
+	/// 	</see>
+	/// implementation that activates an object on a specific
+	/// transaction.
+	/// </summary>
+	/// <exclude></exclude>
+	internal sealed class TransactionalActivator : IActivator
+	{
+		private readonly Transaction _transaction;
+
+		private readonly ObjectReference _objectReference;
+
+		public TransactionalActivator(Transaction transaction, ObjectReference objectReference
+			)
+		{
+			_objectReference = objectReference;
+			_transaction = transaction;
+		}
+
+		public void Activate(ActivationPurpose purpose)
+		{
+			_objectReference.ActivateOn(_transaction, purpose);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/TransparentActivationSupport.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/TransparentActivationSupport.cs
new file mode 100644
index 0000000..51188b9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/TransparentActivationSupport.cs
@@ -0,0 +1,317 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Activation;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Events;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Diagnostic;
+using Db4objects.Db4o.Internal.References;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.TA;
+
+namespace Db4objects.Db4o.TA
+{
+	/// <summary>
+	/// Configuration item that enables Transparent Activation Mode for this
+	/// session.
+	/// </summary>
+	/// <remarks>
+	/// Configuration item that enables Transparent Activation Mode for this
+	/// session. TA mode should be switched on explicitly for manual TA implementation:
+	/// <br/><br/>
+	/// commonConfiguration.Add(new TransparentActivationSupport());
+	/// </remarks>
+	/// <seealso cref="Db4objects.Db4o.TA.TransparentPersistenceSupport"/>
+	public class TransparentActivationSupport : IConfigurationItem
+	{
+		// TODO: unbindOnClose should be configurable
+		public virtual void Prepare(IConfiguration configuration)
+		{
+		}
+
+		// Nothing to do...
+		/// <summary>
+		/// Configures the just opened ObjectContainer by setting event listeners,
+		/// which will be triggered when activation or de-activation is required.
+		/// </summary>
+		/// <remarks>
+		/// Configures the just opened ObjectContainer by setting event listeners,
+		/// which will be triggered when activation or de-activation is required.
+		/// </remarks>
+		/// <param name="container">the ObjectContainer to configure</param>
+		/// <seealso cref="TransparentPersistenceSupport.Apply(Db4objects.Db4o.Internal.IInternalObjectContainer)
+		/// 	">TransparentPersistenceSupport.Apply(Db4objects.Db4o.Internal.IInternalObjectContainer)
+		/// 	</seealso>
+		public virtual void Apply(IInternalObjectContainer container)
+		{
+			if (IsTransparentActivationEnabledOn(container))
+			{
+				return;
+			}
+			TransparentActivationDepthProviderImpl provider = new TransparentActivationDepthProviderImpl
+				();
+			SetActivationDepthProvider(container, provider);
+			IEventRegistry registry = EventRegistryFor(container);
+			registry.Instantiated += new System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>
+				(new _IEventListener4_45(this).OnEvent);
+			registry.Created += new System.EventHandler<Db4objects.Db4o.Events.ObjectInfoEventArgs>
+				(new _IEventListener4_50(this).OnEvent);
+			registry.Closing += new System.EventHandler<Db4objects.Db4o.Events.ObjectContainerEventArgs>
+				(new _IEventListener4_56(this).OnEvent);
+			TransparentActivationSupport.TADiagnosticProcessor processor = new TransparentActivationSupport.TADiagnosticProcessor
+				(this, container);
+			registry.ClassRegistered += new System.EventHandler<Db4objects.Db4o.Events.ClassEventArgs>
+				(new _IEventListener4_67(processor).OnEvent);
+		}
+
+		private sealed class _IEventListener4_45
+		{
+			public _IEventListener4_45(TransparentActivationSupport _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void OnEvent(object sender, Db4objects.Db4o.Events.ObjectInfoEventArgs args
+				)
+			{
+				this._enclosing.BindActivatableToActivator((ObjectEventArgs)args);
+			}
+
+			private readonly TransparentActivationSupport _enclosing;
+		}
+
+		private sealed class _IEventListener4_50
+		{
+			public _IEventListener4_50(TransparentActivationSupport _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void OnEvent(object sender, Db4objects.Db4o.Events.ObjectInfoEventArgs args
+				)
+			{
+				this._enclosing.BindActivatableToActivator((ObjectEventArgs)args);
+			}
+
+			private readonly TransparentActivationSupport _enclosing;
+		}
+
+		private sealed class _IEventListener4_56
+		{
+			public _IEventListener4_56(TransparentActivationSupport _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void OnEvent(object sender, Db4objects.Db4o.Events.ObjectContainerEventArgs
+				 args)
+			{
+				IInternalObjectContainer objectContainer = (IInternalObjectContainer)((ObjectContainerEventArgs
+					)args).ObjectContainer;
+				this._enclosing.UnbindAll(objectContainer);
+				if (!this._enclosing.IsEmbeddedClient(objectContainer))
+				{
+					this._enclosing.SetActivationDepthProvider(objectContainer, null);
+				}
+			}
+
+			private readonly TransparentActivationSupport _enclosing;
+		}
+
+		private sealed class _IEventListener4_67
+		{
+			public _IEventListener4_67(TransparentActivationSupport.TADiagnosticProcessor processor
+				)
+			{
+				this.processor = processor;
+			}
+
+			public void OnEvent(object sender, Db4objects.Db4o.Events.ClassEventArgs args)
+			{
+				ClassEventArgs cea = (ClassEventArgs)args;
+				processor.OnClassRegistered(cea.ClassMetadata());
+			}
+
+			private readonly TransparentActivationSupport.TADiagnosticProcessor processor;
+		}
+
+		public static bool IsTransparentActivationEnabledOn(IInternalObjectContainer container
+			)
+		{
+			return ActivationProvider(container) is ITransparentActivationDepthProvider;
+		}
+
+		private void SetActivationDepthProvider(IInternalObjectContainer container, IActivationDepthProvider
+			 provider)
+		{
+			container.ConfigImpl.ActivationDepthProvider(provider);
+		}
+
+		private IEventRegistry EventRegistryFor(IObjectContainer container)
+		{
+			return EventRegistryFactory.ForObjectContainer(container);
+		}
+
+		private void UnbindAll(IInternalObjectContainer container)
+		{
+			Db4objects.Db4o.Internal.Transaction transaction = container.Transaction;
+			// FIXME should that ever happen?
+			if (transaction == null)
+			{
+				return;
+			}
+			IReferenceSystem referenceSystem = transaction.ReferenceSystem();
+			referenceSystem.TraverseReferences(new _IVisitor4_95(this));
+		}
+
+		private sealed class _IVisitor4_95 : IVisitor4
+		{
+			public _IVisitor4_95(TransparentActivationSupport _enclosing)
+			{
+				this._enclosing = _enclosing;
+			}
+
+			public void Visit(object obj)
+			{
+				this._enclosing.Unbind((ObjectReference)obj);
+			}
+
+			private readonly TransparentActivationSupport _enclosing;
+		}
+
+		private void Unbind(ObjectReference objectReference)
+		{
+			object obj = objectReference.GetObject();
+			if (obj == null || !(obj is IActivatable))
+			{
+				return;
+			}
+			Bind(obj, null);
+		}
+
+		private void BindActivatableToActivator(ObjectEventArgs oea)
+		{
+			object obj = oea.Object;
+			if (obj is IActivatable)
+			{
+				Db4objects.Db4o.Internal.Transaction transaction = (Db4objects.Db4o.Internal.Transaction
+					)oea.Transaction();
+				ObjectReference objectReference = transaction.ReferenceForObject(obj);
+				Bind(obj, ActivatorForObject(transaction, objectReference));
+			}
+		}
+
+		private void Bind(object activatable, IActivator activator)
+		{
+			((IActivatable)activatable).Bind(activator);
+		}
+
+		private IActivator ActivatorForObject(Db4objects.Db4o.Internal.Transaction transaction
+			, ObjectReference objectReference)
+		{
+			if (IsEmbeddedClient(transaction))
+			{
+				return new TransactionalActivator(transaction, objectReference);
+			}
+			return objectReference;
+		}
+
+		private bool IsEmbeddedClient(Db4objects.Db4o.Internal.Transaction transaction)
+		{
+			return IsEmbeddedClient(transaction.ObjectContainer());
+		}
+
+		internal virtual Db4objects.Db4o.Internal.Transaction Transaction(EventArgs args)
+		{
+			return (Db4objects.Db4o.Internal.Transaction)((TransactionalEventArgs)args).Transaction
+				();
+		}
+
+		protected static IActivationDepthProvider ActivationProvider(IInternalObjectContainer
+			 container)
+		{
+			return container.ConfigImpl.ActivationDepthProvider();
+		}
+
+		private bool IsEmbeddedClient(IObjectContainer objectContainer)
+		{
+			return objectContainer is ObjectContainerSession;
+		}
+
+		private sealed class TADiagnosticProcessor
+		{
+			private readonly IInternalObjectContainer _container;
+
+			public TADiagnosticProcessor(TransparentActivationSupport _enclosing, IInternalObjectContainer
+				 container)
+			{
+				this._enclosing = _enclosing;
+				this._container = container;
+			}
+
+			public void OnClassRegistered(ClassMetadata clazz)
+			{
+				// if(Platform4.isDb4oClass(clazz.getName())) {
+				// return;
+				// }
+				IReflectClass reflectClass = clazz.ClassReflector();
+				if (this.ActivatableClass().IsAssignableFrom(reflectClass))
+				{
+					return;
+				}
+				if (this.HasNoActivatingFields(reflectClass))
+				{
+					return;
+				}
+				NotTransparentActivationEnabled diagnostic = new NotTransparentActivationEnabled(
+					clazz);
+				DiagnosticProcessor processor = this._container.Handlers.DiagnosticProcessor();
+				processor.OnDiagnostic(diagnostic);
+			}
+
+			private IReflectClass ActivatableClass()
+			{
+				return this._container.Reflector().ForClass(typeof(IActivatable));
+			}
+
+			private bool HasNoActivatingFields(IReflectClass clazz)
+			{
+				IReflectClass curClass = clazz;
+				while (curClass != null)
+				{
+					IReflectField[] fields = curClass.GetDeclaredFields();
+					if (!this.HasNoActivatingFields(fields))
+					{
+						return false;
+					}
+					curClass = curClass.GetSuperclass();
+				}
+				return true;
+			}
+
+			private bool HasNoActivatingFields(IReflectField[] fields)
+			{
+				for (int i = 0; i < fields.Length; i++)
+				{
+					if (this.IsActivating(fields[i]))
+					{
+						return false;
+					}
+				}
+				return true;
+			}
+
+			private bool IsActivating(IReflectField field)
+			{
+				IReflectClass fieldType = field.GetFieldType();
+				return fieldType != null && !fieldType.IsPrimitive();
+			}
+
+			private readonly TransparentActivationSupport _enclosing;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/TransparentPersistenceSupport.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/TransparentPersistenceSupport.cs
new file mode 100644
index 0000000..c678285
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/TA/TransparentPersistenceSupport.cs
@@ -0,0 +1,71 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.TA;
+
+namespace Db4objects.Db4o.TA
+{
+	/// <summary>
+	/// Enables Transparent Persistence and Transparent Activation behaviours for
+	/// the current session.
+	/// </summary>
+	/// <remarks>
+	/// Enables Transparent Persistence and Transparent Activation behaviours for
+	/// the current session.
+	/// <br/><br/>
+	/// commonConfiguration.Add(new TransparentPersistenceSupport());
+	/// </remarks>
+	/// <seealso cref="Db4objects.Db4o.TA.TransparentActivationSupport">Db4objects.Db4o.TA.TransparentActivationSupport
+	/// </seealso>
+	public class TransparentPersistenceSupport : TransparentActivationSupport
+	{
+		private readonly IRollbackStrategy _rollbackStrategy;
+
+		/// <summary>Creates a new instance of TransparentPersistenceSupport class</summary>
+		/// <param name="rollbackStrategy">
+		/// RollbackStrategy interface implementation, which
+		/// defines the actions to be taken on the object when the transaction is rolled back.
+		/// </param>
+		public TransparentPersistenceSupport(IRollbackStrategy rollbackStrategy)
+		{
+			_rollbackStrategy = rollbackStrategy;
+		}
+
+		/// <summary>
+		/// Creates a new instance of TransparentPersistenceSupport class
+		/// with no rollback strategies defined.
+		/// </summary>
+		/// <remarks>
+		/// Creates a new instance of TransparentPersistenceSupport class
+		/// with no rollback strategies defined.
+		/// </remarks>
+		public TransparentPersistenceSupport() : this(null)
+		{
+		}
+
+		/// <summary>Configures current ObjectContainer to support Transparent Activation and Transparent Persistence
+		/// 	</summary>
+		/// <seealso cref="TransparentActivationSupport.Apply(Db4objects.Db4o.Internal.IInternalObjectContainer)
+		/// 	"></seealso>
+		public override void Apply(IInternalObjectContainer container)
+		{
+			base.Apply(container);
+			EnableTransparentPersistenceFor(container);
+		}
+
+		private void EnableTransparentPersistenceFor(IInternalObjectContainer container)
+		{
+			ITransparentActivationDepthProvider provider = (ITransparentActivationDepthProvider
+				)ActivationProvider(container);
+			provider.EnableTransparentPersistenceSupportFor(container, _rollbackStrategy);
+		}
+
+		public override void Prepare(IConfiguration configuration)
+		{
+			base.Prepare(configuration);
+			((Config4Impl)configuration).UpdateDepthProvider(new TPUpdateDepthProvider());
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/CollectionTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/CollectionTypeHandler.cs
new file mode 100755
index 0000000..4f5b8dd
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/CollectionTypeHandler.cs
@@ -0,0 +1,146 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+	/// <summary>TypeHandler for Collections.</summary>
+	/// <remarks>
+	/// TypeHandler for Collections.
+	/// On the .NET side, usage is restricted to instances of IList.
+	/// </remarks>
+	public partial class CollectionTypeHandler : IReferenceTypeHandler, ICascadingTypeHandler
+		, IVariableLengthTypeHandler, IQueryableTypeHandler
+	{
+		public virtual IPreparedComparison PrepareComparison(IContext context, object obj
+			)
+		{
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		public virtual void Write(IWriteContext context, object obj)
+		{
+			ICollection collection = (ICollection)obj;
+			ITypeHandler4 elementHandler = DetectElementTypeHandler(Container(context), collection
+				);
+			WriteElementClassMetadataId(context, elementHandler);
+			WriteElementCount(context, collection);
+			WriteElements(context, collection, elementHandler);
+		}
+
+		public virtual void Activate(IReferenceActivationContext context)
+		{
+			ICollection collection = (ICollection)((UnmarshallingContext)context).PersistentObject
+				();
+			ClearCollection(collection);
+			ITypeHandler4 elementHandler = ReadElementTypeHandler(context, context);
+			int elementCount = context.ReadInt();
+			for (int i = 0; i < elementCount; i++)
+			{
+				object element = context.ReadObject(elementHandler);
+				AddToCollection(collection, element);
+			}
+		}
+
+		private void WriteElementCount(IWriteContext context, ICollection collection)
+		{
+			context.WriteInt(collection.Count);
+		}
+
+		private void WriteElements(IWriteContext context, ICollection collection, ITypeHandler4
+			 elementHandler)
+		{
+			IEnumerator elements = collection.GetEnumerator();
+			while (elements.MoveNext())
+			{
+				context.WriteObject(elementHandler, elements.Current);
+			}
+		}
+
+		private ObjectContainerBase Container(IContext context)
+		{
+			return ((IInternalObjectContainer)context.ObjectContainer()).Container;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Delete(IDeleteContext context)
+		{
+			if (!context.CascadeDelete())
+			{
+				return;
+			}
+			ITypeHandler4 handler = ReadElementTypeHandler(context, context);
+			int elementCount = context.ReadInt();
+			for (int i = elementCount; i > 0; i--)
+			{
+				handler.Delete(context);
+			}
+		}
+
+		public virtual void Defragment(IDefragmentContext context)
+		{
+			ITypeHandler4 handler = ReadElementTypeHandler(context, context);
+			int elementCount = context.ReadInt();
+			for (int i = 0; i < elementCount; i++)
+			{
+				handler.Defragment(context);
+			}
+		}
+
+		public void CascadeActivation(IActivationContext context)
+		{
+			IEnumerator all = ((ICollection)context.TargetObject()).GetEnumerator();
+			while (all.MoveNext())
+			{
+				context.CascadeActivationToChild(all.Current);
+			}
+		}
+
+		public virtual ITypeHandler4 ReadCandidateHandler(QueryingReadContext context)
+		{
+			return this;
+		}
+
+		public virtual void CollectIDs(QueryingReadContext context)
+		{
+			ITypeHandler4 elementHandler = ReadElementTypeHandler(context, context);
+			int elementCount = context.ReadInt();
+			for (int i = 0; i < elementCount; i++)
+			{
+				context.ReadId(elementHandler);
+			}
+		}
+
+		private void WriteElementClassMetadataId(IWriteContext context, ITypeHandler4 elementHandler
+			)
+		{
+			context.WriteInt(0);
+		}
+
+		private ITypeHandler4 ReadElementTypeHandler(IReadBuffer buffer, IContext context
+			)
+		{
+			buffer.ReadInt();
+			return (ITypeHandler4)Container(context).Handlers.OpenTypeHandler();
+		}
+
+		private ITypeHandler4 DetectElementTypeHandler(IInternalObjectContainer container
+			, ICollection collection)
+		{
+			return (ITypeHandler4)container.Handlers.OpenTypeHandler();
+		}
+
+		public virtual bool DescendsIntoMembers()
+		{
+			return true;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IActivationContext.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IActivationContext.cs
new file mode 100644
index 0000000..1dd0cb5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IActivationContext.cs
@@ -0,0 +1,28 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+	public interface IActivationContext : IContext
+	{
+		void CascadeActivationToTarget();
+
+		void CascadeActivationToChild(object obj);
+
+		ObjectContainerBase Container();
+
+		object TargetObject();
+
+		Db4objects.Db4o.Internal.ClassMetadata ClassMetadata();
+
+		IActivationDepth Depth();
+
+		IActivationContext ForObject(object newTargetObject);
+
+		IActivationContext Descend();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/ICascadingTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/ICascadingTypeHandler.cs
new file mode 100644
index 0000000..893c9f1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/ICascadingTypeHandler.cs
@@ -0,0 +1,38 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+	/// <summary>TypeHandler for objects with members.</summary>
+	/// <remarks>TypeHandler for objects with members.</remarks>
+	public interface ICascadingTypeHandler : ITypeHandler4
+	{
+		/// <summary>
+		/// will be called during activation if the handled
+		/// object is already active
+		/// </summary>
+		/// <param name="context"></param>
+		void CascadeActivation(IActivationContext context);
+
+		/// <summary>
+		/// will be called during querying to ask for the handler
+		/// to be used to collect children of the handled object
+		/// </summary>
+		/// <param name="context"></param>
+		/// <returns></returns>
+		ITypeHandler4 ReadCandidateHandler(QueryingReadContext context);
+
+		/// <summary>
+		/// will be called during querying to ask for IDs of member
+		/// objects of the handled object.
+		/// </summary>
+		/// <remarks>
+		/// will be called during querying to ask for IDs of member
+		/// objects of the handled object.
+		/// </remarks>
+		/// <param name="context"></param>
+		void CollectIDs(QueryingReadContext context);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IInstantiatingTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IInstantiatingTypeHandler.cs
new file mode 100644
index 0000000..4db4895
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IInstantiatingTypeHandler.cs
@@ -0,0 +1,28 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+	public interface IInstantiatingTypeHandler : IReferenceTypeHandler
+	{
+		object Instantiate(IReadContext context);
+
+		/// <summary>gets called when an object is to be written to the database.</summary>
+		/// <remarks>
+		/// gets called when an object is to be written to the database.
+		/// The method must only write data necessary to re instantiate the object, usually
+		/// the immutable bits of information held by the object. For value
+		/// types that means their complete state.
+		/// Mutable state (only allowed in reference types) must be handled
+		/// during
+		/// <see cref="IReferenceTypeHandler.Activate(Db4objects.Db4o.Marshall.IReferenceActivationContext)
+		/// 	">IReferenceTypeHandler.Activate(Db4objects.Db4o.Marshall.IReferenceActivationContext)
+		/// 	</see>
+		/// </remarks>
+		/// <param name="context"></param>
+		/// <param name="obj">the object</param>
+		void WriteInstantiation(IWriteContext context, object obj);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IQueryableTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IQueryableTypeHandler.cs
new file mode 100644
index 0000000..0664026
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IQueryableTypeHandler.cs
@@ -0,0 +1,11 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+	public interface IQueryableTypeHandler : ITypeHandler4
+	{
+		bool DescendsIntoMembers();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IReferenceTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IReferenceTypeHandler.cs
new file mode 100644
index 0000000..ce62ab8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IReferenceTypeHandler.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+	public interface IReferenceTypeHandler : ITypeHandler4
+	{
+		/// <summary>gets called when an object is to be activated.</summary>
+		/// <remarks>gets called when an object is to be activated.</remarks>
+		/// <param name="context"></param>
+		void Activate(IReferenceActivationContext context);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/ITypeFamilyTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/ITypeFamilyTypeHandler.cs
new file mode 100644
index 0000000..980167c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/ITypeFamilyTypeHandler.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+	/// <exclude></exclude>
+	public interface ITypeFamilyTypeHandler : IQueryableTypeHandler, ILinkLengthAware
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/ITypeHandler4.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/ITypeHandler4.cs
new file mode 100644
index 0000000..9402624
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/ITypeHandler4.cs
@@ -0,0 +1,42 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+	/// <summary>
+	/// handles reading, writing, deleting, defragmenting and
+	/// comparisons for types of objects.<br /><br />
+	/// Custom Typehandlers can be implemented to alter the default
+	/// behaviour of storing all non-transient fields of an object.<br /><br />
+	/// </summary>
+	/// <seealso>
+	/// 
+	/// <see cref="Db4objects.Db4o.Config.IConfiguration.RegisterTypeHandler(ITypeHandlerPredicate, ITypeHandler4)
+	/// 	">Db4objects.Db4o.Config.IConfiguration.RegisterTypeHandler(ITypeHandlerPredicate, ITypeHandler4)
+	/// 	</see>
+	/// 
+	/// </seealso>
+	public interface ITypeHandler4
+	{
+		/// <summary>gets called when an object gets deleted.</summary>
+		/// <remarks>gets called when an object gets deleted.</remarks>
+		/// <param name="context"></param>
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException">Db4objects.Db4o.Ext.Db4oIOException
+		/// 	</exception>
+		void Delete(IDeleteContext context);
+
+		/// <summary>gets called when an object gets defragmented.</summary>
+		/// <remarks>gets called when an object gets defragmented.</remarks>
+		/// <param name="context"></param>
+		void Defragment(IDefragmentContext context);
+
+		/// <summary>gets called when an object is to be written to the database.</summary>
+		/// <remarks>gets called when an object is to be written to the database.</remarks>
+		/// <param name="context"></param>
+		/// <param name="obj">the object</param>
+		void Write(IWriteContext context, object obj);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/ITypeHandlerPredicate.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/ITypeHandlerPredicate.cs
new file mode 100644
index 0000000..7dfed79
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/ITypeHandlerPredicate.cs
@@ -0,0 +1,31 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+	/// <summary>
+	/// Predicate to be able to select if a specific TypeHandler is
+	/// applicable for a specific Type.
+	/// </summary>
+	/// <remarks>
+	/// Predicate to be able to select if a specific TypeHandler is
+	/// applicable for a specific Type.
+	/// </remarks>
+	public interface ITypeHandlerPredicate
+	{
+		/// <summary>
+		/// return true if a TypeHandler is to be used for a specific
+		/// Type
+		/// </summary>
+		/// <param name="classReflector">
+		/// the Type passed by db4o that is to
+		/// be tested by this predicate.
+		/// </param>
+		/// <returns>
+		/// true if the TypeHandler is to be used for a specific
+		/// Type.
+		/// </returns>
+		bool Match(IReflectClass classReflector);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IValueTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IValueTypeHandler.cs
new file mode 100644
index 0000000..abb2489
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IValueTypeHandler.cs
@@ -0,0 +1,16 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+	public interface IValueTypeHandler : ITypeHandler4
+	{
+		/// <summary>gets called when an value type is to be read from the database.</summary>
+		/// <remarks>gets called when an value type is to be read from the database.</remarks>
+		/// <param name="context"></param>
+		/// <returns>the read value type</returns>
+		object Read(IReadContext context);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IgnoreFieldsTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IgnoreFieldsTypeHandler.cs
new file mode 100644
index 0000000..83310e0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/IgnoreFieldsTypeHandler.cs
@@ -0,0 +1,62 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+	/// <summary>Typehandler that ignores all fields on a class</summary>
+	public class IgnoreFieldsTypeHandler : IReferenceTypeHandler, ICascadingTypeHandler
+	{
+		public static readonly ITypeHandler4 Instance = new Db4objects.Db4o.Typehandlers.IgnoreFieldsTypeHandler
+			();
+
+		private IgnoreFieldsTypeHandler()
+		{
+		}
+
+		public virtual void Defragment(IDefragmentContext context)
+		{
+		}
+
+		// do nothing
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Delete(IDeleteContext context)
+		{
+		}
+
+		// do nothing
+		public virtual void Activate(IReferenceActivationContext context)
+		{
+		}
+
+		public virtual void Write(IWriteContext context, object obj)
+		{
+		}
+
+		public virtual IPreparedComparison PrepareComparison(IContext context, object obj
+			)
+		{
+			return null;
+		}
+
+		public virtual void CascadeActivation(IActivationContext context)
+		{
+		}
+
+		// do nothing
+		public virtual void CollectIDs(QueryingReadContext context)
+		{
+		}
+
+		// do nothing
+		public virtual ITypeHandler4 ReadCandidateHandler(QueryingReadContext context)
+		{
+			return null;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/Internal/KeyValueHandlerPair.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/Internal/KeyValueHandlerPair.cs
new file mode 100644
index 0000000..8525b5a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/Internal/KeyValueHandlerPair.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Typehandlers.Internal
+{
+	/// <exclude></exclude>
+	public class KeyValueHandlerPair
+	{
+		public readonly ITypeHandler4 _keyHandler;
+
+		public readonly ITypeHandler4 _valueHandler;
+
+		public KeyValueHandlerPair(ITypeHandler4 keyHandler, ITypeHandler4 valueHandler)
+		{
+			_keyHandler = keyHandler;
+			_valueHandler = valueHandler;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/MapTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/MapTypeHandler.cs
new file mode 100644
index 0000000..b3acb68
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/MapTypeHandler.cs
@@ -0,0 +1,158 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Typehandlers;
+using Db4objects.Db4o.Typehandlers.Internal;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+	/// <summary>Typehandler for classes that implement IDictionary.</summary>
+	/// <remarks>Typehandler for classes that implement IDictionary.</remarks>
+	public class MapTypeHandler : IReferenceTypeHandler, ICascadingTypeHandler, IVariableLengthTypeHandler
+	{
+		public virtual IPreparedComparison PrepareComparison(IContext context, object obj
+			)
+		{
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		public virtual void Write(IWriteContext context, object obj)
+		{
+			IDictionary map = (IDictionary)obj;
+			KeyValueHandlerPair handlers = DetectKeyValueTypeHandlers(Container(context), map
+				);
+			WriteClassMetadataIds(context, handlers);
+			WriteElementCount(context, map);
+			WriteElements(context, map, handlers);
+		}
+
+		public virtual void Activate(IReferenceActivationContext context)
+		{
+			UnmarshallingContext unmarshallingContext = (UnmarshallingContext)context;
+			IDictionary map = (IDictionary)unmarshallingContext.PersistentObject();
+			map.Clear();
+			KeyValueHandlerPair handlers = ReadKeyValueTypeHandlers(context, context);
+			int elementCount = context.ReadInt();
+			for (int i = 0; i < elementCount; i++)
+			{
+				object key = unmarshallingContext.ReadFullyActivatedObjectForKeys(handlers._keyHandler
+					);
+				if (key == null && !unmarshallingContext.LastReferenceReadWasReallyNull())
+				{
+					continue;
+				}
+				object value = context.ReadObject(handlers._valueHandler);
+				map[key] = value;
+			}
+		}
+
+		private void WriteElementCount(IWriteContext context, IDictionary map)
+		{
+			context.WriteInt(map.Count);
+		}
+
+		private void WriteElements(IWriteContext context, IDictionary map, KeyValueHandlerPair
+			 handlers)
+		{
+			IEnumerator elements = map.Keys.GetEnumerator();
+			while (elements.MoveNext())
+			{
+				object key = elements.Current;
+				context.WriteObject(handlers._keyHandler, key);
+				context.WriteObject(handlers._valueHandler, map[key]);
+			}
+		}
+
+		private ObjectContainerBase Container(IContext context)
+		{
+			return ((IInternalObjectContainer)context.ObjectContainer()).Container;
+		}
+
+		/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception>
+		public virtual void Delete(IDeleteContext context)
+		{
+			if (!context.CascadeDelete())
+			{
+				return;
+			}
+			KeyValueHandlerPair handlers = ReadKeyValueTypeHandlers(context, context);
+			int elementCount = context.ReadInt();
+			for (int i = elementCount; i > 0; i--)
+			{
+				handlers._keyHandler.Delete(context);
+				handlers._valueHandler.Delete(context);
+			}
+		}
+
+		public virtual void Defragment(IDefragmentContext context)
+		{
+			KeyValueHandlerPair handlers = ReadKeyValueTypeHandlers(context, context);
+			int elementCount = context.ReadInt();
+			for (int i = elementCount; i > 0; i--)
+			{
+				context.Defragment(handlers._keyHandler);
+				context.Defragment(handlers._valueHandler);
+			}
+		}
+
+		public void CascadeActivation(IActivationContext context)
+		{
+			IDictionary map = (IDictionary)context.TargetObject();
+			IEnumerator keys = (map).Keys.GetEnumerator();
+			while (keys.MoveNext())
+			{
+				object key = keys.Current;
+				context.CascadeActivationToChild(key);
+				context.CascadeActivationToChild(map[key]);
+			}
+		}
+
+		public virtual ITypeHandler4 ReadCandidateHandler(QueryingReadContext context)
+		{
+			return this;
+		}
+
+		public virtual void CollectIDs(QueryingReadContext context)
+		{
+			KeyValueHandlerPair handlers = ReadKeyValueTypeHandlers(context, context);
+			int elementCount = context.ReadInt();
+			for (int i = 0; i < elementCount; i++)
+			{
+				context.ReadId(handlers._keyHandler);
+				context.SkipId(handlers._valueHandler);
+			}
+		}
+
+		private void WriteClassMetadataIds(IWriteContext context, KeyValueHandlerPair handlers
+			)
+		{
+			context.WriteInt(0);
+			context.WriteInt(0);
+		}
+
+		private KeyValueHandlerPair ReadKeyValueTypeHandlers(IReadBuffer buffer, IContext
+			 context)
+		{
+			buffer.ReadInt();
+			buffer.ReadInt();
+			ITypeHandler4 untypedHandler = (ITypeHandler4)Container(context).Handlers.OpenTypeHandler
+				();
+			return new KeyValueHandlerPair(untypedHandler, untypedHandler);
+		}
+
+		private KeyValueHandlerPair DetectKeyValueTypeHandlers(IInternalObjectContainer container
+			, IDictionary map)
+		{
+			ITypeHandler4 untypedHandler = (ITypeHandler4)container.Handlers.OpenTypeHandler(
+				);
+			return new KeyValueHandlerPair(untypedHandler, untypedHandler);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/SingleClassTypeHandlerPredicate.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/SingleClassTypeHandlerPredicate.cs
new file mode 100644
index 0000000..86479c7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Typehandlers/SingleClassTypeHandlerPredicate.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+	/// <summary>allows installing a Typehandler for a single class.</summary>
+	/// <remarks>allows installing a Typehandler for a single class.</remarks>
+	public sealed class SingleClassTypeHandlerPredicate : ITypeHandlerPredicate
+	{
+		private readonly Type _class;
+
+		public SingleClassTypeHandlerPredicate(Type clazz)
+		{
+			_class = clazz;
+		}
+
+		public bool Match(IReflectClass candidate)
+		{
+			IReflectClass reflectClass = candidate.Reflector().ForClass(_class);
+			return candidate == reflectClass;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Types/IBlob.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Types/IBlob.cs
new file mode 100644
index 0000000..044eb88
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Types/IBlob.cs
@@ -0,0 +1,131 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o.Types;
+
+namespace Db4objects.Db4o.Types
+{
+	/// <summary>
+	/// the db4o Blob type to store blobs independent of the main database
+	/// file and allows to perform asynchronous upload and download operations.
+	/// </summary>
+	/// <remarks>
+	/// the db4o Blob type to store blobs independent of the main database
+	/// file and allows to perform asynchronous upload and download operations.
+	/// <br /><br />
+	/// <b>Usage:</b><br />
+	/// - Define Blob fields on your user classes.<br />
+	/// - As soon as an object of your class is stored, db4o automatically
+	/// takes care that the Blob field is set.<br />
+	/// - Call readFrom to read a blob file into the db4o system.<br />
+	/// - Call writeTo to write a blob file from within the db4o system.<br />
+	/// - getStatus may help you to determine, whether data has been
+	/// previously stored. It may also help you to track the completion
+	/// of the current process.
+	/// <br /><br />
+	/// db4o client/server carries out all blob operations in a separate
+	/// thread on a specially dedicated socket. One socket is used for
+	/// all blob operations and operations are queued. Your application
+	/// may continue to access db4o while a blob is transferred in the
+	/// background.
+	/// </remarks>
+	public interface IBlob : IDb4oType
+	{
+		/// <summary>returns the name of the file the blob was stored to.</summary>
+		/// <remarks>
+		/// returns the name of the file the blob was stored to.
+		/// <br /><br />The method may return null, if the file was never
+		/// stored.
+		/// </remarks>
+		/// <returns>String the name of the file.</returns>
+		string GetFileName();
+
+		/// <summary>returns the status after the last read- or write-operation.</summary>
+		/// <remarks>
+		/// returns the status after the last read- or write-operation.
+		/// <br /><br />The status value returned may be any of the following:<br />
+		/// <see cref="Db4objects.Db4o.Ext.Status.Unused">Db4objects.Db4o.Ext.Status.Unused</see>
+		/// no data was ever stored to the Blob field.<br />
+		/// <see cref="Db4objects.Db4o.Ext.Status.Available">Db4objects.Db4o.Ext.Status.Available
+		/// 	</see>
+		/// available data was previously stored to the Blob field.<br />
+		/// <see cref="Db4objects.Db4o.Ext.Status.Queued">Db4objects.Db4o.Ext.Status.Queued</see>
+		/// an operation was triggered and is waiting for it's turn in the Blob queue.<br />
+		/// <see cref="Db4objects.Db4o.Ext.Status.Completed">Db4objects.Db4o.Ext.Status.Completed
+		/// 	</see>
+		/// the last operation on this field was completed successfully.<br />
+		/// <see cref="Db4objects.Db4o.Ext.Status.Processing">Db4objects.Db4o.Ext.Status.Processing
+		/// 	</see>
+		/// for internal use only.<br />
+		/// <see cref="Db4objects.Db4o.Ext.Status.Error">Db4objects.Db4o.Ext.Status.Error</see>
+		/// the last operation failed.<br />
+		/// or a double between 0 and 1 that signifies the current completion percentage of the currently
+		/// running operation.<br /><br /> the five
+		/// <see cref="Db4objects.Db4o.Ext.Status">Db4objects.Db4o.Ext.Status</see>
+		/// constants defined in this interface or a double
+		/// between 0 and 1 that signifies the completion of the currently running operation.<br /><br />
+		/// </remarks>
+		/// <returns>status - the current status</returns>
+		/// <seealso cref="Db4objects.Db4o.Ext.Status">constants</seealso>
+		double GetStatus();
+
+		/// <summary>reads a file into the db4o system and stores it as a blob.</summary>
+		/// <remarks>
+		/// reads a file into the db4o system and stores it as a blob.
+		/// <br /><br />
+		/// In Client/Server mode db4o will open an additional socket and
+		/// process writing data in an additional thread.
+		/// <br /><br />
+		/// </remarks>
+		/// <param name="file">the file the blob is to be read from.</param>
+		/// <exception cref="System.IO.IOException">in case of errors</exception>
+		void ReadFrom(Sharpen.IO.File file);
+
+		/// <summary>reads a file into the db4o system and stores it as a blob.</summary>
+		/// <remarks>
+		/// reads a file into the db4o system and stores it as a blob.
+		/// <br /><br />
+		/// db4o will use the local file system in Client/Server mode also.
+		/// <br /><br />
+		/// </remarks>
+		/// <param name="file">the file the blob is to be read from.</param>
+		/// <exception cref="System.IO.IOException">in case of errors</exception>
+		void ReadLocal(Sharpen.IO.File file);
+
+		/// <summary>writes stored blob data to a file.</summary>
+		/// <remarks>
+		/// writes stored blob data to a file.
+		/// <br /><br />
+		/// db4o will use the local file system in Client/Server mode also.
+		/// <br /><br />
+		/// </remarks>
+		/// <exception cref="System.IO.IOException">
+		/// in case of errors and in case no blob
+		/// data was stored
+		/// </exception>
+		/// <param name="file">the file the blob is to be written to.</param>
+		void WriteLocal(Sharpen.IO.File file);
+
+		/// <summary>writes stored blob data to a file.</summary>
+		/// <remarks>
+		/// writes stored blob data to a file.
+		/// <br /><br />
+		/// In Client/Server mode db4o will open an additional socket and
+		/// process writing data in an additional thread.
+		/// <br /><br />
+		/// </remarks>
+		/// <exception cref="System.IO.IOException">
+		/// in case of errors and in case no blob
+		/// data was stored
+		/// </exception>
+		/// <param name="file">the file the blob is to be written to.</param>
+		void WriteTo(Sharpen.IO.File file);
+
+		/// <summary>Deletes the current file stored in this BLOB.</summary>
+		/// <remarks>Deletes the current file stored in this BLOB.</remarks>
+		/// <exception cref="System.IO.IOException">
+		/// in case of errors and in case no
+		/// data was stored
+		/// </exception>
+		void DeleteFile();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Types/IDb4oType.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Types/IDb4oType.cs
new file mode 100644
index 0000000..6fb554c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Types/IDb4oType.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Types
+{
+	/// <summary>marker interface for all special db4o types.</summary>
+	/// <remarks>marker interface for all special db4o types.</remarks>
+	public interface IDb4oType
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Types/ITransientClass.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Types/ITransientClass.cs
new file mode 100644
index 0000000..4331637
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Types/ITransientClass.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Types
+{
+	/// <summary>Marker interface to denote that a class should not be stored by db4o.</summary>
+	/// <remarks>Marker interface to denote that a class should not be stored by db4o.</remarks>
+	public interface ITransientClass
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Types/IUnversioned.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Types/IUnversioned.cs
new file mode 100644
index 0000000..b2b22c3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/Types/IUnversioned.cs
@@ -0,0 +1,13 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Types
+{
+	/// <summary>
+	/// marker interface to denote that version numbers and UUIDs should
+	/// not be generated for a class that implements this interface
+	/// </summary>
+	/// <exclude></exclude>
+	public interface IUnversioned
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/User.cs b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/User.cs
new file mode 100644
index 0000000..f1642ee
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Db4objects.Db4o/User.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
+
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o
+{
+	/// <exclude></exclude>
+	/// <persistent></persistent>
+	public class User : IInternal4
+	{
+		public string name;
+
+		public string password;
+
+		public User()
+		{
+		}
+
+		public User(string name_, string password_)
+		{
+			name = name_;
+			password = password_;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/Properties/AssemblyInfo.cs b/lib/db4o-net/Db4objects.Db4o/Properties/AssemblyInfo.cs
new file mode 100755
index 0000000..63dbbd5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/Properties/AssemblyInfo.cs
@@ -0,0 +1,29 @@
+/* Copyright (C) 2009 Versant Inc.   http://www.db4o.com */
+using System;
+using System.Reflection;
+using System.Security;
+
+[assembly: AssemblyTitle("db4o - database for objects")]
+[assembly: AssemblyCompany("Versant Corp., Redwood City, CA, USA")]
+[assembly: AssemblyProduct("db4o - database for objects")]
+[assembly: AssemblyCopyright("Versant Corp. 2000 - 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyName("")]
+
+// attributes are automatically set by the build
+[assembly: AssemblyVersion("8.0.183.14430")]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyConfiguration(".NET")]
+[assembly: AssemblyDescription("Db4objects.Db4o 8.0.183.14430 (.NET)")]
+
+#if !CF && !SILVERLIGHT
+[assembly: AllowPartiallyTrustedCallers]
+#endif
+
+#if NET_4_0
+[assembly: SecurityRules(SecurityRuleSet.Level1)]
+#endif
+
+[assembly: CLSCompliant(true)]
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/ActivatableDictionary.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/ActivatableDictionary.cs
new file mode 100644
index 0000000..8f50065
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/ActivatableDictionary.cs
@@ -0,0 +1,320 @@
+/* Copyright (C) 2010  Versant Inc.   http://www.db4o.com */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+#if !CF && !SILVERLIGHT
+using System.Reflection;
+using System.Runtime.Serialization;
+#endif
+
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Collections
+{
+	[Serializable]
+	public class ActivatableDictionary<TKey, TValue> : 
+									ActivatableBase,
+									IDictionary<TKey, TValue>,
+									IDictionary
+#if !CF	&& !SILVERLIGHT							
+									,ISerializable
+									,IDeserializationCallback
+#endif
+	{
+		public ActivatableDictionary()
+		{
+		}
+
+		public ActivatableDictionary(IEqualityComparer<TKey> comparer)
+		{
+			_dictionary = new Dictionary<TKey, TValue>(comparer);
+		}
+
+		public ActivatableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
+		{
+			_dictionary = new Dictionary<TKey, TValue>(dictionary, comparer);
+		}
+
+		public ActivatableDictionary(IDictionary<TKey, TValue> dictionary)
+		{
+			_dictionary = new Dictionary<TKey, TValue>(dictionary);
+		}
+
+		public ActivatableDictionary(int capacity)
+		{
+			_dictionary = new Dictionary<TKey, TValue>(capacity);
+		}
+
+		public ActivatableDictionary(int capacity, IEqualityComparer<TKey> comparer)
+		{
+			_dictionary = new Dictionary<TKey, TValue>(capacity, comparer);
+		}
+
+#if !CF && !SILVERLIGHT
+		protected ActivatableDictionary(SerializationInfo info, StreamingContext context)
+		{
+			Type type = typeof(Dictionary<TKey, TValue>);
+			ConstructorInfo ctor = type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }, null);
+
+			_dictionary = (IDictionary<TKey, TValue>)ctor.Invoke(new object[] { info, context });
+		}
+#endif
+
+		#region Implementation of IEnumerable
+
+		public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
+		{
+			ActivateForRead();
+			return _dictionary.GetEnumerator();
+		}
+
+		public void Remove(object key)
+		{
+			Remove((TKey) key);
+		}
+
+		object IDictionary.this[object key]
+		{
+			get { return this[(TKey) key]; }
+			set { this[(TKey) key] =  (TValue) value; }
+		}
+
+		IEnumerator IEnumerable.GetEnumerator()
+		{
+			return GetEnumerator();
+		}
+
+		#endregion
+
+		#region Implementation of ICollection<KeyValuePair<TKey,TValue>>
+
+		public void Add(KeyValuePair<TKey, TValue> item)
+		{
+			ActivateForWrite();
+			_dictionary.Add(item);
+		}
+
+		public bool Contains(object key)
+		{
+			return ContainsKey( (TKey) key);
+		}
+
+		public void Add(object key, object value)
+		{
+			Add( (TKey) key, (TValue) value);
+		}
+
+		public void Clear()
+		{
+			ActivateForWrite();
+			_dictionary.Clear();
+		}
+
+		IDictionaryEnumerator IDictionary.GetEnumerator()
+		{
+			ActivateForRead();
+			return Cast<IDictionary>().GetEnumerator();
+		}
+
+		public bool Contains(KeyValuePair<TKey, TValue> item)
+		{
+			ActivateForRead();
+			return _dictionary.Contains(item);
+		}
+
+		public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
+		{
+			ActivateForRead();
+			_dictionary.CopyTo(array, arrayIndex);
+		}
+
+		public bool Remove(KeyValuePair<TKey, TValue> item)
+		{
+			ActivateForWrite();
+			return _dictionary.Remove(item);
+		}
+
+		public void CopyTo(Array array, int index)
+		{
+			ActivateForRead();
+			Cast<IDictionary>().CopyTo(array, index);
+		}
+
+		public int Count
+		{
+			get
+			{
+				ActivateForRead();
+				return _dictionary.Count;
+			}
+		}
+
+		public object SyncRoot
+		{
+			get
+			{
+				return Cast<ICollection>().SyncRoot;
+			}
+		}
+
+		public bool IsSynchronized
+		{
+			get
+			{
+				return Cast<ICollection>().IsSynchronized;
+			}
+		}
+
+		ICollection IDictionary.Values
+		{
+			get { return Values; }
+		}
+
+		public bool IsReadOnly
+		{
+			get
+			{
+				return _dictionary.IsReadOnly;
+			}
+		}
+
+		public bool IsFixedSize
+		{
+			get
+			{
+				return Cast<IDictionary>().IsFixedSize;
+			}
+		}
+
+		#endregion
+
+		#region Implementation of IDictionary<TKey,TValue>
+
+		public bool ContainsKey(TKey key)
+		{
+			ActivateForRead();
+			return _dictionary.ContainsKey(key);
+		}
+
+		public void Add(TKey key, TValue value)
+		{
+			ActivateForWrite();
+			_dictionary.Add(key, value);
+		}
+
+		public bool Remove(TKey key)
+		{
+			ActivateForWrite();
+			return _dictionary.Remove(key);
+		}
+
+		public bool TryGetValue(TKey key, out TValue value)
+		{
+			ActivateForRead();
+			return _dictionary.TryGetValue(key, out value);
+		}
+
+		public TValue this[TKey key]
+		{
+			get
+			{
+				ActivateForRead();
+				return _dictionary[key];
+			}
+
+			set
+			{
+				ActivateForWrite();
+				_dictionary[key] = value;
+			}
+		}
+
+		public ICollection<TKey> Keys
+		{
+			get
+			{
+				ActivateForRead();
+				return _dictionary.Keys;
+			}
+		}
+
+		ICollection IDictionary.Keys
+		{
+			get
+			{
+				ActivateForRead();
+				return Cast<IDictionary>().Keys;
+			}
+		}
+
+		ICollection<TValue> IDictionary<TKey, TValue>.Values
+		{
+			get
+			{
+				ActivateForRead();
+				return _dictionary.Values;
+			}
+		}
+
+		#endregion
+
+		#region Dictionary<TKey, TValue> methods
+
+		public Dictionary<TKey, TValue>.ValueCollection Values
+		{
+			get
+			{
+				ActivateForRead();
+				return ((Dictionary<TKey, TValue>) _dictionary).Values;
+			}
+		}
+
+		public bool ContainsValue(TValue value)
+		{
+			ActivateForRead();
+			return Cast<Dictionary<TKey, TValue>>().ContainsValue(value);
+		}
+
+		public IEqualityComparer<TKey> Comparer
+		{
+			get
+			{
+				return Cast<Dictionary<TKey, TValue>>().Comparer;
+			}
+		}
+
+		#endregion
+
+#if !CF && !SILVERLIGHT
+		#region Implementation of ISerializable
+
+#if NET_4_0
+		[System.Security.SecurityCritical]
+#endif
+		public void GetObjectData(SerializationInfo info, StreamingContext context)
+		{
+			ActivateForRead();
+			Cast<ISerializable>().GetObjectData(info, context);
+		}
+
+		#endregion
+
+		#region Implementation of IDeserializationCallback
+
+		public void OnDeserialization(object sender)
+		{
+			Cast<IDeserializationCallback>().OnDeserialization(sender);
+		}
+
+		#endregion
+#endif
+
+		private T Cast<T>()
+		{
+			return (T)_dictionary;
+		}
+
+		private readonly IDictionary<TKey, TValue> _dictionary = new Dictionary<TKey, TValue>();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/ActivatableList.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/ActivatableList.cs
new file mode 100644
index 0000000..3e7cedc
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/ActivatableList.cs
@@ -0,0 +1,385 @@
+/* Copyright (C) 2010  Versant Inc.   http://www.db4o.com */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using Db4objects.Db4o.Activation;
+using Db4objects.Db4o.Internal.Activation;
+
+namespace Db4objects.Db4o.Collections
+{
+	public class ActivatableList<T> : ActivatableBase, IList<T>, IActivatableCollection<T>
+	{
+		public ActivatableList()
+		{
+		}
+
+		public ActivatableList(IEnumerable<T> source)
+		{
+			_list = new List<T>(source);
+		}
+
+		public ActivatableList(int capacity)
+		{
+			_list = new List<T>(capacity);
+		}
+
+		public ReadOnlyCollection<T> AsReadOnly()
+		{
+			ActivateForRead();
+			return AsList().AsReadOnly();
+		}
+
+		public IEnumerator<T> GetEnumerator()
+		{
+			Activate(ActivationPurpose.Read);
+			return _list.GetEnumerator();
+		}
+
+		IEnumerator IEnumerable.GetEnumerator()
+		{
+			return GetEnumerator();
+		}
+
+		public void Add(T item)
+		{
+			ActivateForWrite();
+			AsList().Add(item);
+		}
+
+		public void AddRange(IEnumerable<T> collection)
+		{
+			ActivateForWrite();
+			AsList().AddRange(collection);
+		}
+
+		public int BinarySearch(T item)
+		{
+			ActivateForRead();
+			return AsList().BinarySearch(item);
+		}
+
+		public int BinarySearch(int index, int count, T item, IComparer<T> comparer)
+		{
+			ActivateForRead();
+			return AsList().BinarySearch(index, count, item, comparer);
+		}
+
+		public int BinarySearch(T item, IComparer<T> comparer)
+		{
+			ActivateForRead();
+			return AsList().BinarySearch(item, comparer);
+		}
+
+		public void Clear()
+		{
+			ActivateForWrite();
+			AsList().Clear();
+		}
+
+		public bool Contains(T item)
+		{
+			ActivateForRead();
+			return AsList().Contains(item);
+		}
+
+		public void CopyTo(T[] array, int arrayIndex)
+		{
+			ActivateForRead();
+			AsList().CopyTo(array, arrayIndex);
+		}
+
+		public void CopyTo(T[] array)
+		{
+			ActivateForRead();
+			AsList().CopyTo(array);
+		}
+
+		public void CopyTo(int index, T[] array, int arrayIndex, int count)
+		{
+			ActivateForRead();
+			AsList().CopyTo(index, array, arrayIndex, count);
+		}
+
+		public override bool Equals(object obj)
+		{
+			ActivateForRead();
+			return AsList().Equals(obj);
+		}
+
+#if !SILVERLIGHT
+		public bool Exists(Predicate<T> match)
+		{
+			ActivateForRead();
+			return AsList().Exists(match);
+		}
+
+		public T Find(Predicate<T> match)
+		{
+			ActivateForRead();
+			return AsList().Find(match);
+		}
+
+		public List<T> FindAll(Predicate<T> match)
+		{
+			ActivateForRead();
+			return AsList().FindAll(match);
+		}
+
+		public int FindIndex(Predicate<T> match)
+		{
+			ActivateForRead();
+			return AsList().FindIndex(match);
+		}
+		
+		public int FindIndex(int startIndex, Predicate<T> match)
+		{
+			ActivateForRead();
+			return AsList().FindIndex(startIndex, match);
+		}
+		
+		public int FindIndex(int startIndex, int count, Predicate<T> match)
+		{
+			ActivateForRead();
+			return AsList().FindIndex(startIndex, count, match);
+		}
+		
+		public T FindLast(Predicate<T> match)
+		{
+			ActivateForRead();
+			return AsList().FindLast(match);
+		}
+		
+		public int FindLastIndex(Predicate<T> match)
+		{
+			ActivateForRead();
+			return AsList().FindLastIndex(match);
+		}
+		
+		public int FindLastIndex(int startIndex, Predicate<T> match)
+		{
+			ActivateForRead();
+			return AsList().FindLastIndex(startIndex, match);
+		}
+		
+		public int FindLastIndex(int startIndex, int count, Predicate<T> match)
+		{
+			ActivateForRead();
+			return AsList().FindLastIndex(startIndex, count, match);
+		}
+#endif
+
+		public void ForEach(Action<T> action)
+		{
+			ActivateForRead();
+			AsList().ForEach(action);
+		}
+
+		public List<T> GetRange(int index, int count)
+		{
+			ActivateForRead();
+			return AsList().GetRange(index, count);
+		}
+
+		public int IndexOf(T item)
+		{
+			ActivateForRead();
+			return AsList().IndexOf(item);
+		}
+
+		public int IndexOf(T item, int index)
+		{
+			ActivateForRead();
+			return AsList().IndexOf(item, index);
+		}
+
+		public int IndexOf(T item, int index, int count)
+		{
+			ActivateForRead();
+			return AsList().IndexOf(item, index, count);
+		}
+
+		public void InsertRange(int index, IEnumerable<T> collection)
+		{
+			ActivateForWrite();
+			AsList().InsertRange(index, collection);
+		}
+
+		public int LastIndexOf(T item)
+		{
+			ActivateForRead();
+			return AsList().LastIndexOf(item);
+		}
+
+		public int LastIndexOf(T item, int index)
+		{
+			ActivateForRead();
+			return AsList().LastIndexOf(item, index);
+		}
+
+		public int LastIndexOf(T item, int index, int count)
+		{
+			ActivateForRead();
+			return AsList().LastIndexOf(item, index, count);
+		}
+
+#if !SILVERLIGHT
+		public int RemoveAll(Predicate<T> match)
+		{
+			ActivateForWrite();
+			return AsList().RemoveAll(match);
+		}
+#endif
+
+		public void RemoveRange(int index, int count)
+		{
+			ActivateForWrite();
+			AsList().RemoveRange(index, count);
+		}
+
+		public void Reverse()
+		{
+			ActivateForWrite();
+			AsList().Reverse();
+		}
+
+		public void Reverse(int index, int count)
+		{
+			ActivateForWrite();
+			AsList().Reverse(index, count);
+		}
+
+		public void Sort()
+		{
+			ActivateForWrite();
+			AsList().Sort();
+		}
+
+		public void Sort(IComparer<T> comparer)
+		{
+			ActivateForWrite();
+			AsList().Sort(comparer);
+		}
+
+		public void Sort(int index, int count, IComparer<T> comparer)
+		{
+			ActivateForWrite();
+			AsList().Sort(index, count, comparer);
+		}
+
+		public void Sort(Comparison<T> comparison)
+		{
+			ActivateForWrite();
+			AsList().Sort(comparison);
+		}
+
+		public T[] ToArray()
+		{
+			ActivateForRead();
+			return AsList().ToArray();
+		}
+
+		public void TrimExcess()
+		{
+			ActivateForWrite();
+			AsList().TrimExcess();
+		}
+
+#if !SILVERLIGHT
+		public bool TrueForAll(Predicate<T> match)
+		{
+			ActivateForRead();
+			return AsList().TrueForAll(match);
+		}
+
+		public List<TOutput> ConvertAll<TOutput>(Converter<T,TOutput> converter)
+		{
+			ActivateForRead();
+			return AsList().ConvertAll(converter);
+		}
+#endif
+        
+		public bool Remove(T item)
+		{
+			ActivateForWrite();
+			return AsList().Remove(item);
+		}
+
+		public int Count
+		{
+			get
+			{
+				ActivateForRead();
+				return AsList().Count;
+			}
+		}
+
+		public int Capacity
+		{
+			get
+			{
+				ActivateForRead();
+				return AsList().Capacity;
+			}
+
+			set
+			{
+				ActivateForWrite();
+				AsList().Capacity = value;
+			}
+		}
+
+		public bool IsReadOnly
+		{
+			get
+			{
+				ActivateForRead();
+				return AsIList().IsReadOnly;
+			}
+		}
+
+		public void Insert(int index, T item)
+		{
+			ActivateForWrite();
+			AsList().Insert(index, item);
+		}
+
+		public void RemoveAt(int index)
+		{
+			ActivateForWrite();
+			AsList().RemoveAt(index);
+		}
+
+		public T this[int index]
+		{
+			get
+			{
+				ActivateForRead();
+				return AsList()[index];
+			}
+
+			set
+			{
+				ActivateForWrite();
+				AsList()[index] = value;
+			}
+		}
+
+		private List<T> AsList()
+		{
+			if (_list == null)
+			{
+				_list = new List<T>();
+			}
+
+			return _list;
+		}
+
+		private IList<T> AsIList()
+		{
+			return AsList();
+		}
+
+		private List<T> _list;
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/ArrayDictionary4.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/ArrayDictionary4.cs
new file mode 100644
index 0000000..fb5312f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/ArrayDictionary4.cs
@@ -0,0 +1,170 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using Db4objects.Db4o.Activation;
+using Db4objects.Db4o.TA;
+
+namespace Db4objects.Db4o.Collections
+{
+	public partial class ArrayDictionary4<K, V> : IDictionary<K, V>, IActivatable
+	{	
+		public bool IsReadOnly
+		{
+			get { return false;  }
+		}
+
+		void ICollection<KeyValuePair<K, V>>.Add(KeyValuePair<K, V> item)
+		{
+			Add(item.Key, item.Value);
+		}
+
+		public void Add(K key, V value)
+		{
+            Activate(ActivationPurpose.Read);
+            int index = IndexOfKey(key);
+            if (index != -1)
+            {
+                throw new ArgumentException(string.Format("Key {0} already exists", key));
+            }
+            Activate(ActivationPurpose.Write);
+            Insert(key, value);
+		}
+
+		public bool Remove(K key)
+		{
+			Activate(ActivationPurpose.Read);
+            int index = IndexOfKey(key);
+            if (index == -1) return false;
+
+            Delete(index);
+            return true;
+		}
+
+		bool ICollection<KeyValuePair<K, V>>.Contains(KeyValuePair<K, V> pair)
+		{
+			Activate(ActivationPurpose.Read);
+            int index = IndexOfKey(pair.Key);
+            if (index == -1) return false;
+
+            KeyValuePair<K, V> thisKeyValuePair = new KeyValuePair<K, V>(pair.Key, ValueAt(index));
+            return EqualityComparer<KeyValuePair<K, V>>.Default.Equals(thisKeyValuePair, pair);
+		}
+
+		void ICollection<KeyValuePair<K, V>>.CopyTo(KeyValuePair<K, V>[] array, int arrayIndex)
+		{	
+            if (array == null) throw new ArgumentNullException();
+            if (arrayIndex < 0) throw new ArgumentOutOfRangeException();
+            if (arrayIndex >= array.Length || Count > (array.Length - arrayIndex)) throw new ArgumentException();
+
+            for (int i = 0; i < Count; i++)
+            {
+                KeyValuePair<K, V> keyValuePair = new KeyValuePair<K, V>(KeyAt(i), ValueAt(i));
+                array[arrayIndex + i] = keyValuePair;
+            }
+		}
+
+		bool ICollection<KeyValuePair<K, V>>.Remove(KeyValuePair<K, V> pair)
+		{
+            if (!((ICollection<KeyValuePair<K, V>>)this).Contains(pair)) return false;
+
+			return Remove(pair.Key);
+		}
+
+		public bool TryGetValue(K key, out V value)
+		{
+			Activate(ActivationPurpose.Read);
+			int index = IndexOfKey(key);
+			if (index == -1)
+			{
+				value = default(V);
+				return false;
+			}
+			value = ValueAt(index);
+			return true;
+		}
+
+		public V this[K key]
+		{
+            get
+            {
+				Activate(ActivationPurpose.Read);
+                int index = IndexOfKey(key);
+                if (index == -1) throw new KeyNotFoundException();
+                return ValueAt(index);
+            }
+            set
+            {	
+				Activate(ActivationPurpose.Read);
+                int index = IndexOfKey(key);
+                if (index == -1)
+                {
+                    Add(key, value);
+                }
+                else
+                {
+					Activate(ActivationPurpose.Write);
+                    Replace(index, value);
+                }
+            }
+		}
+
+		public ICollection<K> Keys
+		{
+            get
+            {
+				Activate(ActivationPurpose.Read);
+                K[] keys = new K[_size];
+                Array.Copy(_keys, keys, _size);
+                return keys;
+            }
+		}
+
+		public bool ContainsKey(K key)
+		{
+			return ContainsKeyImpl(key);
+		}
+
+		public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
+		{
+			Activate(ActivationPurpose.Read);
+			for (int i = 0; i < _size; ++i)
+			{
+				yield return new KeyValuePair<K, V>(KeyAt(i), ValueAt(i));
+			}
+		}
+
+		IEnumerator IEnumerable.GetEnumerator()
+		{
+			return ((IEnumerable<KeyValuePair<K, V>>)this).GetEnumerator();
+		}
+
+        private int IndexOfKey(K key)
+        {
+            if (key == null) throw new ArgumentNullException();
+            return Array.IndexOf(_keys, key);
+        }
+        
+        #region Sharpen Helpers
+        private static K DefaultKeyValue()
+        {
+            return default(K);
+        }
+
+        private static V DefaultValue()
+        {
+            return default(V);    
+        }
+                
+        private static K[] AllocateKeyStorage(int length)
+        {
+            return new K[length];
+        }
+
+        private static V[] AllocateValueStorage(int length)
+        {
+            return new V[length];
+        }
+
+        #endregion
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/ArrayList4.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/ArrayList4.cs
new file mode 100644
index 0000000..7451efa
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/ArrayList4.cs
@@ -0,0 +1,299 @@
+/* Copyright (C) 2009   Versant Inc.   http://www.db4o.com */
+
+#if !SILVERLIGHT
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using Db4objects.Db4o.Activation;
+using Db4objects.Db4o.TA;
+
+namespace Db4objects.Db4o.Collections
+{
+    public partial class ArrayList4<E> : IList<E>, IList, IActivatable
+    {
+        #region Instance Variables
+
+		[NonSerialized]
+        private int modCount;
+
+        #endregion
+
+        public int IndexOf(E item)
+        {
+            return Array.IndexOf(GetElements(), item, 0, listSize);
+        }
+
+        public void Insert(int index, E item)
+        {
+            Add(index, item);
+        }
+
+        public int Add(object value)
+        {
+            CheckObjectType(value);
+            Add((E) value);
+            return Count - 1;
+        }
+
+        public bool Contains(object value)
+        {
+            CheckObjectType(value);
+            return IndexOf(value) != -1;
+        }
+
+        public int IndexOf(object value)
+        {
+            CheckObjectType(value);
+            IList<E> self = this;
+            return self.IndexOf((E) value);
+        }
+
+        public void Insert(int index, object value)
+        {
+            CheckObjectType(value);
+            Insert(index, (E) value);
+        }
+
+        public void Remove(object value)
+        {
+            CheckObjectType(value);
+            Remove((E)value);
+        }
+
+        public void RemoveAt(int index)
+        {
+            RemoveImpl(index);
+        }
+
+        object IList.this[int index]
+        {
+            get { return Get(index); }
+            set { Set(index, (E) value); }
+        }
+
+        public E this[int index]
+        {
+            get { return Get(index); }
+            set { Set(index, value); }
+        }
+
+        public void Add(E item)
+        {
+            Add(Count, item);
+        }
+
+        public bool Contains(E item)
+        {
+            return Contains((object) item);
+        }
+
+        public void CopyTo(E[] array, int arrayIndex)
+        {   
+            CopyTo((Array) array, arrayIndex);
+        }
+
+        public bool Remove(E item)
+        {
+            int index = IndexOf(item);
+            if (index == -1) return false;
+            
+            RemoveAt(index);
+            return true;
+        }
+
+		public void CopyTo(Array array, int index)
+		{
+			if (null == array) throw new ArgumentNullException();
+			if (array.Rank != 1) throw new ArgumentException();
+
+			Array.Copy(GetElements(), 0, array, index, listSize);
+		}
+
+    	public object SyncRoot
+        {
+            get { throw new NotSupportedException(); }
+        }
+
+        public bool IsSynchronized
+        {
+            get { return false; }
+        }
+
+        public bool IsReadOnly
+        {
+            get { return false; }
+        }
+
+        public bool IsFixedSize
+        {
+            get { return false; }
+        }
+
+        public IEnumerator<E> GetEnumerator()
+        {
+			Activate(ActivationPurpose.Read);
+            int version = modCount;
+        	int size = listSize;
+			for (int i = 0; i < size; ++i)
+			{
+				if (version != modCount)
+				{
+					throw new InvalidOperationException();
+				}
+
+				yield return elements[i];
+			};
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return ((IEnumerable<E>) this).GetEnumerator();
+        }
+
+        public override string ToString()
+        {
+            return String.Format("ArrayList4<{0}> (Count={1})", typeof(E).Name, Count);
+        }
+
+        #region Facility methods
+
+        public void AddRange(IEnumerable<E> collection)
+        {
+        }
+    
+        public int BinarySearch(E item)
+        {
+            return Array.BinarySearch(GetElements(), item);
+        }
+
+        public int BinarySearch(E item, IComparer<E> comparer)
+        {
+            return Array.BinarySearch(GetElements(), item, comparer);
+        }
+
+        public int BinarySearch(int index, int count, E item, IComparer<E> comparer)
+        {
+            return Array.BinarySearch(GetElements(), index, count, item, comparer);
+        }
+
+        #if !CF
+
+        public ArrayList4<TOutput> ConvertAll<TOutput>(Converter<E, TOutput> converter)
+        {
+            return new ArrayList4<TOutput>(Array.ConvertAll(GetElements(), converter));
+        }
+
+        public bool Exists(Predicate<E> match)
+        {
+            return Array.Exists(GetElements(), match);
+        }
+
+        public E Find(Predicate<E> match)
+        {
+            return Array.Find(GetElements(), match);
+        }
+
+        public ArrayList4<E> FindAll(Predicate<E> match)
+        {
+            return new ArrayList4<E>(Array.FindAll(GetElements(), match));
+        }
+    
+        public int FindIndex(int startIndex, int count, Predicate<E> match)
+        {
+            return Array.FindIndex(GetElements(), startIndex, count, match);
+        }
+
+        public E FindLast(Predicate<E> match)
+        {
+            return Array.FindLast(GetElements(), match);
+        }
+
+        public int FindLastIndex(int startIndex, int count, Predicate<E> match)
+        {
+            return Array.FindLastIndex(GetElements(), startIndex, count, match);
+        }
+        
+        public void ForEach(Action<E> action)
+        {
+            Array.ForEach(GetElements(), action);
+        }
+
+        #endif
+
+        public void InsertRange(int index, IEnumerable<E> collection)
+        {
+            AddAllImpl(index, new List<E>(collection).ToArray());
+        }
+    
+        public void RemoveRange(int index, int count)
+        {
+            RemoveRangeImpl(index, count);
+        }
+    
+        public void Sort(int index, int count, IComparer<E> comparer)
+        {
+            Array.Sort(GetElements(), index, count, comparer);
+        }
+    
+        public E[] ToArray()
+        {
+            E[] items = GetElements();
+            return items == null ? items : (E[]) items.Clone();
+        }
+
+        public bool TrueForAll(Predicate<E> match)
+        {
+            return Array.TrueForAll(GetElements(), match);
+        }
+
+        #endregion
+
+        #region Sharpen Helper Methods
+
+        private static E[] CollectionToArray(ICollection<E> coll)
+        {
+            return new List<E>(coll).ToArray();
+        }
+
+        internal static void CheckIndex(int index, int from, int to)
+        {
+            if (index < from || index > to)
+            {
+                throw new ArgumentOutOfRangeException(String.Format("Index {0} must be in the range[{1} - {2}]", index, from, to));
+            }
+        }
+
+        private static E[] AllocateStorage(int size)
+        {
+            return new E[size];
+        }
+
+        private static E DefaultValue()
+        {
+             return default(E);
+        }
+
+        #endregion
+
+        #region Helper Methods
+        
+        private static void CheckObjectType(object value)
+        {
+            if (!(value is E))
+            {
+                throw new ArgumentException();
+            }
+        }
+
+        private E[] GetElements()
+        {
+			Activate(ActivationPurpose.Read);
+            return elements;
+        }
+
+        #endregion
+    }
+}
+
+#endif
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/IActivatableCollection.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/IActivatableCollection.cs
new file mode 100644
index 0000000..3779b82
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/IActivatableCollection.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2010  Versant Inc.   http://www.db4o.com */
+using System.Collections.Generic;
+using Db4objects.Db4o.TA;
+
+namespace Db4objects.Db4o.Collections
+{
+	public interface IActivatableCollection<T> : ICollection<T>, IActivatable
+	{
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/ISet.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/ISet.cs
new file mode 100644
index 0000000..627548a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Collections/ISet.cs
@@ -0,0 +1,13 @@
+/* Copyright (C) 2010 Versant Inc.  http://www.db4o.com */
+using System.Collections.Generic;
+
+namespace Db4objects.Db4o.Collections
+{
+	public interface ISet<T> : ICollection<T>
+	{
+		bool IsEmpty { get; }
+		bool AddAll(IEnumerable<T> ts);
+		bool RemoveAll(IEnumerable<T> ts);
+		bool ContainsAll(IEnumerable<T> ts);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/Attributes/ConfigurationIntrospector.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/Attributes/ConfigurationIntrospector.cs
new file mode 100644
index 0000000..7c211ac
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/Attributes/ConfigurationIntrospector.cs
@@ -0,0 +1,66 @@
+/* Copyright (C) 2006   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Reflection;
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Config.Attributes
+{
+	class ConfigurationIntrospector
+	{
+		private readonly Type _type;
+		private Config4Class _classConfig;
+		private readonly IConfiguration _config;
+
+		public ConfigurationIntrospector(Type type, Config4Class classConfig, IConfiguration config)
+		{
+			if (null == type) throw new ArgumentNullException("type");
+			if (null == config) throw new ArgumentNullException("config");
+			_type = type;
+			_classConfig = classConfig;
+			_config = config;
+		}
+
+		public Type Type
+		{
+			get { return _type; }
+		}
+
+		public Config4Class ClassConfiguration
+		{
+			get
+			{
+				if (null == _classConfig)
+				{
+					_classConfig = (Config4Class)_config.ObjectClass(_type);
+				}
+				return _classConfig;
+			}
+		}
+
+		public IConfiguration IConfiguration
+		{
+			get { return _config; }
+		}		
+
+		public void Apply()
+		{
+			Apply(_type);
+			foreach (FieldInfo field in _type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
+				Apply(field);
+		}
+		
+		private void Apply(ICustomAttributeProvider provider)
+		{
+			foreach (object o in provider.GetCustomAttributes(false))
+			{
+				IDb4oAttribute attr = o as IDb4oAttribute;
+				if (null == attr)
+					continue;
+				
+				attr.Apply(provider, this);
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/Attributes/IDb4oAttribute.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/Attributes/IDb4oAttribute.cs
new file mode 100644
index 0000000..c9ed245
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/Attributes/IDb4oAttribute.cs
@@ -0,0 +1,11 @@
+/* Copyright (C) 2006   Versant Inc.   http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Config.Attributes
+{
+	interface IDb4oAttribute
+	{
+		void Apply (object subject, ConfigurationIntrospector introspector);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/Attributes/IndexedAttribute.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/Attributes/IndexedAttribute.cs
new file mode 100644
index 0000000..c09af04
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/Attributes/IndexedAttribute.cs
@@ -0,0 +1,17 @@
+/* Copyright (C) 2006   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Reflection;
+
+namespace Db4objects.Db4o.Config.Attributes
+{
+	[AttributeUsage(AttributeTargets.Field)]
+	public class IndexedAttribute : Attribute, IDb4oAttribute
+	{
+		void IDb4oAttribute.Apply(object subject, ConfigurationIntrospector introspector)
+		{
+			FieldInfo field = (FieldInfo)subject;
+			introspector.ClassConfiguration.ObjectField(field.Name).Indexed(true);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TClass.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TClass.cs
new file mode 100644
index 0000000..bacd1ee
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TClass.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+using Sharpen.Lang;
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.Config
+{
+	
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TCultureInfo.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TCultureInfo.cs
new file mode 100644
index 0000000..665ab51
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TCultureInfo.cs
@@ -0,0 +1,33 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Globalization;
+using Sharpen.Lang;
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <exclude />
+	public class TCultureInfo : IObjectConstructor
+	{
+		public Object OnInstantiate(IObjectContainer store, object stored)
+		{
+			return new CultureInfo((string)stored);
+		}
+
+		public Object OnStore(IObjectContainer store, object obj)
+		{
+			CultureInfo culture = (CultureInfo)obj;
+			return culture.Name;
+		}
+
+		public void OnActivate(IObjectContainer container, object applicationObject, object storedObject)
+		{
+		}
+
+		public Type StoredClass()
+		{		
+			return typeof(string);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TDictionary.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TDictionary.cs
new file mode 100644
index 0000000..06d86fe
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TDictionary.cs
@@ -0,0 +1,44 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Sharpen.Lang;
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.Config {
+
+	/// <exclude />
+    public class TDictionary : IObjectTranslator {
+
+        public void OnActivate(IObjectContainer objectContainer, object obj, object members){
+            IDictionary dict = (IDictionary)obj;
+            dict.Clear();
+            if(members != null){
+                Entry[] entries = (Entry[]) members;
+                for(int i = 0; i < entries.Length; i++){
+                    if(entries[i].key != null && entries[i].value != null){
+                        dict[entries[i].key] =  entries[i].value;
+                    }
+                }
+            }
+        }
+
+        public Object OnStore(IObjectContainer objectContainer, object obj){
+            IDictionary dict = (IDictionary)obj;
+            Entry[] entries = new Entry[dict.Count];
+            IDictionaryEnumerator e = dict.GetEnumerator();
+            e.Reset();
+            for(int i = 0; i < dict.Count; i++){
+                e.MoveNext();
+                entries[i] = new Entry();
+                entries[i].key = e.Key;
+                entries[i].value = e.Value;
+            }
+            return entries;
+        }
+
+        public System.Type StoredClass(){
+            return typeof(Entry[]);
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TList.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TList.cs
new file mode 100644
index 0000000..9f05c88
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TList.cs
@@ -0,0 +1,37 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Sharpen.Lang;
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.Config {
+
+	/// <exclude />
+    public class TList : IObjectTranslator {
+
+        public void OnActivate(IObjectContainer objectContainer, object obj, object members){
+            IList list = (IList)obj;
+            list.Clear();
+            if(members != null){
+                object[] elements = (object[]) members;
+                for(int i = 0; i < elements.Length; i++){
+                    list.Add(elements[i]);
+                }
+            }
+        }
+
+        public Object OnStore(IObjectContainer objectContainer, object obj){
+            IList list = (IList)obj;
+            object[] elements = new object[list.Count];
+            for(int i = 0; i < list.Count; i++){
+                elements[i] = list[i];
+            }
+            return elements;
+        }
+
+        public System.Type StoredClass(){
+            return typeof(object[]);
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TQueue.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TQueue.cs
new file mode 100644
index 0000000..d6921ad
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TQueue.cs
@@ -0,0 +1,49 @@
+/* Copyright (C) 2009   Versant Inc.   http://www.db4o.com */
+
+#if !SILVERLIGHT
+
+using System;
+using System.Collections;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <exclude />
+	public class TQueue : IObjectTranslator
+	{
+		public void OnActivate(IObjectContainer objectContainer, object obj, object members)
+		{
+			Queue queue = (Queue) obj;
+			queue.Clear();
+			if (members != null)
+			{
+				object[] elements = (object[])members;
+				for (int i = 0; i < elements.Length; i++)
+				{
+					queue.Enqueue(elements[i]);
+				}
+			}
+		}
+
+		public Object OnStore(IObjectContainer objectContainer, object obj)
+		{
+			Queue queue = (Queue)obj;
+			int count = queue.Count;
+			object[] elements = new object[count];
+			IEnumerator e = queue.GetEnumerator();
+			e.Reset();
+			for (int i = 0; i < count; i++)
+			{
+				e.MoveNext();
+				elements[i] = e.Current;
+			}
+			return elements;
+		}
+
+		public System.Type StoredClass()
+		{
+			return typeof(object[]);
+		}
+	}
+}
+
+#endif
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TStack.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TStack.cs
new file mode 100644
index 0000000..49e960e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TStack.cs
@@ -0,0 +1,42 @@
+/* Copyright (C) 2009   Versant Inc.   http://www.db4o.com */
+
+#if !SILVERLIGHT
+
+using System;
+using System.Collections;
+
+namespace Db4objects.Db4o.Config {
+
+	/// <exclude />
+    public class TStack : IObjectTranslator {
+
+        public void OnActivate(IObjectContainer objectContainer, object obj, object members){
+            Stack stack = (Stack)obj;
+            if(members != null){
+                object[] elements = (object[]) members;
+                for(int i = elements.Length - 1; i >= 0 ; i--){
+                    stack.Push(elements[i]);
+                }
+            }
+        }
+
+        public Object OnStore(IObjectContainer objectContainer, object obj){
+            Stack stack = (Stack)obj;
+            int count = stack.Count;
+            object[] elements = new object[count];
+            IEnumerator e = stack.GetEnumerator();
+            e.Reset();
+            for(int i = 0; i < count; i++){
+                e.MoveNext();
+                elements[i] = e.Current;
+            }
+            return elements;
+        }
+
+        public System.Type StoredClass(){
+            return typeof(object[]);
+        }
+    }
+}
+
+#endif
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TTransient.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TTransient.cs
new file mode 100644
index 0000000..c09db3a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TTransient.cs
@@ -0,0 +1,33 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+using Sharpen.Lang;
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+
+    /// <exclude />
+    public class TTransient : IObjectConstructor
+    {
+        public void OnActivate(IObjectContainer objectContainer, object obj, object members)
+        {
+        }
+
+        public object OnStore(IObjectContainer objectContainer, object obj)
+        {
+            return null;
+        }
+
+        public System.Type StoredClass()
+        {
+            return typeof(object);
+        }
+
+        public object OnInstantiate(IObjectContainer objectContainer, object storedObject)
+        {
+            return null;
+        }
+
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TType.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TType.cs
new file mode 100644
index 0000000..0782a92
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Config/TType.cs
@@ -0,0 +1,42 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+using Sharpen.Lang;
+using Db4objects.Db4o;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <exclude />
+    public class TType : IObjectConstructor
+    {		
+        public void OnActivate(IObjectContainer objectContainer, object obj, object members)
+        {
+        }
+      
+        public Object OnInstantiate(IObjectContainer objectContainer, object obj)
+        {
+        	if (obj != null)
+        	{
+            	try
+	            {
+    	            return TypeReference.FromString((string) obj).Resolve();
+        	    }
+            	catch
+	            { 
+	            }
+			}
+			return null; 
+        }
+      
+        public Object OnStore(IObjectContainer objectContainer, object obj)
+        {
+        	if (obj == null) return null;
+            return TypeReference.FromType((Type)obj).GetUnversionedName();
+        }
+      
+        public Type StoredClass()
+        {
+            return typeof(string);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Defragment/AvailableTypeFilter.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Defragment/AvailableTypeFilter.cs
new file mode 100644
index 0000000..6f94ef9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Defragment/AvailableTypeFilter.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+
+using System;
+
+namespace Db4objects.Db4o.Defragment
+{
+	public class AvailableTypeFilter : IStoredClassFilter
+	{
+		
+		/// <param name="storedClass">StoredClass instance to be checked</param>
+		/// <returns>true, if the given StoredClass instance should be accepted, false otherwise.
+		/// 	</returns>
+		public bool Accept(IStoredClass storedClass)
+		{
+			return System.Type.GetType(storedClass.GetName(),false)!=null;
+		}
+		
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Diagnostic/DiagnosticToTrace.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Diagnostic/DiagnosticToTrace.cs
new file mode 100644
index 0000000..ccd5e21
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Diagnostic/DiagnosticToTrace.cs
@@ -0,0 +1,28 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+namespace Db4objects.Db4o.Diagnostic
+{
+#if !CF
+    /// <summary>prints Diagnostic messsages to the Console.</summary>
+    /// <remarks>
+    /// prints Diagnostic messsages to System.Diagnostics.Trace.
+    /// Install this
+    /// <see cref="Db4objects.Db4o.Diagnostic.IDiagnosticListener">Db4objects.Db4o.Diagnostic.IDiagnosticListener
+    /// 	</see>
+    /// with: <br />
+    /// <code>commonConfig.Diagnostic.AddListener(new DiagnosticToTrace());</code><br />
+    /// </remarks>
+    /// <seealso cref="Db4objects.Db4o.Diagnostic.DiagnosticConfiguration">Db4objects.Db4o.Diagnostic.DiagnosticConfiguration
+    /// 	</seealso>
+    public class DiagnosticToTrace : Db4objects.Db4o.Diagnostic.IDiagnosticListener
+    {
+        /// <summary>redirects Diagnostic messages to System.Diagnostics.Trace</summary>
+        /// <remarks>redirects Diagnostic messages to the Console.</remarks>
+        public virtual void OnDiagnostic(Db4objects.Db4o.Diagnostic.IDiagnostic d)
+        {
+#if !SILVERLIGHT        	
+			System.Diagnostics.Trace.WriteLine(d.ToString());
+#endif
+        }
+    }
+#endif
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Dynamic.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Dynamic.cs
new file mode 100644
index 0000000..523dda1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Dynamic.cs
@@ -0,0 +1,44 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Reflection;
+
+namespace Db4objects.Db4o {
+
+	/// <exclude />
+    public class Dynamic {
+
+		private const BindingFlags AllMembers = BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
+
+        public static object GetProperty(object obj, string prop){
+            if(obj != null){
+                Type type = TypeForObject(obj);
+                try {
+                    PropertyInfo pi = type.GetProperty(prop, AllMembers);
+                    return pi.GetValue(obj,null);
+                } catch {
+                }
+            }
+            return null;
+        }
+
+        public static void SetProperty(object obj, string prop, object val){
+            if(obj != null){
+                Type type = TypeForObject(obj);
+                try {
+                    PropertyInfo pi = type.GetProperty(prop, AllMembers);
+                    pi.SetValue(obj, val, null);
+                } catch {
+                }
+            }
+        }
+
+        private static Type TypeForObject(object obj){
+            Type type = obj as Type;
+            if(type != null){
+                return type;
+            }
+            return obj.GetType();
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/CRC32.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/CRC32.cs
new file mode 100644
index 0000000..104b665
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/CRC32.cs
@@ -0,0 +1,52 @@
+namespace Db4objects.Db4o.Foundation
+{
+    public class CRC32
+    {
+        private static uint[] crcTable;
+
+        static CRC32()
+        {
+            BuildCRCTable();
+        }
+
+        private static void BuildCRCTable()
+        {
+            uint Crc32Polynomial = 0xEDB88320;
+            uint i;
+            uint j;
+            uint crc;
+            crcTable = new uint[256];
+            for (i = 0; i <= 255; i++)
+            {
+                crc = i;
+                for (j = 8; j > 0; j--)
+                {
+                    if ((crc & 1) == 1)
+                    {
+                        crc = ((crc) >> (1 & 0x1f)) ^ Crc32Polynomial;
+                    }
+                    else
+                    {
+                        crc = crc >> (1 & 0x1f);
+                    }
+                }
+                crcTable[i] = crc;
+            }
+        }
+
+        public static long CheckSum(byte[] buffer, int start, int count)
+        {
+            uint temp1;
+            uint temp2;
+            int i = start;
+            uint crc = 0xFFFFFFFF;
+            while (count-- != 0)
+            {
+                temp1 = (crc) >> (8 & 0x1f);
+                temp2 = crcTable[(crc ^ buffer[i++]) & 0xFF];
+                crc = temp1 ^ temp2;
+            }
+            return (long)~crc & 0xFFFFFFFFL;
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/Closures4.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/Closures4.cs
new file mode 100644
index 0000000..51ed26b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/Closures4.cs
@@ -0,0 +1,28 @@
+/* Copyright (C) 2004 - 2008  Versant Inc.  http://www.db4o.com */
+namespace Db4objects.Db4o.Foundation
+{
+	class Closures4
+	{
+		public delegate object Closure();
+
+		public static IClosure4 ForDelegate(Closure @delegate)
+		{
+			return new Closure4OverDelegate(@delegate);
+		}
+
+		internal class Closure4OverDelegate : IClosure4
+		{
+			private Closure _delegate;
+
+			public Closure4OverDelegate(Closure @delegate)
+			{
+				_delegate = @delegate;
+			}
+
+			public object Run()
+			{
+				return _delegate();
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/Coercion4.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/Coercion4.cs
new file mode 100644
index 0000000..df19510
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/Coercion4.cs
@@ -0,0 +1,72 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+using System;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class Coercion4
+	{
+		public static object ToByte(object obj)
+		{
+			if (obj is byte) return obj;
+
+			IConvertible convertible = obj as IConvertible;
+			if (null != convertible) return convertible.ToByte(null);
+			return Db4objects.Db4o.Foundation.No4.Instance;
+		}
+
+		public static object ToSByte(object obj)
+		{
+			if (obj is sbyte) return obj;
+
+			IConvertible convertible = obj as IConvertible;
+			if (null != convertible) return convertible.ToSByte(null);
+			return Db4objects.Db4o.Foundation.No4.Instance;
+		}
+
+		public static object ToShort(object obj)
+		{
+			if (obj is short) return obj;
+
+			IConvertible convertible = obj as IConvertible;
+			if (null != convertible) return convertible.ToInt16(null);
+			return Db4objects.Db4o.Foundation.No4.Instance;
+		}
+
+		public static object ToInt(object obj)
+		{
+			if (obj is int) return obj;
+
+			IConvertible convertible = obj as IConvertible;
+			if (null != convertible) return convertible.ToInt32(null);
+			return Db4objects.Db4o.Foundation.No4.Instance;
+		}
+
+		public static object ToLong(object obj)
+		{
+			if (obj is long) return obj;
+
+			IConvertible convertible = obj as IConvertible;
+			if (null != convertible) return convertible.ToInt64(null);
+			return Db4objects.Db4o.Foundation.No4.Instance;
+		}
+
+		public static object ToFloat(object obj)
+		{
+			if (obj is float) return obj;
+
+			IConvertible convertible = obj as IConvertible;
+			if (null != convertible) return convertible.ToSingle(null);
+			return Db4objects.Db4o.Foundation.No4.Instance;
+		}
+
+		public static object ToDouble(object obj)
+		{
+			if (obj is double) return obj;
+
+			IConvertible convertible = obj as IConvertible;
+			if (null != convertible) return convertible.ToDouble(null);
+			return Db4objects.Db4o.Foundation.No4.Instance;
+		}
+	}
+}
+
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/Collections/CollectionInitializer.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/Collections/CollectionInitializer.cs
new file mode 100644
index 0000000..0db905a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/Collections/CollectionInitializer.cs
@@ -0,0 +1,277 @@
+/* Copyright (C) 2008   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+#if CF
+using System.Reflection;
+#endif
+
+namespace Db4objects.Db4o.Foundation.Collections
+{
+	public interface ICollectionInitializer
+	{
+		void Clear();
+		void Add(object o);
+		void FinishAdding();
+	    int Count();
+	}
+
+	public sealed class CollectionInitializer
+	{
+		private static readonly Dictionary<Type, Type> _initializerByType = new Dictionary<Type, Type>();
+
+		static CollectionInitializer()
+		{
+			_initializerByType[typeof (ICollection<>)] = typeof (CollectionInitializerImpl<>);
+			_initializerByType[typeof(Stack<>)] = typeof(StackInitializer<>);
+			_initializerByType[typeof(Queue<>)] = typeof(QueueInitializer<>);
+#if NET_3_5 && ! CF
+		    _initializerByType[typeof (HashSet<>)] = typeof (HashSetInitializer<>);
+#endif
+		}
+
+		public static ICollectionInitializer For(object destination)
+		{
+			if (IsNonGenericList(destination))
+			{
+			    return new ListInitializer((IList)destination);
+			}
+
+			return InitializerFor(destination);
+		}
+
+		private static ICollectionInitializer InitializerFor(object destination)
+		{
+			Type destinationType = destination.GetType();
+			if (!destinationType.IsGenericType)
+			{
+				throw new ArgumentException("Unknown collection: " + destination);
+			}
+
+			Type containerType = GenericContainerTypeFor(destination);
+			if (containerType != null)
+			{
+				return GetInitializer(destination, _initializerByType[containerType]);
+			}
+
+			throw new ArgumentException("Unknown collection: " + destination);
+		}
+
+		private static Type GenericContainerTypeFor(object destination)
+		{
+			Type containerType = destination.GetType().GetGenericTypeDefinition();
+			while (containerType != null && !_initializerByType.ContainsKey(containerType))
+			{
+				foreach (Type interfaceType in containerType.GetInterfaces())
+				{
+					if (!interfaceType.IsGenericType)
+					{
+						continue;
+					}
+
+					Type genericInterfaceType = interfaceType.GetGenericTypeDefinition();
+					if (_initializerByType.ContainsKey(genericInterfaceType))
+					{
+						return genericInterfaceType;
+					}
+				}
+
+				containerType = containerType.BaseType;
+			}
+
+			return containerType;
+		}
+
+		private static ICollectionInitializer GetInitializer(object destination, Type initializerType)
+		{
+			ICollectionInitializer initializer = null;
+			Type containedElementType = ContainerElementTypeFor(destination);
+			if (containedElementType != null)
+			{
+				Type genericProtocolType = initializerType.MakeGenericType(containedElementType);
+				initializer = InstantiateInitializer(destination, genericProtocolType);
+			}
+			return initializer;
+		}
+
+		private static bool IsNonGenericList(object destination)
+		{
+			return !destination.GetType().IsGenericType && destination is IList;
+		}
+
+		private static ICollectionInitializer InstantiateInitializer(object destination, Type genericProtocolType)
+	    {
+#if !CF
+            return (ICollectionInitializer) Activator.CreateInstance(genericProtocolType, destination);
+#else
+	        ConstructorInfo constructor = genericProtocolType.GetConstructors()[0];
+	        return (ICollectionInitializer) constructor.Invoke(new object[] {destination});
+#endif
+	    }
+
+	    private static Type ContainerElementTypeFor(object destination)
+		{
+	    	Type containerType = destination.GetType();
+	    	return containerType.GetGenericArguments()[0];
+		}
+
+		private sealed class ListInitializer : ICollectionInitializer
+		{
+			private readonly IList _list;
+
+			public ListInitializer(IList list)
+			{
+				_list = list;
+			}
+
+			public void Clear()
+			{
+				_list.Clear();
+			}
+
+			public void Add(object o)
+			{
+				_list.Add(o);
+			}
+
+            public int Count()
+            {
+                return _list.Count;
+            }
+
+			public void FinishAdding()
+			{
+			}
+		}
+
+		private sealed class CollectionInitializerImpl<T> : ICollectionInitializer
+		{
+			private readonly ICollection<T> _collection;
+
+			public CollectionInitializerImpl(ICollection<T> collection)
+			{
+				_collection = collection;
+			}
+
+			public void Clear()
+			{
+				_collection.Clear();
+			}
+
+            public int Count()
+            {
+                return _collection.Count;
+            }
+
+			public void Add(object o)
+			{
+				_collection.Add((T)o);
+			}
+
+			public void FinishAdding()
+			{
+			}
+		}
+
+		private sealed class StackInitializer<T> : ICollectionInitializer
+		{
+			private readonly Stack<T> _stack;
+			private readonly Stack<T> _tempStack;
+
+			public StackInitializer(Stack<T> stack)
+			{
+				_stack= stack;
+				_tempStack = new Stack<T>();
+			}
+
+			public void Clear()
+			{
+				_tempStack.Clear();
+				_stack.Clear();
+			}
+
+            public int Count()
+            {
+                return _stack.Count;
+            }
+
+			public void Add(object o)
+			{
+				_tempStack.Push((T) o);
+			}
+
+			public void FinishAdding()
+			{
+				foreach(T item in _tempStack)
+				{
+					_stack.Push(item);
+				}
+
+				_tempStack.Clear();
+			}
+		}
+
+		private sealed class QueueInitializer<T> : ICollectionInitializer
+		{
+			private readonly Queue<T> _queue;
+
+			public QueueInitializer(Queue<T> queue)
+			{
+				_queue = queue;
+			}
+
+			public void Clear()
+			{
+				_queue.Clear();
+			}
+
+            public int Count()
+            {
+                return _queue.Count;
+            }
+
+			public void Add(object o)
+			{
+				_queue.Enqueue((T) o);
+			}
+
+			public void FinishAdding()
+			{
+			}
+		}
+
+#if NET_3_5 && ! CF
+        private sealed class HashSetInitializer<T> : ICollectionInitializer
+        {
+            private readonly HashSet<T> _hashSet;
+
+            public HashSetInitializer(HashSet<T> stack)
+            {
+                _hashSet = stack;
+            }
+
+            public void Clear()
+            {
+                _hashSet.Clear();
+            }
+
+            public void Add(object o)
+            {
+                _hashSet.Add((T)o);
+            }
+
+            public int Count()
+            {
+                return _hashSet.Count;
+            }
+
+            public void FinishAdding()
+            {
+            }
+        }
+#endif
+
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/Environments.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/Environments.cs
new file mode 100644
index 0000000..3803ec4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/Environments.cs
@@ -0,0 +1,30 @@
+/* Copyright (C) 2009 Versant Inc.  http://www.db4o.com */
+using System;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public partial class Environments
+	{
+		public static string DefaultImplementationFor(Type type)
+		{
+			string implName = ("." + type.Name.Substring(1) + "Impl");
+			if (type.Namespace.IndexOf(".Internal.") > 0)
+				return type.Namespace + implName + ", " + AssemblyNameFor(type);
+
+			int lastDot = type.Namespace.LastIndexOf('.');
+			string typeName = type.Namespace.Substring(0, lastDot) + ".Internal." + type.Namespace.Substring(lastDot + 1) + implName;
+			return typeName + ", " + AssemblyNameFor(type);
+		}
+
+		private static string AssemblyNameFor(Type type)
+		{
+#if SILVERLIGHT
+			string fullyQualifiedTypeName = type.AssemblyQualifiedName;
+			int assemblyNameSeparator = fullyQualifiedTypeName.IndexOf(',');
+			return fullyQualifiedTypeName.Substring(assemblyNameSeparator + 1);
+#else
+			return type.Assembly.GetName().Name;
+#endif
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/IO/File4.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/IO/File4.cs
new file mode 100644
index 0000000..851e850
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/IO/File4.cs
@@ -0,0 +1,30 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+#if !SILVERLIGHT
+using System;
+
+using System.IO;
+
+namespace Db4objects.Db4o.Foundation.IO
+{
+    public class File4
+    {
+        public static void Delete(string file)
+        {
+            if (File.Exists(file))
+            {
+                File.Delete(file);
+            }
+        }
+
+        public static void Copy(string from, string to)
+        {
+            File.Copy(from, to, true);
+        }
+
+		public static long Size(string filePath)
+		{
+			return new System.IO.FileInfo(filePath).Length;
+		}
+	}
+}
+#endif
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/Iterators.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/Iterators.cs
new file mode 100644
index 0000000..3d31a7c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/Iterators.cs
@@ -0,0 +1,62 @@
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public delegate B Function<A, B>(A a);
+
+	public struct Tuple<A, B>
+	{
+		public A a;
+		public B b;
+
+		public Tuple(A a, B b)
+		{
+			this.a = a;
+			this.b = b;
+		}
+	}
+
+	public partial class Iterators
+	{
+		public static IEnumerator Map(System.Array array, IFunction4 function)
+		{
+			return Map(array.GetEnumerator(), function);
+		}
+
+		public static IEnumerable<T> Cast<T>(IEnumerable source)
+		{
+			foreach (object o in source) yield return (T) o;
+		}
+
+		public static IEnumerable<Tuple<object, object>> Zip(IEnumerable @as, IEnumerable bs)
+		{
+			return Zip(Cast<object>(@as), Cast<object>(bs));
+		}
+
+		public static IEnumerable<Tuple<A, B>> Zip<A, B>(IEnumerable<A> @as, IEnumerable<B> bs)
+		{
+			IEnumerator<B> bsEnumerator = bs.GetEnumerator();
+			foreach (A a in @as)
+			{
+				if (!bsEnumerator.MoveNext())
+				{
+					yield break;
+				}
+
+				yield return new Tuple<A, B>(a, bsEnumerator.Current);
+			}
+		}
+
+		public static IEnumerable Unique(IEnumerable enumerable)
+		{
+			Hashtable seen = new Hashtable();
+			foreach (object item in enumerable)
+			{
+				if (seen.ContainsKey(item)) continue;
+				seen.Add(item, item);
+				yield return item;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/My.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/My.cs
new file mode 100644
index 0000000..f0d891b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/My.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2009  Versant Inc.  http://www.db4o.com */
+
+namespace Db4objects.Db4o.Foundation
+{
+	public class My<TService>
+	{
+		public static TService Instance
+		{
+			get { return (TService)Environments.My(typeof(TService));  }
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/RunnableAction.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/RunnableAction.cs
new file mode 100644
index 0000000..87c4f82
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/RunnableAction.cs
@@ -0,0 +1,22 @@
+/* Copyright (C) 2009  Versant Inc.  http://www.db4o.com */
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Foundation
+{
+	public delegate void Action4();
+
+	public class RunnableAction : IRunnable
+	{
+		private readonly Action4 _action;
+
+		public RunnableAction(Action4 action)
+		{
+			_action = action;
+		}
+
+		public void Run()
+		{
+			_action();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/SignatureGenerator.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/SignatureGenerator.cs
new file mode 100644
index 0000000..4f09877
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Foundation/SignatureGenerator.cs
@@ -0,0 +1,37 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Foundation
+{
+    public sealed class SignatureGenerator
+    {
+        private static Random _random = new Random();
+	
+	    private static int _counter;
+	
+	    public static string GenerateSignature() {
+            string signature = ToHexString(Environment.TickCount);
+            signature += Pad(ToHexString(_random.Next()));
+            signature += Guid.NewGuid();
+            signature += ToHexString(_counter++);
+            return signature;
+	    }
+
+        private static string ToHexString(int i)
+        {
+            return i.ToString("X");
+        }
+
+        private static string ToHexString(long l)
+        {
+            return l.ToString("X");
+        }
+
+        private static string Pad(String str)
+        {
+            return (str + "XXXXXXXX").Substring(0, 8);
+        }
+
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/IO/RandomAccessFileFactory.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/IO/RandomAccessFileFactory.cs
new file mode 100644
index 0000000..31fca7f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/IO/RandomAccessFileFactory.cs
@@ -0,0 +1,43 @@
+using System;
+using System.IO;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal;
+using Sharpen.IO;
+using File=Sharpen.IO.File;
+
+namespace Db4objects.Db4o.IO
+{
+    public class RandomAccessFileFactory
+    {
+        public static RandomAccessFile NewRandomAccessFile(String path, bool readOnly, bool lockFile)
+        {
+            RandomAccessFile raf = null;
+            bool ok = false;
+            try
+            {
+                raf = new RandomAccessFile(path, readOnly, lockFile);
+                if (lockFile)
+                {
+                    Platform4.LockFile(path, raf);
+                }
+                ok = true;
+                return raf;
+            }
+            catch (IOException x)
+            {
+                if (new File(path).Exists())
+                {
+                    throw new DatabaseFileLockedException(path, x);
+                }
+                throw new Db4oIOException(x);
+            } 
+            finally
+            {
+                if(!ok && raf != null)
+                {
+                    raf.Close();
+                }
+            }
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/IObjectContainer.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/IObjectContainer.cs
new file mode 100644
index 0000000..cc2f1fb
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/IObjectContainer.cs
@@ -0,0 +1,496 @@
+/* Copyright (C) 2004 - 1010  Versant Inc.   http://www.db4o.com */
+using Db4objects.Db4o.Qlin;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o
+{
+	/// <summary>the interface to a db4o database, stand-alone or client/server.</summary>
+	/// <remarks>
+	/// the interface to a db4o database, stand-alone or client/server.
+	/// <br /><br />The IObjectContainer interface provides methods
+	/// to store, query and delete objects and to commit and rollback
+	/// transactions.<br /><br />
+	/// An IObjectContainer can either represent a stand-alone database
+	/// or a connection to a
+	/// <see cref="Db4objects.Db4o.Db4o.OpenServer">db4o server</see>
+	/// .
+	/// <br /><br />An IObjectContainer also represents a transaction. All work
+	/// with db4o always is transactional. Both
+	/// <see cref="Db4objects.Db4o.IObjectContainer.Commit">Db4objects.Db4o.IObjectContainer.Commit</see>
+	/// and
+	/// <see cref="Db4objects.Db4o.IObjectContainer.Rollback">Db4objects.Db4o.IObjectContainer.Rollback</see>
+	/// start new transactions immediately. For working
+	/// against the same database with multiple transactions, open a db4o server
+	/// with
+	/// <see cref="Db4objects.Db4o.Db4o.OpenServer">Db4objects.Db4o.Db4o.OpenServer</see>
+	/// and
+	/// <see cref="Db4objects.Db4o.ObjectServer.OpenClient">connect locally</see>
+	/// or
+	/// <see cref="Db4objects.Db4o.Db4o.OpenClient">over TCP</see>
+	/// .
+	/// </remarks>
+	/// <seealso cref="Db4objects.Db4o.Ext.IExtObjectContainer">IExtObjectContainer for extended functionality.
+	/// 	</seealso>
+	public interface IObjectContainer : System.IDisposable, ISodaQueryFactory
+	{
+		/// <summary>activates all members on a stored object to the specified depth.</summary>
+		/// <remarks>
+		/// activates all members on a stored object to the specified depth.
+		/// <br /><br />
+		/// See
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration.ActivationDepth">"Why activation"</see>
+		/// for an explanation why activation is necessary.<br /><br />
+		/// The activate method activates a graph of persistent objects in memory.
+		/// Only deactivated objects in the graph will be touched: their
+		/// fields will be loaded from the database.
+		/// The activate methods starts from a
+		/// root object and traverses all member objects to the depth specified by the
+		/// depth parameter. The depth parameter is the distance in "field hops"
+		/// (object.field.field) away from the root object. The nodes at 'depth' level
+		/// away from the root (for a depth of 3: object.member.member) will be instantiated
+		/// but deactivated, their fields will be null.
+		/// The activation depth of individual classes can be overruled
+		/// with the methods
+		/// <see cref="Db4objects.Db4o.Config.IObjectClass.MaximumActivationDepth">MaximumActivationDepth()
+		/// 	</see>
+		/// and
+		/// <see cref="Db4objects.Db4o.Config.IObjectClass.MinimumActivationDepth">MinimumActivationDepth()
+		/// 	</see>
+		/// in the
+		/// <see cref="Db4objects.Db4o.Config.IObjectClass">ObjectClass interface</see>
+		/// .<br /><br />
+		/// A successful call to activate triggers Activating and Activated callback methods,
+		/// which can be used for cascaded activation.<br /><br />
+		/// </remarks>
+		/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.ActivationDepth">Why activation?</seealso>
+		/// <seealso cref="Db4objects.Db4o.Ext.IObjectCallbacks">Using callbacks</seealso>
+		/// <param name="obj">the object to be activated.</param>
+		/// <param name="depth">
+		/// the member
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration.ActivationDepth">depth</see>
+		/// to which activate is to cascade.
+		/// </param>
+		void Activate(object obj, int depth);
+
+		/// <summary>closes this IObjectContainer.</summary>
+		/// <remarks>
+		/// closes this IObjectContainer.
+		/// <br /><br />A call to Close() automatically performs a
+		/// <see cref="Db4objects.Db4o.IObjectContainer.Commit">Commit()</see>
+		/// .
+		/// <br /><br />Note that every session opened with Db4oFactory.OpenFile() requires one
+		/// Close()call, even if the same filename was used multiple times.<br /><br />
+		/// Use <code>while(!Close()){}</code> to kill all sessions using this container.<br /><br />
+		/// </remarks>
+		/// <returns>
+		/// success - true denotes that the last used instance of this container
+		/// and the database file were closed.
+		/// </returns>
+		bool Close();
+
+		/// <summary>commits the running transaction.</summary>
+		/// <remarks>
+		/// commits the running transaction.
+		/// <br /><br />Transactions are back-to-back. A call to commit will starts
+		/// a new transaction immedidately.
+		/// </remarks>
+		void Commit();
+
+		/// <summary>deactivates a stored object by setting all members to <code>NULL</code>.
+		/// 	</summary>
+		/// <remarks>
+		/// deactivates a stored object by setting all members to <code>NULL</code>.
+		/// <br />Primitive types will be set to their default values.
+		/// Calls to this method save memory.
+		/// The method has no effect, if the passed object is not stored in the
+		/// <code>IObjectContainer</code>.<br /><br />
+		/// <code>Deactivate()</code> triggers Deactivating and Deactivated callbacks.
+		/// <br /><br />
+		/// Be aware that calling this method with a depth parameter greater than
+		/// 1 sets members on member objects to null. This may have side effects
+		/// in other places of the application.<br /><br />
+		/// </remarks>
+		/// <seealso cref="Db4objects.Db4o.Ext.IObjectCallbacks">Using callbacks</seealso>
+		/// <seealso cref="Db4objects.Db4o.Config.IConfiguration.ActivationDepth">Why activation?</seealso>
+		/// <param name="obj">the object to be deactivated.</param>
+		/// <param name="depth">
+		/// the member
+		/// <see cref="Db4objects.Db4o.Config.IConfiguration.ActivationDepth">depth</see>
+		/// 
+		/// to which deactivate is to cascade.
+		/// </param>
+		void Deactivate(object obj, int depth);
+
+		/// <summary>deletes a stored object permanently.</summary>
+		/// <remarks>
+		/// deletes a stored object permanently.
+		/// <br /><br />Note that this method has to be called <b>for every single object
+		/// individually</b>. Delete does not recurse to object members. Simple
+		/// and array member types are destroyed.
+		/// <br /><br />Object members of the passed object remain untouched, unless
+		/// cascaded deletes are
+		/// <see cref="Db4objects.Db4o.Config.IObjectClass.CascadeOnDelete">configured for the class</see>
+		/// or for
+		/// <see cref="Db4objects.Db4o.Config.IObjectField.CascadeOnDelete">one of the member fields</see>
+		/// .
+		/// <br /><br />The method has no effect, if
+		/// the passed object is not stored in the <code>IObjectContainer</code>.
+		/// <br /><br />A subsequent call to
+		/// <code>Store()</code> with the same object newly stores the object
+		/// to the <code>IObjectContainer</code>.<br /><br />
+		/// <code>Delete()</code> triggers Deleting and Deleted callbacks,
+		/// which can be also used for cascaded deletes.<br /><br />
+		/// </remarks>
+		/// <seealso cref="Db4objects.Db4o.Config.IObjectClass.CascadeOnDelete">Db4objects.Db4o.Config.IObjectClass.CascadeOnDelete
+		/// 	</seealso>
+		/// <seealso cref="Db4objects.Db4o.Config.IObjectField.CascadeOnDelete">Db4objects.Db4o.Config.IObjectField.CascadeOnDelete
+		/// 	</seealso>
+		/// <seealso cref="Db4objects.Db4o.Ext.IObjectCallbacks">Using callbacks</seealso>
+		/// <param name="obj">
+		/// the object to be deleted from the
+		/// <code>IObjectContainer</code>.<br />
+		/// </param>
+		void Delete(object obj);
+
+		/// <summary>returns an IObjectContainer with extended functionality.</summary>
+		/// <remarks>
+		/// returns an IObjectContainer with extended functionality.
+		/// <br /><br />Every IObjectContainer that db4o provides can be casted to
+		/// an IExtObjectContainer. This method is supplied for your convenience
+		/// to work without a cast.
+		/// <br /><br />The IObjectContainer functionality is split to two interfaces
+		/// to allow newcomers to focus on the essential methods.<br /><br />
+		/// </remarks>
+		/// <returns>this, casted to IExtObjectContainer</returns>
+		Db4objects.Db4o.Ext.IExtObjectContainer Ext();
+
+        /// <summary>Query-By-Example interface to retrieve objects.</summary>
+        /// <remarks>
+        /// Query-By-Example interface to retrieve objects.
+        /// <br /><br /><code>QueryByExample()</code> creates an
+        /// <see cref="Db4objects.Db4o.IObjectSet">IObjectSet</see>
+        /// containing
+        /// all objects in the <code>IObjectContainer</code> that match the passed
+        /// template object.<br /><br />
+        /// Calling <code>QueryByExample(null)</code> returns all objects stored in the
+        /// <code>IObjectContainer</code>.<br /><br /><br />
+        /// <b>Query Evaluation</b>
+        /// <br />All non-null members of the template object are compared against
+        /// all stored objects of the same class.
+        /// Primitive type members are ignored if they are 0 or false respectively.
+        /// <br /><br />Arrays and all supported <code>Collection</code> classes are
+        /// evaluated for containment. Differences in <code>Length/Count/Size()</code> are
+        /// ignored.
+        /// <br /><br />Consult the documentation of the IConfiguration package to
+        /// configure class-specific behaviour.<br /><br /><br />
+        /// <b>Returned Objects</b><br />
+        /// The objects returned in the
+        /// <see cref="Db4objects.Db4o.IObjectSet">IObjectSet</see>
+        /// are instantiated
+        /// and activated to the preconfigured depth of 5. The
+        /// <see cref="Db4objects.Db4o.Config.IConfiguration.ActivationDepth">activation depth</see>
+        /// may be configured
+        /// <see cref="Db4objects.Db4o.Config.IConfiguration.ActivationDepth">globally</see>
+        /// or
+        /// <see cref="Db4objects.Db4o.Config.IObjectClass">individually for classes</see>
+        /// .
+        /// <br /><br />
+        /// db4o keeps track of all instantiatied objects. Queries will return
+        /// references to these objects instead of instantiating them a second time.
+        /// <br /><br />
+        /// Objects newly activated by <code>QueryByExample()</code> can respond to the Activating callback
+        /// method.
+        /// <br /><br />
+        /// </remarks>
+        /// <param name="template">object to be used as an example to find all matching objects.<br /><br />
+        /// 	</param>
+        /// <returns>
+        /// 
+        /// <see cref="Db4objects.Db4o.IObjectSet">IObjectSet</see>
+        /// containing all found objects.<br /><br />
+        /// </returns>
+        /// <seealso cref="Db4objects.Db4o.Config.IConfiguration.ActivationDepth">Why activation?</seealso>
+        /// <seealso cref="Db4objects.Db4o.Ext.IObjectCallbacks">Using callbacks</seealso>
+        Db4objects.Db4o.IObjectSet QueryByExample(object template);
+
+
+		/// <summary>
+		/// creates a new SODA
+		/// <see cref="Db4objects.Db4o.Query.IQuery">Query</see>
+		/// .
+		/// <br /><br />
+		/// Linq queries are the recommended main db4o query interface.
+		/// <br /><br />
+		/// Use
+		/// <see cref="Db4objects.Db4o.IObjectContainer.QueryByExample">QueryByExample(Object template)</see>
+		/// for simple Query-By-Example.<br /><br />
+		/// </summary>
+		/// <returns>a new IQuery object</returns>
+		Db4objects.Db4o.Query.IQuery Query();
+
+		/// <summary>queries for all instances of a class.</summary>
+		/// <remarks>queries for all instances of a class.</remarks>
+		/// <param name="clazz">the class to query for.</param>
+		/// <returns>
+		/// the
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// returned by the query.
+		/// </returns>
+		Db4objects.Db4o.IObjectSet Query(System.Type clazz);
+
+		/// <summary>Native Query Interface.</summary>
+		/// <remarks>
+		/// Native Query Interface.
+		/// <br /><br />Native Queries allow typesafe, compile-time checked and refactorable
+		/// querying, following object-oriented principles. Native Queries expressions
+		/// are written as if one or more lines of code would be run against all
+		/// instances of a class. A Native Query expression should return true to mark
+		/// specific instances as part of the result set.
+		/// db4o will  attempt to optimize native query expressions and execute them
+		/// against indexes and without instantiating actual objects, where this is
+		/// possible.<br /><br />
+		/// Example:<br /><br />
+		/// <code>
+		/// <br />
+		/// IList <Cat> cats = db.Query <Cat> (delegate(Cat cat) {<br />
+		///    return cat.Name == "Occam";<br />
+		/// });<br />
+		/// <br />
+		/// Summing up the above:<br />
+		/// In order to run a Native Query, you can use the delegate notation 
+	        /// with a delegate method taking the extend type as a parameter and 
+		/// returning bool. True is returned for the objects that are to be included in the result.<br />
+		/// <br /><br />
+		/// </remarks>
+		/// <param name="predicate">
+		/// the
+		/// <see cref="Db4objects.Db4o.Query.Predicate">Db4objects.Db4o.Query.Predicate</see>
+		/// containing the native query expression.
+		/// </param>
+		/// <returns>
+		/// the
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// returned by the query.
+		/// </returns>
+		Db4objects.Db4o.IObjectSet Query(Db4objects.Db4o.Query.Predicate predicate);
+
+		/// <summary>Native Query Interface.</summary>
+		/// <remarks>
+		/// Native Query Interface. Queries as with
+		/// <see cref="M:Db4objects.Db4o.IObjectContainer.Query(Db4objects.Db4o.Query.Predicate)">Db4objects.Db4o.IObjectContainer.Query(Predicate)</see>
+		/// ,
+		/// but will sort the resulting
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// according to the given
+		/// <see cref="Db4objects.Db4o.Query.IQueryComparator">Db4objects.Db4o.Query.IQueryComparator</see>
+		/// .
+		/// </remarks>
+		/// <param name="predicate">
+		/// the
+		/// <see cref="Db4objects.Db4o.Query.Predicate">Db4objects.Db4o.Query.Predicate</see>
+		/// containing the native query expression.
+		/// </param>
+		/// <param name="comparator">
+		/// the
+		/// <see cref="Db4objects.Db4o.Query.IQueryComparator">Db4objects.Db4o.Query.IQueryComparator</see>
+		/// specifiying the sort order of the result
+		/// </param>
+		/// <returns>
+		/// the
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// returned by the query.
+		/// </returns>
+		Db4objects.Db4o.IObjectSet Query(Db4objects.Db4o.Query.Predicate predicate, Db4objects.Db4o.Query.IQueryComparator
+			 comparator);
+
+		/// <summary>Native Query Interface.</summary>
+		/// <remarks>
+		/// Native Query Interface. Queries as with
+		/// <see cref="M:Db4objects.Db4o.IObjectContainer.Query(Db4objects.Db4o.Query.Predicate)">Db4objects.Db4o.IObjectContainer.Query(Predicate)</see>
+		/// ,
+		/// but will sort the resulting
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// according to the given
+		/// <see cref="System.Collections.IComparer">System.Collections.IComparer</see>
+		/// .
+		/// </remarks>
+		/// <param name="predicate">
+		/// the
+		/// <see cref="Db4objects.Db4o.Query.Predicate">Db4objects.Db4o.Query.Predicate</see>
+		/// containing the native query expression.
+		/// </param>
+		/// <param name="comparator">
+		/// the
+		/// <see cref="System.Collections.IComparer">System.Collections.IComparer</see>
+		/// specifiying the sort order of the result
+		/// </param>
+		/// <returns>
+		/// the
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// returned by the query.
+		/// </returns>
+		Db4objects.Db4o.IObjectSet Query(Db4objects.Db4o.Query.Predicate predicate, System.Collections.IComparer comparer);
+
+		/// <summary>rolls back the running transaction.</summary>
+		/// <remarks>
+		/// rolls back the running transaction.
+		/// <br /><br />Transactions are back-to-back. A call to rollback will starts
+		/// a new transaction immedidately.
+		/// <br /><br />rollback will not restore modified objects in memory. They
+		/// can be refreshed from the database by calling
+		/// <see cref="Db4objects.Db4o.Ext.IExtObjectContainer.Refresh">Db4objects.Db4o.Ext.IExtObjectContainer.Refresh
+		/// 	</see>
+		/// .
+		/// </remarks>
+		void Rollback();
+
+        /// <summary>newly stores objects or updates stored objects.</summary>
+        /// <remarks>
+        /// newly stores objects or updates stored objects.
+        /// <br /><br />An object not yet stored in the <code>IObjectContainer</code> will be
+        /// stored when it is passed to <code>Store()</code>. An object already stored
+        /// in the <code>IObjectContainer</code> will be updated.
+        /// <br /><br /><b>Updates</b><br />
+        /// - will affect all simple type object members.<br />
+        /// - links to object members that are already stored will be updated.<br />
+        /// - new object members will be newly stored. The algorithm traverses down
+        /// new members, as long as further new members are found.<br />
+        /// - object members that are already stored will <b>not</b> be updated
+        /// themselves.<br />Every object member needs to be updated individually with a
+        /// call to <code>Store()</code> unless a deep
+        /// <see cref="Db4objects.Db4o.Config.IConfiguration.UpdateDepth">global</see>
+        /// or
+        /// <see cref="Db4objects.Db4o.Config.IObjectClass.UpdateDepth">class-specific</see>
+        /// update depth was configured or cascaded updates were
+        /// <see cref="Db4objects.Db4o.Config.IObjectClass.CascadeOnUpdate">defined in the class</see>
+        /// or in
+        /// <see cref="Db4objects.Db4o.Config.IObjectField.CascadeOnUpdate">one of the member fields</see>
+        /// .
+       	/// Depending if the passed object is newly stored or updated, Creating/Created or
+       	/// Updaing/Updated callback method is triggered.
+       	/// Callbacks
+       	/// might also be used for cascaded updates.<br /><br />
+        /// </remarks>
+        /// <param name="obj">the object to be stored or updated.</param>
+        /// <seealso cref="Db4objects.Db4o.Ext.IExtObjectContainer.Store">IExtObjectContainer#Store(object, depth)
+        /// 	</seealso>
+        /// <seealso cref="Db4objects.Db4o.Config.IConfiguration.UpdateDepth">Db4objects.Db4o.Config.IConfiguration.UpdateDepth
+        /// 	</seealso>
+        /// <seealso cref="Db4objects.Db4o.Config.IObjectClass.UpdateDepth">Db4objects.Db4o.Config.IObjectClass.UpdateDepth
+        /// 	</seealso>
+        /// <seealso cref="Db4objects.Db4o.Config.IObjectClass.CascadeOnUpdate">Db4objects.Db4o.Config.IObjectClass.CascadeOnUpdate
+        /// 	</seealso>
+        /// <seealso cref="Db4objects.Db4o.Config.IObjectField.CascadeOnUpdate">Db4objects.Db4o.Config.IObjectField.CascadeOnUpdate
+        /// 	</seealso>
+        /// <seealso cref="Db4objects.Db4o.Ext.IObjectCallbacks">Using callbacks</seealso>
+        void Store(object obj);
+
+        /// <summary>.NET 2.0 Native Query interface.</summary>
+        /// <remarks>
+        /// Native Query Interface.
+        /// <br /><br />Native Queries allow typesafe, compile-time checked and refactorable
+        /// querying, following object-oriented principles. Native Queries expressions
+        /// are written as if one or more lines of code would be run against all
+        /// instances of a class. A Native Query expression should return true to mark
+        /// specific instances as part of the result set.
+        /// db4o will  attempt to optimize native query expressions and execute them
+        /// against indexes and without instantiating actual objects, where this is
+        /// possible.<br /><br />
+	/// Example:<br /><br />
+       	/// <code>
+       	/// <br />
+       	/// IList <Cat> cats = db.Query <Cat> (delegate(Cat cat) {<br />
+       	///    return cat.Name == "Occam";<br />
+       	/// });<br />
+       	/// <br />
+       	/// Summing up the above:<br />
+       	/// In order to run a Native Query, you can use the delegate notation 
+               /// with a delegate method taking the extend type as a parameter and 
+       	/// returning bool. True is returned for the objects that are to be included in the result.<br />
+       	/// <br /><br />
+        /// </remarks>
+        /// <param name="match">
+        /// use an anonymous delegate that takes a single paramter and returns
+        /// a bool value, see the syntax example above
+        /// </param>
+        /// <returns>
+        /// the
+        /// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+        /// returned by the query.
+        /// </returns>
+        System.Collections.Generic.IList<Extent> Query<Extent>(System.Predicate<Extent> match);
+        
+		/// <summary>Native Query Interface.</summary>
+		/// <remarks>
+		/// Native Query Interface. Queries as with
+		/// <see cref="M:Db4objects.Db4o.IObjectContainer.Query(Db4objects.Db4o.Query.Predicate)">Db4objects.Db4o.IObjectContainer.Query(Predicate)</see>
+		/// ,
+		/// but will sort the resulting
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// according to the given
+		/// <see cref="System.Collections.Generic.IComparer">System.Collections.Generic.IComparer</see>
+		/// .
+		/// </remarks>
+		/// <param name="predicate">
+		/// the
+		/// <see cref="Db4objects.Db4o.Query.Predicate">Db4objects.Db4o.Query.Predicate</see>
+		/// containing the native query expression.
+		/// </param>
+		/// <param name="comparator">
+		/// the
+		/// <see cref="System.Collections.Generic.IComparer">System.Collections.Generic.IComparer</see>
+		/// specifiying the sort order of the result
+		/// </param>
+		/// <returns>
+		/// the
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// returned by the query.
+		/// </returns>
+		System.Collections.Generic.IList<Extent> Query<Extent>(System.Predicate<Extent> match, System.Collections.Generic.IComparer<Extent> comparer);
+
+		/// <summary>Native Query Interface.</summary>
+		/// <remarks>
+		/// Native Query Interface. Queries as with
+		/// <see cref="M:Db4objects.Db4o.IObjectContainer.Query(Db4objects.Db4o.Query.Predicate)">Db4objects.Db4o.IObjectContainer.Query(Predicate)</see>
+		/// ,
+		/// but will sort the resulting
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// according to the given
+		/// <see cref="System.Comparison">System.Comparison</see>
+		/// .
+		/// </remarks>
+		/// <param name="predicate">
+		/// the
+		/// <see cref="Db4objects.Db4o.Query.Predicate">Db4objects.Db4o.Query.Predicate</see>
+		/// containing the native query expression.
+		/// </param>
+		/// <param name="comparator">
+		/// the
+		/// <see cref="System.Comparison">System.Comparison</see>
+		/// specifiying the sort order of the result
+		/// </param>
+		/// <returns>
+		/// the
+		/// <see cref="Db4objects.Db4o.IObjectSet">Db4objects.Db4o.IObjectSet</see>
+		/// returned by the query.
+		/// </returns>
+		System.Collections.Generic.IList<Extent> Query<Extent>(System.Predicate<Extent> match, System.Comparison<Extent> comparison);
+
+		/// <summary>
+		/// queries for all instances of the type extent, returning
+		/// a IList of ElementType which must be assignable from
+		/// extent.
+		/// </summary>
+		System.Collections.Generic.IList<ElementType> Query<ElementType>(System.Type extent);
+		
+		/// <summary>
+		/// queries for all instances of the type extent.
+		/// </summary>
+		System.Collections.Generic.IList<Extent> Query<Extent>();
+
+		/// <summary>
+		/// queries for all instances of the type extent sorting with the specified comparer.
+		/// </summary>
+		System.Collections.Generic.IList<Extent> Query<Extent>(System.Collections.Generic.IComparer<Extent> comparer);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Collections/BigSet.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Collections/BigSet.cs
new file mode 100644
index 0000000..dd1cdbf
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Collections/BigSet.cs
@@ -0,0 +1,81 @@
+/* Copyright (C) 2010 Versant Inc.  http://www.db4o.com */
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Db4objects.Db4o.Internal.Collections
+{
+	public partial class BigSet<E>
+	{
+		#region Implementation of ICollection
+
+		void ICollection<E>.Add(E item)
+		{
+			Add(item);
+		}
+
+		bool ICollection<E>.Contains(E item)
+		{
+			return Contains(item);
+		}
+
+		void ICollection<E>.CopyTo(E[] array, int arrayIndex)
+		{
+			throw new System.NotImplementedException();
+		}
+
+		bool ICollection<E>.Remove(E item)
+		{
+			return Remove(item);
+		}
+
+		public bool IsReadOnly
+		{
+			get { return false; }
+		}
+
+		IEnumerator<E> IEnumerable<E>.GetEnumerator()
+		{
+			IEnumerator iterator = BTreeIterator();
+			while (iterator.MoveNext())
+			{
+				yield return (E)Element((int) iterator.Current);
+			}
+		}
+
+		IEnumerator IEnumerable.GetEnumerator()
+		{
+			return ((IEnumerable<E>)this).GetEnumerator();
+		}
+
+		#endregion
+
+		#region Implementation of ISet<E>
+
+		bool Db4o.Collections.ISet<E>.RemoveAll(IEnumerable<E> es)
+		{
+			bool result = false;
+			foreach (E e in es)
+			{
+				if (Remove(e))
+				{
+					result = true;
+				}
+			}
+			return result;
+		}
+
+		bool Db4o.Collections.ISet<E>.ContainsAll(IEnumerable<E> es)
+		{
+			foreach (E e in es)
+			{
+				if (!Contains(e))
+				{
+					return false;
+				}
+			}
+			return true;
+		}
+
+		#endregion
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/ComparerAdaptor.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/ComparerAdaptor.cs
new file mode 100644
index 0000000..0902e82
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/ComparerAdaptor.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+using System;
+using System.Text;
+
+namespace Db4objects.Db4o.Internal
+{
+    class ComparerAdaptor : Db4objects.Db4o.Query.IQueryComparator
+    {
+        private System.Collections.IComparer _comparer;
+
+        public ComparerAdaptor(System.Collections.IComparer comparer)
+        {
+            _comparer = comparer;
+        }
+
+        public int Compare(object first, object second)
+        {
+            return _comparer.Compare(first, second);
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Config4Impl.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Config4Impl.cs
new file mode 100644
index 0000000..dca5afc
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Config4Impl.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2009   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Reflection;
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Internal
+{
+	public partial class Config4Impl
+	{
+		private static ILegacyClientServerFactory DefaultClientServerFactory()
+		{
+			Assembly csAssembly = Assembly.Load(ClientServerAssemblyName());
+			return (ILegacyClientServerFactory) Activator.CreateInstance(csAssembly.GetType("Db4objects.Db4o.CS.Internal.Config.LegacyClientServerFactoryImpl"));
+		}
+
+		private static string ClientServerAssemblyName()
+		{
+			Assembly db4oAssembly = typeof(IObjectContainer).Assembly;
+			string db4oAssemblySimpleName = db4oAssembly.GetName().Name;
+			return db4oAssembly.FullName.Replace(db4oAssemblySimpleName, "Db4objects.Db4o.CS");
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Const4.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Const4.cs
new file mode 100644
index 0000000..2f47054
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Const4.cs
@@ -0,0 +1,8 @@
+/* Copyright (C) 2004 - 2008  Versant Inc.  http://www.db4o.com */
+namespace Db4objects.Db4o.Internal
+{
+    public sealed partial class Const4
+    {
+        public const int MaxStackDepth = 20;
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Convert/Conversions/DropClassIndexesConversion.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Convert/Conversions/DropClassIndexesConversion.cs
new file mode 100644
index 0000000..610ffbe
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Convert/Conversions/DropClassIndexesConversion.cs
@@ -0,0 +1,22 @@
+/* Copyright (C) 2009  Versant Inc.  http://www.db4o.com */
+namespace Db4objects.Db4o.Internal.Convert.Conversions
+{
+	public abstract class DropClassIndexesConversion : Conversion
+	{
+		public override void Convert(ConversionStage.SystemUpStage stage)
+		{
+			LocalObjectContainer file = stage.File();
+			ClassMetadataIterator i = file.ClassCollection().Iterator();
+			while (i.MoveNext())
+			{
+				ClassMetadata classmetadata = i.CurrentClass();
+				if (Accept(classmetadata))
+				{
+					classmetadata.DropClassIndex();
+				}
+			}
+		}
+
+		protected abstract bool Accept(ClassMetadata classmetadata);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Convert/Conversions/DropDateTimeOffsetClassIndexes_7_12.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Convert/Conversions/DropDateTimeOffsetClassIndexes_7_12.cs
new file mode 100644
index 0000000..a530d26
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Convert/Conversions/DropDateTimeOffsetClassIndexes_7_12.cs
@@ -0,0 +1,18 @@
+/* Copyright (C) 2009  Versant Inc.  http://www.db4o.com */
+using System;
+using Db4objects.Db4o.Reflect.Net;
+
+namespace Db4objects.Db4o.Internal.Convert.Conversions
+{
+	public partial class DropDateTimeOffsetClassIndexes_7_12 : DropClassIndexesConversion
+	{
+		protected override bool Accept(ClassMetadata classmetadata)
+		{
+#if CF || SILVERLIGHT
+			return false;
+#else
+			return NetReflector.ToNative(classmetadata.ClassReflector()) == typeof(DateTimeOffset);
+#endif
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Convert/Conversions/DropEnumClassIndexes_7_10.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Convert/Conversions/DropEnumClassIndexes_7_10.cs
new file mode 100644
index 0000000..b6de20e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Convert/Conversions/DropEnumClassIndexes_7_10.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2009  Versant Inc.  http://www.db4o.com */
+using System;
+using Db4objects.Db4o.Reflect.Net;
+
+namespace Db4objects.Db4o.Internal.Convert.Conversions
+{
+	public partial class DropEnumClassIndexes_7_10 : DropClassIndexesConversion
+	{
+		protected override bool Accept(ClassMetadata classmetadata)
+		{
+			Type type = NetReflector.ToNative(classmetadata.ClassReflector());
+			return type != null ? type.IsEnum : false;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Convert/Conversions/DropGuidClassIndexes_7_12.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Convert/Conversions/DropGuidClassIndexes_7_12.cs
new file mode 100644
index 0000000..0808bf7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Convert/Conversions/DropGuidClassIndexes_7_12.cs
@@ -0,0 +1,14 @@
+/* Copyright (C) 2009  Versant Inc.  http://www.db4o.com */
+using System;
+using Db4objects.Db4o.Reflect.Net;
+
+namespace Db4objects.Db4o.Internal.Convert.Conversions
+{
+	public partial class DropGuidClassIndexes_7_12 : DropClassIndexesConversion
+	{
+		protected override bool Accept(ClassMetadata classmetadata)
+		{
+			return NetReflector.ToNative(classmetadata.ClassReflector()) == typeof(Guid);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Convert/Conversions/ReindexNetDateTime_7_8.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Convert/Conversions/ReindexNetDateTime_7_8.cs
new file mode 100644
index 0000000..dfcdaa7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Convert/Conversions/ReindexNetDateTime_7_8.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2004 - 2009   Versant Inc.   http://www.db4o.com */
+using System;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Net;
+
+namespace Db4objects.Db4o.Internal.Convert.Conversions
+{
+    partial class ReindexNetDateTime_7_8 : Conversion
+    {
+		public override void Convert(ConversionStage.SystemUpStage stage)
+		{
+			ReindexDateTimeFields(stage);
+		}
+
+		private static void ReindexDateTimeFields(ConversionStage stage)
+		{
+			DateTimeFieldReindexer reindexer = new DateTimeFieldReindexer();
+			
+			ClassMetadataIterator i = stage.File().ClassCollection().Iterator();
+			while (i.MoveNext())
+			{
+				ClassMetadata classmetadata = i.CurrentClass();
+				classmetadata.TraverseDeclaredFields(reindexer);
+			}
+		}
+		
+		private class DateTimeFieldReindexer : IProcedure4
+		{
+			public void Apply(object field)
+			{
+				if (!((FieldMetadata)field).HasIndex())
+				{
+					return;
+				}
+				ReindexDateTimeField(((FieldMetadata)field));
+			}
+
+			private static void ReindexDateTimeField(IStoredField field)
+			{
+				IReflectClass claxx = field.GetStoredType();
+				if (claxx == null)
+				{
+					return;
+				}
+
+				Type t = NetReflector.ToNative(claxx);
+				if (t == typeof(DateTime) || t == typeof(DateTime?))
+				{
+					field.DropIndex();
+					field.CreateIndex();
+				}
+			}
+		}
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Encoding/UTF8StringEncoding.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Encoding/UTF8StringEncoding.cs
new file mode 100644
index 0000000..a727cff
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Encoding/UTF8StringEncoding.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2008   Versant Inc.   http://www.db4o.com */
+using System;
+
+namespace Db4objects.Db4o.Internal.Encoding
+{
+    public class UTF8StringEncoding : BuiltInStringEncoding
+    {
+        public override byte[] Encode(String str)
+        {
+            return System.Text.Encoding.UTF8.GetBytes(str);
+        }
+
+        public override String Decode(byte[] bytes, int start, int length)
+        {
+            return System.Text.Encoding.UTF8.GetString(bytes, start, length);
+        }
+
+    }
+
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/GenericTypeHandlerPredicate.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/GenericTypeHandlerPredicate.cs
new file mode 100644
index 0000000..cb02e90
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/GenericTypeHandlerPredicate.cs
@@ -0,0 +1,32 @@
+/* Copyright (C) 2008   Versant Inc.   http://www.db4o.com */
+using System;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Net;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.native.Db4objects.Db4o.Internal
+{
+	public class GenericTypeHandlerPredicate : ITypeHandlerPredicate
+	{
+		private readonly Type _genericType;
+
+		public GenericTypeHandlerPredicate(Type genericType)
+		{
+			_genericType = genericType;
+		}
+
+		public bool Match(IReflectClass classReflector)
+		{
+			Type type = NetReflector.ToNative(classReflector);
+			if (type == null)
+			{
+				return false;
+			}
+			if (!type.IsGenericType)
+			{
+				return false;
+			}
+			return type.GetGenericTypeDefinition() == _genericType;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/DateHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/DateHandler.cs
new file mode 100644
index 0000000..b74d832
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/DateHandler.cs
@@ -0,0 +1,30 @@
+/* Copyright (C) 2004 - 2009   Versant Inc.   http://www.db4o.com */
+using System;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	public class DateHandler : DateHandlerBase
+	{	
+		public override object DefaultValue()
+		{
+			return DateTime.MinValue;
+		}
+
+		public override object PrimitiveNull()
+		{
+			return DateTime.MinValue;
+		}
+
+		public override object NullRepresentationInUntypedArrays()
+		{
+			return null;
+		}
+
+		public override object CopyValue(object from, object to)
+		{
+			// nothing to do since we already have a immutable
+			// copy
+			return from;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/DateTimeHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/DateTimeHandler.cs
new file mode 100644
index 0000000..703f9f8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/DateTimeHandler.cs
@@ -0,0 +1,94 @@
+/* Copyright (C) 2004 - 2007   Versant Inc.   http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Marshall;
+using Sharpen;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	public class DateTimeHandler : StructHandler
+	{
+		public override Object DefaultValue()
+		{
+			return DateTime.MinValue;
+		}
+
+		public override Object Read(byte[] bytes, int offset)
+		{
+			long ticks = 0;
+			for (int i = 0; i < 8; i++)
+			{
+				ticks = (ticks << 8) + (bytes[offset++] & 255);
+			}
+		    return ReadKind(new DateTime(ticks), bytes, offset);
+		}
+
+	    protected virtual DateTime ReadKind (DateTime dateTime, byte[] bytes, int offset)
+	    {
+            int kind  = 0;
+            for (int i = 0; i < 4; i++)
+            {
+                kind = (kind << 8) + (bytes[offset++] & 255);
+            }
+            return DateTime.SpecifyKind(dateTime, (DateTimeKind)kind);
+	    }
+
+	    public override int TypeID()
+		{
+			return 25;
+		}
+
+		public override void Write(object obj, byte[] bytes, int offset)
+		{
+			long ticks = ((DateTime)obj).Ticks;
+			for (int i = 0; i < 8; i++)
+			{
+				bytes[offset++] = (byte)(int)(ticks >> (7 - i) * 8);
+			}
+		    WriteKind((DateTime)obj, bytes, offset);
+		}
+
+	    protected virtual void WriteKind(DateTime dateTime, byte[] bytes, int offset)
+	    {
+	        int kind = (int) dateTime.Kind;
+            for (int i = 0; i < 4; i++)
+            {
+                bytes[offset++] = (byte)(int)(kind >> (3 - i) * 8);
+            }
+	    }
+
+	    public override object Read(IReadContext context)
+		{	
+			long ticks = context.ReadLong();
+            DateTime dateTime = new DateTime(ticks);
+		    return ReadKind(context, dateTime);
+		}
+
+	    protected virtual object ReadKind(IReadContext context, DateTime dateTime)
+	    {
+	        DateTimeKind kind = (DateTimeKind) context.ReadInt();
+	        return DateTime.SpecifyKind(dateTime, kind);
+	    }
+
+	    public override void Write(IWriteContext context, object obj)
+		{
+	        DateTime dateTime = (DateTime)obj;
+	        long ticks = dateTime.Ticks;
+			context.WriteLong(ticks);
+	        WriteKind(context, dateTime);
+		}
+
+	    protected virtual void WriteKind(IWriteContext context, DateTime dateTime)
+	    {
+	        context.WriteInt((int) dateTime.Kind);
+	    }
+
+	    public override IPreparedComparison InternalPrepareComparison(object obj)
+        {
+            return new PreparedComparisonFor<DateTime>(((DateTime)obj));
+        }
+
+
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/DateTimeHandler6.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/DateTimeHandler6.cs
new file mode 100644
index 0000000..eee95c2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/DateTimeHandler6.cs
@@ -0,0 +1,33 @@
+/* Copyright (C) 2004 - 2009   Versant Inc.   http://www.db4o.com */
+using System;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+    class DateTimeHandler6 : DateTimeHandler
+    {
+        protected override object ReadKind(IReadContext context, DateTime dateTime)
+        {
+            return dateTime;
+        }
+
+        protected override void WriteKind(IWriteContext context, DateTime dateTime)
+        {
+            // do nothing
+        }
+
+        protected override DateTime ReadKind (DateTime dateTime, byte[] bytes, int offset)
+        {
+            return dateTime;
+        }
+
+        protected override void WriteKind(DateTime dateTime, byte[] bytes, int offset)
+        {
+            // do nothing
+        }
+		//public override int LinkLength()
+		//{
+		//    return base.LinkLength() - Const4.LongLength;
+		//}
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/DecimalHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/DecimalHandler.cs
new file mode 100644
index 0000000..c0a825b
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/DecimalHandler.cs
@@ -0,0 +1,82 @@
+/* Copyright (C) 2004 - 2007   Versant Inc.   http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	public class DecimalHandler : IntegralTypeHandler
+	{
+        public override Object DefaultValue(){
+            return (decimal)0;
+        }
+      
+        public override Object Read(byte[] bytes, int offset){
+            int[] ints = new int[4];
+            offset += 3;
+            for(int i = 0; i < 4; i ++){
+                ints[i] = (bytes[offset] & 255 | (bytes[--offset] & 255) << 8 | (bytes[--offset] & 255) << 16 | bytes[--offset] << 24);
+                offset +=7;
+            }
+            return new Decimal(ints);
+        }
+
+        public override int TypeID(){
+            return 21;
+        }
+      
+        public override void Write(Object obj, byte[] bytes, int offset){
+            decimal dec = (decimal)obj;
+            int[] ints = Decimal.GetBits(dec);
+            offset += 4;
+            for(int i = 0; i < 4; i ++){
+                bytes[--offset] = (byte)ints[i];
+                bytes[--offset] = (byte)(ints[i] >>= 8);
+                bytes[--offset] = (byte)(ints[i] >>= 8);
+                bytes[--offset] = (byte)(ints[i] >>= 8);
+                offset += 8;
+            }
+        }
+        public override object Read(IReadContext context)
+        {
+            byte[] bytes = new byte[16];
+            int[] ints = new int[4];
+            int offset = 4;
+            context.ReadBytes(bytes);
+            for (int i = 0; i < 4; i++)
+            {
+                ints[i] =   (
+                             bytes[--offset] & 255 | 
+                            (bytes[--offset] & 255) << 8 | 
+                            (bytes[--offset] & 255) << 16 | 
+                            (bytes[--offset] & 255) << 24
+                            );
+                offset += 8;
+            }
+            return new Decimal(ints);
+        }
+
+        public override void Write(IWriteContext context, object obj)
+        {
+            decimal dec = (decimal)obj;
+            byte[] bytes = new byte[16];
+            int offset = 4;
+            int[] ints = Decimal.GetBits(dec);
+            for (int i = 0; i < 4; i++)
+            {
+                bytes[--offset] = (byte)ints[i];
+                bytes[--offset] = (byte)(ints[i] >>= 8);
+                bytes[--offset] = (byte)(ints[i] >>= 8);
+                bytes[--offset] = (byte)(ints[i] >>= 8);
+                offset += 8;
+            }
+            context.WriteBytes(bytes);
+        }
+
+        public override IPreparedComparison InternalPrepareComparison(object obj)
+        {
+            return new PreparedComparisonFor<decimal>(((decimal) obj));
+        }
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/IntegralTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/IntegralTypeHandler.cs
new file mode 100644
index 0000000..97719ae
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/IntegralTypeHandler.cs
@@ -0,0 +1,11 @@
+/* Copyright (C) 2004 - 2007   Versant Inc.   http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	abstract public class IntegralTypeHandler : NetTypeHandler
+	{
+
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/PreparedComparisonFor.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/PreparedComparisonFor.cs
new file mode 100644
index 0000000..0267421
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/PreparedComparisonFor.cs
@@ -0,0 +1,23 @@
+/* Copyright (C) 2009 Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+    internal class PreparedComparisonFor<T> : IPreparedComparison where T : IComparable<T>
+    {
+        private readonly T _source;
+
+        public PreparedComparisonFor(T source)
+        {
+            _source = source;
+        }
+
+        public int CompareTo(object obj)
+        {
+            T target = ((T)obj);
+            return _source.CompareTo(target);
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/SByteHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/SByteHandler.cs
new file mode 100644
index 0000000..4ee27c2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/SByteHandler.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2004 - 2007   Versant Inc.   http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	public class SByteHandler : IntegralTypeHandler
+	{
+		public override object Coerce(IReflectClass claxx, object obj)
+		{
+			return Coercion4.ToSByte(obj);
+		}
+	
+        public override Object DefaultValue(){
+            return (sbyte)0;
+        }
+      
+        public override Object Read(byte[] bytes, int offset){
+            return (sbyte)  ((bytes[offset]) - 128) ;
+        }
+
+        public override int TypeID(){
+            return 20;
+        }
+      
+        public override void Write(Object obj, byte[] bytes, int offset){
+            bytes[offset] = (byte)(((sbyte)obj) + 128);
+        }
+
+        public override object Read(IReadContext context)
+        {
+            return (sbyte)(context.ReadByte() - 128);
+        }
+
+        public override void Write(IWriteContext context, object obj)
+        {
+            context.WriteByte((byte)(((sbyte)obj) + 128));
+        }
+        
+        public override IPreparedComparison InternalPrepareComparison(object obj)
+        {
+            return new PreparedComparisonFor<sbyte>(((sbyte)obj));
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/StructHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/StructHandler.cs
new file mode 100644
index 0000000..2a79523
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/StructHandler.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2004 - 2007   Versant Inc.   http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+    abstract public class StructHandler : NetTypeHandler {
+
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/UIntHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/UIntHandler.cs
new file mode 100644
index 0000000..940cad7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/UIntHandler.cs
@@ -0,0 +1,61 @@
+/* Copyright (C) 2004 - 2007   Versant Inc.   http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	public class UIntHandler : IntegralTypeHandler
+	{
+        public override Object DefaultValue(){
+            return (uint)0;
+        }
+      
+        public override Object Read(byte[] bytes, int offset){
+            offset += 3;
+            return (uint) (bytes[offset] & 255 | (bytes[--offset] & 255) << 8 | (bytes[--offset] & 255) << 16 | bytes[--offset] << 24);
+        }
+
+        public override int TypeID(){
+            return 22;
+        }
+      
+        public override void Write(Object obj, byte[] bytes, int offset){
+            uint ui = (uint)obj;
+            offset += 4;
+            bytes[--offset] = (byte)ui;
+            bytes[--offset] = (byte)(ui >>= 8);
+            bytes[--offset] = (byte)(ui >>= 8);
+            bytes[--offset] = (byte)(ui >>= 8);
+        }
+        public override object Read(IReadContext context)
+        {
+            byte[] bytes = new byte[4];
+            context.ReadBytes(bytes);
+            return (uint)(
+                     bytes[3] & 255        | 
+                    (bytes[2] & 255) << 8  | 
+                    (bytes[1] & 255) << 16 | 
+                    (bytes[0] & 255) << 24
+                );
+        }
+
+        public override void Write(IWriteContext context, object obj)
+        {
+            uint ui = (uint)obj;
+            context.WriteBytes(
+                new byte[] { 
+                    (byte)(ui>>24),
+                    (byte)(ui>>16),
+                    (byte)(ui>>8),
+                    (byte)ui,
+                });
+        }
+
+        public override IPreparedComparison InternalPrepareComparison(object obj)
+        {
+            return new PreparedComparisonFor<uint>(((uint)obj));
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/ULongHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/ULongHandler.cs
new file mode 100644
index 0000000..29258fd
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/ULongHandler.cs
@@ -0,0 +1,71 @@
+/* Copyright (C) 2004 - 2007   Versant Inc.   http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+    public class ULongHandler : IntegralTypeHandler {
+
+        public override Object DefaultValue(){
+            return (ulong)0;
+        }
+      
+        public override void Write(object obj, byte[] bytes, int offset){
+            ulong ul = (ulong)obj;
+            for (int i = 0; i < 8; i++){
+                bytes[offset++] = (byte)(int)(ul >> (7 - i) * 8);
+            }
+        }
+
+        public override int TypeID(){
+            return 23;
+        }
+
+        public override Object Read(byte[] bytes, int offset){
+            ulong ul = 0;
+            for (int i = 0; i < 8; i++) {
+                ul = (ul << 8) + (ulong)(bytes[offset++] & 255);
+            }
+            return ul;
+        }
+
+        public override object Read(IReadContext context)
+        {
+            byte[] bytes = new byte[8];
+            context.ReadBytes(bytes);
+            return (ulong)(
+                     (ulong)bytes[7] & 255 |
+                    (ulong)(bytes[6] & 255) << 8  |
+                    (ulong)(bytes[5] & 255) << 16 |
+                    (ulong)(bytes[4] & 255) << 24 |
+                    (ulong)(bytes[3] & 255) << 32 |
+                    (ulong)(bytes[2] & 255) << 40 |
+                    (ulong)(bytes[1] & 255) << 48 |
+                    (ulong)(bytes[0] & 255) << 56 
+                );
+        }
+
+        public override void Write(IWriteContext context, object obj)
+        {
+            ulong ui = (ulong)obj;
+            context.WriteBytes(
+                new byte[] { 
+                    (byte)(ui>>56),
+                    (byte)(ui>>48),
+                    (byte)(ui>>40),
+                    (byte)(ui>>32),
+                    (byte)(ui>>24),
+                    (byte)(ui>>16),
+                    (byte)(ui>>8),
+                    (byte)ui,
+                });
+        }
+
+        public override IPreparedComparison InternalPrepareComparison(object obj)
+        {
+            return new PreparedComparisonFor<ulong>(((ulong)obj));
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/UShortHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/UShortHandler.cs
new file mode 100644
index 0000000..b965d29
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/UShortHandler.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2004 - 2007   Versant Inc.   http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Marshall;
+
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	public class UShortHandler : IntegralTypeHandler
+	{
+        public override Object DefaultValue(){
+            return (ushort)0;
+        }
+      
+        public override Object Read(byte[] bytes, int offset){
+            offset += 1;
+            return (ushort) (bytes[offset] & 255 | (bytes[--offset] & 255) << 8);
+        }
+      
+        public override int TypeID(){
+            return 24;
+        }
+      
+        public override void Write(Object obj, byte[] bytes, int offset){
+            ushort us = (ushort)obj;
+            offset += 2;
+            bytes[--offset] = (byte)us;
+            bytes[--offset] = (byte)(us >>= 8);
+        }
+
+        public override object Read(IReadContext context)
+        {
+            byte[] bytes = new byte[2];
+            context.ReadBytes(bytes);
+            return (ushort)(
+                     bytes[1] & 255 |
+                    (bytes[0] & 255) << 8
+                );
+        }
+
+        public override void Write(IWriteContext context, object obj)
+        {
+            ushort us = (ushort)obj;
+            context.WriteBytes(
+                new byte[] { 
+                    (byte)(us>>8),
+                    (byte)us,
+                });
+        }
+
+        public override IPreparedComparison InternalPrepareComparison(object obj)
+        {
+            return new PreparedComparisonFor<ushort>(((ushort)obj));
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/WeakReferenceHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/WeakReferenceHandler.cs
new file mode 100644
index 0000000..8ad0310
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/WeakReferenceHandler.cs
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 - 2007   Versant Inc.   http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+	internal class WeakReferenceHandler
+	{
+		private readonly WeakReference _reference;
+		public object ObjectReference;
+
+		internal WeakReferenceHandler(Object queue, Object objectRef, Object obj)
+		{
+			_reference = new WeakReference(obj, false);
+			ObjectReference = objectRef;
+			((WeakReferenceHandlerQueue)queue).Add(this);
+		}
+
+		public object Get()
+		{
+			return _reference.Target;
+		}
+
+		public bool IsAlive
+		{
+			get { return _reference.IsAlive; }
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/WeakReferenceHandlerQueue.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/WeakReferenceHandlerQueue.cs
new file mode 100644
index 0000000..26dd0da
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Handlers/WeakReferenceHandlerQueue.cs
@@ -0,0 +1,46 @@
+/* Copyright (C) 2004 - 2007   Versant Inc.   http://www.db4o.com */
+
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Internal.Handlers
+{
+    internal class WeakReferenceHandlerQueue
+	{
+        private List4 _list;
+
+        internal void Add(WeakReferenceHandler reference) {
+            lock(this){
+                _list = new List4(_list, reference);
+            }
+        }
+
+        internal void Poll(ObjectContainerBase objectContainer) {
+            List4 remove = null;
+            lock(this){
+                System.Collections.IEnumerator i = new Iterator4Impl(_list);
+                _list = null;
+                while(i.MoveNext()){
+					WeakReferenceHandler refHandler = (WeakReferenceHandler)i.Current;
+                    if(refHandler.IsAlive){
+                        _list = new List4(_list, refHandler);
+                    }else{
+                        remove = new List4(remove, refHandler.ObjectReference);
+                    }
+                }
+            }
+            System.Collections.IEnumerator j = new Iterator4Impl(remove);
+            while (j.MoveNext())
+            {
+                lock (objectContainer.Lock())
+                {
+                    if (objectContainer.IsClosed())
+                    {
+                        return;
+                    }
+                    objectContainer.RemoveFromAllReferenceSystems(j.Current);
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/IInternalObjectContainer.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/IInternalObjectContainer.cs
new file mode 100644
index 0000000..ef2392c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/IInternalObjectContainer.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2009  Versant Inc.  http://www.db4o.com */
+using Db4objects.Db4o.Foundation;
+
+namespace Db4objects.Db4o.Internal
+{
+	public partial interface IInternalObjectContainer
+	{
+		void WithEnvironment(Action4 action);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/LegacyDb4oAssemblyNameMapper.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/LegacyDb4oAssemblyNameMapper.cs
new file mode 100644
index 0000000..897f493
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/LegacyDb4oAssemblyNameMapper.cs
@@ -0,0 +1,90 @@
+/* Copyright (C) 2009 Versant Inc.   http://www.db4o.com */
+using System.Text;
+using Db4objects.Db4o.Internal.Encoding;
+
+namespace Db4objects.Db4o.Internal
+{
+	internal class LegacyDb4oAssemblyNameMapper
+	{
+		static LegacyDb4oAssemblyNameMapper()
+        {   
+            LatinStringIO stringIO = new UnicodeStringIO();
+            oldAssemblies = new byte[oldAssemblyNames.Length][];
+            for (int i = 0; i < oldAssemblyNames.Length; i++)
+            {
+                oldAssemblies[i] = stringIO.Write(oldAssemblyNames[i]);
+            }
+        }
+
+		internal byte[] MappedNameFor(byte[] nameBytes)
+		{
+			for (int i = 0; i < oldAssemblyNames.Length; i++)
+			{
+				byte[] assemblyName = oldAssemblies[i];
+
+				int j = assemblyName.Length - 1;
+				for (int k = nameBytes.Length - 1; k >= 0; k--)
+				{
+					if (nameBytes[k] != assemblyName[j])
+					{
+						break;
+					}
+					j--;
+					if (j < 0)
+					{
+						return UpdateInternalClassName(nameBytes, i);
+					}
+				}
+			}
+			return nameBytes;
+		}
+
+		private static byte[] UpdateInternalClassName(byte[] bytes, int candidateMatchingAssemblyIndex)
+		{
+			UnicodeStringIO io = new UnicodeStringIO();
+			string typeFQN = io.Read(bytes);
+
+			string[] assemblyNameParts = typeFQN.Split(',');
+			if (assemblyNameParts[1].Trim() != oldAssemblyNames[candidateMatchingAssemblyIndex])
+			{
+				return bytes;
+			}
+
+			string typeName = assemblyNameParts[0];
+			return io.Write(FullyQualifiedNameFor(typeName).ToString());
+		}
+
+		private static StringBuilder FullyQualifiedNameFor(string typeName)
+		{
+			StringBuilder typeNameBuffer = new StringBuilder(typeName);
+			ApplyNameSpaceRenamings(typeNameBuffer);
+			typeNameBuffer.Append(", ");
+			typeNameBuffer.Append(GetCurrentAssemblyName());
+			return typeNameBuffer;
+		}
+
+		private static void ApplyNameSpaceRenamings(StringBuilder typeNameBuffer)
+		{
+			foreach (string[] renaming in NamespaceRenamings)
+			{
+				typeNameBuffer.Replace(renaming[0], renaming[1]);
+			}
+		}
+
+		private static string GetCurrentAssemblyName()
+		{
+			return typeof(Platform4).Assembly.GetName().Name;
+		}
+		
+		private static readonly string[] oldAssemblyNames = new string[] { "db4o-4.0-net1", "db4o-4.0-compact1" };
+		private static readonly byte[][] oldAssemblies;
+
+		private static readonly string[][] NamespaceRenamings = new string[][]
+                {
+                    new string[] { "com.db4o.ext", "Db4objects.Db4o.Ext"},
+                    new string[] { "com.db4o.inside", "Db4objects.Db4o.Internal"},
+                    new string[] { "com.db4o", "Db4objects.Db4o"}, 
+                };
+
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Marshall/MarshallingConstants0.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Marshall/MarshallingConstants0.cs
new file mode 100644
index 0000000..1bed3a3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Marshall/MarshallingConstants0.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Db4objects.Db4o.Internal.Marshall
+{
+	public class MarshallingConstants0
+	{
+		public static readonly DateTime NullDate = DateTime.MinValue;
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/ObjectContainerBase.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/ObjectContainerBase.cs
new file mode 100644
index 0000000..fa5f5c5
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/ObjectContainerBase.cs
@@ -0,0 +1,206 @@
+/* Copyright (C) 2004 - 2008  Versant Inc.  http://www.db4o.com */
+
+using System.Collections.Generic;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal
+{
+    using System;
+    using Query;
+    using Query.Result;
+    using Query.Processor;
+    using Ext;
+
+    public partial class ObjectContainerBase
+    {
+        void IDisposable.Dispose()
+        {
+            Close();
+        }
+
+        public IObjectSet Query(Predicate match, System.Collections.IComparer comparer)
+        {
+            if (null == match) throw new ArgumentNullException("match");
+            return Query(null, match, new ComparerAdaptor(comparer));
+        }
+
+        class GenericComparerAdaptor<T> : IQueryComparator
+        {
+            private readonly IComparer<T> _comparer;
+
+            public GenericComparerAdaptor(IComparer<T> comparer)
+            {
+                _comparer = comparer;
+            }
+
+            public int Compare(object first, object second)
+            {
+                return _comparer.Compare((T)first, (T)second);
+            }
+        }
+
+        class GenericComparisonAdaptor<T> : DelegateEnvelope, IQueryComparator
+        {
+            public GenericComparisonAdaptor(Comparison<T> comparer) : base(comparer)
+            {
+            }
+
+            public int Compare(object first, object second)
+            {
+                Comparison<T> _comparer = (Comparison<T>)GetContent();
+                return _comparer((T)first, (T)second);
+            }
+        }
+
+        public IList<Extent> Query<Extent>(Predicate<Extent> match)
+        {
+            return Query(null, match);
+        }
+
+        public IList<Extent> Query<Extent>(Transaction trans, Predicate<Extent> match)
+        {
+            return ExecuteNativeQuery(trans, match, null);
+        }
+
+        public IList<Extent> Query<Extent>(Predicate<Extent> match, IComparer<Extent> comparer)
+        {
+            return Query(null, match, comparer);
+        }
+
+
+        public IList<Extent> Query<Extent>(Transaction trans, Predicate<Extent> match, IComparer<Extent> comparer)
+        {
+            IQueryComparator comparator = null != comparer
+                                                            ? new GenericComparerAdaptor<Extent>(comparer)
+                                                            : null;
+            return ExecuteNativeQuery(trans, match, comparator);
+        }
+
+        public IList<Extent> Query<Extent>(Predicate<Extent> match, Comparison<Extent> comparison)
+        {
+            return Query(null, match, comparison);
+        }
+
+
+        public IList<Extent> Query<Extent>(Transaction trans, Predicate<Extent> match, Comparison<Extent> comparison)
+        {
+            IQueryComparator comparator = null != comparison
+                                                        ? new GenericComparisonAdaptor<Extent>(comparison)
+                                                        : null;
+            return ExecuteNativeQuery(trans, match, comparator);
+        }
+
+        public IList<ElementType> Query<ElementType>(Type extent)
+        {
+            return Query<ElementType>(null, extent, null);
+        }
+
+
+        public IList<ElementType> Query<ElementType>(Transaction trans, Type extent)
+        {
+            return Query<ElementType>(trans, extent, null);
+        }
+
+        public IList<ElementType> Query<ElementType>(Type extent, IComparer<ElementType> comparer)
+        {
+            return Query(null, extent, comparer);
+        }
+
+
+        public IList<ElementType> Query<ElementType>(Transaction trans, Type extent, IComparer<ElementType> comparer)
+        {
+            lock (Lock())
+            {
+                trans = CheckTransaction(trans);
+                QQuery query = (QQuery)Query(trans);
+                query.Constrain(extent);
+                if (null != comparer) query.SortBy(new GenericComparerAdaptor<ElementType>(comparer));
+                IQueryResult queryResult = query.GetQueryResult();
+                return new GenericObjectSetFacade<ElementType>(queryResult);
+            }
+        }
+
+        public IList<Extent> Query<Extent>()
+        {
+            return Query<Extent>(typeof(Extent));
+        }
+
+        public IList<Extent> Query<Extent>(IComparer<Extent> comparer)
+        {
+            return Query<Extent>(typeof(Extent), comparer);
+        }
+
+        private IList<Extent> ExecuteNativeQuery<Extent>(Transaction trans, Predicate<Extent> match, IQueryComparator comparator)
+        {
+            if (null == match) throw new ArgumentNullException("match");
+            lock (Lock())
+            {
+            	IQuery query = Query(CheckTransaction(trans));
+				return (IList<Extent>) ((QQuery)query).TriggeringQueryEvents(Closures4.ForDelegate(
+				                                                     	delegate() {
+				                                                     	           	return GetNativeQueryHandler().Execute(query, match, comparator);
+				                                                     	}));
+            }
+        }
+
+    	public delegate R SyncExecClosure<R>();
+
+		public R SyncExec<R>(SyncExecClosure<R> closure)
+		{
+			return (R)SyncExec(new SyncExecClosure4<R>(closure));
+		}
+
+    	public class SyncExecClosure4<R> : IClosure4
+    	{
+    		private readonly SyncExecClosure<R> _closure;
+
+    		public SyncExecClosure4(SyncExecClosure<R> closure)
+    		{
+    			_closure = closure;
+    		}
+
+    		#region Implementation of IClosure4
+
+    		public object Run()
+    		{
+    			return _closure.Invoke();
+    		}
+
+    		#endregion
+    	}
+
+	    private object AsTopLevelCall(IFunction4 block, Transaction trans) 
+	    {
+	    	trans = CheckTransaction(trans);
+	    	BeginTopLevelCall();
+	        try
+	        {            	
+	        	return block.Apply(trans);
+	        } 
+	        catch(Db4oRecoverableException exc) 
+	        {
+	        	throw;
+	        }
+	        catch(SystemException exc) 
+	        {
+	        	throw;
+	        }
+	        catch(Exception exc) 
+	        {
+				FatalShutdown(exc);
+	        }
+	        finally 
+	        {
+	        	EndTopLevelCall();
+	        }
+	        // should never happen - just to make compiler happy
+			throw new Db4oException();
+	    }
+
+		public void WithEnvironment(Action4 action)
+		{
+			WithEnvironment(new RunnableAction(action));
+		}
+    }
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/ObjectContainerSession.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/ObjectContainerSession.cs
new file mode 100644
index 0000000..7afcb47
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/ObjectContainerSession.cs
@@ -0,0 +1,66 @@
+/* Copyright (C) 2004 - 2008  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Query;
+using Db4objects.Db4o.Internal.Query.Result;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal
+{
+    /// <exclude></exclude>
+    public partial class ObjectContainerSession
+    {
+        void System.IDisposable.Dispose()
+        {
+            Close();
+        }
+
+        public IObjectSet Query(Db4objects.Db4o.Query.Predicate match, System.Collections.IComparer comparer)
+        {
+            return _server.Query(_transaction, match, new ComparerAdaptor(comparer));
+        }
+
+        public System.Collections.Generic.IList<Extent> Query<Extent>(Predicate<Extent> match)
+        {
+            return _server.Query(_transaction, match);
+        }
+
+        public System.Collections.Generic.IList<Extent> Query<Extent>(Predicate<Extent> match, System.Collections.Generic.IComparer<Extent> comparer)
+        {
+            return _server.Query(_transaction, match, comparer);
+        }
+
+        public System.Collections.Generic.IList<Extent> Query<Extent>(Predicate<Extent> match, System.Comparison<Extent> comparison)
+        {
+            return _server.Query(_transaction, match, comparison);
+        }
+
+        public System.Collections.Generic.IList<ElementType> Query<ElementType>(System.Type extent)
+        {
+            return _server.Query<ElementType>(_transaction, extent, null);
+        }
+
+        public System.Collections.Generic.IList<ElementType> Query<ElementType>(System.Type extent, System.Collections.Generic.IComparer<ElementType> comparer)
+        {
+            return _server.Query(_transaction, extent, comparer);
+        }
+
+        public System.Collections.Generic.IList<Extent> Query<Extent>()
+        {
+            return Query<Extent>(typeof(Extent));
+        }
+
+        public System.Collections.Generic.IList<Extent> Query<Extent>(System.Collections.Generic.IComparer<Extent> comparer)
+        {
+            return Query<Extent>(typeof(Extent), comparer);
+        }
+
+		public void WithEnvironment(Action4 action)
+		{
+			_server.WithEnvironment(new RunnableAction(action));
+		}
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Platform4.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Platform4.cs
new file mode 100644
index 0000000..0f1f498
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Platform4.cs
@@ -0,0 +1,726 @@
+/* Copyright (C) 2004 - 2009 Versant Inc.   http://www.db4o.com */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Config.Attributes;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Query;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Query;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Generic;
+using Db4objects.Db4o.Reflect.Net;
+using Db4objects.Db4o.Typehandlers;
+using Sharpen.IO;
+
+namespace Db4objects.Db4o.Internal
+{
+    /// <exclude />
+    public class Platform4
+    {
+		private static readonly LegacyDb4oAssemblyNameMapper _assemlbyNameMapper = new LegacyDb4oAssemblyNameMapper();
+
+        private static List<ObjectContainerBase> _containersToBeShutdown;
+
+		private static readonly object _shutdownStreamsLock = new object();
+
+		public static object[] CollectionToArray(ObjectContainerBase stream, object obj)
+        {
+            Collection4 col = FlattenCollection(stream, obj);
+            object[] ret = new object[col.Size()];
+            col.ToArray(ret);
+            return ret;
+        }
+
+    	internal static void AddShutDownHook(ObjectContainerBase container)
+        {
+            lock (_shutdownStreamsLock)
+            {
+                if (_containersToBeShutdown == null)
+                {
+					_containersToBeShutdown = new List<ObjectContainerBase>();
+#if !CF && !SILVERLIGHT
+                	AppDomain.CurrentDomain.ProcessExit += OnShutDown;
+					AppDomain.CurrentDomain.DomainUnload += OnShutDown;
+#endif
+                }
+                _containersToBeShutdown.Add(container);
+            }
+        }
+
+        internal static byte[] Serialize(Object obj)
+        {
+            throw new NotSupportedException();
+        }
+
+        internal static Object Deserialize(byte[] bytes)
+        {
+            throw new NotSupportedException();
+        }
+
+        internal static bool CanSetAccessible()
+        {
+            return true;
+        }
+
+        internal static IReflector CreateReflector(Object config)
+		{
+#if USE_FAST_REFLECTOR && !CF && !SILVERLIGHT
+			return new Db4objects.Db4o.Internal.Reflect.FastNetReflector();
+#else
+			return new NetReflector();
+#endif
+		}
+
+        public static IReflector ReflectorForType(Type typeInstance)
+		{
+#if USE_FAST_REFLECTOR && !CF && !SILVERLIGHT
+			return new Db4objects.Db4o.Internal.Reflect.FastNetReflector();
+#else
+			return new NetReflector();
+#endif
+		}
+
+        internal static Object CreateReferenceQueue()
+        {
+            return new WeakReferenceHandlerQueue();
+        }
+
+        public static Object CreateWeakReference(Object obj)
+        {
+            return new WeakReference(obj, false);
+        }
+
+        internal static Object CreateActiveObjectReference(Object referenceQueue, Object yapObject, Object obj)
+        {
+            return new WeakReferenceHandler(referenceQueue, yapObject, obj);
+        }
+
+        internal static long DoubleToLong(double a_double)
+		{
+#if CF || SILVERLIGHT
+			byte[] bytes = BitConverter.GetBytes(a_double);
+            return BitConverter.ToInt64(bytes, 0);
+#else
+            return BitConverter.DoubleToInt64Bits(a_double);
+#endif
+        }
+
+        internal static QConEvaluation EvaluationCreate(Transaction a_trans, Object example)
+        {
+            if (example is IEvaluation || example is EvaluationDelegate)
+            {
+                return new QConEvaluation(a_trans, example);
+            }
+            return null;
+        }
+
+        internal static void EvaluationEvaluate(Object a_evaluation, ICandidate a_candidate)
+        {
+            IEvaluation eval = a_evaluation as IEvaluation;
+            if (eval != null)
+            {
+                eval.Evaluate(a_candidate);
+            }
+            else
+            {
+                // use starting _ for PascalCase conversion purposes
+                EvaluationDelegate _ed = a_evaluation as EvaluationDelegate;
+                if (_ed != null)
+                {
+                    _ed(a_candidate);
+                }
+            }
+        }
+
+        internal static Config4Class ExtendConfiguration(IReflectClass clazz, IConfiguration config, Config4Class classConfig)
+        {
+            Type t = GetNetType(clazz);
+            if (t == null)
+            {
+                return classConfig;
+            }
+            ConfigurationIntrospector a = new ConfigurationIntrospector(t, classConfig, config);
+            a.Apply();
+            return a.ClassConfiguration;
+        }
+
+		internal static Collection4 FlattenCollection(ObjectContainerBase stream, Object obj)
+        {
+            Collection4 collection41 = new Collection4();
+            FlattenCollection1(stream, obj, collection41);
+            return collection41;
+        }
+
+		internal static void FlattenCollection1(ObjectContainerBase stream, Object obj, Collection4 collection4)
+        {
+            Array arr = obj as Array;
+            if (arr != null)
+            {
+                IReflectArray reflectArray = stream.Reflector().Array();
+
+                Object[] flat = new Object[arr.Length];
+
+                reflectArray.Flatten(obj, reflectArray.Dimensions(obj), 0, flat, 0);
+                for (int i = 0; i < flat.Length; i++)
+                {
+                    FlattenCollection1(stream, flat[i], collection4);
+                }
+            }
+            else
+            {
+                // If obj implements IEnumerable, add all elements to collection4
+                IEnumerator enumerator = GetCollectionEnumerator(obj, true);
+
+                // Add elements to collection if conversion was succesful
+                if (enumerator != null)
+                {
+                    if (enumerator is IDictionaryEnumerator)
+                    {
+                        IDictionaryEnumerator dictEnumerator = enumerator as IDictionaryEnumerator;
+                        while (enumerator.MoveNext())
+                        {
+                            FlattenCollection1(stream, dictEnumerator.Key, collection4);
+                        }
+                    }
+                    else
+                    {
+                        while (enumerator.MoveNext())
+                        {
+                            // recursive call to flatten Collections in Collections
+                            FlattenCollection1(stream, enumerator.Current, collection4);
+                        }
+                    }
+                }
+                else
+                {
+                    // If obj is not a Collection, it still needs to be collected.
+                    collection4.Add(obj);
+                }
+            }
+        }
+
+        internal static void ForEachCollectionElement(Object obj, IVisitor4 visitor)
+        {
+            IEnumerator enumerator = GetCollectionEnumerator(obj, false);
+            if (enumerator != null)
+            {
+                // If obj is a map (IDictionary in .NET speak) call Visit() with the key
+                // otherwise use the element itself
+                if (enumerator is IDictionaryEnumerator)
+                {
+                    IDictionaryEnumerator dictEnumerator = enumerator as IDictionaryEnumerator;
+                    while (enumerator.MoveNext())
+                    {
+                        visitor.Visit(dictEnumerator.Key);
+                    }
+                }
+                else
+                {
+                    while (enumerator.MoveNext())
+                    {
+                        visitor.Visit(enumerator.Current);
+                    }
+                }
+            }
+        }
+
+        internal static String Format(DateTime date, bool showSeconds)
+        {
+            String fmt = "yyyy-MM-dd";
+            if (showSeconds)
+            {
+                fmt += " HH:mm:ss";
+            }
+            return date.ToString(fmt);
+        }
+
+        internal static IEnumerator GetCollectionEnumerator(object obj, bool allowArray)
+        {
+			IEnumerable enumerable = obj as IEnumerable;
+			if (enumerable == null) return null;
+		    if (obj is string) return null;
+            if (!allowArray && obj is Array) return null;
+		    return enumerable.GetEnumerator();
+		}
+
+        internal static void GetDefaultConfiguration(Config4Impl config)
+        {
+            if (IsCompact())
+            {
+                config.SingleThreadedClient(true);
+            }
+
+            Translate(config, typeof(Delegate), new TNull());
+            Translate(config, typeof(Type), new TType()); // TODO: unnecessary?
+            Translate(config, typeof(Type).GetType(), new TType());
+
+#if !CF && !SILVERLIGHT
+            if (IsMono())
+            {
+
+				Translate(config, new Exception(), new TSerializable());
+            }
+#endif
+
+#if !SILVERLIGHT
+            Translate(config, new ArrayList(), new TList());
+            Translate(config, new Hashtable(), new TDictionary());
+            Translate(config, new Queue(), new TQueue());
+            Translate(config, new Stack(), new TStack());
+#endif
+			Translate(config, CultureInfo.InvariantCulture, new TCultureInfo());
+
+            if (!IsCompact())
+            {
+				Translate(config, "System.Collections.SortedList, mscorlib", new TDictionary());
+            }
+
+            new TypeHandlerConfigurationDotNet(config).Apply();
+
+        	config.ObjectClass(typeof (ActivatableBase)).Indexed(false);
+        }
+
+        public static bool IsCompact()
+		{
+#if CF || SILVERLIGHT
+			return true;
+#else
+            return false;
+#endif
+        }
+
+        internal static bool IsMono()
+        {
+            return null != Type.GetType("System.MonoType, mscorlib");
+        }
+
+        public static Object GetTypeForClass(Object obj)
+        {
+            return obj;
+        }
+
+        internal static Object GetYapRefObject(Object obj)
+        {
+			WeakReferenceHandler refHandler = obj as WeakReferenceHandler;
+			if (refHandler != null)
+            {
+				return refHandler.Get();
+            }
+            return obj;
+        }
+
+        internal static bool HasCollections()
+        {
+            return true;
+        }
+
+        public static bool NeedsLockFileThread()
+        {
+            return false;
+        }
+
+        public static bool HasWeakReferences()
+        {
+            return true;
+        }
+
+        internal static bool IgnoreAsConstraint(Object obj)
+        {
+            Type t = obj.GetType();
+            if (t.IsEnum)
+            {
+                if (System.Convert.ToInt32(obj) == 0)
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        internal static bool IsCollectionTranslator(Config4Class config4class)
+        {
+            if (config4class != null)
+            {
+                IObjectTranslator ot = config4class.GetTranslator();
+                if (ot != null)
+                {
+#if SILVERLIGHT
+					return false;
+#else
+					return ot is TList || ot is TDictionary || ot is TQueue || ot is TStack;
+#endif
+				}
+            }
+            return false;
+        }
+
+        public static bool IsConnected(Sharpen.Net.Socket socket)
+        {
+            if (socket == null)
+            {
+                return false;
+            }
+            return socket.IsConnected();
+        }
+
+        internal static bool IsStruct(IReflectClass claxx)
+        {
+            if (claxx == null)
+            {
+                return false;
+            }
+            System.Type netClass = GetNetType(claxx);
+            if (netClass == null)
+            {
+                return false;
+            }
+            return netClass.IsValueType;
+        }
+
+        internal static void KillYapRef(Object obj)
+        {
+			WeakReferenceHandler yr = obj as WeakReferenceHandler;
+            if (yr != null)
+            {
+                yr.ObjectReference = null;
+            }
+        }
+
+        internal static double LongToDouble(long l)
+		{
+#if CF || SILVERLIGHT
+			byte[] bytes = BitConverter.GetBytes(l);
+            return BitConverter.ToDouble(bytes, 0);
+#else
+            return BitConverter.Int64BitsToDouble(l);
+#endif
+        }
+
+        internal static void LockFile(string path, object file)
+		{
+#if !CF && !SILVERLIGHT
+			try
+            {
+                FileStream stream = ((RandomAccessFile) file).Stream;
+                stream.Lock(0, 1);
+            }
+            catch (IOException x)
+            {
+                throw new DatabaseFileLockedException(path,x);
+            }
+#endif
+        }
+
+        internal static void UnlockFile(string path, object file)
+        {
+            // do nothing. C# RAF is unlocked automatically upon closing
+        }
+
+        internal static void MarkTransient(String marker)
+        {
+            NetField.MarkTransient(marker);
+        }
+
+        internal static bool CallConstructor()
+        {
+            return false;
+        }
+
+        internal static void PollReferenceQueue(Object container, Object referenceQueue)
+        {
+            ((WeakReferenceHandlerQueue)referenceQueue).Poll((ObjectContainerBase)container);
+        }
+
+        public static void RegisterCollections(GenericReflector reflector)
+        {
+//            reflector.RegisterCollectionUpdateDepth(
+//                typeof(IDictionary),
+//                3);
+        }
+
+        internal static void RemoveShutDownHook(ObjectContainerBase container)
+        {
+            lock (_shutdownStreamsLock)
+            {
+                if (_containersToBeShutdown != null)
+                {
+                    _containersToBeShutdown.Remove(container);
+                }
+            }
+        }
+
+        public static void SetAccessible(Object obj)
+        {
+            // do nothing
+        }
+
+        private static void OnShutDown(object sender, EventArgs args)
+        {
+			lock (_shutdownStreamsLock)
+			{
+				foreach (ObjectContainerBase container in _containersToBeShutdown.ToArray())
+				{
+					container.ShutdownHook(); // this will remove the stream for the list
+				}				
+			}
+        }
+
+        public static bool StoreStaticFieldValues(IReflector reflector, IReflectClass clazz)
+        {
+            return false;
+        }
+
+		private static void Translate(IConfiguration config, object obj, IObjectTranslator translator)
+		{
+			config.ObjectClass(obj).Translate(translator);
+		}
+
+        public static byte[] UpdateClassName(byte[] nameBytes)
+        {
+            return _assemlbyNameMapper.MappedNameFor(nameBytes);
+        }
+
+        public static Object WeakReferenceTarget(Object weakRef)
+        {
+            WeakReference wr = weakRef as WeakReference;
+            if (wr != null)
+            {
+                return wr.Target;
+            }
+            return weakRef;
+        }
+
+        internal static object WrapEvaluation(object evaluation)
+		{
+#if CF || SILVERLIGHT
+			// FIXME: How to better support EvaluationDelegate on the CompactFramework?
+			return evaluation;
+#else
+            return (evaluation is EvaluationDelegate)
+                ? new EvaluationDelegateWrapper((EvaluationDelegate)evaluation)
+                : evaluation;
+#endif
+        }
+
+        public static bool IsTransient(IReflectClass clazz)
+        {
+            Type type = GetNetType(clazz);
+            if (null == type) return false;
+        	return IsTransient(type);
+        }
+
+    	public static bool IsTransient(Type type)
+    	{
+    		return type.IsPointer
+    		       || type.IsSubclassOf(typeof(Delegate))
+#if CF || SILVERLIGHT
+;
+#else
+    		       || type == typeof(System.Reflection.Pointer);
+#endif
+    	}
+
+    	private static Type GetNetType(IReflectClass clazz)
+        {
+            if (null == clazz)
+            {
+                return null;
+            }
+
+            NetClass netClass = clazz as NetClass;
+            if (null != netClass)
+            {
+                return netClass.GetNetType();
+            }
+            IReflectClass claxx = clazz.GetDelegate();
+            if (claxx == clazz)
+            {
+                return null;
+            }
+            return GetNetType(claxx);
+        }
+
+		public static NetTypeHandler[] Types(IReflector reflector)
+        {
+			return new NetTypeHandler[]
+				{
+					new SByteHandler(),
+					new DecimalHandler(),
+					new UIntHandler(),
+					new ULongHandler(),
+					new UShortHandler(),
+				};
+        }
+
+        public static bool IsSimple(Type a_class)
+        {
+            for (int i1 = 0; i1 < SIMPLE_CLASSES.Length; i1++)
+            {
+                if (a_class == SIMPLE_CLASSES[i1])
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        private static Type[] SIMPLE_CLASSES = {
+		                                        	typeof(Int32),
+		                                        	typeof(Int64),
+		                                        	typeof(Single),
+		                                        	typeof(Boolean),
+		                                        	typeof(Double),
+		                                        	typeof(Byte),
+		                                        	typeof(Char),
+		                                        	typeof(Int16),
+		                                        	typeof(String),
+		                                        };
+
+        public static DateTime Now()
+        {
+            return DateTime.Now;
+        }
+
+		internal static bool IsJavaEnum(IReflector genericReflector, IReflectClass iReflectClass)
+		{
+			return false;
+		}
+
+		internal static bool IsEnum(IReflector genericReflector, IReflectClass iReflectClass)
+		{
+		    Type type = GetNetType(iReflectClass);
+            if(type == null)
+            {
+                return false;
+            }
+			return type.IsEnum;
+		}
+
+        public static bool UseNativeSerialization() 
+        {
+            return false;
+        }
+
+        public static void RegisterPlatformHandlers(ObjectContainerBase container)
+        {
+            EnumTypeHandler enumTypeHandler = new EnumTypeHandler();
+            container.ConfigImpl.RegisterTypeHandler(new EnumTypeHandlerPredicate(), enumTypeHandler);
+			container.Handlers.RegisterHandlerVersion(enumTypeHandler, 4, new StandardReferenceTypeHandler());
+			container.Handlers.RegisterHandlerVersion(enumTypeHandler, 0, new StandardReferenceTypeHandler0());
+
+			GuidTypeHandler guidTypeHandler = new GuidTypeHandler();
+			container.ConfigImpl.RegisterTypeHandler(new SingleClassTypeHandlerPredicate(typeof(Guid)), guidTypeHandler);
+			container.Handlers.RegisterHandlerVersion(guidTypeHandler, 8, new StandardReferenceTypeHandler());
+
+            DateTimeHandler dateTimeHandler = new DateTimeHandler();
+            container.Handlers.RegisterNetTypeHandler(dateTimeHandler);
+            container.Handlers.RegisterHandlerVersion(dateTimeHandler, 6, new DateTimeHandler6());
+
+#if !CF
+        	DateTimeOffsetTypeHandler dateTimeOffsetHandler = new DateTimeOffsetTypeHandler();
+        	container.ConfigImpl.RegisterTypeHandler(new SingleClassTypeHandlerPredicate(typeof(DateTimeOffset)), dateTimeOffsetHandler);
+			container.Handlers.RegisterHandlerVersion(dateTimeOffsetHandler, 9, new StandardReferenceTypeHandler());
+#endif
+        }
+
+		public static Type[] PrimitiveTypes()
+		{
+			return PRIMITIVE_TYPES;
+		}
+
+        public static object NullValue(Type type) 
+        {
+            if(_nullValues == null) 
+            { 
+                InitNullValues();
+			}
+			
+			return _nullValues.Get(type);                
+		}
+		
+        private static void InitNullValues()
+        {
+    	    _nullValues = new Hashtable4();
+            _nullValues.Put(typeof(int), 0);
+            _nullValues.Put(typeof(uint), (uint)0);
+            _nullValues.Put(typeof(byte), (byte)0);
+    	    _nullValues.Put(typeof(short), (short)0);
+    	    _nullValues.Put(typeof(float), (float)0);
+    	    _nullValues.Put(typeof(double), (double)0);
+            _nullValues.Put(typeof(ulong), (ulong)0);
+            _nullValues.Put(typeof(long), (long)0);
+    	    _nullValues.Put(typeof(bool), false);
+            _nullValues.Put(typeof(char), (char)0);
+            _nullValues.Put(typeof(sbyte), (sbyte)0);
+            _nullValues.Put(typeof(decimal), (decimal)0);
+            _nullValues.Put(typeof(ushort), (ushort)0);
+            _nullValues.Put(typeof(DateTime), DateTime.MinValue);
+        	
+        }
+
+        private static Hashtable4 _nullValues;
+		
+        public static Type NullableTypeFor(Type primitiveType) 
+        {
+            if(_primitive2Wrapper == null)
+                InitPrimitive2Wrapper();
+            Type wrapperClazz = (Type)_primitive2Wrapper.Get(primitiveType);
+            if(wrapperClazz==null)        
+                throw new NotImplementedException();
+            return wrapperClazz;
+        }
+    
+        private static void InitPrimitive2Wrapper()
+        {
+    	    _primitive2Wrapper = new Hashtable4();
+
+        	foreach (Type type in PRIMITIVE_TYPES)
+        	{
+				_primitive2Wrapper.Put(type, ConcreteNullableTypeFor(type));
+        	}
+        }
+
+    	private static Type ConcreteNullableTypeFor(Type type)
+    	{
+    		return typeof (Nullable<>).MakeGenericType(type);
+    	}
+
+    	private static Hashtable4 _primitive2Wrapper;
+
+    	private static readonly Type[] PRIMITIVE_TYPES = new Type[]
+    	                                        	{
+														typeof(int),
+														typeof(uint), 
+														typeof(byte), 
+														typeof(short),
+														typeof(float),
+														typeof(double),
+														typeof(ulong),
+														typeof(long), 
+														typeof(bool), 
+														typeof(char), 
+														typeof(sbyte),
+														typeof(decimal),
+														typeof(ushort),
+														typeof(DateTime),
+    	                                        	};
+
+        public static void ThrowUncheckedException(Exception exc)
+        {
+            throw exc;
+        }
+
+        public static sbyte ToSByte(byte b)
+        {
+		    return (sbyte)b;
+	    }
+
+    }
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/EvaluationDelegateWrapper.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/EvaluationDelegateWrapper.cs
new file mode 100644
index 0000000..30ea8c3
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/EvaluationDelegateWrapper.cs
@@ -0,0 +1,81 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Reflection;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Query
+{
+    // TODO: Use DelegateEnvelope to build a generic delegate translator
+    internal class DelegateEnvelope
+    {
+        System.Type _delegateType;
+        object _target;
+        System.Type _type;
+        string _method;
+
+        [NonSerialized]
+        Delegate _content;
+
+        public DelegateEnvelope()
+        {
+        }
+
+        public DelegateEnvelope(Delegate content)
+        {
+            _content = content;
+            Marshal();
+        }
+
+        protected Delegate GetContent()
+        {
+            if (null == _content)
+            {
+                _content = Unmarshal();
+            }
+            return _content;
+        }
+
+        private void Marshal()
+        {
+            _delegateType = _content.GetType();
+            _target = _content.Target;
+            _method = _content.Method.Name;
+            _type = _content.Method.DeclaringType;
+        }
+
+        private Delegate Unmarshal()
+        {
+			if (null == _target)
+			{
+				return Delegate.CreateDelegate(_delegateType, null, _type.GetMethod(_method,  BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public));
+			}
+				
+			return Delegate.CreateDelegate(_delegateType, _target, _target.GetType().GetMethod(_method, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public));
+        }
+    }
+
+    internal class EvaluationDelegateWrapper : DelegateEnvelope, IEvaluation
+    {	
+        public EvaluationDelegateWrapper()
+        {
+        }
+		
+        public EvaluationDelegateWrapper(EvaluationDelegate evaluation) : base(evaluation)
+        {	
+        }
+		
+        EvaluationDelegate GetEvaluationDelegate()
+        {
+            return (EvaluationDelegate)GetContent();
+        }
+		
+        public void Evaluate(ICandidate candidate)
+        {
+			// use starting _ for PascalCase conversion purposes
+            EvaluationDelegate _evaluation = GetEvaluationDelegate();
+            _evaluation(candidate);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/GenericObjectSetFacade.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/GenericObjectSetFacade.cs
new file mode 100644
index 0000000..2b05b53
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/GenericObjectSetFacade.cs
@@ -0,0 +1,190 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+using System;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal.Query.Result;
+
+namespace Db4objects.Db4o.Internal.Query
+{
+    /// <summary>
+    /// List based objectSet implementation
+    /// </summary>
+    /// <exclude />
+    public class GenericObjectSetFacade<T> : System.Collections.Generic.IList<T>
+    {
+        public readonly StatefulQueryResult _delegate;
+
+        public GenericObjectSetFacade(IQueryResult qr)
+        {
+            _delegate = new StatefulQueryResult(qr);
+        }
+
+        #region IList<T> Members
+        public bool IsReadOnly
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        public T this[int index]
+        {
+            get
+            {
+                return (T)_delegate.Get(index);
+            }
+            set
+            {
+                throw new NotSupportedException();
+            }
+        }
+
+        public void RemoveAt(int index)
+        {
+            throw new NotSupportedException();
+        }
+
+        public void Insert(int index, T value)
+        {
+            throw new NotSupportedException();
+        }
+
+        public bool Remove(T value)
+        {
+            throw new NotSupportedException();
+        }
+
+        public bool Contains(T value)
+        {
+            return IndexOf(value) >= 0;
+        }
+
+        public void Clear()
+        {
+            throw new NotSupportedException();
+        }
+
+        public int IndexOf(T value)
+        {
+            return _delegate.IndexOf(value);
+        }
+
+        public void Add(T value)
+        {
+            throw new NotSupportedException();
+        }
+
+        public bool IsFixedSize
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        #endregion
+
+        #region ICollection<T> Members
+        public bool IsSynchronized
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        public int Count
+        {
+            get
+            {
+                return _delegate.Size();
+            }
+        }
+
+        public void CopyTo(T[] array, int index)
+        {
+            lock (this.SyncRoot)
+            {
+                int i = 0;
+                int s = this.Count;
+                while (i < s)
+                {
+                    array[index + i] = this[i];
+                    i++;
+                }
+            }
+        }
+
+        public object SyncRoot
+        {
+            get
+            {
+                return _delegate.Lock();
+            }
+        }
+
+        #endregion
+
+        #region IEnumerable Members
+
+        class ObjectSetImplEnumerator<T> : System.Collections.IEnumerator, System.Collections.Generic.IEnumerator<T>
+        {
+            System.Collections.Generic.IList<T> _result;
+            int _next = 0;
+
+            public ObjectSetImplEnumerator(System.Collections.Generic.IList<T> result)
+            {
+                _result = result;
+            }
+
+            public void Reset()
+            {
+                _next = 0;
+            }
+
+            object System.Collections.IEnumerator.Current
+            {
+                get
+                {
+                     return _result[_next - 1];
+                }
+            }
+
+            public bool MoveNext()
+            {
+                if (_next < _result.Count)
+                {
+                    ++_next;
+                    return true;
+                }
+                return false;
+            }
+            
+            public T Current
+            {
+                get
+                {
+                     return _result[_next - 1];
+                }
+            }
+
+            public void Dispose()
+            {
+            }
+        }
+
+        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+        {
+            return new ObjectSetImplEnumerator<T>(this);
+        }
+        #endregion
+
+        #region IEnumerable<T> implementation
+        public System.Collections.Generic.IEnumerator<T> GetEnumerator()
+        {
+            return new ObjectSetImplEnumerator<T>(this);
+        }
+        #endregion
+    }
+}
+
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/INQOptimizer.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/INQOptimizer.cs
new file mode 100755
index 0000000..3744945
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/INQOptimizer.cs
@@ -0,0 +1,10 @@
+using System.Reflection;
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Internal.Query
+{
+	public interface INQOptimizer
+	{
+		void Optimize(IQuery q, object predicate, MethodBase method);
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/NQOptimizerFactory.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/NQOptimizerFactory.cs
new file mode 100644
index 0000000..9fb4b58
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/NQOptimizerFactory.cs
@@ -0,0 +1,15 @@
+/* Copyright (C) 2006   Versant Inc.   http://www.db4o.com */
+
+namespace Db4objects.Db4o.Internal.Query
+{
+	using System;
+
+	public class NQOptimizerFactory
+	{
+		public static INQOptimizer CreateExpressionBuilder()
+		{
+			Type type = Type.GetType("Db4objects.Db4o.NativeQueries.NQOptimizer, Db4objects.Db4o.NativeQueries", true);
+			return (INQOptimizer)Activator.CreateInstance(type);
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/NativeQueryHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/NativeQueryHandler.cs
new file mode 100644
index 0000000..9cec7bd
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/NativeQueryHandler.cs
@@ -0,0 +1,230 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+using System;
+using System.IO;
+using System.Reflection;
+using Db4objects.Db4o.Diagnostic;
+using Db4objects.Db4o.Query;
+using Db4objects.Db4o.Internal.Query.Result;
+using Db4objects.Db4o.Internal.Query.Processor;
+using Db4objects.Db4o.Internal.Diagnostic;
+
+namespace Db4objects.Db4o.Internal.Query
+{
+	public class NativeQueryHandler
+	{
+		private IObjectContainer _container;
+
+		private INQOptimizer _builder;
+
+		public event QueryExecutionHandler QueryExecution;
+
+		public event QueryOptimizationFailureHandler QueryOptimizationFailure;
+
+		public NativeQueryHandler(IObjectContainer container)
+		{
+			_container = container;
+		}
+
+        public virtual Db4objects.Db4o.IObjectSet Execute(Db4objects.Db4o.Query.IQuery query, Db4objects.Db4o.Query.Predicate predicate, Db4objects.Db4o.Query.IQueryComparator comparator)
+		{
+			Db4objects.Db4o.Query.IQuery q = ConfigureQuery(query, predicate);
+			q.SortBy(comparator);
+			return q.Execute();
+		}
+
+        public virtual System.Collections.Generic.IList<Extent> Execute<Extent>(Db4objects.Db4o.Query.IQuery query, System.Predicate<Extent> match,
+																				Db4objects.Db4o.Query.IQueryComparator comparator)
+		{
+#if CF
+			return ExecuteUnoptimized<Extent>(QueryForExtent<Extent>(query, comparator), match);
+#else
+			// XXX: check GetDelegateList().Length
+			// only 1 delegate must be allowed
+			// although we could use it as a filter chain
+			// (and)
+			return ExecuteImpl<Extent>(query, match, match.Target, match.Method, match, comparator);
+#endif
+		}
+
+		public static System.Collections.Generic.IList<Extent> ExecuteEnhancedFilter<Extent>(IObjectContainer container, IDb4oEnhancedFilter predicate)
+		{
+			return NQHandler(container).ExecuteEnhancedFilter<Extent>(predicate);
+		}
+
+		public System.Collections.Generic.IList<T> ExecuteEnhancedFilter<T>(IDb4oEnhancedFilter filter)
+		{
+			IQuery query = _container.Query();
+			query.Constrain(typeof(T));
+			filter.OptimizeQuery(query);
+			OnQueryExecution(filter, QueryExecutionKind.PreOptimized);
+			return WrapQueryResult<T>(query);
+		}
+
+		private static NativeQueryHandler NQHandler(IObjectContainer container)
+		{
+			return ((ObjectContainerBase)container).GetNativeQueryHandler();
+		}
+
+		private System.Collections.Generic.IList<Extent> ExecuteImpl<Extent>(
+                                                                        Db4objects.Db4o.Query.IQuery query, 
+																		object originalPredicate,
+																		object matchTarget,
+																		System.Reflection.MethodBase matchMethod,
+																		System.Predicate<Extent> match,
+																		Db4objects.Db4o.Query.IQueryComparator comparator)
+		{
+			Db4objects.Db4o.Query.IQuery q = QueryForExtent<Extent>(query, comparator);
+			try
+			{
+				if (OptimizeNativeQueries())
+				{
+					OptimizeQuery(q, matchTarget, matchMethod);
+					OnQueryExecution(originalPredicate, QueryExecutionKind.DynamicallyOptimized);
+
+					return WrapQueryResult<Extent>(q);
+				}
+			}
+            catch(FileNotFoundException fnfe)
+            {
+                NativeQueryOptimizerNotLoaded(fnfe);
+            }
+            catch(TargetInvocationException tie)
+		    {
+                NativeQueryOptimizerNotLoaded(tie);
+		    }
+			catch(TypeLoadException tle)
+			{
+				NativeQueryOptimizerNotLoaded(tle);
+			}
+            catch (System.Exception e)
+			{
+				OnQueryOptimizationFailure(e);
+			    
+                NativeQueryUnoptimized(e);
+			}
+            
+            return ExecuteUnoptimized(q, match);
+		}
+
+	    private void NativeQueryUnoptimized(Exception e)
+	    {
+            DiagnosticProcessor dp = Container()._handlers.DiagnosticProcessor();
+            if (dp.Enabled()) dp.NativeQueryUnoptimized(null, e);
+	    }
+
+	    private void NativeQueryOptimizerNotLoaded(Exception exception)
+	    {
+	        DiagnosticProcessor dp = Container()._handlers.DiagnosticProcessor();
+	        if (dp.Enabled()) dp.NativeQueryOptimizerNotLoaded(Db4o.Diagnostic.NativeQueryOptimizerNotLoaded.NqNotPresent, exception);
+	    }
+
+	    private System.Collections.Generic.IList<Extent> ExecuteUnoptimized<Extent>(IQuery q, Predicate<Extent> match)
+		{
+			q.Constrain(new GenericPredicateEvaluation<Extent>(match));
+			OnQueryExecution(match, QueryExecutionKind.Unoptimized);
+			return WrapQueryResult<Extent>(q);
+		}
+
+        private Db4objects.Db4o.Query.IQuery QueryForExtent<Extent>(Db4objects.Db4o.Query.IQuery query, Db4objects.Db4o.Query.IQueryComparator comparator)
+		{
+			query.Constrain(typeof(Extent));
+			query.SortBy(comparator);
+			return query;
+		}
+
+		private static System.Collections.Generic.IList<Extent> WrapQueryResult<Extent>(Db4objects.Db4o.Query.IQuery query)
+		{
+			IQueryResult queryResult = ((QQuery)query).GetQueryResult();
+			return new GenericObjectSetFacade<Extent>(queryResult);
+		}
+
+        private Db4objects.Db4o.Query.IQuery ConfigureQuery(Db4objects.Db4o.Query.IQuery query, Db4objects.Db4o.Query.Predicate predicate)
+		{
+			IDb4oEnhancedFilter filter = predicate as IDb4oEnhancedFilter;
+			if (null != filter)
+			{
+				filter.OptimizeQuery(query);
+				OnQueryExecution(predicate, QueryExecutionKind.PreOptimized);
+				return query;
+			}
+
+			query.Constrain(predicate.ExtentType());
+
+			try
+			{
+				if (OptimizeNativeQueries())
+				{
+					OptimizeQuery(query, predicate, predicate.GetFilterMethod());
+					OnQueryExecution(predicate, QueryExecutionKind.DynamicallyOptimized);
+					return query;
+				}
+			}
+			catch (System.Exception e)
+			{
+				OnQueryOptimizationFailure(e);
+
+                if (OptimizeNativeQueries())
+                {
+                    DiagnosticProcessor dp = Container()._handlers.DiagnosticProcessor();
+                    if (dp.Enabled()) dp.NativeQueryUnoptimized(predicate, e);
+                }
+            }
+
+			query.Constrain(new Db4objects.Db4o.Internal.Query.PredicateEvaluation(predicate));
+			OnQueryExecution(predicate, QueryExecutionKind.Unoptimized);
+			return query;
+		}
+
+	    private ObjectContainerBase Container()
+	    {
+	        return ((ObjectContainerBase)_container);
+	    }
+
+	    private bool OptimizeNativeQueries()
+		{
+			return _container.Ext().Configure().OptimizeNativeQueries();
+		}
+
+		void OptimizeQuery(Db4objects.Db4o.Query.IQuery q, object predicate, System.Reflection.MethodBase filterMethod)
+		{
+			if (_builder == null)
+				_builder = NQOptimizerFactory.CreateExpressionBuilder();
+
+			_builder.Optimize(q, predicate, filterMethod);
+		}
+
+		private void OnQueryExecution(object predicate, QueryExecutionKind kind)
+		{
+			if (null == QueryExecution) return;
+			QueryExecution(this, new QueryExecutionEventArgs(predicate, kind));
+		}
+
+		private void OnQueryOptimizationFailure(System.Exception e)
+		{
+			if (null == QueryOptimizationFailure) return;
+			QueryOptimizationFailure(this, new QueryOptimizationFailureEventArgs(e));
+		}
+	}
+
+	class GenericPredicateEvaluation<T> : DelegateEnvelope, Db4objects.Db4o.Query.IEvaluation
+	{
+		public GenericPredicateEvaluation()
+		{
+			// for db4o c/s when CallConstructors == true
+		}
+
+		public GenericPredicateEvaluation(System.Predicate<T> predicate)
+			: base(predicate)
+		{
+		}
+
+		public void Evaluate(Db4objects.Db4o.Query.ICandidate candidate)
+		{
+			// use starting _ for PascalCase conversion purposes
+			System.Predicate<T> _predicate = (System.Predicate<T>)GetContent();
+			candidate.Include(_predicate((T)candidate.GetObject()));
+		}
+	}
+}
+
+
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/ObjectSetFacade.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/ObjectSetFacade.cs
new file mode 100644
index 0000000..0371d06
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/ObjectSetFacade.cs
@@ -0,0 +1,235 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+using System;
+using System.Collections;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal.Query.Result;
+
+namespace Db4objects.Db4o.Internal.Query
+{
+	/// <summary>
+	/// List based objectSet implementation
+	/// </summary>
+	/// <exclude />
+	public class ObjectSetFacade : IExtObjectSet, System.Collections.IList
+	{
+		public readonly StatefulQueryResult _delegate;
+
+        public ObjectSetFacade(IQueryResult qr)
+		{
+            _delegate = new StatefulQueryResult(qr);
+		}
+
+		#region IObjectSet Members
+		
+		public Object Get(int index)
+		{
+            return _delegate.Get(index);
+        }
+
+		public void Sort(Db4objects.Db4o.Query.IQueryComparator cmp)
+		{
+			_delegate.Sort(cmp);
+		}
+
+		public long[] GetIDs() 
+		{
+			return _delegate.GetIDs();
+		}
+
+		public IExtObjectSet Ext() 
+		{
+			return this;
+		}
+
+		public bool MoveNext()
+		{
+			return Enumerator().MoveNext();
+		}
+
+		private IEnumerator _enumerator;
+
+		private IEnumerator Enumerator()
+		{
+			if (null == _enumerator)
+			{
+				_enumerator = GetEnumerator();
+			}
+			return _enumerator;
+		}
+
+		public object Current
+		{
+			get { return Enumerator().Current; }
+		}
+
+		public bool HasNext() 
+		{
+			return _delegate.HasNext();
+		}
+
+		public Object Next() 
+		{
+			return _delegate.Next();
+		}
+
+		public void Reset() 
+		{
+			_delegate.Reset();
+		}
+
+		public int Size() 
+		{
+			return _delegate.Size();
+		}
+    
+		private Object Lock()
+		{
+			return _delegate.Lock();
+		}
+    
+		private IObjectContainer ObjectContainer()
+		{
+			return _delegate.ObjectContainer();
+		}
+
+		public StatefulQueryResult Delegate_()
+		{
+			return _delegate;
+		}
+		#endregion
+
+		#region IList Members
+
+		public bool IsReadOnly
+		{
+			get
+			{
+				return true;
+			}
+		}
+
+		public object this[int index]
+		{
+			get
+			{
+				return _delegate.Get(index);
+			}
+			set
+			{
+				throw new NotSupportedException();
+			}
+		}
+
+		public void RemoveAt(int index)
+		{
+			throw new NotSupportedException();
+		}
+
+		public void Insert(int index, object value)
+		{
+			throw new NotSupportedException();
+		}
+
+		public void Remove(object value)
+		{
+			throw new NotSupportedException();
+		}
+
+		public bool Contains(object value)
+		{
+			return IndexOf(value) >= 0;
+		}
+
+		public void Clear()
+		{
+			throw new NotSupportedException();
+		}
+
+		public int IndexOf(object value)
+		{
+			return _delegate.IndexOf(value);
+		}
+
+		public int Add(object value)
+		{
+			throw new NotSupportedException();
+		}
+
+		public bool IsFixedSize
+		{
+			get
+			{
+				return true;
+			}
+		}
+
+		#endregion
+
+		#region ICollection Members
+		public bool IsSynchronized
+		{
+			get
+			{
+				return true;
+			}
+		}
+
+		public int Count
+		{
+			get
+			{
+				return Size();
+			}
+		}
+
+        public void CopyTo(Array array, int index)
+        {
+            lock (Lock())
+            {
+                int i = 0;
+                int s = _delegate.Size();
+                while (i < s)
+                {
+                    array.SetValue(_delegate.Get(i), index + i);
+                    i++;
+                }
+            }
+        }
+
+        public object SyncRoot
+		{
+			get
+			{
+				return Lock();
+			}
+		}
+
+		#endregion
+		
+		public System.Collections.IEnumerator GetEnumerator()
+		{
+			IEnumerator enumerator = _delegate.GetEnumerator();
+			object current;
+			while (MoveNext(enumerator, out current))
+			{
+				yield return current;
+			}
+		}
+
+		private bool MoveNext(IEnumerator enumerator, out object current)
+		{
+			lock (_delegate.Lock())
+			{
+				if (enumerator.MoveNext())
+				{
+					current = enumerator.Current;
+					return true;
+				}
+			}
+			current = null;
+			return false;
+		}
+	}
+}
+
+
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/QueryExecutionHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/QueryExecutionHandler.cs
new file mode 100644
index 0000000..c3e9e91
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/QueryExecutionHandler.cs
@@ -0,0 +1,34 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+namespace Db4objects.Db4o.Internal.Query
+{
+	public enum QueryExecutionKind
+	{
+		Unoptimized,
+		DynamicallyOptimized,
+		PreOptimized
+	}
+
+	public class QueryExecutionEventArgs : System.EventArgs
+	{
+		private object _predicate;
+		private QueryExecutionKind _kind;
+
+		public QueryExecutionEventArgs(object predicate, QueryExecutionKind kind)
+		{
+			_predicate = predicate;
+			_kind = kind;
+		}
+
+		public object Predicate
+		{
+			get { return _predicate; }
+		}
+
+		public QueryExecutionKind ExecutionKind
+		{
+			get { return _kind; }
+		}
+	}
+
+	public delegate void QueryExecutionHandler(object sender, QueryExecutionEventArgs args);
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/QueryOptimizationFailureHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/QueryOptimizationFailureHandler.cs
new file mode 100644
index 0000000..7cb1d86
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/QueryOptimizationFailureHandler.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+namespace Db4objects.Db4o.Internal.Query
+{
+	public class QueryOptimizationFailureEventArgs : System.EventArgs
+	{
+		System.Exception _reason;
+
+		public QueryOptimizationFailureEventArgs(System.Exception e)
+		{
+			_reason = e;
+		}
+
+		public System.Exception Reason
+		{
+			get { return _reason; }
+		}
+	}
+
+	public delegate void QueryOptimizationFailureHandler(object sender, QueryOptimizationFailureEventArgs args);
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/SilverlightArrayListExtensions.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/SilverlightArrayListExtensions.cs
new file mode 100644
index 0000000..708c1ab
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Query/SilverlightArrayListExtensions.cs
@@ -0,0 +1,14 @@
+using System.Collections;
+
+namespace Db4objects.Db4o.Internal.Query
+{
+#if SILVERLIGHT
+	public static class SilverlightArrayListExtensions
+	{
+		public static void Sort(this ArrayList self, IComparer comparer)
+		{
+			self.Sort(comparer.Compare);
+		}
+	}
+#endif
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Reflect/Emitters/AccessorFactory.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Reflect/Emitters/AccessorFactory.cs
new file mode 100644
index 0000000..fcdf3bf
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Reflect/Emitters/AccessorFactory.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace Db4objects.Db4o.Internal.Reflect.Emitters
+{
+#if !CF
+	public delegate void Setter(object o, object value);
+	public delegate object Getter(object o);
+
+	public static class AccessorFactory
+	{
+		private static readonly Dictionary<FieldInfo, Getter> _getters = new Dictionary<FieldInfo, Getter>();
+		private static readonly Dictionary<FieldInfo, Setter> _setters = new Dictionary<FieldInfo, Setter>();
+		
+		public static Setter SetterFor(FieldInfo field)
+		{
+			return Produce(_setters, field, EmitSetter);
+		}
+
+		public static Getter GetterFor(FieldInfo field)
+		{
+			return Produce(_getters, field, EmitGetter);
+		}
+
+		private delegate TEmitter Producer<TEmitter>(FieldInfo field);
+
+		private static TEmitter Produce<TEmitter>(Dictionary<FieldInfo, TEmitter> cache, FieldInfo field, Producer<TEmitter> producer)
+		{
+			TEmitter emitter;
+			lock (cache)
+			{
+				if (!cache.TryGetValue(field, out emitter))
+				{
+					emitter = producer(field);
+					cache[field] = emitter;
+				}
+			}
+			return emitter;
+		}
+
+		private static Setter EmitSetter(FieldInfo field)
+		{
+			try
+			{
+				return new SetFieldEmitter(field).Emit();
+			}
+			catch
+			{
+				return delegate { };
+			}
+		}
+		
+		private static Getter EmitGetter(FieldInfo field)
+		{
+			try
+			{
+				return new GetFieldEmitter(field).Emit();
+			}
+			catch
+			{
+				return delegate { return null; };
+			}
+		}
+	}
+#endif
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Reflect/Emitters/Emitter.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Reflect/Emitters/Emitter.cs
new file mode 100644
index 0000000..85cb0b0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Reflect/Emitters/Emitter.cs
@@ -0,0 +1,50 @@
+/* Copyright (C) 2004  - 2008  Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Reflection;
+#if !CF
+using System.Reflection.Emit;
+#endif
+
+namespace Db4objects.Db4o.Internal.Reflect.Emitters
+{
+#if !CF
+	internal class Emitter
+	{
+		private readonly DynamicMethod _dynamicMethod;
+		protected readonly FieldInfo _field;
+		protected readonly ILGenerator _il;
+
+		public Emitter(FieldInfo field, Type returnType, Type[] paramTypes)
+		{
+			_field = field;
+			_dynamicMethod = new DynamicMethod(_field.DeclaringType.Name + "$" + _field.Name, returnType, paramTypes, _field.DeclaringType);
+			_il = _dynamicMethod.GetILGenerator();
+		}
+
+		protected void BoxIfNeeded(Type type)
+		{
+			if (!type.IsValueType) return;
+			_il.Emit(OpCodes.Box, type);
+		}
+
+		protected void EmitLoadTargetObject(Type expectedType)
+		{
+			_il.Emit(OpCodes.Ldarg_0); // target object is the first argument
+			if (expectedType.IsValueType)
+			{
+				_il.Emit(OpCodes.Unbox, expectedType);
+			}
+			else
+			{
+				_il.Emit(OpCodes.Castclass, expectedType);
+			}
+		}
+
+		protected Delegate CreateDelegate<T>()
+		{
+			return  _dynamicMethod.CreateDelegate(typeof(T));
+		}
+	}
+#endif
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Reflect/Emitters/GetFieldEmitter.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Reflect/Emitters/GetFieldEmitter.cs
new file mode 100644
index 0000000..b9224fd
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Reflect/Emitters/GetFieldEmitter.cs
@@ -0,0 +1,50 @@
+/* Copyright (C) 2004  - 2008  Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Reflection;
+#if !CF
+using System.Reflection.Emit;
+#endif
+using System.Runtime.CompilerServices;
+
+namespace Db4objects.Db4o.Internal.Reflect.Emitters
+{
+#if !CF
+	class GetFieldEmitter : Emitter
+	{
+		public GetFieldEmitter(FieldInfo field) : base(field, typeof(object), new Type[] { typeof(object) })
+		{
+		}
+
+		public Getter Emit()
+		{
+			EmitMethodBody();
+			return (Getter)CreateDelegate <Getter>();
+		}
+
+		private void EmitMethodBody()
+		{
+			if (_field.IsStatic)
+			{
+				// make sure type is initialized before
+				// accessing any static fields
+				RuntimeHelpers.RunClassConstructor(_field.DeclaringType.TypeHandle);
+				_il.Emit(OpCodes.Ldsfld, _field);
+			}
+			else
+			{
+				EmitLoadTargetObject(_field.DeclaringType);
+				_il.Emit(OpCodes.Ldfld, _field);
+			}
+
+			EmitReturn();
+		}
+
+		protected void EmitReturn()
+		{
+			BoxIfNeeded(_field.FieldType);
+			_il.Emit(OpCodes.Ret);
+		}
+	}
+#endif
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Reflect/Emitters/SetFieldEmitter.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Reflect/Emitters/SetFieldEmitter.cs
new file mode 100644
index 0000000..25cfc8d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Reflect/Emitters/SetFieldEmitter.cs
@@ -0,0 +1,79 @@
+/* Copyright (C) 2004  - 2008  Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Reflection;
+#if !CF
+using System.Reflection.Emit;
+#endif
+
+namespace Db4objects.Db4o.Internal.Reflect.Emitters
+{
+#if !CF
+	class SetFieldEmitter : Emitter
+	{
+		public SetFieldEmitter(FieldInfo field) : base(field, typeof(void), new Type[] { typeof(object), typeof(object) })
+		{	
+		}
+
+		public Setter Emit()
+		{
+			EmitMethodBody();
+			return (Setter) CreateDelegate<Setter>();
+		}
+
+		private void EmitMethodBody()
+		{
+			if (_field.IsStatic)
+			{
+				EmitLoadValue();
+				_il.Emit(OpCodes.Stsfld, _field);
+			}
+			else
+			{
+				EmitLoadTargetObject(_field.DeclaringType);
+				EmitLoadValue();
+				_il.Emit(OpCodes.Stfld, _field);
+			}
+			_il.Emit(OpCodes.Ret);
+		}
+
+		private void EmitLoadValue()
+		{
+			if (_field.FieldType.IsValueType)
+			{
+				EmitLoadValueType();
+			}
+			else
+			{
+				EmitLoadReferenceType();
+			}
+			
+		}
+
+		private void EmitLoadReferenceType()
+		{
+			_il.Emit(OpCodes.Ldarg_1);
+			_il.Emit(OpCodes.Castclass, _field.FieldType);
+		}
+
+		private void EmitLoadValueType()
+		{
+			Type fieldType = _field.FieldType;
+
+			_il.Emit(OpCodes.Ldarg_1);
+			Label nonNull = _il.DefineLabel();
+			_il.Emit(OpCodes.Brtrue_S, nonNull);
+
+			_il.DeclareLocal(fieldType);
+			_il.Emit(OpCodes.Ldloc_0);
+			Label end = _il.DefineLabel();
+			_il.Emit(OpCodes.Br_S, end);
+			_il.MarkLabel(nonNull);
+			_il.Emit(OpCodes.Ldarg_1);
+			_il.Emit(OpCodes.Unbox, fieldType);
+			_il.Emit(OpCodes.Ldobj, fieldType);
+			_il.MarkLabel(end);
+		}
+	}
+#endif
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Reflect/FastNetReflector.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Reflect/FastNetReflector.cs
new file mode 100644
index 0000000..7692034
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/Reflect/FastNetReflector.cs
@@ -0,0 +1,84 @@
+/* Copyright (C) 2004  - 2008  Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Reflection;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Internal.Reflect.Emitters;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Net;
+
+namespace Db4objects.Db4o.Internal.Reflect
+{
+#if !CF
+	public class FastNetReflector : NetReflector
+	{
+		override protected IReflectClass CreateClass(Type forType)
+		{
+			return new FastNetClass(Parent(), this, forType);
+		}
+
+		public override object DeepClone(object obj)
+		{
+			return new FastNetReflector();
+		}
+	}
+
+	class FastNetClass : NetClass
+	{
+		public FastNetClass(IReflector reflector, NetReflector netReflector, Type clazz) : base(reflector, netReflector, clazz)
+		{
+		}
+
+		protected override IReflectField CreateField(FieldInfo field)
+		{
+			return new FastNetField(_reflector, field);
+		}
+	}
+
+	class FastNetField : NetField
+	{
+		private Getter _getter;
+		private Setter _setter;
+
+		public FastNetField(IReflector reflector, FieldInfo field) : base(reflector, field)
+		{	
+		}
+
+		public override object Get(object onObject)
+		{
+			if (null == _getter) _getter = AccessorFactory.GetterFor(_field);
+			try
+			{
+				return _getter(onObject);
+			}
+			catch (FieldAccessException)
+			{
+				_getter = _field.GetValue;
+				return _getter(onObject);
+			}
+			catch (Exception e)
+			{
+				throw new Db4oException(e);
+			}
+		}
+
+		public override void Set(object onObject, object attribute)
+		{
+			if (null == _setter) _setter = AccessorFactory.SetterFor(_field);
+			try
+			{
+				_setter(onObject, attribute);
+			}
+			catch (FieldAccessException)
+			{
+				_setter = _field.SetValue;
+				_setter(onObject, attribute);
+			}
+			catch (Exception e)
+			{
+				throw new Db4oException(e);
+			}
+		}
+	}
+#endif
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/ReflectPlatform.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/ReflectPlatform.cs
new file mode 100644
index 0000000..0730b24
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/ReflectPlatform.cs
@@ -0,0 +1,54 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+
+using System;
+using Sharpen.Lang;
+
+namespace Db4objects.Db4o.Internal
+{
+	public class ReflectPlatform
+	{
+		public static Type ForName(string typeName)
+		{
+			try
+			{
+				return TypeReference.FromString(typeName).Resolve();
+			}
+			catch
+			{
+				return null;
+			}
+		}
+
+		public static object CreateInstance(string typeName)
+		{
+            return ReflectPlatform.CreateInstance(ForName(typeName));
+		}
+
+        public static object CreateInstance(Type type)
+        {
+            try
+            {
+                return Activator.CreateInstance(type);
+            }
+            catch
+            {
+                return null;
+            }
+        }
+
+	    public static string FullyQualifiedName(Type type)
+	    {
+	        return TypeReference.FromType(type).GetUnversionedName();
+	    }
+
+	    public static bool IsNamedClass(Type type)
+	    {
+	        return true;
+	    }
+
+        public static string SimpleName(Type type)
+        {
+            return type.Name;
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/TagAttribute.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/TagAttribute.cs
new file mode 100644
index 0000000..97c6bfd
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/TagAttribute.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+using System;
+
+namespace Db4objects.Db4o.Internal
+{
+    [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
+    public class TagAttribute : Attribute
+    {
+        public TagAttribute(string tag)
+        {
+            this.tag = tag;
+        }
+
+        public string Tag
+        {
+            get { return tag; }
+        }
+
+        private string tag;
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/TypeHandlerConfigurationDotNet.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/TypeHandlerConfigurationDotNet.cs
new file mode 100644
index 0000000..62dc4b9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Internal/TypeHandlerConfigurationDotNet.cs
@@ -0,0 +1,129 @@
+/* Copyright (C) 2009   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Collections.Generic;
+using Db4objects.Db4o.Collections;
+using Db4objects.Db4o.Internal.Collections;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Net;
+using Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Internal
+{
+    class TypeHandlerConfigurationDotNet : TypeHandlerConfiguration
+    {
+        public TypeHandlerConfigurationDotNet(Config4Impl config) : base(config)
+        {
+            ListTypeHandler(new CollectionTypeHandler());
+            MapTypeHandler(new MapTypeHandler());
+        }
+
+        public override void Apply()
+        {
+#if !SILVERLIGHT
+			RegisterCollection(typeof(System.Collections.ArrayList));
+            RegisterCollection(typeof (System.Collections.CollectionBase));
+            RegisterMap(typeof (System.Collections.Hashtable));
+            RegisterMap(typeof (System.Collections.Specialized.HybridDictionary));
+#if !CF
+            RegisterMap(typeof (System.Collections.DictionaryBase));
+#endif
+#endif
+			RegisterGenericTypeHandlers();
+			RegisterBigSetTypeHandler();
+            RegisterSystemArrayTypeHandler();
+        }
+
+    	private void RegisterBigSetTypeHandler()
+    	{
+    		RegisterGenericTypeHandler(typeof(BigSet<>), new BigSetTypeHandler());
+    	}
+
+    	private void RegisterGenericTypeHandlers()
+        {
+			GenericCollectionTypeHandler handler = new GenericCollectionTypeHandler();
+    		handler.RegisterSupportedTypesWith(delegate(Type type) 
+			{
+				RegisterGenericTypeHandler(type, handler);
+    		});
+
+#if NET_3_5 && ! CF
+			_config.Reflector().RegisterCollection(new GenericCollectionTypePredicate(typeof(HashSet<>)));
+#endif 
+
+			Type[] dictionaryTypes = new Type[] {
+				typeof(ActivatableDictionary<,>),
+				typeof(Dictionary<,>),
+#if !SILVERLIGHT
+				typeof(SortedList<,>),
+#if !CF
+				typeof(SortedDictionary<,>),
+#endif
+#endif
+			};
+            _config.RegisterTypeHandler(new GenericTypeHandlerPredicate(dictionaryTypes), new MapTypeHandler());
+
+        }
+
+    	private void RegisterGenericTypeHandler(Type genericTypeDefinition, ITypeHandler4 handler)
+    	{
+    		_config.RegisterTypeHandler(new GenericTypeHandlerPredicate(genericTypeDefinition), handler);
+    	}
+
+    	internal class GenericTypeHandlerPredicate : ITypeHandlerPredicate
+        {
+            private readonly Type[] _genericTypes;
+
+            internal GenericTypeHandlerPredicate(params Type[] genericType)
+            {
+                _genericTypes = genericType;
+            }
+
+            public bool Match(IReflectClass classReflector)
+            {
+                Type type = NetReflector.ToNative(classReflector);
+                if (type == null)
+                {
+                    return false;
+                }
+
+                if (!type.IsGenericType)
+                {
+                    return false;
+                }
+            	return ((IList<Type>) _genericTypes).Contains(type.GetGenericTypeDefinition());
+            }
+        }
+
+        private void RegisterSystemArrayTypeHandler()
+        {
+            _config.RegisterTypeHandler(new SystemArrayPredicate(), new SystemArrayTypeHandler());
+        }
+
+        internal class GenericCollectionTypePredicate : IReflectClassPredicate
+        {
+            private readonly Type _type;
+
+            internal GenericCollectionTypePredicate(Type t)
+            {
+                _type = t;
+            }
+
+
+            public bool Match(IReflectClass classReflector)
+            {
+                Type type = NetReflector.ToNative(classReflector);
+                if (type == null)
+                {
+                    return false;
+                }
+                if (!type.IsGenericType)
+                {
+                    return false;
+                }
+                return _type == type.GetGenericTypeDefinition();
+            }
+        }
+
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Query/EvaluationDelegate.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Query/EvaluationDelegate.cs
new file mode 100644
index 0000000..9a45709
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Query/EvaluationDelegate.cs
@@ -0,0 +1,8 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o.Query
+{
+    public delegate void EvaluationDelegate(ICandidate candidate);
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Query/ISodaQueryFactory.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Query/ISodaQueryFactory.cs
new file mode 100644
index 0000000..205739a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Query/ISodaQueryFactory.cs
@@ -0,0 +1,21 @@
+using Db4objects.Db4o.Query;
+
+namespace Db4objects.Db4o.Query
+{
+    public interface ISodaQueryFactory
+    {
+        /// <summary>
+        /// creates a new SODA
+        /// <see cref="Db4objects.Db4o.Query.IQuery">Query</see>
+        /// .
+        /// <br /><br />
+        /// Linq queries are the recommended main db4o query interface.
+        /// <br /><br />
+        /// Use
+        /// <see cref="Db4objects.Db4o.IObjectContainer.QueryByExample">QueryByExample(Object template)</see>
+        /// for simple Query-By-Example.<br /><br />
+        /// </summary>
+        /// <returns>a new IQuery object</returns>
+        IQuery Query();
+    }
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Query/PredicatePlatform.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Query/PredicatePlatform.cs
new file mode 100755
index 0000000..18c0c0f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Query/PredicatePlatform.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace Db4objects.Db4o.Query
+{
+	using System.Reflection;
+	
+	public sealed class PredicatePlatform
+	{
+		public static readonly string PredicatemethodName = "Match";
+		
+		public static bool IsFilterMethod(MethodInfo method)
+		{
+			if (method.GetParameters().Length != 1) return false;
+			return method.Name == PredicatemethodName;
+		}
+
+        public static T GetField<T>(Object obj, string fieldName)
+        {
+            return (T) obj.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance).GetValue(obj);
+        }
+	}
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetArray.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetArray.cs
new file mode 100644
index 0000000..b0853a6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetArray.cs
@@ -0,0 +1,111 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+using System;
+
+namespace Db4objects.Db4o.Reflect.Net
+{
+    public class NetArray : Db4objects.Db4o.Reflect.Core.AbstractReflectArray
+    {
+        public NetArray(IReflector reflector) : base(reflector)
+        {
+        }
+
+        private static Type GetNetType(IReflectClass clazz)
+		{
+			return ((NetClass)clazz).GetNetType();
+		}
+
+        public override void Analyze(object obj, ArrayInfo info)
+        {
+            info.Nullable(IsNullableType(obj.GetType()));
+        }
+
+        private bool IsNullableType(Type type)
+        {
+            if (type.IsArray)
+            {
+                return IsNullableType(type.GetElementType());
+            }
+
+            Type underlyingType = Nullable.GetUnderlyingType(type);
+            return underlyingType != null;
+        }
+
+        public override object NewInstance(IReflectClass componentType, ArrayInfo info)
+        {
+            Type type = GetNetType(componentType);
+            if (info.Nullable())
+            {
+                type = NullableType(type);
+            }
+            MultidimensionalArrayInfo multiDimensionalInfo = info as MultidimensionalArrayInfo;
+            if (multiDimensionalInfo == null)
+            {
+                return System.Array.CreateInstance(type, info.ElementCount());
+            }
+            int[] dimensions = multiDimensionalInfo.Dimensions();
+            if (dimensions.Length == 1)
+            {
+                return UnfoldArrayCreation(type, dimensions, 0);
+            }
+            return UnfoldArrayCreation(GetArrayType(type, dimensions.Length - 1), dimensions, 0);
+        }
+
+        private Type NullableType(Type type)
+        {
+            if(IsNullableType(type))
+            {
+                return type;
+            }
+            return typeof(Nullable<>).MakeGenericType(new Type[] { type });
+        }
+        
+        public override object NewInstance(IReflectClass componentType, int[] dimensions)
+        {
+            Type type = GetNetType(componentType);
+            if (dimensions.Length == 1)
+            {
+                return UnfoldArrayCreation(type, dimensions, 0);
+            }
+            
+            return UnfoldArrayCreation(GetArrayType(type, dimensions.Length - 1), dimensions, 0);
+        }
+
+        private static object UnfoldArrayCreation(Type type, int[] dimensions, int dimensionIndex)
+        {   
+            int length = dimensions[dimensionIndex];
+            Array array = Array.CreateInstance(type, length);
+            if (dimensionIndex == dimensions.Length - 1)
+            {
+                return array;
+            }
+            for (int i=0; i<length; ++i)
+            {
+                object value = UnfoldArrayCreation(type.GetElementType(), dimensions, dimensionIndex + 1);
+                array.SetValue(value, i);
+            }
+            return array;
+        }
+
+        private static System.Type GetArrayType(Type type, int dimensions)
+        {
+			if (dimensions < 1) throw new ArgumentOutOfRangeException("dimensions");
+            
+            Type arrayType = MakeArrayType(type);
+            for (int i=1; i<dimensions; ++i)
+            {
+                arrayType = MakeArrayType(arrayType);
+            }
+            return arrayType;
+        }
+
+        private static Type MakeArrayType(Type type)
+        {
+        	return Sharpen.Lang.ArrayTypeReference.MakeArrayType(type, 1);
+        }
+
+        public override object NewInstance(IReflectClass componentType, int length)
+        {
+            return System.Array.CreateInstance(GetNetType(componentType), length);
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetClass.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetClass.cs
new file mode 100644
index 0000000..ba8556e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetClass.cs
@@ -0,0 +1,236 @@
+/* Copyright (C) 2007 Versant Inc.   http://www.db4o.com */
+using System;
+using System.Reflection;
+using Db4objects.Db4o.Internal;
+using Sharpen.Lang;
+using Db4objects.Db4o.Reflect.Core;
+
+namespace Db4objects.Db4o.Reflect.Net
+{
+	/// <summary>Reflection implementation for Class to map to .NET reflection.</summary>
+	/// <remarks>Reflection implementation for Class to map to .NET reflection.</remarks>
+	public class NetClass : IConstructorAwareReflectClass
+	{
+		protected readonly IReflector _reflector;
+		
+		private readonly NetReflector _netReflector;
+
+		private readonly Type _type;
+
+		private ReflectConstructorSpec _constructor;
+
+		private string _name;
+	    
+	    private IReflectField[] _fields;
+
+	    public NetClass(IReflector reflector, NetReflector netReflector, Type clazz)
+		{
+			if(reflector == null)
+			{
+				throw new ArgumentNullException("reflector");
+			}
+			
+			if(netReflector == null)
+			{
+				throw new ArgumentNullException("netReflector");
+			}
+			
+			_reflector = reflector;
+			_netReflector = netReflector;
+			_type = clazz;
+			_constructor = ReflectConstructorSpec.UnspecifiedConstructor;
+		}
+
+		public virtual IReflectClass GetComponentType()
+		{
+			return _reflector.ForClass(_type.GetElementType());
+		}
+
+		private IReflectConstructor[] GetDeclaredConstructors()
+		{
+			ConstructorInfo[] constructors = _type.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+			IReflectConstructor[] reflectors = new IReflectConstructor[constructors.Length];
+			for (int i = 0; i < constructors.Length; i++)
+			{
+				reflectors[i] = new NetConstructor(_reflector, constructors[i]);
+			}
+			return reflectors;
+		}
+
+		public virtual IReflectField GetDeclaredField(string name)
+		{
+			foreach (IReflectField field in GetDeclaredFields())
+			{
+				if (field.GetName() == name) return field;
+			}
+			return null;
+		}
+
+		public virtual IReflectField[] GetDeclaredFields()
+		{
+			if (_fields == null)
+			{
+				_fields = CreateDeclaredFieldsArray();
+			}
+			return _fields;
+		}
+		
+		private IReflectField[] CreateDeclaredFieldsArray()
+		{	
+			FieldInfo[] fields = Sharpen.Runtime.GetDeclaredFields(_type);
+			IReflectField[] reflectors = new IReflectField[fields.Length];
+			for (int i = 0; i < reflectors.Length; i++)
+			{
+				reflectors[i] = CreateField(fields[i]);
+			}
+			return reflectors;
+		}
+
+		protected virtual IReflectField CreateField(FieldInfo field)
+		{
+			return new NetField(_reflector, field);
+		}
+
+		public virtual IReflectClass GetDelegate()
+		{
+			return this;
+		}
+
+		public virtual IReflectMethod GetMethod(string methodName, IReflectClass[] paramClasses)
+		{
+			try
+			{
+				Type[] parameterTypes = NetReflector.ToNative(paramClasses);
+				MethodInfo method = GetMethod(_type, methodName, parameterTypes);
+				if (method == null)
+				{
+					return null;
+				}
+				return new NetMethod(_reflector, method);
+			}
+			catch
+			{
+				return null;
+			}
+		}
+
+		private static MethodInfo GetMethod(Type type, string methodName, Type[] parameterTypes)
+		{
+			MethodInfo found = Sharpen.Runtime.GetDeclaredMethod(type, methodName, parameterTypes);
+			if (found != null) return found;
+
+			Type baseType = type.BaseType;
+			if (null == baseType) return null;
+			return GetMethod(baseType, methodName, parameterTypes);
+		}
+
+		public virtual string GetName()
+		{
+            if (_name == null)
+            {
+                _name = TypeReference.FromType(_type).GetUnversionedName();
+            }
+            return _name;
+		}
+
+		public virtual IReflectClass GetSuperclass()
+		{
+			return _reflector.ForClass(_type.BaseType);
+		}
+
+		public virtual bool IsAbstract()
+		{
+			return _type.IsAbstract;
+		}
+
+		public virtual bool IsArray()
+		{
+			return _type.IsArray;
+		}
+
+		public virtual bool IsAssignableFrom(IReflectClass type)
+		{
+			if (!(type is NetClass))
+			{
+				return false;
+			}
+			return _type.IsAssignableFrom(((NetClass)type).GetNetType());
+		}
+
+		public virtual bool IsInstance(object obj)
+		{
+			return _type.IsInstanceOfType(obj);
+		}
+
+		public virtual bool IsInterface()
+		{
+			return _type.IsInterface;
+		}
+
+		public virtual bool IsCollection()
+		{
+			return _reflector.IsCollection(this);
+		}
+
+		public virtual bool IsPrimitive()
+		{
+			return _type.IsPrimitive
+			       || _type == typeof(DateTime)
+			       || _type == typeof(decimal);
+		}
+
+		public virtual object NewInstance()
+		{
+			CreateConstructor();
+			return _constructor.NewInstance();
+		}
+
+		public virtual Type GetNetType()
+		{
+			return _type;
+		}
+
+		public virtual IReflector Reflector()
+		{
+			return _reflector;
+		}
+		
+		public virtual IReflectConstructor GetSerializableConstructor()
+		{
+#if !CF && !SILVERLIGHT
+			return new SerializationConstructor(GetNetType());
+#else
+			return null;
+#endif
+		}
+
+		public override string ToString()
+		{
+			return "NetClass(" + _type + ")";
+		}
+
+		public virtual object NullValue() 
+		{
+			return _netReflector.NullValue(this);
+		}
+	
+		private void CreateConstructor() 
+		{
+			if(!_constructor.CanBeInstantiated().IsUnspecified())
+			{
+				return;
+			}
+			_constructor = ConstructorSupport.CreateConstructor(this, _type, _netReflector.Configuration(), GetDeclaredConstructors());
+		}
+		
+		public virtual bool EnsureCanBeInstantiated() {
+			CreateConstructor();
+			return _constructor.CanBeInstantiated().DefiniteYes();
+		}
+
+	    public bool IsImmutable()
+	    {
+	        return IsPrimitive() || Platform4.IsSimple(_type);
+	    }
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetConstructor.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetConstructor.cs
new file mode 100644
index 0000000..5b91e0c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetConstructor.cs
@@ -0,0 +1,37 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+namespace Db4objects.Db4o.Reflect.Net
+{
+
+	/// <remarks>Reflection implementation for Constructor to map to .NET reflection.</remarks>
+	public class NetConstructor : Db4objects.Db4o.Reflect.Core.IReflectConstructor
+	{
+		private readonly Db4objects.Db4o.Reflect.IReflector reflector;
+
+		private readonly System.Reflection.ConstructorInfo constructor;
+
+		public NetConstructor(Db4objects.Db4o.Reflect.IReflector reflector, System.Reflection.ConstructorInfo
+			 constructor)
+		{
+			this.reflector = reflector;
+			this.constructor = constructor;
+			Db4objects.Db4o.Internal.Platform4.SetAccessible(constructor);
+		}
+
+		public virtual Db4objects.Db4o.Reflect.IReflectClass[] GetParameterTypes()
+		{
+			return Db4objects.Db4o.Reflect.Net.NetReflector.ToMeta(reflector, Sharpen.Runtime.GetParameterTypes(constructor));
+		}
+
+		public virtual object NewInstance(object[] parameters)
+		{
+			try
+			{
+				return constructor.Invoke(parameters);
+			}
+			catch
+			{
+				return null;
+			}
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetField.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetField.cs
new file mode 100644
index 0000000..e81bfde
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetField.cs
@@ -0,0 +1,135 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using Db4objects.Db4o.Ext;
+
+namespace Db4objects.Db4o.Reflect.Net
+{
+	public class NetField : IReflectField
+	{
+		private readonly IReflector _reflector;
+
+		protected readonly FieldInfo _field;
+
+        private static IList _transientMarkers;
+
+		public NetField(IReflector reflector, FieldInfo field)
+		{
+			_reflector = reflector;
+			_field = field;
+		}
+
+        public override string ToString()
+        {
+            return string.Format("NetField({0})", _field);
+        }
+
+		public virtual string GetName()
+		{
+			return _field.Name;
+		}
+
+		public virtual IReflectClass GetFieldType()
+		{
+			return _reflector.ForClass(_field.FieldType);
+		}
+
+		public virtual bool IsPublic()
+		{
+			return _field.IsPublic;
+		}
+
+		public virtual bool IsStatic()
+		{
+			return _field.IsStatic;
+		}
+
+		public virtual bool IsTransient()
+		{
+            return IsTransient(_field);
+		}
+
+		public virtual void SetAccessible()
+		{	
+		}
+
+		public virtual object Get(object onObject)
+		{
+			try
+			{
+				return _field.GetValue(onObject);
+			}
+			catch(Exception e)
+			{
+				throw new Db4oException(e);
+			}
+		}
+
+		public virtual void Set(object onObject, object attribute)
+		{
+			try
+			{
+				_field.SetValue(onObject, attribute);
+			}
+			catch(Exception e)
+			{
+				throw new Db4oException(e);
+			}
+		}
+		
+		public object IndexEntry(object orig)
+		{
+			return orig;
+		}
+		
+		public IReflectClass IndexType()
+		{
+			return GetFieldType();
+		}
+
+        public static bool IsTransient(FieldInfo field)
+        {
+            if (field.IsNotSerialized) return true;
+            if (field.IsDefined(typeof(TransientAttribute), true)) return true;
+            if (_transientMarkers == null) return false;
+            return CheckForTransient(field.GetCustomAttributes(true));
+        }
+
+        private static bool CheckForTransient(object[] attributes)
+        {   
+            if (attributes == null) return false;
+
+            foreach (object attribute in attributes)
+            {
+                string attributeName = attribute.GetType().FullName;
+                if (_transientMarkers.Contains(attributeName)) return true;
+            }
+            return false;
+        }
+
+        public static void MarkTransient(Type attributeType)
+        {
+            MarkTransient(attributeType.FullName);
+        }
+
+        public static void MarkTransient(string attributeName)
+        {
+            if (_transientMarkers == null)
+            {
+                _transientMarkers = new List<string>();
+            }
+            else if (_transientMarkers.Contains(attributeName))
+            {
+                return;
+            }
+            _transientMarkers.Add(attributeName);
+        }
+
+	    public static void ResetTransientMarkers()
+	    {
+            _transientMarkers = null;
+	    }
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetMethod.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetMethod.cs
new file mode 100644
index 0000000..619cd05
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetMethod.cs
@@ -0,0 +1,39 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+namespace Db4objects.Db4o.Reflect.Net
+{
+	public class NetMethod : Db4objects.Db4o.Reflect.IReflectMethod
+	{
+		private readonly System.Reflection.MethodInfo method;
+
+		private readonly Db4objects.Db4o.Reflect.IReflector _reflector;
+
+		public NetMethod(Db4objects.Db4o.Reflect.IReflector reflector, System.Reflection.MethodInfo method)
+		{
+			_reflector = reflector;
+			this.method = method;
+		}
+
+		public Db4objects.Db4o.Reflect.IReflectClass GetReturnType() 
+		{
+			return _reflector.ForClass(method.ReturnType);
+		}
+
+		public virtual object Invoke(object onObject, object[] parameters)
+		{
+            try
+            {
+                return method.Invoke(onObject, parameters);
+            }
+            catch (System.Reflection.TargetInvocationException e)
+            {
+                throw new Db4objects.Db4o.Internal.ReflectException(e.InnerException);
+            }
+#if CF
+            catch (System.Exception e)
+			{
+                throw new Db4objects.Db4o.Internal.ReflectException(e);
+            }
+#endif
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetReflector.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetReflector.cs
new file mode 100644
index 0000000..4f40746
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Reflect/Net/NetReflector.cs
@@ -0,0 +1,210 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+using System;
+
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.Reflect.Net
+{
+	public class NetReflector : IReflector
+	{
+
+	    protected IReflector _parent;
+
+		private IReflectArray _array;
+		
+		private IReflectorConfiguration _config;
+
+        public NetReflector(IReflectorConfiguration config)
+        {
+            _config = config;
+        }
+
+        public NetReflector() : this(new DefaultConfiguration())
+        {
+
+        }
+
+
+		public virtual IReflectArray Array()
+		{
+			if(_array == null)
+			{
+				_array = new NetArray(Parent());
+			}
+			return _array;
+		}
+
+		public virtual object DeepClone(object obj)
+		{
+			return new NetReflector(_config);
+		}
+
+		public virtual IReflectClass ForClass(Type forType)
+		{
+            if(forType == null)
+            {
+                return null;
+            }
+		    Type underlyingType = GetUnderlyingType(forType);
+            if (underlyingType.IsPrimitive)
+            {
+                return CreateClass(forType);
+            }
+            return CreateClass(underlyingType);
+		}
+
+		protected virtual IReflectClass CreateClass(Type type)
+		{
+			if(type == null)
+			{
+				return null;
+			}
+			return new NetClass(Parent(), this, type);
+		}
+
+		private static Type GetUnderlyingType(Type type)
+        {	
+        	if(type == null)
+        	{
+        		return null;
+        	}
+            Type underlyingType = Nullable.GetUnderlyingType(type);
+            if (underlyingType != null)
+            {
+                return underlyingType;
+            }
+            return type;
+        }
+
+		public virtual IReflectClass ForName(string className)
+		{
+			try
+			{
+				Type type = ReflectPlatform.ForName(className);
+				if (type == null) return null;
+				return ForClass(type);
+			}
+			catch
+			{
+			}
+			return null;
+		}
+
+		public virtual IReflectClass ForObject(object a_object)
+		{
+			if (a_object == null)
+			{
+				return null;
+			}
+			return Parent().ForClass(a_object.GetType());
+		}
+
+		public virtual bool IsCollection(IReflectClass candidate)
+		{
+			if (candidate.IsArray())
+			{
+				return false;
+			}
+		    NetClass netClass = candidate as NetClass;
+            if (null == netClass)
+            {
+                return false;
+            }
+		    return typeof(System.Collections.ICollection).IsAssignableFrom(netClass.GetNetType());
+		}
+
+		public virtual bool MethodCallsSupported()
+		{
+			return true;
+		}
+
+		public static IReflectClass[] ToMeta(IReflector reflector, Type[] clazz)
+		{
+			IReflectClass[] claxx = null;
+			if (clazz != null)
+			{
+				claxx = new IReflectClass[clazz.Length];
+				for (int i = 0; i < clazz.Length; i++)
+				{
+					if (clazz[i] != null)
+					{
+						claxx[i] = reflector.ForClass(clazz[i]);
+					}
+				}
+			}
+			return claxx;
+		}
+
+		public static Type[] ToNative(IReflectClass[] claxx)
+		{
+			Type[] clazz = null;
+			if (claxx != null)
+			{
+				clazz = new Type[claxx.Length];
+				for (int i = 0; i < claxx.Length; i++)
+				{
+					if (claxx[i] != null)
+					{
+						IReflectClass reflectClass = claxx[i];
+						clazz[i] = ToNative(reflectClass);
+					}
+				}
+			}
+			return clazz;
+		}
+
+		public static Type ToNative(IReflectClass reflectClass)
+		{
+            NetClass netClass = reflectClass.GetDelegate() as NetClass;
+            if(netClass == null)
+            {
+                return null;
+            }
+			return netClass.GetNetType();
+		}
+
+		public virtual void SetParent(IReflector reflector)
+		{
+			_parent = reflector;
+		}
+
+        public virtual void Configuration(IReflectorConfiguration config)
+		{
+			_config = config;
+		}
+		
+        public virtual IReflectorConfiguration Configuration()
+		{
+			return _config;
+		}
+
+		public virtual object NullValue(IReflectClass clazz) 
+		{
+			return Platform4.NullValue(ToNative(clazz));
+		}
+		
+		protected IReflector Parent()
+		{
+			if(_parent == null)
+			{
+				return this;
+			}
+			
+			return _parent;
+		}
+
+        private class DefaultConfiguration : IReflectorConfiguration
+	    {
+            public bool TestConstructors()
+            {
+                return false;
+            }
+
+            public bool CallConstructor(IReflectClass clazz)
+            {
+                return false;
+            }
+	    }
+
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/TransientAttribute.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/TransientAttribute.cs
new file mode 100644
index 0000000..2b70ca8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/TransientAttribute.cs
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+
+namespace Db4objects.Db4o
+{
+    /// <summary>
+    /// Marks a field or event as transient.
+    /// </summary>
+    /// <remarks>
+    /// Transient fields are not stored by db4o.
+    /// <br />
+    /// If you don't want a field to be stored by db4o,
+    /// simply mark it with this attribute.
+    /// </remarks>
+    /// <exclude />
+    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Event)]
+    public class TransientAttribute : Attribute
+	{
+        public TransientAttribute()
+		{
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/CollectionTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/CollectionTypeHandler.cs
new file mode 100644
index 0000000..8e80004
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/CollectionTypeHandler.cs
@@ -0,0 +1,19 @@
+/* Copyright (C) 2010   Versant Inc.   http://www.db4o.com */
+
+using System.Collections;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+	public partial class CollectionTypeHandler 
+	{
+		private void AddToCollection(ICollection collection, object element) 
+		{
+			((IList)collection).Add(element);
+		}
+	
+		private void ClearCollection(ICollection collection) 
+		{
+			((IList)collection).Clear();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/ComparablePreparedComparison.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/ComparablePreparedComparison.cs
new file mode 100644
index 0000000..71519c1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/ComparablePreparedComparison.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2009  Versant Inc.  http://www.db4o.com */
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+
+namespace Db4objects.Db4o.native.Db4objects.Db4o.Typehandlers
+{
+	sealed internal class ComparablePreparedComparison<T> : IPreparedComparison where T : IComparable
+	{
+		public ComparablePreparedComparison(object source)
+		{
+			if (source is TransactionContext)
+			{
+				source = ((TransactionContext)source)._object;
+			}
+
+			_source = (IComparable)source;
+		}
+
+		public int CompareTo(object obj)
+		{
+			return _source.CompareTo(obj);
+		}
+
+		private readonly IComparable _source;
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/DateTimeOffsetTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/DateTimeOffsetTypeHandler.cs
new file mode 100644
index 0000000..a7364e6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/DateTimeOffsetTypeHandler.cs
@@ -0,0 +1,129 @@
+/* Copyright (C) 2009  Versant Inc.  http://www.db4o.com */
+#if !CF
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.native.Db4objects.Db4o.Typehandlers;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+	public class DateTimeOffsetTypeHandler : IValueTypeHandler, IQueryableTypeHandler, IIndexableTypeHandler
+	{
+		#region Implementation of ITypeHandler4
+
+		void ITypeHandler4.Delete(IDeleteContext context)
+		{
+			context.Seek(context.Offset() + LinkLength());
+		}
+
+		void ITypeHandler4.Defragment(IDefragmentContext context)
+		{
+			IncrementOffset(context);
+		}
+
+		void ITypeHandler4.Write(IWriteContext context, object obj)
+		{
+			Write(context, (DateTimeOffset)obj);
+		}
+
+		bool IQueryableTypeHandler.DescendsIntoMembers()
+		{
+			return false;
+		}
+
+		object IValueTypeHandler.Read(IReadContext context)
+		{
+			return ReadFrom(context);
+		}
+
+		#endregion
+
+		#region Implementation of IComparable4
+
+		IPreparedComparison IComparable4.PrepareComparison(IContext context, object obj)
+		{
+			return new ComparablePreparedComparison<DateTimeOffset>(obj);
+		}
+
+		#endregion
+
+		#region Implementation of ILinkLengthAware
+
+		int ILinkLengthAware.LinkLength()
+		{
+			return LinkLength();
+		}
+
+		#endregion
+
+		#region Implementation of IIndexable4
+
+		object IIndexable4.ReadIndexEntry(IContext context, ByteArrayBuffer reader)
+		{
+			return ReadFrom(reader);
+		}
+
+		void IIndexable4.WriteIndexEntry(IContext context, ByteArrayBuffer writer, object obj)
+		{
+			Write(writer, (DateTimeOffset) obj);
+		}
+
+		void IIndexable4.DefragIndexEntry(DefragmentContextImpl context)
+		{
+			IncrementOffset(context);
+		}
+
+		#endregion
+
+		#region Implementation of IIndexableTypeHandler
+
+		object IIndexableTypeHandler.IndexEntryToObject(IContext context, object indexEntry)
+		{
+			if (indexEntry.GetType() != typeof(DateTimeOffset))
+			{
+				throw new InvalidOperationException();
+			}
+
+			return indexEntry;
+		}
+
+		object IIndexableTypeHandler.ReadIndexEntryFromObjectSlot(MarshallerFamily mf, StatefulBuffer buffer)
+		{
+			return ReadFrom(buffer);
+		}
+
+		object IIndexableTypeHandler.ReadIndexEntry(IObjectIdContext context)
+		{
+			return ReadFrom(context);
+		}
+
+		#endregion
+		
+		private static void Write(IWriteBuffer context, DateTimeOffset dateTimeOffset)
+		{
+			context.WriteLong(dateTimeOffset.Ticks);
+			context.WriteLong(dateTimeOffset.Offset.Ticks);
+		}
+		
+		private static DateTimeOffset ReadFrom(IReadBuffer buffer)
+		{
+			long ticks = buffer.ReadLong();
+			long timeSpanTicks = buffer.ReadLong();
+			return new DateTimeOffset(ticks, new TimeSpan(timeSpanTicks));
+		}
+		
+		private static void IncrementOffset(IDefragmentContext context)
+		{
+			context.IncrementOffset(LinkLength());
+		}
+		
+		private static int LinkLength()
+		{
+			return Const4.LongLength + Const4.LongLength;
+		}
+	}
+}
+#endif
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/EnumTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/EnumTypeHandler.cs
new file mode 100644
index 0000000..9a753ca
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/EnumTypeHandler.cs
@@ -0,0 +1,201 @@
+/* Copyright (C) 2004 - 2008  Versant Inc.  http://www.db4o.com */
+
+using System;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Net;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+    public class EnumTypeHandler : IValueTypeHandler, ITypeFamilyTypeHandler, IIndexableTypeHandler
+    {
+        private class PreparedEnumComparison : IPreparedComparison
+        {
+            private readonly long _enumValue;
+            public PreparedEnumComparison(object obj)
+            {
+				if (obj is TransactionContext)
+                {
+                    obj = ((TransactionContext)obj)._object;
+                }
+
+				if (obj == null) return;
+
+            	_enumValue = ToLong(obj);
+            }
+
+        	public int CompareTo(object obj)
+            {
+                if (obj is TransactionContext)
+                {
+                    obj = ((TransactionContext)obj)._object;
+                }
+
+                if (obj == null) return 1;
+
+                long other = ToLong(obj);
+                if (_enumValue == other) return 0;
+                if (_enumValue < other) return -1;
+
+                return 1;
+            }
+
+			private static long ToLong(object obj)
+			{
+				if (obj is IndexEntry)
+				{
+					return ((IndexEntry)obj).EnumValue;
+				}
+				
+				return Convert.ToInt64(obj);
+			}
+        }
+
+        public IPreparedComparison PrepareComparison(IContext context, object obj)
+        {
+            return new PreparedEnumComparison(obj);
+        }
+
+        public void Delete(IDeleteContext context)
+        {
+            int offset = context.Offset() + Const4.IdLength + Const4.LongLength;
+            context.Seek(offset);
+        }
+
+        public void Defragment(IDefragmentContext context)
+        {
+            context.CopyID();
+            context.IncrementOffset(Const4.LongLength);
+        }
+
+        public object Read(IReadContext context)
+        {
+        	int classId = context.ReadInt();
+			long enumValue = context.ReadLong();
+			
+			return ToEnum(context, classId, enumValue);
+        }
+
+    	public void Write(IWriteContext context, object obj)
+        {
+            int classId = ClassMetadataIdFor(context, obj);
+
+            context.WriteInt(classId);
+            context.WriteLong(Convert.ToInt64(obj));
+        }
+
+    	public bool DescendsIntoMembers()
+    	{
+    		return false;
+    	}
+
+    	public int LinkLength()
+        {
+            return Const4.IdLength + Const4.LongLength;
+        }
+
+    	public object ReadIndexEntry(IContext context, ByteArrayBuffer reader)
+    	{
+    		return new IndexEntry(reader.ReadInt(), reader.ReadLong());
+		}
+
+		public void WriteIndexEntry(IContext context, ByteArrayBuffer writer, object obj)
+    	{
+			IndexEntry indexEntry = obj as IndexEntry;
+			if (indexEntry == null)
+			{
+				indexEntry = new IndexEntry(ClassMetadataIdFor(context, obj), Convert.ToInt64(obj));
+			}
+			writer.WriteInt(indexEntry.ClassMetadataId);
+			writer.WriteLong(indexEntry.EnumValue);
+		}
+
+    	public void DefragIndexEntry(DefragmentContextImpl context)
+    	{
+    		context.IncrementOffset(Const4.LongLength);
+    	}
+
+    	private static int ClassMetadataIdFor(IContext context, object obj)
+        {
+            IReflectClass claxx = Container(context).Reflector().ForObject(obj);
+            ClassMetadata clazz = Container(context).ProduceClassMetadata(claxx);
+
+            //TODO: Handle clazz == null!! Must not happen!
+
+            return clazz.GetID();
+        }
+
+        private static ITypeHandler4 StringTypeHandler(IContext context)
+        {
+            return Container(context).Handlers.TypeHandlerForClass(Container(context).Ext().Reflector().ForClass(typeof(string)));
+        }
+
+        private static ObjectContainerBase Container(IContext context)
+        {
+            return ((IInternalObjectContainer)context.ObjectContainer()).Container;
+        }
+
+    	public object IndexEntryToObject(IContext context, object indexEntry)
+    	{
+    		IndexEntry entry = (IndexEntry) indexEntry;
+    		return ToEnum(context, entry.ClassMetadataId, entry.EnumValue);
+    	}
+
+    	public object ReadIndexEntryFromObjectSlot(MarshallerFamily mf, StatefulBuffer statefulBuffer)
+    	{
+    		return new IndexEntry(statefulBuffer.ReadInt(), statefulBuffer.ReadLong());
+    	}
+
+    	public object ReadIndexEntry(IObjectIdContext context)
+    	{
+    		return new IndexEntry(context.ReadInt(), context.ReadLong());
+    	}
+
+		private static object ToEnum(IContext context, int classId, long enumValue)
+		{
+			ClassMetadata clazz = Container(context).ClassMetadataForID(classId);
+
+			Type enumType = NetReflector.ToNative(clazz.ClassReflector());
+			return Enum.ToObject(enumType, enumValue);
+		}
+
+		private class IndexEntry
+		{
+			private readonly long _enumValue;
+			private readonly int _classMetadataId;
+
+			internal IndexEntry(int classMetadataId, long enumValue)
+			{
+				_classMetadataId = classMetadataId;
+				_enumValue = enumValue;
+			}
+
+			internal long EnumValue
+			{
+				get { return _enumValue; }
+			}
+
+			internal int ClassMetadataId
+			{
+				get { return _classMetadataId; }
+			}
+		}
+    }
+
+    public class EnumTypeHandlerPredicate : ITypeHandlerPredicate
+    {
+        public bool Match(IReflectClass classReflector)
+        {
+            Type type = NetReflector.ToNative(classReflector);
+            if(type == null)
+            {
+                return false;
+            }
+            return type.IsEnum;
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/GenericCollectionTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/GenericCollectionTypeHandler.cs
new file mode 100644
index 0000000..872ced0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/GenericCollectionTypeHandler.cs
@@ -0,0 +1,218 @@
+/* Copyright (C) 2004 - 2008  Versant Inc.  http://www.db4o.com */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using Db4objects.Db4o.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Foundation.Collections;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+	public class GenericCollectionTypeHandler : IReferenceTypeHandler, ICascadingTypeHandler, IVariableLengthTypeHandler, IQueryableTypeHandler
+	{
+		public virtual IPreparedComparison PrepareComparison(IContext context, object obj)
+		{
+			return null;
+		}
+
+		public virtual void Write(IWriteContext context, object obj)
+		{
+            ICollectionInitializer initializer = CollectionInitializer.For(obj);
+            IEnumerable enumerable = (IEnumerable)obj;
+			ClassMetadata elementType = DetectElementTypeErasingNullables(Container(context), enumerable);
+			WriteElementTypeHandlerId(context, elementType);
+			WriteElementCount(context, initializer);
+			WriteElements(context, enumerable, elementType.TypeHandler());
+		}
+
+		public virtual void Activate(IReferenceActivationContext context)
+		{
+			object collection = context.PersistentObject();
+			ICollectionInitializer initializer = CollectionInitializer.For(collection);
+			initializer.Clear();
+
+			ReadElements(context, initializer, ReadElementTypeHandler(context, context));
+
+			initializer.FinishAdding();
+		}
+
+		public virtual void Delete(IDeleteContext context)
+		{
+			if (!context.CascadeDelete()) return;
+
+			ITypeHandler4 handler = ReadElementTypeHandler(context, context);
+			int elementCount = context.ReadInt();
+			for (int i = elementCount; i > 0; i--)
+			{
+				handler.Delete(context);
+			}
+		}
+
+		public virtual void Defragment(IDefragmentContext context)
+		{
+			DefragmentElementHandlerId(context);
+			ITypeHandler4 handler = ReadElementTypeHandler(context, context);
+			int elementCount = context.ReadInt();
+			for (int i = 0; i < elementCount; i++)
+			{
+				context.Defragment(handler);
+			}
+		}
+
+		public void CascadeActivation(IActivationContext context)
+		{
+            IEnumerable collection = ((IEnumerable)context.TargetObject());
+
+			// TODO: detect the element type
+			// and return immediately when it's a primitive
+
+			foreach (object item in collection)
+			{
+				context.CascadeActivationToChild(item);
+			}
+		}
+
+		public virtual ITypeHandler4 ReadCandidateHandler(QueryingReadContext context)
+		{
+			return this;
+		}
+
+		public virtual void CollectIDs(QueryingReadContext context)
+		{
+			ITypeHandler4 elementHandler = ReadElementTypeHandler(context, context);
+			int elementCount = context.ReadInt();
+			for (int i = 0; i < elementCount; i++)
+			{
+				context.ReadId(elementHandler);
+			}
+		}
+
+		private static void DefragmentElementHandlerId(IDefragmentContext context)
+		{
+			int offset = context.Offset();
+			context.CopyID();
+			context.Seek(offset);
+		}
+
+		private static ITypeHandler4 OpenTypeHandlerFrom(IContext context)
+		{
+			return context.Transaction().Container().Handlers.OpenTypeHandler();
+		}
+
+		private static void ReadElements(IReadContext context, ICollectionInitializer initializer, ITypeHandler4 elementHandler)
+		{
+			int elementCount = context.ReadInt();
+			for (int i = 0; i < elementCount; i++)
+			{
+				initializer.Add(context.ReadObject(elementHandler));
+			}
+		}
+
+		private static void WriteElementTypeHandlerId(IWriteContext context, ClassMetadata type)
+		{
+			context.WriteInt(type.GetID());
+		}
+
+        private static void WriteElementCount(IWriteBuffer context, ICollectionInitializer initializer)
+		{
+            context.WriteInt(initializer.Count());
+		}
+
+		private static void WriteElements(IWriteContext context, IEnumerable enumerable, ITypeHandler4 elementHandler)
+		{
+			IEnumerator elements = enumerable.GetEnumerator();
+			while (elements.MoveNext())
+			{
+				context.WriteObject(elementHandler, elements.Current);
+			}
+		}
+
+		private static ObjectContainerBase Container(IContext context)
+		{
+			return ((IInternalObjectContainer)context.ObjectContainer()).Container;
+		}
+
+		private static ITypeHandler4 ReadElementTypeHandler(IReadBuffer buffer, IContext context)
+		{
+			int elementTypeId = buffer.ReadInt();
+			if (elementTypeId == 0) return OpenTypeHandlerFrom(context);
+
+			ITypeHandler4 elementHandler = Container(context).TypeHandlerForClassMetadataID(elementTypeId);
+			return elementHandler ?? OpenTypeHandlerFrom(context);
+		}
+
+		private static ClassMetadata DetectElementTypeErasingNullables(ObjectContainerBase container, IEnumerable collection)
+		{
+			Type elementType = ElementTypeOf(collection);
+			if (IsNullableInstance(elementType))
+			{
+				return container.ClassMetadataForReflectClass(container.Handlers.IclassObject);
+			}
+			return container.ProduceClassMetadata(container.Reflector().ForClass(elementType));
+		}
+
+		private static bool IsNullableInstance(Type elementType)
+		{
+			return elementType.IsGenericType && (elementType.GetGenericTypeDefinition() == typeof(Nullable<>));
+		}
+
+		private static Type ElementTypeOf(IEnumerable collection)
+		{
+			Type genericCollectionType = GenericCollectionTypeFor(collection.GetType());
+			return genericCollectionType.GetGenericArguments()[0];
+		}
+
+		private static Type GenericCollectionTypeFor(Type type)
+		{
+            if (type == null)
+            {
+                throw new InvalidOperationException();
+            }
+
+            if (IsGenericCollectionType(type))
+			{
+				return type;
+			}
+
+			return GenericCollectionTypeFor(type.BaseType);
+		}
+
+		private static bool IsGenericCollectionType(Type type)
+		{
+			return type.IsGenericType && Array.IndexOf(_supportedCollections, type.GetGenericTypeDefinition()) >= 0;
+		}
+
+		public bool DescendsIntoMembers()
+		{
+			return true;
+		}
+
+		public void RegisterSupportedTypesWith(Action<Type> registrationAction)
+		{
+			foreach (Type collectionType in _supportedCollections)
+			{
+				registrationAction(collectionType);
+			}
+		}
+
+		private static readonly Type[] _supportedCollections = new Type[]
+												{
+													typeof(List<>),
+													typeof(LinkedList<>),
+													typeof(Stack<>),
+													typeof(Queue<>),
+													typeof(System.Collections.ObjectModel.Collection<>),
+													typeof(ActivatableList<>),
+#if NET_3_5 && ! CF
+													typeof(HashSet<>),
+#endif
+												};
+	}
+
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/GuidTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/GuidTypeHandler.cs
new file mode 100644
index 0000000..acb50d4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/GuidTypeHandler.cs
@@ -0,0 +1,137 @@
+/* Copyright (C) 2009 Versant Inc.  http://www.db4o.com */
+
+/* Copyright (C) 2009 Judah Himango */
+
+using System;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.native.Db4objects.Db4o.Typehandlers;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Reflect.Net;
+
+namespace Db4objects.Db4o.Typehandlers
+{
+    /// <summary>
+    /// DB4O type handler for efficiently storing and activating System.Guid values.
+    /// </summary>
+    /// <author>Judah Himango</author>
+    public class GuidTypeHandler: IValueTypeHandler, IQueryableTypeHandler, IIndexableTypeHandler
+	{
+		private const int GuidSize = 16;
+		
+        #region IValueTypeHandler Members
+
+        public object Read(IReadContext context)
+        {
+        	return ReadFrom(context);
+        }
+
+        #endregion
+
+        #region ITypeHandler4 Members
+
+        public bool CanHold(IReflectClass type)
+        {
+        	return NetReflector.ToNative(type).Equals(typeof (Guid));
+        }
+
+    	public void Defragment(IDefragmentContext context)
+        {
+            IncrementOffset(context);
+        }
+
+        public void Delete(IDeleteContext context)
+        {
+			context.Seek(context.Offset() + GuidSize);
+        }
+
+        public void Write(IWriteContext context, object obj)
+        {
+        	WriteGuid(obj, context);
+        }
+
+    	#endregion
+
+        #region IComparable4 Members
+
+        public IPreparedComparison PrepareComparison(IContext context, object obj)
+        {
+            return new ComparablePreparedComparison<Guid>(obj);
+        }
+
+        #endregion
+
+		#region IQueryableTypeHandler Members
+
+		public bool DescendsIntoMembers()
+		{
+			return false;
+		}
+
+		#endregion
+
+		#region IIndexableTypeHandler Members 
+
+		public int LinkLength()
+    	{
+    		return GuidSize;
+    	}
+
+    	public object ReadIndexEntry(IContext context, ByteArrayBuffer reader)
+    	{
+    		return ReadFrom(reader);
+    	}
+
+    	public void WriteIndexEntry(IContext context, ByteArrayBuffer writer, object obj)
+    	{
+			WriteGuid(obj, writer);
+    	}
+
+    	public void DefragIndexEntry(DefragmentContextImpl context)
+    	{
+    		IncrementOffset(context);
+    	}
+
+    	public object IndexEntryToObject(IContext context, object indexEntry)
+    	{
+    		if (indexEntry.GetType() != typeof(Guid))
+    		{
+    			throw new InvalidOperationException();	
+    		}
+			return indexEntry;
+    	}
+
+    	public object ReadIndexEntryFromObjectSlot(MarshallerFamily mf, StatefulBuffer buffer)
+    	{
+    		return ReadFrom(buffer);
+    	}
+
+    	public object ReadIndexEntry(IObjectIdContext context)
+    	{
+    		return ReadFrom(context);
+		}
+
+		#endregion
+
+		private static Guid ReadFrom(IReadBuffer buffer)
+		{
+			byte[] guidBytes = new byte[GuidSize];
+			buffer.ReadBytes(guidBytes);
+			return new Guid(guidBytes);
+		}
+
+		private static void WriteGuid(object obj, IWriteBuffer context)
+		{
+			Guid id = (Guid)obj;
+			context.WriteBytes(id.ToByteArray());
+		}
+
+		private static void IncrementOffset(IDefragmentContext context)
+		{
+			context.IncrementOffset(GuidSize);
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/SystemArrayTypeHandler.cs b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/SystemArrayTypeHandler.cs
new file mode 100644
index 0000000..1e620e0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Db4objects.Db4o/Typehandlers/SystemArrayTypeHandler.cs
@@ -0,0 +1,137 @@
+/* Copyright (C) 2009   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Collections;
+using Db4objects.Db4o.Foundation;
+using Db4objects.Db4o.Internal;
+using Db4objects.Db4o.Internal.Activation;
+using Db4objects.Db4o.Internal.Delete;
+using Db4objects.Db4o.Internal.Handlers;
+using Db4objects.Db4o.Internal.Marshall;
+using Db4objects.Db4o.Marshall;
+using Db4objects.Db4o.Reflect;
+using Db4objects.Db4o.Reflect.Net;
+using Db4objects.Db4o.Internal.Handlers.Array;
+
+
+namespace Db4objects.Db4o.Typehandlers
+{
+    public class SystemArrayTypeHandler : ICascadingTypeHandler, IVariableLengthTypeHandler, IValueTypeHandler
+    {
+        public virtual IPreparedComparison PrepareComparison(IContext context, object obj)
+        {
+            return ReadArrayHandler(context).PrepareComparison(context, obj);
+        }
+
+        public virtual void Write(IWriteContext context, object obj)
+        {
+            Array collection = (Array) obj;
+            ClassMetadata elementType = DetectElementTypeHandler(Container(context), collection);
+            WriteElementTypeId(context, elementType);
+            new ArrayHandler(elementType.TypeHandler(), false).Write(context, obj);
+        }
+
+    	public virtual object Read(IReadContext context)
+        {
+            return ReadArrayHandler(context).Read(context);
+        }
+
+        private static ArrayHandler ReadArrayHandler(IContext context)
+        {
+            ITypeHandler4 handler = ReadElementTypeHandler((IReadBuffer)context, context);
+            return new ArrayHandler(handler, false);
+        }
+
+        public virtual void Delete(IDeleteContext context)
+        {
+            ReadArrayHandler(context).Delete(context);
+        }
+
+        public virtual void Defragment(IDefragmentContext context)
+        {
+            DefragmentElementHandlerId(context);
+            ReadArrayHandler(context).Defragment(context);
+        }
+
+        public void CascadeActivation(IActivationContext context)
+        {
+            ICollection collection = ((ICollection)context.TargetObject());
+            foreach (object item in collection)
+            {
+                context.CascadeActivationToChild(item);
+            }
+        }
+
+        public virtual ITypeHandler4 ReadCandidateHandler(QueryingReadContext context)
+        {
+            return this;
+        }
+
+        public virtual void CollectIDs(QueryingReadContext context)
+        {
+            ReadArrayHandler(context).CollectIDs(context);
+        }
+
+        private static void DefragmentElementHandlerId(IDefragmentContext context)
+        {
+            int offset = context.Offset();
+            context.CopyID();
+            context.Seek(offset);
+        }
+
+        private static ITypeHandler4 OpenTypeHandlerFrom(IContext context)
+        {
+            return context.Transaction().Container().Handlers.OpenTypeHandler();
+        }
+
+        private static void WriteElementTypeId(IWriteContext context, ClassMetadata elementType)
+        {
+            context.WriteInt(elementType.GetID());
+        }
+
+        private static ObjectContainerBase Container(IContext context)
+        {
+            return ((IInternalObjectContainer)context.ObjectContainer()).Container;
+        }
+
+        private static ITypeHandler4 ReadElementTypeHandler(IReadBuffer buffer, IContext context)
+        {
+            int elementHandlerId = buffer.ReadInt();
+            if (elementHandlerId == 0) return OpenTypeHandlerFrom(context);
+
+            ITypeHandler4 elementHandler = Container(context).TypeHandlerForClassMetadataID(elementHandlerId);
+            return elementHandler ?? OpenTypeHandlerFrom(context);
+        }
+
+        private static ClassMetadata DetectElementTypeHandler(ObjectContainerBase container, Array collection)
+        {
+            Type elementType = ElementTypeOf(collection);
+        	return container.ProduceClassMetadata(container.Reflector().ForClass(elementType));
+        }
+
+        private static bool IsNullableInstance(Type elementType)
+        {
+            return elementType.IsGenericType && (elementType.GetGenericTypeDefinition() == typeof(Nullable<>));
+        }
+
+        private static Type ElementTypeOf(Array array)
+        {
+            return array.GetType().GetElementType();
+        }
+
+    }
+
+    internal class SystemArrayPredicate : ITypeHandlerPredicate
+    {
+        public bool Match(IReflectClass classReflector)
+        {
+            if(classReflector == null)
+            {
+                return false;
+            }
+            Type type = NetReflector.ToNative(classReflector);
+            return type == typeof(System.Array);
+        }
+    }
+
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Collections.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Collections.cs
new file mode 100644
index 0000000..a797dc1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Collections.cs
@@ -0,0 +1,52 @@
+
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Sharpen
+{
+	public class Collections
+	{
+        public static void AddAll(System.Collections.IList list, System.Collections.IEnumerable added)
+        {
+            foreach (object o in added)
+            {
+                list.Add(o);
+            }
+        }
+
+        public static bool AddAll<T>(ICollection<T> list, System.Collections.Generic.IEnumerable<T> added)
+        {
+            foreach (T o in added)
+            {
+                list.Add(o);
+            }
+            return true;
+        }
+
+		public static object Remove(IDictionary dictionary, object key)
+		{
+			object removed = dictionary[key];
+			dictionary.Remove(key);
+			return removed;
+		}
+
+	    public static object[] ToArray(ICollection collection)
+	    {
+	    	object[] result = new object[collection.Count];
+			collection.CopyTo(result, 0);
+			return result;
+	    }
+
+		public static T[] ToArray<T>(ICollection collection, T[] result)
+		{
+			collection.CopyTo(result, 0);
+			return result;
+		}
+
+		public static T[] ToArray<T>(ICollection<T> collection, T[] result)
+		{
+			collection.CopyTo(result, 0);
+			return result;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/BufferedInputStream.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/BufferedInputStream.cs
new file mode 100644
index 0000000..4f27f88
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/BufferedInputStream.cs
@@ -0,0 +1,41 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+
+namespace Sharpen.IO
+{
+	public class BufferedInputStream : IInputStream
+	{
+		private IInputStream _stream;
+
+		public BufferedInputStream(IInputStream stream)
+		{
+			_stream = stream;
+		}
+
+		public BufferedInputStream(IInputStream stream, int bufferSize)
+		{
+			_stream = stream;
+		}
+
+		public int Read()
+		{
+			return _stream.Read();
+		}
+
+		public int Read(byte[] bytes)
+		{
+			return _stream.Read(bytes);
+		}
+
+		public int Read(byte[] bytes, int offset, int length)
+		{
+			return _stream.Read(bytes, offset, length);
+		}
+
+		public void Close()
+		{
+			_stream.Close();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/BufferedOutputStream.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/BufferedOutputStream.cs
new file mode 100644
index 0000000..b23eff7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/BufferedOutputStream.cs
@@ -0,0 +1,46 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+
+namespace Sharpen.IO
+{
+	public class BufferedOutputStream : IOutputStream
+	{
+		private IOutputStream _stream;
+
+		public BufferedOutputStream(IOutputStream stream)
+		{
+			_stream = stream;
+		}
+
+		public BufferedOutputStream(IOutputStream stream, int bufferSize)
+		{
+			_stream = stream;
+		}
+
+		public void Write(int i)
+		{
+			_stream.Write(i);
+		}
+
+		public void Write(byte[] bytes)
+		{
+			_stream.Write(bytes);
+		}
+
+		public void Write(byte[] bytes, int offset, int length)
+		{
+			_stream.Write(bytes, offset, length);
+		}
+
+		public void Flush()
+		{
+			_stream.Flush();
+		}
+
+		public void Close()
+		{
+			_stream.Close();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/ByteArrayInputStream.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/ByteArrayInputStream.cs
new file mode 100644
index 0000000..35bddd8
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/ByteArrayInputStream.cs
@@ -0,0 +1,14 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.IO;
+
+namespace Sharpen.IO
+{
+	public class ByteArrayInputStream : InputStream
+	{
+		public ByteArrayInputStream(byte[] initial) : base(new MemoryStream(initial))
+		{
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/ByteArrayOutputStream.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/ByteArrayOutputStream.cs
new file mode 100644
index 0000000..1ccb5df
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/ByteArrayOutputStream.cs
@@ -0,0 +1,38 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.IO;
+
+namespace Sharpen.IO
+{
+	public class ByteArrayOutputStream : OutputStream
+	{
+		public ByteArrayOutputStream() : base(new MemoryStream())
+		{
+		}
+
+		public ByteArrayOutputStream(int size) : base(new MemoryStream(size))
+		{
+		}
+
+		public int Size()
+		{
+			return (int)Stream.Length;
+		}
+
+		public void WriteTo(OutputStream stream)
+		{
+			Stream.WriteTo(stream.UnderlyingStream);
+		}
+
+		public byte[] ToByteArray()
+		{
+			return Stream.ToArray();
+		}
+
+		private MemoryStream Stream
+		{
+			get { return (MemoryStream)UnderlyingStream; }
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/File.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/File.cs
new file mode 100644
index 0000000..065411c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/File.cs
@@ -0,0 +1,170 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Db4objects.Db4o.IO;
+
+namespace Sharpen.IO
+{
+	public class File
+	{
+		public static readonly char separatorChar = Path.DirectorySeparatorChar;
+		public static readonly string separator = separatorChar.ToString();
+		
+		private readonly string _path;
+
+		public File(string path)
+		{
+			_path = path;
+		}
+
+		public static implicit operator string(File file)
+		{
+			return file.GetAbsolutePath();
+		}
+
+		public File(string dir, string file)
+		{
+			_path = dir == null ? file : Path.Combine(dir, file);
+		}
+
+		public virtual bool Delete()
+		{
+#if SILVERLIGHT
+			return SilverlightIO.Delete(_path);
+#else
+			if (Exists())
+			{
+				System.IO.File.Delete(_path);
+				return !Exists();
+			}
+			return false;
+#endif
+		}
+
+		public bool Exists()
+		{
+#if CF
+            string path = RemoveTrailingSlash(_path);
+#elif SILVERLIGHT
+			string path = _path;
+			return SilverlightIO.Exists(path);
+#else
+            string path = _path;
+#endif
+            return System.IO.File.Exists(path) || Directory.Exists(path);
+		}
+
+	    private static string RemoveTrailingSlash(string path)
+	    {
+	        return (path.EndsWith("\\") || path.EndsWith("/")) ? path.Remove(path.Length - 1, 1) : path;
+	    }
+
+	    public string GetCanonicalPath()
+		{
+			return Path.GetFullPath(_path);
+		}
+
+		public File GetCanonicalFile()
+		{
+			return new File(GetCanonicalPath());
+		}
+
+		public string GetAbsolutePath()
+		{
+#if SILVERLIGHT
+			return _path;
+#else
+			return Path.GetFullPath(_path);
+#endif
+		}
+
+		public string GetName()
+		{
+			int index = _path.LastIndexOf(separator);
+			return _path.Substring(index + 1);
+		}
+
+		public string GetPath()
+		{
+			return _path;
+		}
+
+		public bool IsDirectory()
+		{
+#if CF || SILVERLIGHT
+			return Exists();
+#else
+			return (System.IO.File.GetAttributes(_path) & FileAttributes.Directory) != 0;
+#endif
+		}
+
+		public long Length()
+		{
+#if SILVERLIGHT
+			return SilverlightIO.Length(_path);
+#else
+			return new FileInfo(_path).Length;
+#endif
+		}
+
+		public string[] List()
+		{
+#if SILVERLIGHT
+            throw new NotImplementedException();
+#else
+			return Directory.GetFiles(_path);
+#endif
+        }
+
+		public bool Mkdir()
+		{
+			if (Exists())
+			{
+				return false;
+			}
+			Directory.CreateDirectory(_path);
+			return Exists();
+		}
+
+		public bool Mkdirs()
+		{
+			if (Exists())
+			{
+				return false;
+			}
+			int pos = _path.LastIndexOf(separator);
+			if (pos > 0)
+			{
+				new File(_path.Substring(0, pos)).Mkdirs();
+			}
+			return Mkdir();
+		}
+
+		public void RenameTo(File file)
+		{
+			new FileInfo(_path).MoveTo(file.GetPath());
+		}
+
+        public File[] ListFiles(IFilenameFilter filter)
+        {
+            String[] ss = List();
+            if (ss == null) return null;
+            List<File> v = new List<File>();
+            for (int i = 0; i < ss.Length; i++)
+            {
+                if ((filter == null) || filter.Accept(this, ss[i]))
+                {
+                    v.Add(new File(ss[i], this));
+                }
+            }
+            return v.ToArray();
+        }
+
+		public override string ToString()
+		{
+			return _path;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/FileInputStream.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/FileInputStream.cs
new file mode 100644
index 0000000..1ff2003
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/FileInputStream.cs
@@ -0,0 +1,14 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.IO;
+
+namespace Sharpen.IO {
+
+    public class FileInputStream : InputStream {
+
+        public FileInputStream(File file) : base(new FileStream(file.GetPath(), FileMode.Open, FileAccess.Read)) {
+        }
+
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/FileOutputStream.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/FileOutputStream.cs
new file mode 100644
index 0000000..188958a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/FileOutputStream.cs
@@ -0,0 +1,14 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.IO;
+
+namespace Sharpen.IO {
+
+    public class FileOutputStream : OutputStream {
+
+        public FileOutputStream(File file) : base(new FileStream(file.GetPath(), FileMode.Create, FileAccess.Write)) {
+        }
+
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/IFilenameFilter.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/IFilenameFilter.cs
new file mode 100644
index 0000000..2923925
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/IFilenameFilter.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace Sharpen.IO
+{
+    public interface IFilenameFilter
+    {
+        bool Accept(Sharpen.IO.File dir, String name);
+    }
+}
+
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/IInputStream.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/IInputStream.cs
new file mode 100644
index 0000000..a33b246
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/IInputStream.cs
@@ -0,0 +1,13 @@
+namespace Sharpen.IO
+{
+	public interface IInputStream
+	{
+		int Read();
+
+		int Read(byte[] bytes);
+
+		int Read(byte[] bytes, int offset, int length);
+
+		void Close();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/IOutputStream.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/IOutputStream.cs
new file mode 100644
index 0000000..ded9273
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/IOutputStream.cs
@@ -0,0 +1,15 @@
+namespace Sharpen.IO
+{
+	public interface IOutputStream
+	{
+		void Write(int i);
+
+		void Write(byte[] bytes);
+
+		void Write(byte[] bytes, int offset, int length);
+
+		void Flush();
+
+		void Close();
+	}
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/InputStream.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/InputStream.cs
new file mode 100644
index 0000000..66cbd5e
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/InputStream.cs
@@ -0,0 +1,34 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System.IO;
+
+namespace Sharpen.IO
+{
+	public class InputStream : StreamAdaptor, IInputStream
+	{
+		public InputStream(Stream stream)
+			: base(stream)
+		{
+		}
+
+		public int Read()
+		{
+			return _stream.ReadByte();
+		}
+
+		public int Read(byte[] bytes)
+		{
+			return Read(bytes, 0, bytes.Length);
+		}
+
+		public int Read(byte[] bytes, int offset, int length)
+		{
+			return TranslateReadReturnValue(_stream.Read(bytes, offset, length));
+		}
+
+		internal static int TranslateReadReturnValue(int read)
+		{
+			return (0 == read) ? -1 : read;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/OutputStream.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/OutputStream.cs
new file mode 100644
index 0000000..c067e5d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/OutputStream.cs
@@ -0,0 +1,34 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System.IO;
+
+namespace Sharpen.IO
+{
+	public class OutputStream : StreamAdaptor, IOutputStream
+	{
+		public OutputStream(Stream stream)
+			: base(stream)
+		{
+		}
+
+		public void Write(int i)
+		{
+			_stream.WriteByte((byte)i);
+		}
+
+		public void Write(byte[] bytes)
+		{
+			_stream.Write(bytes, 0, bytes.Length);
+		}
+
+		public void Write(byte[] bytes, int offset, int length)
+		{
+			_stream.Write(bytes, offset, length);
+		}
+
+		public void Flush()
+		{
+			_stream.Flush();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/RandomAccessFile.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/RandomAccessFile.cs
new file mode 100644
index 0000000..9991aad
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/RandomAccessFile.cs
@@ -0,0 +1,97 @@
+/* Copyright (C) 2004 - 2007  Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace Sharpen.IO
+{
+    public class RandomAccessFile
+    {
+        private readonly FileStream _stream;
+
+#if !CF && !MONO && !SILVERLIGHT
+#if NET_4_0
+        [System.Security.SecuritySafeCritical]
+#endif
+		[DllImport("kernel32.dll", SetLastError = true)]
+        static extern int FlushFileBuffers(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle);
+#endif
+        public RandomAccessFile(String file, bool readOnly, bool lockFile)
+        {
+            _stream = new FileStream(file, FileMode.OpenOrCreate,
+                readOnly ? FileAccess.Read : FileAccess.ReadWrite,
+                lockFile ? FileShare.None : FileShare.ReadWrite
+            );
+        }
+
+        public RandomAccessFile(String file, String fileMode)
+            : this(file, fileMode.Equals("r"), true)
+        {
+        }
+
+        public FileStream Stream
+        {
+            get { return _stream; }
+        }
+
+        public void Close()
+        {
+            _stream.Close();
+        }
+
+        public long Length()
+        {
+            return _stream.Length;
+        }
+
+        public int Read(byte[] bytes, int offset, int length)
+        {
+            return _stream.Read(bytes, offset, length);
+        }
+
+        public void Read(byte[] bytes)
+        {
+            _stream.Read(bytes, 0, bytes.Length);
+        }
+
+        public void Seek(long pos)
+        {
+            _stream.Seek(pos, SeekOrigin.Begin);
+        }
+
+#if NET_4_0
+        [System.Security.SecuritySafeCritical]
+#endif
+		public void Sync()
+        {
+            _stream.Flush();
+
+#if !CF && !MONO && !SILVERLIGHT
+            FlushFileBuffers(_stream.SafeFileHandle);
+#endif
+        }
+
+        public RandomAccessFile GetFD()
+        {
+            return this;
+        }
+
+        public void Write(byte[] bytes)
+        {
+            Write(bytes, 0, bytes.Length);
+        }
+
+        public void Write(byte[] bytes, int offset, int length)
+        {
+            try
+            {
+                _stream.Write(bytes, offset, length);
+            }
+            catch (NotSupportedException e)
+            {
+                throw new IOException("Not supported", e);
+            }
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/StreamAdaptor.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/StreamAdaptor.cs
new file mode 100644
index 0000000..cebb9e2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/IO/StreamAdaptor.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System.IO;
+
+namespace Sharpen.IO 
+{
+	public abstract class StreamAdaptor 
+	{
+		protected readonly Stream _stream;
+
+		public StreamAdaptor(Stream stream) 
+		{
+			_stream = stream;
+		}
+
+		public Stream UnderlyingStream 
+		{
+			get { return _stream; }
+		}
+
+		public void Close() 
+		{
+			_stream.Close();
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/IdentityHashCodeProvider.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/IdentityHashCodeProvider.cs
new file mode 100644
index 0000000..3563bee
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/IdentityHashCodeProvider.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2005   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Reflection;
+
+namespace Sharpen.Lang
+{
+	public class IdentityHashCodeProvider
+	{
+#if !CF
+		public static int IdentityHashCode(object obj)
+		{
+			return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(obj);
+		}
+#else
+		public static int IdentityHashCode(object obj)
+		{
+			if (obj == null) return 0;
+			return (int) _hashMethod.Invoke(null, new object[] { obj });
+		}
+
+		private static MethodInfo _hashMethod = GetIdentityHashCodeMethod();
+
+		private static MethodInfo GetIdentityHashCodeMethod()
+		{
+			Assembly assembly = typeof(object).Assembly;
+			try
+			{
+				Type t = assembly.GetType("System.PInvoke.EE");
+				return t.GetMethod(
+					"Object_GetHashCode",
+					BindingFlags.Public |
+					BindingFlags.NonPublic |
+					BindingFlags.Static);
+			}
+			catch (Exception e)
+			{
+			}
+			// We may be running the CF app on .NET Framework 1.1
+			// for profiling, let's give that a chance
+			try
+			{
+				Type t = assembly.GetType(
+					"System.Runtime.CompilerServices.RuntimeHelpers");
+				return t.GetMethod(
+					"GetHashCode",
+					BindingFlags.Public |
+					BindingFlags.Static);
+			}
+			catch
+			{
+			}
+			return null;
+		}
+#endif
+	}
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/Reflect.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/Reflect.cs
new file mode 100755
index 0000000..e923d0f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/Reflect.cs
@@ -0,0 +1,10 @@
+namespace Sharpen.Lang.Reflect
+{
+	// this namespace just exists because of a bug
+	// in sharpen that makes it fail to realize that
+	// a mapped namespace is not being used
+	class __fixme__
+	{
+		
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/Runnable.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/Runnable.cs
new file mode 100644
index 0000000..5779cdb
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/Runnable.cs
@@ -0,0 +1,8 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+namespace Sharpen.Lang
+{
+	public interface IRunnable
+	{
+		void Run();
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/SimpleTypeReference.Silverlight.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/SimpleTypeReference.Silverlight.cs
new file mode 100644
index 0000000..c32b166
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/SimpleTypeReference.Silverlight.cs
@@ -0,0 +1,94 @@
+/* Copyright (C) 2009   Versant Inc.   http://www.db4o.com */
+
+#if SILVERLIGHT
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Threading;
+using System.Windows;
+using System.Windows.Resources;
+
+#endif
+
+namespace Sharpen.Lang
+{
+	public partial class SimpleTypeReference
+	{
+#if SILVERLIGHT
+		private Assembly ResolveAssemblySilverlight()
+		{
+			if (!_assemblyCache.Contains(_assemblyName.Name))
+			{
+				Assembly assembly = IsInUIThread() 
+				                    	? LoadAssembly(_assemblyName.Name) 
+				                    	: LoadAssemblyInUIThread(_assemblyName.Name);
+				
+				_assemblyCache[_assemblyName.Name] = assembly;
+				return assembly;
+			}
+
+			return _assemblyCache[_assemblyName.Name];
+		}
+
+		private static bool IsInUIThread()
+		{
+			return Deployment.Current.CheckAccess();
+		}
+
+		private static Assembly LoadAssemblyInUIThread(string assemblyName)
+		{
+			Assembly assembly = null;
+			using (EventWaitHandle wait = new ManualResetEvent(false))
+			{
+				Deployment.Current.Dispatcher.BeginInvoke(delegate
+				                                          	{
+				                                          		assembly = LoadAssembly(assemblyName);
+				                                          		wait.Set();
+				                                          	});
+
+				wait.WaitOne();
+			}
+			return assembly;
+		}
+
+		private static Assembly LoadAssembly(string assemblyName)
+		{
+			StreamResourceInfo resourceInfo = Application.GetResourceStream(AssemblyUriFor(assemblyName));
+			return new AssemblyPart().Load(resourceInfo.Stream);
+		}
+
+		private static Uri AssemblyUriFor(string assemblyName)
+		{
+			return new Uri(assemblyName + ".dll", UriKind.Relative);
+		}
+
+		private static readonly AssemblyCache _assemblyCache = new AssemblyCache(typeof(Type).Assembly);
+
+	}
+
+	sealed class AssemblyCache
+	{
+		public AssemblyCache(params Assembly[] preCachedAssemblies)
+		{
+			foreach (var assembly in preCachedAssemblies)
+			{
+				_cache[new AssemblyName(assembly.FullName).Name] = assembly;
+			}
+		}
+
+		public Assembly this[string assemblyName]
+		{
+			get { return _cache[assemblyName]; }
+			set { _cache[assemblyName] = value; }
+		}
+
+		public bool Contains(string assemblyName)
+		{
+			return _cache.ContainsKey(assemblyName);
+		}
+		
+		private IDictionary<string, Assembly> _cache = new Dictionary<string, Assembly>();
+#endif
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/Thread.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/Thread.cs
new file mode 100644
index 0000000..11c933a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/Thread.cs
@@ -0,0 +1,147 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Threading;
+
+namespace Sharpen.Lang
+{
+	public class Thread : IRunnable
+	{
+		private IRunnable _target;
+
+		private string _name;
+
+		private System.Threading.Thread _thread;
+
+		private bool _isDaemon;
+
+		public Thread()
+		{
+			_target = this;
+		}
+
+		public Thread(IRunnable target, string name)
+		{
+			_target = target;
+			SetName(name);
+		}
+
+		public Thread(IRunnable target)
+		{
+			_target = target;
+		}
+
+		public Thread(System.Threading.Thread thread)
+		{
+			_thread = thread;
+		}
+
+		public static Thread CurrentThread()
+		{
+			return new Thread(System.Threading.Thread.CurrentThread);
+		}
+
+		public virtual void Run()
+		{
+		}
+
+		public void SetName(string name)
+		{
+			_name = name;
+#if !CF
+			if (_thread != null && name != null)
+			{
+				try
+				{
+					_thread.Name = _name;
+				}
+				catch
+				{
+				}
+			}
+#endif
+		}
+
+		public string GetName()
+		{
+#if !CF
+			return _thread != null ? _thread.Name : _name;
+#else
+			return "";
+#endif
+		}
+
+		public static void Sleep(long milliseconds)
+		{
+			System.Threading.Thread.Sleep((int)milliseconds);
+		}
+
+		public void Start()
+		{
+			_thread = new System.Threading.Thread(EntryPoint);
+			_thread.IsBackground = _isDaemon;
+			if (_name != null)
+			{
+				SetName(_name);
+			}
+			_thread.Start();
+		}
+
+		public void Join() 
+		{
+			if (_thread == null)
+				return;
+			_thread.Join();
+		}
+
+		public void Join(int millisecondsTimeout)
+		{
+			if (_thread == null)
+				return;
+			_thread.Join(millisecondsTimeout);
+		}
+		
+		public void SetDaemon(bool isDaemon)
+		{
+			_isDaemon = isDaemon;
+		}
+
+		public override bool Equals(object obj)
+		{
+			Thread other = (obj as Thread);
+			if (other == null)
+				return false;
+			if (other == this)
+				return true;
+			if (_thread == null)
+				return false;
+			return _thread == other._thread;
+		}
+
+		public override int GetHashCode()
+		{
+			return _thread == null ? 37 : _thread.GetHashCode();
+		}
+
+		private void EntryPoint()
+		{
+			try
+			{
+				_target.Run();
+			}
+			catch (Exception e)
+			{
+				// don't let an unhandled exception bring
+				// the process down
+				Runtime.PrintStackTrace(e);
+			}
+		}
+
+		public bool IsDaemon()
+		{
+			return _thread != null
+				? _thread.IsBackground
+				: _isDaemon;
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/ThreadLocal.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/ThreadLocal.cs
new file mode 100644
index 0000000..3c3d381
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/ThreadLocal.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+
+namespace Sharpen.Lang
+{
+#if CF
+
+	class ThreadLocal : Db4objects.Db4o.Foundation.ThreadLocal4
+	{
+	}
+
+#else
+
+	class ThreadLocal
+	{
+		[ThreadStatic]
+		private static Dictionary<ThreadLocal, object> _locals;
+
+		public object Get()
+		{
+			object value;
+			if (Locals.TryGetValue(this, out value))
+				return value;
+			return null;
+		}
+
+		public void Set(object value)
+		{
+			if (value == null)
+				Locals.Remove(this);
+			else
+				Locals[this] = value;
+		}
+
+		private static Dictionary<ThreadLocal, object> Locals
+		{
+			get
+			{
+				Dictionary<ThreadLocal, object> value = _locals;
+				if (value == null)
+					_locals = value = new Dictionary<ThreadLocal, object>();
+				return value;
+			}
+		}
+
+	}
+#endif
+}
+
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/TypeReference.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/TypeReference.cs
new file mode 100644
index 0000000..c359bc2
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/TypeReference.cs
@@ -0,0 +1,303 @@
+/* Copyright (C) 2005   Versant Inc.   http://www.db4o.com */
+using System;
+using System.Reflection;
+using System.Text;
+
+namespace Sharpen.Lang
+{	
+	public abstract class TypeReference
+	{
+		public static TypeReference FromString(string s)
+		{
+			if (null == s) throw new ArgumentNullException("s");
+			return new TypeReferenceParser(s).Parse();
+		}
+		
+		public static TypeReference FromType(Type type)
+		{
+			if (null == type) throw new ArgumentNullException("type");
+			return FromString(type.AssemblyQualifiedName);
+		}
+
+		public abstract string SimpleName
+		{
+			get;
+		}
+
+		public abstract AssemblyName AssemblyName
+		{
+			get;
+		}
+
+		public abstract Type Resolve();
+
+		public abstract void AppendTypeName(StringBuilder builder);
+
+		public override string ToString()
+		{
+			return GetUnversionedName();
+		}
+
+		public string GetUnversionedName()
+		{
+			StringBuilder builder = new StringBuilder();
+			AppendUnversionedName(builder);
+			return builder.ToString();
+		}
+
+		internal virtual void AppendUnversionedName(StringBuilder builder)
+		{
+			AppendTypeName(builder);
+			AppendUnversionedAssemblyName(builder);
+		}
+
+		protected void AppendUnversionedAssemblyName(StringBuilder builder)
+		{
+			AssemblyName assemblyName = AssemblyName;
+			if (null == assemblyName) return;
+
+			builder.Append(", ");
+			builder.Append(assemblyName.Name);
+		}
+	}
+
+	public partial class SimpleTypeReference : TypeReference
+	{
+		protected string _simpleName;
+
+		protected AssemblyName _assemblyName;
+
+		internal SimpleTypeReference(string simpleName)
+		{
+			_simpleName = simpleName;
+		}
+
+		public override string SimpleName
+		{
+			get { return _simpleName; }
+		}
+		
+		public override AssemblyName AssemblyName
+		{
+			get { return _assemblyName; }
+		}
+
+		public override Type Resolve()
+		{
+			return _assemblyName == null
+				? Type.GetType(SimpleName)
+                : ResolveAssembly().GetType(SimpleName);
+		}
+
+		public override void AppendTypeName(StringBuilder builder)
+		{
+			builder.Append(SimpleName);
+		}
+
+		public override bool Equals(object obj)
+		{
+			SimpleTypeReference other = obj as SimpleTypeReference;
+			if (null == other) return false;
+			return _simpleName == other._simpleName;
+		}
+
+		internal void SetSimpleName(string simpleName)
+		{
+			_simpleName = simpleName;
+		}
+
+		internal void SetAssemblyName(AssemblyName assemblyName)
+		{
+			_assemblyName = assemblyName;
+		}
+
+		private Assembly ResolveAssembly()
+		{
+#if SILVERLIGHT
+			return ResolveAssemblySilverlight();
+#else
+			if (null == _assemblyName.Version)
+			{
+				return LoadUnversionedAssembly(_assemblyName);
+			}
+			
+			Assembly found;
+			try
+			{
+				found = Assembly.Load(_assemblyName);
+			}
+			catch (Exception)
+			{
+				AssemblyName unversioned = (AssemblyName)_assemblyName.Clone();
+				unversioned.Version = null;
+				found = LoadUnversionedAssembly(unversioned);
+			}
+			return found;
+#endif
+		}
+
+		private Assembly LoadUnversionedAssembly(AssemblyName unversioned)
+		{	
+#if CF || SILVERLIGHT
+            return Assembly.Load(unversioned);
+#else
+			Assembly found = Assembly.LoadWithPartialName(unversioned.FullName);
+			return found == null
+			       	? Assembly.Load(unversioned)
+			       	: found;
+#endif
+		}
+	}
+
+	public abstract class QualifiedTypeReference : TypeReference
+	{
+		protected TypeReference _elementType;
+
+		protected QualifiedTypeReference(TypeReference elementType)
+		{
+			_elementType = elementType;
+		}
+
+		public override string SimpleName
+		{
+			get
+			{
+				return _elementType.SimpleName;
+			}
+		}
+
+		public override AssemblyName AssemblyName
+		{
+			get { return _elementType.AssemblyName; }
+		}
+
+		public override void AppendTypeName(StringBuilder builder)
+		{
+			_elementType.AppendTypeName(builder);
+			AppendQualifier(builder);
+		}
+
+		protected abstract void AppendQualifier(StringBuilder builder);
+	}
+
+	public class PointerTypeReference : QualifiedTypeReference
+	{
+		public PointerTypeReference(TypeReference elementType)
+			: base(elementType)
+		{
+		}
+
+		protected override void AppendQualifier(StringBuilder builder)
+		{
+			builder.Append('*');
+		}
+
+		public override Type Resolve()
+		{
+#if !CF
+			return _elementType.Resolve().MakePointerType();
+#else
+			StringBuilder builder = new StringBuilder();
+			AppendTypeName(builder);
+			return _elementType.Resolve().Assembly.GetType(builder.ToString(), true);
+#endif
+		}
+	}
+
+	public class ArrayTypeReference : QualifiedTypeReference
+	{
+		public static Type MakeArrayType(Type elementType, int rank)
+		{
+#if !CF
+			if (rank == 1) return elementType.MakeArrayType();
+			return elementType.MakeArrayType(rank);
+#else
+			if (rank == 1) return Array.CreateInstance(elementType, 0).GetType();
+			return Array.CreateInstance(elementType, new int[rank]).GetType();
+#endif
+		}
+
+
+		private readonly int _rank;
+
+		internal ArrayTypeReference(TypeReference elementType, int rank) : base(elementType)
+		{
+			_rank = rank;
+		}
+
+		public int Rank
+		{
+			get { return _rank; }
+		}
+
+		public override Type Resolve()
+		{
+			return MakeArrayType(_elementType.Resolve(), _rank);
+		}
+
+		protected override void AppendQualifier(StringBuilder builder)
+		{
+			builder.Append('[');
+			for (int i = 1; i < _rank; ++i)
+			{
+				builder.Append(',');
+			}
+			builder.Append(']');
+		}
+	}
+
+	public class GenericTypeReference : SimpleTypeReference
+	{
+		private readonly TypeReference[] _genericArguments;
+
+		internal GenericTypeReference(string simpleName, TypeReference[] genericArguments)
+			: base(simpleName)
+		{
+			_genericArguments = genericArguments;
+		}
+
+		public TypeReference[] GenericArguments
+		{
+			get { return _genericArguments; }
+		}
+
+		public override Type Resolve()
+		{
+			Type baseType = base.Resolve();
+			return _genericArguments.Length > 0
+				? baseType.MakeGenericType(Resolve(_genericArguments))
+				: baseType;
+		}
+
+		static Type[] Resolve(TypeReference[] typeRefs)
+		{
+			Type[] types = new Type[typeRefs.Length];
+			for (int i = 0; i < types.Length; ++i)
+			{
+				types[i] = typeRefs[i].Resolve();
+			}
+			return types;
+		}
+
+		public override void AppendTypeName(StringBuilder builder)
+		{
+			builder.Append(_simpleName);
+			AppendUnversionedGenericArguments(builder);
+		}
+
+		private void AppendUnversionedGenericArguments(StringBuilder builder)
+		{
+			if (_genericArguments.Length == 0) return;
+
+			builder.Append("[");
+			for (int i = 0; i < _genericArguments.Length; ++i)
+			{
+				if (i > 0) builder.Append(", ");
+				builder.Append("[");
+				_genericArguments[i].AppendUnversionedName(builder);
+				builder.Append("]");
+			}
+			builder.Append("]");
+		}
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/TypeReferenceLexer.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/TypeReferenceLexer.cs
new file mode 100644
index 0000000..cd5e8f0
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/TypeReferenceLexer.cs
@@ -0,0 +1,186 @@
+/* Copyright (C) 2005   Versant Inc.   http://www.db4o.com */
+using System;
+using System.Text;
+
+namespace Sharpen.Lang
+{
+	internal enum TokenKind
+	{
+		Comma,
+		Equals,
+		Id,
+		Number,
+		VersionNumber,
+		GenericQualifier,
+		NestedQualifier,
+		LBrack,
+		RBrack,
+		PointerQualifier
+	}
+
+	internal class Token
+	{
+		public TokenKind Kind;
+		public string Value;
+
+		public Token(TokenKind kind, string value)
+		{
+			this.Kind = kind;
+			this.Value = value;
+			//Console.WriteLine(this);
+		}
+
+		public override string ToString()
+		{
+			return string.Format("Token(Kind: {0}, Value: '{1}')", Kind, Value);
+		}
+	}
+
+	internal class TypeReferenceLexer
+	{
+		string _input;
+		int _index;
+		StringBuilder _buffer; // TODO: get rid of StringBuilder and use string.Substring
+
+		public TypeReferenceLexer(string input)
+		{
+			if (null == input) throw new ArgumentNullException("input");
+			_input = input;
+			_index = 0;
+			_buffer = new StringBuilder(input.Length);
+		}
+
+		bool AtEOF
+		{
+			get { return _index == _input.Length; }
+		}
+
+		public Token NextToken()
+		{
+			if (AtEOF) return null;
+
+			char ch = Peek();
+			switch (ch)
+			{
+				case '*':
+					return ConsumeSingleCharToken(ch, TokenKind.PointerQualifier);
+				case '+':
+					return ConsumeSingleCharToken(ch, TokenKind.NestedQualifier);
+				case '[':
+					return ConsumeSingleCharToken(ch, TokenKind.LBrack);
+				case ']':
+					return ConsumeSingleCharToken(ch, TokenKind.RBrack);
+				case '=':
+					return ConsumeSingleCharToken(ch, TokenKind.Equals);
+				case ',':
+					return ConsumeSingleCharToken(ch, TokenKind.Comma);
+				case '`':
+					return ConsumeSingleCharToken(ch, TokenKind.GenericQualifier);
+				case ' ':
+					Consume();
+					return NextToken();
+				default:
+					if (IsIdStart(ch)) return Id();
+					if (char.IsDigit(ch)) return NumberOrVersion();
+					break;
+			}
+			throw new Exception(string.Format("Unexpected char '{0}'", ch));
+		}
+
+		private static bool IsIdStart(char ch)
+		{
+			switch (ch)
+			{
+				case '_':
+				case '<': // c# compiler generated classes
+					return true;
+			}
+			return char.IsLetter(ch);
+		}
+
+		private Token Id()
+		{
+			do
+			{
+				char ch = Peek();
+				if (!char.IsLetterOrDigit(ch)
+					&& '.' != ch
+					&& '-' != ch
+					&& '_' != ch
+					&& '<' != ch
+					&& '>' != ch
+					&& ':' != ch
+					&& ' ' != ch) // assembly names can contain spaces
+				{
+					break;
+				}
+				ConsumeAndBuffer(ch);
+			}
+			while (!AtEOF);
+			return TokenFromBuffer(TokenKind.Id);
+		}
+
+		private Token NumberOrVersion()
+		{
+			TokenKind kind = TokenKind.Number;
+
+			do
+			{
+				char ch = Peek();
+				if ('.' == ch)
+				{
+					kind = TokenKind.VersionNumber;
+				}
+				else 
+				{
+					if (!IsHexDigit(ch)) 
+					{
+						break;
+					}
+				}
+				ConsumeAndBuffer(ch);
+			}
+			while (!AtEOF);
+			return TokenFromBuffer(kind);
+		}
+
+		private static bool IsHexDigit(char ch)
+		{
+			return char.IsDigit(ch) || IsHexLetter(ch);
+		}
+
+		private static bool IsHexLetter(char ch)
+		{
+			return (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f');
+		}
+
+		private void ConsumeAndBuffer(char ch)
+		{
+			Consume();
+			_buffer.Append(ch);
+		}
+
+		private Token TokenFromBuffer(TokenKind kind)
+		{
+			Token token = new Token(kind, _buffer.ToString());
+			_buffer.Length = 0;
+			return token;
+		}
+
+		private Token ConsumeSingleCharToken(char ch, TokenKind kind)
+		{
+			Consume();
+			return new Token(kind, new string(ch, 1));
+		}
+
+		void Consume()
+		{
+			++_index;
+		}
+
+		char Peek()
+		{
+			return _input[_index];
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/TypeReferenceParser.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/TypeReferenceParser.cs
new file mode 100644
index 0000000..6e50bb7
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Lang/TypeReferenceParser.cs
@@ -0,0 +1,259 @@
+/* Copyright (C) 2005   Versant Inc.   http://www.db4o.com */
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Reflection;
+
+namespace Sharpen.Lang
+{
+	internal class TypeReferenceParser
+	{
+		private readonly TypeReferenceLexer _lexer;
+		private readonly Stack<Token> _stack = new Stack<Token>();
+		
+		public TypeReferenceParser(string input)
+		{
+			_lexer = new TypeReferenceLexer(input);
+		}
+
+		public TypeReference Parse()
+		{
+			SimpleTypeReference str = ParseSimpleTypeReference();
+			TypeReference returnValue = ParseQualifiedTypeReference(str);
+			Token token = NextToken();
+			if (null != token)
+			{
+				switch (token.Kind)
+				{
+					case TokenKind.Comma:
+						str.SetAssemblyName(ParseAssemblyName());
+						break;
+					default:
+						UnexpectedToken(TokenKind.Comma, token);
+						break;
+				}
+			}
+			return returnValue;
+		}
+		
+		private TypeReference ParseQualifiedTypeReference(TypeReference elementType)
+		{
+			TypeReference returnValue = elementType;
+			
+			Token token;
+			while (null != (token = NextToken()))
+			{
+				switch (token.Kind)
+				{
+					case TokenKind.LBrack:
+						returnValue = ParseArrayTypeReference(returnValue);
+						break;
+					case TokenKind.PointerQualifier:
+						returnValue = new PointerTypeReference(returnValue);
+						break;
+					default:
+						Push(token);
+						return returnValue;
+				}
+			}
+			
+			return returnValue;
+		}
+
+		private TypeReference ParseArrayTypeReference(TypeReference str)
+		{
+			int rank = 1;
+			Token token = NextToken();
+			while (null != token && token.Kind == TokenKind.Comma)
+			{
+				++rank;
+				token = NextToken();
+			}
+			AssertTokenKind(TokenKind.RBrack, token);
+
+			return new ArrayTypeReference(str, rank);
+		}
+
+		private SimpleTypeReference ParseSimpleTypeReference()
+		{
+			Token id = Expect(TokenKind.Id);
+
+			Token t = NextToken();
+			if (null == t) return new SimpleTypeReference(id.Value);
+
+			while (TokenKind.NestedQualifier == t.Kind)
+			{
+				Token nestedId = Expect(TokenKind.Id);
+				id.Value += "+" + nestedId.Value;
+
+				t = NextToken();
+				if (null == t) return new SimpleTypeReference(id.Value);
+			}
+			
+			if (t.Kind == TokenKind.GenericQualifier)
+			{
+				return ParseGenericTypeReference(id);
+			}
+			
+			Push(t);
+			return new SimpleTypeReference(id.Value);
+		}
+
+		private SimpleTypeReference ParseGenericTypeReference(Token id)
+		{
+			return InternalParseGenericTypeReference(id, 0);
+		}
+
+		private SimpleTypeReference InternalParseGenericTypeReference(Token id, int count)
+		{
+			Token argcToken = Expect(TokenKind.Number);
+			id.Value += "`" + argcToken.Value;
+
+			int argc = int.Parse(argcToken.Value);
+
+			Token t = NextToken();
+			while (TokenKind.NestedQualifier == t.Kind)
+			{
+				Token nestedId = Expect(TokenKind.Id);
+				id.Value += "+" + nestedId.Value;
+
+				t = NextToken();
+			}
+
+			if (IsInnerGenericTypeReference(t))
+			{
+				return InternalParseGenericTypeReference(id, argc + count);
+			}
+
+			TypeReference[] args = new TypeReference[0];
+			if (!IsOpenGenericTypeDefinition(t))
+			{
+				args = new TypeReference[argc + count];
+				AssertTokenKind(TokenKind.LBrack, t);
+				for (int i = 0; i < args.Length; ++i)
+				{
+					if (i > 0) Expect(TokenKind.Comma);
+					Expect(TokenKind.LBrack);
+					args[i] = Parse();
+					Expect(TokenKind.RBrack);
+				}
+				Expect(TokenKind.RBrack);
+			}
+			else
+			{
+				Push(t);
+			}
+
+			return new GenericTypeReference(id.Value, args);
+		}
+
+		private static bool IsOpenGenericTypeDefinition(Token t)
+		{
+			return t.Kind != TokenKind.LBrack;
+		}
+
+		private static bool IsInnerGenericTypeReference(Token t)
+		{
+			return TokenKind.GenericQualifier == t.Kind;
+		}
+
+		public AssemblyName ParseAssemblyName()
+		{
+			Token simpleName = Expect(TokenKind.Id);
+			
+			AssemblyName assemblyName = new AssemblyName();
+			assemblyName.Name = simpleName.Value;
+
+			if (!CommaIdEquals()) return assemblyName;
+
+			Token version = Expect(TokenKind.VersionNumber);
+			assemblyName.Version = new Version(version.Value);
+
+			if (!CommaIdEquals()) return assemblyName;
+			
+			Token culture = Expect(TokenKind.Id);
+			if ("neutral" == culture.Value)
+			{
+				assemblyName.CultureInfo = CultureInfo.InvariantCulture;
+			}
+			else
+			{
+#if SILVERLIGHT
+                assemblyName.CultureInfo = CultureInfo.InvariantCulture;
+#else
+				assemblyName.CultureInfo = CultureInfo.CreateSpecificCulture(culture.Value);
+#endif
+			}
+
+			if (!CommaIdEquals()) return assemblyName;
+			
+			Token token = NextToken();
+			if ("null" != token.Value)
+			{
+				assemblyName.SetPublicKeyToken(ParsePublicKeyToken(token.Value));
+			}
+
+			return assemblyName;
+		}
+
+		static byte[] ParsePublicKeyToken(string token)
+		{
+			int len = token.Length / 2;
+			byte[] bytes = new byte[len];
+			for (int i = 0; i < len; ++i)
+			{
+				bytes[i] = byte.Parse(token.Substring(i * 2, 2), NumberStyles.HexNumber);
+			}
+			return bytes;
+		}
+
+		private bool CommaIdEquals()
+		{
+			Token token = NextToken();
+			if (null == token) return false;
+			if (token.Kind != TokenKind.Comma)
+			{
+				Push(token);
+				return false;
+			}
+			
+			AssertTokenKind(TokenKind.Comma, token);
+			Expect(TokenKind.Id);
+			Expect(TokenKind.Equals);
+			return true;
+		}
+
+		Token Expect(TokenKind expected)
+		{
+			Token actual = NextToken();
+			AssertTokenKind(expected, actual);
+			return actual;
+		}
+
+		private static void AssertTokenKind(TokenKind expected, Token actual)
+		{
+			if (null == actual || actual.Kind != expected)
+			{
+				UnexpectedToken(expected, actual);
+			}
+		}
+
+		private static void UnexpectedToken(TokenKind expectedKind, Token actual)
+		{
+			throw new ArgumentException(string.Format("Unexpected Token: '{0}' (Expected kind: '{1}')", actual, expectedKind));
+		}
+		
+		private void Push(Token token)
+		{
+			_stack.Push(token);
+		}
+	
+		private Token NextToken()
+		{
+			return _stack.Count > 0
+				? _stack.Pop()
+				: _lexer.NextToken();
+		}
+
+	}
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Net/ServerSocket.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Net/ServerSocket.cs
new file mode 100644
index 0000000..edda8d4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Net/ServerSocket.cs
@@ -0,0 +1,42 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+using System;
+using System.Net;
+using System.Net.Sockets;
+using NativeSocket=System.Net.Sockets.Socket;
+
+namespace Sharpen.Net
+{
+	public class ServerSocket : SocketWrapper
+	{
+		public ServerSocket(int port)
+		{
+#if !SILVERLIGHT
+			try
+            {
+				NativeSocket socket = new NativeSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+                socket.Bind(new IPEndPoint(IPAddress.Any, port));
+
+                int maxPendingConnections = 42;
+                socket.Listen(maxPendingConnections);
+                Initialize(socket);
+            }
+            catch (SocketException e)
+            {
+                throw new System.IO.IOException(e.Message);
+            }
+#endif
+		}
+
+#if !SILVERLIGHT
+		public Socket Accept()
+		{
+			return new Socket(_delegate.Accept());
+		}
+
+		public int GetLocalPort()
+		{
+			return ((IPEndPoint)_delegate.LocalEndPoint).Port;
+		}
+#endif
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Net/Socket.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Net/Socket.cs
new file mode 100644
index 0000000..6d0fdab
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Net/Socket.cs
@@ -0,0 +1,149 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+using System;
+using System.IO;
+using System.Net;
+using Sharpen.IO;
+using NativeSocket=System.Net.Sockets.Socket;
+using System.Net.Sockets;
+
+namespace Sharpen.Net
+{
+	public class Socket : SocketWrapper
+	{
+#if SILVERLIGHT
+		public Socket(string hostName, int port)
+		{
+		}
+	}
+#else
+		public Socket(string hostName, int port)
+		{
+		    NativeSocket socket = new NativeSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+			socket.Connect(new IPEndPoint(Resolve(hostName), port));
+			Initialize(socket);
+			_toString = StringRepresentation();
+		}
+
+	    private static IPAddress Resolve(string hostName)
+	    {
+	    	IPHostEntry found = Dns.GetHostEntry(hostName);
+	        foreach (IPAddress address in found.AddressList)
+	        {
+                if (address.AddressFamily == AddressFamily.InterNetwork)
+                {
+                    return address;
+                }
+	        }
+	        throw new IOException("couldn't find suitable address for name '" + hostName + "'");
+	    }
+
+	    public Socket(NativeSocket socket)
+		{
+			Initialize(socket);
+		}
+
+		public IInputStream GetInputStream()
+		{
+			return _in;
+		}
+
+		public IOutputStream GetOutputStream()
+		{
+			return _out;
+		}
+
+		public int GetPort() 
+		{
+			return ((IPEndPoint) _delegate.RemoteEndPoint).Port;
+		}
+
+		override protected void Initialize(NativeSocket socket)
+		{
+			base.Initialize(socket);
+
+			NetworkStream stream = new NetworkStream(_delegate);
+
+#if CF
+			_in = new SocketInputStream(this);
+#else
+			_in = new InputStream(stream);
+#endif
+			_out = new OutputStream(stream);
+		}
+
+		public override string ToString()
+		{
+			return _toString;
+		}
+
+		private string StringRepresentation()
+		{
+			return ((IPEndPoint)_delegate.LocalEndPoint).Port + " => "+ UnderlyingSocket.RemoteEndPoint;
+		}
+
+		private IInputStream _in;
+		private IOutputStream _out;
+		private readonly string _toString;
+	}
+#if CF
+	internal class SocketInputStream : IInputStream
+    {
+    	private readonly Socket _socket;
+
+    	public SocketInputStream(Socket socket)
+        {
+    		_socket = socket;
+        }
+
+    	public int Read()
+    	{
+			byte[] buffer = new byte[1];
+    		if (1 != Read(buffer))
+    		{
+    			return -1;
+    		}
+    		return (int) buffer[0];
+    	}
+
+    	public int Read(byte[] bytes)
+    	{
+    		return Read(bytes, 0, bytes.Length);
+    	}
+
+    	public int Read(byte[] bytes, int offset, int length)
+    	{
+			try
+			{
+				if (_socket.SoTimeout > 0)
+				{
+					if (!UnderlyingSocket.Poll(_socket.SoTimeout*1000, SelectMode.SelectRead))
+					{
+						throw new IOException("read timeout");
+					}
+				}
+				return InputStream.TranslateReadReturnValue(
+					UnderlyingSocket.Receive(bytes, offset, length, SocketFlags.None));
+			}
+			catch (ObjectDisposedException x)
+			{
+				throw new IOException(x.Message, x);
+			}
+			catch (SocketException x)
+			{
+				throw new IOException(x.Message, x);
+			}
+    	}
+
+    	public void Close()
+    	{
+    		// nothing to do
+    	}
+
+    	private System.Net.Sockets.Socket UnderlyingSocket
+    	{
+			get { return _socket.UnderlyingSocket;  }
+    	}
+	}
+#endif // CF
+#endif // SILVERLIGHT
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Net/SocketWrapper.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Net/SocketWrapper.cs
new file mode 100644
index 0000000..62252f1
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Net/SocketWrapper.cs
@@ -0,0 +1,61 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+using System;
+using System.Net.Sockets;
+using NativeSocket=System.Net.Sockets.Socket;
+
+namespace Sharpen.Net
+{
+	public class SocketWrapper
+	{
+		protected NativeSocket _delegate;
+
+#if CF || SILVERLIGHT
+	    private int _soTimeout = 0;
+
+        public int SoTimeout
+        {
+            get { return _soTimeout; }
+        }
+#endif
+
+		public NativeSocket UnderlyingSocket
+		{
+			get { return _delegate;  }
+		}
+
+	    protected virtual void Initialize(NativeSocket socket)
+		{
+			_delegate = socket;
+		}
+
+		public void SetSoTimeout(int timeout)
+		{
+#if !CF && !SILVERLIGHT
+			_delegate.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, timeout);
+			_delegate.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, timeout);
+#else
+			_soTimeout = timeout;
+#endif
+		}
+
+		public void Close()
+		{
+			if (_delegate.Connected)
+			{
+				try
+				{
+					_delegate.Shutdown(SocketShutdown.Both);
+				}
+				catch (Exception)
+				{	
+				}
+			}
+			_delegate.Close();
+		}
+
+        public bool IsConnected() 
+        {
+            return _delegate.Connected;
+        }
+	}
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Runtime.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Runtime.cs
new file mode 100644
index 0000000..06525c9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Runtime.cs
@@ -0,0 +1,287 @@
+/* Copyright (C) 2004	Versant Inc.	  http://www.db4o.com */
+
+using System;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+using Sharpen.Lang;
+
+namespace Sharpen
+{
+	public class Runtime 
+	{
+		private static long DIFFERENCE_IN_TICKS = 62135604000000;
+		private static long RATIO = 10000;
+
+		public static TextWriter Out
+		{
+			get
+			{
+				return Console.Out;
+			}
+		}
+
+		public static TextWriter Err
+		{
+			get
+			{
+				return Console.Error;
+			}
+		}
+
+		public static object GetArrayValue(object array, int i)
+	    {
+	        return ((Array)array).GetValue(i);
+	    }
+	    
+	    public static int GetArrayLength(object array)
+	    {
+            return ((Array) array).Length;
+	    }
+
+	    public static void SetArrayValue(object array, int index, object value)
+	    {
+	        ((Array)array).SetValue(value, index);
+	    }
+
+        private const BindingFlags AllMembers = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+
+        private const BindingFlags DeclaredMembers = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+
+        private const BindingFlags DeclaredMembersIncludingStatic = DeclaredMembers | BindingFlags.Static;
+		
+		public static FieldInfo GetDeclaredField(Type type, string name)
+		{
+            return type.GetField(name, DeclaredMembersIncludingStatic);
+		}
+
+		public static FieldInfo[] GetDeclaredFields(Type type)
+		{
+            return type.GetFields(DeclaredMembersIncludingStatic);
+		}
+		
+		public static MethodInfo GetDeclaredMethod(Type type, string name, Type[] parameterTypes)
+		{
+			return type.GetMethod(name, DeclaredMembers, null, parameterTypes, null);
+		}
+
+        public static MethodInfo GetMethod(Type type, string name, Type[] parameterTypes)
+        {
+            return type.GetMethod(name, AllMembers, null, parameterTypes, null);
+        }
+
+		public static Type[] GetParameterTypes(MethodBase method)
+		{
+			ParameterInfo[] parameters = method.GetParameters();
+			Type[] types = new Type[parameters.Length];
+			for (int i=0; i<types.Length; ++i)
+			{
+				types[i] = parameters[i].ParameterType;
+			}
+			return types;
+		}
+
+		public static long CurrentTimeMillis() 
+		{
+			return ToJavaMilliseconds(DateTime.Now.ToUniversalTime());
+		}
+
+		public static int FloatToIntBits(float value) 
+		{
+			return BitConverter.ToInt32(BitConverter.GetBytes(value), 0);
+		}
+
+		public static void Gc() 
+		{
+			GC.Collect();
+		}
+		
+		public static bool EqualsIgnoreCase(string lhs, string rhs) 
+		{
+#if SILVERLIGHT
+			return 0 == string.Compare(lhs, rhs, StringComparison.OrdinalIgnoreCase);
+#else
+			return 0 == string.Compare(lhs, rhs, true);
+#endif
+		}
+
+		public static int CompareOrdinal(String a, String b)
+		{
+			return String.CompareOrdinal(a, b);
+		}
+
+		public static string Substring(String s, int startIndex)
+		{
+			return s.Substring(startIndex);
+		}
+
+		public static string Substring(String s, int startIndex, int endIndex)
+		{
+			return s.Substring(startIndex, endIndex-startIndex);
+		}
+
+		public static void GetCharsForString(string str, int start, int end, char[] destination, int destinationStart) 
+		{
+			str.CopyTo(start, destination, 0, end-start);
+		}
+
+		public static byte[] GetBytesForString(string str)
+		{
+#if SILVERLIGHT
+			return System.Text.Encoding.Unicode.GetBytes(str);
+#else
+			return System.Text.Encoding.Default.GetBytes(str);
+#endif
+		}
+
+		public static string GetStringForBytes(byte[] bytes, int index, int length)
+		{
+#if SILVERLIGHT
+			return System.Text.Encoding.Unicode.GetString(bytes, index, length);
+#else
+			return System.Text.Encoding.Default.GetString(bytes, index, length);
+#endif
+		}
+
+		public static string GetStringValueOf(object value) 
+		{
+			return null == value
+				? "null"
+				: value.ToString();
+		}
+
+		public static String GetProperty(String key) 
+		{
+			return GetProperty(key, null);
+		}
+
+		public static String GetProperty(String key, String defaultValue)
+		{
+#if CF
+			return key.Equals("line.separator") ? "\n" : defaultValue;
+#else
+			return key.Equals("line.separator")
+				? Environment.NewLine
+				: GetEnvironmentVariable(key, defaultValue);
+#endif
+		}
+
+		public static string GetEnvironmentVariable(string variableName, string defaultValue)
+		{
+#if CF || SILVERLIGHT
+			return defaultValue;
+#else
+			string value = Environment.GetEnvironmentVariable(variableName);
+			if (value == null || value.Length == 0) return defaultValue;
+			return value;
+#endif
+		}
+
+		public static object GetReferenceTarget(WeakReference reference) 
+		{
+			return reference.Target;
+		}
+
+		public static long GetTimeForDate(DateTime dateTime) 
+		{
+			return ToJavaMilliseconds(dateTime);
+		}
+
+		public static int IdentityHashCode(object obj) 
+		{
+			return IdentityHashCodeProvider.IdentityHashCode(obj);
+		}
+
+		public static float IntBitsToFloat(int value) 
+		{
+			return BitConverter.ToSingle(BitConverter.GetBytes(value), 0);
+		}
+
+		public static void Wait(object obj, long timeout) 
+		{
+#if CF
+			throw new NotImplementedException();
+#else
+			Monitor.Wait(obj, (int) timeout);
+#endif
+		}
+
+		public static void Wait(object obj) 
+		{
+#if CF
+			throw new NotImplementedException();
+#else
+			Monitor.Wait(obj);
+#endif
+		}
+
+		public static void Notify(object obj) 
+		{
+#if CF
+			throw new NotImplementedException();
+#else
+			Monitor.Pulse(obj);
+#endif
+		}
+
+		public static void NotifyAll(object obj) 
+		{
+#if CF
+			throw new NotImplementedException();
+#else
+			Monitor.PulseAll(obj);
+#endif
+		}
+
+		public static void PrintStackTrace(Exception exception) 
+		{
+			PrintStackTrace(exception, Err);
+		}
+
+		public static void PrintStackTrace(Exception exception, TextWriter writer) 
+		{
+			writer.WriteLine(exception);
+		}
+
+		public static void RunFinalization() 
+		{
+			GC.WaitForPendingFinalizers();
+		}
+
+		public static void RunFinalizersOnExit(bool flag) 
+		{
+			// do nothing
+		}
+
+        public static Type GetType(string typeName)
+        {
+            return TypeReference.FromString(typeName).Resolve();
+        }
+
+		public static long ToJavaMilliseconds(DateTime dateTimeNet)
+		{
+			return ToJavaMilliseconds(dateTimeNet.Ticks);
+		}
+
+		public static long ToJavaMilliseconds(long ticks)
+		{
+			return ticks / RATIO - DIFFERENCE_IN_TICKS;
+		}
+
+		public static long ToNetTicks(long javaMilliseconds)
+		{
+			return (javaMilliseconds + DIFFERENCE_IN_TICKS) * RATIO;
+		}
+
+        public static string Getenv(string name)
+        {
+#if CF || SILVERLIGHT
+			throw new NotImplementedException();
+#else
+            return Environment.GetEnvironmentVariable(name);
+#endif
+        }
+
+ 
+    }
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Text/DecimalFormat.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Text/DecimalFormat.cs
new file mode 100644
index 0000000..d59ee2f
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Text/DecimalFormat.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2004 - 2008  Versant Inc.  http://www.db4o.com */
+using System;
+
+namespace Sharpen.Text
+{
+    public class DecimalFormat
+    { 
+        private string _format;
+        public DecimalFormat(string format)
+        {
+            _format = format;
+        }
+
+        public string Format(double number)
+        {
+            Double temp = (Double)number;
+            return temp.ToString(_format);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Util/Arrays.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Util/Arrays.cs
new file mode 100755
index 0000000..52f1b39
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Util/Arrays.cs
@@ -0,0 +1,40 @@
+using System.Collections.Generic;
+
+namespace Sharpen.Util
+{
+	public class Arrays
+	{
+		public static void Fill<T>(T[] array, T value)
+		{	
+			for (int i=0; i<array.Length; ++i)
+			{
+				array[i] = value;
+			}
+		}
+        
+        public static void Fill<T>(T[] array, int fromIndex, int toIndex, T value)
+        {
+            for (int i = fromIndex; i < toIndex; ++i)
+            {
+                array[i] = value;
+            }
+        }
+
+		public static bool Equals<T>(T[] x, T[] y)
+		{
+			if (x == null) return y == null;
+			if (y == null) return false;
+			if (x.Length != y.Length) return false;
+			for (int i = 0; i < x.Length; ++i)
+			{
+				if (!object.Equals(x[i], y[i])) return false;
+			}
+			return true;
+		}
+
+		public static List<T> AsList<T>(T[] array)
+        {
+            return new List<T>(array); 
+        }
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Util/HashSet.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Util/HashSet.cs
new file mode 100644
index 0000000..4b86f70
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Util/HashSet.cs
@@ -0,0 +1,175 @@
+/* Copyright (C) 2004 - 2008  Versant Inc.  http://www.db4o.com */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Sharpen.Util
+{   
+    public class HashSet : ISet, /* IList required for dRS */ IList
+    {   
+        private readonly static object _object = new object();
+
+		// FIXME: dRS doesn't like using a dictionary here
+#if SILVERLIGHT
+		private readonly List<object> _elements = new List<object>();
+#else
+		private readonly ArrayList _elements = new ArrayList();
+#endif
+
+        public HashSet()
+        {
+        }
+
+        public HashSet(ICollection initialValues)
+        {
+            AddAll(initialValues);
+        }
+
+        public bool Add(object o)
+        {
+			if (Contains(o)) return false;
+
+			_elements.Add(o);
+			return true;
+        }
+
+        public bool AddAll(ICollection c)
+        {
+            bool changed = false;
+			foreach (object o in c)
+			{
+				changed |= Add(o);
+			}
+        	return changed;
+        }
+
+        public void Clear()
+        {
+            _elements.Clear();
+        }
+
+        public bool Contains(object o)
+        {
+        	return _elements.Contains(o);
+        }
+
+        public bool ContainsAll(ICollection c)
+        {
+            foreach (object o in c)
+			{
+                if (!Contains(o))
+                {
+                	return false;
+                }
+            }
+            return true;
+        }
+
+        public bool IsEmpty
+        {
+            get { return _elements.Count == 0; }
+        }
+
+        public bool Remove(object o)
+        {
+			if (!Contains(o)) return false;
+            
+			_elements.Remove(o);
+        	return true;
+        }
+
+        public bool RemoveAll(ICollection c)
+        {
+            bool changed = false;
+			foreach (object o in c)
+			{
+				changed |= Remove(o);
+			}
+        	return changed;
+        }
+
+        public void CopyTo(Array array, int index)
+        {
+#if SILVERLIGHT
+            object[] objectArray = new object[array.Length];
+            int idx = 0;
+            foreach (var a in array)
+            {
+                objectArray[idx++] = a;
+            }
+            _elements.CopyTo(objectArray, index);
+#else
+			_elements.CopyTo(array, index);
+#endif
+		}
+
+        public int Count
+        {
+            get { return _elements.Count; }
+        }
+
+        public bool IsSynchronized
+        {
+            get { return false; }
+        }
+
+        public object SyncRoot
+        {
+            get
+            {
+#if SILVERLIGHT
+				throw new InvalidOperationException();
+#else
+            	return _elements.SyncRoot;
+#endif
+            }
+        }
+
+        public IEnumerator GetEnumerator()
+        {
+            return _elements.GetEnumerator();
+        }
+
+    	int IList.Add(object value)
+    	{
+    		((ISet) this).Add(value);
+    		return 0;
+    	}
+
+		void IList.Remove(object value)
+		{
+			((ISet)this).Remove(value);
+		}
+
+    	int IList.IndexOf(object value)
+    	{
+    		throw new NotImplementedException();
+    	}
+
+    	void IList.Insert(int index, object value)
+    	{
+    		throw new NotImplementedException();
+    	}
+
+    	void IList.RemoveAt(int index)
+    	{
+    		throw new NotImplementedException();
+    	}
+
+    	object IList.this[int index]
+    	{
+    		get { throw new NotImplementedException(); }
+    		set { throw new NotImplementedException(); }
+    	}
+
+    	bool IList.IsReadOnly
+    	{
+    		get { return false; }
+    	}
+
+    	bool IList.IsFixedSize
+    	{
+    		get { return false; }
+    	}
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Util/ISet.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Util/ISet.cs
new file mode 100644
index 0000000..60d4d92
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Util/ISet.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections;
+using System.Text;
+
+namespace Sharpen.Util
+{
+    public interface ISet: ICollection
+    {
+    	bool Add(object element);
+    	bool Remove(object element);
+    	bool Contains(object element);
+    }
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Util/Random.cs b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Util/Random.cs
new file mode 100644
index 0000000..5f7deb6
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Sharpen/Util/Random.cs
@@ -0,0 +1,30 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System.Collections;
+
+namespace Sharpen.Util 
+{
+	public class Random 
+	{
+		readonly System.Random _random = new System.Random();
+
+		public Random() 
+		{
+		}
+		
+		public long NextLong() 
+		{
+			return _random.Next();
+		}
+		
+		public int NextInt()
+		{
+			return _random.Next(int.MinValue, int.MaxValue);
+		}
+
+		public object NextInt(int ceiling)
+		{
+			return _random.Next(ceiling);
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/Config/SilverlightSupport.cs b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/Config/SilverlightSupport.cs
new file mode 100644
index 0000000..4aad8cd
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/Config/SilverlightSupport.cs
@@ -0,0 +1,26 @@
+/* Copyright (C) 2010 Versant Inc.  http://www.db4o.com */
+#if SILVERLIGHT
+using Db4objects.Db4o.IO;
+
+namespace Db4objects.Db4o.Config
+{
+	/// <summary>
+	/// Configures the database to be used in a Silverlight application.
+	/// </summary>
+	/// <remarks>
+	/// This configuration item basically configures db4o to use Silverlight isolatad storage. 
+	/// If your Silverlight application may run "out of browser" you may want to not add this.
+	/// </remarks>
+	public class SilverlightSupport : IEmbeddedConfigurationItem
+	{
+		public void Prepare(IEmbeddedConfiguration configuration)
+		{
+			configuration.File.Storage = new IsolatedStorageStorage();
+		}
+
+		public void Apply(IEmbeddedObjectContainer db)
+		{
+		}
+	}
+}
+#endif
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/Foundation/IO/File4.cs b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/Foundation/IO/File4.cs
new file mode 100644
index 0000000..20107ca
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/Foundation/IO/File4.cs
@@ -0,0 +1,45 @@
+/* Copyright (C) 2009 Versant Inc.   http://www.db4o.com */
+
+#if SILVERLIGHT
+using System;
+using System.IO;
+using System.IO.IsolatedStorage;
+
+namespace Db4objects.Db4o.Foundation.IO
+{
+	public class File4
+	{
+		
+		public static void Delete(string file)
+		{
+			IsolatedStorageFile storageFile = IsolatedStorageFile.GetUserStoreForApplication();
+			if (storageFile.FileExists(file))
+			{
+				storageFile.DeleteFile(file);
+			}
+		}
+
+		public static void Copy(string from, string to)
+		{
+			throw new NotImplementedException();
+		}
+
+		public static bool Exists(string file)
+		{
+			IsolatedStorageFile storageFile = IsolatedStorageFile.GetUserStoreForApplication();
+			return storageFile.FileExists(file);
+		}
+
+		public static long Size(string filePath)
+		{
+			using (IsolatedStorageFile storageFile = IsolatedStorageFile.GetUserStoreForApplication())
+			{
+				using (IsolatedStorageFileStream fileStream = storageFile.OpenFile(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
+				{
+					return fileStream.Length;
+				}
+			}
+		}
+	}
+ }
+#endif
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/IO/IsolatedStorageFileBin.cs b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/IO/IsolatedStorageFileBin.cs
new file mode 100644
index 0000000..6a00896
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/IO/IsolatedStorageFileBin.cs
@@ -0,0 +1,169 @@
+/* Copyright (C) 2009  Versant Inc.  http://www.db4o.com */
+
+#if SILVERLIGHT
+
+using System;
+using System.IO;
+using System.IO.IsolatedStorage;
+using Db4objects.Db4o.Ext;
+using Sharpen.Lang;
+using Sharpen.Util;
+
+namespace Db4objects.Db4o.IO
+{
+        class IsolatedStorageFileBin : IBin
+		{
+        	private readonly IsolatedStorageFileStream _fileStream;
+        	private string _fullPath;
+
+        	internal IsolatedStorageFileBin(BinConfiguration config, IsolatedStorageFile store)
+			{
+				Action cleanUp = Close;
+				try
+				{
+					_fileStream = OpenFile(config, store);
+					cleanUp = () => {};
+				}
+				catch (IsolatedStorageException e)
+				{
+					ThrowMappedException(e, config.Uri(), store);
+				}
+				finally
+				{
+					cleanUp();
+				}				
+            }
+
+        	internal string Path
+        	{
+				get { return _fullPath; }
+        	}
+
+        	private static void ThrowMappedException(Exception e, string path, IsolatedStorageFile store)
+        	{
+        		if (store.FileExists(path))
+        		{
+        			throw new DatabaseFileLockedException(path, e);
+        		}
+        		throw new Db4oIOException(e);
+        	}
+
+        	private IsolatedStorageFileStream OpenFile(BinConfiguration config, IsolatedStorageFile store)
+        	{
+        		_fullPath = config.Uri();
+        		string path = config.Uri();
+        		IsolatedStorageFileStream stream = new IsolatedStorageFileStream(path, FileModeFor(store, path), FileAccessFor(config), FileShareFor(config), store);
+        		Fill(stream, config.InitialLength(), 0);
+
+				return stream;
+        	}
+
+        	private static FileMode FileModeFor(IsolatedStorageFile store, string path)
+        	{
+        		return store.FileExists(path) ? FileMode.Open : FileMode.CreateNew;
+        	}
+
+        	private static void Fill(Stream stream, long length, byte value)
+        	{
+        		if (length > 0)
+        		{
+        			byte[] bytes = new byte[length];
+        			Arrays.Fill(bytes, value);
+					stream.Write(bytes, 0, bytes.Length);
+        		}
+        	}
+
+        	private static FileShare FileShareFor(BinConfiguration config)
+        	{
+        		return config.LockFile() ? FileShare.None : FileShare.ReadWrite;
+        	}
+
+        	private static FileAccess FileAccessFor(BinConfiguration config)
+        	{
+        		return config.ReadOnly() ? FileAccess.Read : FileAccess.ReadWrite;
+        	}
+
+        	#region IBin Members
+
+            public long Length()
+            {
+                return _fileStream.Length;
+            }
+
+            public int Read(long position, byte[] bytes, int bytesToRead)
+            {
+                try
+                {
+                    Seek(position);
+                    return _fileStream.Read(bytes, 0, bytesToRead);
+                }
+                catch (IOException e)
+                {
+                    throw new Db4oIOException(e);
+                }
+            }
+
+            public void Write(long position, byte[] bytes, int bytesToWrite)
+            {
+                try
+                {
+                    Seek(position);
+                    _fileStream.Write(bytes, 0, bytesToWrite);
+                }
+                catch (NotSupportedException e)
+                {
+                    throw new Db4oIOException(e);
+                }
+            }
+
+            public void Sync()
+            {
+                _fileStream.Flush();                
+            }
+
+            public void Sync(IRunnable runnable)
+            {
+                Sync();
+                runnable.Run();
+                Sync();
+            }
+
+            public int SyncRead(long position, byte[] bytes, int bytesToRead)
+            {
+                return Read(position, bytes, bytesToRead);
+            }
+
+            public void Close()
+            {
+				if (_fileStream != null)
+				{
+					_fileStream.Close();
+					RaiseOnCloseEvent();
+				}
+            }
+
+	       	#endregion
+
+            private void Seek(long position)
+            {
+                if (DTrace.enabled)
+                {
+                    DTrace.RegularSeek.Log(position);
+                }
+                _fileStream.Seek(position, SeekOrigin.Begin);
+            }
+
+			private void RaiseOnCloseEvent()
+			{
+				Action<object, EventArgs> onClose = OnClose;
+				if (onClose != null)
+				{
+					onClose(this, EventArgs.Empty);
+				}
+			}
+
+			internal event Action<object, EventArgs> OnClose;
+		}
+}
+
+#endif
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/IO/IsolatedStorageStorage.cs b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/IO/IsolatedStorageStorage.cs
new file mode 100644
index 0000000..752ad4a
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/IO/IsolatedStorageStorage.cs
@@ -0,0 +1,113 @@
+/* Copyright (C) 2009  Versant Inc.  http://www.db4o.com */
+
+#if SILVERLIGHT
+
+using System.Collections.Generic;
+using System.IO.IsolatedStorage;
+using System.IO;
+
+namespace Db4objects.Db4o.IO
+{
+	public class IsolatedStorageStorage : IStorage
+	{
+		private static readonly IsolatedStorageFile _store = IsolatedStorageFile.GetUserStoreForApplication();
+		private static readonly IDictionary<string, IsolatedStorageFileBin> _openBins = new Dictionary<string, IsolatedStorageFileBin>();
+
+		#region IStorage Members
+
+		public IBin Open(BinConfiguration config)
+		{
+			IsolatedStorageFileBin bin = new IsolatedStorageFileBin(config, _store);
+			AddToOpenBinsCollection(bin);
+			RegisterForOnCloseEvent(bin);
+			
+			return bin;
+		}
+
+		public bool Exists(string uri)
+		{
+			return _store.FileExists(uri) && FileSize(uri) > 0;
+		}
+
+		public void Delete(string uri)
+		{
+			if (_store.FileExists(uri))
+			{
+				_store.DeleteFile(uri);
+			}
+		}
+
+		public void Rename(string oldUri, string newUri)
+		{
+			if (_store.FileExists(oldUri))
+			{
+				Copy(oldUri, newUri);
+				Delete(oldUri);
+			}
+		}
+
+		private static void Copy(string from, string to)
+		{
+			using (IsolatedStorageFileStream fromStream = _store.OpenFile(from, FileMode.Open, FileAccess.Read, FileShare.None))
+			{
+				using(IsolatedStorageFileStream toStream = _store.OpenFile(to, FileMode.CreateNew, FileAccess.Write, FileShare.None))
+				{
+					byte []buffer = new byte[1024 * 1024];
+					int count = fromStream.Read(buffer, 0, buffer.Length);
+					while (count > 0)
+					{
+						toStream.Write(buffer, 0, count);
+						count = fromStream.Read(buffer, 0, buffer.Length);
+					}
+				}
+			}
+		}
+
+		#endregion
+
+		public static long FileSize(string uri)
+		{
+			lock (_openBins)
+			{
+				if (IsBinAlreadyOpen(uri))
+				{
+					IsolatedStorageFileBin bin = _openBins[uri];
+					return bin.Length();
+				}
+
+				using (IsolatedStorageFileStream fileStream = _store.OpenFile(uri, FileMode.Open, FileAccess.Read, FileShare.None))
+				{
+					return fileStream.Length;
+				}
+			}
+		}
+
+		private static bool IsBinAlreadyOpen(string uri)
+		{
+			return _openBins.ContainsKey(uri);
+		}
+
+		private static void RegisterForOnCloseEvent(IsolatedStorageFileBin bin)
+		{
+			bin.OnClose += (sender, arg) => RemoveFromOpenBinCollection(((IsolatedStorageFileBin)sender).Path);
+		}
+
+		private static void RemoveFromOpenBinCollection(string path)
+		{
+			lock (_openBins)
+			{
+				if (_openBins.ContainsKey(path))
+				{
+					_openBins.Remove(path);
+				}
+			}
+		}
+
+		private static void AddToOpenBinsCollection(IsolatedStorageFileBin bin)
+		{
+			_openBins[bin.Path] = bin;
+		}
+	}
+}
+
+#endif
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/IO/SilverlightIO.cs b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/IO/SilverlightIO.cs
new file mode 100644
index 0000000..2f73c92
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/IO/SilverlightIO.cs
@@ -0,0 +1,42 @@
+/* Copyright (C) 2009 Versant Inc.   http://www.db4o.com */
+#if SILVERLIGHT
+using System;
+using System.IO;
+using System.IO.IsolatedStorage;
+
+namespace Db4objects.Db4o.IO
+{
+	public static class SilverlightIO
+	{
+		public static bool Exists(string path)
+		{
+			return ExistsIn(IsolatedStorageFile.GetUserStoreForApplication(), path);
+		}
+
+		private static bool ExistsIn(IsolatedStorageFile storage, string path)
+		{
+			return storage.FileExists(path);
+		}
+
+		public static bool Delete(string path)
+		{
+			IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
+			if (ExistsIn(storage, path))
+			{
+				storage.DeleteFile(path);
+				return !ExistsIn(storage, path);
+			}
+			return false;
+		}
+
+		public static long Length(string path)
+		{
+			IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
+			using (IsolatedStorageFileStream fileStream = storage.OpenFile(path, FileMode.Open, FileAccess.Read, FileShare.Read))
+			{
+				return fileStream.Length;
+			}
+		}
+	}
+}
+#endif
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/Internal/BlobImpl.cs b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/Internal/BlobImpl.cs
new file mode 100644
index 0000000..3275da9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/Db4objects.Db4o/Internal/BlobImpl.cs
@@ -0,0 +1,46 @@
+/* Copyright (C) 2009  Versant Inc.  http://www.db4o.com */
+
+#if SILVERLIGHT
+
+namespace Db4objects.Db4o.Internal
+{
+	public class BlobImpl : IDb4oTypeImpl
+	{
+		public void SetTrans(Transaction a_trans)
+		{
+			throw new System.NotImplementedException();
+		}
+
+		public bool CanBind()
+		{
+			throw new System.NotImplementedException();
+		}
+
+		public object CreateDefault(Transaction trans)
+		{
+			throw new System.NotImplementedException();
+		}
+
+		public bool HasClassIndex()
+		{
+			throw new System.NotImplementedException();
+		}
+
+		public void SetObjectReference(ObjectReference @ref)
+		{
+			throw new System.NotImplementedException();
+		}
+
+		public object StoredTo(Transaction trans)
+		{
+			throw new System.NotImplementedException();
+		}
+
+		public void PreDeactivate()
+		{
+			throw new System.NotImplementedException();
+		}
+	}
+}
+
+#endif
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Silverlight/System/Collections/ArrayList.cs b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/System/Collections/ArrayList.cs
new file mode 100644
index 0000000..91d80ce
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/System/Collections/ArrayList.cs
@@ -0,0 +1,20 @@
+/* Copyright (C) 2009   Versant Inc.   http://www.db4o.com */
+#if SILVERLIGHT
+
+using System.Collections.Generic;
+
+namespace System.Collections
+{
+	public class ArrayList : List<object>
+	{
+		public ArrayList(int capacity) : base(capacity)
+		{
+		}
+
+		public ArrayList()
+		{
+		}
+	}
+}
+
+#endif
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Silverlight/System/Collections/Hashtable.cs b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/System/Collections/Hashtable.cs
new file mode 100644
index 0000000..78b233d
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/System/Collections/Hashtable.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2009   Versant Inc.   http://www.db4o.com */
+#if SILVERLIGHT
+
+using System.Collections.Generic;
+
+namespace System.Collections
+{
+	public class Hashtable : Dictionary<object, object>
+	{
+		public Hashtable()
+		{
+		}
+
+		public Hashtable(int capacity) : base(capacity)
+		{
+		}
+
+		public bool Contains(object key)
+		{
+			return ContainsKey(key);
+		}
+	}
+}
+
+#endif
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Silverlight/System/NonSerialized.cs b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/System/NonSerialized.cs
new file mode 100644
index 0000000..6b5a898
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/System/NonSerialized.cs
@@ -0,0 +1,12 @@
+/* Copyright (C) 2009   Versant Inc.   http://www.db4o.com */
+
+using Db4objects.Db4o;
+
+#if SILVERLIGHT
+namespace System
+{
+	public class NonSerialized : TransientAttribute
+	{
+	}
+}
+#endif
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/Silverlight/System/Serializable.cs b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/System/Serializable.cs
new file mode 100644
index 0000000..6c1e2f9
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/Silverlight/System/Serializable.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2009   Versant Inc.   http://www.db4o.com */
+
+#if SILVERLIGHT
+namespace System
+{
+	public class Serializable : Attribute
+	{
+	}
+}
+#endif
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/compact/Lock4.cs b/lib/db4o-net/Db4objects.Db4o/native/compact/Lock4.cs
new file mode 100644
index 0000000..7d8f96c
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/compact/Lock4.cs
@@ -0,0 +1,121 @@
+/* Copyright (C) 2009 Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Threading;
+
+namespace Db4objects.Db4o.Foundation
+{
+#if CF
+    public class Lock4
+    {
+        private volatile Thread lockedByThread;
+
+        private volatile Thread waitReleased;
+        private volatile Thread closureReleased;
+
+    	readonly AutoResetEvent waitEvent = new AutoResetEvent(false);
+    	readonly AutoResetEvent closureEvent = new AutoResetEvent(false);
+
+		public void Awake()
+		{
+			AwakeWait();
+		}
+
+		public Object Run(IClosure4 closure4)
+        {
+			EnterClosure();
+            try
+            {
+                return closure4.Run();
+            }
+            finally
+            {
+                AwakeClosure();
+            }
+        }
+
+		public void Snooze(long timeout)
+		{
+			AwakeClosure();
+			WaitWait(timeout);
+			EnterClosure();
+		}
+
+		private void EnterClosure()
+		{
+			while (lockedByThread != Thread.CurrentThread)
+			{
+				while (!SetLock())
+				{
+					WaitClosure();
+				}
+			}
+		}
+
+		private void AwakeClosure()
+        {
+            lock (this)
+            {
+                RemoveLock();
+                closureReleased = Thread.CurrentThread;
+                closureEvent.Set();
+                Thread.Sleep(0);
+                if (closureReleased == Thread.CurrentThread)
+                {
+                    closureEvent.Reset();
+                }
+            }
+        }
+
+		private void AwakeWait()
+		{
+			lock (this)
+			{
+				waitReleased = Thread.CurrentThread;
+				waitEvent.Set();
+				Thread.Sleep(0);
+				if (waitReleased == Thread.CurrentThread)
+				{
+					waitEvent.Reset();
+				}
+			}
+		}
+
+		private void WaitWait(long timeout)
+        {
+        	waitEvent.WaitOne((int) timeout, false);
+            waitReleased = Thread.CurrentThread;
+        }
+
+        private void WaitClosure()
+        {
+            closureEvent.WaitOne();
+            closureReleased = Thread.CurrentThread;
+        }
+
+        private bool SetLock()
+        {
+            lock (this)
+            {
+                if (lockedByThread == null)
+                {
+                    lockedByThread = Thread.CurrentThread;
+                    return true;
+                }
+                return false;
+            }
+        }
+
+        private void RemoveLock()
+        {
+            lock (this)
+            {
+                if (lockedByThread == Thread.CurrentThread)
+                {
+                    lockedByThread = null;
+                }
+            }
+        }
+    }
+#endif
+}
\ No newline at end of file
diff --git a/lib/db4o-net/Db4objects.Db4o/native/net/Compat.cs b/lib/db4o-net/Db4objects.Db4o/native/net/Compat.cs
new file mode 100644
index 0000000..8a52b14
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/net/Compat.cs
@@ -0,0 +1,10 @@
+/* Copyright (C) 2005   Versant Inc.   http://www.db4o.com */
+namespace Db4objects.Db4o
+{
+#if !CF
+	/// <exclude />
+	public class Compat
+	{	
+	}
+#endif
+}
diff --git a/lib/db4o-net/Db4objects.Db4o/native/net/Lock4.cs b/lib/db4o-net/Db4objects.Db4o/native/net/Lock4.cs
new file mode 100644
index 0000000..9cd8276
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/net/Lock4.cs
@@ -0,0 +1,30 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+
+using System;
+using System.Threading;
+
+#if !CF
+namespace Db4objects.Db4o.Foundation
+{
+    public class Lock4
+    {    
+        public void Awake()
+        {
+            Monitor.Pulse(this);
+        }
+
+        public Object Run(IClosure4 closure)
+        {
+            lock (this)
+            {
+                return closure.Run();
+            }
+        }
+    
+        public void Snooze(long timeout)
+        {
+            Monitor.Wait(this, (int)timeout);
+        }
+    }
+}
+#endif
diff --git a/lib/db4o-net/Db4objects.Db4o/native/net/SerializationConstructor.cs b/lib/db4o-net/Db4objects.Db4o/native/net/SerializationConstructor.cs
new file mode 100644
index 0000000..75aca93
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/net/SerializationConstructor.cs
@@ -0,0 +1,32 @@
+/* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
+using System;
+using Db4objects.Db4o.Reflect.Core;
+
+namespace Db4objects.Db4o.Reflect.Net
+{
+#if !CF && !SILVERLIGHT
+	/// <summary>Constructs objects by using System.Runtime.Serialization.FormatterServices.GetUninitializedObject
+	/// and bypasses calls to user contructors this way. Not available on CompactFramework
+	/// </summary>
+	public class SerializationConstructor : IReflectConstructor
+	{
+        private Type _type;
+
+		public SerializationConstructor(Type type){
+            _type = type;
+		}
+
+        public virtual IReflectClass[] GetParameterTypes() {
+            return null;
+        }
+
+#if NET_4_0
+		[System.Security.SecurityCritical]
+#endif		
+        public virtual object NewInstance(object[] parameters) {
+            return System.Runtime.Serialization.FormatterServices.GetUninitializedObject(_type);
+        }
+	}
+#endif
+}
+
diff --git a/lib/db4o-net/Db4objects.Db4o/native/net/TSerializable.cs b/lib/db4o-net/Db4objects.Db4o/native/net/TSerializable.cs
new file mode 100644
index 0000000..a2980c4
--- /dev/null
+++ b/lib/db4o-net/Db4objects.Db4o/native/net/TSerializable.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2004   Versant Inc.   http://www.db4o.com */
+using System;
+using System.IO;
+
+using Sharpen.Lang;
+using Db4objects.Db4o.Config;
+
+namespace Db4objects.Db4o.Config
+{
+#if !CF && !SILVERLIGHT
+	using System.Runtime.Serialization;
+	using System.Runtime.Serialization.Formatters.Binary;
+
+	/// <summary>
+	/// translator for types that are marked with the Serializable attribute.
+	/// The Serializable translator is provided to allow persisting objects that
+	/// do not supply a convenient constructor. The use of this translator is
+	/// recommended only if:<br />
+	/// - the persistent type will never be refactored<br />
+	/// - querying for type members is not necessary<br />
+	/// </summary>
+	public class TSerializable : IObjectConstructor
+	{
+		public Object OnStore(IObjectContainer objectContainer, Object obj)
+		{
+			MemoryStream memoryStream = new MemoryStream();
+			new BinaryFormatter().Serialize(memoryStream, obj);
+			return memoryStream.GetBuffer();
+		}
+
+		public void OnActivate(IObjectContainer objectContainer, Object obj, Object members)
+		{
+		}
+
+		public Object OnInstantiate(IObjectContainer objectContainer, Object obj)
+		{
+			MemoryStream memoryStream = new MemoryStream((byte[])obj);
+			return new BinaryFormatter().Deserialize(memoryStream);
+		}
+
+		public System.Type StoredClass()
+		{
+			return typeof(byte[]);
+		}
+
+	}
+#endif
+}
diff --git a/lib/jabber-net/2005-jabber-net.csproj b/lib/jabber-net/2005-jabber-net.csproj
new file mode 100644
index 0000000..c375385
--- /dev/null
+++ b/lib/jabber-net/2005-jabber-net.csproj
@@ -0,0 +1,481 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+  <PropertyGroup>
+    <ProjectType>Local</ProjectType>
+    <ProductVersion>8.0.50727</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{6CAE854A-F202-4D2B-B10E-E8D8E81E5EF5}</ProjectGuid>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ApplicationIcon>
+    </ApplicationIcon>
+    <AssemblyKeyContainerName>
+    </AssemblyKeyContainerName>
+    <AssemblyName>jabber-net</AssemblyName>
+    <AssemblyOriginatorKeyFile>jabbernet.key</AssemblyOriginatorKeyFile>
+    <DefaultClientScript>JScript</DefaultClientScript>
+    <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+    <DefaultTargetSchema>IE50</DefaultTargetSchema>
+    <DelaySign>false</DelaySign>
+    <OutputType>Library</OutputType>
+    <RootNamespace>
+    </RootNamespace>
+    <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+    <StartupObject>
+    </StartupObject>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <SignAssembly>true</SignAssembly>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <OutputPath>bin5\Debug\</OutputPath>
+    <BaseIntermediateOutputPath>obj5\</BaseIntermediateOutputPath>
+    <IntermediateOutputPath>obj5\Debug\</IntermediateOutputPath>
+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+    <BaseAddress>285212672</BaseAddress>
+    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+    <ConfigurationOverrideFile>
+    </ConfigurationOverrideFile>
+    <DefineConstants Condition="'$(BuildMono)'==''">TRACE;DEBUG;NET20 NO_SRV</DefineConstants>
+    <DefineConstants Condition="'$(BuildMono)'=='true'">TRACE;DEBUG;NO_SRV</DefineConstants>
+    <DocumentationFile>2005-jabber-net.xml</DocumentationFile>
+    <DebugSymbols>true</DebugSymbols>
+    <FileAlignment>4096</FileAlignment>
+    <NoStdLib>false</NoStdLib>
+    <NoWarn>
+    </NoWarn>
+    <Optimize>false</Optimize>
+    <RegisterForComInterop>false</RegisterForComInterop>
+    <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <WarningLevel>4</WarningLevel>
+    <DebugType>full</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <OutputPath>bin5\Release\</OutputPath>
+    <BaseIntermediateOutputPath>obj5\</BaseIntermediateOutputPath>
+    <IntermediateOutputPath>obj5\Debug\</IntermediateOutputPath>
+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+    <BaseAddress>285212672</BaseAddress>
+    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+    <ConfigurationOverrideFile>
+    </ConfigurationOverrideFile>
+    <DefineConstants Condition="'$(BuildMono)'==''">TRACE;NET20 NO_SRV</DefineConstants>
+    <DefineConstants Condition="'$(BuildMono)'=='true'">TRACE;NO_SRV</DefineConstants>
+    <DocumentationFile>2005-jabber-net.xml</DocumentationFile>
+    <DebugSymbols>false</DebugSymbols>
+    <FileAlignment>4096</FileAlignment>
+    <NoStdLib>false</NoStdLib>
+    <NoWarn>
+    </NoWarn>
+    <Optimize>true</Optimize>
+    <RegisterForComInterop>false</RegisterForComInterop>
+    <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <WarningLevel>4</WarningLevel>
+    <DebugType>none</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <ItemGroup Condition="'$(BuildMono)'==''">
+    <Reference Include="System">
+      <Name>System</Name>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Security" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml">
+      <Name>System.XML</Name>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AssemblyInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\collections\ByteStack.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\collections\GraphNode.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\collections\IndexedTrie.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\collections\ISet.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\collections\LinkedList.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\collections\Set.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\collections\SkipList.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\collections\StringSet.cs" />
+    <Compile Include="bedrock\collections\Tree.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\collections\Trie.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\collections\TrieNode.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\Delegates.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\io\BufferAggregate.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\client\BookmarkManager.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="jabber\connection\FileMap.cs" />
+    <Compile Include="bedrock\io\ReadEventStream.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\io\ZlibStream.cs" />
+    <Compile Include="bedrock\net\Address.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\net\AsyncSocket.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\net\BaseSocket.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\net\Exceptions.cs" />
+    <Compile Include="bedrock\net\HttpSocket.cs" />
+    <Compile Include="bedrock\net\IHttpSocket.cs" />
+    <Compile Include="bedrock\net\ProxySocket.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\net\ShttpProxy.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\net\SocketEventListener.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\net\SocketWatcher.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\net\Socks4Proxy.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\net\Socks5Proxy.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\net\XEP124Socket.cs" />
+    <Compile Include="bedrock\net\XEP25Socket.cs" />
+    <Compile Include="bedrock\util\ConfigFile.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\util\GetOptBase.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="bedrock\util\IdleTime.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="bedrock\util\Version.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\connection\BindingStanzaStream.cs" />
+    <Compile Include="jabber\connection\CapsManager.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="jabber\connection\CertificatePrompt.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="jabber\connection\ConferenceManager.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="jabber\connection\DiscoManager.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="jabber\client\JabberClient.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="jabber\client\PresenceManager.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="jabber\client\RosterManager.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="jabber\connection\HttpStanzaStream.cs" />
+    <Compile Include="jabber\connection\HttpUploader.cs" />
+    <Compile Include="jabber\connection\IQTracker.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\connection\PollingStanzaStream.cs" />
+    <Compile Include="jabber\connection\PubSubManager.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="jabber\connection\sasl\ExternalProcessor.cs" />
+    <Compile Include="jabber\connection\sasl\KerbProcessor.cs" />
+    <Compile Include="jabber\connection\sasl\MD5Processor.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\connection\sasl\PlainProcessor.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\connection\sasl\SASLProcessor.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\connection\StreamComponent.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="jabber\connection\XmppStream.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="jabber\connection\SocketStanzaStream.cs" />
+    <Compile Include="jabber\connection\StanzaStream.cs" />
+    <Compile Include="jabber\connection\States.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\JID.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\accept\Factory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\accept\Handshake.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\accept\Log.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\accept\Route.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\accept\Xdb.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\AsynchElementStream.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\client\Error.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\client\Factory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\client\IQ.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\client\Message.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\client\Presence.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\client\ProtocolException.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\Element.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\ElementFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\ElementList.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\ElementStream.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\EnumParser.cs" />
+    <Compile Include="jabber\protocol\iq\Agents.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\iq\Auth.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\iq\Bookmarks.cs" />
+    <Compile Include="jabber\protocol\iq\Browse.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\iq\Disco.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\iq\Factory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\iq\GeoLoc.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\iq\Last.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\iq\MUC.cs">
+    </Compile>
+    <Compile Include="jabber\protocol\iq\OOB.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\iq\Private.cs" />
+    <Compile Include="jabber\protocol\iq\PubSub.cs" />
+    <Compile Include="jabber\protocol\iq\PubSubErrors.cs" />
+    <Compile Include="jabber\protocol\iq\PubSubEvent.cs" />
+    <Compile Include="jabber\protocol\iq\PubSubOwner.cs" />
+    <Compile Include="jabber\protocol\iq\Register.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\iq\Roster.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\iq\Time.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\iq\VCard.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\iq\Version.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\NS.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\Packet.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\stream\Bind.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\stream\Compression.cs" />
+    <Compile Include="jabber\protocol\stream\Error.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\stream\Factory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\stream\Features.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\stream\HttpBind.cs" />
+    <Compile Include="jabber\protocol\stream\SASL.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\stream\Session.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\stream\StartTLS.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\stream\Stream.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\URI.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\x\Caps.cs" />
+    <Compile Include="jabber\protocol\x\Data.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\x\Delay.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\x\Event.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\protocol\x\Factory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="jabber\server\JabberService.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="jabber\server\XdbTracker.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="stringprep\Nameprep.cs" />
+    <Compile Include="stringprep\Plain.cs" />
+    <Compile Include="stringprep\Profile.cs" />
+    <Compile Include="stringprep\steps\BidiStep.cs" />
+    <Compile Include="stringprep\steps\MapStep.cs" />
+    <Compile Include="stringprep\steps\NFKCStep.cs" />
+    <Compile Include="stringprep\steps\ProfileStep.cs" />
+    <Compile Include="stringprep\steps\ProhibitStep.cs" />
+    <Compile Include="stringprep\steps\RFC3454.cs" />
+    <Compile Include="stringprep\unicode\Combining.cs" />
+    <Compile Include="stringprep\unicode\CombiningData.cs" />
+    <Compile Include="stringprep\unicode\Compose.cs" />
+    <Compile Include="stringprep\unicode\ComposeData.cs" />
+    <Compile Include="stringprep\unicode\Decompose.cs" />
+    <Compile Include="stringprep\unicode\DecomposeData.cs" />
+    <Compile Include="stringprep\XmppNode.cs" />
+    <Compile Include="stringprep\XmppResource.cs" />
+    <Compile Include="xpnet\ContentToken.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="xpnet\Encoding.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="xpnet\Exceptions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="xpnet\Position.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="xpnet\Token.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="xpnet\UTF8Encoding.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <EmbeddedResource Include="jabber\client\JabberClient.bmp" />
+    <EmbeddedResource Include="jabber\client\JabberClient.resx">
+      <DependentUpon>JabberClient.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="jabber\client\PresenceManager.bmp" />
+    <EmbeddedResource Include="jabber\client\RosterManager.bmp" />
+    <EmbeddedResource Include="jabber\client\RosterManager.resx">
+      <DependentUpon>RosterManager.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="jabber\connection\XmppStream.resx">
+      <DependentUpon>XmppStream.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="jabber\server\JabberService.bmp" />
+    <EmbeddedResource Include="jabber\server\JabberService.resx">
+      <DependentUpon>JabberService.cs</DependentUpon>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="jabbernet.key" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="jabber\connection\DiscoManager.bmp" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="jabber\connection\CapsManager.bmp" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="jabber\connection\PubSubManager.bmp" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="jabber\connection\CertificatePrompt.resx">
+      <SubType>Designer</SubType>
+      <DependentUpon>CertificatePrompt.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="jabber\connection\ConferenceManager.bmp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Condition="'$(BuildMono)'==''" Include="netlib.Dns\netlib.Dns.csproj">
+      <Project>{40AC7A7C-D3E5-46DF-B740-06BD9D2A00E1}</Project>
+      <Name>netlib.Dns</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="System.Data" />
+  </ItemGroup>
+  <Import Condition="'$(BuildMono)'==''" Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>
+    </PreBuildEvent>
+    <PostBuildEvent>
+    </PostBuildEvent>
+    <SignAssembly>false</SignAssembly>
+  </PropertyGroup>
+</Project>
diff --git a/lib/jabber-net/AssemblyInfo.cs b/lib/jabber-net/AssemblyInfo.cs
new file mode 100644
index 0000000..fe41d25
--- /dev/null
+++ b/lib/jabber-net/AssemblyInfo.cs
@@ -0,0 +1,24 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:2.0.50727.1433
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Jabber-Net library")]
+[assembly: AssemblyDescription("Connect to Jabber (http://www.jabber.org/) from .Net")]
+[assembly: AssemblyCompany("Cursive Systems, Inc.")]
+[assembly: AssemblyProduct("jabber-net")]
+[assembly: AssemblyCopyright("Copyright (c) Cursive, Inc. 2000-2008")]
+[assembly: AssemblyVersion("2.0.0.613")]
+[assembly: AssemblyDelaySign(false)]
+[assembly: CLSCompliant(true)]
+
diff --git a/lib/jabber-net/ConsoleClient/AssemblyInfo.cs b/lib/jabber-net/ConsoleClient/AssemblyInfo.cs
new file mode 100644
index 0000000..ba2e543
--- /dev/null
+++ b/lib/jabber-net/ConsoleClient/AssemblyInfo.cs
@@ -0,0 +1,71 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly: AssemblyTitle("ConsoleClient")]
+[assembly: AssemblyDescription("Jabber-net console client example")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Cursive Systems, Inc.")]
+[assembly: AssemblyProduct("jnExample")]
+[assembly: AssemblyCopyright("Copyright (c) Cursive Systems, 2000-2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+//
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly: AssemblyVersion("1.0.*")]
+
+//
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly signing.
+//
+// Use the attributes below to control which key is used for signing.
+//
+// Notes:
+//   (*) If no key is specified, the assembly is not signed.
+//   (*) KeyName refers to a key that has been installed in the Crypto Service
+//       Provider (CSP) on your machine. KeyFile refers to a file which contains
+//       a key.
+//   (*) If the KeyFile and the KeyName values are both specified, the
+//       following processing occurs:
+//       (1) If the KeyName can be found in the CSP, that key is used.
+//       (2) If the KeyName does not exist and the KeyFile does exist, the key
+//           in the KeyFile is installed into the CSP and used.
+//   (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
+//       When specifying the KeyFile, the location of the KeyFile should be
+//       relative to the project output directory which is
+//       %Project Directory%\obj\<configuration>. For example, if your KeyFile is
+//       located in the project directory, you would specify the AssemblyKeyFile
+//       attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
+//   (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
+//       documentation for more information on this.
+//
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyKeyName("")]
diff --git a/lib/jabber-net/ConsoleClient/Main.cs b/lib/jabber-net/ConsoleClient/Main.cs
new file mode 100644
index 0000000..76ba6fe
--- /dev/null
+++ b/lib/jabber-net/ConsoleClient/Main.cs
@@ -0,0 +1,229 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Threading;
+using System.Xml;
+
+using bedrock.util;
+using jabber;
+using jabber.client;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+using jabber.connection;
+
+namespace ConsoleClient
+{
+    /// <summary>
+    /// Summary description for Class1.
+    /// </summary>
+    [SVN(@"$Id$")]
+    class Class1
+    {
+        [CommandLine("j", "user at host Jabber ID", true)]
+        public string jid = null;
+
+        [CommandLine("p", "Password", false)]
+        public string pass = null;
+
+        [CommandLine("n", "Network Host", false)]
+        public string networkHost = null;
+
+        [CommandLine("o", "Port", false)]
+        public int port = 5222;
+
+        [CommandLine("t", "TLS auto-start", false)]
+        public bool TLS = true;
+
+        [CommandLine("r", "Register user", false)]
+        public bool register = false;
+
+        [CommandLine("c", "Certificate file", false)]
+        public string certificateFile = null;
+
+        [CommandLine("w", "Certificate password", false)]
+        public string certificatePass = "";
+
+        [CommandLine("u", "Untrusted certificates OK", false)]
+        public bool untrustedOK = false;
+
+        [CommandLine("i", "Do not send initial presence", false)]
+        public bool initialPresence = true;
+
+        [CommandLine("b", "HTTP Binding (BOSH) URL", false)]
+        public string boshURL = null;
+
+        public Class1(string[] args)
+        {
+            JabberClient jc = new JabberClient();
+            jc.OnReadText += new bedrock.TextHandler(jc_OnReadText);
+            jc.OnWriteText += new bedrock.TextHandler(jc_OnWriteText);
+            jc.OnError +=new bedrock.ExceptionHandler(jc_OnError);
+            jc.OnStreamError += new jabber.protocol.ProtocolHandler(jc_OnStreamError);
+
+            jc.AutoReconnect = 3f;
+
+            GetOpt go = new GetOpt(this);
+            try
+            {
+                go.Process(args);
+            }
+            catch (ArgumentException)
+            {
+                go.UsageExit();
+            }
+
+            if (untrustedOK)
+                jc.OnInvalidCertificate += new System.Net.Security.RemoteCertificateValidationCallback(jc_OnInvalidCertificate);
+
+            JID j = new JID(jid);
+            jc.User = j.User;
+            jc.Server = j.Server;
+            jc.NetworkHost = networkHost;
+            jc.Port = port;
+            jc.Resource = "Jabber.Net Console Client";
+            jc.Password = pass;
+            jc.AutoStartTLS = TLS;
+            jc.AutoPresence = initialPresence;
+
+            if (certificateFile != null)
+            {
+                jc.SetCertificateFile(certificateFile, certificatePass);
+                Console.WriteLine(jc.LocalCertificate.ToString(true));
+            }
+
+            if (boshURL != null)
+            {
+                jc[Options.POLL_URL] = boshURL;
+                jc[Options.CONNECTION_TYPE] = ConnectionType.HTTP_Binding;
+            }
+            
+            if (register)
+            {
+                jc.AutoLogin = false;
+                jc.OnLoginRequired +=
+                    new bedrock.ObjectHandler(jc_OnLoginRequired);
+                jc.OnRegisterInfo += new RegisterInfoHandler(this.jc_OnRegisterInfo);
+                jc.OnRegistered += new IQHandler(jc_OnRegistered);
+            }
+
+            CapsManager cm = new CapsManager();
+            cm.Stream = jc;
+            cm.Node = "http://cursive.net/clients/ConsoleClient";
+            
+            Console.WriteLine("Connecting");
+            jc.Connect();
+            Console.WriteLine("Connected");
+
+            string line;
+            while ((line = Console.ReadLine()) != null)
+            {
+                if (line == "/clear")
+                {
+                    // Hm.... I wonder if this works on windows.
+                    Console.Write("\x1b[H\x1b[2J");
+                    continue;
+                }
+                if ((line == "/q") || (line == "/quit"))
+                {
+                    jc.Close();
+                    break;
+                }
+                if (line.Trim() == "")
+                {
+                    continue;
+                }
+                try
+                {
+                    if (line == "</stream:stream>")
+                    {
+                        jc.Write(line);
+                    }
+                    else
+                    {
+                        // TODO: deal with stanzas that span lines... keep
+                        // parsing until we have a full "doc".
+                        XmlDocument doc = new XmlDocument();
+                        doc.LoadXml(line);
+                        XmlElement elem = doc.DocumentElement;
+                        if (elem != null)
+                            jc.Write(elem);
+                    }
+                }
+                catch (XmlException ex)
+                {
+                    Console.WriteLine("Invalid XML: " + ex.Message);
+                }
+            }
+        }
+
+        bool jc_OnInvalidCertificate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
+        {
+            Console.WriteLine("Invalid certificate ({0}):\n{1}", sslPolicyErrors.ToString(), certificate.ToString(true));
+            return true;
+        }
+
+        /// <summary>
+        /// The main entry point for the application.
+        /// </summary>
+        [STAThread]
+        static void Main(string[] args)
+        {
+            new Class1(args);
+        }
+
+        private void jc_OnReadText(object sender, string txt)
+        {
+            if (txt != " ")
+                Console.WriteLine("RECV: " + txt);
+        }
+
+        private void jc_OnWriteText(object sender, string txt)
+        {
+            if (txt != " ")
+                Console.WriteLine("SENT: " + txt);
+        }
+
+        private void jc_OnError(object sender, Exception ex)
+        {
+            Console.WriteLine("ERROR: " + ex.ToString());
+            Environment.Exit(1);
+        }
+
+        private void jc_OnStreamError(object sender, System.Xml.XmlElement rp)
+        {
+            Console.WriteLine("Stream ERROR: " + rp.OuterXml);
+            Environment.Exit(1);
+        }
+
+        private void jc_OnLoginRequired(object sender)
+        {
+            Console.WriteLine("Registering");
+            JabberClient jc = (JabberClient) sender;
+            jc.Register(new JID(jc.User, jc.Server, null));
+        }
+
+        private void jc_OnRegistered(object sender,
+                                     IQ iq)
+        {
+            JabberClient jc = (JabberClient) sender;
+            if (iq.Type == IQType.result)
+                jc.Login();
+        }
+
+        private bool jc_OnRegisterInfo(object sender, Register r)
+        {
+            return true;
+        }
+    }
+}
diff --git a/lib/jabber-net/Example/AddContact.cs b/lib/jabber-net/Example/AddContact.cs
new file mode 100644
index 0000000..2d871bd
--- /dev/null
+++ b/lib/jabber-net/Example/AddContact.cs
@@ -0,0 +1,325 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+
+using bedrock.util;
+using jabber;
+
+namespace Example
+{
+    [SVN(@"$Id$")]
+    public class AddContact : Form
+    {
+
+        private Label label1;
+        private TextBox txtJID;
+        private Label label2;
+        private TextBox txtNickname;
+        private Label label3;
+        private CheckedListBox lbGroups;
+        private Button btnOK;
+        private Button btnCancel;
+        private TextBox txtGroup;
+        private Button btnAdd;
+
+        private string m_domain = null;
+
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        public AddContact()
+        {
+            InitializeComponent();
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        /// <summary>
+        /// The Jabber ID to subscribe to.
+        /// </summary>
+        public JID JID
+        {
+            get
+            {
+                return new JID(txtJID.Text);
+            }
+            set
+            {
+                txtJID.Text = value.ToString();
+            }
+        }
+
+        public string Nickname
+        {
+            get
+            {
+                return txtNickname.Text;
+            }
+            set
+            {
+                txtNickname.Text = value;
+            }
+        }
+
+        /// <summary>
+        /// All of the groups, checked or not.
+        /// </summary>
+        public string[] AllGroups
+        {
+            get
+            {
+                string[] items = new string[lbGroups.Items.Count];
+                lbGroups.Items.CopyTo(items, 0);
+                return items;
+            }
+            set
+            {
+                lbGroups.BeginUpdate();
+                lbGroups.Items.Clear();
+                lbGroups.Items.AddRange(value);
+                lbGroups.EndUpdate();
+            }
+        }
+
+        /// <summary>
+        /// The groups that have been selected
+        /// </summary>
+        public string[] SelectedGroups
+        {
+            get
+            {
+                string[] items = new string[lbGroups.CheckedItems.Count];
+                lbGroups.CheckedItems.CopyTo(items, 0);
+                return items;
+            }
+            set
+            {
+                lbGroups.BeginUpdate();
+                lbGroups.ClearSelected();
+                for (int i=0; i<lbGroups.Items.Count; i++ )
+                {
+                    for (int j=0; j<value.Length; j++)
+                    {
+                        if (((string)lbGroups.Items[i]) == value[j])
+                        {
+                            lbGroups.SetItemChecked(i, true);
+                        }
+                    }
+                }
+                lbGroups.EndUpdate();
+            }
+        }
+
+        /// <summary>
+        /// Use this domain, if one isn't provided in the JID.
+        /// </summary>
+        public string DefaultDomain
+        {
+            get { return m_domain; }
+            set { m_domain = value; }
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.txtJID = new System.Windows.Forms.TextBox();
+            this.label2 = new System.Windows.Forms.Label();
+            this.txtNickname = new System.Windows.Forms.TextBox();
+            this.label3 = new System.Windows.Forms.Label();
+            this.lbGroups = new System.Windows.Forms.CheckedListBox();
+            this.btnOK = new System.Windows.Forms.Button();
+            this.btnCancel = new System.Windows.Forms.Button();
+            this.txtGroup = new System.Windows.Forms.TextBox();
+            this.btnAdd = new System.Windows.Forms.Button();
+            this.SuspendLayout();
+            //
+            // label1
+            //
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(54, 9);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(26, 13);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "JID:";
+            //
+            // txtJID
+            //
+            this.txtJID.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtJID.Location = new System.Drawing.Point(86, 6);
+            this.txtJID.Name = "txtJID";
+            this.txtJID.Size = new System.Drawing.Size(269, 20);
+            this.txtJID.TabIndex = 1;
+            this.txtJID.Leave += new System.EventHandler(this.txtJID_Leave);
+            //
+            // label2
+            //
+            this.label2.AutoSize = true;
+            this.label2.Location = new System.Drawing.Point(22, 35);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(58, 13);
+            this.label2.TabIndex = 2;
+            this.label2.Text = "Nickname:";
+            //
+            // txtNickname
+            //
+            this.txtNickname.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtNickname.Location = new System.Drawing.Point(86, 32);
+            this.txtNickname.Name = "txtNickname";
+            this.txtNickname.Size = new System.Drawing.Size(269, 20);
+            this.txtNickname.TabIndex = 3;
+            //
+            // label3
+            //
+            this.label3.AutoSize = true;
+            this.label3.Location = new System.Drawing.Point(36, 58);
+            this.label3.Name = "label3";
+            this.label3.Size = new System.Drawing.Size(44, 13);
+            this.label3.TabIndex = 4;
+            this.label3.Text = "Groups:";
+            //
+            // lbGroups
+            //
+            this.lbGroups.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.lbGroups.Location = new System.Drawing.Point(86, 58);
+            this.lbGroups.Name = "lbGroups";
+            this.lbGroups.Size = new System.Drawing.Size(269, 124);
+            this.lbGroups.Sorted = true;
+            this.lbGroups.TabIndex = 5;
+            //
+            // btnOK
+            //
+            this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
+            this.btnOK.Location = new System.Drawing.Point(199, 215);
+            this.btnOK.Name = "btnOK";
+            this.btnOK.Size = new System.Drawing.Size(75, 23);
+            this.btnOK.TabIndex = 8;
+            this.btnOK.Text = "OK";
+            //
+            // btnCancel
+            //
+            this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+            this.btnCancel.Location = new System.Drawing.Point(280, 216);
+            this.btnCancel.Name = "btnCancel";
+            this.btnCancel.Size = new System.Drawing.Size(75, 23);
+            this.btnCancel.TabIndex = 9;
+            this.btnCancel.Text = "Cancel";
+            //
+            // txtGroup
+            //
+            this.txtGroup.Location = new System.Drawing.Point(86, 190);
+            this.txtGroup.Name = "txtGroup";
+            this.txtGroup.Size = new System.Drawing.Size(269, 20);
+            this.txtGroup.TabIndex = 6;
+            this.txtGroup.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txtGroup_KeyDown);
+            //
+            // btnAdd
+            //
+            this.btnAdd.Location = new System.Drawing.Point(12, 188);
+            this.btnAdd.Name = "btnAdd";
+            this.btnAdd.Size = new System.Drawing.Size(68, 23);
+            this.btnAdd.TabIndex = 7;
+            this.btnAdd.Text = "Add Group";
+            this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click);
+            //
+            // AddContact
+            //
+            this.AcceptButton = this.btnOK;
+            this.CancelButton = this.btnCancel;
+            this.ClientSize = new System.Drawing.Size(367, 250);
+            this.Controls.Add(this.btnAdd);
+            this.Controls.Add(this.txtGroup);
+            this.Controls.Add(this.btnCancel);
+            this.Controls.Add(this.btnOK);
+            this.Controls.Add(this.lbGroups);
+            this.Controls.Add(this.label3);
+            this.Controls.Add(this.txtNickname);
+            this.Controls.Add(this.label2);
+            this.Controls.Add(this.txtJID);
+            this.Controls.Add(this.label1);
+            this.Name = "AddContact";
+            this.Text = "Add Contact";
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private void btnAdd_Click(object sender, EventArgs e)
+        {
+            string g = txtGroup.Text.Trim();
+            if (g != "")
+            {
+                int item = lbGroups.Items.Add(g, true);
+                lbGroups.TopIndex = item;
+                txtGroup.Clear();
+            }
+        }
+
+        private void txtGroup_KeyDown(object sender, KeyEventArgs e)
+        {
+            // TODO: this doesn't actually work.
+            if (e.KeyCode == Keys.Return)
+            {
+                btnAdd_Click(null, null);
+#if NET_20
+                e.SuppressKeyPress = true;
+#endif
+            }
+        }
+
+        private void txtJID_Leave(object sender, EventArgs e)
+        {
+            if (!txtJID.Text.Contains("@") && (m_domain != null))
+            {
+                txtJID.Text = txtJID.Text + "@" + m_domain;
+            }
+            if (txtNickname.Text == "")
+            {
+                JID jid = new JID(txtJID.Text);
+                txtNickname.Text = jid.User;
+            }
+        }
+
+    }
+}
diff --git a/lib/jabber-net/Example/AddGroup.cs b/lib/jabber-net/Example/AddGroup.cs
new file mode 100644
index 0000000..64d649c
--- /dev/null
+++ b/lib/jabber-net/Example/AddGroup.cs
@@ -0,0 +1,128 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+
+using bedrock.util;
+
+namespace Example
+{
+    [SVN(@"$Id$")]
+    public class AddGroup : Form
+    {
+        private System.Windows.Forms.TextBox textBox1;
+        private System.Windows.Forms.Button btnOK;
+        private System.Windows.Forms.Button btnCancel;
+
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        public AddGroup()
+        {
+            InitializeComponent();
+        }
+
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+
+        /// <summary>
+        /// Get the new group name.
+        /// </summary>
+        public string GroupName
+        {
+            get { return textBox1.Text; }
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.textBox1 = new System.Windows.Forms.TextBox();
+            this.btnOK = new System.Windows.Forms.Button();
+            this.btnCancel = new System.Windows.Forms.Button();
+            this.SuspendLayout();
+            //
+            // textBox1
+            //
+            this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.textBox1.Location = new System.Drawing.Point(12, 12);
+            this.textBox1.Name = "textBox1";
+            this.textBox1.Size = new System.Drawing.Size(176, 20);
+            this.textBox1.TabIndex = 0;
+            //
+            // btnOK
+            //
+            this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
+            this.btnOK.Location = new System.Drawing.Point(32, 38);
+            this.btnOK.Name = "btnOK";
+            this.btnOK.Size = new System.Drawing.Size(75, 23);
+            this.btnOK.TabIndex = 1;
+            this.btnOK.Text = "OK";
+            this.btnOK.UseVisualStyleBackColor = true;
+            //
+            // btnCancel
+            //
+            this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+            this.btnCancel.Location = new System.Drawing.Point(113, 38);
+            this.btnCancel.Name = "btnCancel";
+            this.btnCancel.Size = new System.Drawing.Size(75, 23);
+            this.btnCancel.TabIndex = 2;
+            this.btnCancel.Text = "Cancel";
+            this.btnCancel.UseVisualStyleBackColor = true;
+            //
+            // AddGroup
+            //
+            this.AcceptButton = this.btnOK;
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.CancelButton = this.btnCancel;
+            this.ClientSize = new System.Drawing.Size(200, 70);
+            this.Controls.Add(this.btnCancel);
+            this.Controls.Add(this.btnOK);
+            this.Controls.Add(this.textBox1);
+            this.Name = "AddGroup";
+            this.Text = "Add Group";
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+    }
+}
diff --git a/lib/jabber-net/Example/AssemblyInfo.cs b/lib/jabber-net/Example/AssemblyInfo.cs
new file mode 100644
index 0000000..41a4b8c
--- /dev/null
+++ b/lib/jabber-net/Example/AssemblyInfo.cs
@@ -0,0 +1,72 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System.Reflection;
+
+using System.Runtime.CompilerServices;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly: AssemblyTitle("Example")]
+[assembly: AssemblyDescription("Jabber-net examples")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Cursive Systems, Inc.")]
+[assembly: AssemblyProduct("jnExample")]
+[assembly: AssemblyCopyright("Copyright (c) Cursive Systems, 2000-2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+//
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly: AssemblyVersion("1.0.*")]
+
+//
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly signing.
+//
+// Use the attributes below to control which key is used for signing.
+//
+// Notes:
+//   (*) If no key is specified, the assembly is not signed.
+//   (*) KeyName refers to a key that has been installed in the Crypto Service
+//       Provider (CSP) on your machine. KeyFile refers to a file which contains
+//       a key.
+//   (*) If the KeyFile and the KeyName values are both specified, the
+//       following processing occurs:
+//       (1) If the KeyName can be found in the CSP, that key is used.
+//       (2) If the KeyName does not exist and the KeyFile does exist, the key
+//           in the KeyFile is installed into the CSP and used.
+//   (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
+//       When specifying the KeyFile, the location of the KeyFile should be
+//       relative to the project output directory which is
+//       %Project Directory%\obj\<configuration>. For example, if your KeyFile is
+//       located in the project directory, you would specify the AssemblyKeyFile
+//       attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
+//   (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
+//       documentation for more information on this.
+//
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyKeyName("")]
diff --git a/lib/jabber-net/Example/ConferenceForm.cs b/lib/jabber-net/Example/ConferenceForm.cs
new file mode 100644
index 0000000..a07f3a1
--- /dev/null
+++ b/lib/jabber-net/Example/ConferenceForm.cs
@@ -0,0 +1,253 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+
+using bedrock.util;
+using jabber;
+using jabber.connection;
+
+namespace Example
+{
+    [SVN(@"$Id$")]
+    public class ConferenceForm : Form
+    {
+        private Label label1;
+        private Label label2;
+        private ComboBox cmbJID;
+        private TextBox txtRoom;
+        private Button btnOK;
+        private Button btnCancel;
+
+        private DiscoManager m_disco = null;
+        private TextBox txtNick;
+        private Label label3;
+
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        public ConferenceForm()
+        {
+            InitializeComponent();
+        }
+
+        public DiscoManager DiscoManager
+        {
+            get { return m_disco; }
+            set { m_disco = value; }
+        }
+
+        public JID RoomJID
+        {
+            get
+            {
+                return new JID(txtRoom.Text, cmbJID.Text, null);
+            }
+        }
+
+        public JID RoomAndNick
+        {
+            get
+            {
+                return new JID(txtRoom.Text, cmbJID.Text, txtNick.Text);
+            }
+            set
+            {
+                if (value == null)
+                {
+                    cmbJID.Text = txtRoom.Text = txtNick.Text = "";
+                }
+                else
+                {
+                    cmbJID.Text = value.Server;
+                    txtRoom.Text = value.User;
+                    txtNick.Text = value.Resource;
+                }
+            }
+        }
+
+        public string Nick
+        {
+            get { return txtNick.Text; }
+            set { txtNick.Text = value; }
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.label2 = new System.Windows.Forms.Label();
+            this.cmbJID = new System.Windows.Forms.ComboBox();
+            this.txtRoom = new System.Windows.Forms.TextBox();
+            this.btnOK = new System.Windows.Forms.Button();
+            this.btnCancel = new System.Windows.Forms.Button();
+            this.txtNick = new System.Windows.Forms.TextBox();
+            this.label3 = new System.Windows.Forms.Label();
+            this.SuspendLayout();
+            //
+            // label1
+            //
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(12, 9);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(99, 13);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "Conference Server:";
+            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            //
+            // label2
+            //
+            this.label2.AutoSize = true;
+            this.label2.Location = new System.Drawing.Point(73, 35);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(38, 13);
+            this.label2.TabIndex = 2;
+            this.label2.Text = "Room:";
+            this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            //
+            // cmbJID
+            //
+            this.cmbJID.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.cmbJID.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest;
+            this.cmbJID.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
+            this.cmbJID.Location = new System.Drawing.Point(118, 5);
+            this.cmbJID.Name = "cmbJID";
+            this.cmbJID.Size = new System.Drawing.Size(156, 21);
+            this.cmbJID.TabIndex = 1;
+            //
+            // txtRoom
+            //
+            this.txtRoom.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtRoom.Location = new System.Drawing.Point(118, 32);
+            this.txtRoom.Name = "txtRoom";
+            this.txtRoom.Size = new System.Drawing.Size(156, 20);
+            this.txtRoom.TabIndex = 3;
+            //
+            // btnOK
+            //
+            this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
+            this.btnOK.Location = new System.Drawing.Point(118, 84);
+            this.btnOK.Name = "btnOK";
+            this.btnOK.Size = new System.Drawing.Size(75, 23);
+            this.btnOK.TabIndex = 6;
+            this.btnOK.Text = "OK";
+            this.btnOK.UseVisualStyleBackColor = true;
+            //
+            // btnCancel
+            //
+            this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+            this.btnCancel.Location = new System.Drawing.Point(199, 84);
+            this.btnCancel.Name = "btnCancel";
+            this.btnCancel.Size = new System.Drawing.Size(75, 23);
+            this.btnCancel.TabIndex = 7;
+            this.btnCancel.Text = "Cancel";
+            this.btnCancel.UseVisualStyleBackColor = true;
+            //
+            // txtNick
+            //
+            this.txtNick.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtNick.Location = new System.Drawing.Point(118, 58);
+            this.txtNick.Name = "txtNick";
+            this.txtNick.Size = new System.Drawing.Size(156, 20);
+            this.txtNick.TabIndex = 5;
+            //
+            // label3
+            //
+            this.label3.AutoSize = true;
+            this.label3.Location = new System.Drawing.Point(53, 61);
+            this.label3.Name = "label3";
+            this.label3.Size = new System.Drawing.Size(58, 13);
+            this.label3.TabIndex = 4;
+            this.label3.Text = "Nickname:";
+            this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            //
+            // ConferenceForm
+            //
+            this.AcceptButton = this.btnOK;
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.CancelButton = this.btnCancel;
+            this.ClientSize = new System.Drawing.Size(286, 117);
+            this.Controls.Add(this.txtNick);
+            this.Controls.Add(this.label3);
+            this.Controls.Add(this.btnCancel);
+            this.Controls.Add(this.btnOK);
+            this.Controls.Add(this.txtRoom);
+            this.Controls.Add(this.cmbJID);
+            this.Controls.Add(this.label2);
+            this.Controls.Add(this.label1);
+            this.Name = "ConferenceForm";
+            this.Text = "Join/Create room";
+            this.Shown += new System.EventHandler(this.ConferenceForm_Shown);
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+
+        private void ConferenceForm_Shown(object sender, EventArgs e)
+        {
+            cmbJID.BeginUpdate();
+            cmbJID.Items.Clear();
+            if (m_disco != null)
+                m_disco.BeginGetItems(null, GotRoot, null);
+            else
+                cmbJID.EndUpdate();
+        }
+
+        private void GotRoot(DiscoManager sender, DiscoNode node, object state)
+        {
+            if (node.Children != null)
+            {
+                foreach (DiscoNode component in node.Children)
+                {
+                    if (component.HasFeature(jabber.protocol.URI.MUC))
+                        cmbJID.Items.Add(component.JID);
+                }
+                if (cmbJID.Items.Count > 0)
+                    cmbJID.SelectedIndex = 0;
+            }
+            cmbJID.EndUpdate();
+        }
+    }
+}
diff --git a/lib/jabber-net/Example/MainForm.cs b/lib/jabber-net/Example/MainForm.cs
new file mode 100644
index 0000000..7388757
--- /dev/null
+++ b/lib/jabber-net/Example/MainForm.cs
@@ -0,0 +1,1224 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+
+using System;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Xml;
+using bedrock.util;
+using jabber;
+using jabber.connection;
+using jabber.protocol;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+
+namespace Example
+{
+    /// <summary>
+    /// Summary description for MainForm.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class MainForm : Form
+    {
+        #region Private Members
+
+        private StatusBar sb;
+        private jabber.client.JabberClient jc;
+        private jabber.client.RosterManager rm;
+        private jabber.client.PresenceManager pm;
+        private TabControl tabControl1;
+        private TabPage tpDebug;
+        private TabPage tpRoster;
+        private StatusBarPanel pnlCon;
+        private StatusBarPanel pnlPresence;
+        private ContextMenu mnuPresence;
+        private MenuItem mnuAvailable;
+        private MenuItem mnuAway;
+        private IContainer components;
+        private muzzle.RosterTree roster;
+        private StatusBarPanel pnlSSL;
+        private DiscoManager dm;
+        private TabPage tpServices;
+        private CapsManager cm;
+        private muzzle.XmppDebugger debug;
+        private PubSubManager psm;
+        private MenuStrip menuStrip1;
+        private ToolStripMenuItem fileToolStripMenuItem;
+        private ToolStripMenuItem connectToolStripMenuItem;
+        private ToolStripSeparator toolStripMenuItem1;
+        private ToolStripMenuItem exitToolStripMenuItem;
+        private ToolStripMenuItem viewToolStripMenuItem;
+        private ToolStripMenuItem servicesToolStripMenuItem;
+        private ToolStripMenuItem debugToolStripMenuItem;
+        private ToolStripMenuItem rosterToolStripMenuItem;
+        private ToolStripMenuItem addContactToolStripMenuItem;
+        private ToolStripMenuItem removeContactToolStripMenuItem;
+        private ToolStripMenuItem addGroupToolStripMenuItem;
+        private IdleTime idler;
+        private ServiceDisplay services;
+        private ToolStripMenuItem windowToolStripMenuItem;
+        private ToolStripMenuItem closeTabToolStripMenuItem;
+        private ToolStripMenuItem deletePubSubToolStripMenuItem;
+        private ToolStripMenuItem subscribePubSubToolStripMenuItem;
+        private ToolStripMenuItem pubSubToolStripMenuItem;
+        private ConferenceManager muc;
+        private ToolStripMenuItem joinConferenceToolStripMenuItem;
+
+        private bool m_err = false;
+        private jabber.client.BookmarkManager bmm;
+        private TabPage tpBookmarks;
+        private ListView lvBookmarks;
+        private ColumnHeader chName;
+        private ColumnHeader chNick;
+        private ColumnHeader chAutoJoin;
+        private ToolStripMenuItem bookmarkToolStripMenuItem;
+        private ToolStripMenuItem addToolStripMenuItem;
+        private ToolStripMenuItem removeToolStripMenuItem;
+        private bool m_connected = false;
+
+        #endregion
+
+        public MainForm()
+        {
+            //
+            // Required for Windows Form Designer support
+            //
+            InitializeComponent();
+
+            services.ImageList = roster.ImageList;
+            cm.AddFeature(URI.TIME);
+            cm.AddFeature(URI.VERSION);
+            cm.AddFeature(URI.LAST);
+            cm.AddFeature(URI.DISCO_INFO);
+
+            tabControl1.TabPages.Remove(tpServices);
+            tabControl1.TabPages.Remove(tpDebug);
+            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
+        }
+
+
+        void idler_OnUnIdle(object sender, TimeSpan span)
+        {
+            jc.Presence(PresenceType.available, "Available", null, 0);
+            pnlPresence.Text = "Available";
+        }
+
+        private void idler_OnIdle(object sender, TimeSpan span)
+        {
+            jc.Presence(PresenceType.available, "Auto-away", "away", 0);
+            pnlPresence.Text = "Away";
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        protected override void Dispose( bool disposing )
+        {
+            idler.Enabled = false;
+
+            if( disposing )
+            {
+                if (components != null)
+                {
+                    components.Dispose();
+                }
+            }
+            base.Dispose( disposing );
+        }
+
+#region Windows Form Designer generated code
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.components = new System.ComponentModel.Container();
+            jabber.connection.Ident ident2 = new jabber.connection.Ident();
+            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
+            this.sb = new System.Windows.Forms.StatusBar();
+            this.pnlCon = new System.Windows.Forms.StatusBarPanel();
+            this.pnlSSL = new System.Windows.Forms.StatusBarPanel();
+            this.pnlPresence = new System.Windows.Forms.StatusBarPanel();
+            this.tabControl1 = new System.Windows.Forms.TabControl();
+            this.tpRoster = new System.Windows.Forms.TabPage();
+            this.roster = new muzzle.RosterTree();
+            this.jc = new jabber.client.JabberClient(this.components);
+            this.pm = new jabber.client.PresenceManager(this.components);
+            this.cm = new jabber.connection.CapsManager(this.components);
+            this.dm = new jabber.connection.DiscoManager(this.components);
+            this.rm = new jabber.client.RosterManager(this.components);
+            this.tpServices = new System.Windows.Forms.TabPage();
+            this.services = new Example.ServiceDisplay();
+            this.tpBookmarks = new System.Windows.Forms.TabPage();
+            this.lvBookmarks = new System.Windows.Forms.ListView();
+            this.chName = new System.Windows.Forms.ColumnHeader();
+            this.chNick = new System.Windows.Forms.ColumnHeader();
+            this.chAutoJoin = new System.Windows.Forms.ColumnHeader();
+            this.tpDebug = new System.Windows.Forms.TabPage();
+            this.debug = new muzzle.XmppDebugger();
+            this.mnuPresence = new System.Windows.Forms.ContextMenu();
+            this.mnuAvailable = new System.Windows.Forms.MenuItem();
+            this.mnuAway = new System.Windows.Forms.MenuItem();
+            this.menuStrip1 = new System.Windows.Forms.MenuStrip();
+            this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.connectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.joinConferenceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
+            this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.servicesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.debugToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.rosterToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.addContactToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.removeContactToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.addGroupToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.bookmarkToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.addToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.windowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.closeTabToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.pubSubToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.subscribePubSubToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.deletePubSubToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.psm = new jabber.connection.PubSubManager(this.components);
+            this.idler = new bedrock.util.IdleTime();
+            this.muc = new jabber.connection.ConferenceManager(this.components);
+            this.bmm = new jabber.client.BookmarkManager(this.components);
+            ((System.ComponentModel.ISupportInitialize)(this.pnlCon)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.pnlSSL)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.pnlPresence)).BeginInit();
+            this.tabControl1.SuspendLayout();
+            this.tpRoster.SuspendLayout();
+            this.tpServices.SuspendLayout();
+            this.tpBookmarks.SuspendLayout();
+            this.tpDebug.SuspendLayout();
+            this.menuStrip1.SuspendLayout();
+            this.SuspendLayout();
+            // 
+            // sb
+            // 
+            this.sb.Location = new System.Drawing.Point(0, 416);
+            this.sb.Name = "sb";
+            this.sb.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
+            this.pnlCon,
+            this.pnlSSL,
+            this.pnlPresence});
+            this.sb.ShowPanels = true;
+            this.sb.Size = new System.Drawing.Size(632, 22);
+            this.sb.TabIndex = 0;
+            this.sb.PanelClick += new System.Windows.Forms.StatusBarPanelClickEventHandler(this.sb_PanelClick);
+            // 
+            // pnlCon
+            // 
+            this.pnlCon.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring;
+            this.pnlCon.Name = "pnlCon";
+            this.pnlCon.Text = "Click on \"Offline\", and select a presence to log in.";
+            this.pnlCon.Width = 538;
+            // 
+            // pnlSSL
+            // 
+            this.pnlSSL.Alignment = System.Windows.Forms.HorizontalAlignment.Center;
+            this.pnlSSL.Name = "pnlSSL";
+            this.pnlSSL.Width = 30;
+            // 
+            // pnlPresence
+            // 
+            this.pnlPresence.Alignment = System.Windows.Forms.HorizontalAlignment.Right;
+            this.pnlPresence.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Contents;
+            this.pnlPresence.Name = "pnlPresence";
+            this.pnlPresence.Text = "Offline";
+            this.pnlPresence.Width = 47;
+            // 
+            // tabControl1
+            // 
+            this.tabControl1.Controls.Add(this.tpRoster);
+            this.tabControl1.Controls.Add(this.tpServices);
+            this.tabControl1.Controls.Add(this.tpBookmarks);
+            this.tabControl1.Controls.Add(this.tpDebug);
+            this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.tabControl1.Location = new System.Drawing.Point(0, 24);
+            this.tabControl1.Name = "tabControl1";
+            this.tabControl1.SelectedIndex = 0;
+            this.tabControl1.Size = new System.Drawing.Size(632, 392);
+            this.tabControl1.TabIndex = 2;
+            // 
+            // tpRoster
+            // 
+            this.tpRoster.Controls.Add(this.roster);
+            this.tpRoster.Location = new System.Drawing.Point(4, 22);
+            this.tpRoster.Name = "tpRoster";
+            this.tpRoster.Size = new System.Drawing.Size(624, 366);
+            this.tpRoster.TabIndex = 1;
+            this.tpRoster.Text = "Roster";
+            this.tpRoster.UseVisualStyleBackColor = true;
+            // 
+            // roster
+            // 
+            this.roster.AllowDrop = true;
+            this.roster.Client = this.jc;
+            this.roster.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.roster.DrawMode = System.Windows.Forms.TreeViewDrawMode.OwnerDrawText;
+            this.roster.ImageIndex = 1;
+            this.roster.Location = new System.Drawing.Point(0, 0);
+            this.roster.Name = "roster";
+            this.roster.PresenceManager = this.pm;
+            this.roster.RosterManager = this.rm;
+            this.roster.SelectedImageIndex = 0;
+            this.roster.ShowLines = false;
+            this.roster.ShowRootLines = false;
+            this.roster.Size = new System.Drawing.Size(624, 366);
+            this.roster.Sorted = true;
+            this.roster.StatusColor = System.Drawing.Color.Teal;
+            this.roster.TabIndex = 0;
+            this.roster.DoubleClick += new System.EventHandler(this.roster_DoubleClick);
+            // 
+            // jc
+            // 
+            this.jc.AutoReconnect = 3F;
+            this.jc.AutoStartCompression = true;
+            this.jc.AutoStartTLS = true;
+            this.jc.InvokeControl = this;
+            this.jc.KeepAlive = 30F;
+            this.jc.LocalCertificate = null;
+            this.jc.Password = null;
+            this.jc.User = null;
+            this.jc.OnRegisterInfo += new jabber.client.RegisterInfoHandler(this.jc_OnRegisterInfo);
+            this.jc.OnError += new bedrock.ExceptionHandler(this.jc_OnError);
+            this.jc.OnIQ += new jabber.client.IQHandler(this.jc_OnIQ);
+            this.jc.OnAuthenticate += new bedrock.ObjectHandler(this.jc_OnAuthenticate);
+            this.jc.OnStreamError += new jabber.protocol.ProtocolHandler(this.jc_OnStreamError);
+            this.jc.OnConnect += new jabber.connection.StanzaStreamHandler(this.jc_OnConnect);
+            this.jc.OnDisconnect += new bedrock.ObjectHandler(this.jc_OnDisconnect);
+            this.jc.OnAuthError += new jabber.protocol.ProtocolHandler(this.jc_OnAuthError);
+            this.jc.OnRegistered += new jabber.client.IQHandler(this.jc_OnRegistered);
+            this.jc.OnMessage += new jabber.client.MessageHandler(this.jc_OnMessage);
+            // 
+            // pm
+            // 
+            this.pm.CapsManager = this.cm;
+            this.pm.OverrideFrom = null;
+            this.pm.Stream = this.jc;
+            // 
+            // cm
+            // 
+            this.cm.DiscoManager = this.dm;
+            this.cm.Features = new string[0];
+            this.cm.FileName = "caps.xml";
+            ident2.Category = "client";
+            ident2.Lang = "en";
+            ident2.Name = "Jabber-Net Test Client";
+            ident2.Type = "pc";
+            this.cm.Identities = new jabber.connection.Ident[] {
+        ident2};
+            this.cm.Node = "http://cursive.net/clients/csharp-example";
+            this.cm.OverrideFrom = null;
+            this.cm.Stream = this.jc;
+            // 
+            // dm
+            // 
+            this.dm.OverrideFrom = null;
+            this.dm.Stream = this.jc;
+            // 
+            // rm
+            // 
+            this.rm.AutoAllow = jabber.client.AutoSubscriptionHanding.AllowIfSubscribed;
+            this.rm.AutoSubscribe = true;
+            this.rm.OverrideFrom = null;
+            this.rm.Stream = this.jc;
+            this.rm.OnRosterEnd += new bedrock.ObjectHandler(this.rm_OnRosterEnd);
+            this.rm.OnSubscription += new jabber.client.SubscriptionHandler(this.rm_OnSubscription);
+            this.rm.OnUnsubscription += new jabber.client.UnsubscriptionHandler(this.rm_OnUnsubscription);
+            // 
+            // tpServices
+            // 
+            this.tpServices.Controls.Add(this.services);
+            this.tpServices.Location = new System.Drawing.Point(4, 22);
+            this.tpServices.Name = "tpServices";
+            this.tpServices.Size = new System.Drawing.Size(624, 366);
+            this.tpServices.TabIndex = 2;
+            this.tpServices.Text = "Services";
+            this.tpServices.UseVisualStyleBackColor = true;
+            // 
+            // services
+            // 
+            this.services.DiscoManager = this.dm;
+            this.services.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.services.ImageList = null;
+            this.services.Location = new System.Drawing.Point(0, 0);
+            this.services.Name = "services";
+            this.services.Size = new System.Drawing.Size(624, 366);
+            this.services.Stream = this.jc;
+            this.services.TabIndex = 0;
+            // 
+            // tpBookmarks
+            // 
+            this.tpBookmarks.Controls.Add(this.lvBookmarks);
+            this.tpBookmarks.Location = new System.Drawing.Point(4, 22);
+            this.tpBookmarks.Name = "tpBookmarks";
+            this.tpBookmarks.Size = new System.Drawing.Size(624, 366);
+            this.tpBookmarks.TabIndex = 3;
+            this.tpBookmarks.Text = "Bookmarks";
+            this.tpBookmarks.UseVisualStyleBackColor = true;
+            // 
+            // lvBookmarks
+            // 
+            this.lvBookmarks.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+            this.chName,
+            this.chNick,
+            this.chAutoJoin});
+            this.lvBookmarks.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.lvBookmarks.Location = new System.Drawing.Point(0, 0);
+            this.lvBookmarks.Name = "lvBookmarks";
+            this.lvBookmarks.Size = new System.Drawing.Size(624, 366);
+            this.lvBookmarks.Sorting = System.Windows.Forms.SortOrder.Ascending;
+            this.lvBookmarks.TabIndex = 0;
+            this.lvBookmarks.UseCompatibleStateImageBehavior = false;
+            this.lvBookmarks.View = System.Windows.Forms.View.Details;
+            this.lvBookmarks.DoubleClick += new System.EventHandler(this.lvBookmarks_DoubleClick);
+            this.lvBookmarks.KeyUp += new System.Windows.Forms.KeyEventHandler(this.lvBookmarks_KeyUp);
+            // 
+            // chName
+            // 
+            this.chName.Text = "Room";
+            this.chName.Width = 198;
+            // 
+            // chNick
+            // 
+            this.chNick.Text = "Nick";
+            this.chNick.Width = 88;
+            // 
+            // chAutoJoin
+            // 
+            this.chAutoJoin.Text = "AutoJoin";
+            // 
+            // tpDebug
+            // 
+            this.tpDebug.Controls.Add(this.debug);
+            this.tpDebug.Location = new System.Drawing.Point(4, 22);
+            this.tpDebug.Name = "tpDebug";
+            this.tpDebug.Size = new System.Drawing.Size(624, 366);
+            this.tpDebug.TabIndex = 0;
+            this.tpDebug.Text = "Debug";
+            this.tpDebug.UseVisualStyleBackColor = true;
+            // 
+            // debug
+            // 
+            this.debug.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.debug.ErrorColor = System.Drawing.Color.Red;
+            this.debug.Location = new System.Drawing.Point(0, 0);
+            this.debug.Name = "debug";
+            this.debug.OtherColor = System.Drawing.Color.Green;
+            this.debug.OverrideFrom = null;
+            this.debug.ReceiveColor = System.Drawing.Color.Orange;
+            this.debug.SendColor = System.Drawing.Color.Blue;
+            this.debug.Size = new System.Drawing.Size(624, 366);
+            this.debug.Stream = this.jc;
+            this.debug.TabIndex = 0;
+            this.debug.TextColor = System.Drawing.Color.Black;
+            // 
+            // mnuPresence
+            // 
+            this.mnuPresence.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
+            this.mnuAvailable,
+            this.mnuAway});
+            // 
+            // mnuAvailable
+            // 
+            this.mnuAvailable.Enabled = false;
+            this.mnuAvailable.Index = 0;
+            this.mnuAvailable.Shortcut = System.Windows.Forms.Shortcut.CtrlO;
+            this.mnuAvailable.Text = "&Available";
+            this.mnuAvailable.Click += new System.EventHandler(this.mnuAvailable_Click);
+            // 
+            // mnuAway
+            // 
+            this.mnuAway.Enabled = false;
+            this.mnuAway.Index = 1;
+            this.mnuAway.Shortcut = System.Windows.Forms.Shortcut.CtrlA;
+            this.mnuAway.Text = "A&way";
+            this.mnuAway.Click += new System.EventHandler(this.mnuAway_Click);
+            // 
+            // menuStrip1
+            // 
+            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.fileToolStripMenuItem,
+            this.viewToolStripMenuItem,
+            this.rosterToolStripMenuItem,
+            this.bookmarkToolStripMenuItem,
+            this.windowToolStripMenuItem,
+            this.pubSubToolStripMenuItem});
+            this.menuStrip1.Location = new System.Drawing.Point(0, 0);
+            this.menuStrip1.Name = "menuStrip1";
+            this.menuStrip1.Size = new System.Drawing.Size(632, 24);
+            this.menuStrip1.TabIndex = 3;
+            this.menuStrip1.Text = "menuStrip1";
+            // 
+            // fileToolStripMenuItem
+            // 
+            this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.connectToolStripMenuItem,
+            this.joinConferenceToolStripMenuItem,
+            this.toolStripMenuItem1,
+            this.exitToolStripMenuItem});
+            this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
+            this.fileToolStripMenuItem.Size = new System.Drawing.Size(35, 20);
+            this.fileToolStripMenuItem.Text = "&File";
+            // 
+            // connectToolStripMenuItem
+            // 
+            this.connectToolStripMenuItem.Name = "connectToolStripMenuItem";
+            this.connectToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F9;
+            this.connectToolStripMenuItem.Size = new System.Drawing.Size(200, 22);
+            this.connectToolStripMenuItem.Text = "&Connect";
+            this.connectToolStripMenuItem.Click += new System.EventHandler(this.connectToolStripMenuItem_Click);
+            // 
+            // joinConferenceToolStripMenuItem
+            // 
+            this.joinConferenceToolStripMenuItem.Name = "joinConferenceToolStripMenuItem";
+            this.joinConferenceToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.J)));
+            this.joinConferenceToolStripMenuItem.Size = new System.Drawing.Size(200, 22);
+            this.joinConferenceToolStripMenuItem.Text = "&Join Conference";
+            this.joinConferenceToolStripMenuItem.Click += new System.EventHandler(this.joinConferenceToolStripMenuItem_Click);
+            // 
+            // toolStripMenuItem1
+            // 
+            this.toolStripMenuItem1.Name = "toolStripMenuItem1";
+            this.toolStripMenuItem1.Size = new System.Drawing.Size(197, 6);
+            // 
+            // exitToolStripMenuItem
+            // 
+            this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
+            this.exitToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Q)));
+            this.exitToolStripMenuItem.Size = new System.Drawing.Size(200, 22);
+            this.exitToolStripMenuItem.Text = "E&xit";
+            this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
+            // 
+            // viewToolStripMenuItem
+            // 
+            this.viewToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.servicesToolStripMenuItem,
+            this.debugToolStripMenuItem});
+            this.viewToolStripMenuItem.Name = "viewToolStripMenuItem";
+            this.viewToolStripMenuItem.Size = new System.Drawing.Size(41, 20);
+            this.viewToolStripMenuItem.Text = "&View";
+            // 
+            // servicesToolStripMenuItem
+            // 
+            this.servicesToolStripMenuItem.Name = "servicesToolStripMenuItem";
+            this.servicesToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F8;
+            this.servicesToolStripMenuItem.Size = new System.Drawing.Size(144, 22);
+            this.servicesToolStripMenuItem.Text = "&Services";
+            this.servicesToolStripMenuItem.Click += new System.EventHandler(this.servicesToolStripMenuItem_Click);
+            // 
+            // debugToolStripMenuItem
+            // 
+            this.debugToolStripMenuItem.Name = "debugToolStripMenuItem";
+            this.debugToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F12;
+            this.debugToolStripMenuItem.Size = new System.Drawing.Size(144, 22);
+            this.debugToolStripMenuItem.Text = "&Debug";
+            this.debugToolStripMenuItem.Click += new System.EventHandler(this.debugToolStripMenuItem_Click);
+            // 
+            // rosterToolStripMenuItem
+            // 
+            this.rosterToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.addContactToolStripMenuItem,
+            this.removeContactToolStripMenuItem,
+            this.addGroupToolStripMenuItem});
+            this.rosterToolStripMenuItem.Name = "rosterToolStripMenuItem";
+            this.rosterToolStripMenuItem.Size = new System.Drawing.Size(51, 20);
+            this.rosterToolStripMenuItem.Text = "&Roster";
+            // 
+            // addContactToolStripMenuItem
+            // 
+            this.addContactToolStripMenuItem.Name = "addContactToolStripMenuItem";
+            this.addContactToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Insert;
+            this.addContactToolStripMenuItem.Size = new System.Drawing.Size(187, 22);
+            this.addContactToolStripMenuItem.Text = "&Add Contact";
+            this.addContactToolStripMenuItem.Click += new System.EventHandler(this.menuItem3_Click);
+            // 
+            // removeContactToolStripMenuItem
+            // 
+            this.removeContactToolStripMenuItem.Name = "removeContactToolStripMenuItem";
+            this.removeContactToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Delete;
+            this.removeContactToolStripMenuItem.Size = new System.Drawing.Size(187, 22);
+            this.removeContactToolStripMenuItem.Text = "&Remove Contact";
+            this.removeContactToolStripMenuItem.Click += new System.EventHandler(this.menuItem5_Click);
+            // 
+            // addGroupToolStripMenuItem
+            // 
+            this.addGroupToolStripMenuItem.Name = "addGroupToolStripMenuItem";
+            this.addGroupToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.G)));
+            this.addGroupToolStripMenuItem.Size = new System.Drawing.Size(187, 22);
+            this.addGroupToolStripMenuItem.Text = "&Add Group";
+            this.addGroupToolStripMenuItem.Click += new System.EventHandler(this.addGroupToolStripMenuItem_Click);
+            // 
+            // bookmarkToolStripMenuItem
+            // 
+            this.bookmarkToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.addToolStripMenuItem,
+            this.removeToolStripMenuItem});
+            this.bookmarkToolStripMenuItem.Name = "bookmarkToolStripMenuItem";
+            this.bookmarkToolStripMenuItem.Size = new System.Drawing.Size(65, 20);
+            this.bookmarkToolStripMenuItem.Text = "Bookmark";
+            // 
+            // addToolStripMenuItem
+            // 
+            this.addToolStripMenuItem.Name = "addToolStripMenuItem";
+            this.addToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.B)));
+            this.addToolStripMenuItem.Size = new System.Drawing.Size(192, 22);
+            this.addToolStripMenuItem.Text = "Add";
+            this.addToolStripMenuItem.Click += new System.EventHandler(this.addToolStripMenuItem_Click);
+            // 
+            // removeToolStripMenuItem
+            // 
+            this.removeToolStripMenuItem.Name = "removeToolStripMenuItem";
+            this.removeToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
+                        | System.Windows.Forms.Keys.B)));
+            this.removeToolStripMenuItem.Size = new System.Drawing.Size(192, 22);
+            this.removeToolStripMenuItem.Text = "Remove";
+            this.removeToolStripMenuItem.Click += new System.EventHandler(this.removeToolStripMenuItem_Click);
+            // 
+            // windowToolStripMenuItem
+            // 
+            this.windowToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.closeTabToolStripMenuItem});
+            this.windowToolStripMenuItem.Name = "windowToolStripMenuItem";
+            this.windowToolStripMenuItem.Size = new System.Drawing.Size(57, 20);
+            this.windowToolStripMenuItem.Text = "&Window";
+            // 
+            // closeTabToolStripMenuItem
+            // 
+            this.closeTabToolStripMenuItem.Name = "closeTabToolStripMenuItem";
+            this.closeTabToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
+            this.closeTabToolStripMenuItem.Size = new System.Drawing.Size(174, 22);
+            this.closeTabToolStripMenuItem.Text = "&Close Tab";
+            this.closeTabToolStripMenuItem.Click += new System.EventHandler(this.closeTabToolStripMenuItem_Click);
+            // 
+            // pubSubToolStripMenuItem
+            // 
+            this.pubSubToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.subscribePubSubToolStripMenuItem,
+            this.deletePubSubToolStripMenuItem});
+            this.pubSubToolStripMenuItem.Name = "pubSubToolStripMenuItem";
+            this.pubSubToolStripMenuItem.Size = new System.Drawing.Size(55, 20);
+            this.pubSubToolStripMenuItem.Text = "PubSub";
+            // 
+            // subscribePubSubToolStripMenuItem
+            // 
+            this.subscribePubSubToolStripMenuItem.Name = "subscribePubSubToolStripMenuItem";
+            this.subscribePubSubToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F10;
+            this.subscribePubSubToolStripMenuItem.Size = new System.Drawing.Size(156, 22);
+            this.subscribePubSubToolStripMenuItem.Text = "&Subscribe";
+            this.subscribePubSubToolStripMenuItem.Click += new System.EventHandler(this.subscribeToPubSubToolStripMenuItem_Click);
+            // 
+            // deletePubSubToolStripMenuItem
+            // 
+            this.deletePubSubToolStripMenuItem.Name = "deletePubSubToolStripMenuItem";
+            this.deletePubSubToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F11;
+            this.deletePubSubToolStripMenuItem.Size = new System.Drawing.Size(156, 22);
+            this.deletePubSubToolStripMenuItem.Text = "&Delete";
+            this.deletePubSubToolStripMenuItem.Click += new System.EventHandler(this.deletePubSubToolStripMenuItem_Click);
+            // 
+            // psm
+            // 
+            this.psm.OverrideFrom = null;
+            this.psm.Stream = this.jc;
+            // 
+            // idler
+            // 
+            this.idler.InvokeControl = this;
+            this.idler.OnIdle += new bedrock.util.SpanEventHandler(this.idler_OnIdle);
+            this.idler.OnUnIdle += new bedrock.util.SpanEventHandler(this.idler_OnUnIdle);
+            // 
+            // muc
+            // 
+            this.muc.OverrideFrom = null;
+            this.muc.Stream = this.jc;
+            // 
+            // bmm
+            // 
+            this.bmm.ConferenceManager = this.muc;
+            this.bmm.OverrideFrom = null;
+            this.bmm.Stream = this.jc;
+            this.bmm.OnConferenceAdd += new jabber.client.BookmarkConferenceDelegate(this.bmm_OnConferenceAdd);
+            this.bmm.OnConferenceRemove += new jabber.client.BookmarkConferenceDelegate(this.bmm_OnConferenceRemove);
+            // 
+            // MainForm
+            // 
+            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
+            this.ClientSize = new System.Drawing.Size(632, 438);
+            this.ContextMenu = this.mnuPresence;
+            this.Controls.Add(this.tabControl1);
+            this.Controls.Add(this.sb);
+            this.Controls.Add(this.menuStrip1);
+            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+            this.MainMenuStrip = this.menuStrip1;
+            this.Name = "MainForm";
+            this.Text = "MainForm";
+            this.Closing += new System.ComponentModel.CancelEventHandler(this.MainForm_Closing);
+            ((System.ComponentModel.ISupportInitialize)(this.pnlCon)).EndInit();
+            ((System.ComponentModel.ISupportInitialize)(this.pnlSSL)).EndInit();
+            ((System.ComponentModel.ISupportInitialize)(this.pnlPresence)).EndInit();
+            this.tabControl1.ResumeLayout(false);
+            this.tpRoster.ResumeLayout(false);
+            this.tpServices.ResumeLayout(false);
+            this.tpBookmarks.ResumeLayout(false);
+            this.tpDebug.ResumeLayout(false);
+            this.menuStrip1.ResumeLayout(false);
+            this.menuStrip1.PerformLayout();
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+#endregion
+
+        /// <summary>
+        /// The MainForm entry point for the application.
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            Application.Run(new MainForm());
+        }
+
+        private void Connect()
+        {
+            muzzle.ClientLogin.Login(jc, "login.xml");
+        }
+
+        private void jc_OnAuthenticate(object sender)
+        {
+            pnlPresence.Text = "Available";
+            pnlCon.Text = "Connected";
+            mnuAway.Enabled = mnuAvailable.Enabled = true;
+
+            if (jc.SSLon)
+            {
+
+                pnlSSL.Text = "SSL";
+                System.Security.Cryptography.X509Certificates.X509Certificate cert2 =
+                    (System.Security.Cryptography.X509Certificates.X509Certificate)
+                    jc[Options.REMOTE_CERTIFICATE];
+
+                string cert_str = cert2.ToString(true);
+                debug.Write("CERT:", cert_str);
+                pnlSSL.ToolTipText = cert_str;
+            }
+            idler.Enabled = true;
+        }
+
+        private void jc_OnDisconnect(object sender)
+        {
+            m_connected = false;
+            mnuAway.Enabled = mnuAvailable.Enabled = false;
+            idler.Enabled = false;
+            pnlPresence.Text = "Offline";
+            pnlSSL.Text = "";
+            pnlSSL.ToolTipText = "";
+            connectToolStripMenuItem.Text = "&Connect";
+            lvBookmarks.Items.Clear();
+
+            if (!m_err)
+                pnlCon.Text = "Disconnected";
+        }
+
+        private void jc_OnError(object sender, Exception ex)
+        {
+            m_connected = false;
+            mnuAway.Enabled = mnuAvailable.Enabled = false;
+            connectToolStripMenuItem.Text = "&Connect";
+            idler.Enabled = false;
+            lvBookmarks.Items.Clear();
+
+            pnlCon.Text = "Error: " + ex.Message;
+        }
+
+        private void jc_OnAuthError(object sender, XmlElement elem)
+        {
+            if (MessageBox.Show(this,
+                "Create new account?",
+                "Authentication error",
+                MessageBoxButtons.OKCancel,
+                MessageBoxIcon.Warning) == DialogResult.OK)
+            {
+                if (!m_connected)
+                {
+                    MessageBox.Show("You have been disconnected by the server.  Registration is not enabled.", "Disconnected", MessageBoxButtons.OK, MessageBoxIcon.Error);
+                    return;
+                }
+                jc.Register(new JID(jc.User, jc.Server, null));
+            }
+            else
+            {
+                jc.Close(false);
+            }
+        }
+
+        private void jc_OnRegistered(object sender, IQ iq)
+        {
+            if (iq.Type == IQType.result)
+                jc.Login();
+            else
+                pnlCon.Text = "Registration error";
+        }
+
+        private bool jc_OnRegisterInfo(object sender, Register r)
+        {
+            if (r.Form == null)
+                return true;
+            muzzle.XDataForm f = new muzzle.XDataForm(r.Form);
+            if (f.ShowDialog() != DialogResult.OK)
+                return false;
+            f.FillInResponse(r.Form);
+            return true;
+        }
+
+        private void jc_OnMessage(object sender, jabber.protocol.client.Message msg)
+        {
+            jabber.protocol.x.Data x = msg["x", URI.XDATA] as jabber.protocol.x.Data;
+            if (x != null)
+            {
+                muzzle.XDataForm f = new muzzle.XDataForm(msg);
+                f.ShowDialog(this);
+                jc.Write(f.GetResponse());
+            }
+            else
+                MessageBox.Show(this, msg.Body, msg.From, MessageBoxButtons.OK);
+        }
+
+        private void jc_OnIQ(object sender, IQ iq)
+        {
+            if (iq.Type != IQType.get)
+                return;
+
+            XmlElement query = iq.Query;
+            if (query == null)
+                return;
+
+            // <iq id="jcl_8" to="me" from="you" type="get"><query xmlns="jabber:iq:version"/></iq>
+            if (query is jabber.protocol.iq.Version)
+            {
+                iq = iq.GetResponse(jc.Document);
+                jabber.protocol.iq.Version ver = iq.Query as jabber.protocol.iq.Version;
+                if (ver != null)
+                {
+                    ver.OS = Environment.OSVersion.ToString();
+                    ver.EntityName = Application.ProductName;
+                    ver.Ver = Application.ProductVersion;
+                }
+                jc.Write(iq);
+                return;
+            }
+
+            if (query is Time)
+            {
+                iq = iq.GetResponse(jc.Document);
+                Time tim = iq.Query as Time;
+                if (tim != null) tim.SetCurrentTime();
+                jc.Write(iq);
+                return;
+            }
+
+            if (query is Last)
+            {
+                iq = iq.GetResponse(jc.Document);
+                Last last = iq.Query as Last;
+                if (last != null) last.Seconds = (int)IdleTime.GetIdleTime();
+                jc.Write(iq);
+                return;
+            }
+        }
+
+        private void roster_DoubleClick(object sender, EventArgs e)
+        {
+            muzzle.RosterTree.ItemNode n = roster.SelectedNode as muzzle.RosterTree.ItemNode;
+            if (n == null)
+                return;
+            new SendMessage(jc, n.JID).Show();
+        }
+
+        private void sb_PanelClick(object sender, StatusBarPanelClickEventArgs e)
+        {
+            if (e.StatusBarPanel != pnlPresence)
+                return;
+            mnuPresence.Show(sb, new Point(e.X, e.Y));
+        }
+
+        private void connectToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            if (jc.IsAuthenticated)
+            {
+                jc.Close(true);
+                connectToolStripMenuItem.Text = "&Connect";
+            }
+            else
+            {
+                Connect();
+                connectToolStripMenuItem.Text = "Dis&connect";
+            }
+        }
+
+        private void mnuAvailable_Click(object sender, EventArgs e)
+        {
+            if (jc.IsAuthenticated)
+            {
+                jc.Presence(PresenceType.available, "Available", null, 0);
+                pnlPresence.Text = "Available";
+            }
+            else
+                Connect();
+        }
+
+        private void mnuAway_Click(object sender, EventArgs e)
+        {
+            if (jc.IsAuthenticated)
+            {
+                jc.Presence(PresenceType.available, "Away", "away", 0);
+                pnlPresence.Text = "Away";
+            }
+            else
+                Connect();
+        }
+
+        /*
+        private void mnuOffline_Click(object sender, EventArgs e)
+        {
+            if (jc.IsAuthenticated)
+                jc.Close();
+        }
+         */
+
+        void jc_OnConnect(object sender, StanzaStream stream)
+        {
+            m_err = false;
+            m_connected = true;
+        }
+
+        private void jc_OnStreamError(object sender, XmlElement rp)
+        {
+            m_err = true;
+            pnlCon.Text = "Stream error: " + rp.InnerText;
+        }
+
+        /*
+        private void txtDebugInput_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
+        {
+            if ((e.KeyCode == Keys.Enter) && e.Control)
+            {
+                try
+                {
+                    XmlDocument doc = new XmlDocument();
+                    doc.LoadXml(txtDebugInput.Text);
+                    XmlElement elem = doc.DocumentElement;
+                    if (elem != null)
+                        jc.Write(elem);
+                    txtDebugInput.Clear();
+                }
+                catch (XmlException ex)
+                {
+                    MessageBox.Show("Invalid XML: " + ex.Message);
+                }
+            }
+
+        }
+*/
+        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
+        {
+            MessageBox.Show(e.ExceptionObject.ToString(), "Unhandled exception: " + e.GetType());
+        }
+
+        private void rm_OnRosterEnd(object sender)
+        {
+            roster.ExpandAll();
+        }
+
+        private void MainForm_Closing(object sender, CancelEventArgs e)
+        {
+            if (jc.IsAuthenticated)
+                jc.Close();
+        }
+
+        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            jc.Close();
+            Close();
+        }
+
+        private void menuItem3_Click(object sender, EventArgs e)
+        {
+            AddContact ac = new AddContact();
+            ac.AllGroups = roster.Groups;
+            ac.DefaultDomain = jc.Server;
+            if (ac.ShowDialog() != DialogResult.OK)
+                return;
+
+            jc.Subscribe(ac.JID, ac.Nickname, ac.SelectedGroups);
+        }
+
+        private void menuItem5_Click(object sender, EventArgs e)
+        {
+            muzzle.RosterTree.ItemNode n = roster.SelectedNode as muzzle.RosterTree.ItemNode;
+            if (n == null)
+                return;
+            jc.RemoveRosterItem(n.JID);
+       }
+
+
+        // add group
+        private void addGroupToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            AddGroup ag = new AddGroup();
+            if (ag.ShowDialog() == DialogResult.Cancel)
+                return;
+
+            if (ag.GroupName == "")
+                return;
+
+            roster.AddGroup(ag.GroupName).EnsureVisible();
+        }
+
+        private void servicesToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            if (tabControl1.TabPages.Contains(tpServices))
+            {
+                tabControl1.TabPages.Remove(tpServices);
+                servicesToolStripMenuItem.Checked = false;
+            }
+            else
+            {
+                tabControl1.TabPages.Add(tpServices);
+                tabControl1.SelectedTab = tpServices;
+                servicesToolStripMenuItem.Checked = true;
+            }
+        }
+
+        private void debugToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            if (tabControl1.TabPages.Contains(tpDebug))
+            {
+                tabControl1.TabPages.Remove(tpDebug);
+                debugToolStripMenuItem.Checked = false;
+            }
+            else
+            {
+                tabControl1.TabPages.Add(tpDebug);
+                tabControl1.SelectedTab = tpDebug;
+                debugToolStripMenuItem.Checked = true;
+            }
+        }
+
+        private void subscribeToPubSubToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            PubSubSubcribeForm ps = new PubSubSubcribeForm();
+            // this is a small race.  to do it right, I should call dm.BeginFindServiceWithFeature,
+            // and modify that to call back on all of the found services.  The idea is that
+            // by the the time the user has a chance to click on the menu item, the DiscoManager
+            // will be populated.
+            ps.DiscoManager = dm;
+            if (ps.ShowDialog() != DialogResult.OK)
+                return;
+            JID jid = ps.JID;
+            string node = ps.Node;
+            string text = string.Format("{0}/{1}", jid, node);
+
+            TabPage tp = new TabPage(text);
+            tp.Name = text;
+
+            PubSubDisplay disp = new PubSubDisplay();
+            disp.Node = psm.GetNode(jid, node, 10);
+            tp.Controls.Add(disp);
+            disp.Dock = DockStyle.Fill;
+
+            tabControl1.TabPages.Add(tp);
+            tabControl1.SelectedTab = tp;
+        }
+
+        private void rm_OnSubscription(jabber.client.RosterManager manager, Item ri, Presence pres)
+        {
+            DialogResult res = MessageBox.Show("Allow incoming presence subscription request from: " + pres.From,
+                "Subscription Request",
+                MessageBoxButtons.YesNoCancel);
+            switch (res)
+            {
+            case DialogResult.Yes:
+                manager.ReplyAllow(pres);
+                break;
+            case DialogResult.No:
+                manager.ReplyDeny(pres);
+                break;
+            case DialogResult.Cancel:
+                // do nothing;
+                break;
+            }
+        }
+
+        private void rm_OnUnsubscription(jabber.client.RosterManager manager, Presence pres, ref bool remove)
+        {
+            MessageBox.Show(pres.From + " has removed you from their roster.", "Unsubscription notification", MessageBoxButtons.OK);
+        }
+
+        private void closeTabToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            TabPage tp = tabControl1.SelectedTab;
+            if (tp == tpRoster)
+                return;
+            else if (tp == tpDebug)
+                debugToolStripMenuItem.Checked = false;
+            else if (tp == tpServices)
+                servicesToolStripMenuItem.Checked = false;
+            tabControl1.TabPages.Remove(tp);
+        }
+
+        private void deletePubSubToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            PubSubSubcribeForm fm = setupPubSubForm();
+            if (fm.ShowDialog() != DialogResult.OK)
+                return;
+
+            JID jid = fm.JID;
+            string node = fm.Node;
+
+            psm.RemoveNode(jid, node,
+                delegate {
+                    MessageBox.Show("Remove Node unsuccessful.");
+                });
+
+            tabControl1.TabPages.RemoveByKey(string.Format("{0}/{1}", jid, node));
+        }
+
+        private PubSubSubcribeForm setupPubSubForm()
+        {
+            string JID = null;
+            string node = null;
+            if (tabControl1.SelectedTab.Name != null && tabControl1.SelectedTab.Name.Contains("/"))
+            {
+                string value = tabControl1.SelectedTab.Name;
+                int index = value.IndexOf("/");
+
+                JID = value.Substring(0, index);
+                node = value.Substring(index + 1);
+            }
+
+            PubSubSubcribeForm fm = new PubSubSubcribeForm();
+            fm.Text = "Delete PubSub";
+            if (JID != null) fm.JID = JID;
+            if (node != null) fm.Node = node;
+            fm.DiscoManager = dm;
+
+            return fm;
+        }
+
+        private void joinConferenceToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            ConferenceForm cf = new ConferenceForm();
+            cf.DiscoManager = dm;
+            cf.Nick = muc.DefaultNick;
+            if (cf.ShowDialog() != DialogResult.OK)
+                return;
+
+            muc.GetRoom(cf.RoomAndNick).Join();
+        }
+
+        private IQ muc_OnRoomConfig(Room room, IQ parent)
+        {
+            muzzle.XDataForm form = new muzzle.XDataForm(parent);
+            if (form.ShowDialog() != DialogResult.OK)
+                return null;
+
+            return (IQ)form.GetResponse();
+        }
+
+        private void muc_OnPresenceError(Room room, Presence pres)
+        {
+            m_err = true;
+            pnlCon.Text = "Groupchat error: " + pres.Error.OuterXml;
+        }
+
+        private void muc_OnInvite(object sender, jabber.protocol.client.Message msg)
+        {
+            Room r = sender as Room;
+            r.Join();
+        }
+
+        private void bmm_OnConferenceAdd(jabber.client.BookmarkManager manager, BookmarkConference conference)
+        {
+            string jid = conference.JID;
+            string name = conference.ConferenceName;
+            if (name == null)
+                name = jid;
+            if (lvBookmarks.Items.ContainsKey(jid))
+                lvBookmarks.Items.RemoveByKey(jid);
+            ListViewItem item = lvBookmarks.Items.Add(jid, name, -1);
+            item.SubItems.Add(conference.Nick);
+            item.SubItems.Add(conference.AutoJoin.ToString());
+            item.Tag = conference.JID;
+        }
+
+        private void bmm_OnConferenceRemove(jabber.client.BookmarkManager manager, BookmarkConference conference)
+        {
+            string jid = conference.JID;
+            if (lvBookmarks.Items.ContainsKey(jid))
+                lvBookmarks.Items.RemoveByKey(jid);
+        }
+
+        private void lvBookmarks_KeyUp(object sender, KeyEventArgs e)
+        {
+            if (e.KeyCode == Keys.Delete)
+                removeToolStripMenuItem_Click(null, null);
+        }
+
+        private void addToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            // pop up AddBookmark dialog
+            ConferenceForm cf = new ConferenceForm();
+            cf.DiscoManager = dm;
+            cf.Nick = muc.DefaultNick;
+            if (cf.ShowDialog() != DialogResult.OK)
+                return;
+            // TODO: add autojoin and name.
+            bmm.AddConference(cf.RoomJID, null, false, cf.Nick);
+        }
+
+        private void removeToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            foreach (ListViewItem lvi in lvBookmarks.SelectedItems)
+            {
+                bmm[(JID)lvi.Tag] = null;
+            }
+        }
+
+        private void lvBookmarks_DoubleClick(object sender, EventArgs e)
+        {
+            if (lvBookmarks.SelectedItems.Count == 0)
+                return;
+            ListViewItem lvi = lvBookmarks.SelectedItems[0];
+
+            JID jid = (JID)lvi.Tag;
+            BookmarkConference conf = bmm[jid];
+            Debug.Assert(conf != null);
+
+            ConferenceForm cf = new ConferenceForm();
+            cf.DiscoManager = dm;
+            cf.RoomAndNick = new JID(jid.User, jid.Server, conf.Nick);
+
+            if (cf.ShowDialog() != DialogResult.OK)
+                return;
+            bmm.AddConference(cf.RoomJID, null, false, cf.Nick);
+        }
+    }
+}
diff --git a/lib/jabber-net/Example/PubSubDisplay.cs b/lib/jabber-net/Example/PubSubDisplay.cs
new file mode 100644
index 0000000..c6620c6
--- /dev/null
+++ b/lib/jabber-net/Example/PubSubDisplay.cs
@@ -0,0 +1,155 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+
+using System;
+using System.Diagnostics;
+using System.Windows.Forms;
+using jabber.connection;
+
+using bedrock.util;
+
+namespace Example
+{
+    [SVN(@"$Id$")]
+    public class PubSubDisplay : UserControl
+    {
+        private ListBox lbID;
+        private Splitter splitter1;
+        private RichTextBox rtItem;
+
+        private PubSubNode m_node = null;
+
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private readonly System.ComponentModel.IContainer components = null;
+
+        public PubSubDisplay()
+        {
+            InitializeComponent();
+        }
+
+        public PubSubNode Node
+        {
+            get { return m_node; }
+            set
+            {
+                if (m_node == value)
+                    return;
+                if (m_node != null)
+                {
+                    m_node.OnItemAdd -= m_node_OnItemAdd;
+                    m_node.OnItemRemove -= m_node_OnItemRemove;
+                }
+                m_node = value;
+                m_node.OnItemAdd += m_node_OnItemAdd;
+                m_node.OnItemRemove += m_node_OnItemRemove;
+                m_node.AutomatedSubscribe();
+            }
+        }
+
+        private void m_node_OnItemAdd(PubSubNode node, jabber.protocol.iq.PubSubItem item)
+        {
+            // OnItemRemove should have fired first, so no reason to remove it here.
+            // Hopefully.
+            Debug.Assert(lbID.Items.IndexOf(item.ID) == -1);
+            lbID.Items.Add(item.ID);
+        }
+
+        private void m_node_OnItemRemove(PubSubNode node, jabber.protocol.iq.PubSubItem item)
+        {
+            int index = lbID.Items.IndexOf(item.ID);
+            if (lbID.SelectedIndex == index)
+                rtItem.Clear();
+            if (index >= 0)
+                lbID.Items.RemoveAt(index);
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Component Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.lbID = new System.Windows.Forms.ListBox();
+            this.splitter1 = new System.Windows.Forms.Splitter();
+            this.rtItem = new System.Windows.Forms.RichTextBox();
+            this.SuspendLayout();
+            //
+            // lbID
+            //
+            this.lbID.Dock = System.Windows.Forms.DockStyle.Left;
+            this.lbID.FormattingEnabled = true;
+            this.lbID.IntegralHeight = false;
+            this.lbID.Location = new System.Drawing.Point(0, 0);
+            this.lbID.Name = "lbID";
+            this.lbID.Size = new System.Drawing.Size(120, 170);
+            this.lbID.TabIndex = 0;
+            this.lbID.SelectedIndexChanged += new System.EventHandler(this.lbID_SelectedIndexChanged);
+            //
+            // splitter1
+            //
+            this.splitter1.Location = new System.Drawing.Point(120, 0);
+            this.splitter1.Name = "splitter1";
+            this.splitter1.Size = new System.Drawing.Size(3, 170);
+            this.splitter1.TabIndex = 1;
+            this.splitter1.TabStop = false;
+            //
+            // rtItem
+            //
+            this.rtItem.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.rtItem.Location = new System.Drawing.Point(123, 0);
+            this.rtItem.Name = "rtItem";
+            this.rtItem.Size = new System.Drawing.Size(236, 170);
+            this.rtItem.TabIndex = 2;
+            this.rtItem.Text = "";
+            //
+            // PubSubDisplay
+            //
+            this.Controls.Add(this.rtItem);
+            this.Controls.Add(this.splitter1);
+            this.Controls.Add(this.lbID);
+            this.Name = "PubSubDisplay";
+            this.Size = new System.Drawing.Size(359, 170);
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private void lbID_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            rtItem.Clear();
+            if (lbID.SelectedIndex == -1)
+                return;
+            // TODO: XML2RTF
+            rtItem.Text = m_node[(string)lbID.SelectedItem].OuterXml;
+        }
+    }
+}
diff --git a/lib/jabber-net/Example/PubSubSubscribeForm.cs b/lib/jabber-net/Example/PubSubSubscribeForm.cs
new file mode 100644
index 0000000..a88c811
--- /dev/null
+++ b/lib/jabber-net/Example/PubSubSubscribeForm.cs
@@ -0,0 +1,191 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+
+using System;
+using System.ComponentModel;
+using System.Windows.Forms;
+using bedrock.util;
+using jabber;
+using jabber.connection;
+
+namespace Example
+{
+    [SVN(@"$Id$")]
+    public class PubSubSubcribeForm : Form
+    {
+        private Label label1;
+        private Label label2;
+        private ComboBox cmbJID;
+        private TextBox txtNode;
+        private Button btnOK;
+        private Button btnCancel;
+
+        private DiscoManager m_disco = null;
+
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private readonly IContainer components = null;
+
+        public PubSubSubcribeForm()
+        {
+            InitializeComponent();
+        }
+
+        public DiscoManager DiscoManager
+        {
+            get { return m_disco; }
+            set { m_disco = value; }
+        }
+
+        public JID JID
+        {
+            get { return cmbJID.Text; }
+            set { cmbJID.Text = value.ToString(); }
+        }
+
+        public string Node
+        {
+            get { return txtNode.Text; }
+            set { txtNode.Text = value; }
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.label2 = new System.Windows.Forms.Label();
+            this.cmbJID = new System.Windows.Forms.ComboBox();
+            this.txtNode = new System.Windows.Forms.TextBox();
+            this.btnOK = new System.Windows.Forms.Button();
+            this.btnCancel = new System.Windows.Forms.Button();
+            this.SuspendLayout();
+            //
+            // label1
+            //
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(12, 9);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(106, 13);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "PubSub Service JID:";
+            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            //
+            // label2
+            //
+            this.label2.AutoSize = true;
+            this.label2.Location = new System.Drawing.Point(82, 35);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(36, 13);
+            this.label2.TabIndex = 2;
+            this.label2.Text = "Node:";
+            this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            //
+            // cmbJID
+            //
+            this.cmbJID.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.cmbJID.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest;
+            this.cmbJID.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
+            this.cmbJID.Location = new System.Drawing.Point(124, 6);
+            this.cmbJID.Name = "cmbJID";
+            this.cmbJID.Size = new System.Drawing.Size(141, 21);
+            this.cmbJID.TabIndex = 4;
+            //
+            // txtNode
+            //
+            this.txtNode.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtNode.Location = new System.Drawing.Point(124, 32);
+            this.txtNode.Name = "txtNode";
+            this.txtNode.Size = new System.Drawing.Size(141, 20);
+            this.txtNode.TabIndex = 5;
+            //
+            // btnOK
+            //
+            this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
+            this.btnOK.Location = new System.Drawing.Point(109, 58);
+            this.btnOK.Name = "btnOK";
+            this.btnOK.Size = new System.Drawing.Size(75, 23);
+            this.btnOK.TabIndex = 6;
+            this.btnOK.Text = "OK";
+            this.btnOK.UseVisualStyleBackColor = true;
+            //
+            // btnCancel
+            //
+            this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+            this.btnCancel.Location = new System.Drawing.Point(190, 58);
+            this.btnCancel.Name = "btnCancel";
+            this.btnCancel.Size = new System.Drawing.Size(75, 23);
+            this.btnCancel.TabIndex = 7;
+            this.btnCancel.Text = "Cancel";
+            this.btnCancel.UseVisualStyleBackColor = true;
+            //
+            // PubSubSubcribeForm
+            //
+            this.AcceptButton = this.btnOK;
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.CancelButton = this.btnCancel;
+            this.ClientSize = new System.Drawing.Size(277, 90);
+            this.Controls.Add(this.btnCancel);
+            this.Controls.Add(this.btnOK);
+            this.Controls.Add(this.txtNode);
+            this.Controls.Add(this.cmbJID);
+            this.Controls.Add(this.label2);
+            this.Controls.Add(this.label1);
+            this.Name = "PubSubSubcribeForm";
+            this.Text = "Subscribe to PubSub Node";
+            this.Shown += new System.EventHandler(this.PubSub_Shown);
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private void PubSub_Shown(object sender, EventArgs e)
+        {
+            cmbJID.BeginUpdate();
+            cmbJID.Items.Clear();
+            foreach (DiscoNode component in m_disco.Root.Children)
+            {
+                if (component.HasFeature(jabber.protocol.URI.PUBSUB))
+                    cmbJID.Items.Add(component.JID);
+            }
+            if (cmbJID.Items.Count > 0)
+                cmbJID.SelectedIndex = 0;
+            cmbJID.EndUpdate();
+        }
+
+    }
+}
diff --git a/lib/jabber-net/Example/SendMessage.cs b/lib/jabber-net/Example/SendMessage.cs
new file mode 100644
index 0000000..8756572
--- /dev/null
+++ b/lib/jabber-net/Example/SendMessage.cs
@@ -0,0 +1,209 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Drawing;
+using System.Collections;
+using System.ComponentModel;
+using System.Windows.Forms;
+
+namespace Example
+{
+    using bedrock.util;
+
+    /// <summary>
+    /// Summary description for SendMessage.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class SendMessage : System.Windows.Forms.Form
+    {
+        private jabber.client.JabberClient m_jc;
+        private System.Windows.Forms.Panel panel1;
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.TextBox txtTo;
+        private System.Windows.Forms.TextBox txtSubject;
+        private System.Windows.Forms.Button btnSend;
+        private System.Windows.Forms.Button btnCancel;
+        private System.Windows.Forms.TextBox txtBody;
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.Container components = null;
+
+        public SendMessage(jabber.client.JabberClient jc, string toJid) : this(jc)
+        {
+            txtTo.Text = toJid;
+        }
+
+        public SendMessage(jabber.client.JabberClient jc)
+        {
+            //
+            // Required for Windows Form Designer support
+            //
+            InitializeComponent();
+
+            m_jc = jc;
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        protected override void Dispose( bool disposing )
+        {
+            if( disposing )
+            {
+                if(components != null)
+                {
+                    components.Dispose();
+                }
+            }
+            base.Dispose( disposing );
+        }
+
+                #region Windows Form Designer generated code
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(SendMessage));
+            this.panel1 = new System.Windows.Forms.Panel();
+            this.btnCancel = new System.Windows.Forms.Button();
+            this.btnSend = new System.Windows.Forms.Button();
+            this.txtSubject = new System.Windows.Forms.TextBox();
+            this.txtTo = new System.Windows.Forms.TextBox();
+            this.label2 = new System.Windows.Forms.Label();
+            this.label1 = new System.Windows.Forms.Label();
+            this.txtBody = new System.Windows.Forms.TextBox();
+            this.panel1.SuspendLayout();
+            this.SuspendLayout();
+            //
+            // panel1
+            //
+            this.panel1.Controls.Add(this.btnCancel);
+            this.panel1.Controls.Add(this.btnSend);
+            this.panel1.Controls.Add(this.txtSubject);
+            this.panel1.Controls.Add(this.txtTo);
+            this.panel1.Controls.Add(this.label2);
+            this.panel1.Controls.Add(this.label1);
+            this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
+            this.panel1.Location = new System.Drawing.Point(0, 0);
+            this.panel1.Name = "panel1";
+            this.panel1.Size = new System.Drawing.Size(312, 72);
+            this.panel1.TabIndex = 1;
+            //
+            // btnCancel
+            //
+            this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+            this.btnCancel.Location = new System.Drawing.Point(256, 40);
+            this.btnCancel.Name = "btnCancel";
+            this.btnCancel.Size = new System.Drawing.Size(48, 23);
+            this.btnCancel.TabIndex = 2;
+            this.btnCancel.Text = "Cancel";
+            this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
+            //
+            // btnSend
+            //
+            this.btnSend.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnSend.Location = new System.Drawing.Point(256, 8);
+            this.btnSend.Name = "btnSend";
+            this.btnSend.Size = new System.Drawing.Size(48, 23);
+            this.btnSend.TabIndex = 1;
+            this.btnSend.Text = "Send";
+            this.btnSend.Click += new System.EventHandler(this.btnSend_Click);
+            //
+            // txtSubject
+            //
+            this.txtSubject.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtSubject.Location = new System.Drawing.Point(64, 41);
+            this.txtSubject.Name = "txtSubject";
+            this.txtSubject.Size = new System.Drawing.Size(184, 20);
+            this.txtSubject.TabIndex = 0;
+            this.txtSubject.Text = "";
+            //
+            // txtTo
+            //
+            this.txtTo.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtTo.Location = new System.Drawing.Point(64, 9);
+            this.txtTo.Name = "txtTo";
+            this.txtTo.Size = new System.Drawing.Size(184, 20);
+            this.txtTo.TabIndex = 3;
+            this.txtTo.Text = "";
+            //
+            // label2
+            //
+            this.label2.Location = new System.Drawing.Point(8, 40);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(48, 23);
+            this.label2.TabIndex = 2;
+            this.label2.Text = "Subject:";
+            //
+            // label1
+            //
+            this.label1.Location = new System.Drawing.Point(8, 8);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(48, 23);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "To:";
+            //
+            // txtBody
+            //
+            this.txtBody.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.txtBody.Location = new System.Drawing.Point(0, 72);
+            this.txtBody.Multiline = true;
+            this.txtBody.Name = "txtBody";
+            this.txtBody.ScrollBars = System.Windows.Forms.ScrollBars.Both;
+            this.txtBody.Size = new System.Drawing.Size(312, 194);
+            this.txtBody.TabIndex = 0;
+            this.txtBody.Text = "";
+            //
+            // SendMessage
+            //
+            this.AcceptButton = this.btnSend;
+            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
+            this.CancelButton = this.btnCancel;
+            this.ClientSize = new System.Drawing.Size(312, 266);
+            this.Controls.Add(this.txtBody);
+            this.Controls.Add(this.panel1);
+            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+            this.Name = "SendMessage";
+            this.Text = "SendMessage";
+            this.panel1.ResumeLayout(false);
+            this.ResumeLayout(false);
+
+        }
+                #endregion
+
+        private void btnSend_Click(object sender, System.EventArgs e)
+        {
+            jabber.protocol.client.Message msg = new jabber.protocol.client.Message(m_jc.Document);
+            msg.To = txtTo.Text;
+            if (txtSubject.Text != "")
+                msg.Subject = txtSubject.Text;
+            msg.Body = txtBody.Text;
+            m_jc.Write(msg);
+            this.Close();
+        }
+
+        private void btnCancel_Click(object sender, System.EventArgs e)
+        {
+            this.Close();
+        }
+    }
+}
diff --git a/lib/jabber-net/Example/ServiceDisplay.cs b/lib/jabber-net/Example/ServiceDisplay.cs
new file mode 100644
index 0000000..826fe44
--- /dev/null
+++ b/lib/jabber-net/Example/ServiceDisplay.cs
@@ -0,0 +1,248 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Windows.Forms;
+
+using bedrock.util;
+
+using jabber.client;
+using jabber.connection;
+
+namespace Example
+{
+    [SVN(@"$Id$")]
+    public class ServiceDisplay : UserControl
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+        private TreeView tvServices;
+        private Splitter splitter2;
+        private PropertyGrid pgServices;
+        private DiscoManager m_disco = null;
+        private JabberClient m_stream = null;
+
+        public ServiceDisplay()
+        {
+            InitializeComponent();
+            tvServices.ShowNodeToolTips = true;
+            tvServices.NodeMouseDoubleClick += new TreeNodeMouseClickEventHandler(tvServices_NodeMouseDoubleClick);
+            tvServices.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvServices_AfterSelect);
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Component Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.tvServices = new System.Windows.Forms.TreeView();
+            this.splitter2 = new System.Windows.Forms.Splitter();
+            this.pgServices = new System.Windows.Forms.PropertyGrid();
+            this.SuspendLayout();
+            //
+            // tvServices
+            //
+            this.tvServices.Dock = System.Windows.Forms.DockStyle.Left;
+            this.tvServices.Location = new System.Drawing.Point(0, 0);
+            this.tvServices.Name = "tvServices";
+            this.tvServices.ShowLines = false;
+            this.tvServices.ShowPlusMinus = false;
+            this.tvServices.ShowRootLines = false;
+            this.tvServices.Size = new System.Drawing.Size(175, 281);
+            this.tvServices.TabIndex = 1;
+            this.tvServices.AfterCollapse += new System.Windows.Forms.TreeViewEventHandler(this.tvServices_AfterCollapse);
+            this.tvServices.AfterExpand += new System.Windows.Forms.TreeViewEventHandler(this.tvServices_AfterExpand);
+            //
+            // splitter2
+            //
+            this.splitter2.Location = new System.Drawing.Point(175, 0);
+            this.splitter2.Name = "splitter2";
+            this.splitter2.Size = new System.Drawing.Size(3, 281);
+            this.splitter2.TabIndex = 2;
+            this.splitter2.TabStop = false;
+            //
+            // pgServices
+            //
+            this.pgServices.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.pgServices.Location = new System.Drawing.Point(178, 0);
+            this.pgServices.Name = "pgServices";
+            this.pgServices.Size = new System.Drawing.Size(366, 281);
+            this.pgServices.TabIndex = 3;
+            //
+            // ServiceDisplay
+            //
+            this.Controls.Add(this.pgServices);
+            this.Controls.Add(this.splitter2);
+            this.Controls.Add(this.tvServices);
+            this.Name = "ServiceDisplay";
+            this.Size = new System.Drawing.Size(544, 281);
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+
+        /// <summary>
+        /// The JabberClient or JabberService to hook up to.
+        /// </summary>
+        [Description("The JabberClient to hook up to.")]
+        [Category("Jabber")]
+        public virtual JabberClient Stream
+        {
+            get
+            {
+                // If we are running in the designer, let's try to get an XmppStream control
+                // from the environment.
+                if ((this.m_stream == null) && DesignMode)
+                {
+                    IDesignerHost host = (IDesignerHost)base.GetService(typeof(IDesignerHost));
+                    this.Stream = (JabberClient)jabber.connection.StreamComponent.GetComponentFromHost(host, typeof(JabberClient));
+                }
+                return m_stream;
+            }
+            set
+            {
+                if ((object)m_stream != (object)value)
+                {
+                    m_stream = value;
+                    m_stream.OnAuthenticate += new bedrock.ObjectHandler(m_stream_OnAuthenticate);
+                    m_stream.OnDisconnect += new bedrock.ObjectHandler(m_stream_OnDisconnect);
+                }
+            }
+        }
+
+        [Category("Jabber")]
+        public DiscoManager DiscoManager
+        {
+            get
+            {
+                // If we are running in the designer, let's try to get a DiscoManager control
+                // from the environment.
+                if ((this.m_disco == null) && DesignMode)
+                {
+                    IDesignerHost host = (IDesignerHost)base.GetService(typeof(IDesignerHost));
+                    this.m_disco = (DiscoManager)StreamComponent.GetComponentFromHost(host, typeof(DiscoManager));
+                }
+                return m_disco;
+            }
+            set
+            {
+                if ((object)m_disco != (object)value)
+                    m_disco = value;
+            }
+        }
+
+        [Category("Appearance")]
+        public ImageList ImageList
+        {
+            get { return tvServices.ImageList; }
+            set { tvServices.ImageList = value; }
+        }
+
+        private void m_stream_OnAuthenticate(object sender)
+        {
+            // TODO: some of this will break in 2003.
+            jabber.connection.DiscoNode dn = m_disco.GetNode(m_stream.Server, null);
+            TreeNode tn = tvServices.Nodes.Add(dn.Key, dn.Name);
+            tn.ToolTipText = dn.Key.Replace('\u0000', '\n');
+            tn.Tag = dn;
+            tn.ImageIndex = 8;
+            tn.SelectedImageIndex = 8;
+            m_disco.BeginGetFeatures(dn, new jabber.connection.DiscoNodeHandler(GotInitialFeatures), null);
+        }
+
+        private void m_stream_OnDisconnect(object sender)
+        {
+            pgServices.SelectedObject = null;
+            tvServices.Nodes.Clear();
+        }
+
+
+        private void tvServices_AfterExpand(object sender, TreeViewEventArgs e)
+        {
+            e.Node.ImageIndex = 6;
+            e.Node.SelectedImageIndex = 6;
+        }
+
+        private void tvServices_AfterCollapse(object sender, TreeViewEventArgs e)
+        {
+            e.Node.ImageIndex = 7;
+            e.Node.SelectedImageIndex = 7;
+        }
+
+        private void tvServices_NodeMouseDoubleClick(object sender,
+                                             TreeNodeMouseClickEventArgs e)
+        {
+            jabber.connection.DiscoNode dn = (jabber.connection.DiscoNode)e.Node.Tag;
+            if (dn.Children == null)
+                m_disco.BeginGetItems(dn.JID, dn.Node, new jabber.connection.DiscoNodeHandler(GotItems), null);
+        }
+
+        private void tvServices_AfterSelect(object sender, TreeViewEventArgs e)
+        {
+            jabber.connection.DiscoNode dn = (jabber.connection.DiscoNode)e.Node.Tag;
+            m_disco.BeginGetFeatures(dn, new jabber.connection.DiscoNodeHandler(GotInfo), null);
+        }
+
+        private void GotInitialFeatures(DiscoManager sender, jabber.connection.DiscoNode node, object state)
+        {
+            m_disco.BeginGetItems(node, new jabber.connection.DiscoNodeHandler(GotItems), state);
+        }
+
+        private void GotItems(DiscoManager sender, jabber.connection.DiscoNode node, object state)
+        {
+            // TODO: some of this will break in 2003.
+            TreeNode[] nodes = tvServices.Nodes.Find(node.Key, true);
+            foreach (TreeNode n in nodes)
+            {
+                n.ImageIndex = 7;
+                n.SelectedImageIndex = 7;
+                foreach (jabber.connection.DiscoNode dn in node.Children)
+                {
+                    TreeNode tn = n.Nodes.Add(dn.Key, dn.Name);
+                    tn.ToolTipText = dn.Key.Replace('\u0000', '\n');
+                    tn.Tag = dn;
+                    tn.ImageIndex = 8;
+                    tn.SelectedImageIndex = 8;
+                }
+            }
+            pgServices.Refresh();
+        }
+
+        private void GotInfo(DiscoManager sender, jabber.connection.DiscoNode node, object state)
+        {
+            pgServices.SelectedObject = node;
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/Delegates.cs b/lib/jabber-net/bedrock/Delegates.cs
new file mode 100644
index 0000000..427f0d5
--- /dev/null
+++ b/lib/jabber-net/bedrock/Delegates.cs
@@ -0,0 +1,42 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+namespace bedrock
+{
+    /// <summary>
+    /// Delegate for memebers that just have a sender
+    /// </summary>
+    public delegate void ObjectHandler(object sender);
+
+    /// <summary>
+    /// Delegate for members that receive a string
+    /// </summary>
+    public delegate void TextHandler(object sender, string txt);
+
+    /// <summary>
+    /// Delegate for methods that get a block of bytes
+    /// </summary>
+    public delegate void ByteHandler(object sender, byte[] buf);
+
+    /// <summary>
+    /// Delegate for members that receive partial blocks of bytes.
+    /// </summary>
+    public delegate void ByteOffsetHandler(object sender, byte[] buf, int offset, int length);
+
+    /// <summary>
+    /// Delegate for members that receive an exception
+    /// </summary>
+    public delegate void ExceptionHandler(object sender, Exception ex);
+}
diff --git a/lib/jabber-net/bedrock/collections/ByteStack.cs b/lib/jabber-net/bedrock/collections/ByteStack.cs
new file mode 100644
index 0000000..a51396c
--- /dev/null
+++ b/lib/jabber-net/bedrock/collections/ByteStack.cs
@@ -0,0 +1,160 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using bedrock.util;
+namespace bedrock.collections
+{
+    /// <summary>
+    /// A type-safe stack for bytes, implemented as a growable
+    /// buffer.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ByteStack
+    {
+        private const double GROWTH_FACTOR = 1.5d;
+        private const int    DEFAULT_SIZE  = 16;
+        private const int    MIN_SIZE      = 2;
+        private static readonly System.Text.Encoding ENCODING = System.Text.Encoding.Default;
+        private int    m_count    = 0;
+        private int    m_capacity = 0;
+        private byte[] m_buffer;
+        /// <summary>
+        /// Creates an instance with the default initial capacity.
+        /// </summary>
+        public ByteStack() : this(DEFAULT_SIZE)
+        {
+        }
+        /// <summary>
+        /// Create an instance with the given initial capacity.
+        /// </summary>
+        /// <param name="initialSize">The initial capacity</param>
+        public ByteStack(int initialSize)
+        {
+            if (initialSize < MIN_SIZE)
+            {
+                initialSize = DEFAULT_SIZE;
+            }
+            m_capacity = initialSize;
+            m_buffer   = new byte[m_capacity];
+        }
+        /// <summary>
+        /// Create an instance with the given initial value.  The initial size
+        /// will be grown from the size of the given bytes.  A copy is made of
+        /// the given bytes.
+        /// </summary>
+        /// <param name="start">byte array copied into this ByteStack</param>
+        public ByteStack(byte[] start)
+        {
+            m_count  = m_capacity = start.Length;
+            m_buffer = start;
+            IncreaseSize();
+        }
+        /// <summary>
+        /// Increase the size of the stack by GROWTH_FACTOR times.
+        /// </summary>
+        private void IncreaseSize()
+        {
+            m_capacity = (int) (m_capacity * GROWTH_FACTOR);
+            // if the size is 1, we'll never get bigger.
+            if (m_capacity < MIN_SIZE)
+            {
+                m_capacity = DEFAULT_SIZE;
+            }
+            byte[] newBuf = new byte[m_capacity];
+            Buffer.BlockCopy(m_buffer, 0, newBuf, 0, m_count);
+            m_buffer = newBuf;
+        }
+        /// <summary>
+        /// Gets the number of bytes that are currently in the stack.
+        /// </summary>
+        public int Count
+        {
+            get
+            {
+                return m_count;
+            }
+        }
+        /// <summary>
+        /// Gets the number of bytes that the stack can hold.
+        /// </summary>
+        public int Capacity
+        {
+            get
+            {
+                return m_capacity;
+            }
+        }
+        /// <summary>
+        /// Push a byte onto the stack.
+        /// </summary>
+        /// <param name="b"> </param>
+        public void Push(byte b)
+        {
+            if (m_count >= m_capacity)
+            {
+                IncreaseSize();
+            }
+            m_buffer[m_count] = b;
+            m_count++;
+        }
+        /// <summary>
+        /// Pop a byte off of the stack.
+        /// </summary>
+        public byte Pop()
+        {
+            if (m_count <= 0)
+            {
+                throw new InvalidOperationException("Empty stack");
+            }
+            m_count--;
+            byte b =  m_buffer[m_count];
+            return b;
+        }
+        /// <summary>
+        /// Non-destructively read the byte on the top of the stack.
+        /// </summary>
+        public byte Peek()
+        {
+            if (m_count <= 0)
+            {
+                throw new InvalidOperationException("Empty stack");
+            }
+            return m_buffer[m_count - 1];
+        }
+        /// <summary>
+        /// Converts to byte[] by making a trimmed copy.
+        /// </summary>
+        /// <param name="bs">The ByteStack to convert to a byte array.</param>
+        /// <returns>The byte array containing a copy of the passed in ByteStack.</returns>
+        public static implicit operator byte[](ByteStack bs)
+        {
+            if (bs.m_count == 0)
+            {
+                return new byte[0];
+            }
+            byte[] newBuf = new byte[bs.m_count];
+            Buffer.BlockCopy(bs.m_buffer, 0, newBuf, 0, bs.m_count);
+            return newBuf;
+        }
+        /// <summary>
+        /// Convert to a string, using the default encoding.  This is probably not
+        /// right, but it's really nice for debugging and testing.
+        /// </summary>
+        public override string ToString()
+        {
+            return ENCODING.GetString(m_buffer, 0, m_count);
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/collections/GraphNode.cs b/lib/jabber-net/bedrock/collections/GraphNode.cs
new file mode 100644
index 0000000..9e2ac11
--- /dev/null
+++ b/lib/jabber-net/bedrock/collections/GraphNode.cs
@@ -0,0 +1,150 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using bedrock.util;
+namespace bedrock.collections
+{
+    /// <summary>
+    /// A node in a Graph, such as a Tree
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class GraphNode : IEnumerable
+    {
+        private object      m_key      = null;
+        private object      m_data     = null;
+        private GraphNode   m_parent   = null;
+        private IDictionary m_children = null;
+        private bool        m_sorted   = true;
+        /// <summary>
+        /// Creates a new node, with key and data.
+        /// </summary>
+        /// <param name="key">The key used to retrieve the data</param>
+        /// <param name="data">The data in the node</param>
+        public GraphNode(object key, object data) : this(key, data, true)
+        {
+        }
+        /// <summary>
+        /// Creates a new node, with key and data, possibly having
+        /// sorted children. 
+        /// </summary>
+        /// <param name="key">The key used to retrieve the data</param>
+        /// <param name="data">The data in the node</param>
+        /// <param name="sorted">Should the children be sorted?</param>
+        public GraphNode(object key, object data, bool sorted)
+        {
+            m_key    = key;
+            m_data   = data;
+            m_sorted = sorted;
+            if (m_sorted)
+            {
+                m_children = new SortedList();
+            }
+            else
+            {
+                m_children = new Hashtable();
+            }
+        }
+
+        /// <summary>
+        /// The key for this node.
+        /// </summary>
+        public object Key
+        {
+            get { return m_key; }
+        }
+
+        /// <summary>
+        /// The data associated with this node.
+        /// </summary>
+        public object Data
+        {
+            get { return m_data; }
+            set { m_data = value; }
+        }
+        
+        /// <summary>
+        /// Adds a new child node
+        /// </summary>
+        /// <param name="key">The key for the child</param>
+        /// <param name="data">The data for the child</param>
+        /// <returns>The child node added to the graph.</returns>
+        public GraphNode Add(object key, object data)
+        {
+            GraphNode n = new GraphNode(key, data, m_sorted);
+            n.m_parent = this;
+            m_children.Add(key, n);
+            return n;
+        }
+        /// <summary>
+        /// Retrieves a child node, based on the key.
+        /// </summary>
+        public object this[object key]
+        {
+            get
+            {
+                return ((GraphNode)m_children[key]).m_data;
+            }
+        }
+        /// <summary>
+        /// Determines whether this is a root node.
+        /// </summary>
+        public bool IsRoot
+        {
+            get
+            {
+                return m_parent == null;
+            }
+        }
+        #region IEnumerable
+
+        /// <summary>
+        /// Iterate over the child nodes
+        /// </summary>
+        /// <returns></returns>
+        public IEnumerator GetEnumerator()
+        {
+            return new GraphNodeEnumerator(this);
+        }
+
+        private class GraphNodeEnumerator : IEnumerator
+        {
+            private IEnumerator m_arrayEnumerator;
+            public GraphNodeEnumerator(GraphNode n)
+            {
+                m_arrayEnumerator = n.m_children.GetEnumerator();
+            }
+
+            public object Current
+            {
+                get
+                {
+                    return ((GraphNode)m_arrayEnumerator.Current).m_data;
+                }
+            }
+
+            public bool MoveNext()
+            {
+                return m_arrayEnumerator.MoveNext();
+            }
+
+            public void Reset()
+            {
+                m_arrayEnumerator.Reset();
+            }
+        }
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/bedrock/collections/ISet.cs b/lib/jabber-net/bedrock/collections/ISet.cs
new file mode 100644
index 0000000..f807621
--- /dev/null
+++ b/lib/jabber-net/bedrock/collections/ISet.cs
@@ -0,0 +1,66 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using bedrock.util;
+
+namespace bedrock.collections
+{
+    /// <summary>
+    /// Set operations.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public interface ISet : ICollection
+    {
+        /// <summary>
+        /// Add an object to the set
+        /// </summary>
+        /// <param name="o">The object to add</param>
+        /// <exception cref="ArgumentException">object was already in the set.</exception>
+        void Add(object o);
+
+        /// <summary>
+        /// Remove the given object from the set.  If the object is not in the set, this is a no-op.
+        /// </summary>
+        /// <param name="o">The object to remove.</param>
+        void Remove(object o);
+
+        /// <summary>
+        /// Removes all items from the set.
+        /// </summary>
+        void Clear();
+
+        /// <summary>
+        /// Is the given object in the set?
+        /// </summary>
+        /// <param name="o">The object to search for.</param>
+        /// <returns>True if the object is in the set.</returns>
+        bool Contains(object o);
+
+        /// <summary>
+        /// Returns a new collection that contains all of the items that
+        /// are in this set or the other set.
+        /// </summary>
+        /// <param name="other">Second set to combine with this one.</param>
+        /// <returns>Combined set.</returns>
+        ISet Union(ISet other);
+
+        /// <summary>
+        /// Return a new collection that contains all of the items that
+        /// are in this list *and* the other set.
+        /// </summary>
+        ISet Intersection(ISet other);
+    }
+}
diff --git a/lib/jabber-net/bedrock/collections/IndexedTrie.cs b/lib/jabber-net/bedrock/collections/IndexedTrie.cs
new file mode 100644
index 0000000..9487778
--- /dev/null
+++ b/lib/jabber-net/bedrock/collections/IndexedTrie.cs
@@ -0,0 +1,146 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using bedrock.util;
+namespace bedrock.collections
+{
+    /// <summary>
+    /// A Trie that is searchable for substrings.  Uses a separate set of indexes
+    /// to allow entry into the Trie at any point.  Yes, this
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class IndexedTrie : Trie
+    {
+        private Tree m_indexes    = new Tree();
+        private int  m_maxResults = 100;
+
+        /// <summary>
+        /// Creates the indexed trie.
+        /// </summary>
+        public IndexedTrie()  {}
+
+        /// <summary>
+        /// Creates the indexed trie and sets the maximum number of query results returned.
+        /// </summary>
+        /// <param name="maxResults">Maximum number of query results returned.</param>
+        public IndexedTrie(int maxResults)
+        {
+            m_maxResults = maxResults;
+        }
+
+        /// <summary>
+        /// The maximum number of results to return from any query.  This is an approximate number.
+        /// </summary>
+        public int MaxResults
+        {
+            get
+            {
+                return m_maxResults;
+            }
+            set
+            {
+                m_maxResults = value;
+            }
+        }
+        /// <summary>
+        /// Finds the index for the given byte.
+        /// </summary>
+        protected ArrayList this[byte b]
+        {
+            get
+            {
+                return (ArrayList) m_indexes[b];
+            }
+        }
+        /// <summary>
+        /// Traverse the trie, computing indexes.
+        /// </summary>
+        /// <param name="n"> </param>
+        /// <param name="data"> </param>
+        private bool IndexWalker(TrieNode n, object data)
+        {
+            if (n.Parent != null)
+            {
+                 this[n.Byte].Add(new WeakReference(n));
+            }
+            return true;
+        }
+        /// <summary>
+        /// Computes the index.
+        /// </summary>
+        public void Index()
+        {
+            Traverse(new TrieWalker(IndexWalker), null);
+            foreach (ArrayList al in m_indexes)
+            {
+                al.TrimToSize();
+            }
+        }
+        /// <summary>
+        /// Copy the keys from the sub-tree into an ArrayList.
+        /// </summary>
+        /// <param name="n"> </param>
+        /// <param name="data"> </param>
+        /// <param name="key"> </param>
+        private bool CopyWalker(TrieNode n, object data, ByteStack key)
+        {
+            if (n.Value != null)
+            {
+                ArrayList al = (ArrayList) data;
+                al.Add((byte[]) key);
+                if (al.Count >= m_maxResults)
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+        /// <summary>
+        /// Return a list of keys that contain the given substring.
+        /// </summary>
+        /// <param name="lookFor">The substring to search for.</param>
+        public ArrayList SubString(byte[] lookFor)
+        {
+            ArrayList starts = (ArrayList) m_indexes[lookFor[0]];
+            ArrayList finds = new ArrayList();
+            byte[] nBuf = new byte[lookFor.Length - 1];
+            Buffer.BlockCopy(lookFor, 1, nBuf, 0, lookFor.Length - 1);
+            TrieKeyWalker w = new TrieKeyWalker(CopyWalker);
+            foreach (WeakReference wref in starts)
+            {
+                if (finds.Count >= m_maxResults)
+                {
+                    break;
+                }
+                TrieNode first = (TrieNode) wref.Target;
+                if (first == null)
+                {
+                    // node got removed out from underneath.
+                    starts.Remove(wref);
+                }
+                else
+                {
+                    TrieNode last = FindNode(nBuf, first, false);
+                    if (last != null)
+                    {
+                        Traverse(w, finds, last, new ByteStack(last.Key));
+                    }
+                }
+            }
+            return finds;
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/collections/LinkedList.cs b/lib/jabber-net/bedrock/collections/LinkedList.cs
new file mode 100644
index 0000000..a8ac979
--- /dev/null
+++ b/lib/jabber-net/bedrock/collections/LinkedList.cs
@@ -0,0 +1,565 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using bedrock.util;
+namespace bedrock.collections
+{
+    /// <summary>
+    /// A doubly-linked list implementation, with a sentinal wrap-around
+    /// m_header.  Yes, it <b>does</b> seem like this should have been included
+    /// in System.Collections.  This may be a nicer implementation of Queue
+    /// than the one in System.Collections, which uses an array.  YMMV.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class LinkedList : IList
+    {
+        private Node      m_header     = new Node(null, null, null);
+        private int       m_size       = 0;
+        private int       m_modCount   = 0;
+        private IComparer m_comparator = null;
+        private bool      m_readOnly   = false;
+        private bool      m_synch      = false;
+        /// <summary>
+        /// Creates an empty list.
+        /// </summary>
+        public LinkedList()
+        {
+            m_header.next = m_header.previous = m_header;
+        }
+        /// <summary>
+        /// Create a list with the targets of the given
+        /// enumeration copied into it.
+        /// </summary>
+        /// <param name="e"></param>
+        public LinkedList(IEnumerable e) : this()
+        {
+            foreach (object o in e)
+            {
+                Add(o);
+            }
+        }
+        #region IEnumerable
+        /// <summary>
+        /// Iterate over the list.
+        /// </summary>
+        /// <returns></returns>
+        public IEnumerator GetEnumerator()
+        {
+            return new ListEnumerator(this);
+        }
+        #endregion
+        #region ICollection
+        /// <summary>
+        /// How many elements in the list?
+        /// </summary>
+        public int Count
+        {
+            get
+            {
+                return m_size;
+            }
+        }
+
+        /// <summary>
+        /// Determines if the list is read-only (Can the user add or remove an item from this list).
+        /// </summary>
+        public bool IsReadOnly
+        {
+            get
+            {
+                return m_readOnly;
+            }
+            set
+            {
+                m_readOnly = value;
+            }
+        }
+
+        /// <summary>
+        /// Is the list thread-safe?
+        /// TODO: implement thread-safe
+        /// </summary>
+        public bool IsSynchronized
+        {
+            get
+            {
+                return m_synch;
+            }
+            set
+            {
+                m_synch = value;
+            }
+        }
+
+        /// <summary>
+        /// The object to synchronize on.
+        /// TODO: implement settable SyncRoot
+        /// </summary>
+        public object SyncRoot
+        {
+            get
+            {
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Copy this list to the given array.
+        /// </summary>
+        /// <param name="array">Array to copy into</param>
+        /// <param name="index">Index to start copying at</param>
+        public void CopyTo(Array array, int index)
+        {
+            int i = index;
+            foreach (object o in this)
+            {
+                array.SetValue(o, i++);
+            }
+        }
+        #endregion
+        #region IList
+        /// <summary>
+        /// Gets the indexth element by walking the list.
+        /// </summary>
+        public object this[int index]
+        {
+            get
+            {
+                return GetNode(index).element;
+            }
+            set
+            {
+                GetNode(index).element = value;
+            }
+        }
+
+        /// <summary>
+        /// Insert an element at the end of the list
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        public int Add(object value)
+        {
+            AddBefore(value, m_header);
+            return m_size-1;
+        }
+
+        /// <summary>
+        /// Remove all of the elements.
+        /// </summary>
+        public void Clear()
+        {
+            m_modCount++;
+            m_header.next = m_header.previous = m_header;
+            m_size = 0;
+        }
+
+        /// <summary>
+        /// Is the given object in the list?
+        /// </summary>
+        /// <param name="value">The object to find</param>
+        /// <returns>True if the object is in the list</returns>
+        public bool Contains(object value)
+        {
+            return IndexOf(value) != -1;
+        }
+
+        /// <summary>
+        /// Determines where in the index the specified object exists.
+        /// </summary>
+        /// <param name="value">The object to find</param>
+        /// <returns>The position of the object in the list, or -1 if not found</returns>
+        public int IndexOf(object value)
+        {
+            int index = 0;
+            if (value == null)
+            {
+                for (Node e = m_header.next; e != m_header; e = e.next)
+                {
+                    if (e.element == null)
+                        return index;
+                    index++;
+                }
+            }
+            else
+            {
+                for (Node e = m_header.next; e != m_header; e = e.next)
+                {
+                    if (value.Equals(e.element))
+                        return index;
+                    index++;
+                }
+            }
+            return -1;
+        }
+
+        /// <summary>
+        /// Inserts an item into the list at the given index.
+        /// </summary>
+        /// <param name="index">The position to insert before</param>
+        /// <param name="value">The object to insert</param>
+        public void Insert(int index, object value)
+        {
+            if (index >= m_size)
+            {
+                AddBefore(value, m_header);
+            }
+            else
+            {
+                Node n = GetNode(index);
+                AddBefore(value, n);
+            }
+        }
+
+        /// <summary>
+        /// Always returns "false" for now.
+        /// TODO: implement fixed size
+        /// </summary>
+        public bool IsFixedSize
+        {
+            get { return false; }
+        }
+
+        /// <summary>
+        /// Finds the first matching object, and removes it from the list.
+        /// </summary>
+        /// <param name="value">The object to remove</param>
+        /// <exception cref="System.ArgumentException">Object not found</exception>
+        public void Remove(object value)
+        {
+            if (value == null)
+            {
+                for (Node e = m_header.next; e != m_header; e = e.next)
+                {
+                    if (e.element == null)
+                    {
+                        Remove(e);
+                        return;
+                    }
+                }
+            }
+            else
+            {
+                for (Node e = m_header.next; e != m_header; e = e.next)
+                {
+                    if (value.Equals(e.element))
+                    {
+                        Remove(e);
+                        return;
+                    }
+                }
+            }
+            throw new ArgumentException("Object not found", "value");
+        }
+
+        /// <summary>
+        /// Removes the indexth element from the list.
+        /// </summary>
+        /// <param name="index">The index of the element to delete</param>
+        public void RemoveAt(int index)
+        {
+            Node e = GetNode(index);
+            Remove(e);
+        }
+        #endregion
+
+        #region Queue
+        /// <summary>
+        /// Inserts an element at the end of the list.
+        /// </summary>
+        /// <param name="value">Element to insert.</param>
+        public void Enqueue(object value)
+        {
+            AddBefore(value, m_header);
+        }
+
+        /// <summary>
+        /// Remove and return the element at the front of the list
+        /// </summary>
+        /// <returns>The element at the end of the list</returns>
+        public object Dequeue()
+        {
+            object value = m_header.next.element;
+            Remove(m_header.next);
+            return value;
+        }
+
+        /// <summary>
+        /// Retrieve the element at the front of the list, without removing it.
+        /// </summary>
+        /// <returns></returns>
+        public object Peek()
+        {
+            return m_header.next.element;
+        }
+        #endregion
+        #region Stack
+        /// <summary>
+        /// Add an element to the front of the list.
+        /// </summary>
+        /// <param name="value"></param>
+        public void Push(object value)
+        {
+            AddBefore(value, m_header.next);
+        }
+
+        /// <summary>
+        /// Retrieve and remove the element at the front of the list.
+        /// </summary>
+        /// <returns></returns>
+        public object Pop()
+        {
+            return Dequeue();
+        }
+        #endregion Stack
+        #region private
+        private Node GetNode(int index)
+        {
+            if ((index < 0) || (index >= m_size))
+            {
+                throw new IndexOutOfRangeException("Must choose index between 0 and " +
+                                                   (m_size-1));
+            }
+
+            Node e = m_header;
+            // start from end if closer
+            if (index < m_size/2)
+            {
+                for (int i = 0; i <= index; i++)
+                    e = e.next;
+            }
+            else
+            {
+                for (int i = m_size; i > index; i--)
+                    e = e.previous;
+            }
+            return e;
+        }
+
+        private Node AddBefore(object value, Node n)
+        {
+            if (m_readOnly)
+            {
+                throw new InvalidOperationException("Cannot add to a read-only list");
+            }
+
+            if (m_synch)
+            {
+                lock (this)
+                {
+                    return UncheckedAdd(value, n);
+                }
+            }
+            else
+            {
+                return UncheckedAdd(value, n);
+            }
+        }
+
+        private Node UncheckedAdd(object value, Node n)
+        {
+            Node newNode = new Node(value, n, n.previous);
+            newNode.previous.next = newNode;
+            newNode.next.previous = newNode;
+            m_size++;
+            m_modCount++;
+            return newNode;
+        }
+
+        private void Remove(Node n)
+        {
+            if (n == m_header)
+                throw new InvalidOperationException("Deleting from an empty list");
+            if (m_readOnly)
+            {
+                throw new InvalidOperationException("Cannot remove from a read-only list");
+            }
+
+            if (m_synch)
+            {
+                lock (this)
+                {
+                    UncheckedRemove(n);
+                }
+            }
+            else
+            {
+                UncheckedRemove(n);
+            }
+        }
+
+        private void UncheckedRemove(Node n)
+        {
+            n.previous.next = n.next;
+            n.next.previous = n.previous;
+            m_size--;
+            m_modCount++;
+        }
+        #endregion
+        #region Object
+        /// <summary>
+        /// Comma-separated list of element.ToString()'s.
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            System.Text.StringBuilder sb = new System.Text.StringBuilder();
+            bool first = true;
+            foreach (object o in this)
+            {
+                if (!first)
+                {
+                    sb.Append(", ");
+                }
+                else
+                {
+                    first = false;
+                }
+
+                if (o == null)
+                    sb.Append("null");
+                else
+                    sb.Append(o.ToString());
+            }
+            return sb.ToString();
+        }
+        #endregion
+        #region newstuff
+        /// <summary>
+        /// Insert in order.
+        /// </summary>
+        /// <param name="value">Value to insert.</param>
+        /// <returns>The position of the insertion point.</returns>
+        public int Insert(object value)
+        {
+            if (m_comparator == null)
+            {
+                m_comparator = Comparer.Default;
+            }
+
+            // null less than anything
+            if (value == null)
+            {
+                AddBefore(null, m_header.next);
+                return 0;
+            }
+
+            int index=0;
+            int c;
+            for (Node n = m_header.next; n != m_header; n = n.next, index++)
+            {
+                c = m_comparator.Compare(value, n.element);
+                if (c < 0)
+                {
+                    AddBefore(value, n);
+                    return index;
+                }
+                else if (c == 0) // equal.  replace
+                {
+                    n.element = value;
+                    return index;
+                }
+            }
+
+            // got to the end without inserting.  Put it on the end.
+            AddBefore(value, m_header);
+            return m_size-1;
+        }
+
+        /// <summary>
+        /// The object to use for comparisons.
+        /// </summary>
+        public IComparer Comparator
+        {
+            get
+            {
+                return m_comparator;
+            }
+
+            set
+            {
+                m_comparator = value;
+            }
+        }
+
+        /// <summary>
+        /// Returns a read-only linked list from the given enumeration.
+        /// </summary>
+        /// <param name="e">Collection to be copied over to the read-only list.</param>
+        /// <returns>The new read-only list.</returns>
+        public static LinkedList ReadOnly(IEnumerable e)
+        {
+            LinkedList ll = new LinkedList(e);
+            ll.m_readOnly = true;
+            return ll;
+        }
+        #endregion
+        #region enumerator
+        private class ListEnumerator : IEnumerator
+        {
+            private LinkedList  list    = null;
+            private Node        current = null;
+            private int         mods    = -1;
+
+            public ListEnumerator(LinkedList ll)
+            {
+                list    = ll;
+                current = list.m_header;
+                mods    = list.m_modCount;
+            }
+
+            public object Current
+            {
+                get
+                {
+                    if (list.m_modCount != mods)
+                    {
+                        throw new InvalidOperationException("Changed list during iterator");
+                    }
+                    return current.element;
+                }
+            }
+
+            public bool MoveNext()
+            {
+                current = current.next;
+                return current != list.m_header;
+            }
+
+            public void Reset()
+            {
+                current = list.m_header;
+                mods = list.m_modCount;
+            }
+        }
+        #endregion
+        #region Node
+        private class Node
+        {
+            public object element;
+            public Node  next;
+            public Node  previous;
+
+            public Node(object element, Node next, Node previous)
+            {
+                this.element = element;
+                this.next = next;
+                this.previous = previous;
+            }
+        }
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/bedrock/collections/Set.cs b/lib/jabber-net/bedrock/collections/Set.cs
new file mode 100644
index 0000000..86bdfb6
--- /dev/null
+++ b/lib/jabber-net/bedrock/collections/Set.cs
@@ -0,0 +1,229 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using bedrock.util;
+
+namespace bedrock.collections
+{
+    /// <summary>
+    /// The different ways a set can be implemented.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum SetImplementation
+    {
+        /// <summary>
+        /// Hash table.
+        /// </summary>
+        Hashtable,
+        /// <summary>
+        /// Red/Black tree.
+        /// </summary>
+        Tree,
+        /// <summary>
+        /// Skip List.
+        /// </summary>
+        SkipList
+    }
+
+    /// <summary>
+    /// Set backed into a Tree.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Set : ISet
+    {
+        private static readonly object s_nothing = new object();
+
+        private IDictionary m_dict;
+
+        /// <summary>
+        /// Creates a new, empty Set backed into a hash table.
+        /// </summary>
+        public Set()
+        {
+            m_dict = new Hashtable();
+        }
+
+        /// <summary>
+        /// Creates a set with the given back-end implementation.
+        /// </summary>
+        /// <param name="impl">How to implement the set.</param>
+        public Set(SetImplementation impl)
+        {
+            switch (impl)
+            {
+                case SetImplementation.Hashtable:
+                    m_dict = new Hashtable();
+                    break;
+                case SetImplementation.Tree:
+                    m_dict = new Tree();
+                    break;
+                case SetImplementation.SkipList:
+                    m_dict = new SkipList();
+                    break;
+                default:
+                    throw new NotImplementedException("Unknown SetImplementation");
+            }
+        }
+
+        #region Implementation of ISet
+        /// <summary>
+        /// Adds an object to the set.
+        /// </summary>
+        /// <param name="o">The object to add</param>
+        /// <exception cref="ArgumentException">object was already in the set.</exception>
+        public void Add(object o)
+        {
+            if (!m_dict.Contains(o))
+                m_dict.Add(o, s_nothing);
+        }
+
+        /// <summary>
+        /// Removes the given object from the set.
+        /// There is no exception thrown if the object is not in the set.
+        /// </summary>
+        /// <param name="o">The object to remove.</param>
+        public void Remove(object o)
+        {
+            m_dict.Remove(o);
+        }
+
+        /// <summary>
+        /// Removes all items from the set.
+        /// </summary>
+        public void Clear()
+        {
+            m_dict.Clear();
+        }
+
+        /// <summary>
+        /// Determines if the given object is in the set.
+        /// </summary>
+        /// <param name="o">The object to search for.</param>
+        /// <returns>True if the object is in the set.</returns>
+        public bool Contains(object o)
+        {
+            return m_dict.Contains(o);
+        }
+
+        /// <summary>
+        /// Returns a new collection that contains all of the items that
+        /// are in this set or the other set.
+        /// </summary>
+        /// <param name="other">Second set to combine.</param>
+        /// <returns>Combined set.</returns>
+        public bedrock.collections.ISet Union(bedrock.collections.ISet other)
+        {
+            throw new NotImplementedException();
+        }
+
+        /// <summary>
+        /// Returns a new collection that contains all of the items that
+        /// are in this list *and* the other set.
+        /// </summary>
+        /// <param name="other">
+        /// Other set to intersect with.
+        /// </param>
+        /// <returns>Combined set.</returns>
+        public bedrock.collections.ISet Intersection(bedrock.collections.ISet other)
+        {
+            throw new NotImplementedException();
+        }
+        #endregion
+
+        #region Implementation of ICollection
+        /// <summary>
+        /// Copies the elements of the ICollection to an Array, starting at a particular Array index.
+        /// </summary>
+        /// <param name="array">The array to copy.</param>
+        /// <param name="index">The index to start at.</param>
+        public void CopyTo(System.Array array, int index)
+        {
+            int count = index;
+            foreach (object o in this)
+            {
+                array.SetValue(o, count);
+                count++;
+            }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether access to the ICollection is synchronized (thread-safe).
+        /// </summary>
+        public bool IsSynchronized
+        {
+            get { return m_dict.IsSynchronized; }
+        }
+
+        /// <summary>
+        /// Gets the number of items in the set.
+        /// </summary>
+        public int Count
+        {
+            get { return m_dict.Count; }
+        }
+
+        /// <summary>
+        /// Gets an object that can be used to synchronize access to the ICollection.
+        /// </summary>
+        public object SyncRoot
+        {
+            get { return m_dict.SyncRoot; }
+        }
+        #endregion
+
+        #region Implementation of IEnumerable
+        /// <summary>
+        /// Returns an enumerator that iterates through all items in the set.
+        /// </summary>
+        /// <returns>An IEnumerator for the entire set.</returns>
+        public System.Collections.IEnumerator GetEnumerator()
+        {
+            return new TreeSetEnumerator(m_dict);
+        }
+        #endregion
+
+        private class TreeSetEnumerator : IEnumerator
+        {
+            private IEnumerator m_enum;
+
+            public TreeSetEnumerator(IDictionary e)
+            {
+                m_enum = e.GetEnumerator();
+            }
+
+            #region Implementation of IEnumerator
+            public void Reset()
+            {
+                m_enum.Reset();
+            }
+
+            public bool MoveNext()
+            {
+                return m_enum.MoveNext();
+            }
+
+            public object Current
+            {
+                get
+                {
+                    DictionaryEntry entry = (DictionaryEntry) m_enum.Current;
+                    return entry.Key;
+                }
+            }
+            #endregion
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/collections/SkipList.cs b/lib/jabber-net/bedrock/collections/SkipList.cs
new file mode 100644
index 0000000..0ea74b7
--- /dev/null
+++ b/lib/jabber-net/bedrock/collections/SkipList.cs
@@ -0,0 +1,519 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using System.Diagnostics;
+
+using bedrock.util;
+
+namespace bedrock.collections
+{
+    /// <summary>
+    /// Summary description for SkipList.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class SkipList : IEnumerable, IDictionary
+    {
+        /// <summary>
+        /// The default probability for adding new node levels.
+        /// .25 provides a good balance of speed and size.
+        /// .5 will be slightly less variable in run time,
+        /// and take up more space
+        /// </summary>
+        private const float DEFAULT_PROBABILITY = 0.25F;
+
+        /// <summary>
+        /// The maximum depth for searching.
+        /// log(1/p, n), where n is the max number of
+        /// expected nodes.  For the defaults, n = 4096.
+        /// The list will continue to work for larger lists,
+        /// but performance will start to degrade toward
+        /// that of a linear search to further you get
+        /// above n.
+        /// TODO: automatically reset max_level when Length
+        /// goes above n.
+        /// </summary>
+        private const int DEFAULT_MAX_LEVEL = 6;
+
+        private float        m_probability;
+        private int          m_max_level = DEFAULT_MAX_LEVEL;
+        private SkipListNode m_header;
+        private Random       m_rand = new Random();
+        private IComparer    m_comparator = System.Collections.Comparer.Default;
+        private int          m_count = 0;
+
+        /// <summary>
+        /// Creates a skiplist with the default probability (0.25).
+        /// </summary>
+        public SkipList() : this(DEFAULT_PROBABILITY, DEFAULT_MAX_LEVEL)
+        {
+        }
+
+        /// <summary>
+        /// Create a skiplist with the default max_level.
+        /// </summary>
+        /// <param name="probability">Probability of adding a new level</param>
+        public SkipList(float probability) : this(probability, DEFAULT_MAX_LEVEL)
+        {
+        }
+
+        /// <summary>
+        /// Create a skiplist.
+        /// </summary>
+        /// <param name="probability">Probability of adding a new level</param>
+        /// <param name="maxLevel">Highest level in the list</param>
+        public SkipList(float probability, int maxLevel)
+        {
+            m_probability = probability;
+            m_max_level = maxLevel;
+            m_header = new SkipListNode(1, new Ali(), null);
+        }
+
+        /// <summary>
+        /// Gets the current number of elements in the list.
+        /// </summary>
+        public int Count
+        {
+            get { return m_count; }
+        }
+
+        /// <summary>
+        /// Add an item to the list.
+        /// </summary>
+        /// <param name="key">Key for later retrieval.
+        /// Must implement IComparable.</param>
+        /// <param name="val">The value to store</param>
+        /// <exception cref="ArgumentException">Thrown if the same key is added twice</exception>
+        /// <exception cref="ArgumentNullException">Thrown if key is null</exception>
+        public void Add(object key, object val)
+        {
+            if (key == null)
+                throw new ArgumentNullException("key");
+
+            SkipListNode update = new SkipListNode(m_max_level);
+            SkipListNode n = m_header;
+            SkipListNode next;
+
+            for (int i=m_header.Level-1; i>=0; i--)
+            {
+                next = n[i];
+                while ((next != null) &&
+                       (m_comparator.Compare(next.Key, key) < 0))
+                {
+                    n = next;
+                    next = n[i];
+                }
+                update[i] = n;
+            }
+            if ((n.Level > 0) &&
+                (n[0] != null) &&
+                (m_comparator.Compare(n[0].Key, key) == 0))
+            { // already here
+                //n.Value = val;
+                throw new ArgumentException("Can't add the same key twice", "key");
+            }
+            else
+            { // need to insert
+                int level = RandomLevel();
+                int s = m_header.Level;
+                if (level > s)
+                {
+                    // this shouldn't happen any more.
+                    //Debug.Assert(false);
+                    m_header.Level = level;
+                    for (int i=s; i<level; i++)
+                    {
+                        update[i] = m_header;
+                    }
+                }
+
+                n = new SkipListNode(level, key, val);
+                for (int i=0; i<level; i++)
+                {
+                    n[i] = update[i][i];
+                    update[i][i] = n;
+                }
+                m_count++;
+            }
+        }
+
+        /// <summary>
+        /// Is the given key found in the tree?
+        /// </summary>
+        /// <param name="key">The key to search for</param>
+        /// <returns></returns>
+        public bool Contains(object key)
+        {
+            return GetNode(key) != null;
+        }
+
+        /// <summary>
+        /// Looks up the key, and returns the corresponding value, or null if not found.
+        /// </summary>
+        public object this[object key]
+        {
+            get
+            {
+                SkipListNode n = GetNode(key);
+                if (n == null)
+                    return null;
+                return n.Value;
+            }
+            set
+            {
+                Add(key, value);
+            }
+        }
+
+        /// <summary>
+        /// Remove all of the items from the list.
+        /// </summary>
+        public void Clear()
+        {
+            m_header = new SkipListNode(1, new Ali(), null);
+            m_count = 0;
+        }
+
+        /// <summary>
+        /// Removes the item associated with this key from the list.
+        /// </summary>
+        /// <param name="key">Object that implements IComparable</param>
+        public void Remove(object key)
+        {
+            if (key == null)
+                throw new ArgumentNullException("key");
+
+            SkipListNode update = new SkipListNode(m_max_level);
+            SkipListNode n = m_header;
+            SkipListNode next;
+
+            for (int i=m_header.Level-1; i>=0; i--)
+            {
+                next = n[i];
+                while ((next != null) &&
+                       (m_comparator.Compare(next.Key, key) < 0))
+                {
+                    n = next;
+                    next = n[i];
+                }
+                update[i] = n;
+            }
+            if (n.Level == 0)
+                return; // or assert
+
+            n = n[0];
+            if ((n == null) ||
+                (m_comparator.Compare(n.Key, key) != 0))
+            { // not found
+                return;  // or assert
+            }
+
+            for (int i=0; i<m_header.Level; i++)
+            {
+                if (update[i][i] != n)
+                    break;
+                update[i][i] = n[i];
+            }
+            // TODO: reset m_header level
+            m_count--;
+        }
+
+        /// <summary>
+        /// Returns true if the list will not accept more items than constructed with.
+        /// </summary>
+        public bool IsFixedSize
+        {
+            get
+            {
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// Returns true if one is unable to add or removed an item from this list.
+        /// </summary>
+        public bool IsReadOnly
+        {
+            get
+            {
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// Gets all of the keys in the list.
+        /// </summary>
+        public System.Collections.ICollection Keys
+        {
+            get
+            {
+                object[] keys = new object[m_count];
+                int count = 0;
+                foreach (DictionaryEntry e in this)
+                {
+                    keys[count++] = e.Key;
+                }
+                return keys;
+            }
+        }
+
+        /// <summary>
+        /// Gets all of the values in the list.
+        /// </summary>
+        public System.Collections.ICollection Values
+        {
+            get
+            {
+                object[] vals = new object[m_count];
+                CopyTo(vals, 0);
+                return vals;
+            }
+        }
+
+        /// <summary>
+        /// Iterate over the list
+        /// </summary>
+        /// <returns></returns>
+        public IDictionaryEnumerator GetEnumerator()
+        {
+            return new SkipListEnumerator(this);
+        }
+
+        #region IEnumerable
+        /// <summary>
+        /// Iterate over the list
+        /// </summary>
+        /// <returns></returns>
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return new SkipListEnumerator(this);
+        }
+        #endregion
+
+        /// <summary>
+        /// Copy the *values* from this list to the given array.
+        /// It's not clear from the .Net docs wether this should be
+        /// entries or values, so I chose values.
+        /// </summary>
+        /// <param name="array">The array to copy into</param>
+        /// <param name="arrayIndex">The index to start at</param>
+        public void CopyTo(System.Array array, int arrayIndex)
+        {
+            if (array == null)
+                throw new ArgumentNullException("array");
+            if (array.Rank != 1)
+                throw new ArgumentException("Array must be single dimensional", "array");
+            if (arrayIndex < 0)
+                throw new ArgumentOutOfRangeException("arrayIndex", "starting index may not be negative");
+            if (array.Length - arrayIndex < m_count)
+                throw new ArgumentException("Array too small", "array");
+
+            int count = arrayIndex;
+            foreach (DictionaryEntry e in this)
+            {
+                array.SetValue(e.Value, count++);
+            }
+        }
+
+        /// <summary>
+        /// Returns false, for now
+        /// </summary>
+        public bool IsSynchronized
+        {
+            get
+            {
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// Gets an object that can be used to synchronize access to ICollection.
+        /// </summary>
+        /// <exception cref="NotImplementedException">Currently this Property is not implemented.</exception>
+        public object SyncRoot
+        {
+            get
+            {
+                throw new NotImplementedException();
+            }
+        }
+
+        private SkipListNode GetNode(object key)
+        {
+            if (key == null)
+                throw new ArgumentNullException("key");
+
+            if (m_count == 0)
+                return null;
+
+            SkipListNode n = m_header;
+            SkipListNode next;
+
+            for(int i=m_header.Level-1; i>=0; i--)
+            {
+                next = n[i];
+                while((next != null) &&
+                    (m_comparator.Compare(next.Key, key) < 0))
+                {
+                    n = next;
+                    next = n[i];
+                }
+            }
+
+            // n should always be level > 0, now.
+            n = n[0];
+
+            if( (n != null) && (m_comparator.Compare(n.Key, key) == 0))
+                return n;
+            else
+                return null;
+        }
+
+        private int RandomLevel()
+        {
+            int level = 1;
+            while ((level < m_max_level-1) && (m_rand.NextDouble() < m_probability))
+            {
+                level++;
+            }
+
+            return level;
+        }
+
+        private class SkipListNode
+        {
+            private SkipListNode[] m_next;
+            private object m_key;
+            private object m_value;
+
+            public SkipListNode(int level) : this(level, null, null)
+            {
+            }
+
+            public SkipListNode(int level, object key, object val)
+            {
+                m_next  = new SkipListNode[level];
+                for (int i=0; i<level; i++)
+                    m_next[i] = null;
+                m_key   = key;
+                m_value = val;
+            }
+
+            public SkipListNode this[int i]
+            {
+                get { return m_next[i]; }
+                set { m_next[i] = value; }
+            }
+
+            public int Level
+            {
+                get { return m_next.Length; }
+                set
+                {
+                    Debug.Assert(value > m_next.Length);
+                    SkipListNode[] n = new SkipListNode[value];
+                    Array.Copy(m_next, 0, n, 0, m_next.Length);
+                    for (int i=m_next.Length; i<value; i++)
+                    {
+                        n[i] = null;
+                    }
+                    m_next = n;
+                }
+            }
+
+            public object Key
+            {
+                get { return m_key; }
+                set { m_key = value; }
+            }
+
+            public object Value
+            {
+                get { return m_value; }
+                set { m_value = value; }
+            }
+        }
+
+        /// <summary>
+        /// An object that is the greatest.
+        /// </summary>
+        private class Ali : IComparable
+        {
+            int IComparable.CompareTo(object obj)
+            {
+                return 1;
+            }
+        }
+
+        private class SkipListEnumerator : IDictionaryEnumerator
+        {
+            private SkipList     m_list;
+            private SkipListNode m_node;
+
+            public SkipListEnumerator(SkipList list)
+            {
+                m_list = list;
+                m_node = m_list.m_header;
+            }
+
+            public bool MoveNext()
+            {
+                Debug.Assert(m_node != null);
+
+                m_node = m_node[0];
+                return m_node != null;
+            }
+
+            public void Reset()
+            {
+                m_node = m_list.m_header;
+            }
+
+            public object Current
+            {
+                get
+                {
+                    if (m_node == m_list.m_header)
+                        throw new InvalidOperationException("Call MoveNext, first");
+                    return Entry;
+                }
+            }
+
+            public System.Collections.DictionaryEntry Entry
+            {
+                get
+                {
+                    return new System.Collections.DictionaryEntry(m_node.Key, m_node.Value);
+                }
+            }
+
+            public object Key
+            {
+                get
+                {
+                    return m_node.Key;
+                }
+            }
+
+            public object Value
+            {
+                get
+                {
+                    return m_node.Value;
+                }
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/collections/StringSet.cs b/lib/jabber-net/bedrock/collections/StringSet.cs
new file mode 100644
index 0000000..7d0b7a6
--- /dev/null
+++ b/lib/jabber-net/bedrock/collections/StringSet.cs
@@ -0,0 +1,440 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+using bedrock.util;
+
+namespace bedrock.collections
+{
+    /// <summary>
+    /// A set of strings, backed into a BitArray.  Any given string that is inserted
+    /// into any instance of a StringSet increases the size of all StringSets over time.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class StringSet : IEnumerable, IEnumerable<string>, ICloneable
+	{
+        private BitArray m_bits = null;
+
+        // List<T>.Add doesn't return an int.
+        private static ArrayList s_strings = new ArrayList();
+        private static Dictionary<string, int> s_bits = new Dictionary<string,int>();
+
+        /// <summary>
+        /// Create a new StringSet, which is empty, but sized for all strings seen so far.
+        /// </summary>
+        public StringSet()
+        {
+            m_bits = new BitArray(s_strings.Count);
+        }
+
+        /// <summary>
+        /// Create a new set with the contents of another set.
+        /// </summary>
+        /// <param name="other"></param>
+        public StringSet(StringSet other)
+        {
+            if (other != null)
+                m_bits = (BitArray)other.m_bits.Clone();
+        }
+
+        /// <summary>
+        /// Create a set with one string in it.
+        /// </summary>
+        /// <param name="str"></param>
+        public StringSet(string str) : this()
+        {
+            if (str != null)
+                this.Add(str);
+        }
+
+        /// <summary>
+        /// Create a set containing all of the strings from the specified array.
+        /// </summary>
+        /// <param name="arr"></param>
+        public StringSet(string[] arr) : this()
+        {
+            if (arr != null)
+                Add(arr);
+        }
+
+        private static int GetStringValue(string s)
+        {
+            int val = -1;
+            
+            lock (s_bits)
+            {
+                if (!s_bits.TryGetValue(s, out val))
+                {
+                    s_bits[s] = val = s_strings.Add(s);
+                }
+            }
+            return val;
+        }
+
+        /// <summary>
+        /// Add a string to this set.  If it is already in the set, this is a no-op.
+        /// </summary>
+        /// <param name="s"></param>
+        public void Add(string s)
+        {
+            int val = GetStringValue(s);
+            if (val >= m_bits.Length)
+                m_bits.Length = s_strings.Count;
+            m_bits[val] = true;
+        }
+
+        /// <summary>
+        /// Add all of the strings from the given set to this set.
+        /// </summary>
+        /// <param name="set"></param>
+        public void Add(StringSet set)
+        {
+            // Lengthen this one to be able to hold everything in the other set, as well.
+            m_bits.Length = set.m_bits.Length = Math.Max(m_bits.Length, set.m_bits.Length);
+            m_bits.Or(set.m_bits);
+        }
+
+        /// <summary>
+        /// Add all of the strings from the given array to this set.
+        /// </summary>
+        /// <param name="arr"></param>
+        public void Add(string[] arr)
+        {
+            foreach (string s in arr)
+                Add(s);
+        }
+
+        /// <summary>
+        /// Remove the given string from this set.
+        /// </summary>
+        /// <param name="s"></param>
+        public void Remove(string s)
+        {
+            int val = GetStringValue(s);
+            if (val >= m_bits.Length)
+                return;
+            m_bits[val] = false;
+        }
+
+        /// <summary>
+        /// Remove all of the strings from the given set from this set.
+        /// </summary>
+        /// <param name="set"></param>
+        public void Remove(StringSet set)
+        {
+            m_bits.Length = set.m_bits.Length = Math.Max(m_bits.Length, set.m_bits.Length);
+            // Not is destructive.  Stupid.
+            BitArray os = (BitArray)set.m_bits.Clone();
+            os.Not();
+            m_bits.And(os);
+        }
+
+        /// <summary>
+        /// Clear all of the strings from this set.
+        /// </summary>
+        public void Clear()
+        {
+            m_bits.SetAll(false);
+        }
+
+        /// <summary>
+        /// Is this string in the set?
+        /// </summary>
+        /// <param name="s"></param>
+        /// <returns></returns>
+        public bool Contains(string s)
+        {
+            int val = GetStringValue(s);
+            if (val >= m_bits.Length)
+                return false;
+            return m_bits[val];            
+        }
+
+        /// <summary>
+        /// Gets or sets whether this string is in the set.
+        /// </summary>
+        /// <param name="s"></param>
+        /// <returns></returns>
+        public bool this[string s]
+        {
+            get { return Contains(s); }
+            set
+            {
+                if (value)
+                    Add(s);
+                else
+                    Remove(s);
+            }
+        }
+
+        /// <summary>
+        /// How many strings are in the set?
+        /// May be slower than you expect, at the moment.
+        /// </summary>
+        public int Count
+        {
+            get
+            {
+                int c = 0;
+                foreach (bool b in m_bits)
+                {
+                    if (b)
+                        c++;
+                }
+                return c;
+            }
+        }
+
+        #region operators
+        /// <summary>
+        /// Add two StringSets together, returning a new set.
+        /// </summary>
+        /// <param name="one"></param>
+        /// <param name="two"></param>
+        /// <returns></returns>
+        public static StringSet operator +(StringSet one, StringSet two)
+        {
+            StringSet n = new StringSet(one);
+            n.Add(two);
+            return n;
+        }
+
+        /// <summary>
+        /// Returns a new set containing the contents of the first set as well as the
+        /// other string.
+        /// </summary>
+        /// <param name="set"></param>
+        /// <param name="str"></param>
+        /// <returns></returns>
+        public static StringSet operator +(StringSet set, string str)
+        {
+            StringSet n = new StringSet(set);
+            n.Add(str);
+            return n;
+        }
+
+        /// <summary>
+        /// Returns a new set containing everything from the first set that isn't in
+        /// the second set.
+        /// </summary>
+        /// <param name="one"></param>
+        /// <param name="two"></param>
+        /// <returns></returns>
+        public static StringSet operator -(StringSet one, StringSet two)
+        {
+            StringSet n = new StringSet(one);
+            n.Remove(two);
+            return n;
+        }
+
+        /// <summary>
+        /// Returns a new set containing everything from the first except the specified
+        /// string.
+        /// </summary>
+        /// <param name="set"></param>
+        /// <param name="str"></param>
+        /// <returns></returns>
+        public static StringSet operator -(StringSet set, string str)
+        {
+            StringSet n = new StringSet(set);
+            n.Remove(str);
+            return n;
+        }
+
+        /// <summary>
+        /// Is this set equal to another one?
+        /// Warning: this is about 32x slower than it should be.
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <returns></returns>
+        public override bool Equals(object obj)
+        {
+            if ((object)this == obj)
+                return true;
+            StringSet set = obj as StringSet;
+            if (set == null)
+                return false;
+
+            // BitArray.Equals is useless.  
+            // You'd also like to just compare the internal ints, 
+            // but BitArray is sealed.  Thx, MS.
+
+            // it's easiest to just stretch everythin out to the longest.
+            int max = Math.Max(this.m_bits.Length, set.m_bits.Length);
+            if (this.m_bits.Length != max)
+                this.m_bits.Length = max;
+            if (set.m_bits.Length != max)
+                set.m_bits.Length = max;
+
+            for (int i = 0; i < max; i++)
+            {
+                if (this.m_bits[i] != set.m_bits[i])
+                    return false;
+            }
+            
+            return true;
+        }
+
+        /// <summary>
+        /// Hashcode for the current contents of the list.
+        /// SLOW!
+        /// </summary>
+        /// <returns></returns>
+        public override int GetHashCode()
+        {
+            // Again, if I wrote a BitArray, it's GetHashCode would work, probably by
+            // adding and rotating the ints.
+            int hash = 0;
+            foreach (string s in this)
+            {
+                hash ^= s.GetHashCode();
+            }
+            return hash;
+        }
+        #endregion
+
+        /// <summary>
+        /// Get all of the strings that are currently in the set.
+        /// No guarantee of order.
+        /// </summary>
+        /// <returns></returns>
+        public string[] GetStrings()
+        {
+            string[] ret = new string[this.Count];
+            int i = 0;
+            foreach (string s in this)
+            {
+                ret[i++] = s;
+            }
+            return ret;
+        }
+
+        /// <summary>
+        /// All of the strings from the set, newline-separated.
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            System.IO.StringWriter sw = new System.IO.StringWriter();
+            for (int i = 0; i < m_bits.Length; i++)
+            {
+                if (m_bits[i])
+                    sw.WriteLine(s_strings[i]);
+            }
+            return sw.ToString();
+        }
+
+        #region IEnumerable Members
+
+        /// <summary>
+        /// Enumerate over the strings in the set.
+        /// </summary>
+        /// <returns></returns>
+        public IEnumerator GetEnumerator()
+        {
+            return new StringSetEnumerator(this);
+        }
+
+        #endregion
+
+        #region IEnumerable<string> Members
+
+        /// <summary>
+        /// Enumerate over the strings in the set.
+        /// </summary>
+        /// <returns></returns>
+        IEnumerator<string> IEnumerable<string>.GetEnumerator()
+        {
+            return new StringSetEnumerator(this);
+        }
+
+        #endregion
+
+        #region ICloneable Members
+
+        /// <summary>
+        /// Return a copy of this set.
+        /// </summary>
+        /// <returns></returns>
+        public object Clone()
+        {
+            return new StringSet(this);
+        }
+
+        #endregion
+
+        private class StringSetEnumerator : IEnumerator<string>
+        {
+            StringSet m_set;
+            int m_cur = -1;
+
+            public StringSetEnumerator(StringSet set)
+            {
+                m_set = set;
+            }
+
+            #region IEnumerator<string> Members
+
+            public string Current
+            {
+                get 
+                {
+                    if ((m_cur < 0) || (m_cur >= m_set.m_bits.Length))
+                        throw new InvalidOperationException("Call to current outside of MoveNext");
+                    return (string)StringSet.s_strings[m_cur];
+                }
+            }
+
+            #endregion
+
+            #region IDisposable Members
+
+            public void Dispose()
+            {
+                m_set = null;
+            }
+
+            #endregion
+
+            #region IEnumerator Members
+
+            object IEnumerator.Current
+            {
+                get 
+                {
+                    return this.Current;
+                }
+            }
+
+            public bool MoveNext()
+            {
+                while (++m_cur < m_set.m_bits.Length)
+                {
+                    if (m_set.m_bits[m_cur])
+                        return true;
+                }
+                return false;
+            }
+
+            public void Reset()
+            {
+                m_cur = -1;
+            }
+
+            #endregion
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/collections/Tree.cs b/lib/jabber-net/bedrock/collections/Tree.cs
new file mode 100644
index 0000000..eb056af
--- /dev/null
+++ b/lib/jabber-net/bedrock/collections/Tree.cs
@@ -0,0 +1,839 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using bedrock.util;
+namespace bedrock.collections
+{
+    /// <summary>
+    /// A basic balanced tree implementation.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Tree : IEnumerable, IDictionary
+    {
+        private Node      root       = null;
+        private int       size       = 0;
+        private int       modCount   = 0;
+        private IComparer comparator = System.Collections.Comparer.Default;
+        //private bool      readOnly   = false;
+        //private bool      synch      = false;
+        /// <summary>
+        /// Construct an empty tree
+        /// </summary>
+        public Tree()
+        {
+            //
+            // TODO: Add Constructor Logic here
+            //
+        }
+        #region IEnumerable
+        /// <summary>
+        /// Iterate over the tree
+        /// </summary>
+        /// <returns></returns>
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return new TreeEnumerator(this);
+        }
+        #endregion
+        #region ICollection
+        /// <summary>
+        /// The number of items in the tree.
+        /// </summary>
+        public int Count
+        {
+            get
+            {
+                return size;
+            }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether access to the tree is synchronized in thread-safe mode.
+        /// Currently, it only returns false.
+        /// </summary>
+        public bool IsSynchronized
+        {
+            get
+            {
+                return false;
+            }
+        }
+
+        /// <summary>
+        ///  Copies the values from the tree to the specified array in the order of the keys.
+        /// </summary>
+        /// <param name="array">The array to copy into</param>
+        /// <param name="index">The index to start at</param>
+        public void CopyTo(System.Array array, int index)
+        {
+            int i = index;
+            foreach (DictionaryEntry o in this)
+            {
+                array.SetValue(o.Value, i++);
+            }
+        }
+
+        /// <summary>
+        /// Gets an object that can be used to sychronize access to the tree. For now, it returns null.
+        /// </summary>
+        public object SyncRoot
+        {
+            get
+            {
+                return null;
+            }
+        }
+
+        #endregion
+        #region IDictionary
+        /// <summary>
+        /// Add an item to the tree
+        /// </summary>
+        /// <param name="key">The key for the item</param>
+        /// <param name="value">The data to store with this key</param>
+        /// <exception cref="ArgumentException">Thrown if the same key is added twice</exception>
+        /// <exception cref="ArgumentNullException">Thrown if key is null</exception>
+        public void Add(object key,object value)
+        {
+            if (key == null)
+                throw new ArgumentNullException("key");
+
+            Node n = root;
+
+            if (n == null)
+            {
+                sizeUp();
+                root = new Node(key, value, null);
+                return;
+            }
+
+            while (true)
+            {
+                int cmp = comparator.Compare(key, n.key);
+                if (cmp == 0)
+                {
+                    //n.value = value;
+                    //return;
+                    throw new ArgumentException("Can't add the same key twice", "key");
+                }
+                else if (cmp < 0)
+                {
+                    if (n.left != null)
+                    {
+                        n = n.left;
+                    }
+                    else
+                    {
+                        sizeUp();
+                        n.left = new Node(key, value, n);
+                        fixAfterInsertion(n.left);
+                        return;
+                    }
+                }
+                else // cmp > 0
+                {
+                    if (n.right != null) {
+                        n = n.right;
+                    }
+                    else
+                    {
+                        sizeUp();
+                        n.right = new Node(key, value, n);
+                        fixAfterInsertion(n.right);
+                        return;
+                    }
+                }
+            }
+
+        }
+
+        /// <summary>
+        /// Remove all values from the tree.
+        /// </summary>
+        public void Clear()
+        {
+            modCount++;
+            size = 0;
+            root = null;
+        }
+
+        /// <summary>
+        /// Determines if the specified key exists in the tree.
+        /// </summary>
+        /// <param name="key">The key to search for</param>
+        /// <returns>True if the key exists in the tree; otherwise false.</returns>
+        public bool Contains(object key)
+        {
+            return getNode(key) != null;
+        }
+
+        /// <summary>
+        /// Returns a dictionary enumerator.
+        /// </summary>
+        /// <returns>A dictionary enumerator</returns>
+        public IDictionaryEnumerator GetEnumerator()
+        {
+            return new TreeEnumerator(this);
+        }
+
+        /// <summary>
+        /// Remove the element from the tree associated
+        /// with this key, possibly rebalancing.
+        /// </summary>
+        /// <param name="key"></param>
+        public void Remove(object key)
+        {
+            Node n = getNode(key);
+            if (n == null)
+            {
+                return;
+            }
+            sizeDown();
+
+            // If strictly internal, first swap position with successor.
+            if ((n.left != null) && (n.right != null))
+            {
+                Node s = successor(n);
+                swapPosition(s, n);
+            }
+
+            // Start fixup at replacement node, if it exists.
+            Node replacement = ((n.left != null) ? n.left : n.right);
+
+            if (replacement != null)
+            {
+                // Link replacement to parent
+                replacement.parent = n.parent;
+                if (n.parent == null)
+                    root = replacement;
+                else if (n == n.parent.left)
+                    n.parent.left = replacement;
+                else
+                    n.parent.right = replacement;
+
+                // Null out links so they are OK to use by fixAfterDeletion.
+                n.left = n.right = n.parent = null;
+
+                // Fix replacement
+                if (n.color == NodeColor.BLACK)
+                fixAfterDeletion(replacement);
+            }
+            else if (n.parent == null)
+            {
+                root = null;
+            }
+            else
+            {
+                if (n.color == NodeColor.BLACK)
+                    fixAfterDeletion(n);
+
+                if (n.parent != null)
+                {
+                    if (n == n.parent.left)
+                        n.parent.left = null;
+                    else if (n == n.parent.right)
+                        n.parent.right = null;
+                    n.parent = null;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Retrieves the value associated with the given key.
+        /// </summary>
+        public object this[object key]
+        {
+            get
+            {
+                Node n = getNode(key);
+                if (n == null)
+                    return null;
+                return n.value;
+            }
+            set
+            {
+                Add(key, value);
+            }
+        }
+
+        /// <summary>
+        /// Retrieve a list of keys.
+        /// </summary>
+        public ICollection Keys
+        {
+            get
+            {
+                object[] keys = new object[Count];
+                int i=0;
+                if (root == null)
+                    return keys;
+                Node n = first(root);
+                while (n != null)
+                {
+                    keys[i++] = n.key;
+                    n = successor(n);
+                }
+                return keys;
+            }
+        }
+
+        /// <summary>
+        /// Retrieves a list of values.
+        /// </summary>
+        public ICollection Values
+        {
+            get
+            {
+                object[] vals = new object[Count];
+                int i=0;
+                Node n = first(root);
+                while (n != null)
+                {
+                    vals[i++] = n.value;
+                    n = successor(n);
+                }
+                return vals;
+            }
+        }
+
+        /// <summary>
+        /// Always returns false for now.
+        /// </summary>
+        public bool IsFixedSize
+        {
+            get
+            {
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// Always returns false for now.
+        /// </summary>
+        public bool IsReadOnly
+        {
+            get
+            {
+                return false;
+            }
+        }
+        #endregion
+        #region Object
+        /// <summary>
+        /// Retrieves a string representation of the tree.
+        /// </summary>
+        /// <returns>string in the format '{key1}={value1}, {key2}={value2}, ...'</returns>
+        public override string ToString()
+        {
+            System.Text.StringBuilder sb = new System.Text.StringBuilder();
+            bool f = true;
+            for (Node n = first(root); n != null; n = successor(n))
+            {
+                if (!f)
+                {
+                    sb.Append(", ");
+                }
+                else
+                {
+                    f = false;
+                }
+
+                sb.AppendFormat("{0}={1}", n.key, n.value);
+            }
+            return sb.ToString();
+        }
+
+        #endregion
+        /// <summary>
+        /// Retrieve a string representation of the tree.
+        /// Nice for debugging, but otherwise useless.
+        /// </summary>
+        /// <returns></returns>
+        public string Structure()
+        {
+            return root.ToString();
+        }
+        #region hidden
+        private static Node first(Node n)
+        {
+            if (n != null)
+            {
+                while (n.left != null)
+                    n = n.left;
+            }
+            return n;
+        }
+
+        private static Node successor(Node t)
+        {
+            if (t == null)
+                return null;
+
+            if (t.right != null)
+            {
+                Node n = t.right;
+                while (n.left != null)
+                    n = n.left;
+                return n;
+            }
+
+            Node p = t.parent;
+            Node ch = t;
+            while (p != null && ch == p.right)
+            {
+                ch = p;
+                p = p.parent;
+            }
+            return p;
+        }
+
+        private Node getNode(object key)
+        {
+            Node n = root;
+            while (n != null)
+            {
+                int cmp = comparator.Compare(key, n.key);
+                if (cmp == 0)
+                    return n;
+                else if (cmp < 0)
+                    n = n.left;
+                else
+                    n = n.right;
+            }
+            return null;
+        }
+
+        private void swapPosition(Node x, Node y)
+        {
+            Node px = x.parent;
+            Node lx = x.left;
+            Node rx = x.right;
+            Node py = y.parent;
+            Node ly = y.left;
+            Node ry = y.right;
+            bool xWasLeftChild = (px != null) && (x == px.left);
+            bool yWasLeftChild = (py != null) && (y == py.left);
+
+            if (x == py)
+            {
+                x.parent = y;
+                if (yWasLeftChild)
+                {
+                    y.left = x;
+                    y.right = rx;
+                }
+                else
+                {
+                    y.right = x;
+                    y.left = lx;
+                }
+            }
+            else
+            {
+                x.parent = py;
+                if (py != null)
+                {
+                    if (yWasLeftChild)
+                        py.left = x;
+                    else
+                        py.right = x;
+                }
+                y.left = lx;
+                y.right = rx;
+            }
+
+            if (y == px)
+            {
+                y.parent = x;
+                if (xWasLeftChild)
+                {
+                    x.left = y;
+                    x.right = ry;
+                }
+                else
+                {
+                    x.right = y;
+                    x.left = ly;
+                }
+            }
+            else
+            {
+                y.parent = px;
+                if (px != null)
+                {
+                    if (xWasLeftChild)
+                        px.left = y;
+                    else
+                        px.right = y;
+                }
+                x.left = ly;
+                x.right = ry;
+            }
+
+            if (x.left != null)
+                x.left.parent = x;
+            if (x.right != null)
+                x.right.parent = x;
+            if (y.left != null)
+                y.left.parent = y;
+            if (y.right != null)
+                y.right.parent = y;
+
+            NodeColor c = x.color;
+            x.color = y.color;
+            y.color = c;
+
+            if (root == x)
+                root = y;
+            else if (root == y)
+                root = x;
+        }
+
+        private static NodeColor colorOf(Node n)
+        {
+            return (n == null ? NodeColor.BLACK : n.color);
+        }
+
+        private static Node  parentOf(Node n)
+        {
+            return (n == null ? null: n.parent);
+        }
+
+        private static void setColor(Node n, NodeColor c)
+        {
+            if (n != null)
+                n.color = c;
+        }
+
+        private static Node leftOf(Node n)
+        {
+            return (n == null)? null: n.left;
+        }
+
+        private static Node rightOf(Node n)
+        {
+            return (n == null)? null: n.right;
+        }
+
+        private void rotateLeft(Node n)
+        {
+            Node r = n.right;
+            n.right = r.left;
+            if (r.left != null)
+                r.left.parent = n;
+            r.parent = n.parent;
+
+            if (n.parent == null)
+                root = r;
+            else if (n.parent.left == n)
+                n.parent.left = r;
+            else
+                n.parent.right = r;
+
+            r.left   = n;
+            n.parent = r;
+        }
+
+        private void rotateRight(Node n)
+        {
+            Node l = n.left;
+            n.left = l.right;
+            if (l.right != null)
+                l.right.parent = n;
+            l.parent = n.parent;
+
+            if (n.parent == null)
+                root = l;
+            else if (n.parent.right == n)
+                n.parent.right = l;
+            else
+                n.parent.left = l;
+
+            l.right = n;
+            n.parent = l;
+        }
+
+
+        private void fixAfterInsertion(Node n)
+        {
+            n.color = NodeColor.RED;
+
+            while ((n != null) &&
+                   (n != root) &&
+                   (n.parent.color == NodeColor.RED))
+            {
+                if (parentOf(n) == leftOf(parentOf(parentOf(n))))
+                {
+                    Node y = rightOf(parentOf(parentOf(n)));
+                    if (colorOf(y) == NodeColor.RED)
+                    {
+                        setColor(parentOf(n), NodeColor.BLACK);
+                        setColor(y, NodeColor.BLACK);
+                        setColor(parentOf(parentOf(n)), NodeColor.RED);
+                        n = parentOf(parentOf(n));
+                    }
+                    else
+                    {
+                        if (n == rightOf(parentOf(n)))
+                        {
+                            n = parentOf(n);
+                            rotateLeft(n);
+                        }
+
+                        setColor(parentOf(n), NodeColor.BLACK);
+                        setColor(parentOf(parentOf(n)), NodeColor.RED);
+                        if (parentOf(parentOf(n)) != null)
+                            rotateRight(parentOf(parentOf(n)));
+                    }
+                }
+                else
+                {
+                    Node y = leftOf(parentOf(parentOf(n)));
+                    if (colorOf(y) == NodeColor.RED)
+                    {
+                        setColor(parentOf(n), NodeColor.BLACK);
+                        setColor(y, NodeColor.BLACK);
+                        setColor(parentOf(parentOf(n)), NodeColor.RED);
+                        n = parentOf(parentOf(n));
+                    }
+                    else
+                    {
+                        if (n == leftOf(parentOf(n)))
+                        {
+                            n = parentOf(n);
+                            rotateRight(n);
+                        }
+                        setColor(parentOf(n),  NodeColor.BLACK);
+                        setColor(parentOf(parentOf(n)), NodeColor.RED);
+                        if (parentOf(parentOf(n)) != null)
+                            rotateLeft(parentOf(parentOf(n)));
+                    }
+                }
+            }
+            root.color = NodeColor.BLACK;
+        }
+
+        private void fixAfterDeletion(Node x)
+        {
+            while ((x != root) && (colorOf(x) == NodeColor.BLACK))
+            {
+                if (x == leftOf(parentOf(x)))
+                {
+                    Node sib = rightOf(parentOf(x));
+
+                    if (colorOf(sib) == NodeColor.RED)
+                    {
+                        setColor(sib, NodeColor.BLACK);
+                        setColor(parentOf(x), NodeColor.RED);
+                        rotateLeft(parentOf(x));
+                        sib = rightOf(parentOf(x));
+                    }
+
+                    if ((colorOf(leftOf(sib))  == NodeColor.BLACK) &&
+                        (colorOf(rightOf(sib)) == NodeColor.BLACK))
+                    {
+                        setColor(sib,  NodeColor.RED);
+                        x = parentOf(x);
+                    }
+                    else
+                    {
+                        if (colorOf(rightOf(sib)) == NodeColor.BLACK)
+                        {
+                            setColor(leftOf(sib), NodeColor.BLACK);
+                            setColor(sib, NodeColor.RED);
+                            rotateRight(sib);
+                            sib = rightOf(parentOf(x));
+                        }
+                        setColor(sib, colorOf(parentOf(x)));
+                        setColor(parentOf(x), NodeColor.BLACK);
+                        setColor(rightOf(sib), NodeColor.BLACK);
+                        rotateLeft(parentOf(x));
+                        x = root;
+                    }
+                }
+                else
+                {
+                    Node sib = leftOf(parentOf(x));
+
+                    if (colorOf(sib) == NodeColor.RED)
+                    {
+                        setColor(sib, NodeColor.BLACK);
+                        setColor(parentOf(x), NodeColor.RED);
+                        rotateRight(parentOf(x));
+                        sib = leftOf(parentOf(x));
+                    }
+
+                    if (colorOf(rightOf(sib)) == NodeColor.BLACK &&
+                        colorOf(leftOf(sib)) == NodeColor.BLACK)
+                    {
+                        setColor(sib,  NodeColor.RED);
+                        x = parentOf(x);
+                    }
+                    else
+                    {
+                        if (colorOf(leftOf(sib)) == NodeColor.BLACK) {
+                        setColor(rightOf(sib), NodeColor.BLACK);
+                        setColor(sib, NodeColor.RED);
+                        rotateLeft(sib);
+                        sib = leftOf(parentOf(x));
+                        }
+                        setColor(sib, colorOf(parentOf(x)));
+                        setColor(parentOf(x), NodeColor.BLACK);
+                        setColor(leftOf(sib), NodeColor.BLACK);
+                        rotateRight(parentOf(x));
+                        x = root;
+                    }
+                }
+            }
+
+            setColor(x, NodeColor.BLACK);
+        }
+
+        private void sizeUp()   { modCount++; size++; }
+        private void sizeDown() { modCount++; size--; }
+        #endregion
+        #region node
+        private enum NodeColor : byte
+        {
+            RED,
+            BLACK
+        }
+
+        private class Node
+        {
+            public object key;
+            public object value;
+            public Node left = null;
+            public Node right = null;
+            public Node parent;
+            public NodeColor color = NodeColor.BLACK;
+
+            public Node(object key, object value, Node parent)
+            {
+                this.key = key;
+                this.value = value;
+                this.parent = parent;
+            }
+
+            public override bool Equals(object o)
+            {
+                Node n = o as Node;
+                if (n == null)
+                {
+                    return false;
+                }
+                return (key == n.key) && (value == n.value);
+            }
+
+            public override int GetHashCode()
+            {
+                return key.GetHashCode();
+            }
+
+            public override string ToString()
+            {
+                //return key + "=" + value + " (" + color + ")";
+                if ((left==null) && (right==null))
+                {
+                    return key.ToString();
+                }
+                return key + " (" +
+                    ((left == null) ? "null" : left.ToString()) + "," +
+                    ((right == null) ? "null" : right.ToString()) + ")";
+            }
+
+        }
+        #endregion
+        #region enumerator
+        private class TreeEnumerator : IDictionaryEnumerator
+        {
+            private Tree  tree    = null;
+            private Node  current = null;
+            private int   mods    = -1;
+
+            public TreeEnumerator(Tree t) : this(t, t.root)
+            {
+            }
+
+            public TreeEnumerator(Tree t, Node n)
+            {
+                tree    = t;
+                mods    = t.modCount;
+
+                // foreach calls MoveNext before starting.  Create a dummy node before the first one.
+                current = new Node(null, null, null);
+                current.right = first(n);
+            }
+
+            public object Current
+            {
+                get
+                {
+                    if (tree.modCount != mods)
+                    {
+                        throw new InvalidOperationException("Changed list during iterator");
+                    }
+                    return Entry;
+                }
+            }
+
+            public bool MoveNext()
+            {
+                current = successor(current);
+                return current != null;
+            }
+
+            public void Reset()
+            {
+                current = first(tree.root);
+                mods = tree.modCount;
+            }
+
+            public object Key
+            {
+                get
+                {
+                    if (tree.modCount != mods)
+                    {
+                        throw new InvalidOperationException("Changed list during iterator");
+                    }
+                    return current.key;
+                }
+            }
+
+            public object Value
+            {
+                get
+                {
+                    if (tree.modCount != mods)
+                    {
+                        throw new InvalidOperationException("Changed list during iterator");
+                    }
+                    return current.value;
+                }
+            }
+
+            public DictionaryEntry Entry
+            {
+                get
+                {
+                    return new DictionaryEntry(current.key, current.value);
+                }
+            }
+        }
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/bedrock/collections/Trie.cs b/lib/jabber-net/bedrock/collections/Trie.cs
new file mode 100644
index 0000000..68153b6
--- /dev/null
+++ b/lib/jabber-net/bedrock/collections/Trie.cs
@@ -0,0 +1,466 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using bedrock.util;
+
+namespace bedrock.collections
+{
+    /// <summary>
+    /// The method signature used by <see cref="Trie.Traverse(TrieKeyWalker,object,TrieNode,ByteStack)"/> when it encounters a key.
+    /// </summary>
+    public delegate bool TrieKeyWalker(TrieNode e, object data, ByteStack key);
+    /// <summary>
+    /// The method signature used by <see cref="Trie.Traverse(TrieWalker,object,TrieNode)"/> when it encounters a node.
+    /// </summary>
+    public delegate bool TrieWalker(TrieNode e, object data);
+    /// <summary>
+    /// A trie is a tree structure that implements a radix search.  Each node of the tree has a
+    /// sub-node for each possible next byte.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Trie : IDictionary
+    {
+        private static readonly System.Text.Encoding ENCODING = System.Text.Encoding.Default;
+
+        /// <summary>
+        /// The root node of the trie.
+        /// </summary>
+        private TrieNode m_root  = new TrieNode(null, 0);
+
+        /// <summary>
+        /// The number of nodes are in the trie
+        /// </summary>
+        private int      m_count = 0;
+
+        /// <summary>
+        /// Creates an empty trie.
+        /// </summary>
+        public Trie() {}
+
+        /// <summary>
+        /// Find a node for a given key, somewhere under the root.
+        /// </summary>
+        /// <param name="key">The bytes to search for, where key[0] corresponds to a child
+        /// node of the root.</param>
+        /// <param name="create">Create nodes that don't exist, while searching.</param>
+        /// <returns>The node if found. If the node doesn't exist and create is true, the node created; otherwise null.</returns>
+        protected virtual TrieNode FindNode(byte[] key, bool create)
+        {
+            return FindNode(key, m_root, create);
+        }
+        /// <summary>
+        /// Finds a node in the given sub-tree.
+        /// </summary>
+        /// <param name="key">The key to search on, where key[0] corresponds to a child of startAt.</param>
+        /// <param name="startAt">The node to search under</param>
+        /// <param name="create">Create nodes that don't exist, while searching.</param>
+        /// <returns>The node if found. If the node doesn't exist and create is true, the node created; otherwise null.</returns>
+        protected virtual TrieNode FindNode(byte[] key, TrieNode startAt, bool create)
+        {
+            TrieNode current = startAt;
+            byte b;
+
+            for (int i=0; (i<key.Length) && (current != null); i++)
+            {
+                b = key[i];
+                current = current[b, create];
+            }
+            return current;
+        }
+        /// <summary>
+        /// Compute the byte array corresping to the given object.
+        /// This is likely to cause problems for non 7-bit ASCII text.
+        /// </summary>
+        /// <param name="key"> </param>
+        protected static byte[] KeyBytes(object key)
+        {
+            if (key is byte[])
+            {
+                return (byte[]) key;
+            }
+
+            return ENCODING.GetBytes(key.ToString());
+        }
+        /// <summary>
+        /// Extra functionality for trie's whose values are integers.
+        /// Increment the value corresponding to the key.  If
+        /// the key doesn't exist, put in a value of '1'.
+        /// </summary>
+        /// <param name="key"> </param>
+        public virtual void Increment(object key)
+        {
+            TrieNode e = FindNode(KeyBytes(key), true);
+            if (e.Value == null)
+            {
+                e.Value = 1;
+            }
+            else
+            {
+                e.Value = ((int) e.Value) + 1;
+            }
+        }
+        /// <summary>
+        /// Performs the given function on every element of the trie. This is equivalent to Perl's map() operator.
+        /// </summary>
+        /// <param name="w">The function to call</param>
+        /// <param name="data">Extra data to pass along to the function.</param>
+        public void Traverse(TrieKeyWalker w, object data)
+        {
+            Traverse(w, data, m_root, new ByteStack());
+        }
+
+        /// <summary>
+        /// Perform the given function on every element of the trie.  Perl's map() operator.
+        /// </summary>
+        /// <param name="w">The function to call</param>
+        /// <param name="data">Extra data to pass along to the function.</param>
+        /// <param name="current">What node are we currently on?</param>
+        /// <param name="key">A stack holding the current key value</param>
+        protected void Traverse(TrieKeyWalker w, object data, TrieNode current, ByteStack key)
+        {
+            if (!w(current, data, key))
+            {
+                return;
+            }
+            foreach (TrieNode e in current)
+            {
+                key.Push(e.Byte);
+                Traverse(w, data, e, key);
+                key.Pop();
+            }
+        }
+        /// <summary>
+        /// Perform the given function on every element of the trie.  Perl's map() operator.
+        /// Don't keep track of the keys (slightly faster than the other Traverse() method).
+        /// </summary>
+        /// <param name="w">The function to call</param>
+        /// <param name="data">Extra data to pass along to the function.</param>
+        public void Traverse(TrieWalker w, object data)
+        {
+            Traverse(w, data, m_root);
+        }
+        /// <summary>
+        /// Perform the given function on every element of the trie.  Perl's map() operator.
+        /// </summary>
+        /// <param name="w">The function to call</param>
+        /// <param name="data">Extra data to pass along to the function.</param>
+        /// <param name="current">What node are we currently on?</param>
+        protected void Traverse(TrieWalker w, object data, TrieNode current)
+        {
+            if (! w(current, data))
+            {
+                return;
+            }
+            foreach (TrieNode e in current)
+            {
+                Traverse(w, data, e);
+            }
+        }
+        #region System.Collections.IDictionary
+
+        /// <summary>
+        /// Retrieve the value associated with the given key.
+        /// </summary>
+        public virtual object this[object key]
+        {
+            get
+            {
+                TrieNode e = FindNode(KeyBytes(key), false);
+                return (e == null) ? null : e.Value;
+            }
+            set
+            {
+                TrieNode e = FindNode(KeyBytes(key), true);
+                e.Value = value;
+                m_count++;
+            }
+        }
+
+        /// <summary>
+        /// Always "false" for now.
+        /// </summary>
+        public bool IsFixedSize
+        {
+            get { return false; }
+        }
+
+
+        /// <summary>
+        /// Find all of the keys.
+        /// </summary>
+        /// <param name="n"> </param>
+        /// <param name="data"> </param>
+        /// <param name="key"> </param>
+        private bool KeyWalker(TrieNode n, object data, ByteStack key)
+        {
+            if (n.Value != null)
+            {
+                ArrayList al = (ArrayList) data;
+                al.Add((byte[]) key);
+            }
+            return true;
+        }
+
+        /// <summary>
+        /// Get a list of all of the keys.  Hope this doesn't get called often, since it has to make copies
+        /// of all of the possible keys.
+        /// </summary>
+        public ICollection Keys
+        {
+            get
+            {
+                ArrayList al = new ArrayList(m_count);
+                Traverse(new TrieKeyWalker(KeyWalker), al);
+                al.TrimToSize();
+                return al;
+            }
+        }
+
+        /// <summary>
+        /// Returns a collection containing all of the values.
+        /// </summary>
+        public ICollection Values
+        {
+            get
+            {
+                // pretty easy, since we implement ICollection.
+                return new ArrayList(this);
+            }
+        }
+
+        /// <summary>
+        /// Removes the node associated with the given key, along with all newly empty ancestors.
+        /// </summary>
+        /// <param name="key">Key to remove.</param>
+        public void Remove(object key)
+        {
+            TrieNode current = FindNode(KeyBytes(key), false);
+            if (current == null)
+            {
+                return;
+            }
+
+            current.Value = null;
+            m_count--;
+
+            if (m_count == 0)
+            {
+                Clear();
+                return;
+            }
+
+            // prune
+            byte last;
+            while (current.IsEmpty)
+            {
+                last = current.Byte;
+                current = current.Parent;
+                if (current == null)
+                {
+                    // all the way empty.
+                    break;
+                }
+                current.Remove(last);
+            }
+        }
+
+        /// <summary>
+        /// Iterate the dictionary way.
+        /// </summary>
+        IDictionaryEnumerator IDictionary.GetEnumerator()
+        {
+            return new TrieEnumerator(this);
+        }
+
+        /// <summary>
+        /// Deletes all nodes.
+        /// </summary>
+        public void Clear()
+        {
+            m_root  = new TrieNode(null, 0);
+            m_count = 0;
+        }
+
+        /// <summary>
+        /// Add a new key/value pair.
+        /// </summary>
+        /// <param name="key"> </param>
+        /// <param name="value"> </param>
+        public void Add(object key, object value)
+        {
+            this[key] = value;
+        }
+
+        /// <summary>
+        /// Is the given key in the trie?
+        /// </summary>
+        /// <param name="key"> </param>
+        public bool Contains(object key)
+        {
+            TrieNode current = FindNode(KeyBytes(key), false);
+            return current != null;
+        }
+
+        #endregion
+        #region System.Collections.ICollection
+
+        /// <summary>
+        /// How many values are stored?  Note: NOT how many nodes.
+        /// </summary>
+        public int Count
+        {
+            get
+            {
+                return m_count;
+            }
+        }
+
+        /// <summary>
+        /// Object to synchronize on, if in thread-safe mode.
+        /// TODO: implement settable SyncRoot
+        /// </summary>
+        public object SyncRoot
+        {
+            get
+            {
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Always "false" for now
+        /// </summary>
+        public bool IsReadOnly
+        {
+            get
+            {
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether access to the trie is synchronized in thread-safe mode.
+        /// Only returns false now.
+        /// </summary>
+        public bool IsSynchronized
+        {
+            get
+            {
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// Copy into an array.
+        /// </summary>
+        /// <param name="array"> </param>
+        /// <param name="index"> </param>
+        public void CopyTo(Array array, int index)
+        {
+            int i = index;
+            foreach (object o in this)
+            {
+                array.SetValue(o, i);
+                i++;
+            }
+        }
+
+        #endregion
+        #region System.Collections.IEnumerable
+
+        /// <summary>
+        /// Iterate over the keys.  Each key will be a byte[].
+        /// </summary>
+        public IEnumerator GetEnumerator()
+        {
+            return new TrieEnumerator(this);
+        }
+
+        #endregion
+
+        private class TrieEnumerator : IDictionaryEnumerator
+        {
+            protected Trie     m_trie;
+            protected Stack    m_pos     = new Stack();
+            protected TrieNode m_current = null;
+            public TrieEnumerator(Trie t)
+            {
+                m_trie = t;
+                m_pos.Push(m_trie.m_root);
+            }
+
+            public object Current
+            {
+                get
+                {
+                    return Entry;
+                }
+            }
+
+            public void Reset()
+            {
+                m_pos.Clear();
+                m_pos.Push(m_trie.m_root);
+            }
+
+            public bool MoveNext()
+            {
+                if (m_pos.Count <= 0)
+                {
+                    return false;
+                }
+
+                m_current = (TrieNode) m_pos.Pop();
+
+                foreach (TrieNode e in m_current)
+                {
+                    m_pos.Push(e);
+                }
+
+                if (m_current.Value != null)
+                {
+                    return true;
+                }
+
+                return MoveNext();
+            }
+
+            public object Key
+            {
+                get
+                {
+                    return m_current.Key;
+                }
+            }
+
+            public object Value
+            {
+                get
+                {
+                    return m_current.Value;
+                }
+            }
+
+            public DictionaryEntry Entry
+            {
+                get
+                {
+                    return new DictionaryEntry(m_current.Key, m_current.Value);
+                }
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/collections/TrieNode.cs b/lib/jabber-net/bedrock/collections/TrieNode.cs
new file mode 100644
index 0000000..da6865f
--- /dev/null
+++ b/lib/jabber-net/bedrock/collections/TrieNode.cs
@@ -0,0 +1,267 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.IO;
+using System.Collections;
+using bedrock.util;
+namespace bedrock.collections
+{
+    /// <summary>
+    /// A node in a Trie.  This class is public to support traversal via Trie.Traverse().
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class TrieNode : IEnumerable
+    {
+        // Warning: Assumption of 7-bit ASCII encoding!
+        // TODO: replace with GraphNode
+        //public const byte MIN_CHAR  = (byte) ' ';
+        //public const byte MAX_CHAR  = (byte) '~';
+        //public const byte NUM_CHARS = MAX_CHAR - MIN_CHAR + 1;
+
+        //private TrieNode[] m_children = new TrieNode[NUM_CHARS];
+        private Tree       m_children = new Tree();
+        private TrieNode   m_parent   = null;
+        private Object     m_value    = null;
+        private byte       m_key      = 0;
+
+        /// <summary>
+        /// Create a new node
+        /// </summary>
+        /// <param name="parent">The parent of the new node</param>
+        /// <param name="key">The byte for this node</param>
+        public TrieNode(TrieNode parent, byte key)
+        {
+            m_parent = parent;
+            m_key    = key;
+        }
+
+        /// <summary>
+        /// Adds a child to this node.
+        /// </summary>
+        /// <param name="key">The key for the child.</param>
+        /// <returns>The child noded added to this node.</returns>
+        public virtual TrieNode Add(byte key)
+        {
+            TrieNode e = new TrieNode(this, key);
+            this[key]  = e;
+            return e;
+        }
+        /// <summary>
+        /// Are there children of this node?
+        /// </summary>
+        public bool IsEmpty
+        {
+            get
+            {
+                if (m_value != null)
+                    return false;
+                foreach (object key in m_children)
+                {
+                    if (m_children[key] != null)
+                        return false;
+                }
+                return true;
+            }
+        }
+
+        /// <summary>
+        /// Get the parent of this node
+        /// </summary>
+        public TrieNode Parent
+        {
+            get
+            {
+                return m_parent;
+            }
+        }
+        /// <summary>
+        /// Gets the byte associated with this node.
+        /// </summary>
+        public byte Byte
+        {
+            get
+            {
+                return m_key;
+            }
+        }
+
+        /// <summary>
+        /// Retrive the full key for this node, traversing parent-ward toward the root.
+        /// </summary>
+        public byte[] Key
+        {
+            get
+            {
+                MemoryStream ms = new MemoryStream();
+                TrieNode current = this;
+                while (current.Parent != null)
+                {
+                    ms.WriteByte(current.Byte);
+                    current = current.Parent;
+                }
+                byte[] buf = ms.ToArray();
+                Array.Reverse(buf);
+                return buf;
+            }
+        }
+        /// <summary>
+        /// The value associated with this node
+        /// </summary>
+        public Object Value
+        {
+            get
+            {
+                return m_value;
+            }
+            set
+            {
+                m_value = value;;
+            }
+        }
+        /// <summary>
+        /// Gets the child associated with the specified byte, or null if one does not exist.
+        /// </summary>
+        public TrieNode this[byte key]
+        {
+            get
+            {
+                return (TrieNode) m_children[key];
+            }
+            set
+            {
+                m_children[key] = value;
+            }
+        }
+        /// <summary>
+        /// Gets the child associated with the specified byte, or null if one does not exist.
+        /// If create is true, a node will be added with a null value
+        /// if a node does not already exist, so that this can be used
+        /// as an lvalue.
+        /// </summary>
+        public TrieNode this[byte key, bool create]
+        {
+            get
+            {
+                TrieNode e = this[key];
+                if (e != null)
+                {
+                    return e;
+                }
+                if (create)
+                {
+                    return Add(key);
+                }
+                return null;
+            }
+        }
+        /// <summary>
+        /// Is there a child at the given byte?
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
+        public bool HasChild(byte key)
+        {
+            return this[key] != null;
+        }
+        /// <summary>
+        /// Remove the child at the given byte
+        /// </summary>
+        /// <param name="key"></param>
+        public void Remove(byte key)
+        {
+            this[key] = null;
+        }
+        /// <summary>
+        /// Compares the specified object with this entry for equality.
+        /// Returns <tt>true</tt> if the given object is also a map entry and
+        /// the two entries represent the same mapping.  More formally, two
+        /// entries <tt>e1</tt> and <tt>e2</tt> represent the same mapping
+        /// if:<pre>
+        ///     (e1.getKey()==null ?
+        ///      e2.getKey()==null : e1.getKey().equals(e2.getKey()))  &&
+        ///     (e1.getValue()==null ?
+        ///      e2.getValue()==null : e1.getValue().equals(e2.getValue()))
+        /// </pre>
+        /// This ensures that the <tt>equals</tt> method works properly across
+        /// different implementations of the <tt>Map.Entry</tt> interface.
+        /// </summary>
+        /// <param name="o">Object to be compared for equality with this map entry.</param>
+        /// <returns><tt>True</tt> if the specified object is equal to this map
+        ///         entry; otherwise false.</returns>
+        public override bool Equals(Object o)
+        {
+            if (o == null)
+                return false;
+            if (o == this)
+                return true;
+
+            if (! (o is TrieNode))
+                return false;
+            TrieNode e = (TrieNode) o;
+
+            return ((Key == null)    ? (e.Key   == null) : Key.Equals(e.Key))  &&
+                ((Value == null) ? (e.Value == null) : Value.Equals(e.Value));
+        }
+        /// <summary>
+        /// Returns the hash code value for this map entry.
+        /// </summary>
+        /// <returns>Hash code.</returns>
+        public override int GetHashCode()
+        {
+            return ((Key==null)    ? 0 : Key.GetHashCode()) ^
+                    ((Value==null) ? 0 : Value.GetHashCode());
+        }
+        #region Implementation of IEnumerable
+        /// <summary>
+        /// Iterates over the child nodes.
+        /// </summary>
+        /// <returns>An IEnumerator to parse over the child nodes.</returns>
+        public System.Collections.IEnumerator GetEnumerator()
+        {
+            return new TrieNodeEnumerator(this);
+        }
+        #endregion
+        private class TrieNodeEnumerator : IEnumerator
+        {
+            private TrieNode    m_node;
+            private IEnumerator m_enum;
+            public TrieNodeEnumerator(TrieNode n)
+            {
+                m_node = n;
+                Reset();
+            }
+            #region Implementation of IEnumerator
+            public void Reset()
+            {
+                // yeah, I know.  but I want to go to bed.
+                m_enum  = m_node.m_children.Values.GetEnumerator();
+            }
+
+            public bool MoveNext()
+            {
+                return m_enum.MoveNext();
+            }
+
+            public object Current
+            {
+                get
+                {
+                    return m_enum.Current;
+                }
+            }
+            #endregion
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/io/BufferAggregate.cs b/lib/jabber-net/bedrock/io/BufferAggregate.cs
new file mode 100644
index 0000000..dc26acf
--- /dev/null
+++ b/lib/jabber-net/bedrock/io/BufferAggregate.cs
@@ -0,0 +1,133 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System.Collections;
+using System.IO;
+
+using bedrock.util;
+
+namespace bedrock.io
+{
+    /// <summary> Aggregate byte arrays together, so we can parse
+    /// across IP packet boundaries
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class BufferAggregate
+    { // RingBuffer of the Nieblung
+        private class BufNode
+        {
+            public byte[] buf;
+            public BufNode next = null;
+        }
+
+        private MemoryStream m_stream = new MemoryStream();
+        private BufNode m_head = null;
+        private BufNode m_tail = null;
+
+        /// <summary>
+        /// Create an empty buffer
+        /// </summary>
+        public BufferAggregate()
+        {
+        }
+
+        /// <summary>
+        /// Write to the buffer.  Please make sure that you won't use this memory any more after you hand it in.
+        /// It will get mangled.
+        /// </summary>
+        /// <param name="buf"></param>
+        public void Write(byte[] buf)
+        {
+            m_stream.Write(buf, 0, buf.Length);
+            if (m_tail == null)
+            {
+                m_head = m_tail = new BufNode();
+                m_head.buf = buf;
+            }
+            else
+            {
+                BufNode n = new BufNode();
+                n.buf = buf;
+                m_tail.next = n;
+                m_tail = n;
+            }
+        }
+
+        /// <summary>
+        /// Get the current aggregate contents of the buffer.
+        /// </summary>
+        /// <returns></returns>
+        public byte[] GetBuffer()
+        {
+            return m_stream.ToArray();
+        }
+
+        /// <summary>
+        /// Clear the first "offset" bytes of the buffer, so they won't be parsed again.
+        /// </summary>
+        /// <param name="offset"></param>
+        public void Clear(int offset)
+        {
+            int s = 0;
+            int save = -1;
+
+            BufNode bn = null;
+            for (bn = m_head; bn != null; bn = bn.next)
+            {
+                if (s + bn.buf.Length <= offset)
+                {
+                    if (s + bn.buf.Length == offset)
+                    {
+                        bn = bn.next;
+                        break;
+                    }
+                    s += bn.buf.Length;
+                }
+                else
+                {
+                    save = s + bn.buf.Length - offset;
+                    break;
+                }
+            }
+
+            m_head = bn;
+            if (m_head == null)
+                m_tail = null;
+
+            if (save > 0)
+            {
+                byte[] buf = new byte[save];
+                System.Buffer.BlockCopy(m_head.buf,
+                    m_head.buf.Length - save,
+                    buf, 0, save);
+                m_head.buf = buf;
+            }
+
+            m_stream.SetLength(0);
+            for (bn = m_head; bn != null; bn = bn.next)
+            {
+                m_stream.Write(bn.buf, 0, bn.buf.Length);
+            }
+        }
+
+        /// <summary>
+        /// UTF8 encode the current contents of the buffer.  Just for prettiness in the debugger.
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            byte[] b = GetBuffer();
+            return System.Text.Encoding.UTF8.GetString(b, 0, b.Length);
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/io/ReadEventStream.cs b/lib/jabber-net/bedrock/io/ReadEventStream.cs
new file mode 100644
index 0000000..4baee71
--- /dev/null
+++ b/lib/jabber-net/bedrock/io/ReadEventStream.cs
@@ -0,0 +1,236 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.IO;
+using bedrock.util;
+
+namespace bedrock.io
+{
+    /// <summary>
+    /// Wrap a stream, so that OnRead events can be fired.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ReadEventStream : Stream
+    {
+        private Stream m_stream;
+
+        /// <summary>
+        /// Create a new stream.
+        /// </summary>
+        /// <param name="s"></param>
+        public ReadEventStream(Stream s)
+        {
+            m_stream = s;
+        }
+
+        /// <summary>
+        /// Bytes have been read from the underlying stream.
+        /// </summary>
+        public event ByteOffsetHandler OnRead;
+
+        /// <summary>
+        /// Gets a value indicating whether the current stream supports reading.
+        /// </summary>
+        public override bool CanRead
+        {
+            get { return m_stream.CanRead; }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether the current stream supports seeking.
+        /// </summary>
+        public override bool CanSeek
+        {
+            get { return m_stream.CanSeek; }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether the current stream supports writing.
+        /// </summary>
+        public override bool CanWrite
+        {
+            get { return m_stream.CanWrite; }
+        }
+
+        /// <summary>
+        /// Gets the length in bytes of the stream.
+        /// </summary>
+        public override long Length
+        {
+            get { return m_stream.Length; }
+        }
+
+        /// <summary>
+        /// Gets or sets the position within the current stream.
+        /// </summary>
+        public override long Position
+        {
+            get { return m_stream.Position; }
+            set { m_stream.Position = value; }
+        }
+
+        /// <summary>
+        /// Begins an asynchronous read operation.
+        /// </summary>
+        /// <param name="buffer"></param>
+        /// <param name="offset"></param>
+        /// <param name="count"></param>
+        /// <param name="callback"></param>
+        /// <param name="state"></param>
+        /// <returns></returns>
+        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
+        {
+            return m_stream.BeginRead (buffer, offset, count, callback, state);
+        }
+
+        /// <summary>
+        /// Begins an asynchronous write operation.
+        /// </summary>
+        /// <param name="buffer"></param>
+        /// <param name="offset"></param>
+        /// <param name="count"></param>
+        /// <param name="callback"></param>
+        /// <param name="state"></param>
+        /// <returns></returns>
+        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
+        {
+            return m_stream.BeginWrite (buffer, offset, count, callback, state);
+        }
+
+        /// <summary>
+        /// Closes the current stream and releases any resources (such as sockets and file handles) associated with the current stream.
+        /// </summary>
+        public override void Close()
+        {
+            m_stream.Close ();
+        }
+
+        /// <summary>
+        /// Waits for the pending asynchronous read to complete.
+        /// </summary>
+        /// <param name="asyncResult"></param>
+        /// <returns></returns>
+        public override int EndRead(IAsyncResult asyncResult)
+        {
+            int count = m_stream.EndRead(asyncResult);
+            byte[] buf = System.Text.Encoding.UTF8.GetBytes("Read " + count + " bytes from async stream");
+            FireOnRead(buf, 0, buf.Length);
+            return count;
+        }
+
+        /// <summary>
+        /// Ends an asynchronous write operation.
+        /// </summary>
+        /// <param name="asyncResult"></param>
+        public override void EndWrite(IAsyncResult asyncResult)
+        {
+            m_stream.EndWrite (asyncResult);
+        }
+
+        /// <summary>
+        /// Clears all buffers for this stream and causes any buffered data to be written to
+        /// the underlying device.
+        /// </summary>
+        public override void Flush()
+        {
+            m_stream.Flush();
+        }
+
+        /// <summary>
+        /// Reads a sequence of bytes from the current stream and advances the position within the stream
+        /// by the number of bytes read.
+        /// </summary>
+        /// <param name="buffer"></param>
+        /// <param name="offset"></param>
+        /// <param name="count"></param>
+        /// <returns></returns>
+        public override int Read(byte[] buffer, int offset, int count)
+        {
+            int rcount = m_stream.Read(buffer, offset, count);
+            FireOnRead(buffer, offset, rcount);
+            return rcount;
+        }
+
+        /// <summary>
+        /// Reads a byte from the stream and advances the position within the stream by one byte,
+        /// or returns -1 if at the end of the stream.
+        /// </summary>
+        /// <returns></returns>
+        public override int ReadByte()
+        {
+            return m_stream.ReadByte();
+        }
+
+        /// <summary>
+        /// Sets the position within the current stream.
+        /// </summary>
+        /// <param name="offset"></param>
+        /// <param name="origin"></param>
+        /// <returns></returns>
+        public override long Seek(long offset, SeekOrigin origin)
+        {
+            return m_stream.Seek(offset, origin);
+        }
+
+        /// <summary>
+        /// Sets the length of the current stream.
+        /// </summary>
+        /// <param name="value"></param>
+        public override void SetLength(long value)
+        {
+            m_stream.SetLength(value);
+        }
+
+        /// <summary>
+        /// writes a sequence of bytes to the current stream and advances
+        /// the current position within this stream by the number of bytes written.
+        /// </summary>
+        /// <param name="buffer"></param>
+        /// <param name="offset"></param>
+        /// <param name="count"></param>
+        public override void Write(byte[] buffer, int offset, int count)
+        {
+            m_stream.Write(buffer, offset, count);
+        }
+
+        /// <summary>
+        /// Writes a byte to the current position in the stream and advances
+        /// the position within the stream by one byte.
+        /// </summary>
+        /// <param name="val"></param>
+        public override void WriteByte(byte val)
+        {
+            m_stream.WriteByte(val);
+        }
+
+        /// <summary>
+        /// Serves as a hash function for a particular type, suitable for use
+        /// in hashing algorithms and data structures like a hash table.
+        /// </summary>
+        /// <returns></returns>
+        public override int GetHashCode()
+        {
+            return m_stream.GetHashCode();
+        }
+
+        private void FireOnRead(byte[] buf, int offset, int length)
+        {
+            if ((OnRead != null) && (length > 0))
+            {
+                OnRead(this, buf, offset, length);
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/io/ZlibStream.cs b/lib/jabber-net/bedrock/io/ZlibStream.cs
new file mode 100644
index 0000000..4a0d8ac
--- /dev/null
+++ b/lib/jabber-net/bedrock/io/ZlibStream.cs
@@ -0,0 +1,444 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+#if ZLIB_NET
+using System;
+using System.IO;
+using System.Diagnostics;
+
+using bedrock.util;
+using ComponentAce.Compression.Libs.zlib;
+
+namespace bedrock.io
+{
+    /// <summary>
+    /// Compression failed.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class CompressionFailedException : ApplicationException
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="message"></param>
+        public CompressionFailedException(string message) : base(message) { }
+
+        /// <summary>
+        ///
+        /// </summary>
+        public CompressionFailedException() : base() { }
+    }
+
+
+    /// <summary>
+    /// Wrap two ComponentAce.Compression.Libs.zlib.ZStream's, one in and one out.
+    /// The existing wrappers in the project are uni-directional.
+    ///
+    /// No, System.IO.Compression.GZipStream won't work, because they didn't expose
+    /// compression levels or flush types.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ZlibStream : Stream
+    {
+        /// <summary>
+        /// Is zlib supported?  Note, this will throw an exception if the library is missing.
+        /// </summary>
+        public static bool Supported
+        {
+            get
+            {
+                return zlibConst.version() != "";
+            }
+        }
+
+        private Stream m_stream = null;
+        private ZStream m_in;
+        private ZStream m_out;
+        private int m_flush = zlibConst.Z_PARTIAL_FLUSH;
+
+        private const int bufsize = 1024;
+        private byte[] m_inbuf;
+        private byte[] m_outbuf;
+
+        /// <summary>
+        /// Wrap a bi-directional stream in a compression stream.
+        /// </summary>
+        /// <param name="innerStream">The stream to wrap.</param>
+        public ZlibStream(Stream innerStream)
+        {
+            init(innerStream);
+        }
+
+        /// <summary>
+        /// Wrap a bi-directional stream in a compression stream.
+        /// </summary>
+        /// <param name="innerStream">The stream to wrap.</param>
+        /// <param name="flush">The flush type.  TODO: doc these.</param>
+        public ZlibStream(Stream innerStream, int flush)
+        {
+            m_flush = flush;
+            init(innerStream);
+        }
+
+
+        private void init(Stream innerStream)
+        {
+            m_stream = innerStream;
+            if (m_stream.CanRead)
+            {
+                m_in = new ZStream();
+                int ret = m_in.inflateInit();
+                if (ret != zlibConst.Z_OK)
+                    throw new CompressionFailedException("Unable to initialize zlib for deflate: " + ret);
+                m_inbuf = new byte[bufsize];
+                m_in.avail_in = 0;
+                m_in.next_in = m_inbuf;
+                m_in.next_in_index = 0;
+            }
+
+            if (m_stream.CanWrite)
+            {
+                m_out = new ZStream();
+                int ret = m_out.deflateInit(zlibConst.Z_DEFAULT_COMPRESSION);
+                if (ret != zlibConst.Z_OK)
+                    throw new CompressionFailedException("Unable to initialize zlib for inflate: " + ret);
+                m_outbuf = new byte[bufsize];
+                m_out.next_out = m_outbuf;
+            }
+        }
+
+        /// <summary>
+        /// Is the underlying stream readable?
+        /// </summary>
+        public override bool CanRead
+        {
+            get { return m_stream.CanRead; }
+        }
+
+        /// <summary>
+        /// No seeking on compressed streams.  That sounds hard.
+        /// </summary>
+        public override bool CanSeek
+        {
+            get { return false; }
+        }
+
+        /// <summary>
+        /// Is the underlying stream writable?
+        /// </summary>
+        public override bool CanWrite
+        {
+            get { return m_stream.CanWrite; }
+        }
+
+        /// <summary>
+        /// This just flushes the stream, but doesn't perform zlib flushing.
+        /// </summary>
+        public override void Flush()
+        {
+            m_stream.Flush();
+        }
+
+        /// <summary>
+        /// Not implemented.
+        /// </summary>
+        public override long Length
+        {
+            get { throw new NotImplementedException("The method or operation is not implemented."); }
+        }
+
+        /// <summary>
+        /// Not implemented.
+        /// </summary>
+        public override long Position
+        {
+            get { throw new NotImplementedException("The method or operation is not implemented."); }
+            set { throw new NotImplementedException("The method or operation is not implemented."); }
+        }
+
+        /// <summary>
+        /// Start an async read. Implemented locally, since Stream.BeginRead() isn't really asynch.
+        /// </summary>
+        /// <param name="buffer"></param>
+        /// <param name="offset"></param>
+        /// <param name="count"></param>
+        /// <param name="callback"></param>
+        /// <param name="state"></param>
+        /// <returns></returns>
+        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
+        {
+            if (count <= 0)
+                throw new ArgumentException("Can't read 0 bytes", "count");
+
+            m_in.next_out = buffer;
+            m_in.next_out_index = offset;
+            m_in.avail_out = count;
+            if (m_in.avail_in == 0)
+            {
+                m_in.next_in_index = 0;
+                return m_stream.BeginRead(m_inbuf, 0, bufsize, callback, state);
+            }
+            ZlibStreamAsyncResult ar = new ZlibStreamAsyncResult(state);
+            callback(ar);
+            return ar;
+        }
+
+        /// <summary>
+        /// Complete a pending read, when the callback passed to BeginRead fires.
+        /// </summary>
+        /// <param name="asyncResult"></param>
+        /// <returns></returns>
+        public override int EndRead(IAsyncResult asyncResult)
+        {
+            if (!(asyncResult is ZlibStreamAsyncResult))
+                m_in.avail_in = m_stream.EndRead(asyncResult);
+            return Inflate();
+        }
+
+        /// <summary>
+        /// Synchronous read.  Decompresses.
+        /// </summary>
+        /// <param name="buffer"></param>
+        /// <param name="offset"></param>
+        /// <param name="count"></param>
+        /// <returns></returns>
+        public override int Read(byte[] buffer, int offset, int count)
+        {
+            if (count <= 0)
+                return 0;
+
+            m_in.next_out = buffer;
+            m_in.next_out_index = offset;
+            m_in.avail_out = count;
+
+            if (m_in.avail_in == 0)
+            {
+                m_in.next_in_index = 0;
+                m_in.avail_in = m_stream.Read(m_inbuf, 0, bufsize);
+                if (m_in.avail_in == 0)
+                    return 0;
+            }
+            return Inflate();
+        }
+
+        private int Inflate()
+        {
+            int count = m_in.avail_out;
+            int err = m_in.inflate(m_flush);
+            if ((err != zlibConst.Z_OK) && (err != zlibConst.Z_STREAM_END))
+            {
+                if (err == zlibConst.Z_BUF_ERROR)
+                    return 0;
+                if (err != zlibConst.Z_OK)
+                    throw new CompressionFailedException("Decompress failed: " + err);
+            }
+            return (count - m_in.avail_out);
+        }
+
+        /// <summary>
+        /// Not implemented.
+        /// </summary>
+        /// <param name="offset"></param>
+        /// <param name="origin"></param>
+        /// <returns></returns>
+        public override long Seek(long offset, SeekOrigin origin)
+        {
+            throw new NotImplementedException("The method or operation is not implemented.");
+        }
+
+        /// <summary>
+        /// Not implemented.
+        /// </summary>
+        /// <param name="value"></param>
+        public override void SetLength(long value)
+        {
+            throw new NotImplementedException("The method or operation is not implemented.");
+        }
+
+        /// <summary>
+        /// Begin an asynch write, compressing first.  Implemented locally, since Stream.BeginWrite isn't asynch.
+        /// Note: may call Write() on the underlying stream more than once.
+        /// </summary>
+        /// <param name="buffer"></param>
+        /// <param name="offset"></param>
+        /// <param name="count"></param>
+        /// <param name="callback"></param>
+        /// <param name="state"></param>
+        /// <returns></returns>
+        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
+        {
+            if (count <= 0)
+                throw new ArgumentException("Can't write 0 bytes", "count");
+
+            m_out.next_in = buffer;
+            m_out.next_in_index = offset;
+            m_out.avail_in = count;
+
+            m_out.next_out_index = 0;
+            m_out.avail_out = bufsize;
+            int err = m_out.deflate(m_flush);
+            if (err != zlibConst.Z_STREAM_END)
+            {
+                if (err != zlibConst.Z_OK)
+                {
+                    ZlibStreamAsyncResult res = new ZlibStreamAsyncResult(state, new CompressionFailedException("Compress failed: " + err));
+                    callback(res);
+                    return res;
+                }
+            }
+            if (m_out.avail_in == 0)
+                return m_stream.BeginWrite(m_outbuf, 0, bufsize - m_out.avail_out, callback, state);
+            else
+                return m_stream.BeginWrite(m_outbuf, 0, bufsize - m_out.avail_out, new AsyncCallback(IntermediateWrite), new ZlibState(callback, state));
+        }
+
+        private void IntermediateWrite(IAsyncResult asyncResult)
+        {
+            ZlibState state = (ZlibState)asyncResult.AsyncState;
+            try
+            {
+                m_stream.EndWrite(asyncResult);
+            }
+            catch (Exception e)
+            {
+                ZlibStreamAsyncResult res = new ZlibStreamAsyncResult(state.state, e);
+                state.callback(res);
+                return;
+            }
+
+            m_out.next_out_index = 0;
+            m_out.avail_out = bufsize;
+            int err = m_out.deflate(m_flush);
+            if (err != zlibConst.Z_STREAM_END)
+            {
+                if (err != zlibConst.Z_OK)
+                {
+                    ZlibStreamAsyncResult res = new ZlibStreamAsyncResult(state.state, new CompressionFailedException("Compress failed: " + err));
+                    state.callback(res);
+                    return;
+                }
+            }
+            if (m_out.avail_in == 0)
+                m_stream.BeginWrite(m_outbuf, 0, bufsize - m_out.avail_out, state.callback, state.state);
+            else
+                m_stream.BeginWrite(m_outbuf, 0, bufsize - m_out.avail_out, new AsyncCallback(IntermediateWrite), state);
+        }
+
+        /// <summary>
+        /// Complete a pending write, when the callback given to BeginWrite is called.
+        /// </summary>
+        /// <param name="asyncResult"></param>
+        public override void EndWrite(IAsyncResult asyncResult)
+        {
+            if (asyncResult is ZlibStreamAsyncResult)
+            {
+                ZlibStreamAsyncResult ar = (ZlibStreamAsyncResult)asyncResult;
+                if (ar.Exception != null)
+                    throw ar.Exception;
+            }
+            else
+                m_stream.EndWrite(asyncResult);
+            return;
+        }
+
+        /// <summary>
+        /// Synchronous write, after compressing.
+        /// </summary>
+        /// <param name="buffer"></param>
+        /// <param name="offset"></param>
+        /// <param name="count"></param>
+        public override void Write(byte[] buffer, int offset, int count)
+        {
+            if (count <= 0)
+                return;
+            m_out.next_in = buffer;
+            m_out.next_in_index = offset;
+            m_out.avail_in = count;
+
+            while (m_out.avail_in > 0)
+            {
+                m_out.next_out_index = 0;
+                m_out.avail_out = bufsize;
+                int err = m_out.deflate(m_flush);
+                if (err != zlibConst.Z_STREAM_END)
+                {
+                    if (err != zlibConst.Z_OK)
+                        throw new CompressionFailedException("Compress failed: " + err);
+                }
+                m_stream.Write(m_outbuf, 0, bufsize - m_out.avail_out);
+            }
+        }
+
+        private class ZlibStreamAsyncResult : IAsyncResult
+        {
+            private object m_state = null;
+            private Exception m_exception;
+
+            public ZlibStreamAsyncResult(object state)
+            {
+                m_state = state;
+            }
+
+            public ZlibStreamAsyncResult(object state, Exception except)
+            {
+                m_state = state;
+                m_exception = except;
+            }
+
+            public Exception Exception
+            {
+                get { return m_exception; }
+            }
+
+            #region IAsyncResult Members
+
+            public object AsyncState
+            {
+                get { return m_state; }
+            }
+
+            public System.Threading.WaitHandle AsyncWaitHandle
+            {
+                get
+                {
+                    throw new Exception("The method or operation is not implemented.");
+                }
+            }
+
+            public bool CompletedSynchronously
+            {
+                get { return true; }
+            }
+
+            public bool IsCompleted
+            {
+                get { return true; }
+            }
+
+            #endregion
+        }
+
+        private class ZlibState
+        {
+            public AsyncCallback callback;
+            public object state;
+
+            public ZlibState(AsyncCallback callback, object state)
+            {
+                this.callback = callback;
+                this.state = state;
+            }
+        }
+    }
+}
+#endif
diff --git a/lib/jabber-net/bedrock/net/Address.cs b/lib/jabber-net/bedrock/net/Address.cs
new file mode 100644
index 0000000..36b8084
--- /dev/null
+++ b/lib/jabber-net/bedrock/net/Address.cs
@@ -0,0 +1,354 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Diagnostics;
+using System.Net;
+using System.Net.Sockets;
+using System.ComponentModel;
+using System.Globalization;
+
+using bedrock.util;
+
+#if !__MonoCS__
+using netlib.Dns;
+using netlib.Dns.Records;
+#endif
+
+namespace bedrock.net
+{
+    /// <summary>
+    /// Callback for async DNS lookups.
+    /// </summary>
+    public delegate void AddressResolved(Address addr);
+    /// <summary>
+    /// Encapsulation and caching of IP address information.  Very similar to System.Net.IPEndPoint,
+    /// but adds async DNS lookups.
+    /// TODO: add SRV?
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Address
+    {
+        private string    m_hostname = null;
+        private int       m_port     = -1;
+        private IPAddress m_ip       = IPAddress.Any;
+        /// <summary>
+        /// Address for a server, corresponding to IPAddress.Any.
+        /// </summary>
+        /// <param name="port"></param>
+        public Address(int port)
+        {
+            m_port = port;
+        }
+        /// <summary>
+        /// New connection endpoint.
+        /// </summary>
+        /// <param name="hostname">Host name or dotted-quad IP address</param>
+        /// <param name="port">Port number</param>
+        public Address(string hostname, int port) : this(port)
+        {
+            Debug.Assert(hostname != null, "must supply a host name");
+            this.Hostname = hostname;
+        }
+        /// <summary>
+        /// Create a new connection endpoint, where the IP address is already known.
+        /// </summary>
+        /// <param name="ip"></param>
+        /// <param name="port"></param>
+        public Address(IPAddress ip, int port) : this(port)
+        {
+            this.IP = ip;
+        }
+
+
+#if !__MonoCS__
+        private static SRVRecord PickSRV(SRVRecord[] srv)
+        {
+            // TODO: keep track of connection failures, and try the next priority down.
+
+            if ((srv == null) || (srv.Length == 0))
+                throw new ArgumentException();
+            if (srv.Length == 1)
+                return srv[0];
+
+            // randomize order.  One might wish that the OS would have done this for us.
+            // cf. Bob Schriter's Grandfather.
+            Random rnd = new Random();
+            byte[] keys = new byte[srv.Length];
+            rnd.NextBytes(keys);
+            Array.Sort(keys, srv);  // Permute me, Knuth!  (I wish I had a good anagram for that)
+
+            int minpri = int.MaxValue;
+            foreach (SRVRecord rec in srv)
+            {
+                if (rec.Priority < minpri)
+                {
+                    minpri = rec.Priority;
+                }
+            }
+
+            int weight = 0;
+            foreach (SRVRecord rec in srv)
+            {
+                if (rec.Priority == minpri)
+                {
+                    weight += rec.Weight;
+                }
+            }
+
+            int pos = rnd.Next(weight);
+            weight = 0;
+            foreach (SRVRecord rec in srv)
+            {
+                if (rec.Priority == minpri)
+                {
+                    weight += rec.Weight;
+                    if ((pos < weight) || (weight == 0))
+                    {
+                        return rec;
+                    }
+                }
+            }
+
+            throw new DnsException("No matching SRV");
+        }
+
+        /// <summary>
+        /// Look up a DNS SRV record, returning the best host and port number to connect to.
+        /// </summary>
+        /// <param name="prefix">The SRV prefix, ending with a dot.  Example: "_xmpp-client._tcp."</param>
+        /// <param name="domain">The domain to check</param>
+        /// <param name="host">The host name to connect to</param>
+        /// <param name="port">The port number to connect to</param>
+        public static void LookupSRV(string prefix, string domain, ref string host, ref int port)
+        {
+            if (prefix == null)
+                throw new ArgumentNullException("prefix");
+            if (domain == null)
+                throw new ArgumentNullException("domain");
+            if (!prefix.EndsWith("."))
+                throw new ArgumentOutOfRangeException("Prefix must end in '.'", "prefix");
+            try
+            {
+                DnsRequest request = new DnsRequest(prefix + domain);
+                DnsResponse response = request.GetResponse(DnsRecordType.SRV);
+
+                SRVRecord record = PickSRV(response.SRVRecords);
+                host = record.NameNext;
+                port = record.Port;
+                Debug.WriteLine(string.Format("SRV found: {0}:{1}", host, port));
+            }
+            catch
+            {
+                host = domain;
+            }
+        }
+
+        /// <summary>
+        /// Look up a DNS TXT record.
+        /// </summary>
+        /// <param name="prefix">The prefix, ending in '.'.  Example: "_xmppconnect."</param>
+        /// <param name="domain">The domain to search</param>
+        /// <param name="attribute">The attribute name to look for.  Example: "_xmpp-client-xbosh"</param>
+        /// <returns></returns>
+        public static string LookupTXT(string prefix, string domain, string attribute)
+        {
+            if (prefix == null)
+                throw new ArgumentNullException("prefix");
+            if (domain == null)
+                throw new ArgumentNullException("domain");
+            if (attribute == null)
+                throw new ArgumentNullException("attribute");
+            if (!prefix.EndsWith("."))
+                throw new ArgumentOutOfRangeException("Prefix must end in '.'", "prefix");
+
+            try
+            {
+                DnsRequest request = new DnsRequest(prefix + domain);
+                DnsResponse response = request.GetResponse(DnsRecordType.TEXT);
+                string attr = attribute + "=";
+                foreach (TXTRecord txt in response.TXTRecords)
+                {
+                    if (txt.StringArray.StartsWith(attr))
+                    {
+                        Debug.WriteLine(string.Format("TXT found: {0}", txt.StringArray));
+                        return txt.StringArray.Substring(attr.Length);
+                    }
+                }
+            }
+            catch
+            {
+            }
+            return null;
+        }
+#endif
+
+        /// <summary>
+        /// The host name.  When set, checks for dotted-quad representation, to avoid
+        /// async DNS call when possible.
+        /// </summary>
+        public string Hostname
+        {
+            get { return m_hostname; }
+            set
+            {
+                if ((value == null) || (value == ""))
+                {
+                    m_hostname = null;
+                    m_ip = IPAddress.Any;
+                    return;
+                }
+                if (m_hostname != value)
+                {
+                    m_hostname = value;
+
+                    try
+                    {
+                        m_ip = IPAddress.Parse(m_hostname);
+                    }
+                    catch (FormatException)
+                    {
+                        m_ip = null;
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Port number.
+        /// TODO: add string version that looks in /etc/services (or equiv)?
+        /// </summary>
+        public int Port
+        {
+            get { return m_port; }
+            set
+            {
+                Debug.Assert(value > 0);
+                m_port = value;
+            }
+        }
+        /// <summary>
+        /// The binary IP address.  Gives IPAddress.Any if resolution hasn't occured, and
+        /// null if resolution failed.
+        /// </summary>
+        public IPAddress IP
+        {
+            get { return m_ip; }
+            set
+            {
+                m_ip = value;
+                m_hostname = m_ip.ToString();
+            }
+        }
+        /// <summary>
+        /// Not implemented yet.
+        /// </summary>
+        public string Service
+        {
+            get { throw new NotImplementedException(); }
+            set { throw new NotImplementedException(); }
+        }
+        /// <summary>
+        /// An IPEndPoint for making socket connections with.
+        /// </summary>
+        public IPEndPoint Endpoint
+        {
+            get
+            {
+                if (m_ip == null)
+                    return null;
+                return new IPEndPoint(m_ip, Port);
+            }
+            set
+            {
+                m_ip = value.Address;
+                Port = value.Port;
+            }
+        }
+        /// <summary>
+        /// Async DNS lookup.  IP will be null in callback on failure.  Callback will
+        /// be called immediately if IP is already known (e.g. dotted-quad).
+        /// </summary>
+        /// <param name="callback">Called when resolution complete.</param>
+        public void Resolve(AddressResolved callback)
+        {
+            if ((m_ip != null) && (m_ip != IPAddress.Any)
+                && (m_ip != IPAddress.IPv6Any)
+                )
+            {
+                callback(this);
+            }
+            else
+                Dns.BeginGetHostEntry(m_hostname, new AsyncCallback(OnResolved), callback);
+        }
+
+        /// <summary>
+        /// Synchronous DNS lookup.
+        /// </summary>
+        public void Resolve()
+        {
+            if ((m_ip != null) && 
+                (m_ip != IPAddress.Any) && 
+                (m_ip != IPAddress.IPv6Any))
+            {
+                return;
+            }
+            Debug.Assert(m_hostname != null, "Must set hostname first");
+            IPHostEntry iph = Dns.GetHostEntry(m_hostname);
+
+            // TODO: what happens here on error?
+            m_ip = iph.AddressList[0];
+        }
+
+        /// <summary>
+        /// Handle the async DNS response.
+        /// </summary>
+        /// <param name="ar"></param>
+        private void OnResolved(IAsyncResult ar)
+        {
+            try
+            {
+                IPHostEntry ent = Dns.EndGetHostEntry(ar);
+                if (ent.AddressList.Length <= 0)
+                {
+                    m_ip = null;
+                }
+                else
+                {
+                    // From docs:
+                    // When hostName is a DNS-style host name associated with multiple IP addresses,
+                    // only the first IP address that resolves to that host name is returned.
+                    m_ip = ent.AddressList[0];
+                }
+            }
+            catch (Exception e)
+            {
+                Debug.WriteLine(e.ToString());
+                m_ip = null;
+            }
+            AddressResolved callback = (AddressResolved) ar.AsyncState;
+            if (callback != null)
+                callback(this);
+        }
+        /// <summary>
+        /// Readable representation of the address.
+        /// Host (IP):port
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            return string.Format("{0}({1}):{2}", m_hostname, m_ip, m_port);
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/net/AsyncSocket.cs b/lib/jabber-net/bedrock/net/AsyncSocket.cs
new file mode 100644
index 0000000..00dd52a
--- /dev/null
+++ b/lib/jabber-net/bedrock/net/AsyncSocket.cs
@@ -0,0 +1,1314 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+using bedrock.util;
+
+using System.Security.Authentication;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
+
+namespace bedrock.net
+{
+    /// <summary>
+    /// Delegate for members that receive a socket.
+    /// </summary>
+    public delegate void AsyncSocketHandler(object sender, BaseSocket sock);
+
+    /// <summary>
+    /// An asynchronous socket, which calls a listener class when
+    /// interesting things happen.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class AsyncSocket : BaseSocket, IComparable
+    {
+        /// <summary>
+        /// Socket states.
+        /// </summary>
+        [SVN(@"$Id$")]
+            private enum SocketState
+        {
+            /// <summary>
+            /// Socket has been created.
+            /// </summary>
+            Created,
+            /// <summary>
+            /// Socket is listening for new connections
+            /// </summary>
+            Listening,
+            /// <summary>
+            /// Doing DNS lookup
+            /// </summary>
+            Resolving,
+            /// <summary>
+            /// Attempting to connect
+            /// </summary>
+            Connecting,
+            /// <summary>
+            /// Connected to a peer.  The running state.
+            /// </summary>
+            Connected,
+            /// <summary>
+            /// Shutting down the socket.
+            /// </summary>
+            Closing,
+            /// <summary>
+            /// Closed down.
+            /// </summary>
+            Closed,
+            /// <summary>
+            /// An error ocurred.
+            /// </summary>
+            Error
+        }
+
+        private const int BUFSIZE = 4096;
+
+        /// <summary> The set of allowable errors in SSL certificates
+        /// if UntrustedRootOK is set to true.  </summary>
+        [Obsolete("Catch OnInvalidCertificate, instead")]
+        public const SslPolicyErrors DefaultUntrustedPolicy =
+                 SslPolicyErrors.RemoteCertificateChainErrors;
+
+        /// <summary> The allowable SSL certificate errors.  If you
+        /// modify UntrustedRootOK to true, the side effect will be to
+        /// set this to DefaultUntrustedPolicy.  False, the default,
+        /// sets this to None.  </summary>
+        private static SslPolicyErrors AllowedSSLErrors = SslPolicyErrors.None;
+
+        /// <summary>
+        /// Are untrusted root certificates OK when connecting using
+        /// SSL?  Setting this to true is insecure, but it's unlikely
+        /// that you trust jabbber.org or jabber.com's relatively
+        /// bogus certificate roots.
+        ///
+        /// Setting this modifies AllowedSSLErrors by side-effect.
+        /// </summary>
+        [DefaultValue(false)]
+        [Obsolete("Catch OnInvalidCertificate, instead")]
+        public static bool UntrustedRootOK
+        {
+            get
+            {
+                return (AllowedSSLErrors != SslPolicyErrors.None);
+            }
+            set
+            {
+                if (value)
+                {
+                    AllowedSSLErrors = DefaultUntrustedPolicy;
+                }
+                else
+                {
+                    AllowedSSLErrors = SslPolicyErrors.None;
+                }
+            }
+        }
+
+        /// <summary>
+        /// The types of SSL to support.  SSL3 and TLS1 by default.
+        /// That should be good enough for most apps, and was
+        /// hard-coded to start with.  Note: when doing start-tls,
+        /// this is overridden to just be TLS.
+        /// </summary>
+        public static SslProtocols   SSLProtocols        = SslProtocols.Ssl3 | SslProtocols.Tls;
+        private SslProtocols         m_secureProtocol    = SslProtocols.None;
+        private Socket               m_sock              = null;
+        private X509Certificate2     m_cert              = null;
+        private Stream               m_stream            = null;
+        private SslStream            m_sslStream         = null;  // hold on to the SSL stream as it goes by, since compression might happen later.
+        private MemoryStream         m_pending           = new MemoryStream();
+        private bool                 m_writing           = false;
+        private bool                 m_requireClientCert = false;
+        private bool                 m_cert_gui          = true;
+        private bool                 m_server            = false;
+        private byte[]               m_buf               = new byte[BUFSIZE];
+        private SocketState          m_state             = SocketState.Created;
+        private SocketWatcher        m_watcher           = null;
+        private Guid                 m_id                = Guid.NewGuid();
+        private bool                 m_reading           = false;
+        private bool                 m_synch             = false;
+        private Address              m_addr;
+
+
+        /// <summary>
+        /// Called from SocketWatcher.
+        /// </summary>
+        /// <param name="w"></param>
+        /// <param name="listener">The listener for this socket</param>
+        public AsyncSocket(SocketWatcher w, ISocketEventListener listener) : base(listener)
+        {
+            m_watcher = w;
+        }
+
+        /// <summary>
+        /// Called from SocketWatcher.
+        /// </summary>
+        /// <param name="w"></param>
+        /// <param name="listener">The listener for this socket</param>
+        /// <param name="SSL">Do SSL3 and TLS1 on startup (call
+        /// StartTLS later if this is false, and TLS only is needed
+        /// later)</param>
+        /// <param name="synch">Synchronous operation</param>
+        public AsyncSocket(SocketWatcher w,
+                           ISocketEventListener listener,
+                           bool SSL,
+                           bool synch) :
+            base(listener)
+        {
+            m_watcher = w;
+            m_synch = synch;
+
+            if (SSL)
+                m_secureProtocol = SSLProtocols;
+        }
+
+        private AsyncSocket(SocketWatcher w) : base()
+        {
+            m_watcher = w;
+        }
+
+        /*
+        /// <summary>
+        /// Return the state of the socket.  WARNING: don't use this.
+        /// </summary>
+        public State Socket_State
+        {
+            get
+            {
+                return m_state;
+            }
+        }
+        */
+        private SocketState State
+        {
+            get { return m_state; }
+            set
+            {
+// useful for finding unexpected socket closes.
+//                Debug.WriteLine("socket state: " + m_state.ToString() + "->" + value.ToString());
+                m_state = value;
+            }
+        }
+
+        /// <summary>
+        /// For connect sockets, the remote address.  For Accept sockets, the local address.
+        /// </summary>
+        public Address Address
+        {
+            get
+            {
+                return m_addr;
+            }
+        }
+
+        /// <summary>
+        /// Get the certificate of the remote endpoint of the socket.
+        /// </summary>
+        public X509Certificate RemoteCertificate
+        {
+            get
+            {
+                if (m_sslStream == null)
+                    return null;
+                return m_sslStream.RemoteCertificate;
+            }
+        }
+
+        /// <summary>
+        /// Choose a certificate from the local store.  If there are
+        /// none available, returns right away.
+        /// If there is exactly one, uses it.
+        /// Otherwise, prompts.
+        /// </summary>
+        [Obsolete("Pass in a list of acceptable issuers")]
+        public void ChooseClientCertificate()
+        {
+            ChooseClientCertificate(null);
+        }
+
+        /// <summary>
+        /// Choose a certificate from the local store.  If there are
+        /// none available, returns right away.
+        /// If there is exactly one, uses it.
+        /// Otherwise, prompts.
+        /// TODO: figure out something for server certs, too.
+            /// </summary>
+        /// <param name="acceptableIssuers">A list of DNs of CAs that are trusted by the other party</param>
+        public void ChooseClientCertificate(string[] acceptableIssuers)
+        {
+            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
+            store.Open(OpenFlags.ReadOnly);
+            X509Certificate2Collection coll = new X509Certificate2Collection();
+            if (acceptableIssuers == null)
+            {
+                coll.AddRange(store.Certificates);
+            }
+            else
+            {
+                foreach (X509Certificate2 cert in store.Certificates)
+                {
+                    foreach (string issuer in acceptableIssuers)
+                    {
+                        if (cert.Issuer == issuer)
+                        {
+                            coll.Add(cert);
+                        }
+                    }
+                }
+            }
+
+            switch (coll.Count)
+            {
+                case 0:
+                    return;
+                case 1:
+                    m_cert = coll[0];
+                    return;
+                default:
+                    #if __MonoCS__
+                        m_cert = null;
+                    #else
+                    X509Certificate2Collection certs = X509Certificate2UI.SelectFromCollection(
+                        coll,
+                        "Select certificate",
+                        "Use this certificate to log in",
+                        X509SelectionFlag.SingleSelection);
+                    if (certs.Count > 0)
+                        m_cert = certs[0];
+                    #endif
+                    break;
+            }
+        }
+
+        /// <summary>
+        /// Callback to choose client cert.
+        /// TODO: this should surface an event of some kind.
+        /// </summary>
+        public X509Certificate ChooseClientCertificate(Object sender,
+            string targetHost,
+            X509CertificateCollection localCertificates,
+            X509Certificate remoteCertificate,
+            string[] acceptableIssuers)
+        {
+            // this will be called twice if the server requires a client cert.
+            // Ignore the callback the first time; I think this is a .Net bug.
+            if (acceptableIssuers.Length == 0)
+                return m_cert;
+
+            if (CertificateGui)
+            {
+                if (m_cert != null)
+                    return m_cert;
+
+                ChooseClientCertificate(acceptableIssuers);
+            }
+            return m_cert;
+        }
+
+        /// <summary>
+        /// If true the certificate selection dialog is called.
+        /// </summary>
+        public bool CertificateGui
+        {
+            get { return m_cert_gui; }
+            set { m_cert_gui = value; }
+        }
+
+        /// <summary>
+        /// The local certificate of the socket.
+        /// </summary>
+        public X509Certificate2 LocalCertificate
+        {
+            get { return m_cert; }
+            set { m_cert = value; }
+        }
+
+        /// <summary>
+        /// Are we using SSL/TLS?
+        /// </summary>
+        public bool SSL
+        {
+            get
+            {
+                if (m_sslStream == null)
+                    return false;
+                return m_sslStream.IsEncrypted;
+            }
+        }
+
+        /// <summary>
+        /// Is the socket connected?
+        /// </summary>
+        public override bool Connected
+        {
+            get
+            {
+                if (m_sock == null)
+                    return false;
+                return m_sock.Connected;
+            }
+        }
+
+        /// <summary>
+        /// Sets the specified option to the specified value.
+        /// </summary>
+        /// <param name="optionLevel"></param>
+        /// <param name="optionName"></param>
+        /// <param name="optionValue"></param>
+        public void SetSocketOption(SocketOptionLevel optionLevel,
+            SocketOptionName optionName,
+            byte[] optionValue)
+        {
+            m_sock.SetSocketOption(optionLevel, optionName, optionValue);
+        }
+
+        /// <summary>
+        /// Sets the specified option to the specified value.
+        /// </summary>
+        /// <param name="optionLevel"></param>
+        /// <param name="optionName"></param>
+        /// <param name="optionValue"></param>
+        public void SetSocketOption(SocketOptionLevel optionLevel,
+            SocketOptionName optionName,
+            int optionValue)
+        {
+            m_sock.SetSocketOption(optionLevel, optionName, optionValue);
+        }
+
+        /// <summary>
+        /// Sets the specified option to the specified value.
+        /// </summary>
+        /// <param name="optionLevel"></param>
+        /// <param name="optionName"></param>
+        /// <param name="optionValue"></param>
+        public void SetSocketOption(SocketOptionLevel optionLevel,
+            SocketOptionName optionName,
+            object optionValue)
+        {
+            m_sock.SetSocketOption(optionLevel, optionName, optionValue);
+        }
+
+        /// <summary>
+        /// Prepare to start accepting inbound requests.  Call
+        /// RequestAccept() to start the async process.
+        /// </summary>
+        /// <param name="addr">Address to listen on</param>
+        /// <param name="backlog">The Maximum length of the queue of
+        /// pending connections</param>
+        public override void Accept(Address addr, int backlog)
+        {
+            lock (this)
+            {
+                m_addr = addr;
+
+                m_sock = new Socket(AddressFamily.InterNetwork,
+                                    SocketType.Stream,
+                                    ProtocolType.Tcp);
+
+                // Always reuse address.
+                m_sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
+                m_sock.Bind(m_addr.Endpoint);
+                m_sock.Listen(backlog);
+                State = SocketState.Listening;
+
+                if (m_watcher != null)
+                    m_watcher.RegisterSocket(this);
+            }
+        }
+
+        /// <summary>
+        /// Start the flow of async accepts.  Flow will continue while
+        /// Listener.OnAccept() returns true.  Otherwise, call
+        /// RequestAccept() again to continue.
+        /// </summary>
+        public override void RequestAccept()
+        {
+            lock (this)
+            {
+                if (State != SocketState.Listening)
+                {
+                    throw new InvalidOperationException("Not a listen socket");
+                }
+            }
+            if (m_synch)
+            {
+                Socket cli;
+                try
+                {
+                    cli = m_sock.Accept();
+                }
+                catch (SocketException)
+                {
+                    Debug.WriteLine("A cancel call was sent to the accepting socket.");
+                    return;
+                }
+
+                AsyncSocket cliCon = new AsyncSocket(m_watcher);
+                cliCon.m_sock = cli;
+                cliCon.m_synch = true;
+                AcceptDone(cliCon);
+            }
+            else
+            {
+                m_sock.BeginAccept(new AsyncCallback(ExecuteAccept), null);
+            }
+        }
+
+        /// <summary>
+        /// We got a connection from outside.  Add it to the SocketWatcher.
+        /// </summary>
+        /// <param name="ar"></param>
+        private void ExecuteAccept(IAsyncResult ar)
+        {
+            Socket cli = (Socket) m_sock.EndAccept(ar);
+            AsyncSocket cliCon = new AsyncSocket(m_watcher);
+            cliCon.m_sock = cli;
+            AcceptDone(cliCon);
+        }
+
+        private void AcceptDone(AsyncSocket cliCon)
+        {
+            cliCon.m_addr = m_addr;
+            cliCon.Address.IP = ((IPEndPoint) cliCon.m_sock.RemoteEndPoint).Address;
+            cliCon.State = SocketState.Connected;
+
+            cliCon.m_stream = new NetworkStream(cliCon.m_sock);
+            cliCon.m_server = true;
+            cliCon.LocalCertificate = m_cert;
+            cliCon.RequireClientCert = m_requireClientCert;
+
+            ISocketEventListener l = m_listener.GetListener(cliCon);
+            if (l == null)
+            {
+                // if the listener returns null, close the socket and
+                // quit, instead of asserting.
+                cliCon.m_sock.Close();
+                RequestAccept();
+                return;
+            }
+
+            cliCon.m_listener = l;
+
+            try
+            {
+                if (m_watcher != null)
+                    m_watcher.RegisterSocket(cliCon);
+            }
+            catch (InvalidOperationException)
+            {
+                // m_watcher out of slots.
+                cliCon.AsyncClose();
+
+                // don't set state
+                // they really don't need this error, we don't think.
+                // Error(e);
+
+                // tell the watcher that when it gets its act together,
+                // we'd appreciate it if it would restart the RequestAccept().
+                m_watcher.PendingAccept(this);
+                return;
+            }
+
+            if (m_secureProtocol != SslProtocols.None)
+                cliCon.StartTLS();
+
+            if (l.OnAccept(cliCon))
+            {
+                RequestAccept();
+            }
+        }
+
+        /// <summary>
+        /// Outbound connection.  Eventually calls Listener.OnConnect() when
+        /// the connection comes up.  Don't forget to call RequestRead() in
+        /// OnConnect()!
+        /// </summary>
+        /// <param name="addr"></param>
+        public override void Connect(Address addr)
+        {
+            // Debug.WriteLine("starting connect to " + addr.ToString());
+            State = SocketState.Resolving;
+            if (m_synch)
+            {
+                addr.Resolve();
+                OnConnectResolved(addr);
+            }
+            else
+            {
+                addr.Resolve(new AddressResolved(OnConnectResolved));
+            }
+        }
+
+        /// <summary>
+        /// Address resolution finished.  Try connecting.
+        /// </summary>
+        /// <param name="addr"></param>
+        private void OnConnectResolved(Address addr)
+        {
+            // Debug.WriteLine("connectresolved: " + addr.ToString());
+            lock (this)
+            {
+                if (State != SocketState.Resolving)
+                {
+                    // closed in the mean time.   Probably not an error.
+                    return;
+                }
+                if ((addr == null) || (addr.IP == null) || (addr.Endpoint == null))
+                {
+                    FireError(new AsyncSocketConnectionException("Bad host: " + addr.Hostname));
+                    return;
+                }
+
+
+                if (m_watcher != null)
+                    m_watcher.RegisterSocket(this);
+
+                m_addr = addr;
+                State = SocketState.Connecting;
+
+                if (Socket.OSSupportsIPv6 && (m_addr.Endpoint.AddressFamily == AddressFamily.InterNetworkV6))
+                {
+                    // Debug.WriteLine("ipv6");
+                    m_sock = new Socket(AddressFamily.InterNetworkV6,
+                        SocketType.Stream,
+                        ProtocolType.Tcp);
+                }
+                else
+                {
+                    // Debug.WriteLine("ipv4");
+                    m_sock = new Socket(AddressFamily.InterNetwork,
+                        SocketType.Stream,
+                        ProtocolType.Tcp);
+                }
+
+                // well, of course this isn't right.
+                m_sock.SetSocketOption(SocketOptionLevel.Socket,
+                    SocketOptionName.ReceiveBuffer,
+                    4 * m_buf.Length);
+            }
+
+            if (m_synch)
+            {
+                try
+                {
+                    m_sock.Connect(m_addr.Endpoint);
+                }
+                catch (SocketException ex)
+                {
+                    FireError(ex);
+                    return;
+                }
+
+                if (m_sock.Connected)
+                {
+                    // TODO: check to see if this Mono bug is still valid
+#if __MonoCS__
+                    m_sock.Blocking = true;
+                    m_stream = new NetworkStream(m_sock);
+                    m_sock.Blocking = false;
+#else
+                    m_stream = new NetworkStream(m_sock);
+#endif
+                    if (m_secureProtocol != SslProtocols.None)
+                        StartTLS();
+
+                    lock (this)
+                    {
+                        State = SocketState.Connected;
+                    }
+                    m_listener.OnConnect(this);
+                }
+                else
+                {
+                    AsyncClose();
+                    FireError(new AsyncSocketConnectionException("could not connect"));
+                }
+            }
+            else
+            {
+#if __MonoCS__
+                m_sock.Blocking = false;
+#endif
+                m_sock.BeginConnect(m_addr.Endpoint, new AsyncCallback(ExecuteConnect), null);
+            }
+        }
+
+        /// <summary>
+        /// Validate the server cert.  SSLPolicyErrors will be
+        /// pre-filled with the errors you got.
+        ///
+        /// If there is an error in the cert, OnIvalidCertificate will be called.
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="certificate"></param>
+        /// <param name="chain"></param>
+        /// <param name="sslPolicyErrors"></param>
+        /// <returns></returns>
+        protected bool ValidateServerCertificate(object sender,
+                                                 X509Certificate certificate,
+                                                 X509Chain chain,
+                                                 SslPolicyErrors sslPolicyErrors)
+        {
+            // Note: Don't write servers with Jabber-Net, please.  :)
+            if (m_server)
+            {
+                return true;
+            }
+
+            if (sslPolicyErrors == SslPolicyErrors.None)
+                return true;
+
+            if ((sslPolicyErrors & (sslPolicyErrors ^ AllowedSSLErrors)) == SslPolicyErrors.None)
+            {
+                // Huh.  Maybe there should be a listener method for this.
+                return true;
+            }
+
+            if (m_listener.OnInvalidCertificate(this, certificate, chain, sslPolicyErrors))
+                return true;
+
+            Debug.WriteLine("Certificate error: {0}", sslPolicyErrors.ToString());
+
+            // Do not allow this client to communicate with unauthenticated servers.
+            return false;
+        }
+
+        /// <summary>
+        /// Start TLS processing on an open socket.
+        /// </summary>
+        public override void StartTLS()
+        {
+            // we're really doing start-tls.
+            if (m_secureProtocol == SslProtocols.None)
+                m_secureProtocol = SslProtocols.Tls;
+
+            m_stream = m_sslStream = new SslStream(m_stream, false, ValidateServerCertificate, ChooseClientCertificate);
+
+            if (m_server)
+            {
+                if (m_cert == null)
+                {
+                    FireError(new InvalidOperationException("Must set Certificate for server SSL"));
+                    Close();
+                    return;
+                }
+                // TODO: surface these as params
+                m_sslStream.AuthenticateAsServer(m_cert, m_requireClientCert, m_secureProtocol, false);
+            }
+            else
+            {
+                if ((m_watcher != null) && (m_watcher.LocalCertificate != null))
+                    m_cert = m_watcher.LocalCertificate;
+
+                X509CertificateCollection certs = null;
+                if (m_cert != null)
+                {
+                    certs = new X509Certificate2Collection();
+                    certs.Add(m_cert);
+                }
+                try
+                {
+                    m_sslStream.AuthenticateAsClient(m_hostid, certs, m_secureProtocol, false);
+                }
+                catch (Exception ex)
+                {
+                    FireError(ex);
+                    //Close();
+                    //throw;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Is the connection mutually authenticated?  (was there a good client cert, etc.)
+        /// </summary>
+        public bool IsMutuallyAuthenticated
+        {
+            get
+            {
+                if (m_sslStream == null)
+                    return false;
+                return m_sslStream.IsMutuallyAuthenticated;
+            }
+        }
+
+        /// <summary>
+        /// Does the server require a client cert?  If not, the client cert won't be sent.
+        /// </summary>
+        public bool RequireClientCert
+        {
+            get { return m_requireClientCert; }
+            set { m_requireClientCert = value; }
+        }
+
+        /// <summary>
+        /// Start XEP-138 compression on this socket.
+        /// </summary>
+        public override void StartCompression()
+        {
+#if ZLIB_NET
+            m_stream = new bedrock.io.ZlibStream(m_stream, ComponentAce.Compression.Libs.zlib.zlibConst.Z_FULL_FLUSH);
+#else
+            throw new NotSupportedException();
+#endif
+        }
+
+        /// <summary>
+        /// Connection complete.
+        /// </summary>
+        /// <remarks>This is called solely by an async socket thread</remarks>
+        /// <param name="ar"></param>
+        private void ExecuteConnect(IAsyncResult ar)
+        {
+            Debug.WriteLine("ExecuteConnect");
+            lock (this)
+            {
+                try
+                {
+                    m_sock.EndConnect(ar);
+                }
+                catch (SocketException e)
+                {
+                    if (State != SocketState.Connecting)
+                    {
+                        // closed in the mean time.   Probably not an error.
+                        return;
+                    }
+                    FireError(e);
+                    return;
+                }
+                if (m_sock.Connected)
+                {
+                    // TODO: Check to see if this Mono bug is still valid.
+                    // TODO: check to see if blocking should be turned back on after StartTLS.
+#if __MonoCS__
+                    m_sock.Blocking = true;
+                    m_stream = new NetworkStream(m_sock);
+                    m_sock.Blocking = false;
+#else
+                    m_stream = new NetworkStream(m_sock);
+#endif
+
+                    if (m_secureProtocol != SslProtocols.None)
+                    {
+                        try
+                        {
+                            StartTLS();
+                        }
+                        catch (Exception e)
+                        {
+                            FireError(e);
+                            AsyncClose();
+                            return;
+                        }
+                    }
+
+                    State = SocketState.Connected;
+                    m_listener.OnConnect(this);
+                }
+                else
+                {
+                    FireError(new AsyncSocketConnectionException("could not connect"));
+                    AsyncClose();
+                }
+            }
+        }
+
+        private bool SyncRead()
+        {
+            int count = m_stream.Read(m_buf, 0, m_buf.Length);
+
+            if (count > 0)
+            {
+                return m_listener.OnRead(this, m_buf, 0, count);
+            }
+            Close();
+            return false;
+        }
+
+        /// <summary>
+        /// Start an async read from the socket.  Listener.OnRead() is
+        /// eventually called when data arrives.
+        /// </summary>
+        public override void RequestRead()
+        {
+            try
+            {
+                if (m_synch)
+                {
+                    lock (this)
+                    {
+                        if (State != SocketState.Connected)
+                        {
+                            throw new InvalidOperationException("Socket not connected.");
+                        }
+                    }
+
+                    while (SyncRead())
+                    {
+                        ;
+                    }
+                    return;
+                }
+
+                lock (this)
+                {
+                    if (m_reading)
+                    {
+                        throw new InvalidOperationException("Cannot call RequestRead while another read is pending.");
+                    }
+                    if (State != SocketState.Connected)
+                    {
+                        throw new InvalidOperationException("Socket not connected.");
+                    }
+
+                    m_reading = true;
+                }
+                m_stream.BeginRead(m_buf, 0, m_buf.Length, new AsyncCallback(GotData), null);
+            }
+            catch (AuthenticationException)
+            {
+                Close();
+                // don't throw.  this gets caught elsewhere.
+            }
+            catch (SocketException e)
+            {
+                Close();
+
+                // 10053 = An established connection was aborted by the
+                //         software in your host machine.
+                // 10054 = An existing connection was forcibly closed
+                //         by the remote host.
+                if ((e.ErrorCode != 10053) &&
+                    (e.ErrorCode != 10054))
+                {
+                    throw;
+                }
+            }
+            catch (IOException)
+            {
+                Close();
+            }
+            catch (Exception e)
+            {
+                Debug.WriteLine("Exception in RequestRead: " + e.ToString());
+                Close();
+                throw e;
+            }
+        }
+
+        /// <summary>
+        /// Some data arrived.
+        /// </summary>
+        /// <param name="ar"></param>
+        protected virtual void GotData(IAsyncResult ar)
+        {
+            lock (this)
+            {
+                m_reading = false;
+            }
+
+            int count;
+            try
+            {
+                count = m_stream.EndRead(ar);
+            }
+            catch (SocketException e)
+            {
+                AsyncClose();
+
+                // closed in middle of read
+                if (e.ErrorCode != 64)
+                {
+                    FireError(e);
+                }
+                return;
+            }
+            catch(ObjectDisposedException)
+            {
+                //object already disposed, just exit
+                return;
+            }
+            catch (Exception e)
+            {
+                AsyncClose();
+                FireError(e);
+                return;
+            }
+            if (count > 0)
+            {
+                //byte[] ret = new byte[count];
+                //Buffer.BlockCopy(m_buf, 0, ret, 0, count);
+
+                if (m_listener.OnRead(this, m_buf, 0, count) &&
+                    (m_state == SocketState.Connected))
+                {
+                    RequestRead();
+                }
+            }
+            else
+            {
+                AsyncClose();
+            }
+        }
+
+        /// <summary>
+        /// Async write to the socket.  Listener.OnWrite will be
+        /// called eventually when the data has been written.  A
+        /// trimmed copy is made of the data, internally.
+        /// </summary>
+        /// <param name="buf">Buffer to output</param>
+        /// <param name="offset">Offset into buffer</param>
+        /// <param name="len">Number of bytes to output</param>
+        public override void Write(byte[] buf, int offset, int len)
+        {
+            lock (this)
+            {
+                if (State != SocketState.Connected)
+                {
+                    return;
+                    //throw new InvalidOperationException("Socket must be connected before writing.  Current state: " + State.ToString());
+                }
+
+                try
+                {
+                    if (m_synch)
+                    {
+                        m_stream.Write(buf, offset, len);
+                        m_listener.OnWrite(this, buf, offset, len);
+                    }
+                    else
+                    {
+
+                        if (m_writing)
+                        {
+                            // already writing.  save this for later.
+                            m_pending.Write(buf, offset, len);
+                        }
+                        else
+                        {
+                            m_writing = true;
+                            // make copy, since we might be a while in async-land
+                            byte[] ret = new byte[len];
+                            Buffer.BlockCopy(buf, offset, ret, 0, len);
+
+                            m_stream.BeginWrite(ret, 0, ret.Length,
+                                                new AsyncCallback(WroteData),
+                                                ret);
+                        }
+                    }
+                }
+                catch (SocketException e)
+                {
+                    Close();
+
+                    // closed in middle of write
+                    if (e.ErrorCode != 10054)
+                    {
+                        FireError(e);
+                    }
+                    return;
+                }
+                catch (Exception e)
+                {
+                    Close();
+                    FireError(e);
+                    return;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Data was written.
+        /// </summary>
+        /// <param name="ar"></param>
+        private void WroteData(IAsyncResult ar)
+        {
+            try
+            {
+                m_stream.EndWrite(ar);
+            }
+            catch (SocketException)
+            {
+                AsyncClose();
+                return;
+            }
+            catch (ObjectDisposedException)
+            {
+                AsyncClose();
+                return;
+            }
+            catch (Exception e)
+            {
+                AsyncClose();
+                FireError(e);
+                return;
+            }
+
+            lock (this)
+            {
+                m_writing = false;
+            }
+            byte[] buf = (byte[])ar.AsyncState;
+            m_listener.OnWrite(this, buf, 0, buf.Length);
+
+            if (m_pending.Length > 0)
+            {
+                buf = m_pending.ToArray();
+                m_pending.SetLength(0L);
+                Write(buf);
+            }
+        }
+
+        /// <summary>
+        /// Close the socket.  This is NOT async.  .Net doesn't have
+        /// async closes.  But, it can be *called* async, particularly
+        /// from GotData.  Attempts to do a shutdown() first.
+        /// </summary>
+        public override void Close()
+        {
+            Debug.WriteLine("Close");
+            lock (this)
+            {
+                /*
+                switch (State)
+                {
+                case State.Closed:
+                    throw new InvalidOperationException("Socket already closed");
+                case State.Closing:
+                    throw new InvalidOperationException("Socket already closing");
+                }
+                */
+
+                SocketState oldState = State;
+
+                if (m_sock.Connected)
+                {
+                    State = SocketState.Closing;
+                }
+
+                if (m_stream != null)
+                    m_stream.Close();
+                else
+                {
+                    try
+                    {
+                        m_sock.Close();
+                    }
+                    catch { }
+                }
+
+                if (oldState <= SocketState.Connected)
+                    m_listener.OnClose(this);
+
+                if (m_watcher != null)
+                    m_watcher.CleanupSocket(this);
+
+                State = SocketState.Closed;
+            }
+        }
+
+
+        /// <summary>
+        /// Close, called from async places, so that Errors get fired,
+        /// appropriately.
+        /// </summary>
+        protected void AsyncClose()
+        {
+            try
+            {
+                Close();
+            }
+            catch(Exception e)
+            {
+                FireError(e);
+            }
+        }
+
+        /// <summary>
+        /// Error occurred in the class.  Send to Listener.
+        /// </summary>
+        /// <param name="e"></param>
+        protected void FireError(Exception e)
+        {
+            lock (this)
+            {
+                State = SocketState.Error;
+            }
+            if (e is SocketException)
+            {
+                Debug.WriteLine("Sock errno: " + ((SocketException) e).ErrorCode);
+            }
+            if (m_watcher != null)
+                m_watcher.CleanupSocket(this);
+            m_listener.OnError(this, e);
+        }
+
+
+        /// <summary>
+        /// Return a string representation of this socket
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            return "AsyncSocket " + m_sock.LocalEndPoint + "->" +
+                m_sock.RemoteEndPoint;
+        }
+
+        /// <summary>
+        /// In case SocketWatcher wants to use a HashTable.
+        /// </summary>
+        /// <returns></returns>
+        public override int GetHashCode()
+        {
+            return m_id.GetHashCode();
+        }
+
+        #region IComparable
+        int IComparable.CompareTo(object val)
+        {
+            if (val == null)
+                return 1;
+
+            AsyncSocket sock = val as AsyncSocket;
+            if ((object)sock == null)
+                throw new ArgumentException("value compared to is not an AsyncSocket", "val");
+
+            return this.m_id.CompareTo(sock.m_id);
+        }
+
+        /// <summary>
+        /// IComparable's need to implement Equals().  This checks the
+        /// guid's for each socket to see if they are the same.
+        /// </summary>
+        /// <param name="val">The AsyncSocket to check against.</param>
+        /// <returns></returns>
+        public override bool Equals(object val)
+        {
+            AsyncSocket sock = val as AsyncSocket;
+            if (sock == null)
+                return false;
+            return (this.m_id == sock.m_id);
+        }
+
+        /// <summary>
+        /// IComparable's need to implement ==.  Checks for guid equality.
+        /// </summary>
+        /// <param name="one">First socket to compare</param>
+        /// <param name="two">Second socket to compare</param>
+        /// <returns></returns>
+        public static bool operator==(AsyncSocket one, AsyncSocket two)
+        {
+            if ((object)one == null)
+                return ((object)two == null);
+            if ((object)two == null)
+                return false;
+
+            return (one.m_id == two.m_id);
+        }
+
+        /// <summary>
+        /// IComparable's need to implement comparison operators.
+        /// Checks compares guids.
+        /// </summary>
+        /// <param name="one">First socket to compare</param>
+        /// <param name="two">Second socket to compare</param>
+        /// <returns></returns>
+        public static bool operator!=(AsyncSocket one, AsyncSocket two)
+        {
+            if ((object)one == null)
+                return ((object)two != null);
+            if ((object)two == null)
+                return true;
+
+            return (one.m_id != two.m_id);
+        }
+
+        /// <summary>
+        /// IComparable's need to implement comparison operators.  Checks compares guids.
+        /// </summary>
+        /// <param name="one">First socket to compare</param>
+        /// <param name="two">Second socket to compare</param>
+        /// <returns></returns>
+        public static bool operator<(AsyncSocket one, AsyncSocket two)
+        {
+            if ((object)one == null)
+            {
+                return ((object)two != null);
+            }
+            return (((IComparable)one).CompareTo(two) < 0);
+        }
+        /// <summary>
+        /// IComparable's need to implement comparison operators.
+        /// Checks compares guids.
+        /// </summary>
+        /// <param name="one">First socket to compare</param>
+        /// <param name="two">Second socket to compare</param>
+        /// <returns></returns>
+        public static bool operator<=(AsyncSocket one, AsyncSocket two)
+        {
+            if ((object)one == null)
+                return true;
+
+            return (((IComparable)one).CompareTo(two) <= 0);
+        }
+        /// <summary>
+        /// IComparable's need to implement comparison operators.
+        /// Checks compares guids.
+        /// </summary>
+        /// <param name="one">First socket to compare</param>
+        /// <param name="two">Second socket to compare</param>
+        /// <returns></returns>
+        public static bool operator>(AsyncSocket one, AsyncSocket two)
+        {
+            if ((object)one == null)
+                return false;
+            return (((IComparable)one).CompareTo(two) > 0);
+        }
+        /// <summary>
+        /// IComparable's need to implement comparison operators.  Checks compares guids.
+        /// </summary>
+        /// <param name="one">First socket to compare</param>
+        /// <param name="two">Second socket to compare</param>
+        /// <returns></returns>
+        public static bool operator>=(AsyncSocket one, AsyncSocket two)
+        {
+            if ((object)one == null)
+            {
+                return (two == null);
+            }
+            return (((IComparable)one).CompareTo(two) >= 0);
+        }
+
+        #endregion
+
+        /// <summary>
+        /// Retrieve the socketwatcher used by this instance of AsyncSocket
+        /// </summary>
+        public SocketWatcher SocketWatcher
+        {
+            get
+            {
+                return m_watcher;
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/net/BaseSocket.cs b/lib/jabber-net/bedrock/net/BaseSocket.cs
new file mode 100644
index 0000000..6a01323
--- /dev/null
+++ b/lib/jabber-net/bedrock/net/BaseSocket.cs
@@ -0,0 +1,180 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Diagnostics;
+
+namespace bedrock.net
+{
+    /// <summary>
+    /// Base class for AsyncSocket and proxies for AsyncSocket
+    /// </summary>
+    public abstract class BaseSocket
+    {
+        /// <summary>
+        /// Identity of the host we're connecting to.  Used for SSL
+        /// validation, this is the name of the SRV we looked up, for
+        /// example.
+        /// </summary>
+        protected string m_hostid = null;
+
+        /// <summary>
+        /// Call through this interface when events happen.  WARNING:
+        /// AsyncSocket assumes this is not NULL.
+        /// </summary>
+        protected ISocketEventListener m_listener = null;
+
+        /// <summary>
+        /// Only to be called by things that immediately set m_listener!
+        /// </summary>
+        protected BaseSocket()
+        {
+        }
+
+        /// <summary>
+        /// Construct a BaseSocket.
+        /// </summary>
+        /// <param name="listener"></param>
+        protected BaseSocket(ISocketEventListener listener)
+        {
+            Debug.Assert(listener != null);
+            m_listener = listener;
+        }
+
+        /// <summary>
+        /// Where to send notifications of interesting things.
+        /// WARNING!  Only assign to this if you are Tom Waters.
+        /// </summary>
+        public virtual ISocketEventListener Listener
+        {
+            get
+            {
+                return m_listener;
+            }
+            set
+            {
+                lock (this)
+                {
+                    //if (m_reading)
+                    //    throw new InvalidOperationException("Don't set listener while reading, Tom.");
+                    m_listener = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Prepare to start accepting inbound requests.  Call
+        /// RequestAccept() to start the async process.
+        /// Default the listen queue size to 5.
+        /// </summary>
+        /// <param name="addr">Address to listen on</param>
+        public void Accept(Address addr)
+        {
+            Accept(addr, 5);
+        }
+
+        /// <summary>
+        /// Prepare to start accepting inbound requests.  Call
+        /// RequestAccept() to start the async process.
+        /// </summary>
+        /// <param name="addr">Address to listen on</param>
+        /// <param name="backlog">The Maximum length of the queue of
+        /// pending connections</param>
+        public abstract void Accept(Address addr, int backlog);
+
+        /// <summary>
+        /// Start the flow of async accepts.  Flow will continue while
+        /// Listener.OnAccept() returns true.  Otherwise, call RequestAccept() again
+        /// to continue.
+        /// </summary>
+        public abstract void RequestAccept();
+
+        /// <summary>
+        /// Outbound connection.  Eventually calls Listener.OnConnect() when
+        /// the connection comes up.  Don't forget to call RequestRead() in
+        /// OnConnect()!
+        /// </summary>
+        /// <param name="addr">Address/hostname to connect to</param>
+        /// <param name="hostIdentity">Identity of the host we're
+        /// connecting to.  Used for SSL validation, this is the name
+        /// of the SRV we looked up, for example.</param>
+        public void Connect(Address addr, string hostIdentity)
+        {
+            m_hostid = hostIdentity;
+            Connect(addr);
+        }
+
+        /// <summary>
+        /// Outbound connection.  Eventually calls Listener.OnConnect() when
+        /// the connection comes up.  Don't forget to call RequestRead() in
+        /// OnConnect()!
+        /// </summary>
+        /// <param name="addr"></param>
+        public abstract void Connect(Address addr);
+
+        ///<summary>
+        /// Returns true if the socket is connected.
+        ///</summary>
+        public abstract bool Connected
+        { 
+            get;
+        }
+
+#if !NO_SSL
+        /// <summary>
+        /// Start TLS processing on an open socket.
+        /// </summary>
+        public abstract void StartTLS();
+#endif
+
+        /// <summary>
+        /// Start XEP-138 compression on this socket.
+        /// </summary>
+        public abstract void StartCompression();
+
+        /// <summary>
+        /// Start an async read from the socket.  Listener.OnRead() is
+        /// eventually called when data arrives.
+        /// </summary>
+        public abstract void RequestRead();
+
+        /// <summary>
+        /// Async write to the socket.  Listener.OnWrite will be
+        /// called eventually when the data has been written.  A copy
+        /// is made of the data, internally.
+        /// </summary>
+        /// <param name="buf">Data to write</param>
+        public void Write(byte[] buf)
+        {
+            Write(buf, 0, buf.Length);
+        }
+
+        /// <summary>
+        /// Async write to the socket.  Listener.OnWrite will be
+        /// called eventually when the data has been written.  A
+        /// trimmed copy is made of the data, internally.
+        /// </summary>
+        /// <param name="buf">Buffer to output</param>
+        /// <param name="offset">Offset into buffer</param>
+        /// <param name="len">Number of bytes to output</param>
+        public abstract void Write(byte[] buf, int offset, int len);
+
+        /// <summary>
+        /// Close the socket.  This is NOT async.  .Net doesn't have
+        /// async closes.  But, it can be *called* async, particularly
+        /// from GotData.  Attempts to do a shutdown() first.
+        /// </summary>
+        public abstract void Close();
+    }
+}
diff --git a/lib/jabber-net/bedrock/net/CertUtil.cs b/lib/jabber-net/bedrock/net/CertUtil.cs
new file mode 100644
index 0000000..a328614
--- /dev/null
+++ b/lib/jabber-net/bedrock/net/CertUtil.cs
@@ -0,0 +1,60 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net can be used under either JOSL or the GPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+#if !NO_SSL && !NET20  && !__MonoCS__
+using Org.Mentalis.Security.Certificates;
+using bedrock.util;
+
+namespace bedrock.net
+{
+    /// <summary>
+    /// Utilities for creating certificates
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class CertUtil
+    {
+        /// <summary>
+        /// Can this cert be used for server authentication?
+        /// </summary>
+        private const string OID_PKIX_KP_SERVER_AUTH = "1.3.6.1.5.5.7.3.1";
+        /// <summary>
+        /// Can this cert be used for client authentication?
+        /// </summary>
+        private const string OID_PKIX_KP_CLIENT_AUTH = "1.3.6.1.5.5.7.3.2";
+
+        /// <summary>
+        /// Find a server certificate in the given store.
+        /// </summary>
+        /// <param name="store"></param>
+        /// <returns></returns>
+        public static Certificate FindServerCert(CertificateStore store)
+        {
+            // return store.FindCertificate(new string[] {OID_PKIX_KP_SERVER_AUTH});
+            return store.FindCertificateByUsage(new string[] {OID_PKIX_KP_SERVER_AUTH});
+        }
+
+        /// <summary>
+        /// Find a client certificate in the given store.
+        /// </summary>
+        /// <param name="store"></param>
+        /// <returns></returns>
+        public static Certificate FindClientCert(CertificateStore store)
+        {
+            //return store.FindCertificate(new string[] {OID_PKIX_KP_CLIENT_AUTH});
+            return store.FindCertificateByUsage(new string[] {OID_PKIX_KP_CLIENT_AUTH});
+        }
+    }
+}
+#endif
diff --git a/lib/jabber-net/bedrock/net/Exceptions.cs b/lib/jabber-net/bedrock/net/Exceptions.cs
new file mode 100644
index 0000000..bcefc83
--- /dev/null
+++ b/lib/jabber-net/bedrock/net/Exceptions.cs
@@ -0,0 +1,69 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using bedrock.util;
+
+namespace bedrock.net
+{
+    /// <summary>
+    /// Lame exception, since I couldn't find one I liked.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [Serializable]
+    public class AsyncSocketConnectionException : System.SystemException
+    {
+        /// <summary>
+        /// Create a new exception instance.
+        /// </summary>
+        /// <param name="description"></param>
+        public AsyncSocketConnectionException(string description)
+            : base(description)
+        {
+        }
+
+        /// <summary>
+        /// Create a new exception instance.
+        /// </summary>
+        public AsyncSocketConnectionException()
+            : base()
+        {
+        }
+
+        /// <summary>
+        /// Create a new exception instance, wrapping another exception.
+        /// </summary>
+        /// <param name="description">Desecription of the exception</param>
+        /// <param name="e">Inner exception</param>
+        public AsyncSocketConnectionException(string description, Exception e)
+            : base(description, e)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the
+        /// AsyncSocketConnectionException class with serialized
+        /// data.
+        /// </summary>
+        /// <param name="info">The object that holds the serialized
+        /// object data.</param>
+        /// <param name="ctx">The contextual information about the
+        /// source or destination.</param>
+        protected AsyncSocketConnectionException(System.Runtime.Serialization.SerializationInfo info,
+            System.Runtime.Serialization.StreamingContext ctx)
+            :
+            base(info, ctx)
+        {
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/net/HttpSocket.cs b/lib/jabber-net/bedrock/net/HttpSocket.cs
new file mode 100644
index 0000000..e575b97
--- /dev/null
+++ b/lib/jabber-net/bedrock/net/HttpSocket.cs
@@ -0,0 +1,647 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.Net;
+using System.Text;
+using System.Threading;
+
+using bedrock.util;
+
+namespace bedrock.net
+{
+    /// <summary>
+    /// Do basic HTTP processing, with a long-lived socket.
+    /// TODO: the BaseSocket parameter in the listener events will always be null for now.
+    /// TODO: change HttpSocket to be a is-a of AsyncSocket, not has-a.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class HttpSocket : BaseSocket, ISocketEventListener
+	{
+        private class PendingRequest
+        {
+            public string Method;
+            public Uri URI;
+            public byte[] Body;
+            public string ContentType;
+            public int Offset;
+            public int Length;
+
+            public WebHeaderCollection Headers = new WebHeaderCollection();
+            public int Code = -1;
+            public string ResponseText = null;
+            public MemoryStream Response;
+
+            public PendingRequest(string method, Uri URL, byte[] body, int offset, int len, string contentType)
+            {
+                this.Method = method;
+                this.URI = URL;
+                this.Body = (body == null) ? new byte[] { } : body;
+                this.Offset = offset;
+                this.Length = len;
+                this.ContentType = contentType;
+            }
+
+            public int ContentLength
+            {
+                get
+                {
+                    string slen = this.Headers[HttpResponseHeader.ContentLength];
+                    if (slen == null)
+                    {
+                        Debug.WriteLine("No Content-Length header");
+                        return -1;
+                    }
+                    try
+                    {
+                        return int.Parse(slen);
+                    }
+                    catch (Exception)
+                    {
+                        Debug.WriteLine("Invalid Content-Length");
+                        return -1;
+                    }
+                }
+            }
+        }
+
+        private static readonly Encoding ENC = Encoding.UTF8;
+        private string m_host = null;
+        private Address m_addr = null;
+        private bool m_ssl = false;
+
+        private AsyncSocket m_sock = null;
+        private ParseState m_state = ParseState.START;
+        private PendingRequest m_current = null;
+        private bool m_keepRunning = true;
+        private Uri m_proxyURI = null;
+        private NetworkCredential m_proxyCredentials = null;
+        private float m_connectRetrySec = 10.0F;
+        private int m_maxErrors = 5;
+        private int m_errorCount = 0;
+        private object m_lock = new Object();
+                
+        private static readonly byte[] SPACE = ENC.GetBytes(" ");
+        private static readonly byte[] CRLF = ENC.GetBytes("\r\n");
+        private static readonly byte[] COL_SP = ENC.GetBytes(": ");
+        private static readonly byte[] SP_HTTP11_CRLF = ENC.GetBytes(" HTTP/1.1\r\n");
+        private static readonly byte[] HTTP11_SP = ENC.GetBytes("HTTP/1.1 ");
+
+        /// <summary>
+        /// Create a socket.  This starts a thread for background processing, but the thread is mostly paused
+        /// waiting for new requests.
+        /// </summary>
+        public HttpSocket(ISocketEventListener listener) : base(listener)
+        {
+        }
+
+        /// <summary>
+        /// The URI of the HTTP proxy.  Note: HTTPS connections through a proxy are not yet supported.
+        /// </summary>
+        [DefaultValue(null)]
+        public Uri ProxyURI
+        {
+            get { return m_proxyURI; }
+            set { m_proxyURI = value; }
+        }
+
+        /// <summary>
+        /// Username/password for the proxy.
+        /// </summary>
+        [DefaultValue(null)]
+        public NetworkCredential ProxyCredentials
+        {
+            get { return m_proxyCredentials; }
+            set { m_proxyCredentials = value; }
+        }
+
+        /// <summary>
+        /// How long to wait before attempting to reconnect, in seconds.
+        /// </summary>
+        [DefaultValue(10.0f)]
+        public float ReconnectTimeout
+        {
+            get { return m_connectRetrySec; }
+            set { m_connectRetrySec = value; }
+        }
+
+        /// <summary>
+        /// The maximum number of reconnect attempts before giving up.
+        /// </summary>
+        [DefaultValue(5)]
+        public int MaxErrors
+        {
+            get { return m_maxErrors; }
+            set { m_maxErrors = value; }
+        }
+
+        private string m_name;
+
+        /// <summary>
+        /// The name of the socket, for debugging purposes
+        /// </summary>
+        public string Name
+        {
+            get { return m_name; }
+            set { m_name = value; }
+        }
+
+        /// <summary>
+        /// Execute an HTTP request.
+        /// </summary>
+        /// <param name="method">The HTTP method verb.  E.g. "GET", "POST", etc.</param>
+        /// <param name="URL">The URL to request.  MUST be for the same host as the first request.</param>
+        /// <param name="body">Any data to post with the request</param>
+        /// <param name="offset">The offset into body from which to start</param>
+        /// <param name="len">The number of bytes to read from body, starting at offset</param>
+        /// <param name="contentType">The MIME type of the supplied body</param>
+        public void Execute(string method, Uri URL, byte[] body, int offset, int len, string contentType)
+        {
+            Debug.Assert(!this.IsPending);
+
+            PendingRequest req = new PendingRequest(method, URL, body, offset, len, contentType);
+            if (m_host == null)
+                m_host = req.URI.Host;
+            else if (m_host != req.URI.Host)
+                throw new InvalidOperationException("All requests must got to same host: " + m_host);
+
+            // connect if not yet connected
+            if (req.Method != null)
+            {
+                lock (m_lock)
+                {
+                    if (!Connected)
+                    {
+                        Connect(req.URI);
+
+                        Monitor.Wait(m_lock, (int)(m_connectRetrySec * 1000));
+                        if (!m_keepRunning)
+                            return;
+
+                        Debug.Assert(Connected);
+                        Debug.Assert(!IsPending);
+                    }
+                }
+            }
+            Send(req);
+        }
+
+        /// <summary>
+        /// Is there an outstanding request that has not been responded to?
+        /// </summary>
+        public bool IsPending
+        {
+            get { return (m_current != null); }
+        }
+
+        /// <summary>
+        /// Generally should not be used.
+        /// </summary>
+        /// <param name="uri"></param>
+        internal void Connect(Uri uri)
+        {
+            m_keepRunning = true;
+
+            if (Connected)
+                return;
+
+            m_ssl = (uri != null) && (uri.Scheme == "https");
+            m_host = uri.Host;
+            if (m_proxyURI != null)
+            {
+                // TODO: add CONNECT support here.  ShttpProxy?
+                if (m_ssl)
+                    throw new InvalidOperationException("Can't do SSL through proxies yet.");
+                uri = m_proxyURI;
+            }
+            m_addr = new Address(uri.Host, uri.Port);
+            Connect();
+        }
+
+        private void Connect()
+        {
+            m_errorCount = 0;
+
+            if (!m_keepRunning)
+                return;
+            m_state = ParseState.START;
+            m_sock = new AsyncSocket(null, this, m_ssl, false);
+            m_sock.Connect(m_addr, m_host);
+        }
+
+        /// <summary>
+        /// Shut down the socket, abandoning any outstainding requests
+        /// </summary>
+        public override void Close()
+        {
+            lock (m_lock)
+            {
+                m_keepRunning = false;
+                // in case we closed while waiting for connect
+                Monitor.Pulse(m_lock);
+            }
+
+            if (Connected)
+                m_sock.Close();
+            m_sock = null;
+        }
+
+        /// <summary>
+        /// Close the socket after any pending request is completed.
+        /// </summary>
+        public void EnqueueClose()
+        {
+            lock (m_lock)
+            {
+                if (!m_keepRunning)
+                    return;
+
+                m_keepRunning = false;
+                if (!IsPending)
+                    Close();
+                // otherwise, we'll close after the current pending request completes
+            }
+        }
+
+        #region ISocketEventListener Members
+
+        void ISocketEventListener.OnInit(BaseSocket newSock)
+        {
+            // This is the one listener event with a good socket, but it might not be the one that anyone expects.
+            // The important thing is that if someone wants to set the TCP buffer sizes downstream, it 
+            // will work.
+            m_listener.OnInit(newSock);
+        }
+
+        ISocketEventListener ISocketEventListener.GetListener(BaseSocket newSock)
+        {
+            throw new Exception("The method or operation is not implemented.");
+        }
+
+        bool ISocketEventListener.OnAccept(BaseSocket newsocket)
+        {
+            throw new Exception("The method or operation is not implemented.");
+        }
+
+        private static void WriteString(Stream s, string str)
+        {
+            byte[] buf = ENC.GetBytes(str);
+            s.Write(buf, 0, buf.Length);
+        }
+
+        private void Send(PendingRequest req)
+        {
+            m_current = req;
+
+            // Try to get it big enough that we don't have to allocate, without going overboard.
+            MemoryStream ms = new MemoryStream(req.Length + 256);
+            WriteString(ms, req.Method);
+            WriteString(ms, " ");
+            if (m_proxyURI == null)
+                WriteString(ms, req.URI.PathAndQuery);
+            else
+                WriteString(ms, req.URI.ToString());
+            ms.Write(SP_HTTP11_CRLF, 0, SP_HTTP11_CRLF.Length);
+
+            WebHeaderCollection coll = new WebHeaderCollection();
+            coll.Add(HttpRequestHeader.Host, req.URI.Host);
+            if (req.ContentType != null)
+                coll.Add(HttpRequestHeader.ContentType, req.ContentType);
+            if (m_proxyCredentials != null)
+            {
+                byte[] creds = Encoding.ASCII.GetBytes(m_proxyCredentials.UserName + ":" + m_proxyCredentials.Password);
+                coll.Add("Proxy-Authorization", "Basic " + Convert.ToBase64String(creds));
+            }
+            coll.Add("X-JN-Name", m_name);
+            coll.Add(HttpRequestHeader.Date, string.Format("{0:r}", DateTime.Now));
+            coll.Add(HttpRequestHeader.ContentLength, req.Length.ToString());
+
+            byte[] headers = coll.ToByteArray();
+            ms.Write(headers, 0, headers.Length);
+
+            ms.Write(req.Body, req.Offset, req.Length);
+
+            byte[] buf = ms.ToArray();
+
+            m_sock.Write(buf);
+            m_sock.RequestRead();
+        }
+
+        void ISocketEventListener.OnConnect(BaseSocket sock)
+        {
+            m_listener.OnConnect(null);
+            lock (m_lock)
+            {
+                Monitor.Pulse(m_lock);
+            }
+        }
+
+        void ISocketEventListener.OnClose(BaseSocket sock)
+        {
+            m_sock = null;
+            lock (m_lock)
+            {
+                Monitor.Pulse(m_lock);
+            }
+        }
+
+        void ISocketEventListener.OnError(BaseSocket sock, Exception ex)
+        {
+            if (Interlocked.Increment(ref m_errorCount) > m_maxErrors)
+            {
+                m_keepRunning = false;
+                m_listener.OnError(null, ex);
+            }
+
+            lock (m_lock)
+            {
+                Monitor.Pulse(m_lock);
+            }
+        }
+
+        private bool ParseAt(byte[] buf, ref int i, int last, byte[] check, int checkoffset)
+        {
+            int start = i;
+            for (int j = checkoffset; j < check.Length; j++)
+            {
+                if (i >= last)
+                {
+                    i = start;
+                    return false;
+                }
+
+                if (buf[i++] != check[j])
+                {
+                    i = start;
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        private string ParseTo(byte[] buf, ref int i, int last, byte[] check)
+        {
+            int start = i;
+
+            // IndexOf should be in asm.
+            int j;
+            while (i < last)
+            {
+                j = Array.IndexOf(buf, check[0], i);
+                if (j == -1)
+                    return null;
+                i = j;
+                if (check.Length > 1)
+                {
+                    i++;
+                    if (ParseAt(buf, ref i, last, check, 1))
+                        return ENC.GetString(buf, start, j - start);
+                }
+                else
+                    return ENC.GetString(buf, start, j - start);
+            }
+            return null;
+        }
+
+        private enum ParseState
+        {
+            START,
+            RESPONSE,
+            RESPONSE_TEXT,
+            HEADER_NAME,
+            HEADER_VALUE,
+            BODY_START,
+            BODY_CONTINUE
+        }
+
+        private void Done()
+        {
+            m_state = ParseState.START;
+            m_current = null;
+            Debug.WriteLine("HTTP Socket " + m_name + " done");
+        }
+
+        bool ISocketEventListener.OnRead(BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            Debug.WriteLine("IN HTTP(" + m_name + "): " + ENC.GetString(buf, offset, length));
+            int i = offset;
+            string header = null;
+            int last = offset + length;
+
+            while (i < last)
+            {
+                // HTTP/1.1 200 OK
+                // Header: value
+                // Header: value
+                //
+                // Content
+                switch (m_state)
+                {
+                    case ParseState.START:
+                        if (!ParseAt(buf, ref i, last, HTTP11_SP, 0))
+                            goto ERROR;
+                        m_state = ParseState.RESPONSE;
+                        break;
+                    case ParseState.RESPONSE:
+                        string code = ParseTo(buf, ref i, last, SPACE);
+                        if (code == null)
+                            goto ERROR;
+
+                        if (code != "200")
+                        {
+                            Debug.WriteLine("Non-OK response from server (" + code + ").  STOP!");
+                            goto ERROR;
+                        }
+
+                        try
+                        {
+                            // I know this can never fail.  it's here for when we
+                            // implement redirects and the like.
+                            m_current.Code = int.Parse(code);
+                        }
+                        catch (Exception)
+                        {
+                            Debug.WriteLine("invalid response code");
+                            goto ERROR;
+                        }
+
+                        m_state = ParseState.RESPONSE_TEXT;
+                        break;
+                    case ParseState.RESPONSE_TEXT:
+                        m_current.ResponseText = ParseTo(buf, ref i, last, CRLF);
+                        if (m_current.ResponseText == null)
+                            goto ERROR;
+                        m_state = ParseState.HEADER_NAME;
+                        break;
+                    case ParseState.HEADER_NAME:
+                        if (ParseAt(buf, ref i, last, CRLF, 0))
+                        {
+                            m_state = ParseState.BODY_START;
+                            break;
+                        }
+                        header = ParseTo(buf, ref i, last, COL_SP);
+                        if (header == null)
+                            goto ERROR;
+                        m_state = ParseState.HEADER_VALUE;
+                        break;
+                    case ParseState.HEADER_VALUE:
+                        string val = ParseTo(buf, ref i, last, CRLF);
+                        if (val == null)
+                            goto ERROR;
+                        m_current.Headers.Add(header, val);
+                        m_state = ParseState.HEADER_NAME;
+                        break;
+                    case ParseState.BODY_START:
+                        // if we have the whole response, which is typical in XEP-124, then return it all at
+                        // once, without creating a MemoryStream.
+                        int len = m_current.ContentLength;
+                        if (len == -1)
+                            goto ERROR;
+                        if (i + len <= last)
+                        {
+                            Done();
+                            if (!m_listener.OnRead(this, buf, i, len) || !m_keepRunning)
+                            {
+                                Close();
+                                return false;
+                            }
+                            return false;
+                        }
+
+                        // We got a partial response.  We're going to have to wait until OnRead is called
+                        // again before we can pass a full response upstream.  Hold on to the pieces in a
+                        // MemoryStream.
+                        m_current.Response = new MemoryStream(len);
+                        m_current.Response.Write(buf, i, last - i);
+                        m_state = ParseState.BODY_CONTINUE;
+                        return true;
+                    case ParseState.BODY_CONTINUE:
+                        m_current.Response.Write(buf, i, last - i);
+                        if (m_current.Response.Length == m_current.Response.Capacity)
+                        {
+                            PendingRequest req = m_current;
+                            Done();
+
+                            byte[] resp = req.Response.ToArray();
+                            if (!m_listener.OnRead(this, resp, 0, resp.Length) || !m_keepRunning)
+                            {
+                                Close();
+                                return false;
+                            }
+
+                            return false;
+                        }
+                        return true;
+                    default:
+                        break;
+                }
+            }
+            return true;
+
+        ERROR:
+            m_listener.OnError(null, new ProtocolViolationException("Error parsing HTTP response"));
+            Close();
+            return false;
+        }
+
+        void ISocketEventListener.OnWrite(BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            m_listener.OnWrite(null, buf, offset, length);
+        }
+
+        bool ISocketEventListener.OnInvalidCertificate(BaseSocket sock, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
+        {
+            // TODO: pass up the chain
+            return m_listener.OnInvalidCertificate(null, certificate, chain, sslPolicyErrors);
+        }
+
+        #endregion
+
+        /// <summary>
+        /// Not implemented.
+        /// </summary>
+        /// <param name="addr"></param>
+        /// <param name="backlog"></param>
+        public override void Accept(Address addr, int backlog)
+        {
+            throw new Exception("The method or operation is not implemented.");
+        }
+
+        /// <summary>
+        /// Not implemented.
+        /// </summary>
+        public override void RequestAccept()
+        {
+            throw new Exception("The method or operation is not implemented.");
+        }
+
+        /// <summary>
+        /// Not implemented.
+        /// </summary>
+        /// <param name="addr"></param>
+        public override void Connect(Address addr)
+        {
+            throw new Exception("The method or operation is not implemented.");
+        }
+
+        /// <summary>
+        /// Are we currently connected? 
+        /// </summary>
+        public override bool Connected
+        {
+            get { return (m_sock != null) && (m_sock.Connected); }
+        }
+
+#if !NO_SSL
+        /// <summary>
+        /// Not implemented.
+        /// </summary>
+        public override void StartTLS()
+        {
+            throw new Exception("The method or operation is not implemented.");
+        }
+#endif
+
+        /// <summary>
+        /// Not implemented.
+        /// </summary>
+        public override void StartCompression()
+        {
+            throw new Exception("The method or operation is not implemented.");
+        }
+
+        /// <summary>
+        /// Not implemented.
+        /// </summary>
+        public override void RequestRead()
+        {
+            throw new Exception("The method or operation is not implemented.");
+        }
+
+        /// <summary>
+        /// Not implemented.
+        /// </summary>
+        /// <param name="buf"></param>
+        /// <param name="offset"></param>
+        /// <param name="len"></param>
+        public override void Write(byte[] buf, int offset, int len)
+        {
+            throw new Exception("The method or operation is not implemented.");
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/net/IHttpSocket.cs b/lib/jabber-net/bedrock/net/IHttpSocket.cs
new file mode 100644
index 0000000..9f4f4bf
--- /dev/null
+++ b/lib/jabber-net/bedrock/net/IHttpSocket.cs
@@ -0,0 +1,19 @@
+namespace bedrock.net
+{
+	interface IHttpSocket
+	{
+	    string URL { get; set; }
+	}
+
+    /// <summary>
+    /// This socket has special support for writing XML elements.
+    /// </summary>
+    public interface IElementSocket
+    {
+        /// <summary>
+        /// Write an XML element to the socket.
+        /// </summary>
+        /// <param name="elem"></param>
+        void Write(System.Xml.XmlElement elem);
+    }
+}
diff --git a/lib/jabber-net/bedrock/net/ProxySocket.cs b/lib/jabber-net/bedrock/net/ProxySocket.cs
new file mode 100644
index 0000000..a6d10a2
--- /dev/null
+++ b/lib/jabber-net/bedrock/net/ProxySocket.cs
@@ -0,0 +1,318 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Diagnostics;
+using System.Text;
+using bedrock.util;
+
+namespace bedrock.net
+{
+    /// <summary>
+    /// Proxy object for sockets.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ProxySocket : BaseSocket, ISocketEventListener
+    {
+        private BaseSocket     m_sock = null;
+        private string         m_host = null;
+        private int            m_port = 0;
+        private string         m_username = null;
+        private string         m_password = null;
+        private Address        m_remote_addr = null;
+        private bool           m_ssl = false;
+
+        /// <summary>
+        /// Wrap an existing socket event listener with a proxy.  Make SURE to set Socket after this.
+        /// </summary>
+        /// <param name="chain">Event listener to pass events through to.</param>
+        public ProxySocket(ISocketEventListener chain) : base(chain)
+        {
+        }
+
+        /// <summary>
+        /// The address that the proxy should connect to.
+        /// </summary>
+        public Address RemoteAddress
+        {
+            get { return m_remote_addr; }
+            set { m_remote_addr = value; }
+        }
+
+        /// <summary>
+        /// The lower level socket
+        /// </summary>
+        public BaseSocket Socket
+        {
+            get { return m_sock; }
+            set { m_sock = value; }
+        }
+
+        /// <summary>
+        /// the host running the proxy
+        /// </summary>
+        public string Host
+        {
+            get { return m_host; }
+            set { m_host = value; }
+        }
+
+        /// <summary>
+        /// the port to talk to the proxy host on
+        /// </summary>
+        public int Port
+        {
+            get { return m_port; }
+            set { m_port = value; }
+        }
+
+        /// <summary>
+        /// Do SSL **after** connected through the proxy.
+        /// </summary>
+        public bool SSL
+        {
+            get { return m_ssl; }
+            set { m_ssl = value; }
+        }
+
+        /// <summary>
+        /// the auth username for the proxy
+        /// </summary>
+        public string Username
+        {
+            get { return m_username; }
+            set { m_username = value; }
+        }
+
+        /// <summary>
+        /// the auth password for the proxy
+        /// </summary>
+        public string Password
+        {
+            get { return m_password; }
+            set { m_password = value; }
+        }
+
+        /// <summary>
+        /// Are we currently connected?
+        /// </summary>
+        public override bool Connected
+        {
+            get { return false; }
+        }
+
+        /// <summary>
+        /// Prepare to start accepting inbound requests.  Call RequestAccept() to start the async process.
+        /// </summary>
+        /// <param name="addr">Address to listen on</param>
+        /// <param name="backlog">The Maximum length of the queue of pending connections</param>
+        public override void Accept(bedrock.net.Address addr, int backlog)
+        {
+            m_sock.Accept(addr, backlog);
+        }
+
+        /// <summary>
+        /// Close the socket.  This is NOT async.  .Net doesn't have async closes.
+        /// But, it can be *called* async, particularly from GotData.
+        /// Attempts to do a shutdown() first.
+        /// </summary>
+        public override void Close()
+        {
+            m_sock.Close();
+        }
+
+        /// <summary>
+        /// Saves the address passed in, and really connects to m_host:m_port.
+        /// </summary>
+        /// <param name="addr"></param>
+        public override void Connect(bedrock.net.Address addr)
+        {
+            m_remote_addr = addr; // save this till we are ready for it...
+            Debug.Assert(m_host != null);
+            Debug.Assert(m_port != 0);
+            // connect to the proxy.
+            Address proxy_addr = new Address(m_host, m_port);
+            m_sock.Connect(proxy_addr, m_hostid);
+            // we'll end up in OnConnected below.
+        }
+
+#if !NO_SSL
+        /// <summary>
+        /// Start TLS processing on an open socket.
+        /// </summary>
+        public override void StartTLS()
+        {
+            m_sock.StartTLS();
+        }
+#endif
+
+        /// <summary>
+        /// Start compression processing on an open socket.
+        /// </summary>
+        public override void StartCompression()
+        {
+            m_sock.StartCompression();
+        }
+
+        /// <summary>
+        /// Start the flow of async accepts.  Flow will continue while
+        /// Listener.OnAccept() returns true.  Otherwise, call RequestAccept() again
+        /// to continue.
+        /// </summary>
+        public override void RequestAccept()
+        {
+            m_sock.RequestAccept();
+        }
+
+        /// <summary>
+        /// Start an async read from the socket.  Listener.OnRead() is eventually called
+        /// when data arrives.
+        /// </summary>
+        public override void RequestRead()
+        {
+            m_sock.RequestRead();
+        }
+
+        /// <summary>
+        /// Async write to the socket.  Listener.OnWrite will be called eventually
+        /// when the data has been written.  A trimmed copy is made of the data, internally.
+        /// </summary>
+        /// <param name="buf">Buffer to output</param>
+        /// <param name="offset">Offset into buffer</param>
+        /// <param name="len">Number of bytes to output</param>
+        public override void Write(byte[] buf, int offset, int len)
+        {
+            m_sock.Write(buf, offset, len);
+        }
+
+        #region Implementation of ISocketEventListener
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="newSock"></param>
+        public virtual void OnInit(BaseSocket newSock)
+        {
+            m_listener.OnInit(newSock);
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="newSock"></param>
+        /// <returns></returns>
+        public virtual ISocketEventListener GetListener(BaseSocket newSock)
+        {
+            return m_listener.GetListener(newSock);
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="newsocket"></param>
+        /// <returns></returns>
+        public virtual bool OnAccept(BaseSocket newsocket)
+        {
+            return m_listener.OnAccept(newsocket);
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="sock"></param>
+        public virtual void OnConnect(BaseSocket sock)
+        {
+            if (m_ssl)
+            {
+#if !NO_SSL
+                m_sock.StartTLS();
+#else
+                throw new NotImplementedException("SSL not compiled in");
+#endif
+            }
+            m_listener.OnConnect(sock);
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="sock"></param>
+        public virtual void OnClose(BaseSocket sock)
+        {
+            m_listener.OnClose(sock);
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="sock"></param>
+        /// <param name="ex"></param>
+        public virtual void OnError(BaseSocket sock, System.Exception ex)
+        {
+            m_listener.OnError(sock, ex);
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="sock"></param>
+        /// <param name="buf"></param>
+        /// <param name="offset"></param>
+        /// <param name="length"></param>
+        /// <returns></returns>
+        public virtual bool OnRead(BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            return m_listener.OnRead(sock, buf, offset, length);
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="sock"></param>
+        /// <param name="buf"></param>
+        /// <param name="offset"></param>
+        /// <param name="length"></param>
+        public virtual void OnWrite(BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            m_listener.OnWrite(sock, buf, offset, length);
+        }
+
+        /// <summary>
+        /// An invalid peer certificate was sent during SSL/TLS neogtiation.
+        /// </summary>
+        /// <param name="sock">The socket that experienced the error</param>
+        /// <param name="certificate">The bad certificate</param>
+        /// <param name="chain">The chain of CAs for the cert</param>
+        /// <param name="sslPolicyErrors">A bitfield for the erorrs in the certificate.</param>
+        /// <returns>True if the cert should be accepted anyway.</returns>
+        public virtual bool OnInvalidCertificate(BaseSocket sock,
+            System.Security.Cryptography.X509Certificates.X509Certificate certificate,
+            System.Security.Cryptography.X509Certificates.X509Chain chain,
+            System.Net.Security.SslPolicyErrors sslPolicyErrors)
+        {
+            return m_listener.OnInvalidCertificate(sock, certificate, chain, sslPolicyErrors);
+        }
+        #endregion
+
+        /// <summary>
+        /// String representation of the proxy socket.
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            return "Proxy connection to: " + RemoteAddress.ToString();
+        }
+
+    }
+}
diff --git a/lib/jabber-net/bedrock/net/ShttpProxy.cs b/lib/jabber-net/bedrock/net/ShttpProxy.cs
new file mode 100644
index 0000000..0c7e052
--- /dev/null
+++ b/lib/jabber-net/bedrock/net/ShttpProxy.cs
@@ -0,0 +1,173 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Diagnostics;
+using System.Text;
+using bedrock.util;
+
+namespace bedrock.net
+{
+    /// <summary>
+    /// Proxy object for sockets that want to do SHTTP proxying.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ShttpProxy : ProxySocket
+    {
+        private enum States { None, Connecting, WaitingForAuth, Running, Closed, Error }
+        private States m_state = States.None;
+        private System.IO.MemoryStream m_headerstream = new System.IO.MemoryStream();
+        private System.Collections.ArrayList m_headers = new System.Collections.ArrayList();
+
+        /// <summary>
+        /// Wrap an existing socket event listener with a ShttpProxy proxy.  Make SURE to set Socket after this.
+        /// </summary>
+        /// <param name="chain">Event listener to pass events through to.</param>
+        public ShttpProxy(ISocketEventListener chain) : base(chain)
+        {
+        }
+
+        /// <summary>
+        /// Remember that we're in the connecting state, let base connect to proxy, resumes in OnConnect.
+        /// </summary>
+        /// <param name="addr"></param>
+        public override void Connect(bedrock.net.Address addr)
+        {
+            m_state = States.Connecting;
+            base.Connect(addr);
+        }
+
+        #region Implementation of ISocketEventListener
+
+        /// <summary>
+        /// overridden OnConnect to start off SHTTP protocol.
+        /// </summary>
+        /// <param name="sock"></param>
+        public override void OnConnect(bedrock.net.BaseSocket sock)
+        {
+            if (m_state == States.Connecting)
+            { // CONNECT users.instapix.com:5222 HTTP/1.0
+                m_state = States.WaitingForAuth;
+                string cmd = string.Format(@"CONNECT {0}:{1} HTTP/1.1
+Host: {0}
+", RemoteAddress.Hostname, RemoteAddress.Port);
+
+                // if authinfo is set, send it.
+                if (Username != null && Username.Length > 0 && Password != null && Password.Length > 0)
+                {
+                    string auth = Convert.ToBase64String(Encoding.ASCII.GetBytes(Username + ":" + Password));
+                    cmd += "Proxy-Authorization: Basic " + auth + "\r\n";
+                }
+                cmd += "\r\n";
+                Debug.WriteLine("PSEND:" + cmd);
+                Write(Encoding.ASCII.GetBytes(cmd));
+                RequestRead();
+            }
+        }
+
+        /// <summary>
+        /// Overridden OnRead to handle 4 Socks5 states...
+        /// </summary>
+        /// <param name="sock"></param>
+        /// <param name="buf"></param>
+        /// <param name="offset"></param>
+        /// <param name="length"></param>
+        /// <returns></returns>
+        public override bool OnRead(bedrock.net.BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            switch (m_state)
+            {
+            case States.WaitingForAuth:
+                m_headerstream.Write(buf, offset, length);
+                int state = 0;
+                int line = 0;
+                foreach (byte b in buf)
+                {
+                    // Look for \r\n\r\n for end of response header
+                    switch (state)
+                    {
+                    case 0:
+                        if (b == '\r')
+                            state++;
+                        break;
+                    case 1:
+                        if (b == '\n')
+                        {
+                            byte[] hs = m_headerstream.ToArray();
+                            string s = System.Text.Encoding.UTF8.GetString(hs);
+                            Debug.Write("PRECV: " + s);
+                            m_headers.Add(s);
+                            m_headerstream.SetLength(0);
+                            state++;
+                            line++;
+                        }
+                        else
+                            state = 0;
+                        break;
+                    case 2:
+                        if (b == '\r')
+                            state++;
+                        else
+                            state = 0;
+                        break;
+                    case 3:
+                        if (b == '\n')
+                        {
+                            Debug.WriteLine("End of proxy headers");
+                            string line0 = (string)m_headers[0];
+                            if (line0.IndexOf("200") == -1)
+                            {
+                                Debug.WriteLine("200 response not detected.  Closing.");
+                                m_state = States.Error;
+                                this.Close();
+                            }
+                            else
+                            {
+                                Debug.WriteLine("Proxy connected");
+                                m_listener.OnConnect(sock); // tell the real listener that we're connected.
+                                m_state = States.Running;
+                            }
+                            // they'll call RequestRead(), so we can return false here.
+                            return false;
+                        }
+                        else
+                            state = 0;
+                        break;
+                    }
+                }
+                return true;
+            case States.Error:
+                throw new InvalidOperationException("Cannot read after error");
+            default:
+                return base.OnRead(sock, buf, offset, length);
+            }
+        }
+
+        /// <summary>
+        /// Overridden OnWrite to ensure that the base only gets called when in running state.
+        /// </summary>
+        /// <param name="sock"></param>
+        /// <param name="buf"></param>
+        /// <param name="offset"></param>
+        /// <param name="length"></param>
+        public override void OnWrite(bedrock.net.BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            if (m_state == States.Running)
+            {
+                base.OnWrite(sock, buf, offset, length);
+            }
+        }
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/bedrock/net/SocketEventListener.cs b/lib/jabber-net/bedrock/net/SocketEventListener.cs
new file mode 100644
index 0000000..3f155f6
--- /dev/null
+++ b/lib/jabber-net/bedrock/net/SocketEventListener.cs
@@ -0,0 +1,203 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using bedrock.util;
+namespace bedrock.net
+{
+    /// <summary>
+    /// Interface class for Socket events. Any object which
+    /// implements these interfaces is eligible to recieve Socket
+    /// events.  This is an interface instead of events in order
+    /// to preserve symmetry with libbedrock.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public interface ISocketEventListener
+    {
+        /// <summary>
+        /// An accept socket is about to be bound, or a connect socket is about to connect,
+        /// or an incoming socket just came in.  Use this as an opportunity to
+        /// </summary>
+        /// <param name="newSock">The new socket that is about to be connected.</param>
+        void OnInit(BaseSocket newSock);
+
+        /// <summary>
+        /// We accepted a socket, and need to get a listener.
+        /// If the return value is null, then the socket will be closed,
+        /// and RequestAccept will ALWAYS be called.
+        /// </summary>
+        /// <param name="newSock">The new socket.</param>
+        /// <returns>The listener for the *new* socket, as compared to
+        /// the listener for the *listen* socket</returns>
+        ISocketEventListener GetListener(BaseSocket newSock);
+
+        /// <summary>
+        /// A new incoming connection was accepted.
+        /// </summary>
+        /// <param name="newsocket">Socket for new connection.</param>
+        /// <returns>true if RequestAccept() should be called automatically again</returns>
+        bool OnAccept(BaseSocket newsocket);
+        /// <summary>
+        /// Outbound connection was connected.
+        /// </summary>
+        /// <param name="sock">Connected socket.</param>
+        void OnConnect(BaseSocket sock);
+        /// <summary>
+        /// Connection was closed.
+        /// </summary>
+        /// <param name="sock">Closed socket.  Already closed!</param>
+        void OnClose(BaseSocket sock);
+        /// <summary>
+        /// An error happened in processing.  The socket is no longer open.
+        /// </summary>
+        /// <param name="sock">Socket in error</param>
+        /// <param name="ex">Exception that caused the error</param>
+        void OnError(BaseSocket sock, Exception ex);
+        /// <summary>
+        /// Bytes were read from the socket.
+        /// </summary>
+        /// <param name="sock">The socket that was read from.</param>
+        /// <param name="buf">The bytes that were read.</param>
+        /// <param name="offset">Offset into the buffer to start at</param>
+        /// <param name="length">Number of bytes to use out of the buffer</param>
+        /// <returns>true if RequestRead() should be called automatically again</returns>
+        bool OnRead (BaseSocket sock, byte[] buf, int offset, int length);
+        /// <summary>
+        /// Bytes were written to the socket.
+        /// </summary>
+        /// <param name="sock">The socket that was written to.</param>
+        /// <param name="buf">The bytes that were written.</param>
+        /// <param name="offset">Offset into the buffer to start at</param>
+        /// <param name="length">Number of bytes to use out of the buffer</param>
+        void OnWrite(BaseSocket sock, byte[] buf, int offset, int length);
+
+        /// <summary>
+        /// An invalid peer certificate was sent during SSL/TLS neogtiation.
+        /// </summary>
+        /// <param name="sock">The socket that experienced the error</param>
+        /// <param name="certificate">The bad certificate</param>
+        /// <param name="chain">The chain of CAs for the cert</param>
+        /// <param name="sslPolicyErrors">A bitfield for the erorrs in the certificate.</param>
+        /// <returns>True if the cert should be accepted anyway.</returns>
+        bool OnInvalidCertificate(BaseSocket sock,
+            System.Security.Cryptography.X509Certificates.X509Certificate certificate,
+            System.Security.Cryptography.X509Certificates.X509Chain chain,
+            System.Net.Security.SslPolicyErrors sslPolicyErrors);
+    }
+    /// <summary>
+    /// Default, empty implementation of ISocketEventListener
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class SocketEventListener : ISocketEventListener
+    {
+        #region Implementation of ISocketEventListener
+        /// <summary>
+        /// An accept socket is about to be bound, or a connect socket is about to connect,
+        /// or an incoming socket just came in.  Use this as an opportunity to
+        /// </summary>
+        /// <param name="newSock">The new socket that is about to be connected.</param>
+        public virtual void OnInit(BaseSocket newSock)
+        {
+        }
+
+        /// <summary>
+        /// We accepted a socket, and need to get a listener.
+        /// If the return value is null, then the socket will be closed,
+        /// and RequestAccept will ALWAYS be called.
+        /// </summary>
+        /// <param name="newSock">The new socket.</param>
+        /// <returns>The listener for the *new* socket, as compared to
+        /// the listener for the *listen* socket</returns>
+        public virtual ISocketEventListener GetListener(BaseSocket newSock)
+        {
+            return this;
+        }
+
+        /// <summary>
+        /// A new incoming connection was accepted.
+        /// </summary>
+        /// <param name="newsocket">Socket for new connection.</param>
+        /// <returns>true if RequestAccept() should be called automatically again</returns>
+        public virtual bool OnAccept(BaseSocket newsocket)
+        {
+            return true;
+        }
+
+        /// <summary>
+        /// Outbound connection was connected.
+        /// </summary>
+        /// <param name="sock">Connected socket.</param>
+        public virtual void OnConnect(BaseSocket sock)
+        {
+        }
+
+        /// <summary>
+        /// Connection was closed.
+        /// </summary>
+        /// <param name="sock">Closed socket.  Already closed!</param>
+        public virtual void OnClose(BaseSocket sock)
+        {
+        }
+
+        /// <summary>
+        /// An error happened in processing.  The socket is no longer open.
+        /// </summary>
+        /// <param name="sock">Socket in error</param>
+        /// <param name="ec">Exception that caused the error</param>
+        public virtual void OnError(BaseSocket sock, System.Exception ec)
+        {
+        }
+
+        /// <summary>
+        /// Bytes were read from the socket.
+        /// </summary>
+        /// <param name="sock">The socket that was read from.</param>
+        /// <param name="buf">The bytes that were read.</param>
+        /// <returns>true if RequestRead() should be called automatically again</returns>
+        /// <param name="offset">Offset into the buffer to start at</param>
+        /// <param name="length">Number of bytes to use out of the buffer</param>
+        public virtual bool OnRead(BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            return true;
+        }
+
+        /// <summary>
+        /// Bytes were written to the socket.
+        /// </summary>
+        /// <param name="sock">The socket that was written to.</param>
+        /// <param name="buf">The bytes that were written.</param>
+        /// <param name="offset">Offset into the buffer to start at</param>
+        /// <param name="length">Number of bytes to use out of the buffer</param>
+        public virtual void OnWrite(BaseSocket sock, byte[] buf, int offset, int length)
+        {
+        }
+
+        /// <summary>
+        /// An invalid peer certificate was sent during SSL/TLS neogtiation.
+        /// </summary>
+        /// <param name="sock">The socket that experienced the error</param>
+        /// <param name="certificate">The bad certificate</param>
+        /// <param name="chain">The chain of CAs for the cert</param>
+        /// <param name="sslPolicyErrors">A bitfield for the erorrs in the certificate.</param>
+        /// <returns>True if the cert should be accepted anyway.</returns>
+        public virtual bool OnInvalidCertificate(BaseSocket sock,
+            System.Security.Cryptography.X509Certificates.X509Certificate certificate,
+            System.Security.Cryptography.X509Certificates.X509Chain chain,
+            System.Net.Security.SslPolicyErrors sslPolicyErrors)
+        {
+            return false;
+        }
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/bedrock/net/SocketWatcher.cs b/lib/jabber-net/bedrock/net/SocketWatcher.cs
new file mode 100644
index 0000000..f9326c9
--- /dev/null
+++ b/lib/jabber-net/bedrock/net/SocketWatcher.cs
@@ -0,0 +1,318 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using System.Diagnostics;
+using System.IO;
+
+using bedrock.util;
+using bedrock.collections;
+
+using System.Security.Cryptography.X509Certificates;
+
+namespace bedrock.net
+{
+    /// <summary>
+    /// A collection of sockets.  This makes a lot more sense in the poll() version (Unix/C) since
+    /// you need to have a place to collect all of the sockets and call poll().  Here, it's just
+    /// convenience functions.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class SocketWatcher : IDisposable
+    {
+        private enum State
+        {
+            Running,
+            Shutdown,
+            Stopped
+        };
+
+        private ISet        m_pending = new Set(SetImplementation.SkipList);
+        private ISet        m_socks   = new Set(SetImplementation.SkipList);
+        private object      m_lock = new object();
+        private int         m_maxSocks;
+        private bool        m_synch = false;
+
+        private X509Certificate2 m_cert = null;
+        private bool m_requireClientCert = false;
+
+        /// <summary>
+        /// Create a new instance, which will manage an unlimited number of sockets.
+        /// </summary>
+        public SocketWatcher()
+        {
+            m_maxSocks = -1;
+        }
+
+        /// <summary>
+        /// Create a new instance.
+        /// </summary>
+        /// <param name="maxsockets">Maximum number of sockets to watch.  In this version,
+        /// this is mostly for rate-limiting purposes.</param>
+        public SocketWatcher(int maxsockets)
+        {
+            m_maxSocks = maxsockets;
+        }
+
+        /// <summary>
+        /// Synchronous operation
+        /// </summary>
+        public bool Synchronous
+        {
+            get { return m_synch; }
+            set { m_synch = value; }
+        }
+
+        /// <summary>
+        /// The maximum number of sockets watched.  Throws
+        /// InvalidOperationException if the new value is fewer than the number
+        /// currently open.  -1 means no limit.
+        /// </summary>
+        public int MaxSockets
+        {
+            get { return m_maxSocks; }
+            set
+            {
+                lock(m_lock)
+                {
+                    if ((value >= 0) && (m_socks.Count >= value))
+                        throw new InvalidOperationException("Too many sockets: " + m_socks.Count);
+
+                    m_maxSocks = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// The certificate to be used for the local side of sockets, with SSL on.
+        /// </summary>
+        public X509Certificate2 LocalCertificate
+        {
+            get { return m_cert; }
+            set { m_cert = value; }
+        }
+
+        /// <summary>
+        /// Does the server require a client cert?  If not, the client cert won't be sent.
+        /// </summary>
+        public bool RequireClientCert
+        {
+            get { return m_requireClientCert; }
+            set { m_requireClientCert = value; }
+        }
+
+        /// <summary>
+        /// Set the certificate to be used for accept sockets.  To generate a test .pfx file using openssl,
+        /// add this to openssl.conf:
+        ///   <blockquote>
+        ///   [ serverex ]
+        ///   extendedKeyUsage=1.3.6.1.5.5.7.3.1
+        ///   </blockquote>
+        /// and run the following commands:
+        ///   <blockquote>
+        ///   openssl req -new -x509 -newkey rsa:1024 -keyout privkey.pem -out key.pem -extensions serverex
+        ///   openssl pkcs12 -export -in key.pem -inkey privkey.pem -name localhost -out localhost.pfx
+        ///   </blockquote>
+        /// If you leave the certificate null, and you are doing Accept, the SSL class will try to find a
+        /// default server cert on your box.  If you have IIS installed with a cert, this might just go...
+        /// </summary>
+        /// <param name="filename">A .pfx or .cer file</param>
+        /// <param name="password">The password, if this is a .pfx file, null if .cer file.</param>
+        public void SetCertificateFile(string filename,
+                                       string password)
+        {
+            m_cert = new X509Certificate2(filename, password);
+            // TODO: check cert for validity
+        }
+
+        /// <summary>
+        /// Set the certificate from a system store.  Try "MY" for the ones listed in IE.
+        /// </summary>
+        /// <param name="storeName"></param>
+        public void SetCertificateStore(StoreName storeName)
+        {
+            throw new NotImplementedException("Not implemented yet.  Need to figure out how to search for 'server' certs.");
+        }
+
+        /// <summary>
+        /// Create a socket that is listening for inbound connections.
+        /// </summary>
+        /// <param name="listener">Where to send notifications</param>
+        /// <param name="addr">Address to connect to</param>
+        /// <param name="backlog">The maximum length of the queue of pending connections</param>
+        /// <param name="SSL">Do SSL3/TLS1 on connect</param>
+        /// <returns>A socket that is ready for calling RequestAccept()</returns>
+        public AsyncSocket CreateListenSocket(ISocketEventListener listener,
+                                              Address              addr,
+                                              int                  backlog,
+                                              bool                 SSL)
+        {
+            //Debug.Assert(m_maxSocks > 1);
+            AsyncSocket result = new AsyncSocket(this, listener, SSL, m_synch);
+            if (SSL)
+            {
+                result.LocalCertificate = m_cert;
+                result.RequireClientCert = m_requireClientCert;
+            }
+            result.Accept(addr, backlog);
+            return result;
+        }
+
+        /// <summary>
+        /// Create a socket that is listening for inbound connections.
+        /// </summary>
+        /// <param name="listener">Where to send notifications</param>
+        /// <param name="addr">Address to connect to</param>
+        /// <param name="SSL">Do SSL3/TLS1 on connect</param>
+        /// <returns>A socket that is ready for calling RequestAccept()</returns>
+        public AsyncSocket CreateListenSocket(ISocketEventListener listener,
+                                              Address              addr,
+                                              bool                 SSL)
+        {
+            return CreateListenSocket(listener, addr, 5, SSL);
+        }
+
+        /// <summary>
+        /// Create a socket that is listening for inbound connections, with no SSL/TLS.
+        /// </summary>
+        /// <param name="listener">Where to send notifications</param>
+        /// <param name="addr">Address to connect to</param>
+        /// <returns>A socket that is ready for calling RequestAccept()</returns>
+        public AsyncSocket CreateListenSocket(ISocketEventListener listener,
+            Address              addr)
+        {
+            return CreateListenSocket(listener, addr, 5, false);
+        }
+
+        /// <summary>
+        /// Create a socket that is listening for inbound connections, with no SSL/TLS.
+        /// </summary>
+        /// <param name="listener">Where to send notifications</param>
+        /// <param name="addr">Address to connect to</param>
+        /// <param name="backlog">The maximum length of the queue of pending connections</param>
+        /// <returns>A socket that is ready for calling RequestAccept()</returns>
+        public AsyncSocket CreateListenSocket(ISocketEventListener listener,
+                                              Address              addr,
+                                              int                  backlog)
+        {
+            return CreateListenSocket(listener, addr, backlog, false);
+        }
+
+        /// <summary>
+        /// Create an outbound socket.
+        /// </summary>
+        /// <param name="listener">Where to send notifications</param>
+        /// <param name="addr">Address to connect to</param>
+        /// <returns>Socket that is in the process of connecting</returns>
+        public AsyncSocket CreateConnectSocket(ISocketEventListener listener,
+                                               Address              addr)
+        {
+            return CreateConnectSocket(listener, addr, false, null);
+        }
+
+        /// <summary>
+        /// Create an outbound socket.
+        /// </summary>
+        /// <param name="listener">Where to send notifications</param>
+        /// <param name="addr">Address to connect to</param>
+        /// <param name="SSL">Do SSL3/TLS1 on startup</param>
+        /// <param name="hostId">The logical name of the host to connect to, for SSL/TLS purposes.</param>
+        /// <returns>Socket that is in the process of connecting</returns>
+        public AsyncSocket CreateConnectSocket(ISocketEventListener listener,
+                                               Address              addr,
+                                               bool                 SSL,
+                                               string               hostId)
+        {
+            AsyncSocket result;
+
+            // Create the socket:
+            result = new AsyncSocket(this, listener, SSL, m_synch);
+            if (SSL)
+                result.LocalCertificate = m_cert;
+
+            // Start the connect process:
+            result.Connect(addr, hostId);
+            return result;
+        }
+
+        /// <summary>
+        /// Called by AsyncSocket when a new connection is received on a listen socket.
+        /// </summary>
+        /// <param name="s">New socket connection</param>
+        public void RegisterSocket(AsyncSocket s)
+        {
+            lock (m_lock)
+            {
+                if ((m_maxSocks >= 0) && (m_socks.Count >= m_maxSocks))
+                    throw new InvalidOperationException("Too many sockets: " + m_socks.Count);
+                m_socks.Add(s);
+            }
+        }
+
+        /// <summary>
+        /// Called by AsyncSocket when a socket is closed.
+        /// </summary>
+        /// <param name="s">Closed socket</param>
+        public void CleanupSocket(AsyncSocket s)
+        {
+            lock (m_lock)
+            {
+                m_socks.Remove(s);
+
+                if (m_pending.Contains(s))
+                {
+                    m_pending.Remove(s);
+                }
+                else
+                {
+                    foreach (AsyncSocket sock in m_pending)
+                    {
+                        sock.RequestAccept();
+                    }
+                    m_pending.Clear();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Called by AsyncSocket when this class is full, and the listening AsyncSocket
+        /// socket would like to be restarted when there are slots free.
+        /// </summary>
+        /// <param name="s">Listening socket</param>
+        public void PendingAccept(AsyncSocket s)
+        {
+            lock (m_lock)
+            {
+                m_pending.Add(s);
+            }
+        }
+
+        /// <summary>
+        /// Or close.  Potato, tomato.  This is useful if you want to use using().
+        /// </summary>
+        public void Dispose()
+        {
+            lock (m_lock)
+            {
+                m_pending.Clear();
+                foreach (AsyncSocket s in m_socks)
+                {
+                    s.Close();
+                }
+                m_socks.Clear();
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/net/Socks4Proxy.cs b/lib/jabber-net/bedrock/net/Socks4Proxy.cs
new file mode 100644
index 0000000..471c676
--- /dev/null
+++ b/lib/jabber-net/bedrock/net/Socks4Proxy.cs
@@ -0,0 +1,176 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Diagnostics;
+using System.Text;
+using System.Net;
+using bedrock.util;
+
+namespace bedrock.net
+{
+    /// <summary>
+    /// Proxy object for sockets that want to do SOCKS4 proxying.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Socks4Proxy : ProxySocket
+    {
+        private enum States { None, Connecting, RequestingProxy, Running, Closed }
+        private States m_state = States.None;
+
+        /// <summary>
+        /// Wrap an existing socket event listener with a Socks5 proxy.  Make SURE to set Socket after this.
+        /// </summary>
+        /// <param name="chain">Event listener to pass events through to.</param>
+        public Socks4Proxy(ISocketEventListener chain) : base(chain)
+        {
+        }
+
+        /// <summary>
+        /// Saves the address passed in, and really connects to ProxyHost:ProxyPort to begin SOCKS5 handshake.
+        /// </summary>
+        /// <param name="addr"></param>
+        public override void Connect(bedrock.net.Address addr)
+        {
+            m_state = States.Connecting;
+            base.Connect(addr);
+        }
+
+        #region Socks4 private methods.
+
+        /*
+                    +----+----+----+----+----+----+----+----+
+                    | VN | CD | DSTPORT |      DSTIP        |
+                    +----+----+----+----+----+----+----+----+
+     # of bytes:       1    1      2              4
+
+    VN is the version of the reply code and should be 0. CD is the result
+    code with one of the following values:
+
+        90: request granted
+        91: request rejected or failed
+        92: request rejected becasue SOCKS server cannot connect to
+            identd on the client
+        93: request rejected because the client program and identd
+            report different user-ids
+
+     */
+        private bool HandleRequestResponse(int ver, int reply)
+        {
+            if (ver != 0)
+            {
+                Debug.WriteLine("bogus version in reply from proxy: " + ver);
+                return false;
+            }
+            if (reply != 90)
+            {
+                Debug.WriteLine("request failed on proxy: " + reply);
+                return false;
+            }
+            Debug.WriteLine("proxy complete");
+            m_state = States.Running;
+            return true;
+        }
+
+        #endregion
+
+        #region Implementation of ISocketEventListener
+
+        /// <summary>
+        /// overridden OnConnect to start off Socks5 protocol.
+        /// </summary>
+        /// <param name="sock"></param>
+        public override void OnConnect(bedrock.net.BaseSocket sock)
+        {
+            if (m_state == States.Connecting)
+            {
+                IPHostEntry server = Dns.GetHostEntry(RemoteAddress.Hostname);
+                IPAddress ip_addr = server.AddressList[0];
+
+                byte[] addr = ip_addr.GetAddressBytes();
+
+                int port = RemoteAddress.Port;
+                byte [] buffer = new Byte[14];
+                buffer[0] = 4;  // protocol version.
+                buffer[1] = 1;  // connect.
+                buffer[2] = (byte)(port >> 8);
+                buffer[3] = (byte)port;
+                // TODO: test byte order!
+                buffer[4] = addr[3];
+                buffer[5] = addr[2];
+                buffer[6] = addr[1];
+                buffer[7] = addr[0];
+                buffer[8] = (byte)'i';
+                buffer[9] = (byte)'d';
+                buffer[10] = (byte)'e';
+                buffer[11] = (byte)'n';
+                buffer[12] = (byte)'t';
+                buffer[13] = 0;
+
+                /*
+                +----+----+----+----+----+----+----+----+----+----+....+----+
+                | VN | CD | DSTPORT |      DSTIP        | USERID       |NULL|
+                +----+----+----+----+----+----+----+----+----+----+....+----+
+    # of bytes:    1    1      2              4           variable       1
+                */
+
+
+                Write(buffer);
+                RequestRead();
+                m_state = States.RequestingProxy;
+            }
+        }
+
+        /// <summary>
+        /// Overridden OnRead to handle 4 Socks5 states...
+        /// </summary>
+        /// <param name="sock"></param>
+        /// <param name="buf"></param>
+        /// <param name="offset"></param>
+        /// <param name="length"></param>
+        /// <returns></returns>
+        public override bool OnRead(bedrock.net.BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            switch (m_state)
+            {
+                case States.RequestingProxy:
+                    bool ret = HandleRequestResponse(buf[offset], buf[offset + 1]);
+                    if (ret)
+                    {
+                        m_listener.OnConnect(sock); // tell the real listener that we're connected.
+                        // they'll call RequestRead(), so we can return false here.
+                    }
+                    return false;
+                default:
+                    return base.OnRead(sock, buf, offset, length);
+            }
+        }
+
+        /// <summary>
+        /// Overridden OnWrite to ensure that the base only gets called when in running state.
+        /// </summary>
+        /// <param name="sock"></param>
+        /// <param name="buf"></param>
+        /// <param name="offset"></param>
+        /// <param name="length"></param>
+        public override void OnWrite(bedrock.net.BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            if (m_state == States.Running)
+            {
+                base.OnWrite(sock, buf, offset, length);
+            }
+        }
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/bedrock/net/Socks5Proxy.cs b/lib/jabber-net/bedrock/net/Socks5Proxy.cs
new file mode 100644
index 0000000..c085a2e
--- /dev/null
+++ b/lib/jabber-net/bedrock/net/Socks5Proxy.cs
@@ -0,0 +1,265 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Diagnostics;
+using System.Text;
+using bedrock.util;
+
+namespace bedrock.net
+{
+    /// <summary>
+    /// Proxy object for sockets that want to do SOCKS proxying.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Socks5Proxy : ProxySocket
+    {
+        private enum States { None, Connecting, GettingMethods, WaitingForAuth, RequestingProxy, Running, Closed }
+        private States m_state = States.None;
+
+        /// <summary>
+        /// Wrap an existing socket event listener with a Socks5 proxy.  Make SURE to set Socket after this.
+        /// </summary>
+        /// <param name="chain">Event listener to pass events through to.</param>
+        public Socks5Proxy(ISocketEventListener chain) : base(chain)
+        {
+        }
+
+        /// <summary>
+        /// Saves the address passed in, and really connects to ProxyHost:ProxyPort to begin SOCKS5 handshake.
+        /// </summary>
+        /// <param name="addr"></param>
+        public override void Connect(bedrock.net.Address addr)
+        {
+            m_state = States.Connecting;
+            base.Connect(addr);
+        }
+
+        #region Socks5 private methods.
+
+        /*
+         * The SOCKS request is formed as follows:
+         *
+         *      +----+-----+-------+------+----------+----------+
+         *      |VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
+         *      +----+-----+-------+------+----------+----------+
+         *      | 1  |  1  | X'00' |  1   | Variable |    2     |
+         *      +----+-----+-------+------+----------+----------+
+         *
+         *   Where:
+         *
+         *        o  VER    protocol version: X'05'
+         *        o  CMD
+         *           o  CONNECT X'01'
+         *           o  BIND X'02'
+         *           o  UDP ASSOCIATE X'03'
+         *        o  RSV    RESERVED
+         *        o  ATYP   address type of following address
+         *           o  IP V4 address: X'01'
+         *           o  DOMAINNAME: X'03'
+         *           o  IP V6 address: X'04'
+         *        o  DST.ADDR    desired destination address
+         *        o  DST.PORT    desired destination port in network octet order
+         */
+        private void RequestProxyConnection()
+        {
+            m_state = States.RequestingProxy;
+
+            byte[] host = Encoding.ASCII.GetBytes(RemoteAddress.Hostname);
+            int n = host.Length;
+            byte [] buffer = new Byte[7 + n];
+            buffer[0] = 5; // protocol version.
+            buffer[1] = 1; // connect
+            buffer[2] = 0; // reserved.
+            buffer[3] = 3; // DOMAINNAME
+            buffer[4] = (byte)n;
+            host.CopyTo(buffer, 5);
+            buffer[5+n] = (byte)(RemoteAddress.Port >> 8);
+            buffer[6+n] = (byte)RemoteAddress.Port;
+            Debug.WriteLine("sending request to proxy to " + RemoteAddress);
+            Write(buffer);
+        }
+
+        private bool HandleGetMethodsResponse(int ver, int method)
+        {
+            if (ver != 5)
+            {
+                Debug.WriteLine("bogus version  from proxy: " + ver);
+                return false;
+            }
+            if (method == 0xff)
+            {
+                Debug.WriteLine("no valid method returned from proxy");
+                return false;
+            }
+
+            Debug.WriteLine("proxy accepted our connection: " + method);
+            switch (method)
+            {
+                case 2:
+                    /*
+                     * +----+------+----------+------+----------+
+                     * |VER | ULEN |  UNAME   | PLEN |  PASSWD  |
+                     * +----+------+----------+------+----------+
+                     * | 1  |  1   | 1 to 255 |  1   | 1 to 255 |
+                     * +----+------+----------+------+----------+
+                     */
+                    m_state = States.WaitingForAuth;
+                    byte [] buffer = new Byte[3 + Username.Length + Password.Length];
+                    buffer[0] = 1; // version of this subnegotiation.
+                    buffer[1] = (byte)Username.Length;
+                    Encoding.ASCII.GetBytes(Username, 0, Username.Length, buffer, 2);
+                    int pw_offset = 2 + Username.Length;
+                    buffer[pw_offset] = (byte)Password.Length;
+                    Encoding.ASCII.GetBytes(Password, 0, Password.Length, buffer, pw_offset + 1);
+                    Debug.WriteLine("sending plain auth to proxy");
+                    Write(buffer);
+                    return true;
+                case 0:
+                    RequestProxyConnection();
+                    return true;
+                default:
+                    Debug.WriteLine("bogus auth method: " + method);
+                    return false;
+            }
+        }
+
+        private bool HandleAuthResponse(int ver, int status)
+        {
+            if (ver != 1)
+            {
+                Debug.WriteLine("bogus subnegotiation version from proxy: " + ver);
+                return false;
+            }
+            if (status != 0)
+            {
+                Debug.WriteLine("username/password auth failed on proxy");
+                return false;
+            }
+
+            Debug.WriteLine("proxy accepted our auth handshake");
+            RequestProxyConnection();
+            return true;
+        }
+
+        /*
+         * +----+-----+-------+------+----------+----------+
+         * |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
+         * +----+-----+-------+------+----------+----------+
+         * | 1  |  1  | X'00' |  1   | Variable |    2     |
+         * +----+-----+-------+------+----------+----------+
+         *
+         *     Where:
+         *
+         *           o  VER    protocol version: X'05'
+         *           o  REP    Reply field:
+         *              o  X'00' succeeded
+         *              o  X'01' general SOCKS server failure
+         *              o  X'02' connection not allowed by ruleset
+         *              o  X'03' Network unreachable
+         *              o  X'04' Host unreachable
+         *              o  X'05' Connection refused
+         *              o  X'06' TTL expired
+         *              o  X'07' Command not supported
+         *              o  X'08' Address type not supported
+         *              o  X'09' to X'FF' unassigned
+         */
+        private bool HandleRequestResponse(int ver, int reply)
+        {
+            if (ver != 5)
+            {
+                Debug.WriteLine("bogus version in reply from proxy: " + ver);
+                return false;
+            }
+            if (reply != 0)
+            {
+                Debug.WriteLine("request failed on proxy: " + reply);
+                return false;
+            }
+
+            Debug.WriteLine("proxy complete");
+            m_state = States.Running;
+            return true;
+        }
+
+        #endregion
+
+        #region Implementation of ISocketEventListener
+
+        /// <summary>
+        /// overridden OnConnect to start off Socks5 protocol.
+        /// </summary>
+        /// <param name="sock"></param>
+        public override void OnConnect(bedrock.net.BaseSocket sock)
+        {
+            if (m_state == States.Connecting)
+            {
+                byte [] buffer = new Byte[4];
+                buffer[0] = 5; // protocol version.
+                buffer[1] = 2; // number of methods.
+                buffer[2] = 0; // no auth.
+                buffer[3] = 2; // username password.
+                Debug.WriteLine("sending auth methods to proxy...");
+                Write(buffer);
+                RequestRead();
+                m_state = States.GettingMethods;
+            }
+        }
+
+        /// <summary>
+        /// Overridden OnRead to handle 4 Socks5 states...
+        /// </summary>
+        /// <param name="sock"></param>
+        /// <param name="buf"></param>
+        /// <param name="offset"></param>
+        /// <param name="length"></param>
+        /// <returns></returns>
+        public override bool OnRead(bedrock.net.BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            switch (m_state)
+            {
+                case States.GettingMethods:
+                    return HandleGetMethodsResponse(buf[offset], buf[offset + 1]);
+                case States.WaitingForAuth:
+                    return HandleAuthResponse(buf[offset], buf[offset + 1]);
+                case States.RequestingProxy:
+                    bool ret = HandleRequestResponse(buf[offset], buf[offset + 1]);
+                    if (ret)
+                    {
+                        m_listener.OnConnect(sock); // tell the real listener that we're connected.
+                        // they'll call RequestRead(), so we can return false here.
+                    }
+                    return false;
+                default:
+                    return base.OnRead(sock, buf, offset, length);
+            }
+        }
+
+        /// <summary>
+        /// Overridden OnWrite to ensure that the base only gets called when in running state.
+        /// </summary>
+        /// <param name="sock"></param>
+        /// <param name="buf"></param>
+        /// <param name="offset"></param>
+        /// <param name="length"></param>
+        public override void OnWrite(bedrock.net.BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            if (m_state == States.Running)
+            {
+                base.OnWrite(sock, buf, offset, length);
+            }
+        }
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/bedrock/net/XEP124Socket.cs b/lib/jabber-net/bedrock/net/XEP124Socket.cs
new file mode 100644
index 0000000..4e5ee69
--- /dev/null
+++ b/lib/jabber-net/bedrock/net/XEP124Socket.cs
@@ -0,0 +1,673 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.Net;
+using System.Security.Cryptography;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using System.Threading;
+using System.Xml;
+using bedrock.util;
+
+using jabber.protocol.stream;
+using jabber.connection;
+using jabber.protocol;
+
+namespace bedrock.net
+{    
+    /// <summary>
+    /// XEP-0124 Error conditions
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class XEP124Exception : WebException
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="reason"></param>
+        public XEP124Exception(string reason)
+            : base(reason)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Make a XEP-124 (http://www.xmpp.org/extensions/xep-0124.html) polling "connection" look like a socket.
+    /// TODO: get rid of the PipeStream, if possible.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class XEP124Socket : BaseSocket, IHttpSocket, IElementSocket, ISocketEventListener
+    {
+        /// <summary>
+        /// Text encoding.  Always UTF-8 for XMPP.
+        /// </summary>
+        protected static readonly Encoding ENC = Encoding.UTF8;
+
+        private const string CONTENT_TYPE = "text/xml; charset=utf-8";
+        private const string METHOD = "POST";
+
+        private readonly int m_hold = 1;
+        private int m_wait = 60;
+        private int m_maxPoll = 30;
+        private int m_minPoll = 1;
+        private Uri m_uri = null;
+        private bool m_running = false;
+        private long m_rid = -1L;
+        private string m_sid = null;
+        private string m_authID = null;
+        private X509Certificate m_remote_cert = null;
+        private bool m_StartStream = false;
+        private string m_NS;
+        private string m_lang = System.Globalization.CultureInfo.CurrentCulture.IetfLanguageTag;
+        private XmlDocument m_doc = new XmlDocument();
+
+        private Uri m_proxyURI = null;
+        private NetworkCredential m_proxyCredentials = null;
+
+        private Thread m_thread = null;
+        private LinkedList<XmlElement> m_queue = new LinkedList<XmlElement>();
+
+        private HttpSocket m_sockA = null;
+        private HttpSocket m_sockB = null;
+        private HttpSocket m_lastSock = null;
+
+        /// <summary>
+        /// Create an instance
+        /// </summary>
+        /// <param name="listener"></param>
+        public XEP124Socket(ISocketEventListener listener) : base(listener)
+        {
+        }
+
+        /// <summary>
+        /// The xml:lang for all requests.  Defaults to the current culture's language tag.
+        /// </summary>
+        public string Lang
+        {
+            get { return m_lang; }
+            set { m_lang = value; }
+        }
+
+        ///<summary>
+        /// Informs the socket that we are dealing with the start tag.
+        ///</summary>
+        public bool StartStream
+        {
+            get { return m_StartStream; }
+            set { m_StartStream = value; }
+        }
+
+        ///<summary>
+        /// Gets or sets the NS used by the stream:stream tag.
+        ///</summary>
+        public string NS
+        {
+            get { return m_NS; }
+            set { m_NS = value; }
+        }
+
+        /// <summary>
+        /// Maximum time between polls, in seconds
+        /// </summary>
+        public int MaxPoll
+        {
+            get { return m_maxPoll; }
+            set { m_maxPoll = value; }
+        }
+
+        /// <summary>
+        /// Minimum time between polls, in seconds
+        /// </summary>
+        public int MinPoll
+        {
+            get { return m_minPoll; }
+            set { m_minPoll = value; }
+        }
+
+        /// <summary>
+        /// The URL to poll
+        /// </summary>
+        public string URL
+        {
+            get { return m_uri.ToString(); }
+            set { m_uri = new Uri(value); }
+        }
+
+        /// <summary>
+        /// The URI of the HTTP proxy.  Note: HTTPS connections through a proxy are not yet supported.
+        /// </summary>
+        public Uri ProxyURI
+        {
+            get { return m_proxyURI; }
+            set { m_proxyURI = value; }
+        }
+
+        /// <summary>
+        /// Username/password for the proxy.
+        /// </summary>
+        public NetworkCredential ProxyCredentials
+        {
+            get { return m_proxyCredentials; }
+            set { m_proxyCredentials = value; }
+        }
+
+        /// <summary>
+        /// Accept a socket.  Not implemented.
+        /// </summary>
+        /// <param name="addr"></param>
+        /// <param name="backlog"></param>
+        public override void Accept(Address addr, int backlog)
+        {
+            throw new NotImplementedException("HTTP binding server not implemented");
+        }
+
+        private void Enqueue(XmlElement elem)
+        {
+            lock (m_queue)
+            {
+                m_queue.AddLast(elem);
+                Monitor.Pulse(m_queue);
+            }
+        }
+
+        // Must hold lock first.
+        private HttpSocket GetSocket()
+        {
+            // Debug.Assert(!BothPending);
+
+            // Switch to the other socket than the last one, assuming the other socket isn't pending.
+            // If the other socket is pending, use the last one.
+            HttpSocket other = (m_lastSock == m_sockA) ? m_sockB : m_sockA;
+            if (!other.IsPending)
+                m_lastSock = other;
+
+            Debug.WriteLine("Socket: " + m_lastSock.Name);
+            return m_lastSock;
+        }
+
+        private bool BothPending
+        {
+            get { return (m_sockA != null) && (m_sockB != null) && 
+                          m_sockA.IsPending && m_sockB.IsPending; }
+        }
+
+        private bool NeitherPending
+        {
+            get { return !m_sockA.IsPending && !m_sockB.IsPending; }
+        }
+
+        private bool BothConnected
+        {
+            get
+            {
+                return (m_sockA != null) && (m_sockB != null) &&
+                        m_sockA.Connected && m_sockB.Connected;
+            }
+        }
+
+        private void ProcessThread()
+        {
+            Body body = null;
+            int children = 0;
+
+            while (m_running)
+            {
+                lock (m_queue)
+                {
+                    //if (NeitherPending)
+                    //    m_queue.AddFirst((XmlElement)null);
+
+                    Debug.WriteLine("A: " + m_sockA.IsPending);
+                    Debug.WriteLine("b: " + m_sockB.IsPending);
+                    while ((m_queue.First == null) || BothPending)
+                    {
+                        Monitor.Wait(m_queue);
+                        if (!m_running)
+                            return;
+                    }
+
+                    // We'll enq nulls to get a poll.
+                    // We'll enq a body in order to terminate.
+
+                    Debug.Assert(m_queue.First != null);
+                    body = m_queue.First.Value as Body;
+                    children = 0;
+                    if (body != null)
+                        // TODO: what to do with leftover stanzas!?
+                        m_queue.RemoveFirst();
+                    else
+                    {
+                        body = CreateOpenBodyTag();
+                        while (m_queue.First != null)
+                        {
+                            XmlElement elem = m_queue.First.Value;
+                            // ignore nulls.  we're going munge together all pending poll requests.
+                            if (elem != null)
+                            {
+                                // if we get to a body in the queue, stop inserting, and wait for the body
+                                // to come around again next time.
+                                if (elem is Body)
+                                    break;
+                                body.AddChild(elem);
+                                children++;
+                            }
+                            m_queue.RemoveFirst();
+                        }
+                    }
+                }
+
+                if (NeitherPending || (children > 0) || (body.Type == BodyType.terminate))
+                {
+                    if (body.RID == -1)
+                        body.RID = Interlocked.Increment(ref m_rid);
+
+                    byte[] buf = ENC.GetBytes(body.OuterXml);
+                    GetSocket().Execute(METHOD, m_uri, buf, 0, buf.Length, CONTENT_TYPE);
+                }
+
+                if (body.Type == BodyType.terminate)
+                {
+                    // shutting down.
+                    m_sockA.EnqueueClose();
+                    m_sockB.EnqueueClose();
+                    return;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Stop polling.
+        /// </summary>
+        public override void Close()
+        {
+            Body body = CreateOpenBodyTag();
+            body.Type = BodyType.terminate;
+
+            Enqueue(body);
+            
+            if (m_thread != null)
+                m_thread.Join();
+
+            lock (m_queue)
+            {
+                m_running = false;
+                m_thread = null;
+                m_sockA = m_sockB = m_lastSock = null;
+            }
+            m_listener.OnClose(this);
+        }
+
+        /// <summary>
+        /// Start polling
+        /// </summary>
+        /// <param name="addr">Ignored in this case.  Set URL.</param>
+        public override void Connect(Address addr)
+        {
+            Debug.Assert(m_uri != null);
+
+            m_rid = -1L;
+            m_lastSock = null;
+            m_running = false;
+
+            // Create new ones each time, in case the URL has changed or something.
+            m_sockA = new HttpSocket(this);
+            m_sockB = new HttpSocket(this);
+
+            m_sockA.Name = "A";
+            m_sockB.Name = "B";
+
+            m_sockA.ProxyURI = m_sockB.ProxyURI = m_proxyURI;
+            m_sockA.ProxyCredentials = m_sockB.ProxyCredentials = m_proxyCredentials;
+
+            m_sockA.Connect(m_uri);
+            m_sockB.Connect(m_uri);
+        }
+
+        /// <summary>
+        /// Not implemented
+        /// </summary>
+        public override void RequestAccept()
+        {
+            throw new NotImplementedException();
+        }
+
+        /// <summary>
+        /// Start reading.
+        /// </summary>
+        public override void RequestRead()
+        {
+            // shutdown race, likely.
+            if (!m_running)
+                //throw new InvalidOperationException("Call Connect() first");
+                return;
+            if (m_sockA.IsPending || m_sockB.IsPending)
+            {
+                Debug.WriteLine("Skipping request, already pending");
+                return;
+            }
+
+            Enqueue(null);
+        }
+
+        /// <summary>
+        /// Start TLS over this connection.  Not implemented.
+        /// </summary>
+        public override void StartTLS()
+        {
+            throw new NotImplementedException();
+        }
+
+        /// <summary>
+        /// Start compression over this connection.  Not implemented.
+        /// </summary>
+        public override void StartCompression()
+        {
+            throw new NotImplementedException();
+        }
+
+        private void FakeTimer(object state)
+        {
+            // HACK: stream restart is null for older versions of XEP-124.
+            if (!FakeReceivedStream())
+                return;
+
+            Features f = new Features(m_doc);
+            f.AddChild(new Bind(m_doc));
+            f.AddChild(new Session(m_doc));
+            byte[] p = ENC.GetBytes(f.OuterXml);
+            if (!m_listener.OnRead(this, p, 0, p.Length))
+            {
+                Close();
+                return;
+            }
+        }
+
+        /// <summary>
+        /// Send bytes to the jabber server
+        /// </summary>
+        /// <param name="buf"></param>
+        /// <param name="offset"></param>
+        /// <param name="len"></param>
+        public override void Write(byte[] buf, int offset, int len)
+        {
+            if (buf != null)
+                throw new NotImplementedException("Call Write(XmlElement)");
+
+            // HACK
+            byte[] p = ENC.GetBytes("Psuedo-stream body");
+            m_listener.OnWrite(this, p, 0, p.Length);
+            if (m_sid == null)
+            {
+                StartStream = true;
+                return;
+            }
+
+            // HACK: upper levels need this to come in after the
+            // return from write. Double-hack: hope this doesn't get
+            // gc's before the timer fires.... :)
+            
+            //Timer t =
+            new Timer(new TimerCallback(FakeTimer), null, 0, Timeout.Infinite);
+        }
+
+        /// <summary>
+        /// Write an XML element to the socket.
+        /// In this case, the element is queued, so that the write
+        /// thread can pick it up.
+        /// </summary>
+        /// <param name="elem"></param>
+        public void Write(XmlElement elem)
+        {
+            Enqueue(elem);
+        }
+
+        private Body CreateOpenBodyTag()
+        {
+            Body body = new Body(m_doc);
+
+            if (m_rid == -1L)
+            {
+                Random rnd = new Random();
+                long r = m_rid = (long)rnd.Next();
+                body.Content = CONTENT_TYPE;
+                
+                body.To = m_hostid;
+                body.Wait = m_wait;
+                body.Hold = m_hold;
+                body.Lang = m_lang;
+                body.RID = r;
+            }
+            else
+            {
+                body.SID = m_sid;
+            }
+            
+            return body;
+        }
+
+        /// <summary>
+        /// Descripton, including URL.
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            return "XEP-0124 socket: " + m_uri.ToString();
+        }
+
+        /// <summary>
+        /// Are we connected?
+        /// </summary>
+        public override bool Connected
+        {
+            get
+            { return m_running; }
+        }
+
+        /// <summary>
+        /// The certificate from the server.
+        /// </summary>
+        public X509Certificate RemoteCertificate
+        {
+            get { return m_remote_cert; }
+            set { m_remote_cert = value; }
+        }
+
+        #region ISocketEventListener Members
+
+        void ISocketEventListener.OnInit(BaseSocket newSock)
+        {
+            m_listener.OnInit(newSock);
+        }
+
+        ISocketEventListener ISocketEventListener.GetListener(BaseSocket newSock)
+        {
+            throw new Exception("The method or operation is not implemented.");
+        }
+
+        bool ISocketEventListener.OnAccept(BaseSocket newsocket)
+        {
+            throw new Exception("The method or operation is not implemented.");
+        }
+
+        void ISocketEventListener.OnConnect(BaseSocket sock)
+        {
+            lock (m_queue)
+            {
+                if (!m_running &&
+                    (m_sockA != null) && m_sockA.Connected &&
+                    (m_sockB != null) && m_sockB.Connected)
+                {
+                    m_running = true;
+                    m_lastSock = m_sockB;
+
+                    m_thread = new Thread(ProcessThread);
+                    m_thread.IsBackground = true;
+                    m_thread.Name = "XEP 124 processing thread";
+                    m_thread.Start();
+
+                    m_listener.OnConnect(this);
+                }
+            }            
+        }
+
+        void ISocketEventListener.OnClose(BaseSocket sock)
+        {
+            throw new Exception("The method or operation is not implemented.");
+        }
+
+        void ISocketEventListener.OnError(BaseSocket sock, Exception ex)
+        {
+            // shutdown race.
+            if (!m_running)
+                return;
+
+            m_listener.OnError(this, ex);
+        }
+
+        private bool FakeReceivedStream()
+        {
+            jabber.protocol.stream.Stream stream =
+                new jabber.protocol.stream.Stream(m_doc, NS);
+            stream.Version = "1.0";
+            stream.ID = m_authID;
+
+            byte[] sbuf = ENC.GetBytes(stream.StartTag());
+            if (!m_listener.OnRead(this, sbuf, 0, sbuf.Length))
+            {
+                Close();
+                return false;
+            }
+            return true;
+        }
+
+        bool ISocketEventListener.OnRead(BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            if (!m_running)
+            {
+                Debug.WriteLine("shutting down.  extra bytes received.");
+                return false;
+            }
+
+            Debug.WriteLine("OnRead: " + ((HttpSocket)sock).Name);
+
+            // Parse out the first start tag or empty element, which will be
+            // <body/>.
+            xpnet.UTF8Encoding e = new xpnet.UTF8Encoding();
+            xpnet.ContentToken ct = new xpnet.ContentToken();
+            xpnet.TOK tok = e.tokenizeContent(buf, offset, offset + length, ct);
+
+            if ((tok != xpnet.TOK.START_TAG_WITH_ATTS) &&
+                (tok != xpnet.TOK.EMPTY_ELEMENT_WITH_ATTS))
+            {
+                m_listener.OnError(this, new ProtocolViolationException("Invalid HTTP binding XML.  Token type: " + tok.ToString()));
+                return false;
+            }
+
+            string name = ENC.GetString(buf,
+                                        offset + e.MinBytesPerChar,
+                                        ct.NameEnd - offset - e.MinBytesPerChar);
+            Debug.Assert(name == "body");
+            Body b = new Body(m_doc);
+            string val;
+            int start;
+            int end;
+            for (int i = 0; i < ct.getAttributeSpecifiedCount(); i++)
+            {
+                start = ct.getAttributeNameStart(i);
+                end = ct.getAttributeNameEnd(i);
+                name = ENC.GetString(buf, start, end - start);
+
+                start = ct.getAttributeValueStart(i);
+                end = ct.getAttributeValueEnd(i);
+                val = ENC.GetString(buf, start, end - start);
+
+                if (!name.StartsWith("xmlns"))
+                    b.SetAttribute(name, val);
+            }
+
+            if (b.SID != null)
+                m_sid = b.SID;
+
+            if (m_sid == null)
+            {
+                m_listener.OnError(this, new ProtocolViolationException("Invalid HTTP binding.  No SID."));
+                return false;
+            }
+
+            if (b.Wait != -1)
+                m_wait = b.Wait;
+
+            if (StartStream)
+            {
+                StartStream = false;
+                m_authID = b.AuthID;
+                if (!FakeReceivedStream())
+                    return false;
+            }
+
+            lock (m_queue)
+            {
+                if (!m_running)
+                    return false;
+
+                if (b.Type == BodyType.terminate)
+                {
+                    m_running = false;
+                    Error err = new Error(m_doc);
+                    err.AppendChild(m_doc.CreateElement(b.GetAttribute("condition"), URI.STREAM_ERROR));
+                    byte[] sbuf = ENC.GetBytes(err.OuterXml);
+                    m_listener.OnRead(this, sbuf, 0, sbuf.Length);
+                    sbuf = ENC.GetBytes("</stream:stream>");
+                    m_listener.OnRead(this, sbuf, 0, sbuf.Length);
+                    Close();
+                    return false;
+                }
+            }
+
+
+            if (tok == xpnet.TOK.START_TAG_WITH_ATTS)
+            {
+                // len(</body>) = 7
+                start = ct.TokenEnd;
+                if (m_listener.OnRead(this, buf, start, offset + length - start - 7))
+                    RequestRead();
+            }
+            else
+                RequestRead();
+
+            lock (m_queue)
+            {
+                Monitor.Pulse(m_queue);
+            }
+            return true;
+        }
+
+        void ISocketEventListener.OnWrite(BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            m_listener.OnWrite(this, buf, offset, length);
+        }
+
+        bool ISocketEventListener.OnInvalidCertificate(BaseSocket sock, X509Certificate certificate, X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
+        {
+            return m_listener.OnInvalidCertificate(this, certificate, chain, sslPolicyErrors);
+        }
+
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/bedrock/net/XEP25Socket.cs b/lib/jabber-net/bedrock/net/XEP25Socket.cs
new file mode 100644
index 0000000..b419372
--- /dev/null
+++ b/lib/jabber-net/bedrock/net/XEP25Socket.cs
@@ -0,0 +1,518 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+
+using System;
+using System.Collections;
+using System.Diagnostics;
+using System.IO;
+using System.Net;
+using System.Security.Cryptography;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using System.Threading;
+using bedrock.util;
+
+namespace bedrock.net
+{
+    /// <summary>
+    /// XEP25 Error conditions
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class XEP25Exception : WebException
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="reason"></param>
+        public XEP25Exception(string reason) : base(reason)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Make a XEP-25 (http://www.xmpp.org/extensions/xep-0025.html) polling "connection" look like a socket.
+    /// TODO: get rid of the PipeStream, if possible.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class XEP25Socket : BaseSocket, IHttpSocket
+    {
+        private const string CONTENT_TYPE = "application/x-www-form-urlencoded";
+        private const string METHOD       = "POST";
+
+        private readonly RandomNumberGenerator s_rng = RNGCryptoServiceProvider.Create();
+
+        private readonly Queue      m_writeQ  = new Queue();
+        private readonly Object     m_lock    = new Object();
+        private Thread              m_thread  = null;
+        private int                 m_maxPoll = 30;
+        private int                 m_minPoll = 1;
+        private double              m_curPoll = 1.0;
+        private string              m_url     = null;
+        private string[]            m_keys    = null;
+        private int                 m_numKeys = 512;
+        private int                 m_curKey  = 511;
+        private bool                m_running = false;
+        private string              m_id      = null;
+        private WebProxy            m_proxy   = null;
+        private X509Certificate     m_cert = null;
+        private X509Certificate     m_remote_cert = null;
+
+        /// <summary>
+        /// Do trust all server sertificates?
+        /// </summary>
+        public static bool UntrustedRootOK = false;
+
+        /// <summary>
+        /// Create an instance
+        /// </summary>
+        /// <param name="listener"></param>
+        public XEP25Socket(ISocketEventListener listener)
+        {
+            Debug.Assert(listener != null);
+            m_listener = listener;
+        }
+
+        /// <summary>
+        /// Maximum time between polls, in seconds
+        /// </summary>
+        public int MaxPoll
+        {
+            get { return m_maxPoll; }
+            set { m_maxPoll = value; }
+        }
+
+        /// <summary>
+        /// Minimum time between polls, in seconds
+        /// </summary>
+        public int MinPoll
+        {
+            get { return m_minPoll; }
+            set { m_minPoll = value; }
+        }
+
+        /// <summary>
+        /// The URL to poll
+        /// </summary>
+        public string URL
+        {
+            get { return m_url; }
+            set { m_url = value; }
+        }
+
+
+        /// <summary>
+        /// The number of keys to generate at a time.  Higher numbers use more memory,
+        /// and more CPU to generate keys, less often.  Defaults to 512.
+        /// </summary>
+        public int NumKeys
+        {
+            get { return m_numKeys; }
+            set { m_numKeys = value; }
+        }
+
+        /// <summary>
+        /// Proxy information.  My guess is if you leave this null, the IE proxy
+        /// info may be used.  Not tested.
+        /// </summary>
+        public WebProxy Proxy
+        {
+            get { return m_proxy; }
+            set { m_proxy = value; }
+        }
+
+        /// <summary>
+        /// The local certificate of the socket.
+        /// </summary>
+        public X509Certificate LocalCertificate
+        {
+            get { return m_cert; }
+            set { m_cert = value; }
+        }
+
+        /// <summary>
+        /// The remote certificate.
+        /// </summary>
+        public X509Certificate RemoteCertificate
+        {
+            get { return m_remote_cert; }
+            set { m_remote_cert = value; }
+        }
+
+        /// <summary>
+        /// Accept a socket.  Not implemented.
+        /// </summary>
+        /// <param name="addr"></param>
+        /// <param name="backlog"></param>
+        public override void Accept(Address addr, int backlog)
+        {
+            throw new NotImplementedException("HTTP polling server not implemented yet");
+        }
+
+        /// <summary>
+        /// Stop polling.
+        /// </summary>
+        public override void Close()
+        {
+            lock (m_lock)
+            {
+                m_running = false;
+                Monitor.Pulse(m_lock);
+            }
+            m_listener.OnClose(this);
+        }
+
+
+
+        /// <summary>
+        /// Start polling
+        /// </summary>
+        /// <param name="addr"></param>
+        public override void Connect(Address addr)
+        {
+            Debug.Assert(m_url != null);
+            m_running = true;
+            m_curKey = -1;
+
+            if (m_thread == null)
+            {
+                m_thread = new Thread(PollThread);
+                m_thread.IsBackground = true;
+                m_thread.Start();
+            }
+
+            m_listener.OnConnect(this);
+        }
+
+        /// <summary>
+        /// Not implemented
+        /// </summary>
+        public override void RequestAccept()
+        {
+            throw new NotImplementedException();
+        }
+
+        /// <summary>
+        /// Start reading.
+        /// </summary>
+        public override void RequestRead()
+        {
+            if (!m_running)
+                throw new InvalidOperationException("Call Connect() first");
+        }
+
+#if !NO_SSL
+
+        /// <summary>
+        /// Start TLS over this connection.  Not implemented.
+        /// </summary>
+        public override void StartTLS()
+        {
+            throw new NotImplementedException();
+        }
+#endif
+
+        /// <summary>
+        /// Start TLS over this connection.  Not implemented.
+        /// </summary>
+        public override void StartCompression()
+        {
+            throw new NotImplementedException();
+        }
+
+        /// <summary>
+        /// Send bytes to the jabber server
+        /// </summary>
+        /// <param name="buf"></param>
+        /// <param name="offset"></param>
+        /// <param name="len"></param>
+        public override void Write(byte[] buf, int offset, int len)
+        {
+            if (!m_running)
+                throw new InvalidOperationException("Call Connect() first");
+
+            lock (m_lock)
+            {
+                //if (m_thread == null)
+                //{
+                //    // first write
+                //    m_thread = new Thread(new ThreadStart(PollThread));
+                //    m_thread.IsBackground = true;
+                //    m_thread.Start();
+                //}
+                m_writeQ.Enqueue(new WriteBuf(buf, offset, len));
+                Monitor.Pulse(m_lock);
+            }
+        }
+
+        private void GenKeys()
+        {
+            byte[] seed = new byte[32];
+            SHA1 sha = SHA1.Create();
+            Encoding ENC = Encoding.ASCII; // All US-ASCII.  No need for UTF8.
+            string prev;
+
+            // K(n, seed) = Base64Encode(SHA1(K(n - 1, seed))), for n > 0
+            // K(0, seed) = seed, which is client-determined
+
+            s_rng.GetBytes(seed);
+            prev = Convert.ToBase64String(seed);
+            m_keys = new string[m_numKeys];
+            for (int i=0; i<m_numKeys; i++)
+            {
+                m_keys[i] = Convert.ToBase64String(sha.ComputeHash(ENC.GetBytes(prev)));
+                prev = m_keys[i];
+            }
+            m_curKey = m_numKeys - 1;
+        }
+
+        private static bool ValidateRemoteCertificate(Object sender,
+                                               X509Certificate certificate,
+                                               X509Chain chain,
+                                               System.Net.Security.SslPolicyErrors sslPolicyErrors)
+        {
+            return UntrustedRootOK;
+        }
+
+        /// <summary>
+        /// Keep polling until
+        /// </summary>
+        private void PollThread()
+        {
+            m_curPoll = m_minPoll;
+            m_id = null;
+
+            MemoryStream ms = new MemoryStream();
+            CookieContainer cookies = new CookieContainer(5);
+            byte[] readbuf = new byte[1024];
+
+            Stream rs;
+            byte[] buf;
+            HttpWebResponse resp;
+            HttpWebRequest req;
+            Stream s;
+            WriteBuf start;
+
+            while (m_running)
+            {
+                lock (m_lock)
+                {
+                    if (m_writeQ.Count == 0)
+                    {
+                        Monitor.Wait(m_lock, (int)(m_curPoll * 1000.0));
+                    }
+                }
+                // did we get closed?
+                if (!m_running)
+                    break;
+
+
+                if (m_id == null)
+                {
+                    GenKeys();
+                    start = new WriteBuf(string.Format("0;{0},", m_keys[m_curKey]));
+                }
+                else
+                {
+                    if (m_curKey == 0)
+                    {
+                        string k = m_keys[0];
+                        GenKeys();
+                        start = new WriteBuf(string.Format("{0};{1};{2},", m_id, k, m_keys[m_curKey]));
+                    }
+                    else
+                    {
+                        start = new WriteBuf(string.Format("{0};{1},", m_id, m_keys[m_curKey]));
+                    }
+                }
+                m_curKey--;
+
+                ms.SetLength(0);
+                int count = start.len;
+                while (m_writeQ.Count > 0)
+                {
+                    WriteBuf b = (WriteBuf) m_writeQ.Dequeue();
+                    count += b.len;
+                    ms.Write(b.buf, b.offset, b.len);
+                }
+
+            POLL:
+                req = (HttpWebRequest)WebRequest.Create(m_url);
+                req.CookieContainer = cookies;
+                req.ContentType     = CONTENT_TYPE;
+                req.Method          = METHOD;
+
+                if (m_cert != null)
+                    req.ClientCertificates.Add(m_cert);
+
+                req.KeepAlive       = false;
+
+                req.CachePolicy = new System.Net.Cache.HttpRequestCachePolicy(System.Net.Cache.HttpRequestCacheLevel.NoCacheNoStore);
+                req.CachePolicy = new System.Net.Cache.HttpRequestCachePolicy(System.Net.Cache.HttpRequestCacheLevel.NoCacheNoStore);
+
+                if (m_proxy != null)
+                    req.Proxy = m_proxy;
+                req.ContentLength = count;
+
+
+                try
+                {
+                    ServicePointManager.ServerCertificateValidationCallback =
+                        ValidateRemoteCertificate;
+
+                    s = req.GetRequestStream();
+                    s.Write(start.buf, start.offset, start.len);
+
+                    m_remote_cert = req.ServicePoint.Certificate;
+
+                    buf = ms.ToArray();
+                    s.Write(buf, 0, buf.Length);
+                    s.Close();
+
+                    resp = (HttpWebResponse) req.GetResponse();
+                }
+                catch (WebException ex)
+                {
+                    if (ex.Status != WebExceptionStatus.KeepAliveFailure)
+                    {
+                        m_listener.OnError(this, ex);
+                        return;
+                    }
+                    goto POLL;
+                }
+
+
+
+                if (resp.StatusCode != HttpStatusCode.OK)
+                {
+                    m_listener.OnError(this, new WebException("Invalid HTTP return code: " + resp.StatusCode));
+                    return;
+                }
+
+                CookieCollection cc = resp.Cookies;
+                Debug.Assert(cc != null);
+
+                Cookie c = cc["ID"];
+                if ((c == null) || (c.Value == null))
+                {
+                    m_listener.OnError(this, new WebException("No ID cookie returned"));
+                    return;
+                }
+
+                if (m_id == null)
+                {
+                    // if ID ends in :0, it's an error
+                    if (!c.Value.EndsWith(":0"))
+                        m_id = c.Value;
+                }
+
+                if (m_id != c.Value)
+                {
+                    switch (c.Value)
+                    {
+                        case "0:0":
+                            m_listener.OnError(this, new XEP25Exception("Unknown XEP25 error"));
+                            return;
+                        case "-1:0":
+                            m_listener.OnError(this, new XEP25Exception("Server error"));
+                            return;
+                        case "-2:0":
+                            m_listener.OnError(this, new XEP25Exception("Bad request"));
+                            return;
+                        case "-3:0":
+                            m_listener.OnError(this, new XEP25Exception("Key sequence error"));
+                            return;
+                        default:
+                            m_listener.OnError(this, new WebException("ID cookie changed"));
+                            return;
+                    }
+                }
+
+                if (ms.Length > 0)
+                {
+                    m_listener.OnWrite(this, buf, 0, buf.Length);
+                }
+
+                ms.SetLength(0);
+                rs = resp.GetResponseStream();
+
+
+                int readlen;
+                while ((readlen = rs.Read(readbuf, 0, readbuf.Length)) > 0)
+                {
+                    ms.Write(readbuf, 0, readlen);
+                }
+                rs.Close();
+                if (ms.Length > 0)
+                {
+                    buf = ms.ToArray();
+
+                    try
+                    {
+                        if (!m_listener.OnRead(this, buf, 0, buf.Length))
+                        {
+                            Close();
+                            return;
+                        }
+                    } catch (NullReferenceException)
+                    {}
+                    m_curPoll = m_minPoll;
+                }
+                else
+                {
+                    m_curPoll *= 1.25;
+                    if (m_curPoll > m_maxPoll)
+                        m_curPoll = m_maxPoll;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Is socket connected.
+        /// </summary>
+        public override bool Connected
+        {
+            get
+            { return m_running; }
+        }
+
+        /// <summary>
+        /// Descripton, including poll URL.
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            return "XEP-0025 Polling socket: " + m_url;
+        }
+
+        private class WriteBuf
+        {
+            public readonly byte[] buf;
+            public readonly int offset;
+            public readonly int len;
+
+            public WriteBuf(byte[] buf, int offset, int len)
+            {
+                this.buf = buf;
+                this.offset = offset;
+                this.len = len;
+            }
+
+            public WriteBuf(string b)
+            {
+                buf = Encoding.UTF8.GetBytes(b);
+                offset = 0;
+                len = buf.Length;
+            }
+        }
+    }}
diff --git a/lib/jabber-net/bedrock/util/ConfigFile.cs b/lib/jabber-net/bedrock/util/ConfigFile.cs
new file mode 100644
index 0000000..a9df359
--- /dev/null
+++ b/lib/jabber-net/bedrock/util/ConfigFile.cs
@@ -0,0 +1,163 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+using System.IO;
+using System.Diagnostics;
+using System.Collections;
+using bedrock.util;
+namespace bedrock.util
+{
+    /// <summary>
+    /// XML configuration file manager.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ConfigFile
+    {
+        private string m_file;
+        private XmlDocument m_doc;
+        private static Hashtable s_instances = new Hashtable();
+        private FileSystemWatcher m_watcher;
+
+        /// <summary>
+        /// Singleton factory
+        /// </summary>
+        /// <param name="name"></param>
+        /// <returns></returns>
+        public static ConfigFile GetInstance(string name)
+        {
+            ConfigFile inst = (ConfigFile) s_instances[name];
+            if (inst == null)
+            {
+                lock (s_instances.SyncRoot)
+                {
+                    if (inst == null)
+                    {
+                        inst = new ConfigFile(name);
+                        s_instances[name] = inst;
+                    }
+                }
+            }
+            return inst;
+        }
+
+        /// <summary>
+        /// The config file has been modified, and reloaded.
+        /// </summary>
+        public event FileSystemEventHandler OnFileChange;
+
+        private ConfigFile(string name)
+        {
+            // Don't call Tracer from here!
+            m_doc = new XmlDocument();
+            string d = Path.GetDirectoryName(System.Environment.GetCommandLineArgs()[0]);
+            DirectoryInfo p;
+            while (d != null)
+            {
+                FileInfo fi = new FileInfo(Path.Combine(d, name));
+                if (fi.Exists)
+                {
+                    Load(fi);
+                    return;
+                }
+                p = fi.Directory.Parent;
+                if (p == null)
+                    break;
+                d = p.FullName;
+            }
+
+            throw new FileNotFoundException(name);
+        }
+
+        private void Load(FileInfo info)
+        {
+            m_file = info.FullName;
+            m_doc.Load(m_file);
+            m_watcher = new FileSystemWatcher(info.DirectoryName, info.Name);
+            m_watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size | NotifyFilters.CreationTime;
+            m_watcher.Changed += new FileSystemEventHandler(m_watcher_Changed);
+            m_watcher.EnableRaisingEvents = true;
+        }
+
+        private void m_watcher_Changed(object sender, FileSystemEventArgs e)
+        {
+            m_doc = new XmlDocument();
+            m_doc.Load(m_file);
+            if (OnFileChange != null)
+                OnFileChange(this, e);
+        }
+
+        /// <summary>
+        /// The full path of the filename being used.
+        /// </summary>
+        public string Filename
+        {
+            get { return m_file; }
+        }
+
+        /// <summary>
+        /// Get the configuration file XML node associated
+        /// with a given XPath query.
+        /// </summary>
+        /// <param name="xpath"></param>
+        /// <returns></returns>
+        public XmlNode GetNode(string xpath)
+        {
+            return m_doc.SelectSingleNode(xpath);
+            //ConfigFile f;
+        }
+        /// <summary>
+        /// Get the configuration file XML nodes associated with a give XPath query
+        /// </summary>
+        /// <param name="xpath"></param>
+        /// <returns></returns>
+        public XmlNodeList GetNodes(string xpath)
+        {
+            return m_doc.SelectNodes(xpath);
+        }
+        /// <summary>
+        /// Get the configuration file string associated
+        /// with a given XPath query, or null if not found.
+        /// </summary>
+        public string this[string xpath]
+        {
+            get
+            {
+                return this[xpath, null];
+            }
+        }
+        /// <summary>
+        /// Get the configuration file string associated
+        /// with a given XPath query, or defaultValue if not found.
+        /// </summary>
+        public string this[string xpath, string defaultValue]
+        {
+            get
+            {
+                string val;
+                XmlNode n = m_doc.SelectSingleNode(xpath);
+                if (n != null)
+                {
+                    val = n.InnerText;
+                }
+                else
+                {
+                    val = defaultValue;
+                }
+                return val;
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/util/GetOptBase.cs b/lib/jabber-net/bedrock/util/GetOptBase.cs
new file mode 100644
index 0000000..242e45a
--- /dev/null
+++ b/lib/jabber-net/bedrock/util/GetOptBase.cs
@@ -0,0 +1,553 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+namespace bedrock.util
+
+{
+    using System;
+    using System.Collections;
+    using System.Diagnostics;
+    using System.Reflection;
+    using System.Text;
+    using System.Text.RegularExpressions;
+
+    /// <summary>
+    /// GetOpt should be subclassed to create a class that handles
+    /// command-line parameters.  The subclass should use fields or properties
+    /// that have the CommandLine attribute set on them.  Fields and properties
+    /// of type bool will be toggle flags, other types will take a value as
+    /// either the next command-line parameter or following a colon.
+    /// Also, now, you can create an instance of GetOpt, and pass in
+    /// TODO: Give examples of sublcass and calling example.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class GetOpt
+    {
+        private object    m_obj   = null;
+        private string[]  m_args  = null;
+        private Hashtable m_flags =
+            new Hashtable(StringComparer.InvariantCultureIgnoreCase);
+
+        // Regular expression to parse these:
+        // /a
+        // /a:foo
+        // -a
+        // -a:foo
+        private static readonly Regex FLAG_REGEX =
+            new Regex("[/-]([a-z0-9_]+)([:=](.*))?", RegexOptions.IgnoreCase);
+        /// <summary>
+        /// Really only useful for subclasses, I think.
+        /// </summary>
+        public GetOpt()
+        {
+            // Debug.Assert(this.GetType() != typeof(GetOpt));
+            m_obj = this;
+        }
+        /// <summary>
+        /// Get ready to process command line parameters for the given target object.
+        /// </summary>
+        /// <param name="target">Object to set parameters on</param>
+        public GetOpt(object target)
+        {
+            m_obj = (target == null) ? this : target;
+        }
+        /// <summary>
+        /// Process command line parameters for the given target object, with the
+        /// given arguments.
+        /// </summary>
+        /// <param name="target">Object to set parameters on</param>
+        /// <param name="args">An array of arguments.  If null, use the environment's command line.</param>
+        public GetOpt(object target, string[] args) : this(target)
+        {
+            Process(args);
+        }
+        /// <summary>
+        /// Subclass interface, processing immediately.
+        /// </summary>
+        /// <param name="args">An array of arguments.  If null, use the environment's command line.</param>
+        public GetOpt(string[] args) : this(null, args)
+        {
+        }
+        /// <summary>
+        /// Process the given command line parameters.
+        /// </summary>
+        /// <param name="args">An array of arguments.  If null, use the environment's command line.</param>
+        public void Process(string[] args)
+        {
+            int        i;
+            MemberInfo mi;
+            Match      rm;
+            Type       mit;
+
+            SetFlags();
+            if (args == null)
+            {
+                string[] e = Environment.GetCommandLineArgs();
+                args = new string[e.Length - 1];
+                Array.Copy(e, 1, args, 0, e.Length-1);
+            }
+
+            for (i=0; i<args.Length; i++)
+            {
+                rm = FLAG_REGEX.Match(args[i]);
+                if (!rm.Success)   // no more flags
+                {
+                    break;
+                }
+
+                mi = (MemberInfo) m_flags[rm.Groups[1].ToString()];
+                if (mi == null)
+                {
+                    throw new ArgumentException("Invalid command-line argument", args[i]);
+                }
+
+                mit = GetMemberType(mi);
+                // methods return null types, for now.
+                // TODO: should this be moved to SetValue?
+                // Not sure what to do with bool params, then.
+                if (mit == null)
+                {
+                    string old_flag = args[i];
+                    MethodInfo meth = (MethodInfo) mi;
+                    ParameterInfo[] pi = meth.GetParameters();
+                    object[] parms = new object[pi.Length];
+                    for (int j=0; j<pi.Length; j++)
+                    {
+                        if (i+1 >= args.Length)
+                        {
+                            throw new IndexOutOfRangeException("Not enough parameters for: " + old_flag);
+                        }
+                        parms[j] = ConvertValue(args[++i], pi[j].ParameterType);
+                    }
+
+                    meth.Invoke(m_obj, parms);
+                }
+
+                // bool flags act as toggles
+                else if (mit == typeof(bool))
+                {
+                    SetValue(mi, ! (bool) GetValue(mi));
+                }
+                else
+                {
+                    // use the value after the colon, if it exists
+                    if (rm.Groups[3].Success)
+                    {
+                        SetValue(mi, rm.Groups[3].ToString());
+                    }
+                    else
+                    {
+                        if (i+1 >= args.Length)
+                        {
+                            throw new IndexOutOfRangeException("Not enough parameters for: " + args[i]);
+                        }
+                        SetValue(mi, args[++i]);
+                    }
+                }
+            }
+            // copy the rest of the argument array (those after the flags)
+            // into an array for later use.
+            m_args = new string[args.Length - i];
+            Array.Copy(args, i, m_args, 0, args.Length - i);
+            CheckRequired();
+        }
+        /// <summary>
+        /// Look at myself, to see if there are any command line
+        /// parameter fields or properties.
+        /// </summary>
+        private void SetFlags()
+        {
+            if (m_flags.Count != 0)
+                return;
+            MemberInfo[] mis = GetCommandLineMembers();
+            foreach (MemberInfo mi in mis)
+            {
+                CommandLineAttribute cla = GetOption(mi);
+                string cf = cla.CommandFlag;
+                // If no CommandFlag specified, use the member name.
+                if (cf == null)
+                {
+                    cf = mi.Name;
+                }
+                // make sure required parameters are initialized to null.
+                if (cla.Required && (GetValue(mi) != null))
+                {
+                    throw new ArgumentException("Must provide null initial value for required parameters: ", mi.Name);
+                }
+                m_flags[cf] = mi;
+            }
+        }
+        /// <summary>
+        /// Make sure all required fields got hit.
+        /// </summary>
+        private void CheckRequired()
+        {
+            MemberInfo[] mis = GetCommandLineMembers();
+            foreach (MemberInfo mi in mis)
+            {
+                CommandLineAttribute cla = GetOption(mi);
+                if (cla.Required && (GetValue(mi) == null))
+                {
+                    throw new ArgumentException("Did not provide required parameter: ", mi.Name);
+                }
+            }
+        }
+        /// <summary>
+        /// Set the value of a field or property, depending on the kind of member.
+        /// Coerce the type of the value passed in, as possible
+        /// </summary>
+        /// <param name="mi">The member to set</param>
+        /// <param name="val">The value to set</param>
+        private void SetValue(MemberInfo mi, object val)
+        {
+            switch (mi.MemberType)
+            {
+            case MemberTypes.Field:
+                FieldInfo fi = (FieldInfo) mi;
+                fi.SetValue(m_obj, ConvertValue(val, fi.FieldType));
+                break;
+            case MemberTypes.Property:
+                PropertyInfo pi = (PropertyInfo) mi;
+                pi.SetValue(m_obj, ConvertValue(val, pi.PropertyType), null);
+                break;
+            default:
+                throw new ArgumentException("Invalid member type", "mi");
+            }
+        }
+        /// <summary>
+        /// Convert a field value representation to a value of the correct type.
+        /// Enums need special handling, at least for now.
+        /// </summary>
+        /// <param name="val">The value to convert</param>
+        /// <param name="TargetType">The type to convert it to</param>
+        private object ConvertValue(object val, Type TargetType)
+        {
+            if (TargetType.IsEnum)
+            {
+                return Enum.Parse(TargetType, (string) val, true);
+            }
+            return Convert.ChangeType(val, TargetType);
+        }
+        /// <summary>
+        /// Get the value from a field or property, depending on the type of member.
+        /// </summary>
+        /// <param name="mi"> </param>
+        private object GetValue(MemberInfo mi)
+        {
+            object ret = null;
+            switch (mi.MemberType)
+            {
+            case MemberTypes.Field:
+                FieldInfo fi = (FieldInfo) mi;
+                ret = fi.GetValue(m_obj);
+                break;
+            case MemberTypes.Property:
+                PropertyInfo pi = (PropertyInfo) mi;
+                ret = pi.GetValue(m_obj, null);
+                break;
+            default:
+                throw new ArgumentException("Invalid member type", "mi");
+            }
+            return ret;
+        }
+        /// <summary>
+        /// Get the type contained in the given member.
+        /// </summary>
+        /// <param name="mi">The member to check</param>
+        private static Type GetMemberType(MemberInfo mi)
+        {
+            Type ret = null;
+            switch (mi.MemberType)
+            {
+            case MemberTypes.Field:
+                FieldInfo fi = (FieldInfo) mi;
+                ret = fi.FieldType;
+                break;
+            case MemberTypes.Property:
+                PropertyInfo pi = (PropertyInfo) mi;
+                ret = pi.PropertyType;
+                break;
+            case MemberTypes.Method:
+                ret = null;
+                break;
+            default:
+                throw new ArgumentException("Invalid member type", "mi");
+            }
+            return ret;
+        }
+        /// <summary>
+        /// Get all of the members that are tagged with the CommandLineAttribute.
+        /// NOTE: this currently returns private members as well, but setting the
+        /// BindingFlags to public doesn't return anything.  Could be a bug in the BCL?
+        /// </summary>
+        private MemberInfo[] GetCommandLineMembers()
+        {
+            Type t = m_obj.GetType();
+            MemberInfo[] mis = t.FindMembers(MemberTypes.All,
+                                             BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance,
+                                             new MemberFilter(AttrMemberFilter),
+                                             typeof(CommandLineAttribute));
+            Debug.Assert(mis.Length > 0, "Must have at least one CommandLine attribute on class: " + t.FullName);
+            return mis;
+        }
+
+        /// <summary>
+        /// Filter proc for GetCommandLineMembers.  Returns true if the member
+        /// implements a given attribute.
+        /// </summary>
+        /// <param name="m">The member to evaluate</param>
+        /// <param name="filterCriteria">The attribute type to check for</param>
+        private static bool AttrMemberFilter(MemberInfo m, object filterCriteria)
+        {
+            return m.GetCustomAttributes((Type)filterCriteria, true).Length > 0;
+        }
+        /// <summary>
+        /// Get the CommandLineAttribute off of a member.  Assumes that the member implements
+        ///<i>exactly</i> one instance of the attribute.
+        /// </summary>
+        /// <param name="mi">The member to retrieve from</param>
+        private CommandLineAttribute GetOption(MemberInfo mi)
+        {
+            object[] o = mi.GetCustomAttributes(typeof(CommandLineAttribute), true);
+            Debug.Assert(o.Length == 1);
+            return ((CommandLineAttribute[]) o)[0];
+        }
+        /// <summary>
+        /// The list of command-line arguments that were not associated with flags.
+        /// </summary>
+        public virtual string[] Args
+        {
+            get { return m_args; }
+        }
+        /// <summary>
+        /// Get/Set a parameter on the managed object, using the flag.
+        /// Warning: this will do an implicit conversion to the type of the
+        /// field associated with the flag.
+        /// If you're using this, you've probably got a design problem.
+        /// </summary>
+        public object this[string flag]
+        {
+            get
+            {
+                SetFlags();
+                MemberInfo mi = (MemberInfo) m_flags[flag];
+                return GetValue(mi);
+            }
+            set
+            {
+                SetFlags();
+                MemberInfo mi = (MemberInfo) m_flags[flag];
+                SetValue(mi, value);
+            }
+        }
+        /// <summary>
+        /// Get a usage description string from the object.
+        /// Use the CommandLineAttribute descriptions wherever possible.
+        /// </summary>
+        public virtual string Usage
+        {
+            get
+            {
+                SetFlags();
+                StringBuilder sb = new StringBuilder();
+                // Gr.  this used to work, and I can't find the new API.
+                //sb.Append(System.IO.File.GetFileNameFromPath(Environment.GetCommandLineArgs()[0]));
+                sb.Append(Environment.GetCommandLineArgs()[0]);
+                string[] keys = new string[m_flags.Count];
+                m_flags.Keys.CopyTo(keys, 0);
+                Array.Sort(keys);
+                foreach (object key in keys)
+                {
+                    MemberInfo mi = (MemberInfo) m_flags[key];
+                    CommandLineAttribute cla = GetOption(mi);
+                    Type       mit = GetMemberType(mi);
+                    sb.Append(" ");
+                    if (!cla.Required)
+                    {
+                        sb.Append("[");
+                    }
+
+                    // method
+                    if (mit == null)
+                    {
+                        MethodInfo meth = (MethodInfo) mi;
+                        ParameterInfo[] pis = meth.GetParameters();
+                        sb.AppendFormat("/{0}", key);
+                        foreach (ParameterInfo pi in pis)
+                        {
+                            sb.Append(" ");
+                            sb.Append(pi.ParameterType.Name);
+                        }
+                    }
+                    else if (mit == typeof(bool))
+                    {
+                        sb.AppendFormat("/{0}", key);
+                    }
+                    else if (mit.IsEnum)
+                    {
+                        sb.AppendFormat("/{0} (", key);
+                        string val = GetValue(mi).ToString();
+                        string[] names = Enum.GetNames(mit);
+                        bool first = true;
+                        foreach (string n in names)
+                        {
+                            if (first)
+                            {
+                                first = false;
+                            }
+                            else
+                            {
+                                sb.Append("|");
+                            }
+                            if (val == n)
+                            {
+                                sb.AppendFormat("*{0}*", n);
+                            }
+                            else
+                            {
+                                sb.Append(n);
+                            }
+                        }
+                        sb.Append(")");
+                    }
+                    else
+                    {
+                        sb.AppendFormat("/{0} {1}", key, GetValue(mi));
+                    }
+                    if (!cla.Required)
+                    {
+                        sb.Append("]");
+                    }
+                }
+                sb.Append(Environment.NewLine);
+                foreach (object key in keys)
+                {
+                    sb.AppendFormat("\t/{0}: \t{1}", key, GetOption((MemberInfo)m_flags[key]).Description);
+                    sb.Append(Environment.NewLine);
+                }
+                return sb.ToString();
+            }
+        }
+        /// <summary>
+        /// Print out the usage information on StdErr, and exit with code 64.
+        /// </summary>
+        public virtual void UsageExit()
+        {
+            Console.Error.WriteLine(Usage);
+            Environment.Exit(64);
+        }
+
+        /// <summary>
+        /// Echo Command-Line requirements for a GUI app via a MessageBox
+        /// (since we do not have user-visible stdout)
+        /// </summary>
+        public virtual void UsageGUIExit()
+        {
+            /*
+          MessageBox.Show
+            (Usage, "Command-line argument usage",
+             MessageBoxButtons.OK, MessageBoxIcon.Error);
+          Environment.Exit(64);
+             */
+            throw new NotImplementedException("This is the only thing that requires Windows.Forms.  Removed.");
+        }
+    }
+    /// <summary>
+    /// Attribute to annotate subclasses of GetOpt.  Any field or property
+    /// that gets this attribute is a possible command-line argument for the
+    /// program containing the GetOpt subclass.
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method,
+                    AllowMultiple=false)]
+    [SVN(@"$Id$")]
+    public class CommandLineAttribute : Attribute
+    {
+        private string m_commandFlag = null;
+        private string m_description = null;
+        private bool   m_required    = false;
+        /// <summary>
+        /// Use the member name for the command-line parameter.
+        /// </summary>
+        public CommandLineAttribute()
+        {
+        }
+        /// <summary>
+        /// Use the given string as the command-line parameter.
+        /// </summary>
+        /// <param name="commandFlag"> </param>
+        public CommandLineAttribute(string commandFlag)
+        {
+            m_commandFlag = commandFlag;
+        }
+        /// <summary>
+        /// Use the given string as the command-line parameter.
+        /// </summary>
+        /// <param name="commandFlag"> </param>
+        /// <param name="description"> </param>
+        public CommandLineAttribute(string commandFlag, string description)
+        {
+            m_commandFlag = commandFlag;
+            m_description = description;
+        }
+        /// <summary>
+        /// Use the given string as the command-line parameter.
+        /// </summary>
+        /// <param name="commandFlag"> </param>
+        /// <param name="description"> </param>
+        /// <param name="required"> </param>
+        public CommandLineAttribute(string commandFlag, string description, bool required)
+        {
+            m_commandFlag = commandFlag;
+            m_description = description;
+            m_required    = required;
+        }
+        /// <summary>
+        /// Get the command-line flag.  If none was specified, returns null.
+        /// </summary>
+        public string CommandFlag
+        {
+            get
+            {
+                return m_commandFlag;
+            }
+        }
+        /// <summary>
+        /// Get the command-line description.  If none was specified, returns null.
+        /// </summary>
+        public string Description
+        {
+            get
+            {
+                return m_description;
+            }
+            set
+            {
+                m_description = value;
+            }
+        }
+        /// <summary>
+        /// Is the option required?  Defaults to false.
+        /// </summary>
+        public bool Required
+        {
+            get
+            {
+                return m_required;
+            }
+            set
+            {
+                m_required = value;
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/util/IdleTime.cs b/lib/jabber-net/bedrock/util/IdleTime.cs
new file mode 100644
index 0000000..4ca3ad4
--- /dev/null
+++ b/lib/jabber-net/bedrock/util/IdleTime.cs
@@ -0,0 +1,217 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.ComponentModel;
+using System.Text;
+using System.Runtime.InteropServices;
+using System.ComponentModel.Design;
+
+namespace bedrock.util
+{
+    /// <summary>
+    /// TimeSpan event.
+    /// </summary>
+    /// <param name="sender"></param>
+    /// <param name="span"></param>
+    public delegate void SpanEventHandler(object sender, TimeSpan span);
+
+    /// <summary>
+    /// Idle time calculations and notifications.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class IdleTime : System.ComponentModel.Component
+    {
+        [StructLayout(LayoutKind.Sequential)]
+        private struct LASTINPUTINFO
+        {
+            public int cbSize;
+            public int dwTime;
+        }
+
+        [DllImport("User32.dll")]
+        private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
+
+        /// <summary>
+        /// Get the lapse time between user input (mouse or keyboard) system-wide.
+        /// </summary>
+        /// <returns>Lapse time in seconds.</returns>
+        public static double GetIdleTime()
+        {
+            LASTINPUTINFO lii = new LASTINPUTINFO();
+            lii.cbSize = Marshal.SizeOf(lii.GetType());
+            if (!GetLastInputInfo(ref lii))
+                throw new ApplicationException("Error executing GetLastInputInfo");
+            return (Environment.TickCount - lii.dwTime) / 1000.0;
+        }
+
+        /// <summary>
+        /// Fired when user has been idle (mouse, keyboard) for the configured number of seconds.
+        /// </summary>
+        public event SpanEventHandler OnIdle;
+
+        /// <summary>
+        /// Fired when the user comes back.
+        /// </summary>
+        public event SpanEventHandler OnUnIdle;
+
+        private const double DEFAULT_POLL = 5;      // 5s in s.
+        private const double DEFAULT_IDLE = 5 * 60; // 5m in s.
+
+        private System.Timers.Timer m_timer = null;
+        private double m_notifySecs = DEFAULT_IDLE;
+        private bool m_idle = false;
+        private DateTime m_idleStart = DateTime.MinValue;
+        private ISynchronizeInvoke m_invoker = null;
+
+        /// <summary>
+        /// Create an idle timer with the default timouts.
+        /// </summary>
+        public IdleTime()
+        {
+            m_timer = new System.Timers.Timer(DEFAULT_POLL * 1000.0);
+            m_timer.Elapsed += new System.Timers.ElapsedEventHandler(m_timer_Elapsed);
+        }
+
+        /// <summary>
+        /// Create an idle timer.  Make sure to set Enabled = true to start.
+        /// </summary>
+        /// <param name="pollSecs">Every pollSecs seconds, poll to see how long we've been away.</param>
+        /// <param name="notifySecs">If we've been away notifySecs seconds, fire notification.</param>
+        public IdleTime(int pollSecs, int notifySecs) : this()
+        {
+            if (pollSecs > notifySecs)
+                throw new ArgumentException("Poll more often than you notify.");
+            PollInterval = pollSecs;
+            IdleLength = notifySecs;
+        }
+
+        /// <summary>
+        /// Is the timer running?
+        /// </summary>
+        [Category("Logic")]
+        [DefaultValue(false)]
+        public bool Enabled
+        {
+            get { return m_timer.Enabled; }
+            set { m_timer.Enabled = value; }
+        }
+
+        /// <summary>
+        /// Time, in seconds, between checking for
+        /// </summary>
+        [Category("Time")]
+        [DefaultValue(DEFAULT_POLL)]
+        public double PollInterval
+        {
+            get { return m_timer.Interval / 1000.0; }
+            set { m_timer.Interval = value * 1000.0; }
+        }
+
+        /// <summary>
+        /// The amount of time (in seconds) the computer can be idle before OnIdle is fired.
+        /// </summary>
+        [Category("Time")]
+        [DefaultValue(DEFAULT_IDLE)]
+        public double IdleLength
+        {
+            get { return m_notifySecs;  }
+            set { m_notifySecs = value;  }
+        }
+
+        /// <summary>
+        /// Are we currently idle?
+        /// </summary>
+        [Category("Logic")]
+        public bool IsIdle
+        {
+            get { return m_idle; }
+        }
+
+        /// <summary>
+        /// Invoke() all callbacks on this control.
+        /// </summary>
+        [Description("Invoke all callbacks on this control")]
+        [DefaultValue(null)]
+        [Category("Logic")]
+        public ISynchronizeInvoke InvokeControl
+        {
+            get
+            {
+                // If we are running in the designer, let's try to get
+                // an invoke control from the environment.  VB
+                // programmers can't seem to follow directions.
+                if ((this.m_invoker == null) && DesignMode)
+                {
+                    IDesignerHost host = (IDesignerHost)base.GetService(typeof(IDesignerHost));
+                    if (host != null)
+                    {
+                        object root = host.RootComponent;
+                        if ((root != null) && (root is ISynchronizeInvoke))
+                        {
+                            m_invoker = (ISynchronizeInvoke)root;
+                            // TODO: fire some sort of propertyChanged event,
+                            // so that old code gets cleaned up correctly.
+                        }
+                    }
+                }
+                return m_invoker;
+            }
+            set { m_invoker = value; }
+        }
+
+
+        private void m_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
+        {
+            double idle = GetIdleTime();
+            if (m_idle)
+            {
+                if (idle < PollInterval)
+                {
+                    m_idle = false;
+                    if (OnUnIdle != null)
+                    {
+                        TimeSpan span = DateTime.Now - m_idleStart;
+                        if ((m_invoker != null) &&
+                            (m_invoker.InvokeRequired))
+                        {
+                            m_invoker.Invoke(OnUnIdle, new object[] { this, span });
+                        }
+                        else
+                            OnUnIdle(this, span);
+                    }
+                    m_idleStart = DateTime.MinValue;
+                }
+            }
+            else
+            {
+                if (idle > m_notifySecs)
+                {
+                    m_idle = true;
+                    m_idleStart = DateTime.Now;
+                    if (OnIdle != null)
+                    {
+                        TimeSpan span = new TimeSpan((long)(idle * 1000L));
+                        if ((m_invoker != null) &&
+                            (m_invoker.InvokeRequired))
+                        {
+                            m_invoker.Invoke(OnIdle, new object[] { this, span });
+                        }
+                        else
+                            OnIdle(this, span);
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/bedrock/util/Version.cs b/lib/jabber-net/bedrock/util/Version.cs
new file mode 100644
index 0000000..27b0dff
--- /dev/null
+++ b/lib/jabber-net/bedrock/util/Version.cs
@@ -0,0 +1,632 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using System.Collections.Specialized;
+using System.Reflection;
+using System.Text;
+using System.Text.RegularExpressions;
+namespace bedrock.util
+{
+    /// <summary>
+    /// Make source code versions available at runtime.  Use the appropriate
+    /// subclass for your CM system.
+    /// </summary>
+    /// <see cref="StarTeamAttribute"/>
+    /// <see cref="SourceSafeAttribute"/>
+    /// <see cref="RCSAttribute"/>
+    //    [SVN(@"$Id$")]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Struct,
+                    AllowMultiple = false,
+                    Inherited     = false)]
+    public abstract class SourceVersionAttribute : Attribute
+    {
+        /// <summary>
+        /// The entire header
+        /// </summary>
+        protected string   m_header  = null;
+        /// <summary>
+        /// The directory it's stored in
+        /// </summary>
+        protected string   m_archive = null;
+        /// <summary>
+        /// Last check-in author
+        /// </summary>
+        protected string   m_author  = null;
+        /// <summary>
+        /// Last check-in version
+        /// </summary>
+        protected string   m_version = null;
+        /// <summary>
+        /// Last check-in date
+        /// </summary>
+        protected DateTime m_date    = DateTime.MinValue;
+        /// <summary>
+        /// Have we parsed the header, yet?
+        /// </summary>
+        private   bool     m_parsed  = false;
+        // TODO: replace all of the subclasses with a single, uber-regex.
+        private static readonly Regex REGEX =
+            new Regex(@"^(\$(?<field>[a-z]+): *(?<value>.+) *\$)|( *(?<value>.+) *)$",
+                      RegexOptions.IgnoreCase | RegexOptions.Compiled);
+        /// <summary>
+        /// Construct the attribute.  Parsing is delayed until needed.
+        /// </summary>
+        /// <param name="header">the Header keyword for your CM system.
+        /// Usually $Header$</param>
+        public SourceVersionAttribute(string header)
+        {
+            m_header = header;
+        }
+        /// <summary>
+        /// You could use this one, and pass the keywords in individually.
+        /// </summary>
+        public SourceVersionAttribute()
+        {
+
+        }
+        /// <summary>
+        /// Give back the header string.
+        /// </summary>
+        public override string ToString()
+        {
+            return m_header;
+        }
+        /// <summary>
+        /// Have we parsed yet?
+        /// </summary>
+        protected void CheckParse()
+        {
+            if (m_parsed)
+            {
+                return;
+            }
+            lock(this)
+            {
+                if (m_parsed)
+                {
+                    return;
+                }
+                Parse();
+                m_parsed = true;
+            }
+        }
+        /// <summary>
+        /// We have done a parse, now
+        /// </summary>
+        protected void SetParse()
+        {
+            if (!m_parsed)
+            {
+                lock(this)
+                {
+                    m_parsed = true;
+                }
+            }
+        }
+        /// <summary>
+        /// Parse data into internal fields
+        /// </summary>
+        protected abstract void Parse();
+        /// <summary>
+        /// Do a regex match on src
+        /// </summary>
+        /// <param name="src"></param>
+        /// <returns></returns>
+        protected string GetField(string src)
+        {
+            Match m = REGEX.Match(src);
+            if (!m.Success)
+            {
+                throw new FormatException("Bad header format: " + src + " != " + REGEX.ToString());
+            }
+            if (!m.Groups["value"].Success)
+            {
+                throw new FormatException("Value not found in: " + src);
+            }
+            return m.Groups["value"].ToString();
+        }
+        /// <summary>
+        /// The last checked-in version
+        /// </summary>
+        public string Revision
+        {
+            get
+            {
+                CheckParse();
+                return m_version;
+            }
+            set
+            {
+                SetParse();
+                m_version = GetField(value);
+            }
+        }
+        /// <summary>
+        /// The last checked-in version, in perhaps more useful format
+        /// </summary>
+        public Version Version
+        {
+            get
+            {
+                CheckParse();
+                if (m_version == null)
+                {
+                    return null;
+                }
+                if (m_version.IndexOf('.') == -1)
+                {
+                    return new Version(1, Int32.Parse(m_version));
+                }
+                return new Version(m_version);
+            }
+        }
+        /// <summary>
+        /// Retrive the binary date/time of last check-in
+        /// </summary>
+        public DateTime Date
+        {
+            get
+            {
+                CheckParse();
+                return m_date;
+            }
+            set
+            {
+                SetParse();
+                m_date = value;
+            }
+        }
+        /// <summary>
+        /// Retrieve the string representation of the date of last check-in.
+        /// </summary>
+        public string DateString
+        {
+            get
+            {
+                CheckParse();
+                return m_date.ToString();
+            }
+            set
+            {
+                SetParse();
+                m_date = DateTime.Parse(GetField(value));
+            }
+        }
+        /// <summary>
+        /// Retrive the name of the last person to check in
+        /// </summary>
+        public string Author
+        {
+            get
+            {
+                CheckParse();
+                return m_author;
+            }
+            set
+            {
+                SetParse();
+                m_author = GetField(value);
+            }
+        }
+        /// <summary>
+        /// Retrieve the archive name from the header
+        /// </summary>
+        public string Archive
+        {
+            get
+            {
+                CheckParse();
+                return m_archive;
+            }
+            set
+            {
+                SetParse();
+                m_archive = GetField(value);
+            }
+        }
+        /// <summary>
+        /// Get the version information for the given type.
+        /// </summary>
+        /// <param name="t"></param>
+        /// <returns></returns>
+        public static SourceVersionAttribute GetVersion(Type t)
+        {
+            object[] sta = t.GetCustomAttributes(typeof(SourceVersionAttribute), true);
+            if (sta.Length == 0)
+            {
+                // throw exception?  Null seems nicer.
+                return null;
+            }
+            return (SourceVersionAttribute) sta[0];
+        }
+        /// <summary>
+        /// Get the version information for the class of the given object.
+        /// </summary>
+        /// <param name="o"></param>
+        /// <returns></returns>
+        public static SourceVersionAttribute GetVersion(object o)
+        {
+            // Well, someone used it wrong, but who am I to complain?
+            if (o is Type)
+            {
+                return GetVersion((Type) o);
+            }
+            return GetVersion(o.GetType());
+        }
+        /// <summary>
+        /// Get all of the versioned classes currently in the working set.
+        /// </summary>
+        /// <returns></returns>
+        public static SourceVersionCollection GetVersion()
+        {
+            SourceVersionCollection tv = new SourceVersionCollection();
+            Assembly[] assems = AppDomain.CurrentDomain.GetAssemblies();
+            SourceVersionAttribute sta;
+            foreach (Assembly a in assems)
+            {
+                Type[] ts = a.GetTypes();
+                foreach (Type t in ts)
+                {
+                    sta = GetVersion(t);
+                    if (sta != null)
+                    {
+                        tv.Add(t.FullName, sta);
+                    }
+                }
+            }
+            return tv;
+        }
+    }
+    /// <summary>
+    /// Make StarTeam versoning available at run-time.
+    ///
+    /// </summary>
+    /// <example>
+    /// [StarTeam(@"$Header$")]
+    /// public class foo {}
+    ///
+    /// SourceVersionAttribute sta = SourceVersionAttribute.GetVersion(typeof(foo));
+    /// </example>
+    [SVN(@"$Id$")]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Struct,
+                    AllowMultiple=false, Inherited=false)]
+    public class StarTeamAttribute : SourceVersionAttribute
+    {
+        // Dammit gumby.  Don't mess up my regex.
+        private static readonly Regex REGEX =
+            new Regex(@"^\$" + @"Header(: (?<archive>[^,]+), (?<version>[0-9.]+), (?<date>[^,]+), (?<author>[^$]+))?" + @"\$$");
+        /// <summary>
+        /// Normal usage
+        /// </summary>
+        /// <param name="header"></param>
+        public StarTeamAttribute(string header) : base(header)
+        {
+        }
+        /// <summary>
+        /// Not useful
+        /// </summary>
+        public StarTeamAttribute() : base()
+        {
+        }
+
+        /// <summary>
+        /// Return normalized header
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            string s = base.ToString();
+            if (s != null)
+            {
+                return s;
+            }
+
+            return String.Format("{0}Header: {1}, {2}, {3:MM/dd/yyyy h:mm:ss tt}, {4}{5}",
+                                 new object[] {"$", m_archive, m_version, m_date, m_author, "$"});
+        }
+        /// <summary>
+        /// Parse the header
+        /// </summary>
+        protected override void Parse()
+        {
+            Match m = REGEX.Match(m_header);
+            if (!m.Success)
+            {
+                throw new FormatException("Bad header format: " + m_header + " != " + REGEX.ToString());
+            }
+            if (m.Groups["archive"].Success)
+            {
+                m_archive = m.Groups["archive"].ToString();
+                m_version = m.Groups["version"].ToString();
+                m_date    = DateTime.Parse(m.Groups["date"].ToString());
+                m_author  = m.Groups["author"].ToString();
+            }
+        }
+    }
+    /// <summary>
+    /// Version control attribute for RCS and CVS.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Struct,
+                    AllowMultiple=false, Inherited=false)]
+    public class RCSAttribute : SourceVersionAttribute
+    {
+        // Header: /u1/html/cvsroot/www.cyclic.com/RCS-html/info-ref.html,v 1.1 1999/04/14 19:04:02 kingdon Exp
+        private static readonly Regex REGEX =
+            new Regex(@"^\$" + @"Header(: +(?<archive>[^ ]+) +(?<version>[0-9.]+) +(?<date>[0-9/]+ [0-9:]+) +(?<author>[^ ]+) +(?<state>[^ ]+) *)?" + @"\$$");
+        private string m_state = null;
+        /// <summary>
+        /// The most common.  Pass in @"$ Header $" (without the spaces).
+        /// </summary>
+        /// <param name="header"></param>
+        public RCSAttribute(string header) : base(header)
+        {
+        }
+        /// <summary>
+        /// Null constructor.  This is rarely right.
+        /// </summary>
+        public RCSAttribute() : base()
+        {
+        }
+        /// <summary>
+        /// Parse the header string.
+        /// </summary>
+        protected override void Parse()
+        {
+            Match m = REGEX.Match(m_header);
+            if (!m.Success)
+            {
+                throw new FormatException("Bad header format: " + m_header + " != " + REGEX.ToString());
+            }
+            if (m.Groups["archive"].Success)
+            {
+                m_archive = m.Groups["archive"].ToString();
+                m_version = m.Groups["version"].ToString();
+                m_date    = DateTime.Parse(m.Groups["date"].ToString());
+                m_author  = m.Groups["author"].ToString();
+                m_state   = m.Groups["state"].ToString();
+            }
+        }
+        /// <summary>
+        /// Hm.  Wish I remembered what this was for.  :)
+        /// </summary>
+        public string State
+        {
+            get
+            {
+                CheckParse();
+                return m_state;
+            }
+            set
+            {
+                SetParse();
+                m_state  = GetField(value);
+            }
+        }
+    }
+    /// <summary>
+    /// Version control attribute for SourceSafe.
+    /// I don't use this any more, so someone tell me if it breaks with
+    /// some new release.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Struct,
+                    AllowMultiple=false, Inherited=false)]
+    public class SourceSafeAttribute : SourceVersionAttribute
+    {
+        // Header: /t.cs 1     2/14/01 3:57p Hildebzj
+        private static readonly Regex REGEX =
+            new Regex(@"^\$" + @"Header(: +(?<archive>[^ ]+) +(?<version>[0-9.]+) +(?<date>[0-9/]+ [0-9:]+)(?<ampm>[ap]) +(?<author>[^ ]+) *)?" + @"\$$");
+        //private string m_state = null;
+        /// <summary>
+        /// The normal use.  Pass in @"$ Header $" (without the spaces).
+        /// </summary>
+        /// <param name="header"></param>
+        public SourceSafeAttribute(string header) : base(header)
+        {
+        }
+        /// <summary>
+        /// Not usually useful.
+        /// </summary>
+        public SourceSafeAttribute() : base()
+        {
+        }
+        /// <summary>
+        /// Parse the header.
+        /// </summary>
+        protected override void Parse()
+        {
+            Match m = REGEX.Match(m_header);
+            if (!m.Success)
+            {
+                throw new FormatException("Bad header format: " + m_header + " != " + REGEX.ToString());
+            }
+            if (m.Groups["archive"].Success)
+            {
+                m_archive = m.Groups["archive"].ToString();
+                m_version = m.Groups["version"].ToString();
+                m_date    = DateTime.Parse(m.Groups["date"].ToString());
+                if (m.Groups["ampm"].ToString() == "p")
+                {
+                    m_date = m_date.AddHours(12);
+                }
+                m_author  = m.Groups["author"].ToString();
+            }
+        }
+    }
+    /// <summary>
+    /// A collection of SourceVersionAttributes, so that we can
+    /// return a list of all of the versioned classes in the
+    /// current working set.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class SourceVersionCollection : NameObjectCollectionBase
+    {
+        /// <summary>
+        /// Add an attribute to the list
+        /// </summary>
+        /// <param name="type"></param>
+        /// <param name="value"></param>
+        public void Add(string type, SourceVersionAttribute value)
+        {
+            BaseAdd(type, value);
+        }
+        /// <summary>
+        /// Remove all of the attributes from the list
+        /// </summary>
+        public void Clear()
+        {
+            BaseClear();
+        }
+        /// <summary>
+        /// Get the index'th attribute
+        /// </summary>
+        /// <param name="index"></param>
+        /// <returns></returns>
+        public SourceVersionAttribute Get(int index)
+        {
+            return (SourceVersionAttribute) BaseGet(index);
+        }
+        /// <summary>
+        /// Get the attribute associated with a give type name
+        /// </summary>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        public SourceVersionAttribute Get(string type)
+        {
+            return (SourceVersionAttribute) BaseGet(type);
+        }
+        /// <summary>
+        /// Set the attribute associated with a given type name
+        /// </summary>
+        /// <param name="type"></param>
+        /// <param name="value"></param>
+        public void Set(string type, SourceVersionAttribute value)
+        {
+            BaseSet(type, value);
+        }
+        /// <summary>
+        /// Set the index'th attribute
+        /// </summary>
+        /// <param name="index"></param>
+        /// <param name="value"></param>
+        public void Set(int index, SourceVersionAttribute value)
+        {
+            BaseSet(index, value);
+        }
+        /// <summary>
+        /// Remove the index'th attribute
+        /// </summary>
+        /// <param name="index"></param>
+        public void Remove(int index)
+        {
+            BaseRemoveAt(index);
+        }
+        /// <summary>
+        /// Remove the attribute associated with the given type name
+        /// </summary>
+        /// <param name="type"></param>
+        public void Remove(string type)
+        {
+            BaseRemove(type);
+        }
+        /// <summary>
+        /// Retrieve the index'th attribute
+        /// </summary>
+        public string this[int index]
+        {
+            get
+            {
+                return BaseGetKey(index);
+            }
+        }
+        /// <summary>
+        /// Retrieve/set the attriubute associated with the given type name.
+        /// </summary>
+        public SourceVersionAttribute this[string type]
+        {
+            get
+            {
+                return Get(type);
+            }
+            set
+            {
+                Set(type, value);
+            }
+        }
+        /// <summary>
+        /// Retrieve/set the attribute associated with the given type.
+        /// </summary>
+        public SourceVersionAttribute this[Type type]
+        {
+            get
+            {
+                return Get(type.FullName);
+            }
+            set
+            {
+                Set(type.FullName, value);
+            }
+        }
+    }
+
+    /// <summary>
+    /// Version control attribute for Subversion.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Struct,
+                    AllowMultiple=false, Inherited=false)]
+    public class SVNAttribute : SourceVersionAttribute
+    {
+        // Header: /u1/html/cvsroot/www.cyclic.com/RCS-html/info-ref.html,v 1.1 1999/04/14 19:04:02 kingdon Exp
+        // Id: calc.c 148 2002-07-28 21:30:43Z sally
+        private static readonly Regex REGEX =
+            new Regex(@"^\$" + @"Id(: +(?<archive>[^ ]+) +(?<version>[0-9.]+) +(?<date>[0-9-]+ [0-9:]+)Z +(?<author>[^ ]+) *)?\$$");
+        /// <summary>
+        /// The most common.  Pass in @"$ Id $" (without the spaces).
+        /// </summary>
+        /// <param name="header"></param>
+        public SVNAttribute(string header)
+            : base(header)
+        {
+        }
+        /// <summary>
+        /// Null constructor.  This is rarely right.
+        /// </summary>
+        public SVNAttribute()
+            : base()
+        {
+        }
+        /// <summary>
+        /// Parse the header string.
+        /// </summary>
+        protected override void Parse()
+        {
+            Match m = REGEX.Match(m_header);
+            if (!m.Success)
+            {
+                throw new FormatException("Bad header format: " + m_header + " != " + REGEX.ToString());
+            }
+            if (m.Groups["archive"].Success)
+            {
+                m_archive = m.Groups["archive"].ToString();
+                m_version = m.Groups["version"].ToString();
+                m_date    = DateTime.Parse(m.Groups["date"].ToString());
+                m_author  = m.Groups["author"].ToString();
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/JID.cs b/lib/jabber-net/jabber/JID.cs
new file mode 100644
index 0000000..c8eb336
--- /dev/null
+++ b/lib/jabber-net/jabber/JID.cs
@@ -0,0 +1,723 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Text;
+using System.Diagnostics;
+
+using bedrock.util;
+using System.Text.RegularExpressions;
+
+namespace jabber
+{
+    /// <summary>
+    /// Informs the client that an invalid JID was entered.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class JIDFormatException : ApplicationException
+    {
+        /// <summary>
+        /// Creates a new exception for an invalid JID.
+        /// </summary>
+        /// <param name="badJid">The invalid JID</param>
+        public JIDFormatException(string badJid) : base("Bad JID: (" + badJid + ")")
+        {
+        }
+
+        /// <summary>
+        /// Creates a new exception instance.
+        /// </summary>
+        public JIDFormatException() : base()
+        {
+        }
+
+        /// <summary>
+        /// Creates a new exception instance, wrapping another exception.
+        /// </summary>
+        /// <param name="badJid">Invalid JID.</param>
+        /// <param name="e">Inner exception.</param>
+        public JIDFormatException(string badJid, Exception e) : base("Bad JID: (" + badJid + ")", e)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the AsyncSocketConnectionException class with serialized data.
+        /// </summary>
+        /// <param name="info">The object that holds the serialized object data.</param>
+        /// <param name="ctx">The contextual information about the source or destination.</param>
+        protected JIDFormatException(System.Runtime.Serialization.SerializationInfo info,
+            System.Runtime.Serialization.StreamingContext ctx) :
+            base(info, ctx)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Provides simple JID management.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [System.ComponentModel.TypeConverter(typeof(JIDTypeConverter))]
+    public class JID : IComparable
+    {
+#if !NO_STRINGPREP
+        private static readonly stringprep.Profile s_nodeprep     = new stringprep.XmppNode();
+        private static readonly stringprep.Profile s_nameprep     = new stringprep.Nameprep();
+        private static readonly stringprep.Profile s_resourceprep = new stringprep.XmppResource();
+#endif
+
+        private string m_user     = null;
+        private string m_server   = null;
+        private string m_resource = null;
+        private string m_JID      = null;
+
+        /// <summary>
+        /// Creates a JID from a string.
+        /// This will parse and perform the stringprep (RFC 3454) process.
+        /// </summary>
+        /// <param name="jid">Jabber ID, in string form</param>
+        public JID(string jid)
+        {
+            Debug.Assert(jid != null, "jid must be non-null");
+            m_JID = jid;
+            parse();
+        }
+
+        /// <summary>
+        /// Builds a new JID from the given components.
+        /// This will parse and perform the stringprep (RFC 3454) process.
+        /// </summary>
+        /// <param name="user">The username value.</param>
+        /// <param name="server">The XMPP server domain value.</param>
+        /// <param name="resource">The current resource value.</param>
+        public JID(string user, string server, string resource)
+        {
+            Debug.Assert(server != null, "server must be non-null");
+
+#if !NO_STRINGPREP
+            m_user     = (user == null) ? null : s_nodeprep.Prepare(user);
+            m_server   = s_nameprep.Prepare(server);
+            m_resource = (resource == null) ? null : s_resourceprep.Prepare(resource);
+#else
+            m_user     = (user == null) ? null : user.ToLower();
+            m_server   = server.ToLower();
+            m_resource = resource;
+#endif
+            m_JID      = build(m_user, m_server, m_resource);
+
+        }
+
+        /// <summary>
+        /// Builds a new JID, from portions that are guaranteed to already be stringprep'd.
+        /// </summary>
+        /// <param name="user"></param>
+        /// <param name="server"></param>
+        /// <param name="resource"></param>
+        /// <param name="full">The full user at server/resource JID, so that it doesn't have to be recreated from the parts</param>
+        private JID(string user, string server, string resource, string full)
+        {
+            m_user = user;
+            m_server = server;
+            m_resource = resource;
+            m_JID = full;
+        }
+
+        private static string build(string user, string server, string resource)
+        {
+            Debug.Assert(server != null, "Server must be non-null");
+            StringBuilder sb = new StringBuilder();
+            if (user != null)
+            {
+                sb.Append(user);
+                sb.Append("@");
+            }
+            sb.Append(server);
+            if (resource != null)
+            {
+                sb.Append("/");
+                sb.Append(resource);
+            }
+            return sb.ToString();
+        }
+
+        private void parse()
+        {
+            if (m_server != null)
+                return; // already parsed
+
+            string user = null;
+            string server = null;
+            string resource = null;
+
+            int at = m_JID.IndexOf('@');
+            int slash = m_JID.IndexOf('/');
+
+            if (at == -1)
+            {
+                user = null;
+                if (slash == -1)
+                {
+                    server = m_JID;
+                    resource = null;
+                }
+                else
+                {
+                    server = m_JID.Substring(0, slash);
+                    resource = m_JID.Substring(slash+1);
+                }
+            }
+            else
+            {
+                if (slash == -1)
+                {
+                    user = m_JID.Substring(0, at);
+                    server = m_JID.Substring(at + 1);
+                }
+                else
+                {
+                    if (at < slash)
+                    { // normal case
+                        user = m_JID.Substring(0, at);
+                        server = m_JID.Substring(at+1, slash-at-1);
+                        resource = m_JID.Substring(slash+1);
+                    }
+                    else
+                    { // @ in a resource, with no user.  bastards.
+                        user = null;
+                        server = m_JID.Substring(0, slash);
+                        resource = m_JID.Substring(slash+1);
+                    }
+                }
+            }
+            if (user != null)
+            {
+                if (user.IndexOf('@') != -1) throw new JIDFormatException(m_JID);
+                if (user.IndexOf('/') != -1) throw new JIDFormatException(m_JID);
+            }
+
+            if ((server == null) || (server.Length == 0)) throw new JIDFormatException(m_JID);
+            if (server.IndexOf('@') != -1) throw new JIDFormatException(m_JID);
+            if (server.IndexOf('/') != -1) throw new JIDFormatException(m_JID);
+            if ((resource != null) && (resource.Length == 0)) // null is ok, but "" is not.
+                throw new JIDFormatException(m_JID);
+
+#if !NO_STRINGPREP
+            m_user = (user == null) ? null : s_nodeprep.Prepare(user);
+            m_server = s_nameprep.Prepare(server);
+            m_resource = (resource == null) ? null : s_resourceprep.Prepare(resource);
+#else
+            m_user = (user == null) ? null : user.ToLower();
+            m_server = server.ToLower();
+            m_resource = resource;
+#endif
+            // Make the case right, for fast equality comparisons
+            m_JID = build(m_user, m_server, m_resource);
+        }
+
+        /// <summary>
+        /// Gets the hash code on the string version of the JID.
+        /// </summary>
+        /// <returns>Hash code.</returns>
+        public override int GetHashCode()
+        {
+            return m_JID.GetHashCode();
+        }
+
+        /// <summary>
+        /// Returns the string representation.
+        /// </summary>
+        /// <returns>String in the form of "[user]@[server]/[resource]</returns>
+        public override string ToString()
+        {
+            return m_JID;
+        }
+
+        /// <summary>
+        /// Equality of string representations.
+        /// </summary>
+        /// <param name="other">JID or string to compare against.</param>
+        /// <returns></returns>
+        public override bool Equals(object other)
+        {
+            if (other == null)
+                return false;
+            if (other is string)
+                return m_JID.Equals(other);
+            if (! (other is JID))
+                return false;
+
+            return m_JID.Equals(((JID)other).m_JID);
+        }
+
+        /// <summary>
+        /// Determines whether two JIDs have the same value.
+        /// </summary>
+        /// <param name="one">A JID to compare.</param>
+        /// <param name="two">Another JID to compare to the first one.</param>
+        /// <returns>True if everything (user, host and resource) are the same; otherwise false.</returns>
+        public static bool operator==(JID one, JID two)
+        {
+            if ((object)one == null)
+                return ((object)two == null);
+            return one.Equals(two);
+        }
+
+        /// <summary>
+        /// Determines whether the string representation of the specified JID is equal to the current JID.
+        /// </summary>
+        /// <param name="one">This string is converted to a JID than compared to the second parameter.</param>
+        /// <param name="two">JID to compare to the first one.</param>
+        /// <returns>True if everything (user, host and resource) are the same; otherwise false.</returns>
+        public static bool operator==(string one, JID two)
+        {
+            if ((object)two == null)
+                return ((object)one == null);
+            return two.Equals(one);
+        }
+
+        /// <summary>
+        /// Determines whether the string representation of the specified JID is not equal to the current JID.
+        /// </summary>
+        /// <param name="one">This string is converted to a JID than compared to the second parameter.</param>
+        /// <param name="two">JID to compare to the first one.</param>
+        /// <returns>True if one thing (user, host or resource) is different; otherwise false.</returns>
+        public static bool operator!=(string one, JID two)
+        {
+            if ((object)two == null)
+                return ((object)one != null);
+            return !two.Equals(one);
+        }
+
+        /// <summary>
+        /// Determines whether two JIDs have different values.
+        /// </summary>
+        /// <param name="one">A JID to compare.</param>
+        /// <param name="two">Another JID to compare to the first one.</param>
+        /// <returns>True if one thing (user, host and resource) is different; otherwise false.</returns>
+        public static bool operator!=(JID one, JID two)
+        {
+            if ((object)one == null)
+                return ((object)two != null);
+            return !one.Equals(two);
+        }
+
+        /// <summary>
+        /// Converts a string to a JID implicitly (no cast needed).
+        /// </summary>
+        /// <param name="jid">String containing a JID.</param>
+        /// <returns>JID object representing the string passed in.</returns>
+        public static implicit operator JID(string jid)
+        {
+            if (jid == null)
+                return null;
+            return new JID(jid);
+        }
+
+        /// <summary>
+        /// Converts a JID to a string implicitly (no cast needed).
+        /// </summary>
+        /// <param name="jid">JID whos string representation we want.</param>
+        /// <returns>String version of the jid.</returns>
+        public static implicit operator string(JID jid)
+        {
+            if (jid == null)
+                return null;
+            return jid.m_JID;
+        }
+
+        /// <summary>
+        /// Compares two JIDs.
+        /// </summary>
+        /// <param name="left">First JID.</param>
+        /// <param name="right">Second JID.</param>
+        /// <returns>True if the first JID is less to the second; otherwise false.</returns>
+        public static bool operator<(JID left, JID right)
+        {
+            return left.CompareTo(right) == -1;
+        }
+
+        /// <summary>
+        /// Compares two JIDs.
+        /// </summary>
+        /// <param name="left">First JID.</param>
+        /// <param name="right">Second JID.</param>
+        /// <returns>True if the first JID is greater than the second; otherwise false.</returns>
+        public static bool operator>(JID left, JID right)
+        {
+            return left.CompareTo(right) == 1;
+        }
+
+        /// <summary>
+        /// Compares two JIDs.
+        /// </summary>
+        /// <param name="left">First JID.</param>
+        /// <param name="right">Second JID.</param>
+        /// <returns>True if the first JID is less than or equal to the second; otherwise false.</returns>
+        public static bool operator<=(JID left, JID right)
+        {
+            return left.CompareTo(right) != 1;
+        }
+
+        /// <summary>
+        /// Compares two JIDs.
+        /// </summary>
+        /// <param name="left">First JID.</param>
+        /// <param name="right">Second JID.</param>
+        /// <returns>True if the first JID is greater than or equal to the second; otherwise false.</returns>
+        public static bool operator>=(JID left, JID right)
+        {
+            return left.CompareTo(right) != -1;
+        }
+
+        /// <summary>
+        /// Gets and sets the username value of the JID, and returns null if it does not exist.
+        /// </summary>
+        public string User
+        {
+            get
+            {
+                parse();
+                return m_user;
+            }
+            set
+            {
+                parse();
+                m_user = value;
+                m_JID = build(m_user, m_server, m_resource);
+            }
+        }
+
+        /// <summary>
+        /// Gets and sets the XMPP server domain value.
+        /// </summary>
+        public string Server
+        {
+            get
+            {
+                parse();
+                return m_server;
+            }
+            set
+            {
+                parse();
+                m_server = value;
+                m_JID = build(m_user, m_server, m_resource);
+            }
+        }
+
+        /// <summary>
+        /// Gets and sets the resource value and returns null if it does not exist.
+        /// </summary>
+        public string Resource
+        {
+            get
+            {
+                parse();
+                return m_resource;
+            }
+            set
+            {
+                parse();
+                m_resource = value;
+                m_JID = build(m_user, m_server, m_resource);
+            }
+        }
+
+        /// <summary>
+        /// Gets the username and XMPP server domain values of the JID. For example: user at example.com
+        /// </summary>
+        public string Bare
+        {
+            get
+            {
+                parse();
+                if (m_resource == null)
+                    return m_JID;
+                return build(m_user, m_server, null);
+            }
+        }
+
+        /// <summary>
+        /// Gets the user at server JID associated with this JID, as a JID.
+        /// Slightly faster than building it yourself, since stringprep
+        /// is avoided.
+        /// </summary>
+        public JID BareJID
+        {
+            get 
+            {
+                parse();
+                if (m_resource == null)
+                    return this; // already bare
+                return new JID(m_user, m_server, null, build(m_user, m_server, null)); 
+            }
+        }
+
+
+        /// <summary>
+        /// XEP-0106 escaping.
+        /// </summary>
+        /// <returns></returns>
+        public static JID Escape(string user, string server, string resource)
+        {
+            StringBuilder sb = new StringBuilder();
+            int count = 0;
+            foreach (char c in user)
+            {
+                switch (c)
+                {
+                    case ' ':
+                        if ((count == 0) || (count == (user.Length - 1)))
+                            throw new JIDFormatException();
+                        sb.Append("\\20");
+                        break;
+                    case '"':
+                        sb.Append("\\22");
+                        break;
+                    case '&':
+                        sb.Append("\\26");
+                        break;
+                    case '\'':
+                        sb.Append("\\27");
+                        break;
+                    case '/':
+                        sb.Append("\\2f");
+                        break;
+                    case ':':
+                        sb.Append("\\3a");
+                        break;
+                    case '<':
+                        sb.Append("\\3c");
+                        break;
+                    case '>':
+                        sb.Append("\\3e");
+                        break;
+                    case '@':
+                        sb.Append("\\40");
+                        break;
+                    case '\\':
+                        sb.Append("\\5c");
+                        break;
+                    default:
+                        sb.Append(c);
+                        break;
+                }
+                count++;
+            }
+            string u = sb.ToString();
+            return new JID(u, server, resource); 
+        }
+
+        /// <summary>
+        /// Unescape the username portion of a JID, as specified in XEP-106.
+        /// </summary>
+        /// <returns></returns>
+        public string Unescape()
+        {
+            Regex re = new Regex(@"\\([2-5][0267face])");
+            string u = re.Replace(m_user, new MatchEvaluator(delegate(Match m)
+            {
+                switch (m.Groups[1].Value)
+                {
+                    case "20":
+                        return " ";
+                    case "22":
+                        return "\"";
+                    case "26":
+                        return "&";
+                    case "27":
+                        return "'";
+                    case "2f":
+                        return "/";
+                    case "3a":
+                        return ":";
+                    case "3c":
+                        return "<";
+                    case "3e":
+                        return ">";
+                    case "40":
+                        return "@";
+                    case "5c":
+                        return "\\";
+                    default:
+                        return m.Groups[0].Value;
+                }
+            }));
+            return u;
+        }
+
+        #region Implementation of IComparable
+        /// <summary>
+        /// Compares the current instance with another object of the same type.
+        /// </summary>
+        /// <param name="obj">An object to compare with this instance.</param>
+        /// <returns>A 32-bit signed integer that indicates the relative order of the comparands. The return value has these meanings:
+        /// Less than zero This instance is less than obj.
+        /// Zero This instance is equal to obj.
+        /// Greater than zero This instance is greater than obj.
+        /// </returns>
+        public int CompareTo(object obj)
+        {
+            if (obj == null)
+                return 1;
+            if (obj == (object)this)
+                return 0;
+
+            JID oj = obj as JID;
+            if (oj == null)
+                throw new ArgumentException("Comparison of JID to non-JID", "obj");
+
+            // hm.  How tricky to get?
+            // It could be that sorting by domain first is correct...
+            //return this.m_JID.CompareTo(oj.m_JID);
+            this.parse();
+            oj.parse();
+
+            int c = this.m_server.ToLower().CompareTo(oj.m_server.ToLower());
+            if (c != 0) return c;
+
+            if (this.m_user == null)
+            {
+                if (oj.m_user != null)
+                    return -1;
+            }
+            else
+            {
+                if (oj.m_user == null)
+                    return 1;
+
+                c = this.m_user.ToLower().CompareTo(oj.m_user.ToLower());
+                if (c != 0) return c;
+            }
+
+            if (this.m_resource == null)
+            {
+                return (oj.m_resource == null) ? 0 : -1;
+            }
+            return this.m_resource.CompareTo(oj.m_resource);
+        }
+        #endregion
+    }
+
+    /// <summary>
+    /// Convert a JID to and from a string, so that JIDs can be used as properties for
+    /// components, and have those properties set at design time.
+    /// </summary>
+    public class JIDTypeConverter : System.ComponentModel.TypeConverter
+    {
+        /// <summary>
+        /// Returns whether this converter can convert an object of one type to the type of this converter. 
+        /// </summary>
+        /// <param name="context"></param>
+        /// <param name="sourceType"></param>
+        /// <returns></returns>
+        public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, Type sourceType)
+        {
+            if (sourceType == null)
+            {
+                throw new ArgumentNullException("sourceType");
+            }
+            return ((sourceType == typeof(string)) || 
+                    (typeof(JID).IsAssignableFrom(sourceType) || 
+                     base.CanConvertFrom(context, sourceType)));
+        }
+
+        /// <summary>
+        /// Returns whether this converter can convert the object to the specified type. 
+        /// </summary>
+        /// <param name="context"></param>
+        /// <param name="destinationType"></param>
+        /// <returns></returns>
+        public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, Type destinationType)
+        {
+             return ((destinationType == typeof(string)) || 
+                     ((destinationType == typeof(JID)) || 
+                    base.CanConvertTo(context, destinationType)));
+        }
+
+        /// <summary>
+        /// Returns whether the given value object is valid for this type.
+        /// Empty strings are allowed, since they will map to null.
+        /// </summary>
+        /// <param name="context"></param>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        public override bool IsValid(System.ComponentModel.ITypeDescriptorContext context, object value)
+        {
+            string s = value as string;
+            JID j;
+            if (s != null)
+            {
+                if (s == "")
+                    return true;
+
+                try
+                {
+                    j = new JID(s);
+                }
+                catch (JIDFormatException)
+                {
+                    return false;
+                }
+                return true;
+            }
+            j = value as JID;
+            return (j != null);
+        }
+
+        /// <summary>
+        /// Converts the given value to the type of this converter.
+        /// Empty strings are converted to null.
+        /// </summary>
+        /// <param name="context"></param>
+        /// <param name="culture"></param>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
+        {
+            if (value == null)
+                return null;
+
+            string s = value as string;
+            if (s != null)
+            {
+                if (s == "")
+                    return null;
+                return new JID(s);
+            }
+            JID j = value as JID;
+            if (j != null)
+                return j;
+            return base.ConvertFrom(context, culture, value);
+        }
+
+        /// <summary>
+        /// Converts the given value object to the specified type.
+        /// </summary>
+        /// <param name="context"></param>
+        /// <param name="culture"></param>
+        /// <param name="value"></param>
+        /// <param name="destinationType"></param>
+        /// <returns></returns>
+        public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
+        {
+            if (value == null)
+                return null;
+            if (destinationType == typeof(string))
+                return value.ToString();
+            if (destinationType == typeof(JID))
+                return value;
+            return base.ConvertTo(context, culture, value, destinationType);
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/client/BookmarkManager.cs b/lib/jabber-net/jabber/client/BookmarkManager.cs
new file mode 100644
index 0000000..9410bca
--- /dev/null
+++ b/lib/jabber-net/jabber/client/BookmarkManager.cs
@@ -0,0 +1,293 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+
+using bedrock.util;
+using jabber.connection;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+using System.Xml;
+
+namespace jabber.client
+{
+    /// <summary>
+    /// A new conference bookmark.
+    /// </summary>
+    /// <param name="manager"></param>
+    /// <param name="conference"></param>
+    public delegate void BookmarkConferenceDelegate(BookmarkManager manager, BookmarkConference conference);
+
+    /// <summary>
+    /// Manager bookmarks on the server, with the old-style iq:private.
+    /// TODO: add support for new-style PEP.
+    /// </summary>
+    [SVN(@"$Id$")]    
+    public class BookmarkManager : jabber.connection.StreamComponent
+	{
+        private bool m_autoPrivate = true;
+        private ConferenceManager m_confManager;
+        private Dictionary<JID, BookmarkConference> m_conferences = new Dictionary<JID, BookmarkConference>();
+
+        /// <summary>
+        /// Create
+        /// </summary>
+		public BookmarkManager()
+		{
+			InitializeComponent();
+            this.OnStreamChanged += new bedrock.ObjectHandler(BookmarkManager_OnStreamChanged);
+		}
+
+        /// <summary>
+        /// Create
+        /// </summary>
+        /// <param name="container"></param>
+		public BookmarkManager(IContainer container) : this()
+		{
+			container.Add(this);
+		}
+
+        /// <summary>
+        /// Automatically request bookmarks using iq:private on login.
+        /// </summary>
+        [Category("Bookmarks")]
+        [Description("Automatically request bookmarks using iq:private on login.")]
+        [DefaultValue(true)]
+        public bool AutoPrivate
+        {
+            get { return m_autoPrivate; }
+            set { m_autoPrivate = value; }
+        }
+
+        /// <summary>
+        /// A conference bookmark has been .
+        /// </summary>
+        [Category("Bookmarks")]
+        [Description("A conference bookmark has been added to the list.")]
+        public event BookmarkConferenceDelegate OnConferenceAdd;
+
+        /// <summary>
+        /// A conference bookmark has been removed from the list.
+        /// </summary>
+        [Category("Bookmarks")]
+        [Description("A conference bookmark has been removed from the list.")]
+        public event BookmarkConferenceDelegate OnConferenceRemove;
+
+        /// <summary>
+        /// A ConferenceManager into which to auto-join conference rooms.
+        /// </summary>
+        [Category("Jabber")]
+        public ConferenceManager ConferenceManager
+        {
+            get
+            {
+                // If we are running in the designer, let's try to auto-hook a ConferenceManager
+                if ((m_confManager == null) && DesignMode)
+                {
+                    IDesignerHost host = (IDesignerHost)base.GetService(typeof(IDesignerHost));
+                    this.ConferenceManager = (ConferenceManager)jabber.connection.StreamComponent.GetComponentFromHost(host, typeof(ConferenceManager));
+                }
+                return m_confManager;
+            }
+            set
+            {
+                if ((object)m_confManager == (object)value)
+                    return;
+                m_confManager = value;
+            }
+        }
+
+        private void BookmarkManager_OnStreamChanged(object sender)
+        {
+            m_stream.OnDisconnect += new bedrock.ObjectHandler(m_stream_OnDisconnect);
+            m_stream.OnError += new bedrock.ExceptionHandler(m_stream_OnError);
+            JabberClient cli = m_stream as JabberClient;
+            if (cli == null)
+                return;
+
+            cli.OnAuthenticate += new bedrock.ObjectHandler(cli_OnAuthenticate);
+        }
+
+        private void m_stream_OnError(object sender, Exception ex)
+        {
+            m_conferences.Clear();
+        }
+
+        private void m_stream_OnDisconnect(object sender)
+        {
+            m_conferences.Clear();
+        }
+
+        private void cli_OnAuthenticate(object sender)
+        {
+            if (AutoPrivate)
+            {
+                BookmarksIQ biq = new BookmarksIQ(m_stream.Document);
+                biq.Type = IQType.get;
+                m_stream.Tracker.BeginIQ(biq, GotBookmarks, null);
+            }
+        }
+
+        private void GotBookmarks(object sender, IQ iq, object state)
+        {
+            if ((iq == null) || (iq.Type != IQType.result))
+                return;
+
+            Private priv = iq.Query as Private;
+            if (priv == null)
+                return;
+
+            Bookmarks bm = priv.GetChildElement<Bookmarks>();
+            if (bm == null)
+                return;
+
+            foreach (BookmarkConference conf in bm.GetConferences())
+            {
+                if (conf.JID == null)
+                    continue;
+
+                m_conferences[conf.JID] = conf;
+                if (OnConferenceAdd != null)
+                    OnConferenceAdd(this, conf);
+                if (conf.AutoJoin && (m_confManager != null))
+                {
+                    JID rJID = conf.JID;
+                    JID roomAndNick = new JID(rJID.User, rJID.Server, conf.Nick);
+                    Room r = m_confManager.GetRoom(roomAndNick);
+                    r.Join(conf.Password);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Get the details for the given conference bookmark.
+        /// </summary>
+        /// <param name="jid"></param>
+        /// <returns></returns>
+        public BookmarkConference this[JID jid]
+        {
+            get { return m_conferences[jid]; }
+            set
+            {
+                BookmarkConference prev = null;
+                if (value == null)
+                {
+                    if (m_conferences.TryGetValue(jid, out prev))
+                    {
+                        m_conferences.Remove(jid);
+                        prev.SetAttribute("remove", "true");
+                    }
+                    else
+                    {
+                        // no-op.  Setting null on a non-existing JID.
+                        return;
+                    }
+                }
+                else
+                {
+                    m_conferences[jid] = prev = value;
+                }
+
+                BookmarksIQ biq = new BookmarksIQ(m_stream.Document);
+                biq.Type = IQType.set;
+                Bookmarks bm = biq.Bookmarks;
+                foreach (BookmarkConference conf in m_conferences.Values)
+                {
+                    bm.AddChild((XmlElement)conf.CloneNode(true, m_stream.Document));
+                }
+                m_stream.Tracker.BeginIQ(biq, BookmarksSet, prev);
+            }
+        }
+
+        private void BookmarksSet(object sender, IQ iq, object state)
+        {
+            if ((iq == null) || (iq.Type != IQType.result))
+                return;
+
+            BookmarkConference prev = state as BookmarkConference;
+            if (prev == null)
+                return;
+
+            if (prev.GetAttribute("remove") == "true")
+            {
+                if (OnConferenceRemove != null)
+                {
+                    prev.RemoveAttribute("remove");
+                    OnConferenceRemove(this, prev);
+                }
+            }
+            else
+            {
+                if (OnConferenceAdd != null)
+                    OnConferenceAdd(this, prev);
+            }
+        }
+
+        /// <summary>
+        /// Add a conference room to the bookmark list
+        /// </summary>
+        /// <param name="jid">The room at service JID of the room</param>
+        /// <param name="name">Human-readable text</param>
+        /// <param name="autoJoin">Join on login</param>
+        /// <param name="nick">Room nickname.  May be null.</param>
+        /// <returns></returns>
+        public BookmarkConference AddConference(JID jid, string name, bool autoJoin, string nick)
+        {
+            BookmarkConference c = new BookmarkConference(m_stream.Document);
+            if (jid == null)
+                throw new ArgumentNullException("jid", "JID must not be null in a conference bookmark");
+            c.JID = jid;
+            if ((name != null) && (name != ""))
+                c.ConferenceName = name;
+            c.AutoJoin = autoJoin;
+            if ((nick != null) && (nick != ""))
+                c.Nick = nick;
+            this[jid] = c;
+            return c;
+        }
+
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Component Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            components = new System.ComponentModel.Container();
+        }
+
+        #endregion
+	}
+}
diff --git a/lib/jabber-net/jabber/client/JabberClient.bmp b/lib/jabber-net/jabber/client/JabberClient.bmp
new file mode 100644
index 0000000..3f633e8
Binary files /dev/null and b/lib/jabber-net/jabber/client/JabberClient.bmp differ
diff --git a/lib/jabber-net/jabber/client/JabberClient.cs b/lib/jabber-net/jabber/client/JabberClient.cs
new file mode 100644
index 0000000..17caad5
--- /dev/null
+++ b/lib/jabber-net/jabber/client/JabberClient.cs
@@ -0,0 +1,1031 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.ComponentModel;
+using System.Collections;
+using System.Diagnostics;
+using System.Xml;
+
+using bedrock.util;
+using bedrock.net;
+
+using jabber.connection;
+using jabber.protocol;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+using jabber.connection.sasl;
+
+namespace jabber.client
+{
+    /// <summary>
+    /// Informs the client that a presence packet has been received.
+    /// </summary>
+    public delegate void PresenceHandler(Object sender, Presence pres);
+    /// <summary>
+    /// Informst the client that a message has been received.
+    /// </summary>
+    public delegate void MessageHandler(Object sender, Message msg);
+    /// <summary>
+    /// Informs the client that an IQ has been received.
+    /// </summary>
+    public delegate void IQHandler(Object sender, IQ iq);
+    /// <summary>
+    /// Need more information for registration.  Return false to cancel.
+    /// </summary>
+    public delegate bool RegisterInfoHandler(Object sender, Register register);
+
+    /// <summary>
+    /// Provides a component for clients to use to access the XMPP server.
+    /// You can install this in your Toolbox, drop onto a form, a service, and so on.
+    /// This class hooks into the OnProtocol event and calls the Connect() method.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class JabberClient : XmppStream
+    {
+        private static readonly object[][] DEFAULTS = new object[][] {
+            new object[] {Options.RESOURCE, "Jabber.Net"},
+            new object[] {Options.PRIORITY, 0},
+            new object[] {Options.AUTO_LOGIN, true},
+            new object[] {Options.AUTO_ROSTER, true},
+            new object[] {Options.AUTO_IQ_ERRORS, true},
+            new object[] {Options.AUTO_PRESENCE, true},
+            new object[] {Options.PROXY_PORT, 1080},
+            new object[] {Options.SRV_PREFIX, "_xmpp-client._tcp."},
+        };
+
+        private void init()
+        {
+            SetDefaults(DEFAULTS);
+
+            this.OnSASLStart += new jabber.connection.sasl.SASLProcessorHandler(JabberClient_OnSASLStart);
+            this.OnSASLEnd += new jabber.protocol.stream.FeaturesHandler(JabberClient_OnSASLEnd);
+            this.OnSASLError += new ProtocolHandler(JabberClient_OnSASLError);
+            this.OnStreamInit += new StreamHandler(JabberClient_OnStreamInit);
+        }
+
+        /// <summary>
+        /// Creates a new Jabber client and associates it with the parent window.
+        /// Required for Windows.Forms Class Composition Designer support
+        /// </summary>
+        /// <param name="container">Parent container.</param>
+        public JabberClient(System.ComponentModel.IContainer container) :
+            base(container)
+        {
+            init();
+        }
+
+        /// <summary>
+        /// Creates a new JabberClient.
+        /// Required for Windows.Forms Class Composition Designer support.
+        /// </summary>
+        public JabberClient() : base()
+        {
+            init();
+        }
+
+        /*
+        /// <summary>
+        /// Create a new JabberClient, reusing an existing SocketWatcher.
+        /// </summary>
+        /// <param name="watcher">SocketWatcher to use.</param>
+        public JabberClient(SocketWatcher watcher) : base(watcher)
+        {
+            init();
+        }
+        */
+
+        /// <summary>
+        /// Informs the client that it received a presence packet.
+        /// </summary>
+        [Category("Protocol")]
+        [Description("We received a presence packet.")]
+        public event PresenceHandler OnPresence;
+
+        /// <summary>
+        /// Informs the client that it received a message packet.
+        /// </summary>
+        [Category("Protocol")]
+        [Description("We received a message packet.")]
+        public event MessageHandler OnMessage;
+
+        /// <summary>
+        /// Informs the client that it received an IQ packet.
+        /// </summary>
+        [Category("Protocol")]
+        [Description("We received an IQ packet.")]
+        public event IQHandler OnIQ;
+
+        /// <summary>
+        /// Informs the client that the authentication has failed. The connection is not
+        /// terminated if there is an authentication error, and there
+        /// is at least one event handler for this event.
+        /// </summary>
+        [Category("Protocol")]
+        [Description("Authentication failed.")]
+        public event ProtocolHandler OnAuthError;
+
+        /// <summary>
+        /// Informs the client that the presence is about to be sent.
+        /// This gives a chance to modify outbound presence (fore example, entity caps).
+        /// </summary>
+        [Category("Protocol")]
+        [Description("Presence is about to be sent.  This gives a chance to modify outbound presence (e.g. entity caps)")]
+        public event PresenceHandler OnBeforePresenceOut;
+
+        /// <summary>
+        /// Informs the client that the presence has been sent.
+        /// This gives a chance to send presence to other things, such as chat rooms.
+        /// </summary>
+        [Category("Protocol")]
+        [Description("Informs the client that the presence has been sent.  This gives a chance to send presence to other things, such as chat rooms.")]
+        public event PresenceHandler OnAfterPresenceOut;
+
+        /// <summary>
+        /// Determines if SutoLogin is false, and if it is time to log in.
+        /// This callback will receive the results of the IQ type=get
+        /// in the jabber:iq:auth namespace.  When login is completed,
+        /// IsConnected property is set to true.  If there is a login error, the
+        /// FireAuthError() method is called.
+        /// </summary>
+        [Category("Protocol")]
+        [Description("AutoLogin is false, and it's time to log in.")]
+        public event bedrock.ObjectHandler OnLoginRequired;
+
+        /// <summary>
+        /// Informs the client if the registration succeeded or failed.
+        /// </summary>
+        [Category("Protocol")]
+        [Description("After calling Register(), the registration succeeded or failed.")]
+        public event IQHandler OnRegistered;
+
+        /// <summary>
+        /// Allows the user to enter registration requested information before sending to the XMPP server.
+        ///
+        /// WARNING: Make sure you do not return from this handler until the IQ is filled in.
+        /// It is now safe to call UI elements, since this callback is now on the GUI thread if
+        /// the InvokeControl is set.
+        /// </summary>
+        [Category("Protocol")]
+        [Description("After calling Register, information about the user is required.")]
+        public event RegisterInfoHandler OnRegisterInfo;
+
+        /// <summary>
+        /// Retrieves/Sets the username to connect as.
+        /// </summary>
+        [Description("The username to connect as.")]
+        [Category("Jabber")]
+        public string User
+        {
+            get { return this[Options.USER] as string; }
+            set { this[Options.USER] = value; }
+        }
+
+        /// <summary>
+        /// Gets the priority for this connection.
+        /// </summary>
+        [Description("Priority for this connection.")]
+        [Category("Jabber")]
+        [DefaultValue(0)]
+        public int Priority
+        {
+            get { return (int)this[Options.PRIORITY]; }
+            set { this[Options.PRIORITY] = value; }
+        }
+
+        /// <summary>
+        /// Gets or sets the password to use for connecting to the XMPP server.
+        /// This may be sent across the wire plaintext if the XMPP
+        /// server doesn't support digest and PlaintextAuth is set to true.
+        /// </summary>
+        [Description("The password to use for connecting.  " +
+             "This may be sent across the wire plaintext, " +
+             "if the server doesn't support digest, " +
+             "and PlaintextAuth is true")]
+        [Category("Jabber")]
+        [PasswordPropertyText]
+        public string Password
+        {
+            get { return this[Options.PASSWORD] as string; }
+            set { this[Options.PASSWORD] = value; }
+        }
+
+        /// <summary>
+        /// Allows auto-login to be used for the connection to the XMPP server if set to true.
+        /// </summary>
+        [Description("Automatically log in on connection.")]
+        [DefaultValue(true)]
+        [Category("Automation")]
+        public bool AutoLogin
+        {
+            get { return (bool)this[Options.AUTO_LOGIN]; }
+            set { this[Options.AUTO_LOGIN] = value; }
+        }
+
+        /// <summary>
+        /// Retrieves the roster on connection.
+        /// </summary>
+        [Description("Retrieves the roster on connection.")]
+        [DefaultValue(true)]
+        [Category("Automation")]
+        public bool AutoRoster
+        {
+            get { return (bool)this[Options.AUTO_ROSTER]; }
+            set { this[Options.AUTO_ROSTER] = value; }
+        }
+
+        /// <summary>
+        /// Sends 501/feature-not-implemented back to the client when an IQ
+        /// has not been handled if set to true.
+        /// </summary>
+        [Description("Automatically send back 501/feature-not-implemented to IQs that have not been handled.")]
+        [DefaultValue(true)]
+        [Category("Automation")]
+        public bool AutoIQErrors
+        {
+            get { return (bool)this[Options.AUTO_IQ_ERRORS]; }
+            set { this[Options.AUTO_IQ_ERRORS] = value; }
+        }
+
+        /// <summary>
+        /// Sends presence information when the connection has been established
+        /// if set to true.
+        /// </summary>
+        [Description("Automatically send presence on connection.")]
+        [DefaultValue(true)]
+        [Category("Automation")]
+        public bool AutoPresence
+        {
+            get { return (bool)this[Options.AUTO_PRESENCE]; }
+            set { this[Options.AUTO_PRESENCE] = value; }
+        }
+
+        /// <summary>
+        /// Gets or sets the connecting resource.
+        /// Used to identify a unique connection.
+        /// </summary>
+        [Description("Gets or sets the connecting resource.  " +
+             "Used to identify a unique connection.")]
+        [DefaultValue("Jabber.Net")]
+        [Category("Jabber")]
+        public string Resource
+        {
+            get { return this[Options.RESOURCE] as string; }
+            set { this[Options.RESOURCE] = value; }
+        }
+
+        /// <summary>
+        /// Gets the stream namespace for this connection.
+        /// </summary>
+        [Browsable(false)]
+        protected override string NS
+        {
+            get { return URI.CLIENT; }
+        }
+
+        /// <summary>
+        /// Are we currently connected?
+        /// </summary>
+        [Browsable(false)]
+        [DefaultValue(false)]
+        public override bool IsAuthenticated
+        {
+            get { return base.IsAuthenticated; }
+            set
+            {
+                base.IsAuthenticated = value;
+                if (value)
+                {
+                    if (AutoRoster)
+                        GetRoster();
+                    if (AutoPresence)
+                        Presence(PresenceType.available,
+                            "online", null, Priority);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Connects to the XMPP server.  This happens asynchronously, and
+        /// could take a couple of seconds to get the full handshake
+        /// completed.  This will authenticate, send presence, and request
+        /// roster info, if the Auto* properties are set.
+        /// </summary>
+        public override void Connect()
+        {
+            this[Options.AUTO_LOGIN_THISPASS] = this[Options.AUTO_LOGIN];
+            this[Options.SERVER_ID] = this[Options.TO];
+            base.Connect();
+        }
+
+        /// <summary>
+        /// Closes down the connection.
+        /// </summary>
+        public override void Close()
+        {
+            if (IsAuthenticated)
+            {
+                Presence p = new Presence(Document);
+                p.Type = PresenceType.unavailable;
+                p.Status = "offline";
+                Write(p);
+            }
+            base.Close();
+        }
+
+        /// <summary>
+        /// Initiates the authentication process.
+        /// </summary>
+        public void Login()
+        {
+            Debug.Assert(User != null, "Username must not be null for XEP-78 authentication");
+            Debug.Assert(Password != null, "Password must not be null for XEP-78 authentication");
+            Debug.Assert(Resource != null, "Resource must not be null for XEP-78 authentication");
+
+            this[Options.AUTO_LOGIN_THISPASS] = true;
+
+            if (State == ManualSASLLoginState.Instance)
+            {
+                ProcessFeatures();
+                return;
+            }
+
+            this[Options.JID] = new JID(User, Server, Resource);
+
+            AuthIQ aiq = new AuthIQ(Document);
+            aiq.Type = IQType.get;
+            Auth a = aiq.Instruction;
+            a.Username = User;
+
+            lock (StateLock)
+            {
+                State = GetAuthState.Instance;
+            }
+            Tracker.BeginIQ(aiq, new IqCB(OnGetAuth), null);
+        }
+
+        /// <summary>
+        /// Sends a presence packet to the XMPP server.
+        /// </summary>
+        /// <param name="t">The type of presence.</param>
+        /// <param name="status">Determines the status of the presence.</param>
+        /// <param name="show">Shows the available, away, dnd and so on status.</param>
+        /// <param name="priority">Prioritizes this connection.
+        /// Higher number mean higher priority. 0 minumum, 127 max.
+        /// -1 means this is a presence-only connection.</param>
+        public void Presence(PresenceType t,
+            string status,
+            string show,
+            int priority)
+        {
+            if (IsAuthenticated)
+            {
+                if ((priority < -128) || (priority > 127))
+                {
+                    throw new ArgumentException("Priority must be -128 to 127", "priority");
+                }
+
+                Presence p = new Presence(Document);
+                if (status != null)
+                    p.Status = status;
+                if (t != PresenceType.available)
+                {
+                    p.Type = t;
+                }
+                if (show != null)
+                    p.Show = show;
+                p.Priority = priority.ToString();
+
+                if (OnBeforePresenceOut != null)
+                    OnBeforePresenceOut(this, p);
+                Write(p);
+                if (OnAfterPresenceOut != null)
+                    OnAfterPresenceOut(this, p);
+            }
+            else
+            {
+                throw new InvalidOperationException("Client must be authenticated before sending presence.");
+            }
+        }
+
+        /// <summary>
+        /// Sends a certain type of message packet to another user.
+        /// </summary>
+        /// <param name="t">The type of message.</param>
+        /// <param name="to">The JID to send the message to.</param>
+        /// <param name="body">The body of the message.</param>
+        public void Message(MessageType t,
+            string to,
+            string body)
+        {
+            if (IsAuthenticated)
+            {
+                Message msg = new Message(Document);
+                msg.Type = t;
+                msg.To = to;
+                msg.Body = body;
+                Write(msg);
+            }
+            else
+            {
+                throw new InvalidOperationException("Client must be authenticated before sending messages.");
+            }
+        }
+
+        /// <summary>
+        /// Sends a message packet to another user
+        /// </summary>
+        /// <param name="to">The JID to send the message to.</param>
+        /// <param name="body">The body of the message.</param>
+        public void Message(
+            string to,
+            string body)
+        {
+            Message(MessageType.chat, to, body);
+        }
+
+        /// <summary>
+        /// Requests a new copy of the roster.
+        /// </summary>
+        public void GetRoster()
+        {
+            if (IsAuthenticated)
+            {
+                RosterIQ riq = new RosterIQ(Document);
+                riq.Type = IQType.get;
+                Write(riq);
+            }
+            else
+            {
+                throw new InvalidOperationException("Client must be authenticated before getting roster.");
+            }
+        }
+
+
+        /// <summary>
+        /// Sends a presence subscription request and updates the roster
+        /// for a new roster contact.
+        /// </summary>
+        /// <param name="to">The JID of the contact (required)</param>
+        /// <param name="nickname">The nickname to show for the contact.</param>
+        /// <param name="groups">A list of groups to put the contact in.  May be null.  Hint: new string[] {"foo", "bar"}</param>
+        public void Subscribe(JID to, string nickname, string[] groups)
+        {
+            Debug.Assert(to != null);
+
+            RosterIQ riq = new RosterIQ(Document);
+            riq.Type = IQType.set;
+            Roster r = riq.Instruction;
+            Item i = r.AddItem();
+            i.JID = to;
+            if (nickname != null)
+                i.Nickname = nickname;
+            if (groups != null)
+            {
+                foreach (string g in groups)
+                    i.AddGroup(g);
+            }
+            Write(riq); // don't care about result.  we should get a iq/response and a roster push.
+
+            Presence pres = new Presence(Document);
+            pres.To = to;
+            pres.Type = PresenceType.subscribe;
+            Write(pres);
+        }
+
+        /// <summary>
+        /// Removes a contact from the roster.
+        /// This will also remove the subscription for that contact being removed.
+        /// </summary>
+        /// <param name="to">The JID to remove</param>
+        public void RemoveRosterItem(JID to)
+        {
+            Debug.Assert(to != null);
+
+/*
+<iq from='juliet at example.com/balcony' type='set' id='roster_4'>
+  <query xmlns='jabber:iq:roster'>
+    <item jid='nurse at example.com' subscription='remove'/>
+  </query>
+</iq>
+ */
+            RosterIQ riq = new RosterIQ(Document);
+            riq.Type = IQType.set;
+            Roster r = riq.Instruction;
+            Item i = r.AddItem();
+            i.JID = to;
+            i.Subscription = Subscription.remove;
+            Write(riq); // don't care about result.  we should get a iq/response and a roster push.
+        }
+
+        /// <summary>
+        /// Requests a list of agents from the XMPP server.
+        /// </summary>
+        public void GetAgents()
+        {
+            DiscoInfoIQ diq = new DiscoInfoIQ(Document);
+            diq.Type = IQType.get;
+            diq.To = this.Server;
+            Tracker.BeginIQ(diq, new IqCB(GotDiscoInfo), null);
+        }
+
+        private void GotDiscoInfo(object sender, IQ iq, object state)
+        {
+            bool error = false;
+            if (iq.Type == IQType.error)
+                error = true;
+            else
+            {
+                DiscoInfo info = iq.Query as DiscoInfo;
+                if (info == null)
+                    error = true;
+                else
+                {
+                    if (!info.HasFeature(URI.DISCO_ITEMS))
+                        error = true;  // wow.  weird server.
+
+                    // TODO: stash away features for this node in discomanager?
+                }
+            }
+
+            if (error)
+            {
+                // TODO: check the error type that jabberd1.4 or XCP 2.x return
+            }
+        }
+
+
+        /// <summary>
+        /// Attempts to register a new user.  This will fire
+        /// OnRegisterInfo to retrieve information about the
+        /// new user, and OnRegistered when the registration
+        /// is completed or failed.
+        /// </summary>
+        /// <param name="jid">The user to register.</param>
+        public void Register(JID jid)
+        {
+            RegisterIQ iq = new RegisterIQ(Document);
+            Register reg = iq.Instruction;
+            iq.Type = IQType.get;
+            iq.To = jid.Server;
+
+            reg.Username = jid.User;
+            Tracker.BeginIQ(iq, new IqCB(OnGetRegister), jid);
+        }
+
+        private void OnGetRegister(object sender, IQ iq, object data)
+        {
+            if (iq == null)
+            {
+                FireOnError(new IQTimeoutException((JID) data));
+                return;
+            }
+
+            if (iq.Type == IQType.error)
+            {
+                if (OnRegistered != null)
+                {
+                    if (InvokeRequired)
+                        CheckedInvoke(OnRegistered, new object[] {this, iq});
+                    else
+                        OnRegistered(this, iq);
+                }
+            }
+            else if (iq.Type == IQType.result)
+            {
+                JID jid = (JID) data;
+                iq.Type = IQType.set;
+                iq.From = null;
+                iq.To = jid.Server;
+                iq.ID = Element.NextID();
+                Register r = iq.Query as Register;
+                if (r == null)
+                    throw new BadProtocolException(iq, "Expected a register response");
+
+                jabber.protocol.x.Data xdata = r["x", URI.XDATA] as jabber.protocol.x.Data;
+                jabber.protocol.x.Field f;
+                if (xdata != null)
+                {
+                    f = xdata.GetField("username");
+                    if (f != null)
+                        f.Val = jid.User;
+                    f = xdata.GetField("password");
+                    if (f != null)
+                        f.Val = this.Password;
+                }
+                else
+                {
+                    r.Username = jid.User;
+                    r.Password = this.Password;
+                }
+
+                bool res = true;
+                if (OnRegisterInfo != null)
+                {
+                    if (InvokeRequired)
+                        // Don't use CheckedInvoke, since we want this to be synchronous
+                        res = (bool)this.InvokeControl.Invoke(OnRegisterInfo, new object[] { this, r });
+                    else
+                        res = OnRegisterInfo(this, r);
+                    if (xdata != null)
+                    {
+                        f = xdata.GetField("username");
+                        if (f != null)
+                        {
+                            this.User = f.Val;
+                        }
+                        f = xdata.GetField("password");
+                        if (f != null)
+                            this.Password = f.Val;
+                    }
+                    else
+                    {
+                        this.User = r.Username;
+                        this.Password = r.Password;
+                    }
+                }
+                if (!res)
+                {
+                    this.Close();
+                    return;
+                }
+                if (xdata != null)
+                    xdata.Type = jabber.protocol.x.XDataType.result;
+                Tracker.BeginIQ(iq, new IqCB(OnSetRegister), jid);
+            }
+        }
+
+        private void OnSetRegister(object sender, IQ iq, object data)
+        {
+            if (OnRegistered == null)
+                return;
+
+            if (InvokeRequired)
+                CheckedInvoke(OnRegistered, new object[] {this, iq});
+            else
+                OnRegistered(this, iq);
+        }
+
+        private void OnGetAuth(object sender, IQ i, object data)
+        {
+            if ((i == null) || (i.Type != IQType.result))
+            {
+                FireAuthError(i);
+                return;
+            }
+
+            Auth res = i.Query as Auth;
+            if (res == null)
+            {
+                FireOnError(new InvalidOperationException("Invalid IQ result type"));
+                return;
+            }
+
+            AuthIQ aiq = new AuthIQ(Document);
+            aiq.Type = IQType.set;
+            Auth a = aiq.Instruction;
+
+            if ((res["sequence"] != null) && (res["token"] != null))
+            {
+                a.SetZeroK(User, Password, res.Token, res.Sequence);
+            }
+            else if (res["digest"] != null)
+            {
+                a.SetDigest(User, Password, StreamID);
+            }
+            else if (res["password"] != null)
+            {
+                if (!SSLon && !this.PlaintextAuth)
+                {
+                    FireOnError(new AuthenticationFailedException("Plaintext authentication forbidden."));
+                    return;
+                }
+                a.SetAuth(User, Password);
+            }
+            else
+            {
+                FireOnError(new NotImplementedException("Authentication method not implemented for:\n" + i));
+                return;
+            }
+            if (res["resource"] != null)
+                a.Resource = Resource;
+            a.Username = User;
+
+            lock (StateLock)
+            {
+                State = SetAuthState.Instance;
+            }
+            Tracker.BeginIQ(aiq, new IqCB(OnSetAuth), null);
+        }
+
+        private void OnSetAuth(object sender, IQ i, object data)
+        {
+            if ((i == null) || (i.Type != IQType.result))
+                FireAuthError(i);
+            else
+                IsAuthenticated = true;
+        }
+
+        /// <summary>
+        /// Sorts the XML element looking for Presence, Message, and IQ packets.
+        /// </summary>
+        /// <param name="sender">The object calling this method.</param>
+        /// <param name="tag">The XML element containing a stanza.</param>
+        protected override void OnElement(object sender, System.Xml.XmlElement tag)
+        {
+            base.OnElement(sender, tag);
+
+            if (OnPresence != null)
+            {
+                Presence p = tag as Presence;
+                if (p != null)
+                {
+                    if (InvokeRequired)
+                        CheckedInvoke(OnPresence, new object[] {this, p});
+                    else
+                        OnPresence(this, p);
+                    return;
+                }
+            }
+            if (OnMessage != null)
+            {
+                Message m = tag as Message;
+                if (m != null)
+                {
+                    if (InvokeRequired)
+                        CheckedInvoke(OnMessage, new object[] {this, m});
+                    else
+                        OnMessage(this, m);
+                    return;
+                }
+            }
+
+            IQ i = tag as IQ;
+            if (i != null)
+            {
+                if (InvokeRequired)
+                    CheckedInvoke(new IQHandler(FireOnIQ) , new object[] { this, i });
+                else
+                    FireOnIQ(this, i);
+                return;
+            }
+        }
+
+        private void FireOnIQ(object sender, IQ iq)
+        {
+            // We know we're on the GUI thread.
+            if (OnIQ != null)
+                OnIQ(this, iq);
+
+            if (AutoIQErrors)
+            {
+                if (!iq.Handled &&
+                    iq.HasAttribute("from") &&   // Belt.  Suspenders.  Don't respond to roster pushes.
+                    ((iq.Type == IQType.get) || (iq.Type == IQType.set)))
+                {
+                    Write(iq.GetErrorResponse(this.Document, Error.FEATURE_NOT_IMPLEMENTED));
+                }
+            }
+        }
+
+        /// <summary>
+        /// Informs the client that an error occurred during authentication.
+        /// This is public so that manual authenticators
+        /// can fire errors using the same events.
+        /// </summary>
+        /// <param name="i">Xml element containing the error message.</param>
+        public void FireAuthError(XmlElement i)
+        {
+            if (OnAuthError != null)
+            {
+                if (InvokeRequired)
+                    CheckedInvoke(OnAuthError, new object[] { this, i });
+                else
+                    OnAuthError(this, i);
+            }
+            else
+            {
+                IQ iq = i as IQ;
+                if (iq != null)
+                    FireOnError(new IQException(iq));
+                else
+                    FireOnError(new AuthenticationFailedException(i.OuterXml));
+            }
+        }
+
+        void JabberClient_OnSASLError(object sender, XmlElement rp)
+        {
+            FireAuthError(rp);
+        }
+
+        private void LoginRequired(BaseState newState)
+        {
+            lock (StateLock)
+            {
+                State = newState;
+            }
+
+            if (OnLoginRequired != null)
+            {
+                if (InvokeRequired)
+                    CheckedInvoke(OnLoginRequired, new object[] { this });
+                else
+                    OnLoginRequired(this);
+            }
+            else
+            {
+                FireOnError(new InvalidOperationException("If AutoLogin is false, you must supply a OnLoginRequired event handler"));
+            }
+        }
+
+        private void JabberClient_OnSASLStart(Object sender, jabber.connection.sasl.SASLProcessor proc)
+        {
+            BaseState s = null;
+            lock (StateLock)
+            {
+                s = State;
+            }
+
+            // HACK: fire OnSASLStart with state of NonSASLAuthState to initiate old-style auth.
+            if (s == NonSASLAuthState.Instance)
+            {
+                if ((bool)this[Options.AUTO_LOGIN_THISPASS])
+                    Login();
+                else
+                    LoginRequired(ManualLoginState.Instance);
+            }
+            else
+            {
+                if ((bool)this[Options.AUTO_LOGIN_THISPASS])
+                {
+                    // TODO: integrate SASL params into XmppStream params
+                    proc[SASLProcessor.USERNAME] = User;
+                    proc[SASLProcessor.PASSWORD] = Password;
+                    proc[MD5Processor.REALM] = this.Server;
+                    object creds = this[KerbProcessor.USE_WINDOWS_CREDS];
+                    if (creds == null)
+                        creds = false;
+                    proc[KerbProcessor.USE_WINDOWS_CREDS] = creds.ToString();
+                }
+                else
+                {
+                    LoginRequired(ManualSASLLoginState.Instance);
+                }
+            }
+        }
+
+        private void JabberClient_OnSASLEnd(Object sender, jabber.protocol.stream.Features feat)
+        {
+            lock (StateLock)
+            {
+                State = BindState.Instance;
+            }
+            if (feat["bind", URI.BIND] != null)
+            {
+                IQ iq = new IQ(this.Document);
+                iq.Type = IQType.set;
+
+                jabber.protocol.stream.Bind bind = new jabber.protocol.stream.Bind(this.Document);
+                if ((Resource != null) && (Resource != ""))
+                    bind.Resource = Resource;
+
+                iq.AddChild(bind);
+                this.Tracker.BeginIQ(iq, new IqCB(GotResource), feat);
+            }
+            else if (feat["session", URI.SESSION] != null)
+            {
+                IQ iq = new IQ(this.Document);
+                iq.Type = IQType.set;
+                iq.AddChild(new jabber.protocol.stream.Session(this.Document));
+                this.Tracker.BeginIQ(iq, new IqCB(GotSession), feat);
+            }
+            else
+                IsAuthenticated = true;
+        }
+
+        private void GotResource(object sender, IQ iq, object state)
+        {
+
+            jabber.protocol.stream.Features feat =
+                state as jabber.protocol.stream.Features;
+
+            if (iq == null)
+            {
+                FireOnError(new AuthenticationFailedException("Timeout authenticating"));
+                return;
+            }
+            if (iq.Type != IQType.result)
+            {
+                Error err = iq.Error;
+                if (err == null)
+                    FireOnError(new AuthenticationFailedException("Unknown error binding resource"));
+                else
+                    FireOnError(new AuthenticationFailedException("Error binding resource: " + err.OuterXml));
+                return;
+            }
+
+            XmlElement bind = iq["bind", URI.BIND];
+            if (bind == null)
+            {
+                FireOnError(new AuthenticationFailedException("No binding returned.  Server implementation error."));
+                return;
+            }
+            XmlElement jid = bind["jid"];
+            if (jid == null)
+            {
+                FireOnError(new AuthenticationFailedException("No jid returned from binding.  Server implementation error."));
+                return;
+            }
+            this[Options.JID] = new JID(jid.InnerText);
+
+            if (feat["session", URI.SESSION] != null)
+            {
+                IQ iqs = new IQ(this.Document);
+                iqs.Type = IQType.set;
+                iqs.AddChild(new jabber.protocol.stream.Session(this.Document));
+                this.Tracker.BeginIQ(iqs, new IqCB(GotSession), feat);
+            }
+            else
+                IsAuthenticated = true;
+        }
+
+        private void GotSession(object sender, IQ iq, object state)
+        {
+            if ((iq != null) && (iq.Type == IQType.result))
+                IsAuthenticated = true;
+            else
+                FireOnError(new AuthenticationFailedException());
+        }
+
+        private void JabberClient_OnStreamInit(Object sender, ElementStream stream)
+        {
+            stream.AddFactory(new jabber.protocol.client.Factory());
+            stream.AddFactory(new jabber.protocol.iq.Factory());
+            stream.AddFactory(new jabber.protocol.x.Factory());
+
+        }
+    }
+
+    /// <summary>
+    /// Contains the "Getting authorization" information.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class GetAuthState : jabber.connection.BaseState
+    {
+        /// <summary>
+        /// Gets the instance that is always used.
+        /// </summary>
+        public static readonly jabber.connection.BaseState Instance = new GetAuthState();
+    }
+
+    /// <summary>
+    /// Contains the "Setting authorization" information.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class SetAuthState : jabber.connection.BaseState
+    {
+        /// <summary>
+        /// Gets the instance that is always used.
+        /// </summary>
+        public static readonly jabber.connection.BaseState Instance = new SetAuthState();
+    }
+
+    /// <summary>
+    /// Informs the client that the JabberClient is in
+    /// the "Waiting for manual login" state.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ManualLoginState : jabber.connection.BaseState
+    {
+        /// <summary>
+        /// Gets the instance that is always used.
+        /// </summary>
+        public static readonly jabber.connection.BaseState Instance = new ManualLoginState();
+    }
+
+    /// <summary>
+    /// Informs the client that the JabberClient is in
+    /// the "Waiting for manual login" state, but when Login()
+    /// happens, it should try SASL.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ManualSASLLoginState : jabber.connection.BaseState
+    {
+        /// <summary>
+        /// Gets the instance that is always used.
+        /// </summary>
+        public static readonly jabber.connection.BaseState Instance = new ManualSASLLoginState();
+    }
+
+}
diff --git a/lib/jabber-net/jabber/client/JabberClient.resx b/lib/jabber-net/jabber/client/JabberClient.resx
new file mode 100644
index 0000000..8689d66
--- /dev/null
+++ b/lib/jabber-net/jabber/client/JabberClient.resx
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<root>
+    <!-- 
+            Microsoft ResX Schema 
+        
+            Version 1.3
+                
+            The primary goals of this format is to allow a simple XML format 
+            that is mostly human readable. The generation and parsing of the 
+            various data types are done through the TypeConverter classes 
+            associated with the data types.
+        
+            Example:
+        
+                ... ado.net/XML headers & schema ...
+                <resheader name="resmimetype">text/microsoft-resx</resheader>
+                <resheader name="version">1.3</resheader>
+                <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+                <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+                <data name="Name1">this is my long string</data>
+                <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+                <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+                    [base64 mime encoded serialized .NET Framework object]
+                </data>
+                <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+                    [base64 mime encoded string representing a byte array form of the .NET Framework object]
+                </data>
+        
+            There are any number of "resheader" rows that contain simple 
+            name/value pairs.
+            
+            Each data row contains a name, and value. The row also contains a 
+            type or mimetype. Type corresponds to a .NET class that support 
+            text/value conversion through the TypeConverter architecture. 
+            Classes that don't support this are serialized and stored with the 
+            mimetype set.
+                     
+            The mimetype is used for serialized objects, and tells the 
+            ResXResourceReader how to depersist the object. This is currently not 
+            extensible. For a given mimetype the value must be set accordingly:
+        
+            Note - application/x-microsoft.net.object.binary.base64 is the format 
+                   that the ResXResourceWriter will generate, however the reader can 
+                   read any of the formats listed below.
+        
+            mimetype: application/x-microsoft.net.object.binary.base64
+            value   : The object must be serialized with 
+                    : System.Serialization.Formatters.Binary.BinaryFormatter
+                    : and then encoded with base64 encoding.
+        
+            mimetype: application/x-microsoft.net.object.soap.base64
+            value   : The object must be serialized with 
+                    : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+                    : and then encoded with base64 encoding.
+            mimetype: application/x-microsoft.net.object.bytearray.base64
+            value   : The object must be serialized into a byte array 
+                    : using a System.ComponentModel.TypeConverter
+                    : and then encoded with base64 encoding.
+        -->
+    <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+        <xsd:element name="root" msdata:IsDataSet="true">
+            <xsd:complexType>
+                <xsd:choice maxOccurs="unbounded">
+                    <xsd:element name="data">
+                        <xsd:complexType>
+                            <xsd:sequence>
+                                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+                            </xsd:sequence>
+                            <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+                            <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+                            <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+                        </xsd:complexType>
+                    </xsd:element>
+                    <xsd:element name="resheader">
+                        <xsd:complexType>
+                            <xsd:sequence>
+                                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                            </xsd:sequence>
+                            <xsd:attribute name="name" type="xsd:string" use="required" />
+                        </xsd:complexType>
+                    </xsd:element>
+                </xsd:choice>
+            </xsd:complexType>
+        </xsd:element>
+    </xsd:schema>
+    <resheader name="resmimetype">
+        <value>text/microsoft-resx</value>
+    </resheader>
+    <resheader name="version">
+        <value>1.3</value>
+    </resheader>
+    <resheader name="reader">
+        <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    </resheader>
+    <resheader name="writer">
+        <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    </resheader>
+    <data name="$this.Name">
+        <value>JabberClient</value>
+    </data>
+    <data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+        <value>False</value>
+    </data>
+</root>
\ No newline at end of file
diff --git a/lib/jabber-net/jabber/client/PresenceManager.bmp b/lib/jabber-net/jabber/client/PresenceManager.bmp
new file mode 100644
index 0000000..9949a2f
Binary files /dev/null and b/lib/jabber-net/jabber/client/PresenceManager.bmp differ
diff --git a/lib/jabber-net/jabber/client/PresenceManager.cs b/lib/jabber-net/jabber/client/PresenceManager.cs
new file mode 100644
index 0000000..190bdd7
--- /dev/null
+++ b/lib/jabber-net/jabber/client/PresenceManager.cs
@@ -0,0 +1,566 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Collections;
+using gen = System.Collections.Generic;
+using System.Diagnostics;
+
+using bedrock.util;
+using bedrock.collections;
+
+using jabber.protocol.client;
+using jabber.protocol.x;
+using jabber.protocol.iq;
+using jabber.connection;
+
+namespace jabber.client
+{
+
+    /// <summary>
+    /// Informs the client of a change of derived primary session for a user.
+    /// </summary>
+    /// <param name="sender">The PresenceManager object that sent the update</param>
+    /// <param name="bare">The bare JID (node at domain) of the user whose presence changed</param>
+    public delegate void PrimarySessionHandler(object sender, JID bare);
+
+    /// <summary>
+    /// Specifies the presence proxy database.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PresenceManager : jabber.connection.StreamComponent, IEnumerable
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+#pragma warning disable 0414
+        private System.ComponentModel.Container components = null;
+#pragma warning restore 0414
+ 
+        private Tree m_items = new Tree();
+        private CapsManager m_caps = null;
+
+        /// <summary>
+        /// Constructs a PresenceManager object and adds it to a container.
+        /// </summary>
+        /// <param name="container">Parent container.</param>
+        public PresenceManager(System.ComponentModel.IContainer container) : this()
+        {
+            container.Add(this);
+        }
+
+        /// <summary>
+        /// Constructs a new PresenceManager object.
+        /// </summary>
+        public PresenceManager()
+        {
+            InitializeComponent();
+
+            this.OnStreamChanged += new bedrock.ObjectHandler(PresenceManager_OnStreamChanged);
+        }
+
+        private void PresenceManager_OnStreamChanged(object sender)
+        {
+            JabberClient cli = m_stream as JabberClient;
+            if (cli == null)
+                return;
+
+            cli.OnPresence += new PresenceHandler(GotPresence);
+            cli.OnDisconnect += new bedrock.ObjectHandler(GotDisconnect);
+        }
+
+        /// <summary>
+        /// Gets or sets the JabberClient associated with the Presence Manager.
+        /// </summary>
+        [Description("Gets or sets the JabberClient associated with the Presence Manager.")]
+        [Category("Jabber")]
+        [Browsable(false)]
+        [Obsolete("Use the Stream property instead")]
+        [ReadOnly(true)]
+        public JabberClient Client
+        {
+            get { return (JabberClient)this.Stream; }
+            set { this.Stream = value; }
+        }
+
+        /// <summary>
+        /// The CapsManager for this view
+        /// </summary>
+        [Category("Jabber")]
+        public CapsManager CapsManager
+        {
+            get
+            {
+                // If we are running in the designer, let's try to auto-hook a CapsManager
+                if ((m_caps == null) && DesignMode)
+                {
+                    IDesignerHost host = (IDesignerHost)base.GetService(typeof(IDesignerHost));
+                    this.CapsManager = (CapsManager)jabber.connection.StreamComponent.GetComponentFromHost(host, typeof(CapsManager));
+                }
+                return m_caps;
+            }
+            set
+            {
+                if ((object)m_caps == (object)value)
+                    return;
+                m_caps = value;
+            }
+        }
+
+        /// <summary>
+        /// Gets the current presence state as a string.
+        /// </summary>
+        /// <returns>string in the format '{bare JID}={list of presence stanzas}, ...'</returns>
+        public override string ToString()
+        {
+            return m_items.ToString();
+        }
+
+        /// <summary>
+        /// Informs the client that the primary session has changed for a user.
+        /// </summary>
+        public event PrimarySessionHandler OnPrimarySessionChange;
+
+        private void GotDisconnect(object sender)
+        {
+            lock(this)
+                m_items.Clear();
+        }
+
+        /// <summary>
+        /// Adds a new available or unavailable presence packet to the database.
+        /// </summary>
+        /// <param name="p">Presence stanza to add.</param>
+        public void AddPresence(Presence p)
+        {
+            // can't use .From, since that will cause a JID parse.
+            Debug.Assert(p.GetAttribute("from") != "",
+                "Do not call AddPresence by hand.  I can tell you are doing that because you didn't put a from address on your presence packet, and all presences from the server have a from address.");
+            GotPresence(this, p);
+        }
+
+        private void GotPresence(object sender, Presence p)
+        {
+            PresenceType t = p.Type;
+            if ((t != PresenceType.available) &&
+                (t != PresenceType.unavailable))
+                return;
+
+            JID f = p.From;
+            lock (this)
+            {
+                UserPresenceManager upm = (UserPresenceManager)m_items[f.Bare];
+
+                if (t == PresenceType.available)
+                {
+                    if (upm == null)
+                    {
+                        upm = new UserPresenceManager(f.Bare);
+                        m_items[f.Bare] = upm;
+                    }
+
+                    upm.AddPresence(p, this);
+                }
+                else
+                {
+                    if (upm != null)
+                    {
+                        upm.RemovePresence(p, this);
+                        if (upm.Count == 0)
+                        {
+                            m_items.Remove(f.Bare);
+                        }
+                    }
+                }
+            }
+        }
+
+        private void FireOnPrimarySessionChange(JID from)
+        {
+            if (OnPrimarySessionChange != null)
+                OnPrimarySessionChange(this, from);
+        }
+
+        /// <summary>
+        /// Determines if a specified JID is online with any resources.
+        /// This performs better than retrieving the particular associated presence packet.
+        /// </summary>
+        /// <param name="jid">The JID to look up.</param>
+        /// <returns>If true, the user is online; otherwise the user is offline</returns>
+        public bool IsAvailable(JID jid)
+        {
+            lock (this)
+            {
+                return (m_items[jid.Bare] != null);
+            }
+        }
+
+        /// <summary>
+        /// Gets the primary presence if given a bare JID.
+        /// If given a FQJ, returns the associated presence.
+        /// </summary>
+        public Presence this[JID jid]
+        {
+            get
+            {
+                lock (this)
+                {
+                    UserPresenceManager upm = (UserPresenceManager)m_items[jid.Bare];
+                    if (upm == null)
+                        return null;
+                    return upm[jid.Resource];
+                }
+            }
+        }
+
+        /// <summary>
+        /// Get the features associated with the JID.  If a bare JID is passed in, this will be 
+        /// a union of all of the features for all of the resources of this user.  Otherwise,
+        /// it will be the features for the given resource.
+        /// 
+        /// Requires a CapsManager to be set before use.
+        /// </summary>
+        /// <param name="jid"></param>
+        /// <returns>Null if no features are known.</returns>
+        public StringSet GetFeatures(JID jid)
+        {
+            if (m_caps == null)
+                return null;
+
+            lock (this)
+            {
+                UserPresenceManager upm = (UserPresenceManager)m_items[jid.Bare];
+                if (upm == null)
+                    return null;
+                return upm.GetFeatures(m_caps, jid.Resource);
+            }
+        }
+
+        /// <summary>
+        /// Does the given JID implement the given feature?  Bare JID asks if any
+        /// resource of that user implements that feature.  Full JID asks if the
+        /// given resource implements that feature.
+        /// 
+        /// Requires a CapsManager to be set before use.
+        /// </summary>
+        /// <param name="jid"></param>
+        /// <param name="featureURI"></param>
+        /// <returns>True if the feaure is implemented</returns>
+        public bool HasFeature(JID jid, string featureURI)
+        {
+            StringSet feats = GetFeatures(jid);
+            if (feats == null)
+                return false;
+            return feats[featureURI];
+        }
+
+        /// <summary>
+        /// Get the most available full JID that implements the given feature.  Unlike
+        /// most routines in PresenceManager, may also return JIDs that have negative
+        /// presence.  If a full JID is specified, this is effectively the same as
+        /// HasFeature, but null will be returned if the feature isn't implemented.
+        /// 
+        /// </summary>
+        /// <param name="jid"></param>
+        /// <param name="featureURI"></param>
+        /// <returns>null if none found</returns>
+        public JID GetFeatureJID(JID jid, string featureURI)
+        {
+            if (jid.Resource != null)
+            {
+                if (HasFeature(jid, featureURI))
+                    return jid;
+                return null;
+            }
+
+            lock (this)
+            {
+                UserPresenceManager upm = (UserPresenceManager)m_items[jid.Bare];
+                if (upm == null)
+                    return null;
+                return upm.GetFeatureJID(m_caps, featureURI);
+            }
+        }
+
+        /// <summary>
+        /// Gets all of the current presence stanzas for the given user.
+        /// </summary>
+        /// <param name="jid">User who's presence stanzas you want.</param>
+        /// <returns>Array of presence stanzas for the given user.</returns>
+        public Presence[] GetAll(JID jid)
+        {
+            UserPresenceManager upm = (UserPresenceManager)m_items[jid.Bare];
+            if (upm == null)
+                return new Presence[0];
+            return upm.GetAll();
+        }
+
+
+        #region Component Designer generated code
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            components = new System.ComponentModel.Container();
+        }
+        #endregion
+
+        /// <summary>
+        /// Iterate over all of the JIDs we have not-unavilable presence from.
+        /// </summary>
+        /// <returns></returns>
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return new UserPresenceManagerEnumerator(m_items.Values);
+        }
+
+        private class UserPresenceManagerEnumerator : IEnumerator
+        {
+            private IEnumerator m_enum;
+
+            public UserPresenceManagerEnumerator(ICollection values)
+            {
+                m_enum = values.GetEnumerator();
+            }
+
+            #region IEnumerator Members
+            public object Current
+            {
+                get
+                {
+                    UserPresenceManager m = (UserPresenceManager)m_enum.Current;
+                    if (m == null)
+                        return null;
+                    return m.JID;
+                }
+            }
+
+            public bool MoveNext()
+            {
+                return m_enum.MoveNext();
+            }
+
+            public void Reset()
+            {
+                m_enum.Reset();
+            }
+
+            #endregion
+        }
+
+        /// <summary>
+        /// Manage the presence for all of the resources of a user.  No locking is performed,
+        /// since PresenceManager is already doing locking.
+        ///
+        /// The intent of this class is to be able to deliver the last presence stanza
+        /// from the "most available" resource.
+        /// Note that negative priority sessions are never the most available.
+        /// </summary>
+        private class UserPresenceManager
+        {
+            // List sorted by presence availability, in ascending order.
+            // most-available is always last.
+            private gen.LinkedList<Presence> m_all = new gen.LinkedList<Presence>();
+            private JID m_jid = null;
+
+            public UserPresenceManager(JID jid)
+            {
+                Debug.Assert(jid.Resource == null);
+                m_jid = jid;
+            }
+
+            public JID JID
+            {
+                get { return m_jid; }
+            }
+
+            public override string ToString()
+            {
+                System.IO.StringWriter sw = new System.IO.StringWriter();
+                sw.WriteLine("{");
+                foreach (Presence p in m_all)
+                    sw.WriteLine(p.OuterXml);
+                sw.WriteLine("}");
+                return sw.ToString();
+            }
+
+            private void Primary(Presence p, PresenceManager handler)
+            {
+                Debug.Assert((p == null) ? true : (p.IntPriority >= 0), "Primary presence is always positive priority");
+                handler.FireOnPrimarySessionChange(m_jid);
+            }
+
+            private gen.LinkedListNode<Presence> Find(string resource)
+            {
+                for (gen.LinkedListNode<Presence> n = m_all.First; n != null; n = n.Next)
+                {
+                    if (n.Value.From.Resource == resource)
+                        return n;
+                }
+                return null;
+            }
+
+            public void AddPresence(Presence p, PresenceManager handler)
+            {
+                JID from = p.From;
+                string res = from.Resource;
+                Debug.Assert(p.Type == PresenceType.available);
+
+                // If this is an update, remove the existing one.
+                // we'll add the new one back in, in the correct place.
+                gen.LinkedListNode<Presence> n = Find(res);
+                if (n != null)
+                    m_all.Remove(n);
+
+
+                gen.LinkedListNode<Presence> inserted = new gen.LinkedListNode<Presence>(p);
+                for (n = m_all.First; n != null; n = n.Next)
+                {
+                    if (p < n.Value)
+                    {
+                        m_all.AddBefore(n, inserted);
+                        break;
+                    }
+                }
+
+                // This is the highest one.
+                if (inserted.List == null)
+                {
+                    m_all.AddLast(inserted);
+                    if (p.IntPriority >= 0)
+                        Primary(p, handler);
+                }
+            }
+
+            public void RemovePresence(Presence p, PresenceManager handler)
+            {
+                JID from = p.From;
+                string res = from.Resource;
+                Debug.Assert(p.Type == PresenceType.unavailable);
+
+                gen.LinkedListNode<Presence> n = Find(res);
+
+                // unavail for a resource we haven't gotten presence from.
+                if (n == null)
+                    return;
+
+                gen.LinkedListNode<Presence> last = m_all.Last;
+                m_all.Remove(n);
+
+                if (last == n)
+                {
+                    // current high-pri.
+                    if ((m_all.Last != null) && (m_all.Last.Value.IntPriority >= 0))
+                        Primary(m_all.Last.Value, handler);
+                    else
+                    {
+                        // last non-negative presence went away
+                        if (n.Value.IntPriority >= 0)
+                            Primary(null, handler);
+                    }
+                }
+            }
+
+            public int Count
+            {
+                get { return m_all.Count; }
+            }
+
+            public Presence this[string Resource]
+            {
+                get
+                {
+                    gen.LinkedListNode<Presence> n;
+                    if (Resource == null)
+                    {
+                        // get highest non-negative for this bare JID.
+                        n = m_all.Last;
+
+                        if ((n != null) && (n.Value.IntPriority >= 0))
+                            return n.Value;
+                    }
+                    else
+                    {
+                        n = Find(Resource);
+                        if (n != null)
+                            return n.Value;
+                    }
+                    return null;
+                }
+            }
+
+            public Presence[] GetAll()
+            {
+                Presence[] all = new Presence[m_all.Count];
+                m_all.CopyTo(all, 0);
+                return all;
+            }
+
+            private StringSet GetFeatures(CapsManager caps, Presence p)
+            {
+                if (p == null)
+                    return null;
+
+                Caps c = p.GetChildElement<Caps>();
+                if (c == null)
+                    return null;
+
+                DiscoInfo di = caps[c.Version];
+                if (di == null)
+                    return null;
+
+                return di.FeatureSet;
+            }
+
+            public StringSet GetFeatures(CapsManager caps, string resource)
+            {
+                if (resource == null)
+                    return GetAllFeatures(caps);
+
+                return GetFeatures(caps, this[resource]);
+            }
+
+            public StringSet GetAllFeatures(CapsManager caps)
+            {
+                if (caps == null)
+                    throw new ArgumentNullException("caps");
+
+                StringSet features = new StringSet();
+                foreach (Presence p in m_all)
+                {
+                    StringSet f = GetFeatures(caps, p);
+                    if (f != null)
+                        features.Add(f);
+                }
+                return features;
+            }
+
+            public JID GetFeatureJID(CapsManager caps, string featureURI)
+            {
+                gen.LinkedListNode<Presence> n;
+                for (n = m_all.Last; n != null; n = n.Previous)
+                {
+                    StringSet f = GetFeatures(caps, n.Value);
+                    if ((f != null) && f.Contains(featureURI))
+                        return n.Value.From;
+                }
+                return null;
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/client/PresenceManager.resx b/lib/jabber-net/jabber/client/PresenceManager.resx
new file mode 100644
index 0000000..d5a1efd
--- /dev/null
+++ b/lib/jabber-net/jabber/client/PresenceManager.resx
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<root>
+    <!-- 
+            Microsoft ResX Schema 
+        
+            Version 1.3
+                
+            The primary goals of this format is to allow a simple XML format 
+            that is mostly human readable. The generation and parsing of the 
+            various data types are done through the TypeConverter classes 
+            associated with the data types.
+        
+            Example:
+        
+                ... ado.net/XML headers & schema ...
+                <resheader name="resmimetype">text/microsoft-resx</resheader>
+                <resheader name="version">1.3</resheader>
+                <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+                <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+                <data name="Name1">this is my long string</data>
+                <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+                <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+                    [base64 mime encoded serialized .NET Framework object]
+                </data>
+                <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+                    [base64 mime encoded string representing a byte array form of the .NET Framework object]
+                </data>
+        
+            There are any number of "resheader" rows that contain simple 
+            name/value pairs.
+            
+            Each data row contains a name, and value. The row also contains a 
+            type or mimetype. Type corresponds to a .NET class that support 
+            text/value conversion through the TypeConverter architecture. 
+            Classes that don't support this are serialized and stored with the 
+            mimetype set.
+                     
+            The mimetype is used for serialized objects, and tells the 
+            ResXResourceReader how to depersist the object. This is currently not 
+            extensible. For a given mimetype the value must be set accordingly:
+        
+            Note - application/x-microsoft.net.object.binary.base64 is the format 
+                   that the ResXResourceWriter will generate, however the reader can 
+                   read any of the formats listed below.
+        
+            mimetype: application/x-microsoft.net.object.binary.base64
+            value   : The object must be serialized with 
+                    : System.Serialization.Formatters.Binary.BinaryFormatter
+                    : and then encoded with base64 encoding.
+        
+            mimetype: application/x-microsoft.net.object.soap.base64
+            value   : The object must be serialized with 
+                    : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+                    : and then encoded with base64 encoding.
+            mimetype: application/x-microsoft.net.object.bytearray.base64
+            value   : The object must be serialized into a byte array 
+                    : using a System.ComponentModel.TypeConverter
+                    : and then encoded with base64 encoding.
+        -->
+    <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+        <xsd:element name="root" msdata:IsDataSet="true">
+            <xsd:complexType>
+                <xsd:choice maxOccurs="unbounded">
+                    <xsd:element name="data">
+                        <xsd:complexType>
+                            <xsd:sequence>
+                                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+                            </xsd:sequence>
+                            <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+                            <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+                            <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+                        </xsd:complexType>
+                    </xsd:element>
+                    <xsd:element name="resheader">
+                        <xsd:complexType>
+                            <xsd:sequence>
+                                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                            </xsd:sequence>
+                            <xsd:attribute name="name" type="xsd:string" use="required" />
+                        </xsd:complexType>
+                    </xsd:element>
+                </xsd:choice>
+            </xsd:complexType>
+        </xsd:element>
+    </xsd:schema>
+    <resheader name="resmimetype">
+        <value>text/microsoft-resx</value>
+    </resheader>
+    <resheader name="version">
+        <value>1.3</value>
+    </resheader>
+    <resheader name="reader">
+        <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    </resheader>
+    <resheader name="writer">
+        <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    </resheader>
+    <data name="$this.Name">
+        <value>PresenceManager</value>
+    </data>
+    <data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+        <value>False</value>
+    </data>
+</root>
\ No newline at end of file
diff --git a/lib/jabber-net/jabber/client/RosterManager.bmp b/lib/jabber-net/jabber/client/RosterManager.bmp
new file mode 100644
index 0000000..6246d70
Binary files /dev/null and b/lib/jabber-net/jabber/client/RosterManager.bmp differ
diff --git a/lib/jabber-net/jabber/client/RosterManager.cs b/lib/jabber-net/jabber/client/RosterManager.cs
new file mode 100644
index 0000000..5715848
--- /dev/null
+++ b/lib/jabber-net/jabber/client/RosterManager.cs
@@ -0,0 +1,450 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Collections;
+using System.Diagnostics;
+
+using bedrock.collections;
+using bedrock.util;
+
+using jabber.protocol.client;
+using jabber.protocol.iq;
+
+namespace jabber.client
+{
+    /// <summary>
+    /// Informs the client of roster items.
+    /// </summary>
+    public delegate void RosterItemHandler(object sender, Item ri);
+
+    /// <summary>
+    /// Informs the client of a subscription requests.
+    /// </summary>
+    /// <param name="manager">The RosterManager than detected the subscription</param>
+    /// <param name="ri">The affected roster item, in its current state.  Null if not found.</param>
+    /// <param name="pres">The inbound presence stanza</param>
+    public delegate void SubscriptionHandler(RosterManager manager, Item ri, Presence pres);
+
+    /// <summary>
+    /// Manages unsubscription notifications.
+    /// </summary>
+    /// <param name="manager">The RosterManager than detected the subscription</param>
+    /// <param name="remove">Set this to false to prevent the user being removed from the roster.</param>
+    /// <param name="pres">The inbound presence stanza</param>
+    public delegate void UnsubscriptionHandler(RosterManager manager, Presence pres, ref bool remove);
+
+    /// <summary>
+    /// Determines how the RosterManager deals with incoming subscriptions.
+    /// </summary>
+    public enum AutoSubscriptionHanding
+    {
+        /// <summary>
+        /// Do not do any automatic processing
+        /// </summary>
+        NONE = 0,
+        /// <summary>
+        /// Reply with a subscribed to every subscribe
+        /// </summary>
+        AllowAll,
+        /// <summary>
+        /// Reply with an unsubscribed to every subscribe
+        /// </summary>
+        DenyAll,
+        /// <summary>
+        /// If the user is either subscribed or trying to subscribe to another user,
+        /// allow the other user's subscription.
+        /// Otherwise, treat as NONE, and fire the OnSubscribe event.
+        /// </summary>
+        AllowIfSubscribed,
+    }
+
+    /// <summary>
+    /// Manages the roster of the client.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class RosterManager : jabber.connection.StreamComponent, IEnumerable
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+#pragma warning disable 0414
+        private System.ComponentModel.Container components = null;
+#pragma warning restore 0414
+        private Tree m_items = new Tree();
+        private AutoSubscriptionHanding m_autoAllow = AutoSubscriptionHanding.NONE;
+        private bool m_autoSubscribe = false;
+
+        /// <summary>
+        /// Creates a new roster manager inside a container.
+        /// </summary>
+        /// <param name="container">Parent container</param>
+        public RosterManager(System.ComponentModel.IContainer container) : this()
+        {
+            // Required for Windows.Forms Class Composition Designer support
+            container.Add(this);
+        }
+
+        /// <summary>
+        /// Creates a new roster manager.
+        /// </summary>
+        public RosterManager()
+        {
+            // Required for Windows.Forms Class Composition Designer support
+            InitializeComponent();
+            this.OnStreamChanged += new bedrock.ObjectHandler(RosterManager_OnStreamChanged);
+        }
+
+        private void RosterManager_OnStreamChanged(object sender)
+        {
+            JabberClient cli = m_stream as JabberClient;
+            if (cli == null)
+                return;
+            cli.OnIQ += new IQHandler(GotIQ);
+            cli.OnPresence += new PresenceHandler(cli_OnPresence);
+            cli.OnDisconnect += new bedrock.ObjectHandler(GotDisconnect);
+        }
+
+
+        /// <summary>
+        /// Gets or sets the Jabber client associated with the Roster Manager.
+        /// </summary>
+        [Description("The JabberClient to hook up to.")]
+        [Category("Jabber")]
+        [Browsable(false)]
+        [Obsolete("Use the Stream property instead")]
+        [ReadOnly(true)]
+        public JabberClient Client
+        {
+            get { return (JabberClient) this.Stream; }
+            set { this.Stream = value; }
+        }
+
+        /// <summary>
+        /// Gets the AutoSubscription Handling value for inbound subscriptions.
+        /// </summary>
+        [Description("How to handle inbound subscriptions")]
+        [Category("Jabber")]
+        [DefaultValue(AutoSubscriptionHanding.NONE)]
+        public AutoSubscriptionHanding AutoAllow
+        {
+            get { return m_autoAllow; }
+            set { m_autoAllow = value; }
+        }
+
+        /// <summary>
+        /// Determines whether auto-subscribe is enabled or disabled for a user.
+        /// </summary>
+        [Description("Should we subscribe to a user whenever we allow a subscription from them?")]
+        [Category("Jabber")]
+        [DefaultValue(false)]
+        public bool AutoSubscribe
+        {
+            get { return m_autoSubscribe; }
+            set { m_autoSubscribe = value; }
+        }
+
+        /// <summary>
+        /// Informs the client that is has new roster items.
+        /// </summary>
+        [Description("Convenience event for new roster items.")]
+        [Category("Jabber")]
+        public event RosterItemHandler OnRosterItem;
+
+        /// <summary>
+        /// Informs the client when a roster result starts, before any OnRosterItem events fire.
+        /// This will not fire for type='set'.
+        /// </summary>
+        [Description("Roster result about to start being processed.")]
+        [Category("Jabber")]
+        public event bedrock.ObjectHandler OnRosterBegin;
+
+        /// <summary>
+        /// Informs the client that the roster has been retrieved from the XMPP server.
+        /// </summary>
+        [Description("Roster result finished being processed.")]
+        [Category("Jabber")]
+        public event bedrock.ObjectHandler OnRosterEnd;
+
+        /// <summary>
+        /// Informs the client that a subscription request was received that cannot be auto-handled.
+        /// </summary>
+        [Description("Subscription request received that cannot be auto-handled")]
+        [Category("Jabber")]
+        public event SubscriptionHandler OnSubscription;
+
+        /// <summary>
+        /// Informs the client that an Unsubscribe/Unsubscribed notification from another
+        /// user. By default, the user will be removed from the roster after this event
+        /// fires. To prevent this, you need to set the remove property to false.
+        /// </summary>
+        [Description("Unsubscribe/Unsubscribed notification from other user")]
+        [Category("Jabber")]
+        public event UnsubscriptionHandler OnUnsubscription;
+
+        /// <summary>
+        /// Returns a string that represents the current object.
+        /// </summary>
+        public override string ToString()
+        {
+            return m_items.ToString();
+        }
+
+        /// <summary>
+        /// Gets the currently-known version of a roster item for this JID.
+        /// </summary>
+        public Item this[JID jid]
+        {
+            get
+            {
+                lock (this)
+                    return (Item) m_items[jid];
+            }
+        }
+
+        /// <summary>
+        /// Gets the number of items currently in the roster.
+        /// </summary>
+        public int Count
+        {
+            get
+            {
+                lock (this)
+                    return m_items.Count;
+            }
+        }
+
+        private void GotDisconnect(object sender)
+        {
+            lock (this)
+                m_items.Clear();
+        }
+
+        private void cli_OnPresence(object sender, Presence pres)
+        {
+            PresenceType typ = pres.Type;
+            switch (typ)
+            {
+            case PresenceType.available:
+            case PresenceType.unavailable:
+            case PresenceType.error:
+            case PresenceType.probe:
+                return;
+            case PresenceType.subscribe:
+                switch (m_autoAllow)
+                {
+                case AutoSubscriptionHanding.AllowAll:
+                    ReplyAllow(pres);
+                    return;
+                case AutoSubscriptionHanding.DenyAll:
+                    ReplyDeny(pres);
+                    return;
+                case AutoSubscriptionHanding.NONE:
+                    if (OnSubscription != null)
+                        OnSubscription(this, this[pres.From], pres);
+                    return;
+                case AutoSubscriptionHanding.AllowIfSubscribed:
+                    Item ri = this[pres.From];
+                    if (ri != null)
+                    {
+                        switch (ri.Subscription)
+                        {
+                        case Subscription.to:
+                            ReplyAllow(pres);
+                            return;
+                        case Subscription.from:
+                        case Subscription.both:
+                            // Almost an assert
+                            throw new InvalidOperationException("Server sent a presence subscribe for an already-subscribed contact");
+                        case Subscription.none:
+                            if (ri.Ask == Ask.subscribe)
+                            {
+                                ReplyAllow(pres);
+                                return;
+                            }
+                            break;
+                        }
+                    }
+                    if (OnSubscription != null)
+                        OnSubscription(this, ri, pres);
+                    break;
+                }
+                break;
+            case PresenceType.subscribed:
+                // This is the new ack case.
+                Presence sub_ack = new Presence(m_stream.Document);
+                sub_ack.To = pres.From;
+                sub_ack.Type = PresenceType.subscribe;
+                Write(sub_ack);                
+                break;
+            case PresenceType.unsubscribe:
+                // ack.  we'll likely get an unsubscribed soon, anyway.
+                Presence un_ack = new Presence(m_stream.Document);
+                un_ack.To = pres.From;
+                un_ack.Type = PresenceType.unsubscribed;
+                Write(un_ack);
+                break;
+            case PresenceType.unsubscribed:
+                bool remove = true;
+                if (OnUnsubscription != null)
+                    OnUnsubscription(this, pres, ref remove);
+
+                if (remove)
+                    Remove(pres.From);
+                break;
+            }
+        }
+
+        /// <summary>
+        /// Adds a new roster item to the database.
+        /// </summary>
+        /// <param name="iq">An IQ containing a roster query.</param>
+        public void AddRoster(IQ iq)
+        {
+            GotIQ(this, iq);
+        }
+
+        private void GotIQ(object sender, IQ iq)
+        {
+            if ((iq.Query == null) ||
+                (iq.Query.NamespaceURI != jabber.protocol.URI.ROSTER) ||
+                ((iq.Type != IQType.result) && (iq.Type != IQType.set)))
+                return;
+
+            iq.Handled = true;
+            Roster r = (Roster) iq.Query;
+            if ((iq.Type == IQType.result) && (OnRosterBegin != null))
+                OnRosterBegin(this);
+
+            foreach (Item i in r.GetItems())
+            {
+                lock (this)
+                {
+                    if (i.Subscription == Subscription.remove)
+                    {
+                        m_items.Remove(i.JID);
+                    }
+                    else
+                    {
+                        if (m_items.Contains(i.JID))
+                            m_items.Remove(i.JID);
+                        m_items[i.JID] = i;
+                    }
+                }
+                if (OnRosterItem != null)
+                    OnRosterItem(this, i);
+            }
+
+            if ((iq.Type == IQType.result) && (OnRosterEnd != null))
+                OnRosterEnd(this);
+        }
+
+        /// <summary>
+        /// Allows the subscription request and sends a subscribed to the user.
+        /// </summary>
+        /// <param name="pres">
+        /// The presence packet containing the subscription request.
+        /// </param>
+        public void ReplyAllow(Presence pres)
+        {
+            Debug.Assert(pres.Type == PresenceType.subscribe);
+            Presence reply = new Presence(m_stream.Document);
+            reply.To = pres.From;
+            reply.Type = PresenceType.subscribed;
+            Write(reply);
+
+            if (m_autoSubscribe)
+            {
+                Presence sub = new Presence(m_stream.Document);
+                sub.To = pres.From;
+                sub.Type = PresenceType.subscribe;
+                Write(sub);
+            }
+        }
+
+        /// <summary>
+        /// Denies the subscription request.
+        /// </summary>
+        /// <param name="pres">
+        /// The presence packet containing the subscription request.
+        /// </param>
+        public void ReplyDeny(Presence pres)
+        {
+            Debug.Assert(pres.Type == PresenceType.subscribe);
+            Presence reply = new Presence(m_stream.Document);
+            reply.To = pres.From;
+            reply.Type = PresenceType.unsubscribed;
+            Write(reply);
+        }
+
+        /// <summary>
+        /// Remove a contact from the roster
+        /// </summary>
+        /// <param name="jid">Typically just a user at host JID</param>
+        public void Remove(JID jid)
+        {
+/*
+C: <iq from='juliet at example.com/balcony' type='set' id='delete_1'>
+     <query xmlns='jabber:iq:roster'>
+       <item jid='nurse at example.com' subscription='remove'/>
+     </query>
+   </iq>
+ */
+            RosterIQ iq = new RosterIQ(m_stream.Document);
+            iq.Type = IQType.set;
+            Roster r = iq.Instruction;
+            Item item = r.AddItem();
+            item.JID = jid;
+            item.Subscription = Subscription.remove;
+            Write(iq);  // ignore response
+        }
+
+        /// <summary>
+        /// Modifies the roster item to look like the given roster item.
+        /// This does not modify the model,
+        /// but waits for roster pushes from the XMPP server.
+        /// </summary>
+        /// <param name="item">Roster item that will appear in the roster.</param>
+        public void Modify(Item item)
+        {
+            RosterIQ iq = new RosterIQ(m_stream.Document);
+            iq.Type = IQType.set;
+            Roster r = iq.Instruction;
+            r.AppendChild(item);
+            Write(iq);  // ignore response
+        }
+
+        #region Component Designer generated code
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            components = new System.ComponentModel.Container();
+        }
+        #endregion
+
+        #region IEnumerable Members
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return m_items.Keys.GetEnumerator();
+        }
+
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/jabber/client/RosterManager.resx b/lib/jabber-net/jabber/client/RosterManager.resx
new file mode 100644
index 0000000..5413f14
--- /dev/null
+++ b/lib/jabber-net/jabber/client/RosterManager.resx
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<root>
+    <!-- 
+            Microsoft ResX Schema 
+        
+            Version 1.3
+                
+            The primary goals of this format is to allow a simple XML format 
+            that is mostly human readable. The generation and parsing of the 
+            various data types are done through the TypeConverter classes 
+            associated with the data types.
+        
+            Example:
+        
+                ... ado.net/XML headers & schema ...
+                <resheader name="resmimetype">text/microsoft-resx</resheader>
+                <resheader name="version">1.3</resheader>
+                <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+                <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+                <data name="Name1">this is my long string</data>
+                <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+                <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+                    [base64 mime encoded serialized .NET Framework object]
+                </data>
+                <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+                    [base64 mime encoded string representing a byte array form of the .NET Framework object]
+                </data>
+        
+            There are any number of "resheader" rows that contain simple 
+            name/value pairs.
+            
+            Each data row contains a name, and value. The row also contains a 
+            type or mimetype. Type corresponds to a .NET class that support 
+            text/value conversion through the TypeConverter architecture. 
+            Classes that don't support this are serialized and stored with the 
+            mimetype set.
+                     
+            The mimetype is used for serialized objects, and tells the 
+            ResXResourceReader how to depersist the object. This is currently not 
+            extensible. For a given mimetype the value must be set accordingly:
+        
+            Note - application/x-microsoft.net.object.binary.base64 is the format 
+                   that the ResXResourceWriter will generate, however the reader can 
+                   read any of the formats listed below.
+        
+            mimetype: application/x-microsoft.net.object.binary.base64
+            value   : The object must be serialized with 
+                    : System.Serialization.Formatters.Binary.BinaryFormatter
+                    : and then encoded with base64 encoding.
+        
+            mimetype: application/x-microsoft.net.object.soap.base64
+            value   : The object must be serialized with 
+                    : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+                    : and then encoded with base64 encoding.
+            mimetype: application/x-microsoft.net.object.bytearray.base64
+            value   : The object must be serialized into a byte array 
+                    : using a System.ComponentModel.TypeConverter
+                    : and then encoded with base64 encoding.
+        -->
+    <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+        <xsd:element name="root" msdata:IsDataSet="true">
+            <xsd:complexType>
+                <xsd:choice maxOccurs="unbounded">
+                    <xsd:element name="data">
+                        <xsd:complexType>
+                            <xsd:sequence>
+                                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+                            </xsd:sequence>
+                            <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+                            <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+                            <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+                        </xsd:complexType>
+                    </xsd:element>
+                    <xsd:element name="resheader">
+                        <xsd:complexType>
+                            <xsd:sequence>
+                                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                            </xsd:sequence>
+                            <xsd:attribute name="name" type="xsd:string" use="required" />
+                        </xsd:complexType>
+                    </xsd:element>
+                </xsd:choice>
+            </xsd:complexType>
+        </xsd:element>
+    </xsd:schema>
+    <resheader name="resmimetype">
+        <value>text/microsoft-resx</value>
+    </resheader>
+    <resheader name="version">
+        <value>1.3</value>
+    </resheader>
+    <resheader name="reader">
+        <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    </resheader>
+    <resheader name="writer">
+        <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    </resheader>
+    <data name="$this.Name">
+        <value>RosterManager</value>
+    </data>
+    <data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+        <value>False</value>
+    </data>
+</root>
\ No newline at end of file
diff --git a/lib/jabber-net/jabber/connection/BindingStanzaStream.cs b/lib/jabber-net/jabber/connection/BindingStanzaStream.cs
new file mode 100644
index 0000000..ff14be9
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/BindingStanzaStream.cs
@@ -0,0 +1,48 @@
+using bedrock.net;
+using jabber.protocol.stream;
+
+namespace jabber.connection
+{
+	class BindingStanzaStream : HttpStanzaStream
+	{
+	    public BindingStanzaStream(IStanzaEventListener listener) : base(listener)
+	    {
+	    }
+
+	    protected override BaseSocket CreateSocket()
+	    {
+	        XEP124Socket sock = new XEP124Socket(this);
+            ProxyType pt = (ProxyType)m_listener[Options.PROXY_TYPE];
+            if (pt == ProxyType.HTTP)
+            {
+                string host = m_listener[Options.PROXY_HOST] as string;
+                int port = (int)m_listener[Options.PROXY_PORT];
+                if (port == -1)
+                    port = 80;
+                string proxy_uri = string.Format("http://{0}:{1}/", host, port);
+                sock.ProxyURI = new System.Uri(proxy_uri);
+                string user = m_listener[Options.PROXY_USER] as string;
+                if ((user != null) && (user != ""))
+                {
+                    sock.ProxyCredentials = new System.Net.NetworkCredential(user,
+                        m_listener[Options.PROXY_PW] as string);
+                }
+            }
+            return sock;
+	    }
+
+        public override void WriteStartTag(Stream stream)
+        {
+            // We don't send the <stream:stream> tag in XEP 124.
+            XEP124Socket mySock = ((XEP124Socket) Socket);
+            mySock.NS = stream.NS;
+            mySock.Write(null, 0, 0);
+        }
+
+        public override void Close(bool clean)
+        {
+            // We don't send the </stream:stream> tag in XEP 124.
+            base.Close(false);
+        }
+	}
+}
diff --git a/lib/jabber-net/jabber/connection/CapsManager.bmp b/lib/jabber-net/jabber/connection/CapsManager.bmp
new file mode 100644
index 0000000..4fb7089
Binary files /dev/null and b/lib/jabber-net/jabber/connection/CapsManager.bmp differ
diff --git a/lib/jabber-net/jabber/connection/CapsManager.cs b/lib/jabber-net/jabber/connection/CapsManager.cs
new file mode 100644
index 0000000..f247117
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/CapsManager.cs
@@ -0,0 +1,573 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Diagnostics;
+using System.Security.Cryptography;
+using System.Text;
+using System.Xml;
+
+using jabber.protocol;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+using jabber.protocol.x;
+
+using bedrock.util;
+using bedrock.io;
+
+namespace jabber.connection
+{
+    /// <summary>
+    /// Manages the entity capabilities information for the local connection as well as remote ones.
+    /// See XEP-0115, version 1.5 for details.
+    /// </summary>
+    [SVN("$Id$")]
+    public class CapsManager: StreamComponent
+    {
+        /// <summary>
+        /// Defines the default hash function to use for calculating ver attributes.
+        /// </summary>
+        public const string DEFAULT_HASH = "sha-1";
+        private const string SEP = "<";
+
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        private DiscoNode m_disco;
+        private string m_hash = DEFAULT_HASH;
+        private string m_ver = null;
+
+        private FileMap<DiscoInfo> m_cache = null;
+        private DiscoManager m_discoManager = null;
+
+        /// <summary>
+        /// Creates a new capability manager.
+        /// </summary>
+        public CapsManager() : this((DiscoNode)null)
+        {
+        }
+
+        /// <summary>
+        /// Creates a new capability manager and associates it with a container.
+        /// </summary>
+        /// <param name="container">Parent container.</param>
+        public CapsManager(IContainer container) : this((DiscoNode)null)
+        {
+            container.Add(this);
+        }
+
+        /// <summary>
+        /// Create a CapsManager from an existing Disco Node.  Pass in null
+        /// to use a placeholder.
+        /// </summary>
+        /// <param name="node"></param>
+        public CapsManager(DiscoNode node)
+        {
+            InitializeComponent();
+            this.OnStreamChanged += new bedrock.ObjectHandler(CapsManager_OnStreamChanged);
+
+            if (node == null)
+                m_disco = new DiscoNode(new JID(null, "placeholder", null), null);
+            else
+                m_disco = node;
+        }
+
+        /// <summary>
+        /// Performs tasks associated with freeing, releasing, or resetting resources.
+        /// </summary>
+        /// <param name="disposing">
+        /// True if managed resources should be disposed; otherwise, false.
+        /// </param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        /// <summary>
+        /// The RosterManager for this view
+        /// </summary>
+        [Category("Cache")]
+        public DiscoManager DiscoManager
+        {
+            get
+            {
+                // If we are running in the designer, let's try to auto-hook a RosterManager
+                if ((m_discoManager == null) && DesignMode)
+                {
+                    IDesignerHost host = (IDesignerHost)base.GetService(typeof(IDesignerHost));
+                    this.DiscoManager = (DiscoManager)jabber.connection.StreamComponent.GetComponentFromHost(host, typeof(DiscoManager));
+                }
+                return m_discoManager;
+            }
+            set
+            {
+                if ((object)m_discoManager == (object)value)
+                    return;
+                m_discoManager = value;
+            }
+        }
+
+        /// <summary>
+        /// The file to store a cache of all received caps into.  If no cache file is supplied,
+        /// caps queries will not be generated.
+        /// </summary>
+        [Category("Cache")]
+        public string FileName
+        {
+            get
+            {
+                if (m_cache == null)
+                    return null;
+                return m_cache.FileName;
+            }
+            set
+            {
+                if (m_cache == null)
+                {
+                    ElementFactory ef = new ElementFactory();
+                    ef.AddType(new jabber.protocol.iq.Factory());
+
+                    m_cache = new FileMap<DiscoInfo>(value, ef);
+                }
+                else
+                    m_cache.FileName = value;
+            }
+        }
+
+        /// <summary>
+        /// Adds a feature to the feature list
+        /// </summary>
+        /// <param name="feature"></param>
+        public void AddFeature(string feature)
+        {
+            m_ver = null;
+            m_disco.AddFeature(feature);
+        }
+
+        /// <summary>
+        /// Removes a feature from the feature list
+        /// </summary>
+        /// <param name="feature"></param>
+        public void RemoveFeature(string feature)
+        {
+            m_ver = null;
+            m_disco.RemoveFeature(feature);
+        }
+
+        /// <summary>
+        /// Gets or sets the current features enabled by this entity.
+        /// </summary>
+        [Category("Capabilities")]
+        [DefaultValue(null)]
+        public string[] Features
+        {
+            get
+            {
+                if (m_disco.Features == null)
+                    return new string[0];
+                return m_disco.FeatureNames;
+            }
+            set
+            {
+                m_ver = null;
+                m_disco.ClearFeatures();
+                if (value != null)
+                    foreach (string feature in value)
+                        m_disco.AddFeature(feature);
+            }
+        }
+
+        private static HashAlgorithm GetHasher(string name)
+        {
+            switch (name)
+            {
+            case null:
+                return null;
+            case "sha-1":
+                return SHA1.Create();
+            case "sha-256":
+                return SHA256.Create();
+            case "sha-512":
+                return SHA512.Create();
+            case "sha-384":
+                return SHA384.Create();
+            case "md5":
+                return MD5.Create();
+            }
+            throw new ArgumentException("Invalid hash method: " + name, "Hash");
+        }
+
+        /// <summary>
+        /// Gets or sets the hash algorithm to use.
+        /// </summary>
+        [Category("Capabilities")]
+        [DefaultValue(DEFAULT_HASH)]
+        public string Hash
+        {
+            get { return m_hash; }
+            set
+            {
+                GetHasher(value);  // throws if bad.
+                m_hash = value;
+            }
+        }
+
+        private string CalculateVer(DiscoNode n)
+        {
+            if (m_hash == null)
+                return null;
+
+            // 1. Initialize an empty string S.
+            StringBuilder S = new StringBuilder();
+
+            // 2. Sort the service discovery identities [16] by category and then by type
+            // (if it exists) and then by xml:lang (if it exists), formatted as
+            // CATEGORY '/' [TYPE] '/' [LANG] '/' [NAME]. Note that each slash is
+            // included even if the TYPE, LANG, or NAME is not included.
+            Ident[] ids = n.GetIdentities();
+            Array.Sort(ids);
+
+            // 3. For each identity, append the 'category/type/lang/name' to S, followed by
+            // the '<' character.
+            foreach (Ident id in ids)
+            {
+                S.Append(id.Key);
+                S.Append(SEP);
+            }
+
+            // 4. Sort the supported service discovery features.
+            string[] features = n.FeatureNames;
+            Array.Sort(features);
+
+            // 5. For each feature, append the feature to S, followed by the '<' character.
+            foreach (string feature in features)
+            {
+                S.Append(feature);
+                S.Append(SEP);
+            }
+
+            // 6. If the service discovery information response includes XEP-0128 data forms, 
+            // sort the forms by the FORM_TYPE (i.e., by the XML character 
+            // data of the <value/> element).
+            Data[] ext = n.Extensions;
+            if (ext != null)
+            {
+                Array.Sort(ext, new FormTypeComparer());
+                foreach (Data x in ext)  
+                {
+                    // For each extended service discovery information form:
+
+                    // 1. Append the XML character data of the FORM_TYPE field's <value/> 
+                    // element, followed by the '<' character.
+                    S.Append(x.FormType);
+                    S.Append(SEP);
+
+                    // 2. Sort the fields by the value of the "var" attribute.
+                    bedrock.collections.Tree fields = new bedrock.collections.Tree();
+                    foreach (Field f in x.GetFields())
+                        fields[f.Var] = f;
+
+                    // 3. For each field:
+                    foreach (System.Collections.DictionaryEntry entry in fields)
+                    {
+                        Field f = (Field)entry.Value;
+                        if (f.Var == "FORM_TYPE")
+                            continue;
+
+                        // 1. Append the value of the "var" attribute, followed by the '<' character.
+                        S.Append(f.Var);
+                        S.Append(SEP);
+
+                        // 2. Sort values by the XML character data of the <value/> element.
+                        string[] values = f.Vals;
+                        Array.Sort(values);
+                        foreach (string v in values)
+                        {
+                            // 3. For each <value/> element, append the XML character data, followed by the '<' character.
+                            S.Append(v);
+                            S.Append(SEP);
+                        }
+                    }
+                }
+            }
+
+            // Ensure that S is encoded according to the UTF-8 encoding (RFC 3269 [16]).
+            byte[] input = Encoding.UTF8.GetBytes(S.ToString());
+
+            // Compute the verification string by hashing S using the algorithm specified
+            // in the 'hash' attribute (e.g., SHA-1 as defined in RFC 3174 [17]). The hashed
+            // data MUST be generated with binary output and encoded using Base64 as specified
+            // in Section 4 of RFC 4648 [18] (note: the Base64 output MUST NOT include
+            // whitespace and MUST set padding bits to zero). [19]
+            HashAlgorithm hasher = GetHasher(m_hash);
+            byte[] hash = hasher.ComputeHash(input, 0, input.Length);
+            return Convert.ToBase64String(hash);
+        }
+
+        /// <summary>
+        /// Returns the calculated hash over all of the caps information.
+        /// </summary>
+        [Category("Capabilities")]
+        public string Ver
+        {
+            get
+            {
+                if (m_ver == null)
+                    m_ver = CalculateVer(m_disco);
+                return m_ver;
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the node URI for this client.
+        /// </summary>
+        [Category("Capabilities")]
+        [DefaultValue(null)]
+        public string Node
+        {
+            get { return m_disco.Node; }
+            set { m_disco.Node = value; }
+        }
+
+        /// <summary>
+        /// Retrieves the node#ver to look for in queries.
+        /// </summary>
+        [Category("Capabilities")]
+        public string NodeVer
+        {
+            get { return Node + "#" + Ver; }
+        }
+
+        /// <summary>
+        /// Adds a new identity.
+        /// </summary>
+        /// <param name="category"></param>
+        /// <param name="type"></param>
+        /// <param name="lang"></param>
+        /// <param name="name"></param>
+        public void AddIdentity(string category, string type, string lang, string name)
+        {
+            m_ver = null;
+            m_disco.AddIdentity(new Ident(name, category, type, lang));
+        }
+
+        /// <summary>
+        /// Adds a new identity
+        /// </summary>
+        /// <param name="id"></param>
+        public void AddIdentity(Ident id)
+        {
+            m_ver = null;
+            m_disco.AddIdentity(id);
+        }
+
+        /// <summary>
+        /// Gets or sets all of the identities currently supported by this manager.
+        /// </summary>
+        [Category("Capabilities")]
+        [DefaultValue(null)]
+        public Ident[] Identities
+        {
+            get
+            {
+                if (m_disco.Identity == null)
+                    return new Ident[0];
+                return m_disco.GetIdentities();
+            }
+            set
+            {
+                m_ver = null;
+                m_disco.ClearIdentity();
+                if (value != null)
+                    foreach (Ident id in value)
+                        m_disco.AddIdentity(id);
+            }
+        }
+
+        private void CapsManager_OnStreamChanged(object sender)
+        {
+            m_disco.JID = m_stream.JID;
+
+            jabber.client.JabberClient jc = m_stream as jabber.client.JabberClient;
+            if (jc == null)
+                return;
+
+            jc.OnBeforePresenceOut += new jabber.client.PresenceHandler(jc_OnBeforePresenceOut);
+            jc.OnIQ += new jabber.client.IQHandler(jc_OnIQ);
+            jc.OnPresence += new jabber.client.PresenceHandler(jc_OnPresence);
+        }
+
+        private void jc_OnPresence(object sender, Presence pres)
+        {
+            if ((m_cache == null) || (m_discoManager == null))
+                return;
+            Caps c = pres["c", URI.CAPS] as Caps;
+            if (c == null)
+                return;
+            
+            // TODO: ignoring old-style caps for now.
+            if (!c.NewStyle)
+                return;
+            string ver = c.Version;
+            if ((ver == null) || (ver == ""))
+                return;
+            string node = c.Node;
+            if ((node == null) || (node == ""))
+                return;
+
+            if (m_cache.Contains(ver))
+                return;
+
+            m_discoManager.BeginGetFeatures(pres.From, c.Node + "#" + ver, GotCaps, ver);
+        }
+
+        private void GotCaps(DiscoManager m, DiscoNode node, object state)
+        {
+            // timeout
+            if (node == null)
+                return;
+
+            string ver = (string)state;
+            string calc = CalculateVer(node);
+            if (ver != calc)
+            {
+                Debug.WriteLine("WARNING: invalid caps ver hash: '" + ver + "' != '" + calc + "'");
+                if (node.Info != null)
+                    Debug.WriteLine(node.Info.OuterXml);
+                return;
+            }
+            m_cache[ver] = node.Info;
+        }
+
+        /// <summary>
+        /// Get a DiscoNode that has all of the info associated with the 
+        /// given ver hash, or null if there is none cached.
+        /// 
+        /// </summary>
+        /// <param name="ver"></param>
+        /// <returns></returns>
+        public DiscoInfo this[string ver]
+        {
+            get
+            {
+                if (m_cache == null)
+                    return null;
+                return m_cache[ver];
+            }
+            set
+            {
+                // mostly for test.
+                if (m_cache == null)
+                    return;
+                m_cache[ver] = value;
+            }
+        }
+
+        /// <summary>
+        /// Determines whether or not this is a capabilities request.
+        /// Answers true for a bare no-node disco request, as well as
+        /// for requests to the correct hash.
+        /// </summary>
+        /// <param name="iq">XML to look through for capabilities.</param>
+        /// <returns>True if this is a capabilities request.</returns>
+        public bool IsCaps(IQ iq)
+        {
+            if (iq.Type != IQType.get)
+                return false;
+
+            DiscoInfo info = iq.Query as DiscoInfo;
+            if (info == null)
+                return false;
+
+            string node = info.Node;
+            if (node == null)
+                return true;
+
+            if (node == NodeVer)
+                return true;
+
+            return false;
+        }
+
+        /// <summary>
+        /// Take the info for this entity, and fill it in to the given DiscoInfo protocol element.
+        /// Node, identities, and features get filled in.
+        /// </summary>
+        /// <param name="info">The empty info element to fill in.</param>
+        public void FillInInfo(DiscoInfo info)
+        {
+            foreach (Ident id in Identities)
+                info.AddIdentity(id.Category, id.Type, id.Name, id.Lang);
+            foreach (string uri in Features)
+                info.AddFeature(uri);
+        }
+
+        private void jc_OnIQ(object sender, IQ iq)
+        {
+            if (!IsCaps(iq))
+                return;
+
+            DiscoInfo info = iq.Query as DiscoInfo;
+            if (info == null)
+                return;
+
+            IQ resp = iq.GetResponse(m_stream.Document);
+            info = (DiscoInfo)resp.Query;
+            FillInInfo(info);
+
+            Write(resp);
+        }
+
+        /// <summary>
+        /// Get a caps element that describes the current version, etc.
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <returns></returns>
+        public Caps GetCaps(XmlDocument doc)
+        {
+            Caps caps = new Caps(doc);
+            caps.Version = Ver;
+            caps.Node = Node;
+            caps.Hash = m_hash;
+            return caps;
+        }
+
+        private void jc_OnBeforePresenceOut(object sender, Presence pres)
+        {
+            Debug.Assert(Node != null, "Node is required");
+            pres.AppendChild(GetCaps(pres.OwnerDocument));
+        }
+
+        #region Component Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            components = new System.ComponentModel.Container();
+        }
+
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/jabber/connection/CertificatePrompt.cs b/lib/jabber-net/jabber/connection/CertificatePrompt.cs
new file mode 100644
index 0000000..299bbcc
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/CertificatePrompt.cs
@@ -0,0 +1,240 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+
+#if !__MonoCS__
+    #define UI_OK
+#endif
+
+namespace jabber.connection
+{
+    using System;
+    using bedrock.util;
+
+#if UI_OK
+    using System.Security.Cryptography.X509Certificates;
+    using System.Net.Security;
+    using System.Windows.Forms;
+    using System.Drawing;
+#endif
+
+    /// <summary>
+    /// Intentionally-ugly form to deal with bad certificates.  Because you don't like it, you should catch XmppStream.OnInvalidCertificate,
+    /// and do something better.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class CertificatePrompt
+#if UI_OK
+        : Form
+#endif
+    {
+#if UI_OK
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+        private Label lblSubject;
+        private Label lblBegin;
+        private Label lblEnd;
+        private Button btnCancel;
+        private Button btnAllow;
+        private Button btnShow;
+        private Panel panel2;
+
+        private X509Certificate2 m_cert;
+
+        /// <summary>
+        /// Create an ugly form to prompt the user about an invalid certificate.
+        /// </summary>
+        /// <param name="cert">The invalid certificate</param>
+        /// <param name="chain">The CA chain for the cert</param>
+        /// <param name="errors">The errors associated with the certificate</param>
+        public CertificatePrompt(X509Certificate2 cert, X509Chain chain, SslPolicyErrors errors)
+        {
+            m_cert = cert;
+            InitializeComponent();
+            lblSubject.Text = m_cert.SubjectName.Name;
+            if ((errors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch)
+                lblSubject.ForeColor = Color.Red;
+            lblBegin.Text = cert.NotBefore.ToString();
+            lblEnd.Text = cert.NotAfter.ToString();
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        private void btnShow_Click(object sender, EventArgs e)
+        {
+            System.Diagnostics.Debug.Assert(!this.InvokeRequired);
+            X509Certificate2UI.DisplayCertificate(m_cert);
+            if (m_cert.Verify())
+                this.DialogResult = DialogResult.OK;
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            System.Windows.Forms.Label label1;
+            System.Windows.Forms.Label label2;
+            System.Windows.Forms.Label label3;
+            this.panel2 = new System.Windows.Forms.Panel();
+            this.btnCancel = new System.Windows.Forms.Button();
+            this.btnAllow = new System.Windows.Forms.Button();
+            this.lblSubject = new System.Windows.Forms.Label();
+            this.lblBegin = new System.Windows.Forms.Label();
+            this.lblEnd = new System.Windows.Forms.Label();
+            this.btnShow = new System.Windows.Forms.Button();
+            label1 = new System.Windows.Forms.Label();
+            label2 = new System.Windows.Forms.Label();
+            label3 = new System.Windows.Forms.Label();
+            this.panel2.SuspendLayout();
+            this.SuspendLayout();
+            //
+            // label1
+            //
+            label1.AutoSize = true;
+            label1.Location = new System.Drawing.Point(12, 9);
+            label1.Name = "label1";
+            label1.Size = new System.Drawing.Size(77, 13);
+            label1.TabIndex = 2;
+            label1.Text = "Subject Name:";
+            //
+            // label2
+            //
+            label2.AutoSize = true;
+            label2.Location = new System.Drawing.Point(12, 36);
+            label2.Name = "label2";
+            label2.Size = new System.Drawing.Size(63, 13);
+            label2.TabIndex = 3;
+            label2.Text = "Begin Date:";
+            //
+            // label3
+            //
+            label3.AutoSize = true;
+            label3.Location = new System.Drawing.Point(12, 64);
+            label3.Name = "label3";
+            label3.Size = new System.Drawing.Size(55, 13);
+            label3.TabIndex = 4;
+            label3.Text = "End Date:";
+            //
+            // panel2
+            //
+            this.panel2.Controls.Add(this.btnCancel);
+            this.panel2.Controls.Add(this.btnAllow);
+            this.panel2.Dock = System.Windows.Forms.DockStyle.Bottom;
+            this.panel2.Location = new System.Drawing.Point(0, 134);
+            this.panel2.Name = "panel2";
+            this.panel2.Size = new System.Drawing.Size(500, 44);
+            this.panel2.TabIndex = 1;
+            //
+            // btnCancel
+            //
+            this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+            this.btnCancel.Location = new System.Drawing.Point(413, 9);
+            this.btnCancel.Name = "btnCancel";
+            this.btnCancel.Size = new System.Drawing.Size(75, 23);
+            this.btnCancel.TabIndex = 2;
+            this.btnCancel.Text = "Cancel";
+            this.btnCancel.UseVisualStyleBackColor = true;
+            //
+            // btnAllow
+            //
+            this.btnAllow.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnAllow.DialogResult = System.Windows.Forms.DialogResult.OK;
+            this.btnAllow.Location = new System.Drawing.Point(332, 9);
+            this.btnAllow.Name = "btnAllow";
+            this.btnAllow.Size = new System.Drawing.Size(75, 23);
+            this.btnAllow.TabIndex = 1;
+            this.btnAllow.Text = "Allow Once";
+            this.btnAllow.UseVisualStyleBackColor = true;
+            //
+            // lblSubject
+            //
+            this.lblSubject.AutoSize = true;
+            this.lblSubject.Location = new System.Drawing.Point(126, 9);
+            this.lblSubject.Name = "lblSubject";
+            this.lblSubject.Size = new System.Drawing.Size(43, 13);
+            this.lblSubject.TabIndex = 5;
+            this.lblSubject.Text = "Subject";
+            //
+            // lblBegin
+            //
+            this.lblBegin.AutoSize = true;
+            this.lblBegin.Location = new System.Drawing.Point(126, 36);
+            this.lblBegin.Name = "lblBegin";
+            this.lblBegin.Size = new System.Drawing.Size(34, 13);
+            this.lblBegin.TabIndex = 6;
+            this.lblBegin.Text = "Begin";
+            //
+            // lblEnd
+            //
+            this.lblEnd.AutoSize = true;
+            this.lblEnd.Location = new System.Drawing.Point(126, 64);
+            this.lblEnd.Name = "lblEnd";
+            this.lblEnd.Size = new System.Drawing.Size(26, 13);
+            this.lblEnd.TabIndex = 7;
+            this.lblEnd.Text = "End";
+            //
+            // btnShow
+            //
+            this.btnShow.Location = new System.Drawing.Point(14, 90);
+            this.btnShow.Name = "btnShow";
+            this.btnShow.Size = new System.Drawing.Size(75, 23);
+            this.btnShow.TabIndex = 8;
+            this.btnShow.Text = "Trust...";
+            this.btnShow.UseVisualStyleBackColor = true;
+            this.btnShow.Click += new System.EventHandler(this.btnShow_Click);
+            //
+            // CertificatePrompt
+            //
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.CancelButton = this.btnCancel;
+            this.ClientSize = new System.Drawing.Size(500, 178);
+            this.Controls.Add(this.btnShow);
+            this.Controls.Add(this.lblEnd);
+            this.Controls.Add(this.lblBegin);
+            this.Controls.Add(this.lblSubject);
+            this.Controls.Add(label3);
+            this.Controls.Add(label2);
+            this.Controls.Add(label1);
+            this.Controls.Add(this.panel2);
+            this.Name = "CertificatePrompt";
+            this.Text = "Invalid Certificate";
+            this.panel2.ResumeLayout(false);
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+#endif
+
+    }
+}
diff --git a/lib/jabber-net/jabber/connection/CertificatePrompt.resx b/lib/jabber-net/jabber/connection/CertificatePrompt.resx
new file mode 100644
index 0000000..1332036
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/CertificatePrompt.resx
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="label1.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>False</value>
+  </metadata>
+  <metadata name="label2.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>False</value>
+  </metadata>
+  <metadata name="label3.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>False</value>
+  </metadata>
+</root>
\ No newline at end of file
diff --git a/lib/jabber-net/jabber/connection/ConferenceManager.bmp b/lib/jabber-net/jabber/connection/ConferenceManager.bmp
new file mode 100644
index 0000000..69d7cf7
Binary files /dev/null and b/lib/jabber-net/jabber/connection/ConferenceManager.bmp differ
diff --git a/lib/jabber-net/jabber/connection/ConferenceManager.cs b/lib/jabber-net/jabber/connection/ConferenceManager.cs
new file mode 100644
index 0000000..d238f73
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/ConferenceManager.cs
@@ -0,0 +1,1658 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.Diagnostics;
+
+using bedrock.util;
+using jabber.protocol;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+using jabber.client;
+using jabber.protocol.x;
+using System.ComponentModel.Design;
+
+namespace jabber.connection
+{
+
+    /// <summary>
+    /// An error occurred with a presence sent to a room.
+    /// </summary>
+    /// <param name="room"></param>
+    /// <param name="pres"></param>
+    public delegate void RoomPresenceHandler(Room room, Presence pres);
+
+    /// <summary>
+    /// Notifies the client that a room configuration form has been received.
+    /// </summary>
+    /// <param name="room">Room associated with the configuration.</param>
+    /// <param name="parent">Contains an x:data child with the form.</param>
+    /// <returns>null to take the defaults, otherwise the IQ response</returns>
+    public delegate IQ ConfigureRoom(Room room, IQ parent);
+
+    /// <summary>
+    /// An event, like join or leave, has happened to a room.
+    /// </summary>
+    /// <param name="room">The room the event is for</param>
+    public delegate void RoomEvent(Room room);
+
+    /// <summary>
+    /// An event, like join or leave, has happened to a room.
+    /// </summary>
+    /// <param name="room">The room the event is for</param>
+    /// <param name="state">State passed in by the caller, or null if none.</param>
+    public delegate void RoomStateEvent(Room room, object state);
+
+    /// <summary>
+    /// A participant-related callback.
+    /// </summary>
+    /// <param name="room">The room the event is for</param>
+    /// <param name="participant">The participant in the room</param>
+    public delegate void RoomParticipantEvent(Room room, RoomParticipant participant);
+
+    /// <summary>
+    /// A participantCollection-related callback.
+    /// </summary>
+    /// <param name="room">The room the event is for</param>
+    /// <param name="participants">The participants in the response</param>
+    /// <param name="state">State passed in by the caller, or null if none.</param>
+    public delegate void RoomParticipantsEvent(Room room, ParticipantCollection participants, object state);
+
+    /// <summary>
+    /// Manages a set of conference rooms
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ConferenceManager : StreamComponent
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+        private Hashtable m_rooms = new Hashtable();
+        private string m_nick = null;
+
+        /// <summary>
+        /// Creates a new conference manager.
+        /// </summary>
+        public ConferenceManager()
+        {
+            this.OnStreamChanged += new bedrock.ObjectHandler(ConferenceManager_OnStreamChanged);
+            InitializeComponent();
+        }
+
+        private void ConferenceManager_OnStreamChanged(object sender)
+        {
+            Stream.OnProtocol += new ProtocolHandler(Stream_OnProtocol);
+        }
+
+        private void Stream_OnProtocol(object sender, System.Xml.XmlElement rp)
+        {
+            if (OnInvite == null)
+                return;
+
+            Message msg = rp as Message;
+            if (msg == null)
+                return;
+/*
+<message
+    from='darkcave at macbeth.shakespeare.lit'
+    to='hecate at shakespeare.lit'>
+  <x xmlns='http://jabber.org/protocol/muc#user'>
+    <invite from='crone1 at shakespeare.lit/desktop'>
+      <reason>
+        Hey Hecate, this is the place for all good witches!
+      </reason>
+    </invite>
+    <password>cauldronburn</password>
+  </x>
+</message>
+ */
+            UserX x = msg["x", URI.MUC_USER] as UserX;
+            if (x == null)
+                return;
+
+            Invite inv = x["invite", URI.MUC_USER] as Invite;
+            if (inv == null)
+                return;
+
+            Room r = GetRoom(msg.From);
+            OnInvite(r, msg);
+        }
+
+        /// <summary>
+        /// Creates a new conference manager in a container
+        /// </summary>
+        /// <param name="container">Parent container.</param>
+        public ConferenceManager(IContainer container) : this()
+        {
+            container.Add(this);
+        }
+
+        /// <summary>
+        /// Performs tasks associated with freeing, releasing, or resetting resources.
+        /// </summary>
+        /// <param name="disposing">True if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Component Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            components = new System.ComponentModel.Container();
+        }
+
+        #endregion
+
+        /// <summary>
+        /// Finished joining the room, including all potential configuration.
+        /// If set, will be added to each room created through the manager.
+        /// </summary>
+        [Category("Room")]
+        public event RoomEvent OnJoin;
+
+        /// <summary>
+        /// Finished leaving the room, or was kicked/banned, or the room server went down cleanly.
+        /// If set, will be added to each room created through the manager.
+        /// </summary>
+        [Category("Room")]
+        public event RoomPresenceHandler OnLeave;
+
+        /// <summary>
+        /// Error in response to a room join, nick change, or presence update.
+        /// If set, will be added to each room created through the manager.
+        /// </summary>
+        [Category("Room")]
+        public event RoomPresenceHandler OnPresenceError;
+
+        /// <summary>
+        /// Room configuration form received.  It is up to the listener call FinishConfig().
+        /// The IQ in the callback is the parent of the x:data element.
+        /// If set, will be added to each room created through the manager.
+        /// </summary>
+        [Category("Room")]
+        public event ConfigureRoom OnRoomConfig;
+
+        /// <summary>
+        /// A message broadcast to all in the room
+        /// If set, will be added to each room created through the manager.
+        /// </summary>
+        [Category("Room")]
+        public event MessageHandler OnRoomMessage;
+
+        /// <summary>
+        /// A side-chat message.
+        /// If set, will be added to each room created through the manager.
+        /// </summary>
+        [Category("Room")]
+        public event MessageHandler OnPrivateMessage;
+
+        /// <summary>
+        /// An admin message from the room itself.  Typically status change sorts of things
+        /// like kick/ban.
+        /// If set, will be added to each room created through the manager.
+        /// </summary>
+        [Category("Room")]
+        public event MessageHandler OnAdminMessage;
+
+        /// <summary>
+        /// A message that was sent by this user to the room, echo'd back.
+        /// If set, will be added to each room created through the manager.
+        /// </summary>
+        [Category("Room")]
+        public event MessageHandler OnSelfMessage;
+
+        /// <summary>
+        /// The subject of the room has been changed
+        /// If set, will be added to each room created through the manager.
+        /// </summary>
+        [Category("Room")]
+        public event MessageHandler OnSubjectChange;
+
+        /// <summary>
+        /// A participant has joined the room.  This will not fire for yourself.
+        /// If set, will be added to each room created through the manager.
+        /// </summary>
+        [Category("Room")]
+        public event RoomParticipantEvent OnParticipantJoin;
+
+        /// <summary>
+        /// A participant has left the room.  This will not fire for yourself.
+        /// If set, will be added to each room created through the manager.
+        /// </summary>
+        [Category("Room")]
+        public event RoomParticipantEvent OnParticipantLeave;
+
+        /// <summary>
+        /// A participant has changed presence, without joining or leaving the room.  This will not fire for yourself.
+        /// If set, will be added to each room created through the manager.
+        /// </summary>
+        [Category("Room")]
+        public event RoomParticipantEvent OnParticipantPresenceChange;
+
+        /// <summary>
+        /// An invite was received.  A room object will be passed in as the sender.
+        /// </summary>
+        [Category("Manager")]
+        public event MessageHandler OnInvite;
+
+        /// <summary>
+        /// The default room nickname, if one is not specified.  If none
+        /// specified, the user name from the stream JID is used.
+        /// </summary>
+        [Category("Manager")]
+        [DefaultValue(null)]
+        public string DefaultNick
+        {
+            get 
+            { 
+                if (m_nick != null)
+                    return m_nick;
+                if ((m_stream == null) || m_stream.JID == null)
+                    return null;
+                return m_stream.JID.User;
+            }
+            set { m_nick = value; }
+        }
+
+        /// <summary>
+        /// Joins a conference room.
+        /// </summary>
+        /// <param name="roomAndNick">room at conference/nick, where "nick" is the desred nickname in the room.</param>
+        /// <returns>
+        /// If already joined, the existing room will be returned.
+        /// If not, a Room object will be returned in the joining state.
+        /// </returns>
+        public Room GetRoom(JID roomAndNick)
+        {
+            if (roomAndNick == null)
+                throw new ArgumentNullException("roomAndNick");
+
+            if (roomAndNick.Resource == null)
+                roomAndNick.Resource = DefaultNick;
+
+            Room r = (Room)m_rooms[roomAndNick];
+            if (r != null)
+                return r;
+
+            // If no resource specified, pick up the user's name from their JID
+            if (roomAndNick.Resource == null)
+                roomAndNick.Resource = m_stream.JID.User;
+
+            r = new Room(this, roomAndNick);
+            r.OnJoin += OnJoin;
+            r.OnLeave += OnLeave;
+            r.OnPresenceError += OnPresenceError;
+            r.OnRoomConfig += OnRoomConfig;
+            r.OnRoomMessage += OnRoomMessage;
+            r.OnPrivateMessage += OnPrivateMessage;
+            r.OnAdminMessage += OnAdminMessage;
+            r.OnSelfMessage += OnSelfMessage;
+            r.OnSubjectChange += OnSubjectChange;
+            r.OnParticipantJoin += OnParticipantJoin;
+            r.OnParticipantLeave += OnParticipantLeave;
+            r.OnParticipantPresenceChange += OnParticipantPresenceChange;
+
+            m_rooms[roomAndNick] = r;
+            return r;
+        }
+
+        /// <summary>
+        /// Determines whether or not the conference room is being managed
+        /// by this ConferenceManager.
+        /// </summary>
+        /// <param name="roomAndNick">Room to look for.</param>
+        /// <returns>True if the room is being managed.</returns>
+        public bool HasRoom(JID roomAndNick)
+        {
+            return m_rooms.ContainsKey(roomAndNick);
+        }
+
+        /// <summary>
+        /// Removes the room from the list.
+        /// Should most often be called by the Room.Leave() method.
+        /// If the room does not exist, no exception is thrown.
+        /// </summary>
+        /// <param name="roomAndNick">Room to remove.</param>
+        public void RemoveRoom(JID roomAndNick)
+        {
+            m_rooms.Remove(roomAndNick);
+        }
+
+        private class UniqueState
+        {
+            public string Nick;
+            public RoomStateEvent Callback;
+            public object State;
+
+            public UniqueState(string nick, RoomStateEvent callback, object state)
+            {
+                this.Nick = nick;
+                this.Callback = callback;
+                this.State = state;
+            }
+        }
+
+        /// <summary>
+        /// Get a unique room name from the given server, and create a Room
+        /// object for that room with the given nick.  You'll be called back on
+        /// "callback" when complete; the Room will be null if there was an error
+        /// or timeout.
+        ///
+        /// Note: the server should implement the feature http://jabber.org/protocol/muc#unique,
+        /// or this will return an error.  To work around, just create a room with a Guid for
+        /// a name.
+        /// </summary>
+        /// <param name="server">The server to send the request to</param>
+        /// <param name="nick">The nickname desired in the new room</param>
+        /// <param name="callback">A callback to be called when the room is created</param>
+        /// <param name="state">State object to be passed back when the callback fires</param>
+        public void GetUniqueRoom(string server, string nick, RoomStateEvent callback, object state)
+        {
+            if (server == null)
+                throw new ArgumentNullException("server");
+            if (nick == null)
+                throw new ArgumentNullException("nick");
+            if (callback == null)
+                throw new ArgumentNullException("callback");
+
+/*
+<iq from='crone1 at shakespeare.lit/desktop'
+    id='unique1'
+    to='macbeth.shakespeare.lit'
+    type='get'>
+  <unique xmlns='http://jabber.org/protocol/muc#unique'/>
+</iq>
+ */
+            UniqueIQ iq = new UniqueIQ(m_stream.Document);
+            iq.To = server;
+            BeginIQ(iq, new IqCB(GotUnique), new UniqueState(nick, callback, state));
+        }
+
+        private void GotUnique(object sender, IQ iq, object state)
+        {
+            UniqueState us = (UniqueState)state;
+            if ((iq == null) || (iq.Type == IQType.error))
+            {
+                us.Callback(null, us.State);
+                return;
+            }
+
+/*
+<iq from='macbeth.shakespeare.lit'
+    id='unique1'
+    to='crone1 at shakespeare.lit/desktop'
+    type='result'>
+  <unique xmlns='http://jabber.org/protocol/muc#unique'>
+    6d9423a55f499b29ad20bf7b2bdea4f4b885ead1
+  </unique>
+</iq>
+ */
+            UniqueRoom unique = (UniqueRoom)iq.Query;
+            Room r = GetRoom(new JID(unique.RoomNode, iq.From.Server, us.Nick));
+            us.Callback(r, us.State);
+        }
+    }
+
+    /// <summary>
+    /// Manages a multi-user conference room.  See XEP-0045 (http://www.xmpp.org/extensions/xep-0045.html).
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Room
+    {
+        private enum STATE
+        {
+            start,
+            join,
+            configGet,
+            configSet,
+            running,
+            leaving,
+            error
+        }
+
+        private STATE m_state = STATE.start;
+        /// <summary>
+        /// Nick JID.  room at conference/nick.
+        /// </summary>
+        private JID m_jid;
+        /// <summary>
+        /// Bare room JID.  room at conference
+        /// </summary>
+        private JID m_room;
+        //private XmppStream m_stream;
+        private bool m_default = false;
+        private ConferenceManager m_manager;
+        private Message m_subject;
+        private ParticipantCollection m_participants = new ParticipantCollection();
+        private object m_tag;
+
+        /// <summary>
+        /// Create.
+        /// </summary>
+        /// <param name="manager">The manager for this room.</param>
+        /// <param name="roomAndNick">room at conference/nick, where "nick" is the desred nickname in the room.</param>
+        internal Room(ConferenceManager manager, JID roomAndNick)
+        {
+            m_manager = manager;
+            XmppStream stream = manager.Stream;
+            m_jid = roomAndNick;
+            m_room = new JID(m_jid.User, m_jid.Server, null);
+            stream.OnProtocol += new jabber.protocol.ProtocolHandler(m_stream_OnProtocol);
+            JabberClient jc = stream as JabberClient;
+            if (jc != null)
+                jc.OnAfterPresenceOut += new jabber.client.PresenceHandler(m_stream_OnAfterPresenceOut);
+        }
+
+        /// <summary>
+        /// Finished joining the room, including all potential configuration.
+        /// </summary>
+        public event RoomEvent OnJoin;
+
+        /// <summary>
+        /// Finished leaving the room, or was kicked/banned, or the room server went down cleanly.
+        /// </summary>
+        public event RoomPresenceHandler OnLeave;
+
+        /// <summary>
+        /// Informs the client that an error in response to a room join,
+        /// nick change, or presence update has occurred.
+        /// </summary>
+        public event RoomPresenceHandler OnPresenceError;
+
+        /// <summary>
+        /// Informs the client that the room configuration form was received.
+        /// It is up to the listener to call the FinishConfig() method.
+        /// The IQ in the callback is the parent of the x:data element.
+        /// </summary>
+        public event ConfigureRoom OnRoomConfig;
+
+        /// <summary>
+        /// A message broadcast to all in the room
+        /// </summary>
+        public event MessageHandler OnRoomMessage;
+
+        /// <summary>
+        /// A message that was sent by this user to the room, echo'd back.
+        /// </summary>
+        public event MessageHandler OnSelfMessage;
+
+        /// <summary>
+        /// A side-chat message.
+        /// </summary>
+        public event MessageHandler OnPrivateMessage;
+
+        /// <summary>
+        /// An admin message from the room itself.  Typically status change sorts of things
+        /// like kick/ban.
+        /// </summary>
+        public event MessageHandler OnAdminMessage;
+
+        /// <summary>
+        /// The subject of the room has been changed
+        /// </summary>
+        public event MessageHandler OnSubjectChange;
+
+        /// <summary>
+        /// A participant has joined the room.  This will not fire for yourself.
+        /// </summary>
+        [Category("Room")]
+        public event RoomParticipantEvent OnParticipantJoin;
+
+        /// <summary>
+        /// A participant has left the room.  This will not fire for yourself.
+        /// </summary>
+        [Category("Room")]
+        public event RoomParticipantEvent OnParticipantLeave;
+
+        /// <summary>
+        /// A participant has changed presence, without joining or leaving the room.  This will not fire for yourself.
+        /// </summary>
+        [Category("Room")]
+        public event RoomParticipantEvent OnParticipantPresenceChange;
+
+        /// <summary>
+        /// Determines whether to use the default conference room configuration
+        /// or to retrieve the configuration form from the XMPP server.
+        /// </summary>
+        [DefaultValue(false)]
+        public bool DefaultConfig
+        {
+            get { return m_default; }
+            set { m_default = value; }
+        }
+
+        /// <summary>
+        /// The subject of the room.  Set has the side-effect of sending to the server.
+        /// </summary>
+        public string Subject
+        {
+            get { return m_subject.Subject; }
+            set
+            {
+                Message m = new Message(m_manager.Stream.Document);
+                m.To = m_room;
+                m.Type = MessageType.groupchat;
+                m.Subject = value;
+                m.Body = "/me has changed the subject to: " + value;
+                m_manager.Write(m);
+            }
+        }
+
+        /// <summary>
+        /// The full JID of the user in the room.  room at service/nick
+        /// </summary>
+        public JID RoomAndNick
+        {
+            get { return m_jid; }
+        }
+
+        /// <summary>
+        /// The bare JID of the room.  room at service
+        /// </summary>
+        public JID JID
+        {
+            get { return m_room; }
+        }
+
+        /// <summary>
+        /// Have we joined the room successfully?
+        /// </summary>
+        public bool IsParticipating
+        {
+            get { return m_state == STATE.running; }
+        }
+
+        /// <summary>
+        /// The nickname that others in the room will see for you.
+        /// Set has the side-effect of changing the nickname on the server.
+        /// </summary>
+        public string Nickname
+        {
+            get { return m_jid.Resource; }
+            set
+            {
+                m_jid = new JID(m_jid.User, m_jid.Server, value);
+                Presence p = new Presence(m_manager.Stream.Document);
+                p.To = m_jid;
+                m_manager.Write(p);
+            }
+        }
+
+        /// <summary>
+        /// Current room participants.
+        /// </summary>
+        /// <returns></returns>
+        public ParticipantCollection Participants
+        {
+            get { return m_participants; }
+        }
+
+        /// <summary>
+        /// Extra data associated with the room.
+        /// </summary>
+        public object Tag
+        {
+            get { return m_tag; }
+            set { m_tag = value; }
+        }
+
+        /// <summary>
+        /// Whenver we change presence, send the new presence to the room, including
+        /// caps etc.
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="pres"></param>
+        private void m_stream_OnAfterPresenceOut(object sender, Presence pres)
+        {
+            Presence p = (Presence)pres.CloneNode(true);
+            p.To = m_room;
+            m_manager.Write(p);
+        }
+
+        private void m_stream_OnProtocol(object sender, System.Xml.XmlElement rp)
+        {
+            // There isn't always a from address.  iq:roster, for example.
+            string af = rp.GetAttribute("from");
+            if (af == "")
+                return;
+            JID from = new JID(af);
+            if (from.Bare != (string)m_room)
+                return;  // not for this room.
+
+            switch (rp.LocalName)
+            {
+            case "presence":
+                Presence p = (Presence)rp;
+                if (p.Error != null)
+                {
+                    m_state = STATE.error;
+                    if (OnPresenceError != null)
+                        OnPresenceError(this, p);
+                    return;
+                }
+
+                ParticipantCollection.Modification mod = ParticipantCollection.Modification.NONE;
+                RoomParticipant party = m_participants.Modify(p, out mod);
+
+                // if this is ours
+                if (p.From == m_jid)
+                {
+                    switch (m_state)
+                    {
+                    case STATE.join:
+                        OnJoinPresence(p);
+                        break;
+                    case STATE.leaving:
+                        OnLeavePresence(p);
+                        break;
+                    case STATE.running:
+                        if (p.Type == PresenceType.unavailable)
+                            OnLeavePresence(p);
+                        break;
+                    }
+                }
+                else
+                {
+                    switch (mod)
+                    {
+                    case ParticipantCollection.Modification.NONE:
+                        if (OnParticipantPresenceChange != null)
+                            OnParticipantPresenceChange(this, party);
+                        break;
+                    case ParticipantCollection.Modification.JOIN:
+                        if (OnParticipantJoin != null)
+                            OnParticipantJoin(this, party);
+                        break;
+                    case ParticipantCollection.Modification.LEAVE:
+                        if (OnParticipantLeave != null)
+                            OnParticipantLeave(this, party);
+                        break;
+                    }
+                }
+                break;
+            case "message":
+                Message m = (Message)rp;
+                if (m.Type == MessageType.groupchat)
+                {
+                    if (m.Subject != null)
+                    {
+                        if (OnSubjectChange != null)
+                            OnSubjectChange(this, m);
+                        m_subject = m;
+                    }
+                    else if (m.From == m_jid)
+                    {
+                        if (OnSelfMessage != null)
+                            OnSelfMessage(this, m);
+                    }
+                    else
+                    {
+                        if (OnRoomMessage != null)
+                            OnRoomMessage(this, m);
+                    }
+                }
+                else
+                {
+                    if (m.From.Resource == null)
+                    {
+                        // room notification of some kind
+                        if (OnAdminMessage != null)
+                            OnAdminMessage(this, m);
+                    }
+                    else
+                    {
+                        if (OnPrivateMessage != null)
+                            OnPrivateMessage(this, m);
+                    }
+                }
+                break;
+            case "iq":
+                // TODO: IQs the room sends to us.
+                break;
+            }
+        }
+
+        private void OnJoinPresence(Presence p)
+        {
+            // from is always us.
+/*
+<presence
+    to='crone1 at shakespeare.lit/desktop'>
+  <x xmlns='http://jabber.org/protocol/muc#user'>
+    <item affiliation='owner'
+          role='moderator'/>
+    <status code='201'/>
+  </x>
+</presence>
+ */
+            UserX x = p["x", URI.MUC_USER] as UserX;
+            if (x == null)
+            {
+                // Old server.  Hope for the best.
+                if (OnJoin != null)
+                    OnJoin(this);
+                return;
+            }
+
+            if (x.HasStatus(RoomStatus.CREATED))
+            {
+                // room was created.  this must be me.
+                if (m_default || (OnRoomConfig == null))
+                    FinishConfigDefault();
+                else
+                    Configure();
+                return;
+            }
+
+            // if it wasn't created, and this is mine, we must be running.
+            m_state = STATE.running;
+            if (OnJoin != null)
+                OnJoin(this);
+        }
+
+        private void OnLeavePresence(Presence p)
+        {
+/*
+<presence
+    to='hag66 at shakespeare.lit/pda'
+    type='unavailable'>
+  <x xmlns='http://jabber.org/protocol/muc#user'>
+    <item affiliation='member' role='none'/>
+    <status code='110'/>
+  </x>
+</presence>
+ */
+            // not quite an assert.  some sort of race.
+            if (p.Type != PresenceType.unavailable)
+                return;
+
+            m_manager.Stream.OnProtocol -= new jabber.protocol.ProtocolHandler(m_stream_OnProtocol);
+            jabber.client.JabberClient jc = m_manager.Stream as jabber.client.JabberClient;
+            if (jc != null)
+                jc.OnAfterPresenceOut -= new jabber.client.PresenceHandler(m_stream_OnAfterPresenceOut);
+            m_manager.RemoveRoom(m_jid); // should cause this object to GC.
+            if (OnLeave != null)
+                OnLeave(this, p);
+        }
+
+        /// <summary>
+        /// Configures the room. OnRoomConfig MUST be set first.
+        /// OnRoomConfig will be called back in the GUI thread if there is an
+        /// InvokeControl on your XmppStream.  Make sure that OnRoomConfig does not
+        /// return until it has the answer, typically by popping up a modal dialog
+        /// with the x:data form.
+        /// </summary>
+        public void Configure()
+        {
+            if (OnRoomConfig == null)
+                throw new ArgumentNullException("Must set OnRoomConfig before calling Configure()", "OnRoomConfig");
+
+/*
+<iq id='create1'
+    to='darkcave at macbeth.shakespeare.lit'
+    type='get'>
+  <query xmlns='http://jabber.org/protocol/muc#owner'/>
+</iq>
+ */
+            m_state = STATE.configGet;
+            OwnerIQ iq = new OwnerIQ(m_manager.Stream.Document);
+            iq.Type = IQType.get;
+            iq.To = m_room;
+            m_manager.BeginIQ(iq, new IqCB(ConfigForm), null);
+        }
+
+        private void ConfigForm(object sender, IQ iq, object context)
+        {
+            // We should always be on the GUI thread.
+            // XmppStream should invoke before calling OnProtocol in the Tracker.
+            Debug.Assert((m_manager.Stream.InvokeControl == null) || (!m_manager.Stream.InvokeControl.InvokeRequired));
+
+            IQ resp = OnRoomConfig(this, iq);
+            if (resp == null)
+            {
+                FinishConfigDefault();
+                return;
+            }
+
+            m_state = STATE.configSet;
+            resp.To = m_room;
+            resp.Type = IQType.set;
+            resp.From = null;
+            m_manager.BeginIQ(resp, new IqCB(Configured), null);
+        }
+
+        private void Configured(object sender, IQ iq, object context)
+        {
+            if (iq.Type != IQType.result)
+            {
+                m_state = STATE.error;
+                // TODO: fire an error
+                return;
+            }
+
+            if (m_state != STATE.running)
+            {
+                // reconfigs don't call OnJoin
+                m_state = STATE.running;
+                if (OnJoin != null)
+                    OnJoin(this);
+            }
+        }
+
+        /// <summary>
+        /// Finish up configuration, taking the default room config.  Also known as
+        /// an "Instant Room".  Suitable for use if the user cancels the configuration
+        /// request, perhaps.
+        /// </summary>
+        private void FinishConfigDefault()
+        {
+/*
+<iq from='crone1 at shakespeare.lit/desktop'
+    id='create1'
+    to='darkcave at macbeth.shakespeare.lit'
+    type='set'>
+  <query xmlns='http://jabber.org/protocol/muc#owner'>
+    <x xmlns='jabber:x:data' type='submit'/>
+  </query>
+</iq>
+ */
+            m_state = STATE.configSet;
+            OwnerIQ iq = new OwnerIQ(m_manager.Stream.Document);
+            iq.Type = IQType.set;
+            iq.To = m_room;
+            OwnerQuery oq = iq.Instruction;
+            Data form = oq.Form;
+            form.Type = XDataType.submit;
+            m_manager.BeginIQ(iq, new IqCB(Configured), null);
+        }
+
+        /// <summary>
+        /// Joins the room.  If the room is created, Configure() will
+        /// be called automatically.
+        /// </summary>
+        public void Join()
+        {
+            Join(null);
+        }
+
+        /// <summary>
+        /// Join a room, using a password.
+        /// </summary>
+        /// <param name="password"></param>
+        public void Join(string password)
+        {
+            if (m_state == STATE.running)
+                return;
+
+            m_state = STATE.join;
+            RoomPresence pres = new RoomPresence(m_manager.Stream.Document, m_jid);
+            if (password != null)
+                pres.X.Password = password;
+
+            m_manager.Write(pres);
+        }
+
+        /// <summary>
+        /// Exits the room.  This cleans up the entry in the ConferenceManager, as well.
+        /// </summary>
+        /// <param name="reason">Reason for leaving the room.  May be null for no reason.</param>
+        public void Leave(string reason)
+        {
+            m_state = STATE.leaving;
+
+/*
+<presence
+    to='darkcave at macbeth.shakespeare.lit/oldhag'
+    type='unavailable'>
+  <status>gone where the goblins go</status>
+</presence>
+ */
+            Presence p = new Presence(m_manager.Stream.Document);
+            p.To = m_jid;
+            p.Type = PresenceType.unavailable;
+            if (reason != null)
+                p.Status = reason;
+            m_manager.Write(p);
+
+
+            // cleanup done when unavailable/110 received.
+        }
+
+        /// <summary>
+        /// Sends a message to everyone currently in the room.
+        /// </summary>
+        /// <param name="body">The message text to send.</param>
+        public void PublicMessage(string body)
+        {
+            if (m_state != STATE.running)
+                throw new InvalidOperationException("Must be in running state to send message: " + m_state.ToString());
+/*
+<message
+    to='darkcave at macbeth.shakespeare.lit'
+    type='groupchat'>
+  <body>Harpier cries: 'tis time, 'tis time.</body>
+</message>
+ */
+            if (body == null)
+                throw new ArgumentNullException("body");
+            Message m = new Message(m_manager.Stream.Document);
+            m.To = m_room;
+            m.Type = MessageType.groupchat;
+            m.Body = body;
+            m_manager.Write(m);
+        }
+
+        /// <summary>
+        /// Sends a private message to a single user in the room.
+        /// </summary>
+        /// <param name="nick">The nickname of the user to send a private message to.</param>
+        /// <param name="body">The message body to send.</param>
+        public void PrivateMessage(string nick, string body)
+        {
+            if (m_state != STATE.running)
+                throw new InvalidOperationException("Must be in running state to send message: " + m_state.ToString());
+
+/*
+<message
+    to='darkcave at macbeth.shakespeare.lit/firstwitch'
+    type='chat'>
+  <body>I'll give thee a wind.</body>
+</message>
+ */
+            if (nick == null)
+                throw new ArgumentNullException("nick");
+            if (body == null)
+                throw new ArgumentNullException("body");
+
+            Message m = new Message(m_manager.Stream.Document);
+            m.To = new JID(m_room.User, m_room.Server, nick);
+            m.Type = MessageType.chat;
+            m.Body = body;
+            m_manager.Write(m);
+        }
+
+        /// <summary>
+        /// Invite a user to join the room.
+        /// </summary>
+        /// <param name="invitee">The JID of the person to invite</param>
+        /// <param name="reason">The reason for the invite, or null for none.</param>
+        public void Invite(JID invitee, string reason)
+        {
+            if (m_state != STATE.running)
+                throw new InvalidOperationException("Must be in running state to send invite: " + m_state.ToString());
+
+            if (invitee == null)
+                throw new ArgumentNullException("invitee");
+/*
+<message
+    from='crone1 at shakespeare.lit/desktop'
+    to='darkcave at macbeth.shakespeare.lit'>
+  <x xmlns='http://jabber.org/protocol/muc#user'>
+    <invite to='hecate at shakespeare.lit'>
+      <reason>
+        Hey Hecate, this is the place for all good witches!
+      </reason>
+    </invite>
+  </x>
+</message>
+ */
+            Message m = new Message(m_manager.Stream.Document);
+            m.To = m_room;
+            UserX x = new UserX(m_manager.Stream.Document);
+            x.AddInvite(invitee, reason);
+            m.AddChild(x);
+            m_manager.Write(m);
+        }
+
+#region Moderator use cases
+        /// <summary>
+        /// Change the role of a user in the room, by nickname.  Must be a moderator.
+        /// </summary>
+        /// <param name="nick">The nickname of the user to modify.</param>
+        /// <param name="role">The new role</param>
+        /// <param name="reason">The reason for the change</param>
+        public void ChangeRole(string nick, RoomRole role, string reason)
+        {
+            if (m_state != STATE.running)
+                throw new InvalidOperationException("Must be in running state to change role: " + m_state.ToString());
+
+            if (nick == null)
+                throw new ArgumentNullException("nick");
+            if (role == RoomRole.UNSPECIFIED)
+                throw new ArgumentNullException("role");
+/*
+<iq from='fluellen at shakespeare.lit/pda'
+    id='kick1'
+    to='harfleur at henryv.shakespeare.lit'
+    type='set'>
+  <query xmlns='http://jabber.org/protocol/muc#admin'>
+    <item nick='pistol' role='none'>
+      <reason>Avaunt, you cullion!</reason>
+    </item>
+  </query>
+</iq>
+*/
+            RoomAdminIQ iq = new RoomAdminIQ(m_manager.Stream.Document);
+            iq.To = m_room;
+            iq.Type = IQType.set;
+            AdminQuery query = iq.Instruction;
+            AdminItem item = query.AddItem();
+            item.Nick = nick;
+            item.Role = role;
+            item.Reason = reason;
+            m_manager.BeginIQ(iq, null, null);
+        }
+
+        /// <summary>
+        /// Kick the given user from the room, based on their nickname.
+        /// </summary>
+        /// <param name="nick">The nickname of the person to kick</param>
+        /// <param name="reason">The reason for kicking, or null for none.</param>
+        public void Kick(string nick, string reason)
+        {
+            ChangeRole(nick, RoomRole.none, reason);
+        }
+
+        /// <summary>
+        /// Disallow a user from speaking; remove their "voice".
+        /// </summary>
+        /// <param name="nick">The nickname of the person to mute</param>
+        /// <param name="reason">The reason for the muting</param>
+        public void RevokeVoice(string nick, string reason)
+        {
+            ChangeRole(nick, RoomRole.visitor, reason);
+        }
+
+        /// <summary>
+        /// Un-mute a muted user.  Give them "voice".
+        /// </summary>
+        /// <param name="nick">The nicname of the person to unmute</param>
+        /// <param name="reason">The reason for the change</param>
+        public void GrantVoice(string nick, string reason)
+        {
+            ChangeRole(nick, RoomRole.participant, reason);
+        }
+
+        private class RetrieveParticipantsState
+        {
+            public RoomParticipantsEvent Callback;
+            public object State;
+
+            public RetrieveParticipantsState(RoomParticipantsEvent callback, object state)
+            {
+                this.Callback = callback;
+                this.State = state;
+            }
+        }
+
+        /// <summary>
+        /// Retrieve all of the parties with a given role.
+        /// Modify the affiliations of persons in this list, then call ModifyRoles
+        /// </summary>
+        /// <param name="role">The role to search for</param>
+        /// <param name="callback">A callback to receive the participant list</param>
+        /// <param name="state">Caller state information</param>
+        public void RetrieveListByRole(RoomRole role, RoomParticipantsEvent callback, object state)
+        {
+            if (callback == null)
+                throw new ArgumentNullException("callback");
+/*
+<iq from='bard at shakespeare.lit/globe'
+    id='voice3'
+    to='goodfolk at chat.shakespeare.lit'
+    type='get'>
+  <query xmlns='http://jabber.org/protocol/muc#admin'>
+    <item role='participant'/>
+  </query>
+</iq>
+*/
+            RoomAdminIQ iq = new RoomAdminIQ(m_manager.Stream.Document);
+            iq.To = m_room;
+            AdminQuery query = iq.Instruction;
+            query.AddItem().Role = role;
+            m_manager.BeginIQ(iq, new IqCB(GotList), new RetrieveParticipantsState(callback, state));
+        }
+
+        private void GotList(object sender, IQ iq, object state)
+        {
+            RetrieveParticipantsState rps = (RetrieveParticipantsState)state;
+            if (iq.Type == IQType.error)
+            {
+                rps.Callback(this, null, rps.State);
+                return;
+            }
+/*
+<iq from='southampton at henryv.shakespeare.lit'
+    id='ban2'
+    to='kinghenryv at shakespeare.lit/throne'
+    type='result'>
+  <query xmlns='http://jabber.org/protocol/muc#admin'>
+    <item affiliation='outcast'
+          jid='earlofcambridge at shakespeare.lit'>
+      <reason>Treason</reason>
+    </item>
+  </query>
+</iq>
+*/
+            ParticipantCollection parties = new ParticipantCollection();
+            AdminQuery query = (AdminQuery)iq.Query;
+            ParticipantCollection.Modification mod;
+            foreach (AdminItem item in query.GetItems())
+            {
+                Presence pres = new Presence(m_manager.Stream.Document);
+                pres.From = new JID(m_jid.User, m_jid.Server, item.Nick);
+                UserX x = new UserX(m_manager.Stream.Document);
+                RoomItem xi = x.RoomItem;
+                xi.Role = item.Role;
+                xi.Affiliation = item.Affiliation;
+                xi.Nick = item.Nick;
+                xi.JID = item.JID;
+                pres.AppendChild(x);
+                parties.Modify(pres, out mod);
+            }
+            rps.Callback(this, parties, rps.State);
+        }
+
+        /// <summary>
+        /// Modify the roles of the parties in this list.
+        /// To use, retrive a ParticipantCollection, change the roles
+        /// of the parties in that collection, then pass that modified
+        /// collection in here.
+        /// </summary>
+        /// <param name="parties">The modified participant collection</param>
+        /// <param name="reason">The reason for the change</param>
+        /// <param name="callback">A callback to call when complete.  Will have a null IQ if there were no changes to make.</param>
+        /// <param name="state">Caller's state information</param>
+        public void ModifyRoles(ParticipantCollection parties, string reason, IqCB callback, object state)
+        {
+/*
+<iq from='bard at shakespeare.lit/globe'
+    id='voice4'
+    to='goodfolk at chat.shakespeare.lit'
+    type='set'>
+  <query xmlns='http://jabber.org/protocol/muc#admin'>
+    <item nick='Hecate'
+          role='visitor'/>
+    <item nick='rosencrantz'
+          role='participant'>
+      <reason>A worthy fellow.</reason>
+    </item>
+    <item nick='guildenstern'
+          role='participant'>
+      <reason>A worthy fellow.</reason>
+    </item>
+  </query>
+</iq>
+*/
+            RoomAdminIQ iq = new RoomAdminIQ(m_manager.Stream.Document);
+            iq.To = m_room;
+            iq.Type = IQType.set;
+            AdminQuery query = iq.Instruction;
+
+            int count = 0;
+            foreach (RoomParticipant party in parties)
+            {
+                if (party.Changed)
+                {
+                    count++;
+                    AdminItem item = query.AddItem();
+                    item.Nick = party.Nick;
+                    item.Role = party.Role;
+                    item.Reason = reason;
+                }
+            }
+            if (count > 0)
+                m_manager.BeginIQ(iq, callback, state);
+            else
+                callback(this, null, state);
+        }
+
+#endregion
+
+#region Admin use cases
+        /// <summary>
+        /// Change the affiliation (long-term) with the room of a user, based on their real JID.
+        /// </summary>
+        /// <param name="jid">The bare JID of the user of which to change the affiliation</param>
+        /// <param name="affiliation">The new affiliation</param>
+        /// <param name="reason">The reason for the change</param>
+        public void ChangeAffiliation(JID jid, RoomAffiliation affiliation, string reason)
+        {
+            if (m_state != STATE.running)
+                throw new InvalidOperationException("Must be in running state to change affiliation: " + m_state.ToString());
+            if (jid == null)
+                throw new ArgumentNullException("jid");
+            if (affiliation == RoomAffiliation.UNSPECIFIED)
+                throw new ArgumentNullException("affiliation");
+/*
+<iq from='kinghenryv at shakespeare.lit/throne'
+    id='ban1'
+    to='southampton at henryv.shakespeare.lit'
+    type='set'>
+  <query xmlns='http://jabber.org/protocol/muc#admin'>
+    <item affiliation='outcast'
+          jid='earlofcambridge at shakespeare.lit'>
+      <reason>Treason</reason>
+    </item>
+  </query>
+</iq>
+ */
+            RoomAdminIQ iq = new RoomAdminIQ(m_manager.Stream.Document);
+            iq.To = m_room;
+            iq.Type = IQType.set;
+            AdminQuery query = iq.Instruction;
+            AdminItem item = query.AddItem();
+            item.JID = jid;
+            item.Affiliation = affiliation;
+            item.Reason = reason;
+            m_manager.BeginIQ(iq, null, null);
+        }
+
+        /// <summary>
+        /// Ban a user from re-joining the room.  Must be an admin.
+        /// </summary>
+        /// <param name="jid">The bare JID of the user to ban</param>
+        /// <param name="reason">The reason for the shunning</param>
+        public void Ban(JID jid, string reason)
+        {
+            ChangeAffiliation(jid, RoomAffiliation.outcast, reason);
+        }
+
+        /// <summary>
+        /// Make this user a member of the room.
+        /// </summary>
+        /// <param name="jid">The bare jid of the user to grant membership to.</param>
+        /// <param name="reason"></param>
+        public void GrantMembership(JID jid, string reason)
+        {
+            ChangeAffiliation(jid, RoomAffiliation.member, reason);
+        }
+
+        /// <summary>
+        /// Remove the membership privileges of the given user
+        /// </summary>
+        /// <param name="jid">The bare jid of the user to revoke the membership of.</param>
+        /// <param name="reason"></param>
+        public void RevokeMembership(JID jid, string reason)
+        {
+            // Or "Dismember".
+            ChangeAffiliation(jid, RoomAffiliation.none, reason);
+        }
+
+        /// <summary>
+        /// Make this user a moderator of the room.
+        /// </summary>
+        /// <param name="nick">The nickname of the user to change</param>
+        public void MakeModerator(string nick)
+        {
+            ChangeRole(nick, RoomRole.moderator, null);
+        }
+
+        /// <summary>
+        /// Retrieve all of the parties with a given affiliiation.
+        /// Modify the affiliations of persons in this list, then call ModifyAffiliations
+        /// </summary>
+        /// <param name="affiliation">The affiliation to search for</param>
+        /// <param name="callback">A callback to receive the participant list</param>
+        /// <param name="state">Caller state information</param>
+        public void RetrieveListByAffiliation(RoomAffiliation affiliation, RoomParticipantsEvent callback, object state)
+        {
+            if (callback == null)
+                throw new ArgumentNullException("callback");
+/*
+<iq from='kinghenryv at shakespeare.lit/throne'
+    id='ban2'
+    to='southampton at henryv.shakespeare.lit'
+    type='get'>
+  <query xmlns='http://jabber.org/protocol/muc#admin'>
+    <item affiliation='outcast'/>
+  </query>
+</iq>
+*/
+            RoomAdminIQ iq = new RoomAdminIQ(m_manager.Stream.Document);
+            iq.To = m_room;
+            AdminQuery query = iq.Instruction;
+            query.AddItem().Affiliation = affiliation;
+            m_manager.BeginIQ(iq, new IqCB(GotList), new RetrieveParticipantsState(callback, state));
+        }
+
+        /// <summary>
+        /// Modify the roles of the parties in this list.
+        /// To use, retrive a ParticipantCollection, change the roles
+        /// of the parties in that collection, then pass that modified
+        /// collection in here.
+        /// </summary>
+        /// <param name="parties">The modified participant collection</param>
+        /// <param name="reason">The reason for the change</param>
+        /// <param name="callback">A callback to call when complete.  Will have a null IQ if there were no changes to make.</param>
+        /// <param name="state">Caller's state information</param>
+        public void ModifyAffiliations(ParticipantCollection parties, string reason, IqCB callback, object state)
+        {
+/*
+<iq from='southampton at henryv.shakespeare.lit'
+    id='ban2'
+    to='kinghenryv at shakespeare.lit/throne'
+    type='result'>
+  <query xmlns='http://jabber.org/protocol/muc#admin'>
+    <item affiliation='outcast'
+          jid='earlofcambridge at shakespeare.lit'>
+      <reason>Treason</reason>
+    </item>
+  </query>
+</iq>
+*/
+            RoomAdminIQ iq = new RoomAdminIQ(m_manager.Stream.Document);
+            iq.To = m_room;
+            iq.Type = IQType.set;
+            AdminQuery query = iq.Instruction;
+
+            int count = 0;
+            foreach (RoomParticipant party in parties)
+            {
+                if (party.Changed && (party.RealJID != null))
+                {
+                    count++;
+                    AdminItem item = query.AddItem();
+                    item.JID = party.RealJID;
+                    item.Affiliation = party.Affiliation;
+                    item.Reason = reason;
+                }
+            }
+            if (count > 0)
+                m_manager.BeginIQ(iq, callback, state);
+            else
+                callback(this, null, state);
+        }
+#endregion
+    }
+
+    /// <summary>
+    /// A list of all of the current participants.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ParticipantCollection : IEnumerable
+    {
+        private Hashtable m_hash = new Hashtable();
+
+        internal enum Modification
+        {
+            NONE = -1,
+            JOIN,
+            LEAVE
+        }
+
+        /// <summary>
+        /// Get a participant by their room at service/nick JID.
+        /// </summary>
+        /// <param name="nickJid">room at service/nick</param>
+        /// <returns>Participant object</returns>
+        public RoomParticipant this[JID nickJid]
+        {
+            get
+            {
+                return (RoomParticipant)m_hash[nickJid];
+            }
+        }
+
+        /// <summary>
+        /// Add a participant to the list, indexed by full nick JID.
+        /// </summary>
+        /// <param name="pres">The latest presence</param>
+        /// <param name="mod">Was this a JOIN, a LEAVE, or no change?</param>
+        /// <returns>The associated participant.</returns>
+        internal RoomParticipant Modify(Presence pres, out Modification mod)
+        {
+            JID from = pres.From;
+            mod = Modification.NONE;
+            RoomParticipant party = (RoomParticipant)m_hash[from];
+            if (party != null)
+            {
+                party.Presence = pres;
+                if (pres.Type == PresenceType.unavailable)
+                {
+                    m_hash.Remove(from);
+                    mod = Modification.LEAVE;
+                }
+            }
+            else
+            {
+                party = new RoomParticipant(pres);
+                // XCP will send unavails from registered users that
+                // are not currently online.
+                if (pres.Type != PresenceType.unavailable)
+                {
+                    m_hash[from] = party;
+                    mod = Modification.JOIN;
+                }
+            }
+            return party;
+        }
+
+        /// <summary>
+        /// Get all of the participants that are in a given room role.
+        /// </summary>
+        /// <param name="role">The role to search for</param>
+        /// <returns></returns>
+        public RoomParticipant[] GetParticipantsByRole(RoomRole role)
+        {
+            ArrayList res = new ArrayList(m_hash.Count);
+            foreach (RoomParticipant party in m_hash.Values)
+            {
+                if (party.Role == role)
+                    res.Add(party);
+            }
+            return (RoomParticipant[])res.ToArray(typeof(RoomParticipant));
+        }
+
+        /// <summary>
+        /// Get all of the participants that are in a given room affiliation.
+        /// </summary>
+        /// <param name="affiliation">The role to search for</param>
+        /// <returns></returns>
+        public RoomParticipant[] GetParticipantsByAffiliation(RoomAffiliation affiliation)
+        {
+            ArrayList res = new ArrayList(m_hash.Count);
+            foreach (RoomParticipant party in m_hash.Values)
+            {
+                if (party.Affiliation == affiliation)
+                    res.Add(party);
+            }
+            return (RoomParticipant[])res.ToArray(typeof(RoomParticipant));
+        }
+
+        #region IEnumerable Members
+        /// <summary>
+        /// Enumerate over all of the participants
+        /// </summary>
+        /// <returns></returns>
+        public IEnumerator GetEnumerator()
+        {
+            return m_hash.Values.GetEnumerator();
+        }
+
+        #endregion
+    }
+
+    /// <summary>
+    /// Someone who is currently in or associated with a room.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class RoomParticipant
+    {
+        private Presence m_presence;
+        private bool m_changed = false;
+
+        /// <summary>
+        /// Create a participant from the last presence received for that user.
+        /// </summary>
+        /// <param name="pres"></param>
+        public RoomParticipant(Presence pres)
+        {
+            if (pres == null)
+                throw new ArgumentNullException("Presence must nut be null", "pres");
+            m_presence = pres;
+        }
+
+        /// <summary>
+        /// Last presence received for this user.
+        /// </summary>
+        public Presence Presence
+        {
+            get { return m_presence; }
+            set
+            {
+                m_presence = value;
+                m_changed = false;
+            }
+        }
+
+        /// <summary>
+        /// Has this participant's role or affiliation been changed?
+        /// </summary>
+        public bool Changed
+        {
+            get { return m_changed; }
+        }
+
+        /// <summary>
+        /// The muc#user item in the presence.
+        /// </summary>
+        protected RoomItem Item
+        {
+            get
+            {
+                UserX x = (UserX)m_presence["x", URI.MUC_USER];
+                if (x == null)
+                    return null;
+                return x.RoomItem;
+            }
+        }
+
+        /// <summary>
+        /// Nickname of the user
+        /// </summary>
+        public string Nick
+        {
+            get { return m_presence.From.Resource; }
+        }
+
+        /// <summary>
+        /// Affiliation of the user.
+        /// </summary>
+        public RoomAffiliation Affiliation
+        {
+            get
+            {
+                RoomItem item = Item;
+                if (item == null)
+                    return RoomAffiliation.UNSPECIFIED;
+                return item.Affiliation;
+            }
+            set
+            {
+                RoomItem item = Item;
+                if (item == null)
+                    return;
+                if (item.Affiliation != value)
+                {
+                    item.Affiliation = value;
+                    m_changed = true;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Role of the user.
+        /// </summary>
+        public RoomRole Role
+        {
+            get
+            {
+                RoomItem item = Item;
+                if (item == null)
+                    return RoomRole.UNSPECIFIED;
+                return item.Role;
+            }
+            set
+            {
+                RoomItem item = Item;
+                if (item == null)
+                    return;
+                if (item.Role != value)
+                {
+                    item.Role = value;
+                    m_changed = true;
+                }
+            }
+        }
+
+        /// <summary>
+        /// room at server/nick of the user.
+        /// </summary>
+        public JID NickJID
+        {
+            get { return m_presence.From; }
+        }
+
+        /// <summary>
+        /// The real JID of the user, if this is a non-anonymous room.
+        /// </summary>
+        public JID RealJID
+        {
+            get
+            {
+/*
+<presence
+    from='darkcave at macbeth.shakespeare.lit/thirdwitch'
+    to='crone1 at shakespeare.lit/desktop'>
+  <x xmlns='http://jabber.org/protocol/muc#user'>
+    <item affiliation='none'
+          jid='hag66 at shakespeare.lit/pda'
+          role='participant'/>
+  </x>
+</presence>
+ */
+                RoomItem item = Item;
+                if (item == null)
+                    return null;
+                return item.JID;
+            }
+        }
+
+        /// <summary>
+        /// The nick JID or nick (real).
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            JID nick = NickJID;
+            JID real = RealJID;
+            if (real != null)
+                return string.Format("{0} ({1})", nick, real);
+            return nick;
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/connection/DiscoManager.bmp b/lib/jabber-net/jabber/connection/DiscoManager.bmp
new file mode 100644
index 0000000..f69146e
Binary files /dev/null and b/lib/jabber-net/jabber/connection/DiscoManager.bmp differ
diff --git a/lib/jabber-net/jabber/connection/DiscoManager.cs b/lib/jabber-net/jabber/connection/DiscoManager.cs
new file mode 100644
index 0000000..72bd4e9
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/DiscoManager.cs
@@ -0,0 +1,1332 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Collections;
+using System.Diagnostics;
+using System.Xml;
+using System.Threading;
+
+using bedrock.util;
+using bedrock.collections;
+
+using jabber.protocol;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+
+namespace jabber.connection
+{
+    /// <summary>
+    /// Manages a service discovery (disco) identity. See <a href="http://www.xmpp.org/extensions/xep-0030.html">XEP-0030</a> for more information.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Ident : IComparable
+    {
+        private string m_name;
+        private string m_category;
+        private string m_type;
+        private string m_lang;
+
+        /// <summary>
+        /// Create a new identity from its constituent parts.
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="category"></param>
+        /// <param name="type"></param>
+        /// <param name="lang"></param>
+        public Ident(string name, string category, string type, string lang)
+        {
+            m_category = (category == null) ? "" : category;
+            m_name = (name == null) ? "" : name;
+            m_type = (type == null) ? "" : type;
+            m_lang = (lang == null) ? "" : lang;
+        }
+
+        /// <summary>
+        /// Create a new, empty identity
+        /// </summary>
+        public Ident() : this("", "", "", "")
+        {
+        }
+
+        /// <summary>
+        /// Create an identity from protocol
+        /// </summary>
+        /// <param name="id"></param>
+        public Ident(DiscoIdentity id) : this(id.Named, id.Category, id.Type, id.Lang)
+        {
+        }
+
+        /// <summary>
+        /// Retrieves the string representation of the Ident (category/type/lang/name).
+        /// </summary>
+        /// <returns></returns>
+        [Category("Capabilities")]
+        public string Key
+        {
+            get
+            {
+                return string.Format("{0}/{1}/{2}/{3}", m_category, m_type, m_lang, m_name);
+            }
+        }
+
+        /// <summary>
+        /// Contains the description of the entity.
+        /// </summary>
+        [Category("Text")]
+        public string Name
+        {
+            get { return m_name; }
+            set { m_name = value; }
+        }
+
+        /// <summary>
+        /// Contains the capabilities category, such as server,
+        /// client, gateway, directory and so on.
+        /// </summary>
+        [Category("Identity")]
+        public string Category
+        {
+            get { return m_category; }
+            set { m_category = value; }
+        }
+
+        /// <summary>
+        /// Contains the entity type.
+        /// </summary>
+        [Category("Identity")]
+        public string Type
+        {
+            get { return m_type; }
+            set { m_type = value; }
+        }
+
+        /// <summary>
+        /// xml:lang language of this identity
+        /// </summary>
+        [Category("Text")]
+        public string Lang
+        {
+            get { return m_lang; }
+            set { m_lang = value; }
+        }
+
+        /// <summary>
+        /// Does this identity have the given category and type?
+        /// </summary>
+        /// <param name="category">The category to compare</param>
+        /// <param name="type">The type to compare</param>
+        /// <returns></returns>
+        public bool Matches(string category, string type)
+        {
+            return (m_category == category) && (m_type == type);
+        }
+
+        #region IComparable Members
+        /// <summary>
+        /// Compare to another identity, by comparing the string-ified versions
+        /// of each.
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <returns></returns>
+        public int CompareTo(object obj)
+        {
+            if ((object)this == obj)
+                return 0;
+            Ident other = obj as Ident;
+            if (other == null)
+                return 1;
+            return Key.CompareTo(other.Key);
+        }
+        #endregion
+
+        /// <summary>
+        /// Is this identity equal to that one?  If two are the same except for
+        /// language, they are different by this method.
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <returns></returns>
+        public override bool Equals(object obj)
+        {
+            return (this.CompareTo(obj) == 0);
+        }
+
+        /// <summary>
+        /// Hash over the string version of the identity.
+        /// </summary>
+        /// <returns></returns>
+        public override int GetHashCode()
+        {
+            return Key.GetHashCode();
+        }
+
+        /// <summary>
+        /// A slash-separated version of the name, with the unset parts omitted.
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            System.Text.StringBuilder sb = new System.Text.StringBuilder();
+            sb.Append(m_category);
+            sb.Append("/");
+            sb.Append(m_type);
+
+            if ((m_lang != null) && (m_lang != ""))
+            {
+                sb.Append("/");
+                sb.Append(m_lang);
+            }
+
+            if ((m_name != null) && (m_name != ""))
+            {
+                sb.Append("/");
+                sb.Append(m_name);
+            }
+
+            return sb.ToString(); ;
+        }
+    }
+
+    /// <summary>
+    /// Manages a JID and Node combination.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class JIDNode
+    {
+        private JID m_jid = null;
+        private string m_node = null;
+
+        /// <summary>
+        /// Creates a new JID/Node combination.
+        /// </summary>
+        /// <param name="jid">JID to associate with JIDNode.</param>
+        /// <param name="node">Node to associate with JIDNode.</param>
+        public JIDNode(JID jid, string node)
+        {
+            this.m_jid = jid;
+            if ((node != null) && (node != ""))
+                this.m_node = node;
+        }
+
+        /// <summary>
+        /// Gets the JID.
+        /// </summary>
+        [Category("Identity")]
+        public JID JID
+        {
+            get { return m_jid; }
+            set { m_jid = value; }
+        }
+
+        /// <summary>
+        /// Gets the Node.
+        /// </summary>
+        [Category("Identity")]
+        public string Node
+        {
+            get { return m_node; }
+            set { m_node = value; }
+        }
+
+        /// <summary>
+        /// Retrieves a hash key that combines the JID and the node.
+        /// </summary>
+        /// <param name="jid">JID to use in the hash code.</param>
+        /// <param name="node">Node to use in the hash code.</param>
+        /// <returns>The hash code.</returns>
+        internal static string GetKey(string jid, string node)
+        {
+            if ((node == null) || (node == ""))
+            {
+                if (jid == null)
+                    return null;
+                return jid.ToString();
+            }
+            return jid + '\u0000' + node;
+        }
+
+        /// <summary>
+        /// Gets the JID/Node key for Hash lookup.
+        /// </summary>
+        [Browsable(false)]
+        public string Key
+        {
+            get { return GetKey(m_jid, m_node); }
+        }
+
+        /// <summary>
+        /// Determines if both the jid and the node are equal.
+        /// </summary>
+        /// <param name="obj">JIDNode to compare to.</param>
+        /// <returns>True if both the jid and the node are equal.</returns>
+        public override bool Equals(object obj)
+        {
+            JIDNode other = obj as JIDNode;
+            if (other == null)
+            {
+                return false;
+            }
+
+            return (m_jid == other.m_jid) && (m_node == other.m_node);
+        }
+
+        /// <summary>
+        /// Serves as a hash function to combine the JID and node together.
+        /// GetHashCode() is suitable for use in hashing algorithms and
+        /// data structures like a hash table.
+        /// </summary>
+        /// <returns>The hash code of this JIDNode.</returns>
+        public override int GetHashCode()
+        {
+            int code = 0;
+            if (m_jid != null)
+                code = m_jid.GetHashCode();
+            if (m_node != null)
+                code ^= m_node.GetHashCode();
+            return code;
+        }
+
+        /// <summary>
+        /// Returns a string representing the JID/Node.
+        /// </summary>
+        /// <returns>String representing the JID/Node.</returns>
+        public override string ToString()
+        {
+            return JID + "/" + Node;
+        }
+    }
+
+
+    /// <summary>
+    /// Manages the information and children of a given JID/Node combination.
+    ///
+    /// NOTE: If you have multiple connections in the same process, they all share the same Disco cache.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class DiscoNode : JIDNode, IEnumerable
+    {
+        /// <summary>
+        /// Contains the children of this node.
+        /// </summary>
+        public Set Children = null;
+        /// <summary>
+        /// Contains the Features of this node.
+        /// </summary>
+        public StringSet Features = null;
+        /// <summary>
+        /// Contains the identities of this node.
+        /// </summary>
+        public Set Identity = null;
+        private string m_name = null;
+        private bool m_pendingItems = false;
+        private bool m_pendingInfo = false;
+        private jabber.protocol.x.Data[] m_extensions;
+        private DiscoInfo m_info = null;
+
+        private ArrayList m_featureCallbacks = new ArrayList();
+        private ArrayList m_itemCallbacks = new ArrayList();
+        private ArrayList m_identCallbacks = new ArrayList();
+
+        /// <summary>
+        /// Creates a disco node.
+        /// </summary>
+        /// <param name="jid">JID associated with this JIDNode.</param>
+        /// <param name="node">node associated with this JIDNode.</param>
+        public DiscoNode(JID jid, string node)
+            : base(jid, node)
+        {
+        }
+
+        private class NodeCallback
+        {
+            public DiscoManager manager;
+            public DiscoNodeHandler callback;
+            public object state;
+
+            public NodeCallback(DiscoManager m, DiscoNodeHandler h, object s)
+            {
+                manager = m;
+                callback = h;
+                state = s;
+            }
+
+            public void Call(DiscoNode node)
+            {
+                if (callback != null)
+                    callback(manager, node, state);
+            }
+        }
+
+        /// <summary>
+        /// Add a callback for when features are received.
+        /// 
+        /// Calls the callback immediately if the features have already been retrieved.
+        /// </summary>
+        /// <param name="manager"></param>
+        /// <param name="callback"></param>
+        /// <param name="state"></param>
+        /// <returns>True if there were no features yet, and the callback was queued.</returns>
+        public bool AddFeatureCallback(DiscoManager manager, DiscoNodeHandler callback, object state)
+        {
+            lock (this)
+            {
+                if (Features != null)
+                {
+                    if (callback != null)
+                        callback(manager, this, state);
+                    return false;
+                }
+                else
+                {
+                    if (callback != null)
+                        m_featureCallbacks.Add(new NodeCallback(manager, callback, state));
+                    return true;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Add a callback for when items are received.
+        /// 
+        /// Calls the callback immediately if the items have already been retrieved.
+        /// </summary>
+        /// <param name="manager"></param>
+        /// <param name="callback"></param>
+        /// <param name="state"></param>
+        /// <returns>True if there were no items yet, and the callback was queued.</returns>
+        public bool AddItemsCallback(DiscoManager manager, DiscoNodeHandler callback, object state)
+        {
+            lock (this)
+            {
+                if (Children != null)
+                {
+                    if (callback != null)
+                        callback(manager, this, state);
+                    return false;
+                }
+                else
+                {
+                    if (callback != null)
+                        m_itemCallbacks.Add(new NodeCallback(manager, callback, state));
+                    return true;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Add a callback for when identities are received.
+        /// 
+        /// Calls the callback immediately if the features have already been retrieved.
+        /// </summary>
+        /// <param name="manager"></param>
+        /// <param name="callback"></param>
+        /// <param name="state"></param>
+        /// <returns>True if there were no identities yet, and the callback was queued.</returns>
+        public bool AddIdentityCallback(DiscoManager manager, DiscoNodeHandler callback, object state)
+        {
+            lock (this)
+            {
+                if (Identities != null)
+                {
+                    if (callback != null)
+                        callback(manager, this, state);
+                    return false;
+                }
+                else
+                {
+                    m_identCallbacks.Add(new NodeCallback(manager, callback, state));
+                    return true;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the string representation of the first identity.
+        /// </summary>
+        [Category("Info")]
+        public string Name
+        {
+            set { m_name = value; }
+            get
+            {
+                if (m_name != null)
+                    return m_name;
+                if (Identity != null)
+                {
+                    foreach (Ident id in Identity)
+                    {
+                        if ((id.Name != null) && (id.Name != ""))
+                            m_name = id.Name;
+                    }
+                    return m_name;
+                }
+                string n = JID;
+                if (Node != null)
+                    n += "/" + Node;
+                return n;
+            }
+        }
+
+        /// <summary>
+        /// Determines whether or not the disco#info packet has been sent.
+        /// </summary>
+        [Category("Status")]
+        public bool PendingInfo
+        {
+            get { return m_pendingInfo; }
+        }
+
+        /// <summary>
+        /// Determines whether or not the disco#items packet has been sent.
+        /// </summary>
+        [Category("Status")]
+        public bool PendingItems
+        {
+            get { return m_pendingItems; }
+        }
+
+        /// <summary>
+        /// Retrieves the features associated with this node.
+        /// </summary>
+        [Category("Info")]
+        public string[] FeatureNames
+        {
+            get
+            {
+                if (Features == null)
+                    return new string[0];
+                return Features.GetStrings();
+            }
+        }
+
+        /// <summary>
+        /// Retrieves the disco identities of the node.
+        /// </summary>
+        [Category("Info")]
+        public string[] Identities
+        {
+            get
+            {
+                if (Identity == null)
+                    return new string[0];
+                string[] names = new string[Identity.Count];
+                int count = 0;
+                foreach (Ident i in Identity)
+                {
+                    names[count++] = i.Key;
+                }
+                return names;
+            }
+        }
+
+        /// <summary>
+        /// Retrieves an identity object for each identity of the node.
+        /// </summary>
+        /// <returns>List of identities associated with this node.</returns>
+        public Ident[] GetIdentities()
+        {
+            if (Identity == null)
+                return new Ident[0];
+
+            Ident[] ret = new Ident[Identity.Count];
+            int count = 0;
+            foreach (Ident i in Identity)
+            {
+                ret[count++] = i;
+            }
+            return ret;
+        }
+
+        /// <summary>
+        /// Determines whether or not this node has the given category and type among its identities.
+        /// </summary>
+        /// <param name="category">Category to look for.</param>
+        /// <param name="type">Type to look for.</param>
+        /// <returns>The node contains the category and the type if true.</returns>
+        public bool HasIdentity(string category, string type)
+        {
+            if (Identity == null)
+                return false;
+            foreach (Ident i in Identity)
+            {
+                if (i.Matches(category, type))
+                    return true;
+            }
+            return false;
+        }
+
+        /// <summary>
+        /// Gets or sets the x:data extensions of the disco information.
+        /// </summary>
+        public jabber.protocol.x.Data[] Extensions
+        {
+            get
+            {
+                return m_extensions;
+            }
+            set
+            {
+                m_extensions = value;
+            }
+        }
+
+        /// <summary>
+        /// This last info result returned for this JID and node.
+        /// </summary>
+        public DiscoInfo Info
+        {
+            get { return m_info; }
+        }
+
+        /// <summary>
+        /// Determines if this node has the specified feature.
+        /// </summary>
+        /// <param name="URI">Feature to look for.</param>
+        /// <returns>The node has this feature if true.</returns>
+        public bool HasFeature(string URI)
+        {
+            if (Features == null)
+                return false;
+            return Features.Contains(URI);
+        }
+
+        private void DoCallbacks(ArrayList callbacks)
+        {
+            lock (this)
+            {
+                foreach (NodeCallback cb in callbacks)
+                    cb.Call(this);
+                callbacks.Clear();
+            }
+        }
+
+        /// <summary>
+        /// Pulls all of the data out of the given protocol response.
+        /// </summary>
+        /// <param name="info">If null, just calls callbacks</param>
+        public void AddInfo(DiscoInfo info)
+        {
+            m_info = info;
+            if (info == null)
+            {
+                AddIdentities(null);
+                AddFeatures((StringSet)null);
+                return;
+            }
+            Extensions = info.GetExtensions();
+            AddIdentities(info.GetIdentities());
+            AddFeatures(info.FeatureSet);
+        }
+
+        /// <summary>
+        /// Add a single feature to the node.
+        /// Does not fire OnFeatures, since this should mostly be used by
+        /// things that are not querying externally.
+        /// </summary>
+        /// <param name="feature">The feature URI to add</param>
+        public void AddFeature(string feature)
+        {
+            if (Features == null)
+                Features = new StringSet();
+            
+            Features.Add(feature);
+        }
+
+        /// <summary>
+        /// Remove a single feature from the node.
+        /// Does not fire OnFeatures, since this should mostly be used by
+        /// things that are not querying externally.
+        /// 
+        /// No exception should be thrown if the feature doesn't exist.
+        /// </summary>
+        /// <param name="feature">The feature URI to remove</param>
+        public void RemoveFeature(string feature)
+        {
+            if (Features == null)
+                return;
+            Features.Remove(feature);
+        }
+
+        /// <summary>
+        /// Adds these features to the node. Calls the OnFeatures event.
+        /// </summary>
+        /// <param name="features">Features to add to this node.</param>
+        [Obsolete("Use AddFeatures(StringSet)")]
+        public void AddFeatures(DiscoFeature[] features)
+        {
+            if (Features == null)
+                Features = new StringSet();
+
+            // features may be null when used from outside.
+            if (features != null)
+            {
+                foreach (DiscoFeature f in features)
+                    Features.Add(f.Var);
+            }
+
+            DoCallbacks(m_featureCallbacks);
+        }
+
+        /// <summary>
+        /// Add all of the features from the specified set.
+        /// </summary>
+        /// <param name="features"></param>
+        public void AddFeatures(StringSet features)
+        {
+            if (features != null)
+            {
+                if (Features == null)
+                    Features = new StringSet(features);
+                else
+                    Features.Add(features);
+            }
+            DoCallbacks(m_featureCallbacks);
+        }
+
+        /// <summary>
+        /// Clear out any features already in the list.
+        /// </summary>
+        public void ClearFeatures()
+        {
+            Features = null;
+        }
+
+        /// <summary>
+        /// Adds these identities to the node.
+        /// </summary>
+        /// <param name="id">Identities to add.</param>
+        public void AddIdentity(Ident id)
+        {
+            if (Identity == null)
+                Identity = new Set();
+            Identity.Add(id);
+        }
+
+        /// <summary>
+        /// Add these identities to the node.
+        /// Fires OnIdentities
+        /// </summary>
+        /// <param name="ids">Identities to add.</param>
+        public void AddIdentities(DiscoIdentity[] ids)
+        {
+            if (Identity == null)
+                Identity = new Set();
+
+            // ids may be null when used from outside.
+            if (ids != null)
+            {
+                foreach (DiscoIdentity id in ids)
+                    Identity.Add(new Ident(id));
+            }
+
+            DoCallbacks(m_identCallbacks);
+        }
+
+        /// <summary>
+        /// Clear out any identities already in the list.
+        /// </summary>
+        public void ClearIdentity()
+        {
+            Identity = null;
+        }
+
+        internal DiscoNode AddItem(DiscoManager manager, DiscoItem di)
+        {
+            DiscoNode dn = manager.GetNode(di.Jid, di.Node);
+            if ((di.Named != null) && (di.Named != ""))
+                dn.Name = di.Named;
+            Children.Add(dn);
+            return dn;
+        }
+
+        /// <summary>
+        /// Adds the given items to the cache.
+        /// </summary>
+        /// <param name="manager">The DiscoManager used to create/cache nodes</param>
+        /// <param name="items">Items to add.</param>
+        public void AddItems(DiscoManager manager, DiscoItem[] items)
+        {
+            if (Children == null)
+                Children = new Set();
+
+            // items may be null when used from outside.
+            if (items != null)
+            {
+                foreach (DiscoItem di in items)
+                    AddItem(manager, di);
+            }
+
+            DoCallbacks(m_itemCallbacks);
+        }
+
+        /// <summary>
+        /// Creates a disco#info IQ packet.
+        /// </summary>
+        /// <param name="doc">XmlDocument to create the XML elements with.</param>
+        /// <returns>XML representing the disco#info request.</returns>
+        public IQ InfoIQ(System.Xml.XmlDocument doc)
+        {
+            m_pendingInfo = true;
+            DiscoInfoIQ iiq = new DiscoInfoIQ(doc);
+            iiq.To = JID;
+            iiq.Type = IQType.get;
+            if (Node != null)
+            {
+                DiscoInfo info = iiq.Instruction;
+                info.Node = Node;
+            }
+
+            return iiq;
+        }
+
+        /// <summary>
+        /// Creates a disco#items IQ packet.
+        /// </summary>
+        /// <param name="doc">XmlDocument used to create the XML Elements.</param>
+        /// <returns>XML element representing the disco#items request.</returns>
+        public IQ ItemsIQ(System.Xml.XmlDocument doc)
+        {
+            m_pendingItems = true;
+
+            DiscoItemsIQ iiq = new DiscoItemsIQ(doc);
+            iiq.To = JID;
+            iiq.Type = IQType.get;
+            if (Node != null)
+            {
+                DiscoItems items = iiq.Instruction;
+                items.Node = Node;
+            }
+            return iiq;
+        }
+
+        #region IEnumerable Members
+        /// <summary>
+        /// Gets an enumerator across all items.
+        /// </summary>
+        /// <returns>Set enumerator to loop over.</returns>
+        public IEnumerator GetEnumerator()
+        {
+            return Children.GetEnumerator();
+        }
+        #endregion
+    }
+
+    /// <summary>
+    /// Represents a callback with a new disco node.
+    /// </summary>
+    /// <param name="sender">The DiscoManager managing this node</param>
+    /// <param name="node">The node that changed</param>
+    /// <param name="state">State passed in to the Begin request.</param>
+    public delegate void DiscoNodeHandler(DiscoManager sender, DiscoNode node, object state);
+
+    /// <summary>
+    /// Manages the discovery (disco) database.
+    /// </summary>
+    // TODO: once etags are finished, make all of this information cached on disk.
+    // TODO: cache XEP-115 client caps data to disk
+    // TODO: add negative caching
+    [SVN(@"$Id$")]
+    public class DiscoManager : StreamComponent, IEnumerable
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+#pragma warning disable 0414
+        private System.ComponentModel.Container components = null;
+#pragma warning restore 0414
+        private DiscoNode m_root = null;
+        private Tree m_items = new Tree();
+
+        /// <summary>
+        /// Creates a new DiscoManager and associates it with a parent container.
+        /// </summary>
+        /// <param name="container">Parent container.</param>
+        public DiscoManager(System.ComponentModel.IContainer container) : this()
+        {
+            container.Add(this);
+        }
+
+        /// <summary>
+        /// Creates a new DiscoManager.
+        /// </summary>
+        public DiscoManager()
+        {
+            InitializeComponent();
+            this.OnStreamChanged +=new bedrock.ObjectHandler(DiscoManager_OnStreamChanged);
+        }
+
+
+        /// <summary>
+        /// Gets the root node.  This is probably the server that the client is
+        /// connected to. If the Children property of this root node is null,
+        /// the disco#items request has not returned an answer. Register on this
+        /// node's OnFeatures callback.
+        /// </summary>
+        public DiscoNode Root
+        {
+            get 
+            {
+                if (m_root != null)
+                    return m_root;
+                if (m_stream == null)
+                    return null;
+                // GetNode locks.
+                m_root = GetNode(m_stream.Server);
+                return m_root; 
+            }
+        }
+
+        /// <summary>
+        /// Creates nodes and ensure that they are cached.
+        /// </summary>
+        /// <param name="jid">JID associated with DiscoNode.</param>
+        /// <param name="node">Node associated with DiscoNode.</param>
+        /// <returns>
+        /// If DiscoNode exists, returns the found node.
+        /// Otherwise it creates the node and return it.
+        /// </returns>
+        public DiscoNode GetNode(JID jid, string node)
+        {
+            lock (m_items)
+            {
+                string key = DiscoNode.GetKey(jid, node);
+                DiscoNode n = (DiscoNode)m_items[key];
+                if (n == null)
+                {
+                    n = new DiscoNode(jid, node);
+                    m_items.Add(key, n);
+                }
+                return n;
+            }
+        }
+
+        /// <summary>
+        /// Creates nodes where only the JID is specified.
+        /// </summary>
+        /// <param name="jid">JID associated with DiscoNode.</param>
+        /// <returns>
+        /// If DiscoNode exists, returns the found node.
+        /// Otherwise it creates the node and return it.
+        /// </returns>
+        public DiscoNode GetNode(JID jid)
+        {
+            return GetNode(jid, null);
+        }
+
+        /// <summary>
+        /// Deletes the cache.
+        /// </summary>
+        public void Clear()
+        {
+            lock (m_items)
+            {
+                m_root = null;
+                m_items.Clear();
+            }
+        }
+
+        /// <summary>
+        /// Gets all of the cached nodes.
+        /// </summary>
+        /// <returns>Tree enumerator to loop over.</returns>
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return m_items.GetEnumerator();
+        }
+
+        private void DiscoManager_OnStreamChanged(object sender)
+        {
+            if (m_stream == null)
+                return;
+            m_stream.OnAuthenticate += new bedrock.ObjectHandler(m_client_OnAuthenticate);
+            m_stream.OnDisconnect += new bedrock.ObjectHandler(m_stream_OnDisconnect);
+            m_stream.OnError += new bedrock.ExceptionHandler(m_stream_OnError);
+        }
+
+        private void m_client_OnAuthenticate(object sender)
+        {
+            RequestInfo(Root);
+        }
+
+        private void m_stream_OnDisconnect(object sender)
+        {
+            Clear();
+        }
+
+        private void m_stream_OnError(object sender, Exception ex)
+        {
+            Clear();
+        }
+
+
+        private void RequestInfo(DiscoNode node)
+        {
+            lock (node)
+            {
+                if (!node.PendingInfo)
+                {
+                    IQ iq = node.InfoIQ(m_stream.Document);
+                    jabber.server.JabberService js = m_stream as jabber.server.JabberService;
+                    if (js != null)
+                        iq.From = js.ComponentID;
+                    BeginIQ(iq, new jabber.connection.IqCB(GotInfo), node);
+                }
+            }
+        }
+
+        private void RequestItems(DiscoNode node)
+        {
+            lock (node)
+            {
+                if (!node.PendingItems)
+                {
+                    IQ iq = node.ItemsIQ(m_stream.Document);
+                    jabber.server.JabberService js = m_stream as jabber.server.JabberService;
+                    if (js != null)
+                        iq.From = js.ComponentID;
+                    BeginIQ(iq, new jabber.connection.IqCB(GotItems), node);
+                }
+            }
+        }
+
+
+        private void GotInfo(object sender, IQ iq, object onode)
+        {
+            DiscoNode dn = onode as DiscoNode;
+            Debug.Assert(dn != null);
+
+            if (iq.Type == IQType.error)
+            {
+                if (dn == m_root)
+                {
+                    // root node.
+                    // Try agents.
+                    Error err = iq.Error;
+                    if (err != null)
+                    {
+                        string cond = err.Condition;
+                        if ((cond == Error.FEATURE_NOT_IMPLEMENTED) ||
+                            (cond == Error.SERVICE_UNAVAILABLE))
+                        {
+                            IQ aiq = new AgentsIQ(m_stream.Document);
+                            BeginIQ(aiq, new jabber.connection.IqCB(GotAgents), m_root);
+                            return;
+                        }
+                    }
+                }
+            }
+            if (iq.Type != IQType.result)
+            {
+                // protocol error
+                dn.AddInfo(null);
+                return;
+            }
+
+            dn.AddInfo(iq.Query as DiscoInfo);
+
+            if (dn == m_root)
+                RequestItems(m_root);
+        }
+
+        private void GotItems(object sender, IQ iq, object onode)
+        {
+            DiscoNode dn = onode as DiscoNode;
+            Debug.Assert(dn != null);
+
+            if (iq.Type != IQType.result)
+            {
+                // protocol error
+                dn.AddItems(this, null);
+                return;
+            }
+
+            DiscoItems items = iq.Query as DiscoItems;
+            if (items == null)
+            {
+                // protocol error
+                dn.AddItems(this, null);
+                return;
+            }
+
+            dn.AddItems(this, items.GetItems());
+
+            // automatically info everything we get an item for.
+            foreach (DiscoNode n in dn.Children)
+            {
+                if (n.Features == null)
+                {
+                    RequestInfo(n);
+                }
+            }
+        }
+
+        private void GotAgents(object sender, IQ iq, object onode)
+        {
+            DiscoNode dn = onode as DiscoNode;
+            Debug.Assert(dn != null);
+
+            if (iq.Type != IQType.result)
+            {
+                dn.AddItems(this, null);
+                return;
+            }
+
+            AgentsQuery aq = iq.Query as AgentsQuery;
+            if (aq == null)
+            {
+                dn.AddItems(this, null);
+                return;
+            }
+
+            if (dn.Children == null)
+                dn.Children = new Set();
+
+            foreach (Agent agent in aq.GetAgents())
+            {
+                DiscoItem di = new DiscoItem(m_stream.Document);
+                di.Jid = agent.JID;
+                di.Named = agent.AgentName;
+
+                DiscoNode child = dn.AddItem(this, di);
+                if (child.Features == null)
+                    child.Features = new StringSet();
+                if (child.Identity == null)
+                    child.Identity = new Set();
+
+                Ident id = new Ident();
+                id.Name = agent.Description;
+                switch (agent.Service)
+                {
+                case "groupchat":
+                    id.Category = "conference";
+                    id.Type = "text";
+                    child.Identity.Add(id);
+                    break;
+                case "jud":
+                    id.Category = "directory";
+                    id.Type = "user";
+                    child.Identity.Add(id);
+                    break;
+                case null:
+                case "":
+                    break;
+                default:
+                    // guess this is a transport
+                    id.Category = "gateway";
+                    id.Type = agent.Service;
+                    child.Identity.Add(id);
+                    break;
+                }
+
+                if (agent.Register)
+                    child.Features.Add(URI.REGISTER);
+                if (agent.Search)
+                    child.Features.Add(URI.SEARCH);
+                if (agent.Groupchat)
+                    child.Features.Add(URI.MUC);
+                if (agent.Transport)
+                {
+                    if (id.Category != "gateway")
+                    {
+                        Ident tid = new Ident();
+                        tid.Name = id.Name;
+                        tid.Category = "gateway";
+                        child.Identity.Add(tid);
+                    }
+                }
+
+                foreach (XmlElement ns in agent.GetElementsByTagName("ns"))
+                {
+                    child.Features.Add(ns.InnerText);
+                }
+                child.AddItems(this, null);
+                child.AddIdentities(null);
+                child.AddFeatures((StringSet)null);
+            }
+            dn.AddItems(this, null);
+            dn.AddIdentities(null);
+            dn.AddFeatures((StringSet)null);
+        }
+
+        /// <summary>
+        /// Retrieves the features associated with this node and
+        /// then calls back on the handler.
+        /// If the information is in the cache, handler gets called right now.
+        /// </summary>
+        /// <param name="node">Node to look for.</param>
+        /// <param name="handler">Callback to use afterwards.</param>
+        /// <param name="state">Context to pass back to caller when complete</param>
+        public void BeginGetFeatures(DiscoNode node, DiscoNodeHandler handler, object state)
+        {
+            if (node == null)
+                node = Root;
+
+            if (node.AddFeatureCallback(this, handler, state))
+                RequestInfo(node);
+        }
+
+        /// <summary>
+        /// Retrieves the features associated with this node and
+        /// then calls back on the handler.
+        /// 
+        /// If caching is specified, items already in the cache call the handler
+        /// immediately.
+        /// </summary>
+        /// <param name="jid">JID to look for.</param>
+        /// <param name="node">Node to look for.</param>
+        /// <param name="handler">Callback to use afterwards.</param>
+        /// <param name="state">Context to pass back to caller when complete</param>
+        /// <param name="cache">Should caching be performed on this request?</param>
+        public void BeginGetFeatures(JID jid, string node, DiscoNodeHandler handler, object state, bool cache)
+        {
+            DiscoNode dn = cache ? GetNode(jid, node) : new DiscoNode(jid, node);
+            BeginGetFeatures(dn, handler, state);
+        }
+
+        /// <summary>
+        /// Retrieves the features associated with this JID and node and
+        /// then calls back on the handler.
+        /// If the information is in the cache, handler gets called right now.
+        /// </summary>
+        /// <param name="jid">JID to look for.</param>
+        /// <param name="node">Node to look for.</param>
+        /// <param name="handler">Callback to use afterwards.</param>
+        /// <param name="state">Context to pass back to caller when complete</param>
+        public void BeginGetFeatures(JID jid, string node, DiscoNodeHandler handler, object state)
+        {
+            BeginGetFeatures(GetNode(jid, node), handler, state);
+        }
+
+        /// <summary>
+        /// Retrieves the child items associated with this node,
+        /// and then calls back on the handler.
+        /// If the information is in the cache, handler gets
+        /// called right now.
+        /// </summary>
+        /// <param name="node">Disco node to search.</param>
+        /// <param name="handler">Callback that gets called with the items.</param>
+        /// <param name="state">Context to pass back to caller when complete</param>
+        public void BeginGetItems(DiscoNode node, DiscoNodeHandler handler, object state)
+        {
+            if (node == null)
+                node = Root;
+
+            if (node.AddItemsCallback(this, handler, state))
+                RequestItems(node);
+        }
+
+        /// <summary>
+        /// Retrieves the child items associated with this node,
+        /// and then calls back on the handler.
+        /// 
+        /// If caching is specified, items already in the cache call the handler
+        /// immediately.
+        /// </summary>
+        /// <param name="jid">JID of Service to query.</param>
+        /// <param name="node">Node on the service to interact with.</param>
+        /// <param name="handler">Callback that gets called with the items.</param>
+        /// <param name="state">Context to pass back to caller when complete</param>
+        /// <param name="cache">Should caching be performed on this request?</param>
+        public void BeginGetItems(JID jid, string node, DiscoNodeHandler handler, object state, bool cache)
+        {
+            DiscoNode dn = cache ? GetNode(jid, node) : new DiscoNode(jid, node);
+            BeginGetItems(dn, handler, state);
+        }
+
+        /// <summary>
+        /// Retrieves the child items associated with this node and JID,
+        /// and then calls back on the handler.
+        /// If the information is in the cache, handler gets
+        /// called right now.
+        /// </summary>
+        /// <param name="jid">JID of Service to query.</param>
+        /// <param name="node">Node on the service to interact with.</param>
+        /// <param name="handler">Callback that gets called with the items.</param>
+        /// <param name="state">Context to pass back to caller when complete</param>
+        public void BeginGetItems(JID jid, string node, DiscoNodeHandler handler, object state)
+        {
+            BeginGetItems(GetNode(jid, node), handler, state);
+        }
+
+        private class FindServiceRequest
+        {
+            private string m_URI;
+            private DiscoNodeHandler m_handler;
+            private int m_outstanding = 0;
+
+            public FindServiceRequest(string featureURI, DiscoNodeHandler handler)
+            {
+                m_URI = featureURI;
+                m_handler = handler;
+            }
+
+            public void GotFeatures(DiscoManager manager, DiscoNode node, object state)
+            {
+
+                // yes, yes, this may call the handler more than once in multi-threaded world.  Punt for now.
+                if (m_handler != null)
+                {
+                    if (node.HasFeature(m_URI))
+                    {
+                        m_handler(manager, node, state);
+                        m_handler = null;
+                    }
+                }
+
+                if (Interlocked.Decrement(ref m_outstanding) == 0)
+                {
+                    if (m_handler != null)
+                        m_handler(manager, null, state);
+                }
+            }
+
+            public void GotRootItems(DiscoManager manager, DiscoNode node, object state)
+            {
+                m_outstanding = node.Children.Count;
+                foreach (DiscoNode n in node.Children)
+                    manager.BeginGetFeatures(n, new DiscoNodeHandler(GotFeatures), state);
+            }
+        }
+
+        /// <summary>
+        /// Finds a component that implements a given feature, which is a child of
+        /// the root. This will call back on the first match.  It will call back
+        /// with null if none are found.
+        /// </summary>
+        /// <param name="featureURI">Feature to look for.</param>
+        /// <param name="handler">Callback to use when finished.</param>
+        /// <param name="state">Context to pass back to caller when complete</param>
+        public void BeginFindServiceWithFeature(string featureURI, DiscoNodeHandler handler, object state)
+        {
+            if (handler == null)
+                return;  // prove I *didn't* call it. :)
+
+            FindServiceRequest req = new FindServiceRequest(featureURI, handler);
+            BeginGetItems(Root, new DiscoNodeHandler(req.GotRootItems), state);  // hopefully enough to prevent GC.
+        }
+
+        #region Component Designer generated code
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            components = new System.ComponentModel.Container();
+        }
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/jabber/connection/FileMap.cs b/lib/jabber-net/jabber/connection/FileMap.cs
new file mode 100644
index 0000000..191f8d3
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/FileMap.cs
@@ -0,0 +1,220 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Xml;
+
+using jabber.protocol;
+using bedrock.util;
+
+namespace jabber.connection
+{
+    /// <summary>
+    /// A dictionary backed into a file.  Any modification to the dictionary re-writes the file, so 
+    /// writes are somewhat costly.  Reads are cached lazily.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class FileMap<T>
+        where T : Element
+	{
+        private const string NS = "http://cursive.net/xml/FileMap";
+
+        private string m_fileName = null;
+        private ElementFactory m_factory = null;
+        private Dictionary<string, T> m_cache = null;
+
+        /// <summary>
+        /// Create a file map.
+        /// </summary>
+        /// <param name="fileName">Valid file name, either absoulte, or relative 
+        /// to the current working directory.</param>
+        /// <param name="factory">Element factory to create elements of a given type.  If null,
+        /// Elements will always be created, and T MUST be Element.</param>
+        public FileMap(string fileName, ElementFactory factory)
+        {
+            Factory = factory;
+            FileName = fileName;
+        }
+
+        /// <summary>
+        /// The ElementFactory that determines the type of the elements being stored.
+        /// </summary>
+        public ElementFactory Factory
+        {
+            get { return m_factory; }
+            set
+            {
+                if (value == null)
+                {
+                    if (!typeof(T).Equals(typeof(Element)))
+                        throw new ArgumentException("Factory must not be null if type is not XmlElement", "factory");
+                    m_factory = new ElementFactory();
+                }
+                else
+                    m_factory = value;
+            }
+        }
+
+        /// <summary>
+        /// The name of the file to manage.
+        /// </summary>
+        public string FileName
+        {
+            get { return m_fileName; }
+            set 
+            {
+                if (value == null)
+                    throw new ArgumentNullException("fileName");
+                if (value == "")
+                    throw new ArgumentOutOfRangeException("fileName");
+
+                lock (this)
+                {
+                    if (value == null)
+                        throw new ArgumentNullException("FileName");
+                    if (m_fileName == value)
+                        return;
+                    m_fileName = value;
+                    Read();
+                }
+            }
+        }
+
+        private void Flush()
+        {
+            Debug.Assert(m_cache != null, "m_cache should be initialized in constructor");
+
+            XmlDocument doc = new XmlDocument();
+            XmlElement fm = doc.CreateElement("fm", NS);
+            doc.AppendChild(fm);
+
+            XmlElement val;
+            lock (this)
+            {
+                foreach (KeyValuePair<string, T> kv in m_cache)
+                {
+                    val = doc.CreateElement("val", NS);
+                    val.SetAttribute("name", kv.Key);
+                    if (kv.Value != null)
+                        val.AppendChild(doc.ImportNode(kv.Value, true));
+                    fm.AppendChild(val);
+                }
+            }
+            XmlWriter xw = new XmlTextWriter(m_fileName, System.Text.Encoding.UTF8);
+            doc.WriteTo(xw);
+            xw.Close();
+        }
+
+        private void Read()
+        {
+            lock (this)
+            {
+                m_cache = new Dictionary<string, T>();
+                try
+                {
+                    XmlDocument doc = new XmlDocument();
+                    doc.Load(m_fileName);
+                    XmlElement fm = doc.DocumentElement;
+                    foreach (XmlElement val in fm.GetElementsByTagName("val"))
+                    {
+                        string name = val.GetAttribute("name");
+                        if (name == "")
+                            continue;
+                        foreach (XmlNode child in val.ChildNodes)
+                        {
+                            if (child is XmlElement)
+                            {
+                                m_cache[name] = (T)Element.AddTypes((XmlElement)child, m_factory);
+                                break;
+                            }
+                        }
+                    }
+                }
+                catch (Exception ex)
+                {
+                    Debug.WriteLine("WARNING: " + ex.ToString());
+                }
+            }
+        }
+
+        /// <summary>
+        /// Remove the specified key and value
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
+        public bool Remove(string key)
+        {
+            bool ret = m_cache.Remove(key);
+            if (ret)
+                Flush();
+            return ret;
+        }
+
+        /// <summary>
+        /// Get or set the XmlElement associated with the given key.
+        /// If the key already has a value, it WILL NOT be overridden; you 
+        /// MUST call Clear or Remove first.
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
+        public T this[string key]
+        {
+            get
+            {
+                T val = null;
+                if (m_cache.TryGetValue(key, out val))
+                    return val;
+                return null;
+            }
+            set
+            {
+                if (m_cache.ContainsKey(key))
+                    return;
+                m_cache[key] = value;
+                Flush();
+            }
+        }
+
+        /// <summary>
+        /// How many key/value pairs are stored?
+        /// </summary>
+        public int Count
+        {
+            get { return m_cache.Count; }
+        }
+
+        /// <summary>
+        /// Clear all stored keys/values.
+        /// </summary>
+        public void Clear()
+        {
+            if (Count == 0)
+                return;
+            m_cache.Clear();
+            Flush();
+        }
+
+        /// <summary>
+        /// Is the given key in the map?
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
+        public bool Contains(string key)
+        {
+            return m_cache.ContainsKey(key);
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/connection/HttpStanzaStream.cs b/lib/jabber-net/jabber/connection/HttpStanzaStream.cs
new file mode 100644
index 0000000..ef8005e
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/HttpStanzaStream.cs
@@ -0,0 +1,302 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+
+using System;
+using System.Diagnostics;
+using System.Xml;
+using bedrock.net;
+using bedrock.util;
+using jabber.protocol;
+
+namespace jabber.connection
+{
+    /// <summary>
+    /// Manages the HTTP Polling XMPP stream.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public abstract class HttpStanzaStream : StanzaStream, ISocketEventListener
+    {
+        private AsynchElementStream m_elements = null;
+        private BaseSocket m_sock = null;
+
+        /// <summary>
+        /// The underlying socket
+        /// </summary>
+        protected BaseSocket Socket
+        {
+            get { return m_sock; }
+        }
+
+        /// <summary>
+        /// Create a new one.
+        /// </summary>
+        /// <param name="listener"></param>
+        internal HttpStanzaStream(IStanzaEventListener listener)
+            : base(listener)
+        {
+        }
+
+        /// <summary>
+        /// Determines whether or not the client is connected to the XMPP server.
+        /// </summary>
+        public override bool Connected
+        {
+            get { return m_sock.Connected; }
+        }
+
+        /// <summary>
+        /// Supports Start-TLS if SSL is enabled.
+        /// </summary>
+        public override bool SupportsTLS
+        {
+            get { return false; }
+        }
+
+        /// <summary>
+        /// Sets up the element stream.  This is the place to add factories.
+        /// </summary>
+        public override void InitializeStream()
+        {
+            bool first = (m_elements == null);
+            m_elements = new AsynchElementStream();
+            m_elements.OnDocumentStart += new ProtocolHandler(m_elements_OnDocumentStart);
+            m_elements.OnDocumentEnd += new bedrock.ObjectHandler(m_elements_OnDocumentEnd);
+            m_elements.OnElement += new ProtocolHandler(m_elements_OnElement);
+            m_elements.OnError += new bedrock.ExceptionHandler(m_elements_OnError);
+
+            m_listener.StreamInit(m_elements);
+
+            Debug.Assert(this.Connected);
+            if (first)
+                m_sock.RequestRead();
+        }
+
+        /// <summary>
+        /// Connects the outbound socket.
+        /// </summary>
+        public override void Connect()
+        {
+            int port = (int)m_listener[Options.PORT];
+            Debug.Assert(port > 0);
+
+            m_sock = CreateSocket();
+
+
+            string to = (string)m_listener[Options.TO];
+            Debug.Assert(to != null);
+
+            string host = (string)m_listener[Options.NETWORK_HOST];
+            if ((host == null) || (host == ""))
+                host = to;
+
+            string url = (string)m_listener[Options.POLL_URL];
+            if ((url == null) || (url == ""))
+            {
+#if !__MonoCS__
+                url = Address.LookupTXT("_xmppconnect.", to, "_xmpp-client-xbosh");
+                if (url == null)
+#endif
+                    throw new ArgumentNullException("URL not found in DNS, and not specified", "URL");
+            }
+            ((IHttpSocket)m_sock).URL = url;
+
+            //Address addr = new Address(host, port);
+            m_sock.Connect(null, (string)m_listener[Options.SERVER_ID]);
+        }
+
+        /// <summary>
+        /// Create a socket of the correct type.
+        /// </summary>
+        /// <returns></returns>
+        protected abstract BaseSocket CreateSocket();
+
+        /// <summary>
+        /// Listens for an inbound connection.
+        /// </summary>
+        public override void Accept()
+        {
+            AsyncSocket s = new AsyncSocket(null, this, (bool)m_listener[Options.SSL], false);
+            s.LocalCertificate = m_listener[Options.LOCAL_CERTIFICATE] as
+                System.Security.Cryptography.X509Certificates.X509Certificate2;
+
+            m_sock = s;
+            m_sock.Accept(new Address((int)m_listener[Options.PORT]));
+            m_sock.RequestAccept();
+        }
+
+        /// <summary>
+        /// Writes a string to the stream.
+        /// </summary>
+        /// <param name="str">
+        /// The string to write; this will be transcoded to UTF-8.
+        /// </param>
+        public override void Write(string str)
+        {
+            //int keep = (int)m_listener[Options.KEEP_ALIVE];
+            m_sock.Write(ENC.GetBytes(str));
+        }
+
+        /// <summary>
+        /// Writes a stream:stream start tag.
+        /// </summary>
+        /// <param name="stream">Stream containing the stream:stream packet to send.</param>
+        public override void WriteStartTag(jabber.protocol.stream.Stream stream)
+        {
+            Write(stream.StartTag());
+        }
+
+        /// <summary>
+        /// Writes a full stanza.
+        /// </summary>
+        /// <param name="elem">The stanza to write out.</param>
+        public override void Write(XmlElement elem)
+        {
+            if (m_sock is IElementSocket)
+                ((IElementSocket)m_sock).Write(elem);
+            else
+                Write(elem.OuterXml);
+        }
+
+        /// <summary>
+        /// Closes the socket connection.
+        /// </summary>
+        /// <param name="clean">Sends the stream:stream close packet if true.</param>
+        public override void Close(bool clean)
+        {
+            // TODO: socket should still be connected, excepts for races.  Revist.
+            if (clean)
+                Write("</stream:stream>");
+            m_sock.Close();
+        }
+
+#if !NO_SSL
+        /// <summary>
+        /// Negotiates Start-TLS with the other endpoint.
+        /// </summary>
+        public override void StartTLS()
+        {
+            //m_sock.StartTLS();
+            //XEP25Socket s = Sock;
+
+            //Debug.Assert(s != null);
+            //m_listener[Options.REMOTE_CERTIFICATE] = s.RemoteCertificate;
+        }
+#endif
+
+        #region ElementStream handlers
+        private void m_elements_OnDocumentStart(object sender, XmlElement rp)
+        {
+            m_listener.DocumentStarted(rp);
+        }
+
+        private void m_elements_OnDocumentEnd(object sender)
+        {
+            m_listener.DocumentEnded();
+        }
+
+        private void m_elements_OnElement(object sender, XmlElement rp)
+        {
+            m_listener.StanzaReceived(rp);
+        }
+
+        private void m_elements_OnError(object sender, Exception ex)
+        {
+            // XML parse error.
+            m_listener.Errored(ex);
+        }
+        #endregion
+
+        #region ISocketEventListener Members
+
+        void ISocketEventListener.OnInit(BaseSocket newSock)
+        {
+        }
+
+        ISocketEventListener ISocketEventListener.GetListener(BaseSocket newSock)
+        {
+            return this;
+        }
+
+        bool ISocketEventListener.OnAccept(BaseSocket newsocket)
+        {
+            m_sock = newsocket;
+            InitializeStream();
+            m_listener.Accepted();
+
+            // Don't accept any more connections until this one closes
+            // yes, it will look like we're still listening until the old sock is free'd by GC.
+            // don't want OnClose() to fire, though, so we can't close the previous sock.
+            return false;
+        }
+
+        void ISocketEventListener.OnConnect(BaseSocket sock)
+        {
+#if !NO_SSL
+            if ((bool)m_listener[Options.SSL])
+            {
+                XEP25Socket s = sock as XEP25Socket;
+
+                m_listener[Options.REMOTE_CERTIFICATE] = s.RemoteCertificate;
+            }
+#endif
+            m_listener.Connected();
+        }
+
+        void ISocketEventListener.OnClose(BaseSocket sock)
+        {
+            m_listener[Options.REMOTE_CERTIFICATE] = null;
+            m_elements = null;
+            m_listener.Closed();
+        }
+
+        void ISocketEventListener.OnError(BaseSocket sock, Exception ex)
+        {
+            m_listener[Options.REMOTE_CERTIFICATE] = null;
+            m_elements = null;
+            m_listener.Errored(ex);
+        }
+
+        bool ISocketEventListener.OnRead(BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            Debug.Assert(m_listener != null);
+            Debug.Assert(m_elements != null);
+            m_listener.BytesRead(buf, offset, length);
+            m_elements.Push(buf, offset, length);
+            return true;
+        }
+
+        void ISocketEventListener.OnWrite(BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            m_listener.BytesWritten(buf, offset, length);
+        }
+
+        /// <summary>
+        /// An invalid peer certificate was sent during SSL/TLS neogtiation.
+        /// </summary>
+        /// <param name="sock">The socket that experienced the error</param>
+        /// <param name="certificate">The bad certificate</param>
+        /// <param name="chain">The chain of CAs for the cert</param>
+        /// <param name="sslPolicyErrors">A bitfield for the erorrs in the certificate.</param>
+        /// <returns>True if the cert should be accepted anyway.</returns>
+        bool ISocketEventListener.OnInvalidCertificate(BaseSocket sock,
+            System.Security.Cryptography.X509Certificates.X509Certificate certificate,
+            System.Security.Cryptography.X509Certificates.X509Chain chain,
+            System.Net.Security.SslPolicyErrors sslPolicyErrors)
+        {
+            return m_listener.OnInvalidCertificate(sock, certificate, chain, sslPolicyErrors);
+        }
+        #endregion
+    }
+}
+
diff --git a/lib/jabber-net/jabber/connection/HttpUploader.cs b/lib/jabber-net/jabber/connection/HttpUploader.cs
new file mode 100644
index 0000000..d1f1202
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/HttpUploader.cs
@@ -0,0 +1,78 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using System.Net;
+using System.IO;
+using System.Collections;
+
+using bedrock.util;
+
+namespace jabber.connection
+{
+    /// <summary>
+    /// Manages HTTP Requests via XMPP (XEP-70).
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class HttpUploader
+    {
+        /// <summary>
+        /// Notifies the client that an upload has finished.
+        /// </summary>
+        public event bedrock.ObjectHandler OnUpload;
+
+        private void ResponseCallback(IAsyncResult result)
+        {
+            HttpWebRequest request  = (HttpWebRequest)result.AsyncState;
+            //request.GetResponse().GetResponseStream();
+            if (OnUpload != null)
+                OnUpload(this);
+        }
+
+        /// <summary>
+        /// Uploads a file to a given URL and verifies the HTTP request
+        /// through the XMPP server (XEP-0070).
+        /// </summary>
+        /// <param name="uri">URI to send the file to.</param>
+        /// <param name="jid">JID to send as.</param>
+        /// <param name="filename">File to send.</param>
+        public void Upload(string uri, string jid, string filename)
+        {
+            //try
+            //{
+            StreamReader reader = new StreamReader(filename);
+            HttpWebRequest request =
+                (HttpWebRequest)HttpWebRequest.Create(uri);
+
+            request.Method = "POST";
+            request.Headers.Add(HttpRequestHeader.Authorization,
+                                "x-xmpp-auth jid=\"" + jid + "\"");
+
+            StreamWriter writer = new StreamWriter(request.GetRequestStream());
+            writer.Write(reader.ReadToEnd());
+
+            reader.Close();
+
+            request.BeginGetResponse(new AsyncCallback(ResponseCallback),
+                                     request);
+            writer.Close();
+            // }
+            // catch (WebException)
+            // {
+            // }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/connection/IQTracker.cs b/lib/jabber-net/jabber/connection/IQTracker.cs
new file mode 100644
index 0000000..2c1ee14
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/IQTracker.cs
@@ -0,0 +1,230 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Threading;
+using System.Xml;
+
+using bedrock.util;
+using jabber.protocol.client;
+
+namespace jabber.connection
+{
+    /// <summary>
+    /// Informs the client that a response to an IQ request has been received.
+    /// </summary>
+    public delegate void IqCB(object sender, IQ iq, object data);
+
+    /// <summary>
+    /// Informs the client that an IQ has timed out.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class IQTimeoutException : Exception
+    {
+        /// <summary>
+        /// Creates a new timeout exception.
+        /// </summary>
+        /// <param name="message">Description of the error.</param>
+        public IQTimeoutException(string message)
+            : base(message)
+        {
+        }
+    }
+
+    ///<summary>
+    /// Represents the interface for tracking an IQ packet.
+    ///</summary>
+    [SVN(@"$Id$")]
+    public interface IIQTracker
+    {
+        ///<summary>
+        /// Does an asynchronous IQ call.
+        ///</summary>
+        ///<param name="iq">IQ packet to send.</param>
+        ///<param name="cb">Callback to execute when the result comes back.</param>
+        ///<param name="cbArg">Arguments to pass to the callback.</param>
+        void BeginIQ(IQ iq, IqCB cb, object cbArg);
+
+        ///<summary>
+        /// Does a synchronous IQ call.
+        ///</summary>
+        ///<param name="iqp">IQ packet to send.</param>
+        ///<param name="millisecondsTimeout">Time, in milliseconds, to wait for the response.</param>
+        ///<returns>The IQ packet that was sent back.</returns>
+        IQ IQ(IQ iqp, int millisecondsTimeout);
+    }
+
+    /// <summary>
+    /// Tracks outstanding IQ requests.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class IQTracker: IIQTracker
+    {
+        private Dictionary<string, TrackerData> m_pending = new Dictionary<string, TrackerData>();
+        private XmppStream m_cli     = null;
+
+        /// <summary>
+        /// Creates a new IQ tracker.
+        /// </summary>
+        /// <param name="stream">The client to send/receive on</param>
+        public IQTracker(XmppStream stream)
+        {
+            m_cli = stream;
+            m_cli.OnProtocol += new jabber.protocol.ProtocolHandler(OnIQ);
+        }
+
+        private void OnIQ(object sender, XmlElement elem)
+        {
+            IQ iq = elem as IQ;
+            if (iq == null)
+                return;
+            if ((iq.Type != IQType.result) && (iq.Type != IQType.error))
+                return;
+
+            string id = iq.ID;
+            TrackerData td;
+
+            lock (m_pending)
+            {
+                if (!m_pending.TryGetValue(id, out td))
+                    return;
+
+                // this wasn't one that was being tracked.
+                if (!td.IsMatch(iq))
+                    return;
+
+                m_pending.Remove(id);
+            }
+
+            td.Call(this, iq);
+        }
+
+        /// <summary>
+        /// Starts an IQ request.
+        /// </summary>
+        /// <param name="iq">IQ to send.</param>
+        /// <param name="cb">Callback to use when a response comes back.</param>
+        /// <param name="cbArg">Arguments to the callback.</param>
+        public void BeginIQ(IQ iq, IqCB cb, object cbArg)
+        {
+            // if no callback, ignore response.
+            if (cb != null)
+            {
+                TrackerData td = new TrackerData(cb, cbArg, iq.To, iq.ID);
+                lock (m_pending)
+                {
+                    m_pending[iq.ID] = td;
+                }
+            }
+            m_cli.Write(iq);
+        }
+
+        /// <summary>
+        /// Sends an IQ request and waits for the response.
+        /// </summary>
+        /// <param name="iqp">An IQ packet to send, and wait for.</param>
+        /// <param name="millisecondsTimeout">Time to wait for response, in milliseconds</param>
+        /// <returns>An IQ in reponse to the sent IQ.</returns>
+        public IQ IQ(IQ iqp, int millisecondsTimeout)
+        {
+            AutoResetEvent are = new AutoResetEvent(false);
+            TrackerData td = new TrackerData(SignalEvent, are, iqp.To, iqp.ID);
+            string id = iqp.ID;
+            lock (m_pending)
+            {
+                m_pending[id] = td;
+            }
+            m_cli.Write(iqp);
+
+            if (!are.WaitOne(millisecondsTimeout, true))
+            {
+                throw new Exception("Timeout waiting for IQ response");
+            }
+
+            lock (m_pending)
+            {
+                IQ resp = td.Response;
+                m_pending.Remove(id);
+                return resp;
+            }
+        }
+
+        private void SignalEvent(object sender, IQ iq, object data)
+        {
+            ((AutoResetEvent)data).Set();
+        }
+
+        /// <summary>
+        /// Internal state for a pending tracker request
+        /// </summary>
+        [SVN(@"$Id$")]
+        public class TrackerData
+        {
+            private IqCB  cb;
+            private object data;
+            private JID jid;
+            private string id;
+            private IQ response = null;
+
+            /// <summary>
+            /// Create a tracker data instance.
+            /// </summary>
+            /// <param name="callback"></param>
+            /// <param name="state"></param>
+            /// <param name="to"></param>
+            /// <param name="iq_id"></param>
+            public TrackerData(IqCB callback, object state, JID to, string iq_id)
+            {
+                Debug.Assert(callback != null);
+                cb = callback;
+                data = state;
+                jid = to;
+                id = iq_id;
+            }
+
+            /// <summary>
+            /// The response that came in.
+            /// </summary>
+            public IQ Response
+            {
+                get { return response; }
+            }
+
+            /// <summary>
+            /// Is this IQ the one we're looking for?
+            /// </summary>
+            /// <param name="iq"></param>
+            /// <returns></returns>
+            public bool IsMatch(IQ iq)
+            {
+                JID from = iq.From;
+                return (iq.ID == id) && ((jid == null) || (from == null) || (from == jid));
+            }
+
+            /// <summary>
+            /// Call the callback.
+            /// </summary>
+            /// <param name="sender"></param>
+            /// <param name="iq"></param>
+            public void Call(object sender, IQ iq)
+            {
+                response = iq;
+                cb(sender, iq, data);
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/connection/PollingStanzaStream.cs b/lib/jabber-net/jabber/connection/PollingStanzaStream.cs
new file mode 100644
index 0000000..952866d
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/PollingStanzaStream.cs
@@ -0,0 +1,50 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Diagnostics;
+using System.Threading;
+using System.Xml;
+
+using bedrock.net;
+using bedrock.util;
+using jabber.protocol;
+using System.Security.Cryptography;
+
+namespace jabber.connection
+{
+    /// <summary>
+    /// Manages the HTTP Polling XMPP stream.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PollingStanzaStream : HttpStanzaStream
+    {
+        ///<summary>
+        /// Creates a PollingStanzaStream
+        ///</summary>
+        ///<param name="listener">Listener associated with PollingStanzaStream.</param>
+        public PollingStanzaStream(IStanzaEventListener listener) : base(listener)
+        {
+        }
+
+        /// <summary>
+        /// Create a XEP25Socket.
+        /// </summary>
+        /// <returns></returns>
+        protected override BaseSocket CreateSocket()
+        {
+            return new XEP25Socket(this);
+        }
+    }
+}
+
diff --git a/lib/jabber-net/jabber/connection/PubSubManager.bmp b/lib/jabber-net/jabber/connection/PubSubManager.bmp
new file mode 100644
index 0000000..02dfc7f
Binary files /dev/null and b/lib/jabber-net/jabber/connection/PubSubManager.bmp differ
diff --git a/lib/jabber-net/jabber/connection/PubSubManager.cs b/lib/jabber-net/jabber/connection/PubSubManager.cs
new file mode 100644
index 0000000..eab1c91
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/PubSubManager.cs
@@ -0,0 +1,1164 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Xml;
+using bedrock.util;
+using jabber.protocol;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+
+namespace jabber.connection
+{
+    /// <summary>
+    /// Manages a set of publish-subscribe (<a href="http://www.xmpp.org/extensions/xep-0060.html">XEP-60</a>) subscriptions.
+    /// The goal is to have a list of jid/node combinations, each of which is a singleton.
+    /// <example>
+    /// PubSubNode node = ps.GetNode("infobroker.corp.jabber.com", "test/foo", 10);
+    /// node.AddItemAddCallback(new ItemCB(node_OnItemAdd));
+    /// node.OnItemRemove += new ItemCB(node_OnItemRemove);
+    /// node.OnError += new bedrock.ExceptionHandler(node_OnError);
+    /// node.AutomatedSubscribe();
+    /// </example>
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PubSubManager : StreamComponent
+    {
+        private class CBHolder
+        {
+            public string Node = null;
+            public int Max = 10;
+            public event ItemCB OnAdd;
+            public event ItemCB OnRemove;
+
+            public void FireAdd(PubSubNode node, PubSubItem item)
+            {
+                if (OnAdd != null)
+                    OnAdd(node, item);
+            }
+            public void FireRemove(PubSubNode node, PubSubItem item)
+            {
+                if (OnRemove != null)
+                    OnRemove(node, item);
+            }
+        }
+
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private IContainer components = null;
+        private Dictionary<JIDNode, PubSubNode> m_nodes = new Dictionary<JIDNode,PubSubNode>();
+        private Dictionary<string, CBHolder> m_callbacks = new Dictionary<string, CBHolder>();
+
+        /// <summary>
+        /// Creates a manager.
+        /// </summary>
+        public PubSubManager()
+        {
+            InitializeComponent();
+            this.OnStreamChanged += new bedrock.ObjectHandler(PubSubManager_OnStreamChanged);
+        }
+
+        /// <summary>
+        /// Creates a manager in a container.
+        /// </summary>
+        /// <param name="container">Parent container.</param>
+        public PubSubManager(IContainer container) : this()
+        {
+            container.Add(this);
+        }
+
+        private void PubSubManager_OnStreamChanged(object sender)
+        {
+            m_stream.OnProtocol += new ProtocolHandler(m_stream_OnProtocol);
+        }
+
+        private void m_stream_OnProtocol(object sender, XmlElement rp)
+        {
+            Message msg = rp as Message;
+            if (msg == null)
+                return;
+            PubSubEvent evt = msg["event", URI.PUBSUB_EVENT] as PubSubEvent;
+            if (evt == null)
+                return;
+
+            EventItems items = evt.GetChildElement<EventItems>();
+            if (items == null)
+                return;
+
+            string node = items.Node;
+            JID from = msg.From.BareJID;
+            JIDNode jn = new JIDNode(from, node);
+            PubSubNode psn = null;
+            if (!m_nodes.TryGetValue(jn, out psn))
+            {
+                CBHolder holder = null;
+                if (!m_callbacks.TryGetValue(node, out holder))
+                {
+                    Console.WriteLine("WARNING: notification received for unknown pubsub node");
+                    return;
+                }
+                psn = new PubSubNode(m_stream, from, node, holder.Max);
+                psn.OnItemAdd += holder.FireAdd;
+                psn.OnItemRemove += holder.FireRemove;
+                m_nodes[jn] = psn;
+            }
+            psn.FireItems(items);
+        }
+
+        /// <summary>
+        /// Performs tasks associated with freeing, releasing, or resetting resources.
+        /// </summary>
+        /// <param name="disposing">True if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Component Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            components = new System.ComponentModel.Container();
+        }
+
+        #endregion
+
+        /// <summary>
+        /// Notifies the client that an error occurred.  If this is set, it will be copied to
+        /// each node that is created by the manager.
+        /// </summary>
+        public event bedrock.ExceptionHandler OnError;
+
+        /// <summary>
+        /// Add a handler for all inbound notifications with the given node name.
+        /// This is handy for PEP implicit subscriptions.
+        /// </summary>
+        /// <param name="node">PEP node URI</param>
+        /// <param name="addCB">Callback when items added</param>
+        /// <param name="removeCB">Callbacks when items removed</param>
+        /// <param name="maxNumber">Maximum number of items to store per node in this namespace</param>
+        public void AddNodeHandler(string node, ItemCB addCB, ItemCB removeCB, int maxNumber)
+        {
+            CBHolder holder = null;
+            if (!m_callbacks.TryGetValue(node, out holder))
+            {
+                holder = new CBHolder();
+                holder.Node = node;
+                holder.Max = maxNumber;
+                m_callbacks[node] = holder;
+            }
+            holder.OnAdd += addCB;
+            holder.OnRemove += removeCB;
+        }
+
+        /// <summary>
+        /// Remove an existing callback.
+        /// </summary>
+        /// <param name="node"></param>
+        /// <param name="cb"></param>
+        public void RemoveNodeHandler(string node, ItemCB cb)
+        {
+            CBHolder holder = null;
+            if (m_callbacks.TryGetValue(node, out holder))
+            {
+                // tests indicate removing from a list that doesn't contain this callback is safe.
+                holder.OnAdd -= cb;
+                holder.OnRemove -= cb;
+            }
+        }
+
+        /// <summary>
+        /// Subscribes to a publish-subscribe node.
+        /// </summary>
+        /// <param name="service">Component that handles PubSub requests.</param>
+        /// <param name="node">The node on the component that the client wants to interact with.</param>
+        /// <param name="maxItems">Maximum number of items to retain.  First one to call Subscribe gets their value, for now.</param>
+        /// <returns>
+        /// The existing node will be returned if there is already a subscription.
+        /// If the node does not exist, the PubSubNode object will be returned
+        /// in a subscribing state.
+        /// </returns>
+        public PubSubNode GetNode(JID service, string node, int maxItems)
+        {
+            JIDNode jn = new JIDNode(service, node);
+            PubSubNode n = null;
+            if (m_nodes.TryGetValue(jn, out n))
+                return n;
+            n = new PubSubNode(Stream, service, node, maxItems);
+            m_nodes[jn] = n;
+            n.OnError += OnError;
+            return n;
+        }
+
+        ///<summary>
+        /// Removes the publish-subscribe node from the manager and sends a delete
+        /// node to the XMPP server.
+        ///</summary>
+        /// <param name="service">
+        /// Component that handles PubSub requests.
+        /// </param>
+        /// <param name="node">
+        /// The node on the component that the client wants to interact with.
+        /// </param>
+        /// <param name="errorHandler">
+        /// Callback for any errors with the publish-subscribe node deletion.
+        /// </param>
+        public void RemoveNode(JID service, string node, bedrock.ExceptionHandler errorHandler)
+        {
+            JIDNode jn = new JIDNode(service, node);
+
+            PubSubNode psNode = null;
+            if (m_nodes.TryGetValue(jn, out psNode))
+            {
+                m_nodes.Remove(jn);
+            }
+            else
+            {
+                psNode = new PubSubNode(Stream, service, node, 10);
+            }
+
+            psNode.OnError += errorHandler;
+
+            psNode.Delete();
+        }
+
+
+        /// <summary>
+        /// Get the default configuration of the node.
+        /// </summary>
+        /// <param name="service">JID of the pub/sub service</param>
+        /// <param name="callback">Callback.  Must not be null.  Will not be called back 
+        /// if there is an error, but instead OnError will be called.</param>
+        /// <param name="state">State information to be passed back to callback</param>
+        public void GetDefaults(JID service, IqCB callback, object state)
+        {
+            OwnerPubSubCommandIQ<OwnerDefault> iq = new OwnerPubSubCommandIQ<OwnerDefault>(m_stream.Document);
+            iq.To = service;
+            iq.Type = IQType.get;
+            BeginIQ(iq, OnDefaults, new IQTracker.TrackerData(callback, state, null, null));
+        }
+
+        private void OnDefaults(object sender, IQ iq, object data)
+        {
+            if (iq == null)
+            {
+                if (OnError != null)
+                    OnError(this, new PubSubException(Op.DEFAULTS, "IQ timeout", null));
+                return;
+            }
+
+            if (iq.Type != IQType.result)
+            {
+                string msg = string.Format("Error configuring pubsub node: {0}", iq.Error.Condition);
+                Debug.WriteLine(msg);
+
+                if (OnError != null)
+                    OnError(this, new PubSubException(Op.DEFAULTS, msg, iq));
+                return;
+            }
+            PubSubOwner ow = iq.Query as PubSubOwner;
+            if (ow == null)
+            {
+                if (OnError != null)
+                    OnError(this, new PubSubException(Op.DEFAULTS, "Invalid protocol", iq));
+                return;
+            }
+
+            OwnerDefault conf = ow.Command as OwnerDefault;
+            if (conf == null)
+            {
+                if (OnError != null)
+                    OnError(this, new PubSubException(Op.DEFAULTS, "Invalid protocol", iq));
+                return;
+            }
+
+            IQTracker.TrackerData td = data as IQTracker.TrackerData;
+            td.Call(this, iq);
+        }
+    }
+
+    /// <summary>
+    /// Notifies the client about a publish-subscribe item.
+    /// </summary>
+    public delegate void ItemCB(PubSubNode node, PubSubItem item);
+
+    /// <summary>
+    /// Manages a list of items with a maximum size.  Only one item with a given ID will be in the
+    /// list at a given time.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ItemList : ArrayList
+    {
+        private Hashtable m_index = new Hashtable();
+        private PubSubNode m_node = null;
+
+        /// <summary>
+        /// Creates an item list, which will have at most some number of items.
+        /// </summary>
+        /// <param name="node">The node to which this item list applies.</param>
+        /// <param name="maxItems">Maximum size of the list.  Delete notifications will be sent if this size is exceeded.</param>
+        public ItemList(PubSubNode node, int maxItems) : base(maxItems)
+        {
+            m_node = node;
+        }
+
+        /// <summary>
+        /// Makes sure that the underlying ID index is in sync
+        /// when an item is removed.
+        /// </summary>
+        /// <param name="index">Index of PubSubItem to remove.</param>
+        public override void RemoveAt(int index)
+        {
+            PubSubItem item = (PubSubItem)this[index];
+            string id = item.GetAttribute("id");
+            if (id != "")
+            {
+                m_index.Remove(id);
+            }
+            base.RemoveAt(index);
+            m_node.ItemRemoved(item);
+
+            // renumber
+            for (int i=index; i<Count; i++)
+            {
+                item = (PubSubItem)this[i];
+                id = item.ID;
+                if (id != "")
+                    m_index[id] = i;
+            }
+        }
+
+        /// <summary>
+        /// Adds to the end of the list, replacing any item with the same ID,
+        /// or bumping the oldest item if the list is full.
+        /// </summary>
+        /// <param name="value">PubSubItem to add to the list.</param>
+        /// <returns>Index where the PubSubItem was inserted.</returns>
+        public override int Add(object value)
+        {
+            PubSubItem item = value as PubSubItem;
+            if (item == null)
+                throw new ArgumentException("Must be an XmlElement", "value");
+            string id = item.ID;
+            int i;
+            if (id == null)
+            {
+                if (Count == Capacity)
+                {
+                    RemoveAt(0);
+                }
+                i = base.Add(value);
+                m_node.ItemAdded(item);
+                return i;
+            }
+
+            // RemoveId(id);
+            if (!m_index.Contains(id) && (Count == Capacity))
+                RemoveAt(0);
+
+            i = base.Add(value);
+            m_index[id] = i;
+            m_node.ItemAdded(item);
+            return i;
+        }
+
+        /// <summary>
+        /// Removes the item with the given ID.
+        /// No exception is thrown if no item is found with that ID.
+        /// </summary>
+        /// <param name="id">ID of the item to remove</param>
+        public void RemoveId(string id)
+        {
+            object index = m_index[id];
+            if (index != null)
+                RemoveAt((int)index);
+        }
+
+        /// <summary>
+        /// Gets or sets the contents of the specified item.
+        /// </summary>
+        /// <param name="id">Id of the PubSubItem.</param>
+        /// <returns>XmlElement representing the contents of the PubSubItem.</returns>
+        public XmlElement this[string id]
+        {
+            get
+            {
+                object index = m_index[id];
+                if (index == null)
+                    return null;
+                PubSubItem item = this[(int)index] as PubSubItem;
+                if (item == null)
+                    return null;
+                return item.Contents;
+            }
+            set
+            {
+                // wrap an item around the contents.
+                PubSubItem item = new PubSubItem(value.OwnerDocument);
+                item.Contents = value;
+                item.ID = id;
+                Add(item);
+            }
+        }
+    }
+
+
+    /// <summary>
+    /// Contains the different possible operations on a publish-subscribe node.
+    /// </summary>
+    public enum Op
+    {
+        /// <summary>
+        /// Creates a node
+        /// </summary>
+        CREATE,
+        /// <summary>
+        /// Subscribes to a node
+        /// </summary>
+        SUBSCRIBE,
+        /// <summary>
+        /// Gets the current items in the node
+        /// </summary>
+        ITEMS,
+        /// <summary>
+        /// Deletes a node
+        /// </summary>
+        DELETE,
+        /// <summary>
+        /// Deletes an item from the node
+        /// </summary>
+        DELETE_ITEM,
+        /// <summary>
+        /// Publishes an item to a node
+        /// </summary>
+        PUBLISH_ITEM,
+        /// <summary>
+        /// Configure a node
+        /// </summary>
+        CONFIGURE,
+        /// <summary>
+        /// Purge all items from a node.
+        /// </summary>
+        PURGE,
+        /// <summary>
+        /// Configuration defaults
+        /// </summary>
+        DEFAULTS
+    }
+
+    /// <summary>
+    /// Informs the client that a publish-subscribe error occurred.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PubSubException : Exception
+    {
+        /// <summary>
+        /// Contains the stanza that caused the error.
+        /// </summary>
+        public XmlElement Protocol = null;
+        /// <summary>
+        /// Contains the operation that failed.
+        /// </summary>
+        public Op Operation;
+
+        /// <summary>
+        /// Creates a new publish-subscribe exception.
+        /// </summary>
+        /// <param name="op">The operation that failed.</param>
+        /// <param name="error">A description of the error.</param>
+        /// <param name="elem">The stanza that caused the error.</param>
+        public PubSubException(Op op, string error, XmlElement elem) : base(error)
+        {
+            Operation = op;
+            Protocol = elem;
+        }
+
+        /// <summary>
+        /// Gets the error string.
+        /// </summary>
+        public override string Message
+        {
+            get
+            { return string.Format("PubSub error on {0}: {1}\r\nAssociated protocol: {2}", Operation, base.Message, Protocol); }
+        }
+    }
+
+    /// <summary>
+    /// Some event has occurred on a PubSub node.
+    /// </summary>
+    /// <param name="node"></param>
+    public delegate void NodeHandler(PubSubNode node);
+
+    /// <summary>
+    /// Manages a node to be subscribed to.  Will keep a maximum number of items.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PubSubNode : StreamComponent, IEnumerable
+    {
+        private enum STATE
+        {
+            Start,
+            Pending,
+            Asking,
+            Running,
+            Error,
+        }
+
+        // indexed by op.
+        private STATE[] m_state = new STATE[] { STATE.Start, STATE.Start, STATE.Start, STATE.Start};
+
+        private JID         m_jid = null;
+        private string      m_node = null;
+        private ItemList    m_items = null;
+
+        ///<summary>
+        /// Retrieves the component that handles publish-subscribe requests.
+        ///</summary>
+        public JID Jid
+        {
+            get { return m_jid; }
+        }
+
+        ///<summary>
+        /// Retrieves the node to interact with as defined by XEP-60.
+        ///</summary>
+        public string Node
+        {
+            get { return m_node; }
+        }
+
+        /// <summary>
+        /// Create a Node.  Next, call Create and/or Subscribe.
+        /// </summary>
+        /// <param name="stream"></param>
+        /// <param name="jid"></param>
+        /// <param name="node"></param>
+        /// <param name="maxItems"></param>
+        internal PubSubNode(XmppStream stream, JID jid, string node, int maxItems)
+        {
+            if (stream == null)
+                throw new ArgumentException("must not be null", "stream");
+            if (node == null)
+                throw new ArgumentException("must not be null", "node");
+            if (node == "")
+                throw new ArgumentException("must not be empty", "node");
+
+            m_stream = stream;
+            m_jid = jid;
+            m_node = node;
+            m_items = new ItemList(this, maxItems);
+        }
+
+        /// <summary>
+        /// The document associated with the stream we're attached to.
+        /// </summary>
+        public XmlDocument Document
+        {
+            get { return m_stream.Document; }
+        }
+
+        /// <summary>
+        /// Determines whether or not this node is fully initialized.
+        /// </summary>
+        public bool IsInitialized
+        {
+            get { return (this[Op.CREATE] == STATE.Running) && (this[Op.SUBSCRIBE] == STATE.Running); }
+        }
+
+        /// <summary>
+        /// Has the creation request succeeded?
+        /// </summary>
+        public bool IsCreated
+        {
+            get { return this[Op.CREATE] == STATE.Running; }
+        }
+
+        /// <summary>
+        /// Informs the client that an item has been added to the node,
+        /// either on initial get or by notification.
+        /// NOTE: This may fire for the same item more than once.
+        /// </summary>
+        public event ItemCB OnItemAdd;
+
+        /// <summary>
+        /// Informs the client that an item has been deleted from the node,
+        /// either by notification or the list being full.
+        /// </summary>
+        public event ItemCB OnItemRemove;
+
+
+        /// <summary>
+        /// Informs the publisher that an item has been published 
+        /// successfully.
+        /// </summary>
+        public event ItemCB OnItemPublished;
+
+        /// <summary>
+        /// Notifies the client that an error occurred.
+        /// </summary>
+        public event bedrock.ExceptionHandler OnError;
+
+        /// <summary>
+        /// Node has finished being created, successfully.
+        /// </summary>
+        public event NodeHandler OnCreate;
+
+        private STATE this[Op op]
+        {
+            get { return m_state[(int)op]; }
+            set { m_state[(int)op] = value; }
+        }
+
+        private void FireError(Op op, string message, XmlElement protocol)
+        {
+            Debug.WriteLine(string.Format("Error {0}ing pubsub node: {1}", op, message));
+            this[op] = STATE.Error;
+
+            if (OnError != null)
+                OnError(this, new PubSubException(op, message, protocol));
+        }
+
+        internal void FireItems(EventItems items)
+        {
+            // OK, it's for us.  Might be a new one or a retraction.
+            // Shrug, even if we're sent a mix, it shouldn't hurt anything.
+
+            /*
+            <message from='pubsub.shakespeare.lit' to='bernardo at denmark.lit' id='bar'>
+              <event xmlns='http://jabber.org/protocol/pubsub#event'>
+                <items node='princely_musings'>
+                  <retract id='ae890ac52d0df67ed7cfdf51b644e901'/>
+                </items>
+              </event>
+            </message>
+             */
+            foreach (string id in items.GetRetractions())
+                m_items.RemoveId(id);
+
+            foreach (PubSubItem item in items.GetItems())
+                m_items.Add(item);
+        }
+
+        /// <summary>
+        /// Adds a handler for the OnItemAdd event, and calls the handler for any existing
+        /// items.  To prevent races, use this rather than .OnItemAdd +=.
+        /// </summary>
+        /// <param name="callback">Callback to call with every item.</param>
+        public void AddItemAddCallback(ItemCB callback)
+        {
+            if (callback == null)
+                throw new ArgumentException("Must not be null", "callback");
+
+            OnItemAdd += callback;
+            foreach (PubSubItem item in m_items)
+            {
+                callback(this, item);
+            }
+        }
+
+        /// <summary>
+        /// Creates the node then subscribes. If the creation succeeded, or if the node
+        /// already exists, retrieve the items for the node.
+        ///
+        /// This is the typical starting point.  Please make sure to register callbacks before calling
+        /// this function.
+        /// </summary>
+        public void AutomatedSubscribe()
+        {
+            lock (this)
+            {
+                if ((this[Op.SUBSCRIBE] == STATE.Start) || (this[Op.SUBSCRIBE] == STATE.Error))
+                    this[Op.SUBSCRIBE] = STATE.Pending;
+                if ((this[Op.ITEMS] == STATE.Start) || (this[Op.ITEMS] == STATE.Error))
+                    this[Op.ITEMS] = STATE.Pending;
+            }
+            Create();
+        }
+
+        /// <summary>
+        /// Creates the node with default configuration.
+        /// </summary>
+        public void Create()
+        {
+            Create(null);
+        }
+
+        /// <summary>
+        /// Creates the node using the specified configuration form.
+        /// </summary>
+        /// <param name="config">Null for the default configuration</param>
+        public void Create(jabber.protocol.x.Data config)
+        {
+            lock (this)
+            {
+                if (!NeedsAsking(this[Op.CREATE]))
+                {
+                    SubscribeIfPending();
+                    return;
+                }
+
+                this[Op.CREATE] = STATE.Asking;
+            }
+/*
+<iq type='set'
+    from='hamlet at denmark.lit/elsinore'
+    to='pubsub.shakespeare.lit'
+    id='create1'>
+    <pubsub xmlns='http://jabber.org/protocol/pubsub'>
+      <create node='princely_musings'/>
+      <configure/>
+    </pubsub>
+</iq>
+ */
+            PubSubCommandIQ<Create> iq = new PubSubCommandIQ<Create>(m_stream.Document, m_node);
+            iq.To = m_jid;
+            iq.Type = IQType.set;
+            iq.Command.CreateConfiguration(config);
+            BeginIQ(iq, GotCreated, null);
+        }
+
+        private void GotCreated(object sender, IQ iq, object state)
+        {
+            if (iq.Type != IQType.result)
+            {
+                // Type=error with conflict is basically a no-op.
+                if (iq.Type != IQType.error)
+                {
+                    FireError(Op.CREATE, "Create failed, invalid protocol", iq);
+                    return;
+                }
+                Error err = iq.Error;
+                if (err == null)
+                {
+                    FireError(Op.CREATE, "Create failed, unknown error", iq);
+                    return;
+                }
+                if (err.Condition != Error.CONFLICT)
+                {
+                    FireError(Op.CREATE, "Error creating node", iq);
+                    return;
+                }
+            }
+            else
+            {
+                PubSub ps = iq.Query as PubSub;
+                if (ps != null)
+                {
+                    Create c = ps["create", URI.PUBSUB] as Create;
+                    if (c != null)
+                        m_node = c.Node;
+                }
+            }
+
+            this[Op.CREATE] = STATE.Running;
+
+            if (OnCreate != null)
+                OnCreate(this);
+
+            SubscribeIfPending();
+        }
+
+        private bool NeedsAsking(STATE state)
+        {
+            switch (state)
+            {
+            case STATE.Start:
+            case STATE.Pending:
+                return true;
+            case STATE.Asking:
+            case STATE.Running:
+                return false;
+            case STATE.Error:
+                Debug.WriteLine("Retrying create after error.  Hope you've changed perms or something in the mean time.");
+                return true;
+            }
+            return true;
+        }
+
+        private void SubscribeIfPending()
+        {
+            if (this[Op.SUBSCRIBE] == STATE.Pending)
+                Subscribe();
+        }
+
+        /// <summary>
+        /// Sends a subscription request.
+        /// Items request will be sent automatically on successful subscribe.
+        /// </summary>
+        public void Subscribe()
+        {
+            lock (this)
+            {
+                if (!NeedsAsking(this[Op.SUBSCRIBE]))
+                    return;
+
+                this[Op.SUBSCRIBE] = STATE.Asking;
+            }
+
+            PubSubIQ iq = createCommand(PubSubCommandType.subscribe);
+            addInfo(iq);
+            BeginIQ(iq, GotSubscribed, null);
+            // don't parallelize getItems, in case sub fails.
+        }
+
+        private PubSubIQ createCommand(PubSubCommandType type)
+        {
+            PubSubIQ iq = new PubSubIQ(m_stream.Document, type, m_node);
+            iq.To = m_jid;
+            iq.Type = IQType.set;
+
+            return iq;
+        }
+
+        private void addInfo(PubSubIQ iq)
+        {
+            Subscribe sub = (Subscribe) iq.Command;
+            sub.JID = m_stream.JID;
+        }
+
+        private void GotSubscribed(object sender, IQ iq, object state)
+        {
+            if (iq.Type != IQType.result)
+            {
+                FireError(Op.SUBSCRIBE, "Subscription failed", iq);
+                return;
+            }
+
+            PubSub ps = iq.Query as PubSub;
+            if (ps == null)
+            {
+                FireError(Op.SUBSCRIBE, "Invalid protocol", iq);
+                return;
+            }
+
+            PubSubSubscriptionType subType;
+            PubSubSubscription sub = ps["subscription", URI.PUBSUB] as PubSubSubscription;
+            if (sub != null)
+                subType = sub.Type;
+            else
+            {
+                XmlElement ent = ps["entity", URI.PUBSUB];
+                if (ent == null)
+                {
+                    FireError(Op.SUBSCRIBE, "Invalid protocol", iq);
+                    return;
+                }
+                string s = ent.GetAttribute("subscription");
+                if (s == "")
+                    subType = PubSubSubscriptionType.NONE_SPECIFIED;
+                else
+                    subType = (PubSubSubscriptionType)Enum.Parse(typeof(PubSubSubscriptionType), s);
+            }
+
+            switch (subType)
+            {
+            case PubSubSubscriptionType.NONE_SPECIFIED:
+            case PubSubSubscriptionType.subscribed:
+                break;
+            case PubSubSubscriptionType.pending:
+                FireError(Op.SUBSCRIBE, "Subscription pending authorization", iq);
+                return;
+            case PubSubSubscriptionType.unconfigured:
+                FireError(Op.SUBSCRIBE, "Subscription configuration required.  Not implemented yet.", iq);
+                return;
+            }
+
+            this[Op.SUBSCRIBE] = STATE.Running;
+            GetItemsIfPending();
+        }
+
+        private void GetItemsIfPending()
+        {
+            if (this[Op.ITEMS] == STATE.Pending)
+                GetItems();
+        }
+
+        /// <summary>
+        /// Gets the items from the node on the XMPP server.
+        /// </summary>
+        public void GetItems()
+        {
+            lock (this)
+            {
+                if (!NeedsAsking(this[Op.ITEMS]))
+                    return;
+                this[Op.ITEMS] = STATE.Asking;
+            }
+            PubSubIQ piq = new PubSubIQ(m_stream.Document, PubSubCommandType.items, m_node);
+            piq.To = m_jid;
+            piq.Type = IQType.get;
+            BeginIQ(piq, GotItems, null);
+        }
+
+        private void GotItems(object sender, IQ iq, object state)
+        {
+            if (iq.Type != IQType.result)
+            {
+                FireError(Op.ITEMS, "Error retrieving items", iq);
+                return;
+            }
+
+            PubSub ps = iq["pubsub", URI.PUBSUB] as PubSub;
+            if (ps == null)
+            {
+                FireError(Op.ITEMS, "Invalid pubsub protocol", iq);
+                return;
+            }
+            PubSubItemCommand items = ps["items", URI.PUBSUB] as PubSubItemCommand;
+            if (items == null)
+            {
+                // That doesn't really hurt us, I guess.  No items.  Keep going.
+                this[Op.ITEMS] = STATE.Running;
+                return;
+            }
+
+            if (items.Node != m_node)
+            {
+                FireError(Op.ITEMS, "Non-matching node.  Probably a server bug.", iq);
+                return;
+            }
+
+            foreach (PubSubItem item in items.GetItems())
+                m_items.Add(item);
+
+            this[Op.ITEMS] = STATE.Running;
+        }
+
+        /// <summary>
+        /// Notifies the client that an item has been add to this PubSubNode.
+        /// </summary>
+        /// <param name="item">Item that was added.</param>
+        public void ItemAdded(PubSubItem item)
+        {
+            if (OnItemAdd != null)
+                OnItemAdd(this, item);
+        }
+
+        /// <summary>
+        /// Notifies the client that an item has been removed from this PubSubNode.
+        /// </summary>
+        /// <param name="item">Item that was removed.</param>
+        public void ItemRemoved(PubSubItem item)
+        {
+            if (OnItemRemove != null)
+                OnItemRemove(this, item);
+        }
+
+        /// <summary>
+        /// Returns the contents of the specified item
+        /// </summary>
+        /// <param name="id">Index of the element to retrieve.</param>
+        /// <returns>XmlElement contents.</returns>
+        public XmlElement this[string id]
+        {
+            get { return m_items[id]; }
+            set
+            {
+                // TODO: publish, and reset ID when it comes back.
+                m_items[id] = value;
+            }
+        }
+
+        /// <summary>
+        /// Unsubscribes from the node.
+        /// </summary>
+        public void Unsubscribe()
+        {
+            PubSubIQ iq = createCommand(PubSubCommandType.unsubscribe);
+            BeginIQ(iq, GotUnsubsribed, null);
+        }
+
+        private void GotUnsubsribed(object sender, IQ iq, object data)
+        {
+            //TODO: Report back error
+        }
+
+        /// <summary>
+        /// Deletes the node from the XMPP server.
+        /// </summary>
+        public void Delete()
+        {
+            OwnerPubSubCommandIQ<OwnerDelete> iq = new OwnerPubSubCommandIQ<OwnerDelete>(m_stream.Document);
+            iq.To = m_jid;
+            iq.Type = IQType.set;
+            iq.Command.Node = m_node;
+            BeginIQ(iq, GotDelete, null);
+        }
+
+        private void GotDelete(object sender, IQ iq, object data)
+        {
+            if (iq.Type != IQType.result)
+            {
+                FireError(Op.DELETE, "Delete failed", iq);
+                return;
+            }
+        }
+
+        /// <summary>
+        /// Deletes a single item from the XMPP server.
+        /// </summary>
+        /// <param name="id">Id of item.</param>
+        public void DeleteItem(string id)
+        {
+            PubSubIQ iq = createCommand(PubSubCommandType.retract);
+            Retract retract = (Retract)iq.Command;
+            retract.AddItem(id);
+            BeginIQ(iq, OnDeleteNode, null);
+        }
+
+        private void OnDeleteNode(object sender, IQ iq, object data)
+        {
+            if (iq.Type != IQType.result)
+            {
+                string msg = string.Format("Error deleting pubsub item: {0}", iq.Error.Condition);
+                Debug.WriteLine(msg);
+
+                if (OnError != null)
+                    OnError(this, new PubSubException(Op.DELETE_ITEM, msg, iq));
+                return;
+            }
+        }
+
+        /// <summary>
+        /// Delete all items from a node at once.
+        /// </summary>
+        public void Purge()
+        {
+            OwnerPubSubCommandIQ<OwnerPurge> iq = new OwnerPubSubCommandIQ<OwnerPurge>(m_stream.Document);
+            iq.To = m_jid;
+            iq.Type = IQType.set;
+            iq.Command.Node = m_node;
+            BeginIQ(iq, GotPurge, null);
+
+        }
+
+        private void GotPurge(object sender, IQ iq, object data)
+        {
+            if (iq.Type != IQType.result)
+            {
+                FireError(Op.PURGE, "Purge failed", iq);
+                return;
+            }
+        }
+
+        /// <summary>
+        /// Publishes an item to the node.
+        /// </summary>
+        /// <param name="id">If null, the server will assign an item ID.</param>
+        /// <param name="contents">The XML inside the item.  Should be in a new namespace.</param>
+        public void PublishItem(string id, XmlElement contents)
+        {
+            PubSubIQ iq = createCommand(PubSubCommandType.publish);
+            Publish pub = (Publish)iq.Command;
+            PubSubItem item = new PubSubItem(m_stream.Document);
+            if (id != null)
+                item.ID = id;
+            item.AddChild(contents);
+            pub.AddChild(item);
+            BeginIQ(iq, new IqCB(OnPublished), item);
+        }
+
+        private void OnPublished(object sender, IQ iq, object data)
+        {
+            if (iq.Type != IQType.result)
+            {
+                string msg = string.Format("Error publishing pubsub item: {0}", iq.Error.Condition);
+                Debug.WriteLine(msg);
+
+                if (OnError != null)
+                    OnError(this, new PubSubException(Op.PUBLISH_ITEM, msg, iq));
+                return;
+            }
+
+            // TODO: if an item is returned, it will have a new item id.
+            if (OnItemPublished != null)
+                OnItemPublished(this, (PubSubItem)data);
+        }
+
+        /// <summary>
+        /// Request configuration form as the owner
+        /// </summary>
+        /// <param name="callback">Callback.  Must not be null.  Will not be called back 
+        /// if there is an error, but instead OnError will be called.</param>
+        /// <param name="state">State information to be passed back to callback</param>
+        public void Configure(IqCB callback, object state)
+        {
+            OwnerPubSubCommandIQ<OwnerConfigure> iq = new OwnerPubSubCommandIQ<OwnerConfigure>(m_stream.Document);
+            iq.To = m_jid;
+            iq.Type = IQType.get;
+            iq.Command.Node = m_node;
+            BeginIQ(iq, OnConfigure, new IQTracker.TrackerData(callback, state, null, null));
+        }
+
+        private void OnConfigure(object sender, IQ iq, object data)
+        {
+            if (iq == null)
+            {
+                if (OnError != null)
+                    OnError(this, new PubSubException(Op.CONFIGURE, "IQ timeout", null));
+                return;
+            }
+
+            if (iq.Type != IQType.result)
+            {
+                string msg = string.Format("Error configuring pubsub node: {0}", iq.Error.Condition);
+                Debug.WriteLine(msg);
+
+                if (OnError != null)
+                    OnError(this, new PubSubException(Op.CONFIGURE, msg, iq));
+                return;
+            }
+            PubSubOwner ow = iq.Query as PubSubOwner;
+            if (ow == null)
+            {
+                if (OnError != null)
+                    OnError(this, new PubSubException(Op.CONFIGURE, "Invalid protocol", iq));
+                return;
+            }
+
+            OwnerConfigure conf = ow.Command as OwnerConfigure;
+            if (conf == null)
+            {
+                if (OnError != null)
+                    OnError(this, new PubSubException(Op.CONFIGURE, "Invalid protocol", iq));
+                return;
+            }
+
+            IQTracker.TrackerData td = data as IQTracker.TrackerData;
+            td.Call(this, iq);
+        }
+
+        #region IEnumerable Members
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return m_items.GetEnumerator();
+        }
+
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/jabber/connection/SocketStanzaStream.cs b/lib/jabber-net/jabber/connection/SocketStanzaStream.cs
new file mode 100644
index 0000000..5e5743d
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/SocketStanzaStream.cs
@@ -0,0 +1,467 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Diagnostics;
+using System.Threading;
+using System.Xml;
+
+using bedrock.net;
+using bedrock.util;
+using jabber.protocol;
+
+namespace jabber.connection
+{
+    /// <summary>
+    /// Contains the types of proxies Jabber-Net supports.  This is only for socket connections.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum ProxyType
+    {
+        /// <summary>
+        /// no proxy
+        /// </summary>
+        None,
+        /// <summary>
+        /// SOCKS4 as in http://archive.socks.permeo.com/protocol/socks4.protocol
+        /// </summary>
+        Socks4,
+        /// <summary>
+        /// SOCKS5 as in http://archive.socks.permeo.com/rfc/rfc1928.txt
+        /// </summary>
+        Socks5,
+        /// <summary>
+        /// HTTP CONNECT
+        /// </summary>
+        HTTP,
+    }
+
+
+    /// <summary>
+    /// "Standard" XMPP socket for outbound connections.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class SocketStanzaStream : StanzaStream, ISocketEventListener
+    {
+        private AsynchElementStream m_elements = null;
+        private BaseSocket          m_sock     = null;
+        private BaseSocket          m_accept   = null;
+        private Timer               m_timer    = null;
+
+        /// <summary>
+        /// Create a new one.
+        /// </summary>
+        /// <param name="listener"></param>
+        internal SocketStanzaStream(IStanzaEventListener listener) : base(listener)
+        {
+            m_timer = new Timer(new TimerCallback(DoKeepAlive), null, Timeout.Infinite, Timeout.Infinite);
+        }
+
+        /// <summary>
+        /// Determines if the socket is connected.
+        /// </summary>
+        public override bool Connected
+        {
+            get { return ASock.Connected;  }
+        }
+
+        /// <summary>
+        /// Determines whether or not Jabber-Net supports StartTLS.
+        /// </summary>
+        public override bool SupportsTLS
+        {
+            get
+            {
+#if NO_SSL
+                return false;
+#else
+                return true;
+#endif
+            }
+        }
+
+        /// <summary>
+        /// Determines whether or not Jabber-Net supports compression.
+        /// </summary>
+        public override bool SupportsCompression
+        {
+            get
+            {
+                try
+                {
+#if ZLIB_NET
+                    return bedrock.io.ZlibStream.Supported;
+#else
+                    return false;
+#endif
+                }
+                catch
+                {
+                    Debug.WriteLine("WARNING: zlib.net.dll missing!");
+                    return false;
+                }
+            }
+        }
+
+        private AsyncSocket ASock
+        {
+            get
+            {
+                if (m_sock is ProxySocket)
+                    return ((ProxySocket)m_sock).Socket as AsyncSocket;
+                else
+                    return m_sock as AsyncSocket;
+            }
+        }
+
+        /// <summary>
+        /// Initializes the element stream.  This is the place to add factories.
+        /// </summary>
+        public override void InitializeStream()
+        {
+            bool first = (m_elements == null);
+            m_elements = new AsynchElementStream();
+            m_elements.OnDocumentStart += new ProtocolHandler(m_elements_OnDocumentStart);
+            m_elements.OnDocumentEnd += new bedrock.ObjectHandler(m_elements_OnDocumentEnd);
+            m_elements.OnElement += new ProtocolHandler(m_elements_OnElement);
+            m_elements.OnError += new bedrock.ExceptionHandler(m_elements_OnError);
+
+            m_listener.StreamInit(m_elements);
+
+            Debug.Assert(this.Connected);
+            if (first)
+                m_sock.RequestRead();
+
+        }
+
+        /// <summary>
+        /// Connects to the XMPP server.
+        /// </summary>
+        public override void Connect()
+        {
+            m_elements = null;
+            int port = (int)m_listener[Options.PORT];
+            Debug.Assert(port > 0);
+            //m_sslOn = m_ssl;
+
+            ProxySocket proxy = null;
+            ProxyType pt = (ProxyType)m_listener[Options.PROXY_TYPE];
+            switch (pt)
+            {
+            case ProxyType.Socks4:
+                proxy = new Socks4Proxy(this);
+                break;
+
+            case ProxyType.Socks5:
+                proxy = new Socks5Proxy(this);
+                break;
+
+            case ProxyType.HTTP:
+                proxy = new ShttpProxy(this);
+                break;
+
+                /*
+            case ProxyType.HTTP_Polling:
+                XEP25Socket j25s = new XEP25Socket(this);
+                if (m_ProxyHost != null)
+                {
+                    System.Net.WebProxy wp = new System.Net.WebProxy();
+                    wp.Address = new Uri("http://" + m_ProxyHost + ":" + m_ProxyPort);
+                    if (m_ProxyUsername != null)
+                    {
+                        wp.Credentials = new System.Net.NetworkCredential(m_ProxyUsername, m_ProxyPassword);
+                    }
+                    j25s.Proxy = wp;
+                }
+                j25s.URL = m_server;
+                m_sock = j25s;
+                break;
+                */
+            case ProxyType.None:
+                m_sock = new AsyncSocket(null, this, (bool)m_listener[Options.SSL], false);
+
+                ((AsyncSocket)m_sock).LocalCertificate = m_listener[Options.LOCAL_CERTIFICATE] as
+                    System.Security.Cryptography.X509Certificates.X509Certificate2;
+
+                ((AsyncSocket)m_sock).CertificateGui = (bool)m_listener[Options.CERTIFICATE_GUI];
+                break;
+
+            default:
+                throw new ArgumentException("no handler for proxy type: " + pt, "ProxyType");
+            }
+
+            if (proxy != null)
+            {
+                proxy.Socket = new AsyncSocket(null, proxy, (bool)m_listener[Options.SSL], false);
+                ((AsyncSocket)proxy.Socket).LocalCertificate = m_listener[Options.LOCAL_CERTIFICATE] as
+                    System.Security.Cryptography.X509Certificates.X509Certificate2;
+
+                proxy.Host = m_listener[Options.PROXY_HOST] as string;
+                proxy.Port = (int)m_listener[Options.PROXY_PORT];
+                proxy.Username = m_listener[Options.PROXY_USER] as string;
+                proxy.Password = m_listener[Options.PROXY_PW] as string;
+                m_sock = proxy;
+            }
+
+            string to = (string)m_listener[Options.TO];
+            Debug.Assert(to != null);
+
+            string host = (string)m_listener[Options.NETWORK_HOST];
+            if ((host == null) || (host == ""))
+            {
+#if __MonoCS__
+                host = to;
+#else
+                try
+                {
+                    Address.LookupSRV((string)m_listener[Options.SRV_PREFIX], to, ref host, ref port);
+                }
+                catch
+                {
+                    Debug.WriteLine("WARNING: netlib.Dns.dll missing");
+                    host = to;
+                }
+#endif
+            }
+
+            Address addr = new Address(host, port);
+            m_sock.Connect(addr, (string)m_listener[Options.SERVER_ID]);
+        }
+
+        /// <summary>
+        /// Listens for an inbound connection.
+        /// </summary>
+        public override void Accept()
+        {
+            if (m_accept == null)
+            {
+                m_accept = new AsyncSocket(null, this, (bool)m_listener[Options.SSL], false);
+                ((AsyncSocket)m_accept).LocalCertificate = m_listener[Options.LOCAL_CERTIFICATE] as
+                    System.Security.Cryptography.X509Certificates.X509Certificate2;
+
+                Address addr = new Address((string)m_listener[Options.NETWORK_HOST],
+                    (int)m_listener[Options.PORT]);
+
+                m_accept.Accept(addr);
+            }
+            m_accept.RequestAccept();
+        }
+
+        /// <summary>
+        /// Determines if the method Accept() can be called now.
+        /// </summary>
+        public override bool Acceptable
+        {
+            get
+            {
+                return (m_accept != null);
+            }
+        }
+
+        /// <summary>
+        /// Writes the given string to the socket after UTF-8 encoding.
+        /// </summary>
+        /// <param name="str">String to write out.</param>
+        public override void Write(string str)
+        {
+            int keep = (int)m_listener[Options.CURRENT_KEEP_ALIVE];
+            if (keep > 0)
+                m_timer.Change(keep, keep);
+            m_sock.Write(ENC.GetBytes(str));
+        }
+
+        /// <summary>
+        /// Writes a stream:stream.
+        /// </summary>
+        /// <param name="stream">Stream containing the stream:stream packet to send.</param>
+        public override void WriteStartTag(jabber.protocol.stream.Stream stream)
+        {
+            Write(stream.StartTag());
+        }
+
+        /// <summary>
+        /// Writes a full stanza.
+        /// </summary>
+        /// <param name="elem">XML stanza to write.</param>
+        public override void Write(XmlElement elem)
+        {
+            if (m_sock is IElementSocket)
+                ((IElementSocket)m_sock).Write(elem);
+            else
+                Write(elem.OuterXml);
+        }
+
+        /// <summary>
+        /// Closes the session with the XMPP server.
+        /// </summary>
+        /// <param name="clean">Sends the close stanza to the XMPP server if true.</param>
+        public override void Close(bool clean)
+        {
+            // Note: socket should still be connected, excepts for races.  Revist.
+            if (clean)
+                Write("</stream:stream>");
+            m_sock.Close();
+        }
+
+        private void DoKeepAlive(object state)
+        {
+            if ((m_sock != null) && this.Connected && ((int)m_listener[Options.CURRENT_KEEP_ALIVE] > 0))
+                m_sock.Write(new byte[] { 32 });
+        }
+
+#if !NO_SSL
+        /// <summary>
+        /// Negotiates Start-TLS with the other endpoint.
+        /// </summary>
+        public override void StartTLS()
+        {
+            m_sock.StartTLS();
+            AsyncSocket s = ASock;
+
+            Debug.Assert(s != null);
+            m_listener[Options.REMOTE_CERTIFICATE] = s.RemoteCertificate;
+        }
+#endif
+
+        /// <summary>
+        /// Starts compressing outgoing traffic for this connection with the XMPP server.
+        /// </summary>
+        public override void StartCompression()
+        {
+            m_sock.StartCompression();
+        }
+
+        #region ElementStream handlers
+        private void m_elements_OnDocumentStart(object sender, XmlElement rp)
+        {
+            m_listener.DocumentStarted(rp);
+        }
+
+        private void m_elements_OnDocumentEnd(object sender)
+        {
+            m_listener.DocumentEnded();
+        }
+
+        private void m_elements_OnElement(object sender, XmlElement rp)
+        {
+            m_listener.StanzaReceived(rp);
+        }
+
+        private void m_elements_OnError(object sender, Exception ex)
+        {
+            // XML parse error.
+            m_timer.Change(Timeout.Infinite, Timeout.Infinite);
+            m_listener.Errored(ex);
+        }
+        #endregion
+
+        #region ISocketEventListener Members
+
+        void ISocketEventListener.OnInit(BaseSocket newSock)
+        {
+        }
+
+        ISocketEventListener ISocketEventListener.GetListener(BaseSocket newSock)
+        {
+            return this;
+        }
+
+        bool ISocketEventListener.OnAccept(BaseSocket newsocket)
+        {
+            m_sock = newsocket;
+            InitializeStream();
+            m_listener.Accepted();
+
+            // Don't accept any more connections until this one closes
+            // yes, it will look like we're still listening until the old sock is free'd by GC.
+            // don't want OnClose() to fire, though, so we can't close the previous sock.
+            return false;
+        }
+
+        void ISocketEventListener.OnConnect(BaseSocket sock)
+        {
+#if !NO_SSL
+            if ((bool)m_listener[Options.SSL])
+            {
+                AsyncSocket s = sock as AsyncSocket;
+                m_listener[Options.REMOTE_CERTIFICATE] = s.RemoteCertificate;
+            }
+#endif
+            m_listener.Connected();
+        }
+
+        void ISocketEventListener.OnClose(BaseSocket sock)
+        {
+            //System.Windows.Forms.Application.DoEvents();
+            //System.Threading.Thread.Sleep(1000);
+            m_listener[Options.REMOTE_CERTIFICATE] = null;
+            //m_elements = null;
+            m_timer.Change(Timeout.Infinite, Timeout.Infinite);
+            m_listener.Closed();
+        }
+
+        void ISocketEventListener.OnError(BaseSocket sock, Exception ex)
+        {
+            m_listener[Options.REMOTE_CERTIFICATE] = null;
+            //m_elements = null;
+            m_timer.Change(Timeout.Infinite, Timeout.Infinite);
+            m_listener.Errored(ex);
+        }
+
+        bool ISocketEventListener.OnRead(BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            int tim = (int)m_listener[Options.KEEP_ALIVE];
+            if (tim > 0)
+                m_timer.Change(tim, tim);
+
+            m_listener.BytesRead(buf, offset, length);
+            try
+            {
+                m_elements.Push(buf, offset, length);
+            }
+            catch (Exception e)
+            {
+                ((ISocketEventListener)this).OnError(sock, e);
+                sock.Close();
+                return false;
+            }
+            return true;
+        }
+
+        void ISocketEventListener.OnWrite(BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            int tim = (int)m_listener[Options.KEEP_ALIVE];
+            if (tim > 0)
+                m_timer.Change(tim, tim);
+
+            m_listener.BytesWritten(buf, offset, length);
+        }
+
+        /// <summary>
+        /// An invalid peer certificate was sent during SSL/TLS neogtiation.
+        /// </summary>
+        /// <param name="sock">The socket that experienced the error</param>
+        /// <param name="certificate">The bad certificate</param>
+        /// <param name="chain">The chain of CAs for the cert</param>
+        /// <param name="sslPolicyErrors">A bitfield for the erorrs in the certificate.</param>
+        /// <returns>True if the cert should be accepted anyway.</returns>
+        bool ISocketEventListener.OnInvalidCertificate(BaseSocket sock,
+            System.Security.Cryptography.X509Certificates.X509Certificate certificate,
+            System.Security.Cryptography.X509Certificates.X509Chain chain,
+            System.Net.Security.SslPolicyErrors sslPolicyErrors)
+        {
+            return m_listener.OnInvalidCertificate(sock, certificate, chain, sslPolicyErrors);
+        }
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/jabber/connection/StanzaStream.cs b/lib/jabber-net/jabber/connection/StanzaStream.cs
new file mode 100644
index 0000000..5b02907
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/StanzaStream.cs
@@ -0,0 +1,296 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Diagnostics;
+using System.Text;
+using System.Xml;
+
+using bedrock.net;
+using bedrock.util;
+using jabber.protocol;
+
+namespace jabber.connection
+{
+    /// <summary>
+    /// Specifies the connection type, such as socket, polling, and so on.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum ConnectionType
+    {
+        /// <summary>
+        /// Uses "Normal" XMPP socket
+        /// </summary>
+        Socket,
+        /// <summary>
+        /// Uses HTTP Polling, as in http://www.xmpp.org/extensions/xep-0025.html
+        /// </summary>
+        HTTP_Polling,
+        /// <summary>
+        /// Uses HTTP Binding, as in http://www.xmpp.org/extensions/xep-0124.html
+        /// </summary>
+        HTTP_Binding
+    }
+
+    /// <summary>
+    /// Listens for stanza and connection events
+    /// </summary>
+    [SVN(@"$Id$")]
+    public interface IStanzaEventListener
+    {
+        /// <summary>
+        /// Gets or sets properties on the listener.
+        /// </summary>
+        /// <param name="prop">Property name.  Look at the Options class for some ideas.</param>
+        /// <returns></returns>
+        object this[string prop]
+        {
+            get;
+            set;
+        }
+
+        /// <summary>
+        /// Notifies the user that one of the properties has changed.
+        /// </summary>
+        event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
+
+        /// <summary>
+        /// Informs the client that the connection to the XMPP server has finished.
+        /// Time to send the stream:stream packet.
+        /// </summary>
+        void Connected();
+
+        /// <summary>
+        /// Informs the client that a new connection from the server has been accepted.
+        /// Wait for a stream:stream.
+        /// </summary>
+        void Accepted();
+
+        /// <summary>
+        /// Informs the client that text was read from the XMPP server.
+        /// Use for debugging only.
+        /// Will NOT be complete nodes at a time.
+        /// </summary>
+        /// <param name="buf">Buffer containing the data read.</param>
+        /// <param name="offset">Where in the buffer the read data begins.</param>
+        /// <param name="len">Length of the data read.</param>
+        void BytesRead(byte[] buf, int offset, int len);
+
+        /// <summary>
+        /// Informs the client that text was written to the server.
+        /// Use for debugging only. Will NOT be complete nodes at a time.
+        /// </summary>
+        /// <param name="buf">Bytes to write out.</param>
+        /// <param name="offset">The index in the buffer to start getting bytes.</param>
+        /// <param name="len">The amount of bytes to write out.</param>
+        void BytesWritten(byte[] buf, int offset, int len);
+
+        /// <summary>
+        /// Informs the client that a new stream was initialized.
+        /// You can add your packet factories to it.
+        /// </summary>
+        /// <param name="stream">The stream that was initialized.</param>
+        void StreamInit(ElementStream stream);
+
+        /// <summary>
+        /// Notifies the client that an error has occurred.
+        /// </summary>
+        /// <param name="e">The exception that caused the error.</param>
+        void Errored(Exception e);
+
+        /// <summary>
+        /// Notifies the client that the session has been closed.
+        /// </summary>
+        void Closed();
+
+        /// <summary>
+        /// Informs the client that a doc start tag has been received.
+        /// This may be "synthetic" for some backends.
+        /// </summary>
+        /// <param name="elem">XML element containing the start tag.</param>
+        void DocumentStarted(XmlElement elem);
+
+        /// <summary>
+        /// Receives the closing stream:stream.  Probably mostly equivalent to Closed(),
+        /// except if the stream is still open, you should close it at this point.
+        /// May not be called for some backends.
+        /// </summary>
+        void DocumentEnded();
+
+        /// <summary>
+        /// Receives an XML element such as stream:features and so on.
+        /// </summary>
+        /// <param name="elem">The XML Element received.</param>
+        void StanzaReceived(XmlElement elem);
+
+        /// <summary>
+        /// An invalid peer certificate was sent during SSL/TLS neogtiation.
+        /// </summary>
+        /// <param name="sock">The socket that experienced the error</param>
+        /// <param name="certificate">The bad certificate</param>
+        /// <param name="chain">The chain of CAs for the cert</param>
+        /// <param name="sslPolicyErrors">A bitfield for the erorrs in the certificate.</param>
+        /// <returns>True if the cert should be accepted anyway.</returns>
+        bool OnInvalidCertificate(BaseSocket sock,
+            System.Security.Cryptography.X509Certificates.X509Certificate certificate,
+            System.Security.Cryptography.X509Certificates.X509Chain chain,
+            System.Net.Security.SslPolicyErrors sslPolicyErrors);
+    }
+
+    /// <summary>
+    /// Manages the base stream for reading and writing full stanzas.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public abstract class StanzaStream
+    {
+        /// <summary>
+        /// Text encoding.  Always UTF-8 for XMPP.
+        /// </summary>
+        protected readonly Encoding ENC = Encoding.UTF8;
+
+        /// <summary>
+        /// Notifies the client that an event has occurred.
+        /// </summary>
+        protected IStanzaEventListener m_listener = null;
+
+        /// <summary>
+        /// Creates a StanzaStream.
+        /// </summary>
+        /// <param name="kind">Connection type, such as socket, polling, and so on.</param>
+        /// <param name="listener">Connection event listeners.</param>
+        /// <returns>StanzaStream used to connect to an XMPP server and send stanzas.</returns>
+        public static StanzaStream Create(ConnectionType kind, IStanzaEventListener listener)
+        {
+            switch (kind)
+            {
+            case ConnectionType.Socket:
+                return new SocketStanzaStream(listener);
+            case ConnectionType.HTTP_Polling:
+                return new PollingStanzaStream(listener);
+            case ConnectionType.HTTP_Binding:
+                return new BindingStanzaStream(listener);
+            default:
+                throw new NotImplementedException("Proxy type not implemented yet: " + kind.ToString());
+            }
+        }
+
+        /// <summary>
+        /// Creates a new stanza stream.
+        /// </summary>
+        /// <param name="listener">Event listener associated with the new stanza stream.</param>
+        protected StanzaStream(IStanzaEventListener listener)
+        {
+            Debug.Assert(listener != null);
+            m_listener = listener;
+        }
+
+        /// <summary>
+        /// Starts the outbound connection to the XMPP server.
+        /// </summary>
+        abstract public void Connect();
+
+        /// <summary>
+        /// Listens for an inbound connection.  Only implemented by socket types for now.
+        /// </summary>
+        virtual public void Accept()
+        {
+            throw new NotImplementedException("Accept not implemented on this stream type");
+        }
+
+        /// <summary>
+        /// Determines whether or not the client can call the Accept() method.
+        /// </summary>
+        virtual public bool Acceptable
+        {
+            get { return false; }
+        }
+
+        /// <summary>
+        /// Starts the TLS handshake.
+        /// </summary>
+        virtual public void StartTLS()
+        {
+            throw new NotImplementedException("Start-TLS not implemented on this stream type");
+        }
+
+        /// <summary>
+        /// Starts the compression on the connection.
+        /// </summary>
+        virtual public void StartCompression()
+        {
+            throw new NotImplementedException("Start-TLS not implemented on this stream type");
+        }
+
+        /// <summary>
+        /// Initializes a new stream:stream.
+        /// </summary>
+        virtual public void InitializeStream()
+        {
+        }
+
+        /// <summary>
+        /// Writes a stream:stream start tag.
+        /// Some underlying implementations will ignore this,
+        /// but may pull out pertinent data.
+        /// </summary>
+        /// <param name="stream">Stream containing the start tag.</param>
+        abstract public void WriteStartTag(jabber.protocol.stream.Stream stream);
+
+        /// <summary>
+        /// Writes an entire XML element.
+        /// </summary>
+        /// <param name="elem">XML element to write out.</param>
+        abstract public void Write(XmlElement elem);
+
+        /// <summary>
+        /// Writes a raw string.
+        /// </summary>
+        /// <param name="str">String to write out.</param>
+        abstract public void Write(string str);
+
+        /// <summary>
+        /// Closes the session with the XMPP server.
+        /// </summary>
+        /// <param name="clean">If true, send the stream:stream close packet.</param>
+        abstract public void Close(bool clean);
+
+        /// <summary>
+        /// Determines whether or not the client is connected to the XMPP server.
+        /// </summary>
+        abstract public bool Connected
+        {
+            get;
+        }
+
+        /// <summary>
+        /// Determines whether or not Jabber-Net supports TLS.
+        /// </summary>
+        virtual public bool SupportsTLS
+        {
+            get { return false; }
+        }
+
+        /// <summary>
+        /// Determines whether or not this stream supports compression (XEP-0138).
+        /// </summary>
+        virtual public bool SupportsCompression
+        {
+            get { return false; }
+        }
+    }
+
+    /// <summary>
+    /// Informs the client that something happened on a StanzaStream.
+    /// </summary>
+    public delegate void StanzaStreamHandler(object sender, StanzaStream stream);
+}
diff --git a/lib/jabber-net/jabber/connection/States.cs b/lib/jabber-net/jabber/connection/States.cs
new file mode 100644
index 0000000..711e351
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/States.cs
@@ -0,0 +1,216 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using bedrock.util;
+
+namespace jabber.connection
+{
+    /// <summary>
+    /// Represents the base class for all states.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public abstract class BaseState
+    {
+    }
+
+    /// <summary>
+    /// Specifies the state is up and running.  If subclasses change the
+    /// state transition approach, they should end at the RunningState state.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class RunningState : BaseState
+    {
+        /// <summary>
+        /// Returns the instance of the running state.
+        /// </summary>
+        public static readonly BaseState Instance = new RunningState();
+    }
+
+    /// <summary>
+    /// Specifies the state is not connected.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ClosedState : BaseState
+    {
+        /// <summary>
+        /// Returns the instance of the closed state.
+        /// </summary>
+        public static readonly BaseState Instance = new ClosedState();
+    }
+
+    /// <summary>
+    /// Specifies the state is in the process of connecting such as
+    /// DNS lookup, socket setup, and so on.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ConnectingState : BaseState
+    {
+        /// <summary>
+        /// Returns the instance of the connecting state.
+        /// </summary>
+        public static readonly BaseState Instance = new ConnectingState();
+    }
+
+    /// <summary>
+    /// Specifies the state is in the "connected socket" state.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ConnectedState : BaseState
+    {
+        /// <summary>
+        /// The instance that is always used.
+        /// </summary>
+        public static readonly BaseState Instance = new ConnectedState();
+    }
+
+    /// <summary>
+    /// Specifies the state is in the "stream:stream has been received" state.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class StreamState : BaseState
+    {
+        /// <summary>
+        /// Returns the instance of the XMPP stream state.
+        /// </summary>
+        public static readonly BaseState Instance = new StreamState();
+    }
+
+    /// <summary>
+    /// Specifies the state is in a closing state.
+    /// A close was requested, but hasn't yet finalized.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ClosingState : BaseState
+    {
+        /// <summary>
+        /// Returns the instance for the closing state.
+        /// </summary>
+        public static readonly BaseState Instance = new ClosingState();
+    }
+
+    /// <summary>
+    /// Specifies the state is in a paused state waiting for reconnect timeout.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ReconnectingState : BaseState
+    {
+        /// <summary>
+        /// Returns the instance of the reconnecting state.
+        /// </summary>
+        public static readonly BaseState Instance = new ReconnectingState();
+    }
+
+    /// <summary>
+    /// Specifies the state is in the "Accepting incoming socket connections" state.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class AcceptingState : BaseState
+    {
+        /// <summary>
+        /// Returns the instance of the accepting state.
+        /// </summary>
+        public static readonly BaseState Instance = new AcceptingState();
+    }
+    /// <summary>
+    /// Specifies the state is in Old-style auth, iq:auth or handshake.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class NonSASLAuthState : BaseState
+    {
+        /// <summary>
+        /// Returns the instance of the non SASL authentication state.
+        /// </summary>
+        public static readonly BaseState Instance = new NonSASLAuthState();
+    }
+    /// <summary>
+    /// Specifies the state is in waiting for the server to send the features element.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ServerFeaturesState : BaseState
+    {
+        /// <summary>
+        /// Returns the instance of the server features state.
+        /// </summary>
+        public static readonly BaseState Instance = new ServerFeaturesState();
+    }
+    /// <summary>
+    /// Specifies the state is in Start-TLS.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class StartTLSState : BaseState
+    {
+        /// <summary>
+        /// Returns the instance of the Start-TLS state.
+        /// </summary>
+        public static readonly BaseState Instance = new StartTLSState();
+    }
+    /// <summary>
+    /// Specifies the state is in the compression state.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class CompressionState : BaseState
+    {
+        /// <summary>
+        /// The instance that is always used.
+        /// </summary>
+        public static readonly BaseState Instance = new CompressionState();
+    }
+    /// <summary>
+    /// Specifies the state is in SASL Authentication.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class SASLState : BaseState
+    {
+        /// <summary>
+        /// Returns the instance of the SASL state.
+        /// </summary>
+        public static readonly BaseState Instance = new SASLState();
+    }
+    /// <summary>
+    /// Specifies the state is in the SASL Authentication has finished state.
+    /// Restarting the stream for the last time.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class SASLAuthedState : BaseState
+    {
+        /// <summary>
+        /// Returns the instance for the SASL authentication state.
+        /// </summary>
+        public static readonly BaseState Instance = new SASLAuthedState();
+    }
+    /// <summary>
+    /// SASL Authentication failed.  On some servers you can re-try, or register.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class SASLFailedState : BaseState
+    {
+        /// <summary>
+        /// The instance that is always used.
+        /// </summary>
+        public static readonly BaseState Instance = new SASLFailedState();
+    }
+    /// <summary>
+    /// Specifies the state is in the "Binding session" state.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class BindState : BaseState
+    {
+        /// <summary>
+        /// Returns the instance for the Bind state.
+        /// </summary>
+        public static readonly BaseState Instance = new BindState();
+    }
+
+}
diff --git a/lib/jabber-net/jabber/connection/StreamComponent.cs b/lib/jabber-net/jabber/connection/StreamComponent.cs
new file mode 100644
index 0000000..194aa6e
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/StreamComponent.cs
@@ -0,0 +1,149 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Xml;
+
+using bedrock.util;
+using System.Diagnostics;
+using jabber.protocol.client;
+
+namespace jabber.connection
+{
+    /// <summary>
+    /// Manages the XmppStream as a component.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public abstract class StreamComponent : System.ComponentModel.Component
+    {
+        /// <summary>
+        /// Finds the first component that subclasses XmppStream in Visual Studio
+        /// during runtime.
+        /// </summary>
+        /// <param name="host">
+        /// Calls GetService(typeof(IDesignerHost)) on your control to get this.
+        /// </param>
+        /// <returns>Null if none found</returns>
+        public static XmppStream GetStreamFromHost(IDesignerHost host)
+        {
+            return (XmppStream)GetComponentFromHost(host, typeof(XmppStream));
+        }
+
+        /// <summary>
+        /// Finds the first component that subclasses the given type at runtime.
+        /// </summary>
+        /// <param name="host">Call GetService(typeof(IDesignerHost)) on your control to get this.</param>
+        /// <param name="type">The type to search for.</param>
+        /// <returns>Null if none found</returns>
+        public static Component GetComponentFromHost(IDesignerHost host, Type type)
+        {
+            if (host == null)
+                return null;
+            Debug.Assert(type != null);
+            Component root = host.RootComponent as Component;
+            if (root == null)
+                return null;
+
+            foreach (Component c in root.Container.Components)
+            {
+                if (type.IsAssignableFrom(c.GetType()))
+                    return c;
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// Retrieves the XmppStream for this control.
+        /// Set at design time when a subclass control is dragged onto a form.
+        /// </summary>
+        protected XmppStream m_stream = null;
+
+        /// <summary>
+        /// Informs the client that the XmppStream was changed.
+        /// Often at design time, the object will be this StreamComponent.
+        /// </summary>
+        public event bedrock.ObjectHandler OnStreamChanged;
+
+        /// <summary>
+        /// Gets and sets the JabberClient or JabberService XMPP stream value.
+        /// </summary>
+        [Description("The JabberClient or JabberService to hook up to.")]
+        [Category("Jabber")]
+        public virtual XmppStream Stream
+        {
+            get
+            {
+                // If we are running in the designer, let's try to get an XmppStream control
+                // from the environment.
+                if ((this.m_stream == null) && DesignMode)
+                {
+                    IDesignerHost host = (IDesignerHost)base.GetService(typeof(IDesignerHost));
+                    this.Stream = GetStreamFromHost(host);
+                }
+                return m_stream;
+            }
+            set
+            {
+                if ((object)m_stream != (object)value)
+                {
+                    m_stream = value;
+                    if (OnStreamChanged != null)
+                        OnStreamChanged(this);
+                }
+            }
+        }
+
+        private JID m_overrideFrom = null;
+
+        /// <summary>
+        /// Override the from address that will be stamped on outbound packets.
+        /// Unless your server implemets XEP-193, you shouldn't use this for 
+        /// client connections.
+        /// </summary>
+        public JID OverrideFrom
+        {
+            get { return m_overrideFrom; }
+            set { m_overrideFrom = value; }
+        }
+
+        /// <summary>
+        /// Write the specified stanza to the stream.
+        /// If the from address hasn't been set, and an OverrideFrom has been set,
+        /// the from address will be set to the value of OverrideFrom.
+        /// </summary>
+        /// <param name="elem"></param>
+        public void Write(XmlElement elem)
+        {
+            if ((m_overrideFrom != null) && (elem.GetAttribute("from") == ""))
+                elem.SetAttribute("from", m_overrideFrom);
+            m_stream.Write(elem);
+        }
+
+        ///<summary>
+        /// Does an asynchronous IQ call.
+        /// If the from address hasn't been set, and an OverrideFrom has been set,
+        /// the from address will be set to the value of OverrideFrom.
+        ///</summary>
+        ///<param name="iq">IQ packet to send.</param>
+        ///<param name="cb">Callback to execute when the result comes back.</param>
+        ///<param name="cbArg">Arguments to pass to the callback.</param>
+        public void BeginIQ(IQ iq, IqCB cb, object cbArg)
+        {
+            if ((m_overrideFrom != null) && (iq.From == null))
+                iq.From = m_overrideFrom;
+            m_stream.Tracker.BeginIQ(iq, cb, cbArg);
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/connection/XmppStream.cs b/lib/jabber-net/jabber/connection/XmppStream.cs
new file mode 100644
index 0000000..5159d19
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/XmppStream.cs
@@ -0,0 +1,1774 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Diagnostics;
+using System.IO;
+using System.Threading;
+using System.Security.Cryptography;
+using System.Xml;
+using bedrock.util;
+
+using jabber.protocol;
+using jabber.protocol.stream;
+using jabber.connection.sasl;
+
+using System.Security.Cryptography.X509Certificates;
+
+namespace jabber.connection
+{
+    /// <summary>
+    /// Informs the client about events that happen on an ElementStream.
+    /// </summary>
+    public delegate void StreamHandler(Object sender, ElementStream stream);
+
+    /// <summary>
+    /// Manages option names.  These must be well-formed XML element names.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public abstract class Options
+    {
+        /// <summary>
+        /// Contains the default namespace for this connection.
+        /// </summary>
+        public const string NAMESPACE = "namespace";
+
+        /// <summary>
+        /// Contains the network hostname or IP address of the XMPP server to connect to.
+        /// </summary>
+        public const string NETWORK_HOST = "network_host";
+        /// <summary>
+        /// Contains the identity of the item that the client is connecting to.
+        /// For components, the component ID.
+        /// </summary>
+        public const string TO = "to";
+        /// <summary>
+        /// Contains the server identity that is expected on the X.509 certificate
+        /// from the XMPP server.
+        /// </summary>
+        public const string SERVER_ID    = "tls.cn";
+        /// <summary>
+        /// Determines the keep-alive interval in seconds.
+        /// </summary>
+        public const string KEEP_ALIVE   = "keep_alive";
+        /// <summary>
+        /// Don't start keep-alives until we're fully authenticated.  This is what the SocketStanzaStream actually checks.
+        /// </summary>
+        public const string CURRENT_KEEP_ALIVE = "current_keep_alive";
+        /// <summary>
+        /// Contains the port number to connect to or to listen on.
+        /// </summary>
+        public const string PORT         = "port";
+        /// <summary>
+        /// Uses SSL on connection if set to true.
+        /// </summary>
+        public const string SSL          = "ssl";
+        /// <summary>
+        /// Uses Start-TLS on connection if set to true and
+        /// the server supports it.
+        /// </summary>
+        public const string AUTO_TLS     = "tls.auto";
+        /// <summary>
+        /// Starts the XMPP stream compression (XEP-138) on connection
+        /// if set to true.
+        /// </summary>
+        public const string AUTO_COMPRESS = "compress.auto";
+        /// <summary>
+        /// Allows plaintext authentication for connecting to the XMPP server.
+        /// </summary>
+        public const string PLAINTEXT    = "plaintext";
+        /// <summary>
+        /// Attempts a SASL connection if set to true and the feature is available
+        /// from the XMPP server. If the server doesn't support SASL, the connection
+        /// will move to a fallback mechanism.
+        /// </summary>
+        public const string SASL = "sasl";
+        /// <summary>
+        /// Requires SASL authentication on this connection if set to true.
+        /// There is no fallback mechanism. If the server doesn't support SASL,
+        /// the connection attempt will fail.
+        /// </summary>
+        public const string REQUIRE_SASL = "sasl.require";
+        /// <summary>
+        /// Contains the list of SASL Mechanisms such as Digest-MD5, Plain and so on.
+        /// </summary>
+        public const string SASL_MECHANISMS = "sasl.mechanisms";
+
+        /// <summary>
+        /// Contains the username to connect as.
+        /// </summary>
+        public const string USER     = "user";
+        /// <summary>
+        /// Contains the password for the user, or secret for the component.
+        /// </summary>
+        public const string PASSWORD = "password";
+        /// <summary>
+        /// Contains the connecting resource which is used to identify a unique connection.
+        /// </summary>
+        public const string RESOURCE = "resource";
+        /// <summary>
+        /// Contains the presence default priority for this connection.
+        /// </summary>
+        public const string PRIORITY = "priority";
+        /// <summary>
+        /// Contains the DNS Service/Protocol to prepend to domain.
+        /// Example: _xmpp-client._tcp.
+        /// </summary>
+        public const string SRV_PREFIX = "srv.prefix";
+        /// <summary>
+        /// Allows auto-login to be used for the connection to the XMPP server
+        /// if set to true.
+        /// </summary>
+        public const string AUTO_LOGIN    = "auto.login";
+        /// <summary>
+        /// This pass through the login process, can we login?
+        /// This option is set/reset by the framework.
+        /// </summary>
+        public const string AUTO_LOGIN_THISPASS = "auto.login.thispass";
+        /// <summary>
+        /// Retrieves the roster items from the XMPP server on
+        /// connection if set to true.
+        /// </summary>
+        public const string AUTO_ROSTER   = "auto.roster";
+        /// <summary>
+        /// Sends back 501/feature-not-implemented to the XMPP server if
+        /// there are IQs that have not been handled if set to true.
+        /// </summary>
+        public const string AUTO_IQ_ERRORS   = "auto.iq_errors";
+        /// <summary>
+        /// Sends the presence on connection if set to true.
+        /// </summary>
+        public const string AUTO_PRESENCE = "auto.presence";
+
+        /// <summary>
+        /// Contains the certificate for our side of the SSL/TLS negotiation.
+        /// </summary>
+        public const string LOCAL_CERTIFICATE   = "certificate.local";
+        /// <summary>
+        /// Contains the remote certificate that the XMPP server sent to the client.
+        /// </summary>
+        public const string REMOTE_CERTIFICATE  = "certificate.remote";
+        /// <summary>
+        /// Uses x509 selection dialog box when a certificate is requested
+        /// if set to true.
+        /// </summary>
+        public const string CERTIFICATE_GUI = "certificate.gui";
+        /// <summary>
+        /// Contains the number of seconds to wait before attempting a reconnect.
+        /// </summary>
+        public const string RECONNECT_TIMEOUT   = "reconnect_timeout";
+        /// <summary>
+        /// Determines the connection type (sockets, HTTP polling, or HTTP binding).
+        /// </summary>
+        public const string CONNECTION_TYPE     = "connection";
+        /// <summary>
+        /// Contains the URL to poll on, or bind to.
+        /// </summary>
+        public const string POLL_URL            = "poll.url";
+        /// <summary>
+        /// Connects to the XMPP server or listen for connections.
+        /// </summary>
+        public const string COMPONENT_DIRECTION = "component.dir";
+        /// <summary>
+        /// Contains the logical JID associated with this connection.
+        /// </summary>
+        public const string JID = "jid";
+
+        /// <summary>
+        /// Contains the proxy type, such as none, SOCKS5 and so on.
+        /// </summary>
+        public const string PROXY_TYPE = "proxy.type";
+        /// <summary>
+        /// Contains the hostname or IP address of the proxy.
+        /// </summary>
+        public const string PROXY_HOST = "proxy.host";
+        /// <summary>
+        /// Contains the port number for the proxy.
+        /// </summary>
+        public const string PROXY_PORT = "proxy.port";
+        /// <summary>
+        /// Contains the username for the proxy server.
+        /// </summary>
+        public const string PROXY_USER = "proxy.user";
+        /// <summary>
+        /// Contains the password for the proxy server.
+        /// </summary>
+        public const string PROXY_PW   = "proxy.password";
+        /// <summary>
+        /// Override the from address, in a component/service connection.
+        /// </summary>
+        public const string OVERRIDE_FROM = "override_from";
+    }
+
+    /// <summary>
+    /// Manages the XMPP stream of the connection.
+    /// </summary>
+    [SVN(@"$Id$")]
+    abstract public class XmppStream :
+        System.ComponentModel.Component,
+        IStanzaEventListener
+    {
+        private static readonly object[][] DEFAULTS = new object[][] {
+            new object[] {Options.TO, "jabber.com"},
+            new object[] {Options.KEEP_ALIVE, 30000},
+            new object[] {Options.CURRENT_KEEP_ALIVE, -1},
+            new object[] {Options.PORT, 5222},
+            new object[] {Options.RECONNECT_TIMEOUT, 30000},
+            new object[] {Options.PROXY_PORT, 1080},
+            new object[] {Options.SSL, false},
+            new object[] {Options.SASL, true},
+            new object[] {Options.REQUIRE_SASL, false},
+            new object[] {Options.PLAINTEXT, false},
+            new object[] {Options.AUTO_TLS, true},
+            new object[] {Options.AUTO_COMPRESS, true},
+
+#if __MonoCS__
+            new object[] {Options.CERTIFICATE_GUI, false},
+#else
+            new object[] {Options.CERTIFICATE_GUI, true},
+#endif
+            new object[] {Options.PROXY_TYPE, ProxyType.None},
+            new object[] {Options.CONNECTION_TYPE, ConnectionType.Socket},
+        };
+
+        /// <summary>
+        /// Contains the character encoding for the XMPP stream.
+        /// Currently, it is set to UTF-8.
+        /// </summary>
+        protected static readonly System.Text.Encoding ENC = System.Text.Encoding.UTF8;
+
+        private StanzaStream m_stanzas = null;
+        private IQTracker m_tracker = null;
+
+        private XmlDocument m_doc        = new XmlDocument();
+        private BaseState   m_state      = ClosedState.Instance;
+        private IDictionary m_properties = new Hashtable();
+
+        private string m_streamID = null;
+        private object m_stateLock = new object();
+        private ArrayList m_callbacks = new ArrayList();
+
+        private Timer m_reconnectTimer = null;
+        private bool m_reconnect = false;
+        private bool m_sslOn = false;
+        private bool m_compressionOn = false;
+
+        private XmlNamespaceManager m_ns;
+        private ISynchronizeInvoke m_invoker = null;
+
+        // XMPP v1 stuff
+        private string m_serverVersion = null;
+        private SASLProcessor m_saslProc = null;
+        private Features m_features = null; // the last features tag received.
+
+
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+#pragma warning disable 0414
+        private System.ComponentModel.Container components = new System.ComponentModel.Container();
+#pragma warning restore 0414
+        
+        /// <summary>
+        /// Creates a new XMPP stream and associates it with the parent control.
+        /// </summary>
+        /// <param name="container">Parent control.</param>
+        public XmppStream(System.ComponentModel.IContainer container) : this()
+        {
+            container.Add(this);
+        }
+
+        /// <summary>
+        /// Sets defaults in bulk.
+        /// </summary>
+        /// <param name="defaults">Array of objects to replace to defaults with.</param>
+        protected void SetDefaults(object[][] defaults)
+        {
+            foreach (object[] def in defaults)
+            {
+                this[(string)def[0]] = def[1];
+            }
+        }
+
+        /// <summary>
+        /// Creates a new SocketElementStream.
+        /// </summary>
+        public XmppStream()
+        {
+            m_ns = new XmlNamespaceManager(m_doc.NameTable);
+            m_tracker = new IQTracker(this);
+
+            SetDefaults(DEFAULTS);
+        }
+
+        /// <summary>
+        /// Sets or retrieves a connection property.
+        /// You have to know the type of the property based on the name.
+        /// For example, PORT is an integer.
+        /// </summary>
+        /// <param name="prop">The property to get or set.</param>
+        /// <returns></returns>
+        public object this[string prop]
+        {
+            get
+            {
+                if (!m_properties.Contains(prop))
+                    return null;
+                return m_properties[prop];
+            }
+            set
+            {
+                m_properties[prop] = value;
+                if (PropertyChanged != null)
+                {
+                    PropertyChanged(this, new PropertyChangedEventArgs(prop));
+                }
+            }
+        }
+
+        /// <summary>
+        /// Informs the client that a property changed on the instance.
+        /// </summary>
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        /*
+        /// <summary>
+        /// Create a SocketElementStream out of an accepted socket.
+        /// </summary>
+        /// <param name="aso"></param>
+        public XmppStream(BaseSocket aso)
+        {
+            m_accept = m_sock = null;
+            if (aso is AsyncSocket)
+            {
+                m_watcher = ((AsyncSocket)aso).SocketWatcher;
+            }
+            m_ns = new XmlNamespaceManager(m_doc.NameTable);
+            m_timer = new Timer(new TimerCallback(DoKeepAlive), null, Timeout.Infinite, Timeout.Infinite);
+            InitializeStream();
+            m_state = jabber.connection.AcceptingState.Instance;
+        }
+
+        /// <summary>
+        /// Create a SocketElementStream with an existing SocketWatcher, so that you can do
+        /// lots of concurrent connections.
+        /// </summary>
+        /// <param name="watcher"></param>
+        public XmppStream(SocketWatcher watcher)
+        {
+            m_watcher = watcher;
+            m_ns = new XmlNamespaceManager(m_doc.NameTable);
+            m_timer = new Timer(new TimerCallback(DoKeepAlive), null, Timeout.Infinite, Timeout.Infinite);
+        }
+        */
+
+        /// <summary>
+        /// Informs the client when text has been written to the XMPP server.
+        /// Use for debugging only.
+        /// Will NOT be complete nodes at a time.
+        /// </summary>
+        [Category("Debug")]
+        public event bedrock.TextHandler OnWriteText;
+
+        /// <summary>
+        /// Informs the client that text was read from the server.
+        /// Use for debugging only. Will NOT be complete nodes at a time.
+        /// </summary>
+        [Category("Debug")]
+        public event bedrock.TextHandler OnReadText;
+
+        /// <summary>
+        /// Informs the client that a new stream has been inialized.
+        /// You can add your packet factories to the new stream.
+        /// NOTE: You may NOT make calls to the GUI in this callback, unless you
+        /// call Invoke.  Make sure you add your packet factories before
+        /// calling Invoke, however.
+        /// </summary>
+        [Category("Stream")]
+        public event StreamHandler OnStreamInit;
+
+        /// <summary>
+        /// Informs the client that an error occurred when processing.
+        /// The connection has been closed.
+        /// </summary>
+        [Category("Stream")]
+        public event bedrock.ExceptionHandler OnError;
+
+        /// <summary>
+        /// Notifies the client about every jabber packet.
+        /// This is a union of the OnPresence, OnMessage, and OnIQ methods.
+        /// Use this *or* the other 3 methods, but not both, as a matter of style.
+        /// </summary>
+        [Category("Stream")]
+        public event ProtocolHandler OnProtocol;
+
+        /// <summary>
+        /// Notifies the client that the stream header, as a packet,
+        /// has been received.  Can be called multiple  times for
+        /// a single session, with XMPP.
+        /// </summary>
+        [Category("Stream")]
+        public event ProtocolHandler OnStreamHeader;
+
+        /// <summary>
+        /// Notifies the client that the SASL handshake has started.
+        /// </summary>
+        protected event SASLProcessorHandler OnSASLStart;
+
+        /// <summary>
+        /// Gets notified of the end of a SASL handshake.
+        /// </summary>
+        protected event FeaturesHandler OnSASLEnd;
+
+        /// <summary>
+        /// Gets notified when SASL login fails.
+        /// </summary>
+        protected event ProtocolHandler OnSASLError;
+
+        /// <summary>
+        /// Informs the client that it received a stream:error packet.
+        /// </summary>
+        [Category("Stream")]
+        [Description("We received stream:error packet.")]
+        public event ProtocolHandler OnStreamError;
+
+        /// <summary>
+        /// Informs the client that the connection is complete and the user is authenticated.
+        /// </summary>
+        [Category("Stream")]
+        public event bedrock.ObjectHandler OnAuthenticate;
+
+        /// <summary>
+        /// Informs the client that the connection is connected,
+        /// but no stream:stream has been sent yet.
+        /// </summary>
+        [Category("Stream")]
+        public event StanzaStreamHandler OnConnect;
+
+        /// <summary>
+        /// Informs the client that the connection is disconnected.
+        /// </summary>
+        [Category("Stream")]
+        public event bedrock.ObjectHandler OnDisconnect;
+
+        /// <summary>
+        /// An invalid cert was received from the other side.  Set this event and return true to
+        /// use the cert anyway.  If the event is not set, an ugly user interface will be displayed.
+        /// </summary>
+        [Category("Stream")]
+        public event System.Net.Security.RemoteCertificateValidationCallback OnInvalidCertificate;
+
+        /// <summary>
+        /// Gets the tracker for sending IQ packets.
+        /// </summary>
+        [Browsable(false)]
+        public IIQTracker Tracker
+        {
+            get { return m_tracker; }
+        }
+
+        /// <summary>
+        /// Gets or sets the name of the XMPP server to connect to.
+        /// </summary>
+        [Description("Gets or sets the name of the XMPP server to connect to.")]
+        [DefaultValue("jabber.com")]
+        [Category("Jabber")]
+        public virtual string Server
+        {
+            get { return this[Options.TO] as string; }
+            set { this[Options.TO] = value; }
+        }
+
+        /// <summary>
+        /// Gets or sets the network host address to use on the "to" attribute
+        /// of the stream:stream. You can put the network hostname or IP address
+        /// of the XMPP server to connect to. If none is specified, the Server will
+        /// be used. Eventually, when SRV is supported, this will be deprecated.
+        /// </summary>
+        [Description("")]
+        [DefaultValue(null)]
+        [Category("Jabber")]
+        public string NetworkHost
+        {
+            get { return this[Options.NETWORK_HOST] as string; }
+            set { this[Options.NETWORK_HOST] = value; }
+        }
+
+        /// <summary>
+        /// Specifies the TCP port to connect to.
+        /// </summary>
+        [Description("Specifies the TCP port to connect to.")]
+        [DefaultValue(5222)]
+        [Category("Jabber")]
+        public int Port
+        {
+            get { return (int)this[Options.PORT]; }
+            set { this[Options.PORT] = value; }
+        }
+
+        /// <summary>
+        /// Specifies whether plaintext authentication is used for connecting
+        /// to the XMPP server.
+        /// </summary>
+        [Description("Allow plaintext authentication?")]
+        [DefaultValue(false)]
+        [Category("Jabber")]
+        public bool PlaintextAuth
+        {
+            get { return (bool)this[Options.PLAINTEXT]; }
+            set { this[Options.PLAINTEXT] = value; }
+        }
+
+        /// <summary>
+        /// Determines whether or not the current connection is secured with SSL/TLS.
+        /// </summary>
+        [Browsable(false)]
+        public bool SSLon
+        {
+            get { return m_sslOn; }
+        }
+
+        /// <summary>
+        /// Gets the JID from the connection.
+        /// </summary>
+        [Browsable(false)]
+        public JID JID
+        {
+            // Make sure to set this option in subclasses.
+            get
+            {
+                object j = this[Options.JID];
+                if (j == null)
+                    return null;
+                if (j is JID)
+                    return (JID)j;
+                if (j is string)
+                    return new JID((string)j);
+                Debug.Assert(false, "Unknown JID type", j.GetType().ToString());
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// Determines whether or not the current connection uses
+        /// XMPP stream compression (XEP-138).
+        /// </summary>
+        [Browsable(false)]
+        public bool CompressionOn
+        {
+            get { return m_compressionOn; }
+        }
+
+        /// <summary>
+        /// Determines whether SSL3/TLS1 authentication is used when a user
+        /// connects to the XMPP server.
+        /// </summary>
+        [Description("Do SSL3/TLS1 on startup.")]
+        [DefaultValue(false)]
+        [Category("Jabber")]
+        public bool SSL
+        {
+            get { return (bool)this[Options.SSL]; }
+            set { this[Options.SSL] = value; }
+        }
+
+        /// <summary>
+        /// Allows Start-TLS on connection if the server supports it and if set to true.
+        /// </summary>
+        [Browsable(false)]
+        public bool AutoStartTLS
+        {
+            get { return (bool)this[Options.AUTO_TLS]; }
+            set { this[Options.AUTO_TLS] = value; }
+        }
+
+        /// <summary>
+        /// Allows start compression on connection if the server supports it and
+        /// is set to true.
+        /// </summary>
+        [Browsable(false)]
+        public bool AutoStartCompression
+        {
+            get { return (bool)this[Options.AUTO_COMPRESS]; }
+            set { this[Options.AUTO_COMPRESS] = value; }
+        }
+
+        /// <summary>
+        /// Gets or sets the certificate to be used for the local
+        /// side of sockets when SSL is enabled.
+        /// </summary>
+        [Browsable(false)]
+        public X509Certificate LocalCertificate
+        {
+            get { return this[Options.LOCAL_CERTIFICATE] as X509Certificate; }
+            set { this[Options.LOCAL_CERTIFICATE] = value; }
+        }
+
+        /// <summary>
+        /// Sets the certificate to be used for accept sockets.  To
+        /// generate a test .pfx file using OpenSSL, add this to
+        /// openssl.conf:
+        ///   <blockquote>
+        ///   [ serverex ]
+        ///   extendedKeyUsage=1.3.6.1.5.5.7.3.1
+        ///   </blockquote>
+        /// and run the following commands:
+        ///   <blockquote>
+        ///   openssl req -new -x509 -newkey rsa:1024 -keyout
+        ///     privkey.pem -out key.pem -extensions serverex
+        ///   openssl pkcs12 -export -in key.pem -inkey privkey.pem
+        ///     -name localhost -out localhost.pfx
+        ///   </blockquote>
+        /// If you leave the certificate null, and you are doing
+        /// Accept, the SSL class will try to find a default server
+        /// certificate on your box.
+        /// </summary>
+        /// <param name="filename">A .pfx or .cer file.</param>
+        /// <param name="password">The password, if this is a .pfx
+        /// file, null if .cer file.</param>
+        public void SetCertificateFile(string filename,
+                                       string password)
+        {
+            this[Options.LOCAL_CERTIFICATE] = new X509Certificate2(filename, password);
+        }
+
+        /// <summary>
+        /// Calls Invoke() for all callbacks on this control.
+        /// </summary>
+        [Description("Invoke all callbacks on this control")]
+        [DefaultValue(null)]
+        [Category("Jabber")]
+        public ISynchronizeInvoke InvokeControl
+        {
+            get
+            {
+                // If we are running in the designer, let's try to get
+                // an invoke control from the environment.  VB
+                // programmers can't seem to follow directions.
+                if ((this.m_invoker == null) && DesignMode)
+                {
+                    IDesignerHost host = (IDesignerHost)base.GetService(typeof(IDesignerHost));
+                    if (host != null)
+                    {
+                        object root = host.RootComponent;
+                        if ((root != null) && (root is ISynchronizeInvoke))
+                        {
+                            m_invoker = (ISynchronizeInvoke)root;
+                            // TODO: fire some sort of propertyChanged event,
+                            // so that old code gets cleaned up correctly.
+                        }
+                    }
+                }
+                return m_invoker;
+            }
+            set { m_invoker = value; }
+        }
+
+        /// <summary>
+        /// Gets or sets the keep-alive interval in seconds.
+        /// </summary>
+        [Description("Gets or sets the keep-alive interval in seconds")]
+        [Category("Jabber")]
+        [DefaultValue(20f)]
+        public float KeepAlive
+        {
+            get { return ((int)this[Options.KEEP_ALIVE]) / 1000f; }
+            set { this[Options.KEEP_ALIVE] = (int)(value * 1000f); }
+        }
+
+        /// <summary>
+        /// Gets or sets the number of seconds before automatically
+        /// reconnecting if the connection drops.
+        /// -1 to disable, 0 for immediate.
+        /// </summary>
+        [Description("Automatically reconnect a connection.")]
+        [DefaultValue(30)]
+        [Category("Automation")]
+        public float AutoReconnect
+        {
+            get { return ((int)this[Options.RECONNECT_TIMEOUT]) / 1000f; }
+            set { this[Options.RECONNECT_TIMEOUT] = (int)(value * 1000f); }
+        }
+
+        /// <summary>
+        /// Gets or sets the proxy type, such as none, SOCKS5 and so on.
+        /// </summary>
+        [Description("Gets or sets the proxy type, such as none, SOCKS5 and so on.")]
+        [DefaultValue(ProxyType.None)]
+        [Category("Proxy")]
+        public ProxyType Proxy
+        {
+            get { return (ProxyType)this[Options.PROXY_TYPE]; }
+            set { this[Options.PROXY_TYPE] = value; }
+        }
+
+        /// <summary>
+        /// Gets or sets the connection type, such as Socket, HTTP polling and so on.
+        /// </summary>
+        [Description("Gets or sets the connection type, such as Socket, HTTP polling and so on.")]
+        [DefaultValue(ConnectionType.Socket)]
+        [Category("Proxy")]
+        public ConnectionType Connection
+        {
+            get { return (ConnectionType)this[Options.CONNECTION_TYPE]; }
+            set { this[Options.CONNECTION_TYPE] = value; }
+        }
+
+        /// <summary>
+        /// Gets or sets the hostname running the proxy.
+        /// </summary>
+        [Description("Gets or sets the hostname running the proxy.")]
+        [DefaultValue(null)]
+        [Category("Proxy")]
+        public string ProxyHost
+        {
+            get { return this[Options.PROXY_HOST] as string; }
+            set { this[Options.PROXY_HOST] = value; }
+        }
+
+        /// <summary>
+        /// Gets or sets the port number of the proxy host.
+        /// </summary>
+        [Description("Gets or sets the port number of the proxy host.")]
+        [DefaultValue(1080)]
+        [Category("Proxy")]
+        public int ProxyPort
+        {
+            get { return (int)this[Options.PROXY_PORT]; }
+            set { this[Options.PROXY_PORT] = value; }
+        }
+
+        /// <summary>
+        /// Gets or sets the authentication username for the SOCKS5 proxy.
+        /// </summary>
+        [Description("Gets or sets the authentication username for the SOCKS5 proxy.")]
+        [DefaultValue(null)]
+        [Category("Proxy")]
+        public string ProxyUsername
+        {
+            get { return this[Options.PROXY_USER] as string; }
+            set { this[Options.PROXY_USER] = value; }
+        }
+
+        /// <summary>
+        /// Gets or sets the authentication password for the SOCKS5 proxy.
+        /// </summary>
+        [Description("the auth password for the socks5 proxy")]
+        [DefaultValue(null)]
+        [Category("Proxy")]
+        public string ProxyPassword
+        {
+            get { return this[Options.PROXY_PW] as string; }
+            set { this[Options.PROXY_PW] = value; }
+        }
+
+        /// <summary>
+        /// Gets or sets the ID attribute from the
+        /// stream:stream element sent by the XMPP server.
+        /// </summary>
+        [Browsable(false)]
+        [DefaultValue(null)]
+        public string StreamID
+        {
+            get { return m_streamID; }
+            set { m_streamID = value; }
+        }
+
+        /// <summary>
+        /// Retrieves the outbound document.
+        /// </summary>
+        [Browsable(false)]
+        public XmlDocument Document
+        {
+            get { return m_doc; }
+        }
+
+        /// <summary>
+        /// Gets or sets the current state of the connection.
+        /// Lock on StateLock before accessing.
+        /// </summary>
+        [Browsable(false)]
+        protected virtual BaseState State
+        {
+            get { return m_state; }
+            set { m_state = value;
+            // Debug.WriteLine("New state: " + m_state.ToString());
+            }
+        }
+
+        /// <summary>
+        /// Gets the lock for the state information.
+        /// </summary>
+        [Browsable(false)]
+        protected object StateLock
+        {
+            get { return m_stateLock; }
+        }
+
+        /// <summary>
+        /// Gets or sets the state to authenticated.  Locks on StateLock
+        /// </summary>
+        [Browsable(false)]
+        [DefaultValue(false)]
+        public virtual bool IsAuthenticated
+        {
+            get
+            {
+                lock (StateLock)
+                {
+                    return (State == RunningState.Instance);
+                }
+            }
+            set
+            {
+                bool close = false;
+                lock (StateLock)
+                {
+                    if (value)
+                    {
+                        State = RunningState.Instance;
+                    }
+                    else
+                        close = true;
+                }
+                if (close)
+                    Close();
+                if (value && (OnAuthenticate != null))
+                {
+                    if (InvokeRequired)
+                        CheckedInvoke(OnAuthenticate, new object[] { this });
+                    else
+                        OnAuthenticate(this);
+                }
+                this[Options.CURRENT_KEEP_ALIVE] = this[Options.KEEP_ALIVE];
+            }
+        }
+
+        /// <summary>
+        /// Returns the namespace for this connection.
+        /// </summary>
+        [Browsable(false)]
+        protected abstract string NS
+        {
+            get;
+        }
+
+        /// <summary>
+        /// Determines whether or not SASL is required for connecting to the XMPP server.
+        /// </summary>
+        [Description("Determines if SASL is required for connecting to the XMPP server.")]
+        [DefaultValue(false)]
+        public bool RequiresSASL
+        {
+            get { return (bool)this[Options.REQUIRE_SASL]; }
+            set { this[Options.REQUIRE_SASL] = value; }
+        }
+
+        /// <summary>
+        /// Gets the version number of the XMPP server.
+        /// </summary>
+        [Description("Gets the version number of the XMPP server.")]
+        [DefaultValue(null)]
+        public string ServerVersion
+        {
+            get { return m_serverVersion; }
+        }
+
+        /// <summary>
+        /// Writes just the start tag of the given XML element.
+        /// Typically only used for <stream:stream>.
+        /// </summary>
+        /// <param name="elem"><stream:stream%gt; XML element.</param>
+        public void WriteStartTag(jabber.protocol.stream.Stream elem)
+        {
+            m_stanzas.WriteStartTag(elem);
+        }
+
+        /// <summary>
+        /// Sends the given packet to the server.
+        /// </summary>
+        /// <param name="elem">The XML element to send.</param>
+        public virtual void Write(XmlElement elem)
+        {
+            m_stanzas.Write(elem);
+        }
+
+        /// <summary>
+        /// Sends a raw string.
+        /// </summary>
+        /// <param name="str">The string to send.</param>
+        public void Write(string str)
+        {
+            m_stanzas.Write(str);
+        }
+
+        /// <summary>
+        /// Starts connecting to the XMPP server.  This is done asyncronously.
+        /// </summary>
+        public virtual void Connect()
+        {
+            this[Options.CURRENT_KEEP_ALIVE] = -1;
+            m_stanzas = StanzaStream.Create(this.Connection, this);
+            lock (StateLock)
+            {
+                State = ConnectingState.Instance;
+                m_reconnect = ((int)this[Options.RECONNECT_TIMEOUT] >= 0);
+            }
+            m_stanzas.Connect();
+        }
+
+        /// <summary>
+        /// Listens for connections from the XMPP server and is used for components only.
+        /// </summary>
+        protected virtual void Accept()
+        {
+            if ((m_stanzas == null) || (!m_stanzas.Acceptable))
+                m_stanzas = StanzaStream.Create(this.Connection, this);
+            lock (StateLock)
+            {
+                this.State = AcceptingState.Instance;
+                m_reconnect = ((int)this[Options.RECONNECT_TIMEOUT] >= 0);
+            }
+            m_stanzas.Accept();
+        }
+
+        /// <summary>
+        /// If autoReconnect is on, start the timer for reconnect now.
+        /// </summary>
+        private void TryReconnect()
+        {
+            // close was not requested, or autoreconnect turned on.
+            if (m_reconnect)
+            {
+                if (m_reconnectTimer != null)
+                    m_reconnectTimer.Dispose();
+
+                m_reconnectTimer = new System.Threading.Timer(
+                        new System.Threading.TimerCallback(Reconnect),
+                        null,
+                        (int)this[Options.RECONNECT_TIMEOUT],
+                        System.Threading.Timeout.Infinite);
+            }
+        }
+
+        /// <summary>
+        /// Closes down the connection with the XMPP server with a clean shutdown.
+        /// </summary>
+        public virtual void Close()
+        {
+            Close(true);
+        }
+
+        /// <summary>
+        /// Closes down the connection.
+        /// </summary>
+        /// <param name="clean">True for graceful shutdown</param>
+        public virtual void Close(bool clean)
+        {
+            bool doClose = false;
+            bool doStream = false;
+
+
+            lock (StateLock)
+            {
+                // if close is called, never try to reconnect.
+                m_reconnect = false;
+
+                if ((State == RunningState.Instance) && (clean))
+                {
+                    doStream = true;
+                }
+                if (m_state != ClosedState.Instance)
+                {
+                    State = ClosingState.Instance;
+                    doClose = true;
+                }
+            }
+
+            if ((m_stanzas != null) && m_stanzas.Connected && doClose)
+            {
+                m_stanzas.Close(doStream);
+            }
+            else
+            {
+                Debug.WriteLine("Cannot close a socket before it is open");
+                //FireOnError(new InvalidOperationException("Cannot close a socket before it is open"));
+            }
+        }
+
+        /// <summary>
+        /// Invokes the given method on the Invoker, and does some exception handling.
+        /// </summary>
+        /// <param name="method">Method to call on the invoker thread.</param>
+        /// <param name="args">Arguments to pass to the method.</param>
+        protected void CheckedInvoke(MulticastDelegate method, object[] args)
+        {
+            try
+            {
+                Debug.Assert(m_invoker != null, "Check for this.InvokeControl == null before calling CheckedInvoke");
+                Debug.Assert(m_invoker.InvokeRequired, "Check for InvokeRequired before calling CheckedInvoke");
+
+                m_invoker.BeginInvoke(method, args);
+            }
+            catch (System.Reflection.TargetInvocationException e)
+            {
+                Debug.WriteLine("Exception passed along by XmppStream: " + e.ToString());
+                throw e.InnerException;
+            }
+            catch (Exception e)
+            {
+                Debug.WriteLine("Exception in XmppStream: " + e.ToString());
+                throw;
+            }
+        }
+
+        /// <summary>
+        /// Determines whether or not a callback needs to be on the GUI thread.
+        /// </summary>
+        /// <returns>
+        /// True if the invoke control is set and the current thread
+        /// is not the GUI thread.
+        /// </returns>
+        protected bool InvokeRequired
+        {
+            get
+            {
+                if (m_invoker == null)
+                    return false;
+                return m_invoker.InvokeRequired;
+            }
+        }
+
+        /// <summary>
+        /// Informs the client that the first tag of the XML document has been received.
+        /// </summary>
+        /// <param name="sender">Caller of this function.</param>
+        /// <param name="elem">The XML element that was received.</param>
+        protected virtual void OnDocumentStart(object sender, System.Xml.XmlElement elem)
+        {
+            bool hack = false;
+
+            if (elem is jabber.protocol.stream.Stream)
+            {
+                jabber.protocol.stream.Stream str = elem as jabber.protocol.stream.Stream;
+
+                m_streamID = str.ID;
+                m_serverVersion = str.Version;
+
+                // See XMPP-core section 4.4.1.  We'll accept 1.x
+                if (m_serverVersion.StartsWith("1."))
+                {
+                    lock (m_stateLock)
+                    {
+                        if (State == SASLState.Instance)
+                            // already authed.  last stream restart.
+                            State = SASLAuthedState.Instance;
+                        else
+                            State = jabber.connection.ServerFeaturesState.Instance;
+                    }
+                }
+                else
+                {
+                    lock (m_stateLock)
+                    {
+                        State = NonSASLAuthState.Instance;
+                    }
+                    hack = true;
+                }
+                if (OnStreamHeader != null)
+                {
+                    if (InvokeRequired)
+                        CheckedInvoke(OnStreamHeader, new object[] { this, elem });
+                    else
+                        OnStreamHeader(this, elem);
+                }
+                CheckAll(elem);
+
+                if (hack && (OnSASLStart != null))
+                {
+                    OnSASLStart(this, null); // Hack.  Old-style auth for jabberclient.
+                }
+            }
+        }
+
+        /// <summary>
+        /// Handle the last set of stream:features we have received, 
+        /// based on the current state.
+        /// </summary>
+        protected virtual void ProcessFeatures()
+        {
+            // don't do starttls if we're already on an SSL socket.
+            // bad server setup, but no skin off our teeth, we're already
+            // SSL'd.  Also, start-tls won't work when polling.
+            if ((bool)this[Options.AUTO_TLS] &&
+                (m_features.StartTLS != null) &&
+                (!m_sslOn) &&
+                m_stanzas.SupportsTLS)
+            {
+                // start-tls
+                lock (m_stateLock)
+                {
+                    State = StartTLSState.Instance;
+                }
+                this.Write(new StartTLS(m_doc));
+                return;
+            }
+
+            Compression comp = m_features.Compression;
+            if ((bool)this[Options.AUTO_COMPRESS] &&
+                (comp != null) &&
+                comp.HasMethod("zlib") &&
+                (!m_compressionOn) &&
+                m_stanzas.SupportsCompression)
+            {
+                // start compression
+                lock (m_stateLock)
+                {
+                    State = CompressionState.Instance;
+                }
+                Compress c = new Compress(m_doc);
+                c.Method = "zlib";
+                this.Write(c);
+                return;
+            }
+
+            // not authenticated yet.  Note: we'll get a stream:features
+            // after the last sasl restart, so we shouldn't try to iq:auth
+            // at that point.
+            if (!IsAuthenticated)
+            {
+                Mechanisms ms = m_features.Mechanisms;
+                m_saslProc = null;
+
+                MechanismType types = MechanismType.NONE;
+
+                if (ms != null)
+                {
+                    // if SASL_MECHANISMS is set in the options, it is the limited set
+                    // of mechanisms we're willing to try.  Mask them off of the offered set.
+                    object smt = this[Options.SASL_MECHANISMS];
+                    if (smt != null)
+                        types = (MechanismType)smt & ms.Types;
+                    else
+                        types = ms.Types;
+                }
+
+                // If we're doing SASL, and there are mechanisms implemented by both
+                // client and server.
+                if ((types != MechanismType.NONE) && ((bool)this[Options.SASL]))
+                {
+                    lock (m_stateLock)
+                    {
+                        State = SASLState.Instance;
+                    }
+                    m_saslProc = SASLProcessor.createProcessor(types, m_sslOn || (bool)this[Options.PLAINTEXT], ms);
+                    if (m_saslProc == null)
+                    {
+                        FireOnError(new NotImplementedException("No implemented mechanisms in: " + types.ToString()));
+                        return;
+                    }
+                    if (OnSASLStart != null)
+                        OnSASLStart(this, m_saslProc);
+                    lock (m_stateLock)
+                    {
+                        // probably manual authentication
+                        if (State != SASLState.Instance)
+                            return;
+                    }
+
+                    try
+                    {
+                        Step s = m_saslProc.step(null, this.Document);
+                        if (s != null)
+                            this.Write(s);
+                    }
+                    catch (Exception e)
+                    {
+                        FireOnError(new SASLException(e.Message));
+                        return;
+                    }
+                }
+
+                if (m_saslProc == null)
+                { // no SASL mechanisms.  Try iq:auth.
+                    if ((bool)this[Options.REQUIRE_SASL])
+                    {
+                        FireOnError(new SASLException("No SASL mechanisms available"));
+                        return;
+                    }
+                    lock (m_stateLock)
+                    {
+                        State = NonSASLAuthState.Instance;
+                    }
+                    if (OnSASLStart != null)
+                        OnSASLStart(this, null); // HACK: old-style auth for jabberclient.
+                }
+            }
+        }
+
+        /// <summary>
+        /// Informs the client that an XML element was received and
+        /// invokes the OnProtocol event.
+        /// </summary>
+        /// <param name="sender">The object that called this method.</param>
+        /// <param name="tag">XML element that contains the new tag.</param>
+        protected virtual void OnElement(object sender, System.Xml.XmlElement tag)
+        {
+            //Debug.WriteLine(tag.OuterXml);
+
+            if (tag is jabber.protocol.stream.Error)
+            {
+                // Stream error.  Race condition!  Two cases:
+                // 1) OnClose has already fired, in which case we are in ClosedState, and the reconnect timer is pending.
+                // 2) OnClose hasn't fired, in which case we trick it into not starting the reconnect timer.
+                lock (m_stateLock)
+                {
+                    if (m_state != ClosedState.Instance)
+                    {
+                        State = ClosingState.Instance;
+                    }
+                    else if (m_reconnectTimer != null)
+                    {
+                        Debug.WriteLine("Disposing of timer");
+                        m_reconnectTimer.Dispose();
+                    }
+                }
+
+                if (OnStreamError != null)
+                {
+                    if (InvokeRequired)
+                        CheckedInvoke(OnStreamError, new object[] { this, tag });
+                    else
+                        OnStreamError(this, tag);
+                }
+                return;
+            }
+
+            if (State == ServerFeaturesState.Instance)
+            {
+                Features f = tag as Features;
+                if (f == null)
+                {
+                    FireOnError(new InvalidOperationException("Expecting stream:features from a version='1.0' server"));
+                    return;
+                }
+                m_features = f;
+                ProcessFeatures();
+                return;
+            }
+            else if (State == SASLState.Instance)
+            {
+                if (tag is Success)
+                {
+                    // restart the stream again
+                    SendNewStreamHeader();
+                }
+                else if (tag is SASLFailure)
+                {
+                    m_saslProc = null;
+
+                    lock (m_stateLock)
+                    {
+                        State = SASLFailedState.Instance;
+                    }
+                    SASLFailure sf = tag as SASLFailure;
+                    // TODO: I18N
+                    if (OnSASLError != null)
+                    {
+                        m_reconnect = false;
+                        OnSASLError(this, sf);
+                    }
+                    else
+                        FireOnError(new SASLException("SASL failure: " + sf.InnerXml));
+                    return;
+                }
+                else if (tag is Step)
+                {
+                    try
+                    {
+                        Step s = m_saslProc.step(tag as Step, this.Document);
+                        if (s != null)
+                            Write(s);
+                    }
+                    catch (Exception e)
+                    {
+                        FireOnError(new SASLException(e.Message));
+                        return;
+                    }
+                }
+                else
+                {
+                    m_saslProc = null;
+                    FireOnError(new SASLException("Invalid SASL protocol"));
+                    return;
+                }
+            }
+            else if (State == StartTLSState.Instance)
+            {
+                switch (tag.Name)
+                {
+                case "proceed":
+                    if (!StartTLS())
+                        return;
+                    SendNewStreamHeader();
+                    break;
+                case "failure":
+                    FireOnError(new AuthenticationFailedException());
+                    return;
+                }
+            }
+            else if (State == CompressionState.Instance)
+            {
+                switch (tag.Name)
+                {
+                case "compressed":
+                    if (!StartCompression())
+                        return;
+                    SendNewStreamHeader();
+                    break;
+                case "failure":
+                    CompressionFailure fail = tag as CompressionFailure;
+#if ZLIB_NET
+                    FireOnError(new bedrock.io.CompressionFailedException(fail.Error));
+#else
+                    FireOnError(new IOException(fail.Error));
+#endif
+                    return;
+                }
+
+            }
+            else if (State == SASLAuthedState.Instance)
+            {
+                Features f = tag as Features;
+                if (f == null)
+                {
+                    FireOnError(new InvalidOperationException("Expecting stream:features from a version='1.0' server"));
+                    return;
+                }
+                if (OnSASLEnd != null)
+                    OnSASLEnd(this, f);
+                m_saslProc = null;
+            }
+            else
+            {
+                if (OnProtocol != null)
+                {
+                    if (InvokeRequired)
+                        CheckedInvoke(OnProtocol, new object[] { this, tag });
+                    else
+                        OnProtocol(this, tag);
+                }
+            }
+            CheckAll(tag);
+        }
+
+        /// <summary>
+        /// Begins the TLS handshake, either client-side or server-side.
+        /// </summary>
+        /// <returns>True if StartTLS worked.</returns>
+        protected bool StartTLS()
+        {
+            try
+            {
+                m_stanzas.StartTLS();
+            }
+            catch (Exception e)
+            {
+                m_reconnect = false;
+                if (e.InnerException != null)
+                    FireOnError(e.InnerException);
+                else
+                    FireOnError(e);
+                return false;
+            }
+            m_sslOn = true;
+            return true;
+        }
+
+        /// <summary>
+        /// Begins compressing the XMPP stream.
+        /// </summary>
+        /// <returns>If True, compression was successful, otherwise False.</returns>
+        protected bool StartCompression()
+        {
+            try
+            {
+                m_stanzas.StartCompression();
+            }
+            catch (Exception e)
+            {
+                m_reconnect = false;
+                FireOnError(e);
+                return false;
+            }
+            m_compressionOn = true;
+            return true;
+        }
+
+        /// <summary>
+        /// Gets ready for a new stream:stream by starting a new XML document.
+        /// Needed after Start-TLS or compression, for example.
+        /// </summary>
+        protected void InitializeStream()
+        {
+            try
+            {
+                m_stanzas.InitializeStream();
+            }
+            catch (Exception e)
+            {
+                FireOnError(e);
+            }
+        }
+
+        /// <summary>
+        /// Sends a new XMPP stream header.
+        /// </summary>
+        protected void SendNewStreamHeader()
+        {
+            jabber.protocol.stream.Stream str = new jabber.protocol.stream.Stream(m_doc, NS);
+            str.To = new JID((string)this[Options.TO]);
+            str.Version = "1.0";
+            m_stanzas.WriteStartTag(str);
+            InitializeStream();
+        }
+
+        /// <summary>
+        /// Informs the client of XMPP stream errors through the OnError event.
+        /// </summary>
+        /// <param name="e">Error that occurred.</param>
+        protected void FireOnError(Exception e)
+        {
+            m_reconnect = false;
+
+            // ignore spurious IO errors on shutdown.
+            if (((State == ClosingState.Instance) || (State == ClosedState.Instance)) &&
+                ((e is System.IO.IOException) || (e.InnerException is System.IO.IOException)))
+                return;
+
+            if (OnError != null)
+            {
+                if (InvokeRequired)
+                    CheckedInvoke(OnError, new object[] { this, e });
+                else
+                    OnError(this, e);
+            }
+
+            if ((State != ClosingState.Instance) && (State == ClosedState.Instance))
+                Close(false);
+        }
+
+        private void Reconnect(object state)
+        {
+            // prevent double-connects
+            if (this.State == ClosedState.Instance)
+                Connect();
+        }
+
+        /// <summary>
+        /// Registers a callback, so that if a packet arrives that matches the given xpath expression,
+        /// the callback fires.  Use <see cref="AddNamespace"/> to add namespace prefixes.
+        /// </summary>
+        /// <example>jc.AddCallback("self::iq[@type='result']/roster:query", new ProtocolHandler(GotRoster));</example>
+        /// <param name="xpath">The xpath expression to search for</param>
+        /// <param name="cb">The callback to call when the xpath matches</param>
+        /// <returns>A guid that can be used to unregister the callback</returns>
+        public Guid AddCallback(string xpath, ProtocolHandler cb)
+        {
+            CallbackData cbd = new CallbackData(xpath, cb);
+            m_callbacks.Add(cbd);
+            return cbd.Guid;
+        }
+
+        /// <summary>
+        /// Removes a callback added with <see cref="AddCallback"/>.
+        /// </summary>
+        /// <param name="guid">GUID representing the callback to remove.</param>
+        public void RemoveCallback(Guid guid)
+        {
+            int count = 0;
+            foreach (CallbackData cbd in m_callbacks)
+            {
+                if (cbd.Guid == guid)
+                {
+                    m_callbacks.RemoveAt(count);
+                    return;
+                }
+                count++;
+            }
+            throw new ArgumentException("Unknown Guid", "guid");
+        }
+
+        /// <summary>
+        /// Adds a namespace prefix, for use with callback xpath expressions added
+        /// with <see cref="AddCallback"/>.
+        /// </summary>
+        /// <param name="prefix">The prefix to use.</param>
+        /// <param name="uri">The URI associated with the prefix.</param>
+        public void AddNamespace(string prefix, string uri)
+        {
+            m_ns.AddNamespace(prefix, uri);
+        }
+
+        private void CheckAll(XmlElement elem)
+        {
+            foreach (CallbackData cbd in m_callbacks)
+            {
+                cbd.Check(this, elem);
+            }
+        }
+
+        private class CallbackData
+        {
+            private Guid m_guid = Guid.NewGuid();
+            private ProtocolHandler m_cb;
+            private string m_xpath;
+
+            public CallbackData(string xpath, ProtocolHandler cb)
+            {
+                Debug.Assert(cb != null);
+                m_cb = cb;
+                m_xpath = xpath;
+            }
+
+            public Guid Guid
+            {
+                get { return m_guid; }
+            }
+
+            public string XPath
+            {
+                get { return m_xpath; }
+            }
+
+            public void Check(XmppStream sender, XmlElement elem)
+            {
+                try
+                {
+                    XmlNode n = elem.SelectSingleNode(m_xpath, sender.m_ns);
+                    if (n != null)
+                    {
+                        if (sender.InvokeRequired)
+                            sender.CheckedInvoke(m_cb, new object[] { sender, elem });
+                        else
+                            m_cb(sender, elem);
+                    }
+                }
+                catch (Exception e)
+                {
+                    sender.FireOnError(e);
+                }
+            }
+        }
+
+        #region IStanzaEventListener Members
+
+        void IStanzaEventListener.Connected()
+        {
+            lock (m_stateLock)
+            {
+                this.State = ConnectedState.Instance;
+                if ((bool)this[Options.SSL])
+                    m_sslOn = true;
+            }
+
+            if (OnConnect != null)
+            {
+                if (InvokeRequired)
+                    CheckedInvoke(OnConnect, new Object[] { this, m_stanzas });
+                else
+                    OnConnect(this, m_stanzas);
+            }
+
+            SendNewStreamHeader();
+        }
+
+        void IStanzaEventListener.Accepted()
+        {
+            lock (StateLock)
+            {
+                Debug.Assert(this.State == AcceptingState.Instance, this.State.GetType().ToString());
+
+                this.State = ConnectedState.Instance;
+            }
+
+            if (OnConnect != null)
+            {
+                if (InvokeRequired)
+                    CheckedInvoke(OnConnect, new object[] { this, m_stanzas });
+                else
+                {
+                    // Um.  This cast might not be right, but I don't want to break backward compatibility
+                    // if I don't have to by changing the delegate interface.
+                    OnConnect(this, m_stanzas);
+                }
+            }
+        }
+
+        void IStanzaEventListener.BytesRead(byte[] buf, int offset, int count)
+        {
+            if (OnReadText != null)
+            {
+                if (InvokeRequired)
+                    CheckedInvoke(OnReadText, new object[] { this, ENC.GetString(buf, offset, count) });
+                else
+                    OnReadText(this, ENC.GetString(buf, offset, count));
+            }
+        }
+
+        void IStanzaEventListener.BytesWritten(byte[] buf, int offset, int count)
+        {
+            if (OnWriteText != null)
+            {
+                if (InvokeRequired)
+                    CheckedInvoke(OnWriteText, new object[] { this, ENC.GetString(buf, offset, count) });
+                else
+                    OnWriteText(this, ENC.GetString(buf, offset, count));
+            }
+        }
+
+        void IStanzaEventListener.StreamInit(ElementStream stream)
+        {
+            if (OnStreamInit != null)
+            {
+                // Race condition.  Make sure not to make GUI calls in OnStreamInit
+                /*
+                if (InvokeRequired)
+                    CheckedInvoke(OnStreamInit, new object[] { this, stream });
+                else
+              */
+                    OnStreamInit(this, stream);
+            }
+        }
+
+        void IStanzaEventListener.Errored(Exception ex)
+        {
+            m_reconnect = false;
+
+            lock (m_stateLock)
+            {
+                State = ClosedState.Instance;
+                if ((m_stanzas != null) && (!m_stanzas.Acceptable))
+                    m_stanzas = null;
+            }
+
+            if (OnError != null)
+            {
+                if (InvokeRequired)
+                    CheckedInvoke(OnError, new object[] { this, ex });
+                else
+                    OnError(this, ex);
+            }
+
+            // TODO: Figure out what the "good" errors are, and try to
+            // reconnect.  There are too many "bad" errors to just let this fly.
+            //TryReconnect();
+        }
+
+        void IStanzaEventListener.Closed()
+        {
+            lock (StateLock)
+            {
+                State = ClosedState.Instance;
+                if ((m_stanzas != null) && (!m_stanzas.Acceptable))
+                    m_stanzas = null;
+                m_sslOn = false;
+                m_compressionOn = false;
+            }
+
+            if (OnDisconnect != null)
+            {
+                if (InvokeRequired)
+                    CheckedInvoke(OnDisconnect, new object[] { this });
+                else
+                    OnDisconnect(this);
+            }
+
+            TryReconnect();
+        }
+
+        void IStanzaEventListener.DocumentStarted(XmlElement elem)
+        {
+            // The OnDocumentStart logic stays outside the listener, so that it can be
+            // more easily overriden by subclasses.
+            OnDocumentStart(m_stanzas, elem);
+        }
+
+        void IStanzaEventListener.DocumentEnded()
+        {
+            lock (StateLock)
+            {
+                State = ClosingState.Instance;
+                // TODO: Validate this, with current parser:
+
+                // No need to close stream any more.  AElfred does this for us, even though
+                // the docs say it doesn't.
+
+                //if (m_sock != null)
+                //m_sock.Close();
+            }
+        }
+
+        void IStanzaEventListener.StanzaReceived(XmlElement elem)
+        {
+            // The OnElement logic stays outside the listener, so that it can be
+            // more easily overriden by subclasses.
+                OnElement(m_stanzas, elem);
+        }
+
+        private bool ShowCertificatePrompt(object sender,
+            System.Security.Cryptography.X509Certificates.X509Certificate certificate,
+            System.Security.Cryptography.X509Certificates.X509Chain chain,
+            System.Net.Security.SslPolicyErrors sslPolicyErrors)
+        {
+#if !__MonoCS__
+            CertificatePrompt cp = new CertificatePrompt((X509Certificate2)certificate, chain, sslPolicyErrors);
+            return (cp.ShowDialog() == System.Windows.Forms.DialogResult.OK);
+#else
+            return false;
+#endif
+        }
+
+        bool IStanzaEventListener.OnInvalidCertificate(bedrock.net.BaseSocket sock,
+            System.Security.Cryptography.X509Certificates.X509Certificate certificate,
+            System.Security.Cryptography.X509Certificates.X509Chain chain,
+            System.Net.Security.SslPolicyErrors sslPolicyErrors)
+        {
+            if (OnInvalidCertificate != null)
+            {
+                if ((m_invoker == null) || (!m_invoker.InvokeRequired))
+                    return OnInvalidCertificate(sock, certificate, chain, sslPolicyErrors);
+                try
+                {
+                    // Note: can't use CheckedInvoke here, since we need the return value.  We'll wait for the response.
+                    return (bool)m_invoker.Invoke(OnInvalidCertificate, new object[] { sock, certificate, chain, sslPolicyErrors });
+                }
+                catch (Exception e)
+                {
+                    Debug.WriteLine("Exception passed along by XmppStream: " + e.ToString());
+                    return false;
+                }
+            }
+            if ((m_invoker == null) || (!m_invoker.InvokeRequired))
+                return ShowCertificatePrompt(sock, certificate, chain, sslPolicyErrors);
+
+            return (bool)m_invoker.Invoke(new System.Net.Security.RemoteCertificateValidationCallback(ShowCertificatePrompt), new object[]{ sock, certificate, chain, sslPolicyErrors });
+        }
+
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/jabber/connection/XmppStream.resx b/lib/jabber-net/jabber/connection/XmppStream.resx
new file mode 100644
index 0000000..f598e3c
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/XmppStream.resx
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<root>
+        <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+                <xsd:element name="root" msdata:IsDataSet="true">
+                        <xsd:complexType>
+                                <xsd:choice maxOccurs="unbounded">
+                                        <xsd:element name="data">
+                                                <xsd:complexType>
+                                                        <xsd:sequence>
+                                                                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                                                                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+                                                        </xsd:sequence>
+                                                        <xsd:attribute name="name" type="xsd:string" />
+                                                        <xsd:attribute name="type" type="xsd:string" />
+                                                        <xsd:attribute name="mimetype" type="xsd:string" />
+                                                </xsd:complexType>
+                                        </xsd:element>
+                                        <xsd:element name="resheader">
+                                                <xsd:complexType>
+                                                        <xsd:sequence>
+                                                                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                                                        </xsd:sequence>
+                                                        <xsd:attribute name="name" type="xsd:string" use="required" />
+                                                </xsd:complexType>
+                                        </xsd:element>
+                                </xsd:choice>
+                        </xsd:complexType>
+                </xsd:element>
+        </xsd:schema>
+        <resheader name="ResMimeType">
+                <value>text/microsoft-resx</value>
+        </resheader>
+        <resheader name="Version">
+                <value>1.0.0.0</value>
+        </resheader>
+        <resheader name="Reader">
+                <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+        </resheader>
+        <resheader name="Writer">
+                <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+        </resheader>
+</root>
diff --git a/lib/jabber-net/jabber/connection/sasl/ExternalProcessor.cs b/lib/jabber-net/jabber/connection/sasl/ExternalProcessor.cs
new file mode 100644
index 0000000..2460467
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/sasl/ExternalProcessor.cs
@@ -0,0 +1,44 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.IO;
+using System.Diagnostics;
+using System.Xml;
+
+using bedrock.util;
+using jabber.protocol.stream;
+
+namespace jabber.connection.sasl
+{
+    /// <summary>
+    /// SASL Mechanism EXTERNAL as specified in XEP-0178.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ExternalProcessor : SASLProcessor
+    {
+        /// <summary>
+        /// Perform the next step
+        /// </summary>
+        /// <param name="s">Null if it's the initial response</param>
+        /// <param name="doc">Document to create Steps in</param>
+        /// <returns></returns>
+        public override Step step(Step s, XmlDocument doc)
+        {
+            Debug.Assert(s == null);
+            Auth a = new Auth(doc);
+            a.Mechanism = MechanismType.EXTERNAL;
+            return a;
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/connection/sasl/KerbProcessor.cs b/lib/jabber-net/jabber/connection/sasl/KerbProcessor.cs
new file mode 100644
index 0000000..63078d9
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/sasl/KerbProcessor.cs
@@ -0,0 +1,798 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Runtime.InteropServices;
+using System.Security.Principal;
+using System.Xml;
+using jabber.protocol.stream;
+using HANDLE = System.IntPtr;
+
+using bedrock.util;
+
+namespace jabber.connection.sasl
+{
+
+    ///<summary>
+    /// Uses Kerberos authentication ot log into XMPP server.
+    ///</summary>
+    [SVN(@"$Id$")]
+    public class KerbProcessor : SASLProcessor
+    {
+        /// <summary>
+        /// Should we use the existing Windows (kerberos) credentials?
+        /// </summary>
+        public const string USE_WINDOWS_CREDS = "USE_WINDOWS_CREDS";
+
+        private readonly SSPIHelper kerbClient;
+        ///<summary>
+        /// Creates a new KerbProcessor
+        ///</summary>
+        ///<param name="remotePrincipal">Remote principal that represents the XMPP server.</param>
+        public KerbProcessor(string remotePrincipal)
+        {
+            kerbClient = new SSPIHelper(remotePrincipal);
+        }
+
+        /// <summary>
+        /// Perform the next step
+        /// </summary>
+        /// <param name="s">Null if it's the initial response</param>
+        /// <param name="doc">Document to create Steps in</param>
+        /// <returns>XML to send to the XMPP server.</returns>
+        public override Step step(Step s, XmlDocument doc)
+        {
+            byte[] outBytes;
+            byte[] inBytes = null;
+
+            Step returnStep;
+
+            if (s == null)
+            {
+                // First step.
+                returnStep = new Auth(doc);
+                ((Auth)returnStep).Mechanism = MechanismType.GSSAPI;
+
+                SetCredentials();
+            }
+            else
+            {
+                returnStep = new Response(doc);
+                inBytes = s.Bytes;
+            }
+
+            kerbClient.ExecuteKerberos(inBytes, out outBytes);
+            returnStep.Bytes = outBytes;
+
+            return returnStep;
+        }
+
+        private void SetCredentials()
+        {
+            // Username should be in the form of "DOMAIN\USERNAME"
+            // If it isn't, we'll assume it is the username and get
+            // the domain from somewhere else.
+            string username = this[USERNAME];
+            int sepIndex = username.IndexOf('\\');
+            kerbClient.Username = username.Substring(sepIndex + 1);
+
+            if (sepIndex != -1)
+                kerbClient.Domain = username.Substring(0, sepIndex);
+            else
+            {
+                // Domain wasn't specified. Use the current user's domain.
+                string currentName = WindowsIdentity.GetCurrent().Name;
+                kerbClient.Domain = currentName.Substring(0, currentName.IndexOf('\\'));
+            }
+            kerbClient.Password = this[PASSWORD];
+            kerbClient.UseWindowsCreds = Boolean.Parse(this[USE_WINDOWS_CREDS]);
+        }
+    }
+
+    internal enum SecBufferType
+    {
+        SECBUFFER_VERSION = 0,
+        SECBUFFER_EMPTY = 0,
+        SECBUFFER_DATA = 1,
+        SECBUFFER_TOKEN = 2,
+        SECBUFFER_PADDING = 9,
+        SECBUFFER_STREAM = 10
+    }
+    /*
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct SecHandle //=PCtxtHandle
+    {
+        uint dwLower;
+        uint dwUpper;
+    }
+    */
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct SecBuffer : IDisposable
+    {
+        public int cbBuffer;
+        public int BufferType;
+        public IntPtr pvBuffer;
+
+
+        public SecBuffer(int bufferSize)
+        {
+            cbBuffer = bufferSize;
+            BufferType = (int)SecBufferType.SECBUFFER_TOKEN;
+            pvBuffer = Marshal.AllocHGlobal(bufferSize);
+        }
+
+        public SecBuffer(byte[] secBufferBytes)
+        {
+            cbBuffer = secBufferBytes.Length;
+            BufferType = (int)SecBufferType.SECBUFFER_TOKEN;
+            pvBuffer = Marshal.AllocHGlobal(cbBuffer);
+            Marshal.Copy(secBufferBytes, 0, pvBuffer, cbBuffer);
+        }
+
+        public SecBuffer(byte[] secBufferBytes, SecBufferType bufferType)
+        {
+            BufferType = (int)bufferType;
+
+            if (secBufferBytes != null && secBufferBytes.Length != 0)
+            {
+                cbBuffer = secBufferBytes.Length;
+                pvBuffer = Marshal.AllocHGlobal(cbBuffer);
+                Marshal.Copy(secBufferBytes, 0, pvBuffer, cbBuffer);
+            }
+            else
+            {
+                cbBuffer = 0;
+                pvBuffer = HANDLE.Zero;
+            }
+        }
+
+        public void Dispose()
+        {
+            if (pvBuffer != IntPtr.Zero)
+            {
+                Marshal.FreeHGlobal(pvBuffer);
+                pvBuffer = IntPtr.Zero;
+            }
+        }
+    }
+
+    internal struct MultipleSecBufferHelper
+    {
+        public byte[] Buffer;
+        public SecBufferType BufferType;
+
+        public MultipleSecBufferHelper(byte[] buffer, SecBufferType bufferType)
+        {
+            Buffer = buffer;
+            BufferType = bufferType;
+        }
+    };
+
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct SecBufferDesc : IDisposable
+    {
+
+        public int ulVersion;
+        public int cBuffers;
+        public IntPtr pBuffers; //Point to SecBuffer
+
+        public SecBufferDesc(int bufferSize)
+        {
+            ulVersion = (int)SecBufferType.SECBUFFER_VERSION;
+            cBuffers = 1;
+            SecBuffer ThisSecBuffer = new SecBuffer(bufferSize);
+            pBuffers = Marshal.AllocHGlobal(Marshal.SizeOf(ThisSecBuffer));
+            Marshal.StructureToPtr(ThisSecBuffer, pBuffers, false);
+        }
+
+        public SecBufferDesc(byte[] secBufferBytes)
+        {
+            ulVersion = (int)SecBufferType.SECBUFFER_VERSION;
+            cBuffers = 1;
+            SecBuffer ThisSecBuffer = new SecBuffer(secBufferBytes);
+            pBuffers = Marshal.AllocHGlobal(Marshal.SizeOf(ThisSecBuffer));
+            Marshal.StructureToPtr(ThisSecBuffer, pBuffers, false);
+        }
+
+        internal SecBufferDesc(MultipleSecBufferHelper[] secBufferBytesArray)
+        {
+            if (secBufferBytesArray == null || secBufferBytesArray.Length == 0)
+            {
+                throw new ArgumentException("secBufferBytesArray cannot be null or 0 length");
+            }
+
+            ulVersion = (int)SecBufferType.SECBUFFER_VERSION;
+            cBuffers = secBufferBytesArray.Length;
+
+            //Allocate memory for SecBuffer Array....
+            pBuffers = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SecBuffer)) * cBuffers);
+
+            for (int Index = 0; Index < secBufferBytesArray.Length; Index++)
+            {
+                //Super hack: Now allocate memory for the individual SecBuffers
+                //and just copy the bit values to the SecBuffer array!!!
+                SecBuffer ThisSecBuffer = new SecBuffer(secBufferBytesArray[Index].Buffer,
+                    secBufferBytesArray[Index].BufferType);
+
+                //We will write out bits in the following order:
+                //int cbBuffer;
+                //int BufferType;
+                //pvBuffer;
+                //Note: that we won't be releasing the memory allocated by ThisSecBuffer until we
+                //are disposed...
+                int CurrentOffset = Index * Marshal.SizeOf(typeof(SecBuffer));
+                Marshal.WriteInt32(pBuffers, CurrentOffset, ThisSecBuffer.cbBuffer);
+
+                int length = CurrentOffset + Marshal.SizeOf(ThisSecBuffer.cbBuffer);
+                Marshal.WriteInt32(pBuffers, length, ThisSecBuffer.BufferType);
+
+                length = CurrentOffset + Marshal.SizeOf(ThisSecBuffer.cbBuffer) +
+                         Marshal.SizeOf(ThisSecBuffer.BufferType);
+                Marshal.WriteIntPtr(pBuffers, length, ThisSecBuffer.pvBuffer);
+            }
+        }
+
+        public void Dispose()
+        {
+            if (pBuffers != IntPtr.Zero)
+            {
+                if (cBuffers == 1)
+                {
+                    SecBuffer ThisSecBuffer =
+                        (SecBuffer)Marshal.PtrToStructure(pBuffers, typeof(SecBuffer));
+                    ThisSecBuffer.Dispose();
+                }
+                else
+                {
+                    // Since we aren't sending any messages using the kerberos encrypt/decrypt.
+                    // The 1st buffer is going to be empty. We can skip it.
+                    for (int Index = 1; Index < cBuffers; Index++)
+                    {
+                        //The bits were written out the following order:
+                        //int cbBuffer;
+                        //int BufferType;
+                        //pvBuffer;
+                        //What we need to do here is to grab a hold of the pvBuffer allocate by the individual
+                        //SecBuffer and release it...
+                        int CurrentOffset = Index * Marshal.SizeOf(typeof(SecBuffer));
+
+                        int totalLength = CurrentOffset + Marshal.SizeOf(typeof(int)) +
+                                          Marshal.SizeOf(typeof(int));
+                        IntPtr SecBufferpvBuffer = Marshal.ReadIntPtr(pBuffers, totalLength);
+                        Marshal.FreeHGlobal(SecBufferpvBuffer);
+                    }
+                }
+
+                Marshal.FreeHGlobal(pBuffers);
+                pBuffers = IntPtr.Zero;
+            }
+        }
+
+        public byte[] GetSecBufferByteArray()
+        {
+            byte[] Buffer = null;
+
+            if (pBuffers == IntPtr.Zero)
+            {
+                throw new InvalidOperationException("Object has already been disposed!!!");
+            }
+
+            if (cBuffers == 1)
+            {
+                SecBuffer ThisSecBuffer = (SecBuffer)Marshal.PtrToStructure(pBuffers, typeof(SecBuffer));
+
+                if (ThisSecBuffer.cbBuffer > 0)
+                {
+                    Buffer = new byte[ThisSecBuffer.cbBuffer];
+                    Marshal.Copy(ThisSecBuffer.pvBuffer, Buffer, 0, ThisSecBuffer.cbBuffer);
+                }
+            }
+            else
+            {
+                int BytesToAllocate = 0;
+
+                for (int Index = 0; Index < cBuffers; Index++)
+                {
+                    //The bits were written out the following order:
+                    //int cbBuffer;
+                    //int BufferType;
+                    //pvBuffer;
+                    //What we need to do here calculate the total number of bytes we need to copy...
+                    int CurrentOffset = Index * Marshal.SizeOf(typeof(SecBuffer));
+                    BytesToAllocate += Marshal.ReadInt32(pBuffers, CurrentOffset);
+                }
+
+                Buffer = new byte[BytesToAllocate];
+
+                for (int Index = 0, BufferIndex = 0; Index < cBuffers; Index++)
+                {
+                    //The bits were written out the following order:
+                    //int cbBuffer;
+                    //int BufferType;
+                    //pvBuffer;
+                    //Now iterate over the individual buffers and put them together into a
+                    //byte array...
+                    int CurrentOffset = Index * Marshal.SizeOf(typeof(SecBuffer));
+                    int BytesToCopy = Marshal.ReadInt32(pBuffers, CurrentOffset);
+                    int length = CurrentOffset + Marshal.SizeOf(typeof(int)) + Marshal.SizeOf(typeof(int));
+                    IntPtr SecBufferpvBuffer = Marshal.ReadIntPtr(pBuffers, length);
+                    Marshal.Copy(SecBufferpvBuffer, Buffer, BufferIndex, BytesToCopy);
+                    BufferIndex += BytesToCopy;
+                }
+            }
+
+            return (Buffer);
+        }
+    }
+
+
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct SECURITY_INTEGER
+    {
+        public uint LowPart;
+        public int HighPart;
+        public SECURITY_INTEGER(int dummy)
+        {
+            LowPart = 0;
+            HighPart = 0;
+        }
+    };
+
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct SECURITY_HANDLE
+    {
+        public uint LowPart;
+        public uint HighPart;
+        public SECURITY_HANDLE(int dummy)
+        {
+            LowPart = HighPart = 0;
+        }
+    };
+
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct SecPkgContext_Sizes
+    {
+        public uint cbMaxToken;
+        public uint cbMaxSignature;
+        public uint cbBlockSize;
+        public uint cbSecurityTrailer;
+    };
+
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct SEC_WINNT_AUTH_IDENTITY
+    {
+        public string User;
+        public int UserLength;
+        public string Domain;
+        public int DomainLength;
+        public string Password;
+        public int PasswordLength;
+        public int Flags;
+    }
+
+    internal class SSPIHelper
+    {
+        public const int TOKEN_QUERY = 0x00008;
+        public const uint SEC_E_OK = 0;
+        public const uint SEC_E_INVALID_HANDLE = 0x80090301;
+        public const uint SEC_E_LOGON_DENIED = 0x8009030C;
+        public const uint SEC_I_CONTINUE_NEEDED = 0x90312;
+        public const uint SEC_I_COMPLETE_NEEDED = 0x90313;
+        public const uint SEC_I_COMPLETE_AND_CONTINUE = 0x90314;
+
+        public const uint SECQOP_WRAP_NO_ENCRYPT = 0x80000001;
+
+        const int SECPKG_CRED_OUTBOUND = 2;
+        private const int SECURITY_NETWORK_DREP = 0x0;
+        const int MAX_TOKEN_SIZE = 12288;
+        //For AcquireCredentialsHandle in 3er Parameter "fCredentialUse"
+
+        SECURITY_HANDLE _hOutboundCred = new SECURITY_HANDLE(0);
+        public SECURITY_HANDLE _hClientContext = new SECURITY_HANDLE(0);
+
+        public const int ISC_REQ_DELEGATE = 0x00000001;
+        public const int ISC_REQ_MUTUAL_AUTH = 0x00000002;
+        public const int ISC_REQ_REPLAY_DETECT = 0x00000004;
+        public const int ISC_REQ_SEQUENCE_DETECT = 0x00000008;
+        public const int ISC_REQ_CONFIDENTIALITY = 0x00000010;
+        public const int ISC_REQ_USE_SESSION_KEY = 0x00000020;
+        public const int ISC_REQ_PROMPT_FOR_CREDS = 0x00000040;
+        public const int ISC_REQ_USE_SUPPLIED_CREDS = 0x00000080;
+        public const int ISC_REQ_ALLOCATE_MEMORY = 0x00000100;
+        public const int ISC_REQ_USE_DCE_STYLE = 0x00000200;
+        public const int ISC_REQ_DATAGRAM = 0x00000400;
+        public const int ISC_REQ_CONNECTION = 0x00000800;
+        public const int ISC_REQ_CALL_LEVEL = 0x00001000;
+        public const int ISC_REQ_FRAGMENT_SUPPLIED = 0x00002000;
+        public const int ISC_REQ_EXTENDED_ERROR = 0x00004000;
+        public const int ISC_REQ_STREAM = 0x00008000;
+        public const int ISC_REQ_INTEGRITY = 0x00010000;
+        public const int ISC_REQ_IDENTIFY = 0x00020000;
+        public const int ISC_REQ_NULL_SESSION = 0x00040000;
+        public const int ISC_REQ_MANUAL_CRED_VALIDATION = 0x00080000;
+        public const int ISC_REQ_RESERVED1 = 0x00100000;
+        public const int ISC_REQ_FRAGMENT_TO_FIT = 0x00200000;
+
+        public const int SECPKG_ATTR_SIZES = 0;
+
+        public const int STANDARD_CONTEXT_ATTRIBUTES = ISC_REQ_MUTUAL_AUTH;
+
+        bool _bGotClientCredentials = false;
+
+        [DllImport("secur32", CharSet = CharSet.Auto)]
+        static extern uint AcquireCredentialsHandle(
+            string pszPrincipal, //SEC_CHAR*
+            string pszPackage, //SEC_CHAR* //"Kerberos","NTLM","Negotiative"
+            int fCredentialUse,
+            IntPtr PAuthenticationID,//_LUID AuthenticationID,//pvLogonID, //PLUID
+            ref SEC_WINNT_AUTH_IDENTITY pAuthData,//PVOID
+            int pGetKeyFn, //SEC_GET_KEY_FN
+            IntPtr pvGetKeyArgument, //PVOID
+            ref SECURITY_HANDLE phCredential, //SecHandle //PCtxtHandle ref
+            ref SECURITY_INTEGER ptsExpiry); //PTimeStamp //TimeStamp ref
+
+        [DllImport("secur32", CharSet = CharSet.Auto)]
+        static extern uint AcquireCredentialsHandle(
+            string pszPrincipal, //SEC_CHAR*
+            string pszPackage, //SEC_CHAR* //"Kerberos","NTLM","Negotiative"
+            int fCredentialUse,
+            IntPtr PAuthenticationID,//_LUID AuthenticationID,//pvLogonID, //PLUID
+            IntPtr pAuthData,//PVOID
+            int pGetKeyFn, //SEC_GET_KEY_FN
+            IntPtr pvGetKeyArgument, //PVOID
+            ref SECURITY_HANDLE phCredential, //SecHandle //PCtxtHandle ref
+            ref SECURITY_INTEGER ptsExpiry); //PTimeStamp //TimeStamp ref
+
+        [DllImport("secur32", CharSet = CharSet.Auto, SetLastError = true)]
+        static extern uint InitializeSecurityContext(
+            ref SECURITY_HANDLE phCredential,//PCredHandle
+            IntPtr phContext, //PCtxtHandle
+            string pszTargetName,
+            int fContextReq,
+            int Reserved1,
+            int TargetDataRep,
+            IntPtr pInput, //PSecBufferDesc SecBufferDesc
+            int Reserved2,
+            out SECURITY_HANDLE phNewContext, //PCtxtHandle
+            out SecBufferDesc pOutput, //PSecBufferDesc SecBufferDesc
+            out uint pfContextAttr, //managed ulong == 64 bits!!!
+            out SECURITY_INTEGER ptsExpiry); //PTimeStamp
+
+        [DllImport("secur32", CharSet = CharSet.Auto, SetLastError = true)]
+        static extern uint InitializeSecurityContext(
+            ref SECURITY_HANDLE phCredential,//PCredHandle
+            ref SECURITY_HANDLE phContext, //PCtxtHandle
+            string pszTargetName,
+            int fContextReq,
+            int Reserved1,
+            int TargetDataRep,
+            ref SecBufferDesc SecBufferDesc, //PSecBufferDesc SecBufferDesc
+            int Reserved2,
+            out SECURITY_HANDLE phNewContext, //PCtxtHandle
+            out SecBufferDesc pOutput, //PSecBufferDesc SecBufferDesc
+            out uint pfContextAttr, //managed ulong == 64 bits!!!
+            out SECURITY_INTEGER ptsExpiry); //PTimeStamp
+
+        /*
+        [DllImport("secur32.Dll", CharSet = CharSet.Auto, SetLastError = false)]
+        static extern int AcceptSecurityContext(ref SECURITY_HANDLE phCredential,
+                                                IntPtr phContext,
+                                                ref SecBufferDesc pInput,
+                                                uint fContextReq,
+                                                uint TargetDataRep,
+                                                out SECURITY_HANDLE phNewContext,
+                                                out SecBufferDesc pOutput,
+                                                out uint pfContextAttr,    //managed ulong == 64 bits!!!
+                                                out SECURITY_INTEGER ptsTimeStamp);
+
+        [DllImport("secur32.Dll", CharSet = CharSet.Auto, SetLastError = false)]
+        static extern int AcceptSecurityContext(ref SECURITY_HANDLE phCredential,
+                                                ref SECURITY_HANDLE phContext,
+                                                ref SecBufferDesc pInput,
+                                                uint fContextReq,
+                                                uint TargetDataRep,
+                                                out SECURITY_HANDLE phNewContext,
+                                                out SecBufferDesc pOutput,
+                                                out uint pfContextAttr,    //managed ulong == 64 bits!!!
+                                                out SECURITY_INTEGER ptsTimeStamp);
+        */
+
+        [DllImport("secur32.Dll", CharSet = CharSet.Auto, SetLastError = false)]
+        public static extern int ImpersonateSecurityContext(ref SECURITY_HANDLE phContext);
+
+        [DllImport("secur32.Dll", CharSet = CharSet.Auto, SetLastError = false)]
+        public static extern int QueryContextAttributes(ref SECURITY_HANDLE phContext,
+                                                        uint ulAttribute,
+                                                        out SecPkgContext_Sizes pContextAttributes);
+
+        [DllImport("secur32.Dll", CharSet = CharSet.Auto, SetLastError = false)]
+        public static extern int EncryptMessage(ref SECURITY_HANDLE phContext,
+                                                uint fQOP,        //managed ulong == 64 bits!!!
+                                                ref SecBufferDesc pMessage,
+                                                uint MessageSeqNo);    //managed ulong == 64 bits!!!
+
+        [DllImport("secur32.Dll", CharSet = CharSet.Auto, SetLastError = false)]
+        public static extern int DecryptMessage(ref SECURITY_HANDLE phContext,
+                                                 ref SecBufferDesc pMessage,
+                                                 uint MessageSeqNo,
+                                                 out uint pfQOP);
+
+        [DllImport("secur32.Dll", CharSet = CharSet.Auto, SetLastError = false)]
+        public static extern int MakeSignature(ref SECURITY_HANDLE phContext,          // Context to use
+                                                uint fQOP,         // Quality of Protection
+                                                ref SecBufferDesc pMessage,        // Message to sign
+                                                uint MessageSeqNo);      // Message Sequence Num.
+
+        [DllImport("secur32.Dll", CharSet = CharSet.Auto, SetLastError = false)]
+        public static extern int VerifySignature(ref SECURITY_HANDLE phContext,          // Context to use
+                                                ref SecBufferDesc pMessage,        // Message to sign
+                                                uint MessageSeqNo,            // Message Sequence Num.
+                                                out uint pfQOP);      // Quality of Protection
+
+
+        readonly string _sAccountName = WindowsIdentity.GetCurrent().Name;
+
+        public SSPIHelper()
+        {
+
+        }
+
+        public SSPIHelper(string sRemotePrincipal)
+        {
+            _sAccountName = sRemotePrincipal;
+        }
+
+        private string sUsername;
+        public string Username
+        {
+            set { sUsername = value; }
+            get { return sUsername; }
+        }
+        private string sDomain;
+        public string Domain
+        {
+            set { sDomain = value; }
+            get { return sDomain; }
+        }
+        private string sPassword;
+        public string Password
+        {
+            set { sPassword = value; }
+            get { return sPassword; }
+        }
+
+        private bool bUseWindowsCreds = false;
+        public bool UseWindowsCreds
+        {
+            set { bUseWindowsCreds = value; }
+            get { return bUseWindowsCreds; }
+        }
+
+        public void ExecuteKerberos(byte[] inToken, out byte[] outToken)
+        {
+            if (InitializeKerberosStage)
+            {
+                InitializeClient(inToken, out outToken);
+            }
+            else
+            {
+                if (inToken == null)
+                {
+                    throw new Exception("Kerberos failure: Incoming bytes can't be null.");
+                }
+
+                DecryptMessage(0, inToken, out outToken);
+
+                inToken = new byte[] { 0x01, 0x00, 0x00, 0x00 };
+                EncryptMessage(inToken, out outToken);
+            }
+        }
+
+        private void InitializeClient(byte[] serverToken, out byte[] clientToken)
+        {
+            clientToken = null;
+
+            SECURITY_INTEGER ClientLifeTime = new SECURITY_INTEGER(0);
+
+            if (!_bGotClientCredentials)
+            {
+                uint returnValue;
+
+                if (!UseWindowsCreds)
+                {
+                    SEC_WINNT_AUTH_IDENTITY ident = new SEC_WINNT_AUTH_IDENTITY();
+                    ident.User = Username;
+                    ident.UserLength = ident.User.Length;
+                    ident.Domain = Domain;
+                    ident.DomainLength = ident.Domain.Length;
+                    ident.Password = Password;
+                    ident.PasswordLength = ident.Password.Length;
+                    ident.Flags = 0x1;
+
+                    returnValue = AcquireCredentialsHandle(null, "Kerberos", SECPKG_CRED_OUTBOUND,
+                                                               IntPtr.Zero, ref ident, 0, IntPtr.Zero,
+                                                               ref _hOutboundCred, ref ClientLifeTime);
+                }
+                else
+                {
+                    returnValue = AcquireCredentialsHandle(null, "Kerberos", SECPKG_CRED_OUTBOUND,
+                                                           HANDLE.Zero, HANDLE.Zero, 0, HANDLE.Zero,
+                                                           ref _hOutboundCred, ref ClientLifeTime);
+                }
+
+                if (returnValue != SEC_E_OK)
+                {
+                    throw new Exception("Couldn't acquire client credentials");
+                }
+
+                _bGotClientCredentials = true;
+            }
+
+            uint ss;
+
+            SecBufferDesc ClientToken = new SecBufferDesc(MAX_TOKEN_SIZE);
+
+            try
+            {
+                uint ContextAttributes;
+
+                if (serverToken == null)
+                {
+                    ss = InitializeSecurityContext(ref _hOutboundCred,
+                        IntPtr.Zero,
+                        _sAccountName,// null string pszTargetName,
+                        STANDARD_CONTEXT_ATTRIBUTES,
+                        0,//int Reserved1,
+                        SECURITY_NETWORK_DREP, //int TargetDataRep
+                        IntPtr.Zero,    //Always zero first time around...
+                        0, //int Reserved2,
+                        out _hClientContext, //pHandle CtxtHandle = SecHandle
+                        out ClientToken,//ref SecBufferDesc pOutput, //PSecBufferDesc
+                        out ContextAttributes,//ref int pfContextAttr,
+                        out ClientLifeTime); //ref IntPtr ptsExpiry ); //PTimeStamp
+
+                }
+                else
+                {
+                    SecBufferDesc ServerToken = new SecBufferDesc(serverToken);
+
+                    try
+                    {
+                        ss = InitializeSecurityContext(ref _hOutboundCred,
+                            ref _hClientContext,
+                            _sAccountName,// null string pszTargetName,
+                            STANDARD_CONTEXT_ATTRIBUTES,
+                            0,//int Reserved1,
+                            SECURITY_NETWORK_DREP,//int TargetDataRep
+                            ref ServerToken,    //Always zero first time around...
+                            0, //int Reserved2,
+                            out _hClientContext, //pHandle CtxtHandle = SecHandle
+                            out ClientToken,//ref SecBufferDesc pOutput, //PSecBufferDesc
+                            out ContextAttributes,//ref int pfContextAttr,
+                            out ClientLifeTime); //ref IntPtr ptsExpiry ); //PTimeStamp
+                    }
+                    finally
+                    {
+                        ServerToken.Dispose();
+                    }
+                }
+
+                if (ss == SEC_E_LOGON_DENIED)
+                {
+                    throw new Exception("Bad username, password or domain.");
+                }
+                else if (ss != SEC_E_OK && ss != SEC_I_CONTINUE_NEEDED)
+                {
+                    throw new Exception("InitializeSecurityContext() failed!!!");
+                }
+
+                clientToken = ClientToken.GetSecBufferByteArray();
+            }
+            finally
+            {
+                ClientToken.Dispose();
+            }
+
+            InitializeKerberosStage = ss != SEC_E_OK;
+        }
+
+        private bool bInitializeKerberosStage = true;
+        private bool InitializeKerberosStage
+        {
+            get { return bInitializeKerberosStage; }
+            set { bInitializeKerberosStage = value; }
+        }
+
+        public void EncryptMessage(byte[] message, out byte[] encryptedBuffer)
+        {
+            encryptedBuffer = null;
+
+            SECURITY_HANDLE EncryptionContext = _hClientContext;
+
+            SecPkgContext_Sizes ContextSizes;
+
+            if (QueryContextAttributes(ref EncryptionContext,
+                   SECPKG_ATTR_SIZES, out ContextSizes) != SEC_E_OK)
+            {
+                throw new Exception("QueryContextAttribute() failed!!!");
+            }
+
+            MultipleSecBufferHelper[] ThisSecHelper = new MultipleSecBufferHelper[]
+                    {
+                        new MultipleSecBufferHelper(new byte[ContextSizes.cbSecurityTrailer],
+                                                    SecBufferType.SECBUFFER_TOKEN),
+                        new MultipleSecBufferHelper(message, SecBufferType.SECBUFFER_DATA),
+                        new MultipleSecBufferHelper(new byte[ContextSizes.cbBlockSize],
+                                                    SecBufferType.SECBUFFER_PADDING)
+                    };
+
+            SecBufferDesc DescBuffer = new SecBufferDesc(ThisSecHelper);
+
+            try
+            {
+                if (EncryptMessage(ref EncryptionContext,
+                        SECQOP_WRAP_NO_ENCRYPT, ref DescBuffer, 0) != SEC_E_OK)
+                {
+                    throw new Exception("EncryptMessage() failed!!!");
+                }
+
+                encryptedBuffer = DescBuffer.GetSecBufferByteArray();
+            }
+            finally
+            {
+                DescBuffer.Dispose();
+            }
+        }
+
+        public void DecryptMessage(int messageLength, byte[] encryptedBuffer, out byte[] decryptedBuffer)
+        {
+            decryptedBuffer = null;
+
+            SECURITY_HANDLE DecryptionContext = _hClientContext;
+
+            byte[] EncryptedMessage = new byte[messageLength];
+            Array.Copy(encryptedBuffer, 0, EncryptedMessage, 0, messageLength);
+
+            int SecurityTrailerLength = encryptedBuffer.Length - messageLength;
+
+            byte[] SecurityTrailer = new byte[SecurityTrailerLength];
+            Array.Copy(encryptedBuffer, messageLength, SecurityTrailer, 0, SecurityTrailerLength);
+
+            MultipleSecBufferHelper[] ThisSecHelper = new MultipleSecBufferHelper[]
+                    {
+                        new MultipleSecBufferHelper(EncryptedMessage, SecBufferType.SECBUFFER_DATA),
+                        new MultipleSecBufferHelper(SecurityTrailer, SecBufferType.SECBUFFER_STREAM)
+                    };
+
+            SecBufferDesc DescBuffer = new SecBufferDesc(ThisSecHelper);
+            try
+            {
+                uint EncryptionQuality;
+
+                if (DecryptMessage(ref DecryptionContext, ref DescBuffer, 0, out EncryptionQuality) != SEC_E_OK)
+                {
+                    throw new Exception("DecryptMessage() failed!!!");
+                }
+
+                decryptedBuffer = new byte[messageLength];
+                Array.Copy(DescBuffer.GetSecBufferByteArray(), 0, decryptedBuffer, 0, messageLength);
+            }
+            finally
+            {
+                DescBuffer.Dispose();
+            }
+        }
+    }
+}
+
+
diff --git a/lib/jabber-net/jabber/connection/sasl/MD5Processor.cs b/lib/jabber-net/jabber/connection/sasl/MD5Processor.cs
new file mode 100644
index 0000000..7afa5d7
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/sasl/MD5Processor.cs
@@ -0,0 +1,339 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Diagnostics;
+using System.Collections;
+using System.Security.Cryptography;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.IO;
+using System.Xml;
+
+using bedrock.util;
+using jabber.protocol.stream;
+
+namespace jabber.connection.sasl
+{
+    /// <summary>
+    /// RFC2831 DIGEST-MD5 SASL mechanism
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class MD5Processor : SASLProcessor
+    {
+        /// <summary>
+        /// Private members
+        /// </summary>
+        private string  m_response;
+        private string  m_realm;
+        private string  m_username;
+        private string  m_password;
+        private string  m_nonce;
+        private string  m_cnonce;
+        private int     m_nc;
+        private string  m_ncString;
+        private string  m_qop;
+        private string  m_charset;
+        private string  m_authzid;
+
+        private readonly MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider();
+        private readonly Regex CSV = new Regex(@"(?<tag>[^= \t\r\n]+)=(?:(?<data>[^,"" \t\r\n]+)|(?:""(?<data>[^""]*)"")),?",
+                RegexOptions.ExplicitCapture);
+
+        /// <summary>
+        /// DIGEST-MD5 Realm
+        /// </summary>
+        public const string REALM = "realm";
+        /// <summary>
+        /// DIGEST-MD5 nonce
+        /// </summary>
+        public const string NONCE = "nonce";
+        /// <summary>
+        /// DIGEST-MD5 qop
+        /// </summary>
+        public const string QOP = "qop";
+        /// <summary>
+        /// DIGEST-MD5 charset
+        /// </summary>
+        public const string CHARSET = "charset";
+        /// <summary>
+        /// DIGEST-MD5 algorithm
+        /// </summary>
+        public const string ALGORITHM = "algorithm";
+        /// <summary>
+        /// DIGEST-MD5 authorization id
+        /// </summary>
+        public const string AUTHZID = "authzid";
+
+        /// <summary>
+        /// The directives that are required to be set on the SASLProcessor in OnSASLStart
+        /// </summary>
+        public static readonly string[] s_requiredDirectives = {USERNAME, PASSWORD};
+
+        private static readonly Encoding ENC = System.Text.Encoding.UTF8;
+
+        /// <summary>
+        ///
+        /// </summary>
+        public MD5Processor() : base()
+        {
+            m_nc = 0;
+        }
+
+        /// <summary>
+        /// Process the next DIGEST-MD5 step.
+        /// </summary>
+        /// <param name="s">The previous step.  Null for the first step</param>
+        /// <param name="doc">Document to create next step in.</param>
+        /// <returns></returns>
+        /// <exception cref="AuthenticationFailedException">Thrown if authentication fails</exception>
+        public override Step step(Step s, XmlDocument doc)
+        {
+            Step resp = null;
+
+            if (s == null)
+            { // first step
+                Auth a = new Auth(doc);
+                a.Mechanism = MechanismType.DIGEST_MD5;
+                return a;
+            }
+
+            Debug.Assert(s is Challenge);
+            populateDirectives(ENC.GetString(s.Bytes));
+            validateStartDirectives();
+
+
+            resp = new Response(doc);
+            if (this["rspauth"] == null)  // we haven't authenticated yet
+            {
+                generateResponseString();
+                resp.Bytes = generateResponse();
+            }
+            else // we have authenticated
+            {
+                // make sure what is in rspauth is correct
+                if (!validateResponseAuth())
+                {
+                    throw new AuthenticationFailedException();
+                }
+            }
+            return resp;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="decoded"></param>
+        private void populateDirectives(string decoded)
+        {
+            MatchCollection coll = CSV.Matches(decoded);
+            foreach (Match m in coll)
+            {
+                this[m.Groups["tag"].Value] = m.Groups["data"].Value;
+            }
+        }
+
+
+        /// <summary>
+        ///
+        /// </summary>
+        ///
+        private void validateStartDirectives()
+        {
+            Object n;
+            string temp;
+            if ( (n = this[USERNAME]) != null)
+            {
+                temp = n.ToString();
+                m_username = ENC.GetString(ENC.GetBytes(temp));
+            }
+            else
+            {
+                throw new MissingDirectiveException("Missing SASL username directive");
+            }
+            if ( (n = this[PASSWORD]) != null)
+            {
+                temp = n.ToString();
+                m_password = ENC.GetString(ENC.GetBytes(temp));
+            }
+            else
+            {
+                throw new MissingDirectiveException("Missing SASL password directive");
+            }
+
+            if ( (n = this[REALM]) != null)
+            {
+                m_realm = n.ToString();
+            }
+            else
+            {
+                throw new InvalidServerChallengeException("Missing SASL realm");
+            }
+            if ( (n = this[NONCE]) != null)
+            {
+                m_nonce = n.ToString();
+            }
+            else
+            {
+                throw new InvalidServerChallengeException("Missing nonce directive");
+            }
+            if ( (n = this[QOP]) != null)
+            {
+                m_qop = n.ToString();
+            }
+            else
+            {
+                throw new InvalidServerChallengeException("Missing qop directive");
+            }
+            if ( (n = this[CHARSET]) != null)
+            {
+                m_charset = n.ToString();
+            }
+            if ( (n = this[AUTHZID]) != null)
+            {
+                m_authzid = n.ToString();
+            }
+        }
+
+        /// <summary>
+        /// Generates the entrire response to send to the server
+        /// </summary>
+        /// <returns></returns>
+        private byte[] generateResponse()
+        {
+            StringBuilder sb = new StringBuilder();
+            sb.Append("username=\"");
+            sb.Append(m_username);
+            sb.Append("\",");
+            sb.Append("realm=\"");
+            sb.Append(m_realm);
+            sb.Append("\",");
+            sb.Append("nonce=\"");
+            sb.Append(m_nonce);
+            sb.Append("\",");
+            sb.Append("cnonce=\"");
+            sb.Append(m_cnonce);
+            sb.Append("\",");
+            sb.Append("nc=");
+            sb.Append(m_ncString);
+            sb.Append(",");
+            sb.Append("qop=");
+            sb.Append(m_qop);
+            sb.Append(",");
+            sb.Append("digest-uri=\"");
+            sb.Append("xmpp/");
+            sb.Append(m_realm);
+            sb.Append("\",");
+            sb.Append("response=");
+            sb.Append(m_response);
+            sb.Append(",");
+            sb.Append("charset=");
+            sb.Append(m_charset);
+            return ENC.GetBytes(sb.ToString());
+        }
+        /// <summary>
+        /// Generates the MD5 hash that goes in the response attribute of the
+        /// response sent to the server.
+        /// </summary>
+        private void generateResponseString()
+        {
+            // here is where we do the md5 foo
+            ASCIIEncoding AE = new ASCIIEncoding();
+            byte[] H1, H2, H3, temp;
+            string A1, A2, A3, uri, p1, p2;
+
+            uri = "xmpp/" + m_realm;
+            Random r = new Random();
+            int v = r.Next(1024);
+
+            StringBuilder sb = new StringBuilder();
+            sb.Append(v.ToString());
+            sb.Append(":");
+            sb.Append(m_username);
+            sb.Append(":");
+            sb.Append(m_password);
+
+            m_cnonce = HexString(AE.GetBytes(sb.ToString())).ToLower();
+
+            m_nc++;
+            m_ncString = m_nc.ToString().PadLeft(8,'0');
+
+            sb.Remove(0,sb.Length);
+            sb.Append(m_username);
+            sb.Append(":");
+            sb.Append(m_realm);
+            sb.Append(":");
+            sb.Append(m_password);
+            H1 = MD5.ComputeHash(AE.GetBytes(sb.ToString()));
+
+            sb.Remove(0, sb.Length);
+            sb.Append(":");
+            sb.Append(m_nonce);
+            sb.Append(":");
+            sb.Append(m_cnonce);
+
+            if (m_authzid != null)
+            {
+                sb.Append(":");
+                sb.Append(m_authzid);
+            }
+            A1 = sb.ToString();
+
+            MemoryStream ms = new MemoryStream();
+            ms.Write(H1,0,16);
+            temp = AE.GetBytes(A1);
+            ms.Write(temp,0,temp.Length);
+            ms.Seek(0,System.IO.SeekOrigin.Begin);
+            H1 = MD5.ComputeHash(ms);
+
+            sb.Remove(0,sb.Length);
+            sb.Append("AUTHENTICATE:");
+            sb.Append(uri);
+            if (m_qop.CompareTo("auth") != 0)
+            {
+                sb.Append(":00000000000000000000000000000000");
+            }
+            A2 = sb.ToString();
+            H2 = AE.GetBytes(A2);
+            H2 = MD5.ComputeHash(H2);
+
+            // create p1 and p2 as the hex representation of H1 and H2
+            p1 = HexString(H1).ToLower();
+            p2 = HexString(H2).ToLower();
+
+            sb.Remove(0, sb.Length);
+            sb.Append(p1);
+            sb.Append(":");
+            sb.Append(m_nonce);
+            sb.Append(":");
+            sb.Append(m_ncString);
+            sb.Append(":");
+            sb.Append(m_cnonce);
+            sb.Append(":");
+            sb.Append(m_qop);
+            sb.Append(":");
+            sb.Append(p2);
+
+            A3 = sb.ToString();
+            H3 = MD5.ComputeHash(AE.GetBytes(A3));
+            m_response = HexString(H3).ToLower();
+        }
+
+        private bool validateResponseAuth()
+        {
+            //TODO:  We need to validate the respauth's value by going through the responseString
+            //function again
+            return true;
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/connection/sasl/PlainProcessor.cs b/lib/jabber-net/jabber/connection/sasl/PlainProcessor.cs
new file mode 100644
index 0000000..c5ca385
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/sasl/PlainProcessor.cs
@@ -0,0 +1,63 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.IO;
+using System.Diagnostics;
+using System.Xml;
+
+using bedrock.util;
+using jabber.protocol.stream;
+
+namespace jabber.connection.sasl
+{
+    /// <summary>
+    /// SASL Mechanism PLAIN as specified in RFC 2595.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PlainProcessor : SASLProcessor
+    {
+        /// <summary>
+        /// Perform the next step
+        /// </summary>
+        /// <param name="s">Null if it's the initial response</param>
+        /// <param name="doc">Document to create Steps in</param>
+        /// <returns></returns>
+        public override Step step(Step s, XmlDocument doc)
+        {
+            Debug.Assert(s == null);
+            Auth a = new Auth(doc);
+            a.Mechanism = MechanismType.PLAIN;
+            MemoryStream ms = new MemoryStream();
+
+            // message = [authorize-id] NUL authenticate-id NUL password
+
+            // Skip authzid.
+            ms.WriteByte(0);
+            string u = this[USERNAME];
+            if ((u == null) || (u == ""))
+                throw new SASLException("Username required");
+            byte[] bu = System.Text.Encoding.UTF8.GetBytes(u);
+            ms.Write(bu, 0, bu.Length);
+            ms.WriteByte(0);
+            string p = this[PASSWORD];
+            if ((p == null) || (p == ""))
+                throw new SASLException("Password required");
+            byte[] pu = System.Text.Encoding.UTF8.GetBytes(p);
+            ms.Write(pu, 0, pu.Length);
+
+            a.Bytes = ms.ToArray();
+            return a;
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/connection/sasl/SASLProcessor.cs b/lib/jabber-net/jabber/connection/sasl/SASLProcessor.cs
new file mode 100644
index 0000000..2cbf5a6
--- /dev/null
+++ b/lib/jabber-net/jabber/connection/sasl/SASLProcessor.cs
@@ -0,0 +1,191 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Collections;
+using System.Xml;
+using System.Text;
+
+using bedrock.util;
+using jabber.protocol.stream;
+
+namespace jabber.connection.sasl
+{
+    /// <summary>
+    /// A SASL processor instance has been created.  Fill it with information, like USERNAME and PASSWORD.
+    /// </summary>
+    public delegate void SASLProcessorHandler(Object sender, SASLProcessor proc);
+
+    /// <summary>
+    /// Some sort of SASL error
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class SASLException : ApplicationException
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="message"></param>
+        public SASLException(string message) : base(message){}
+
+        /// <summary>
+        ///
+        /// </summary>
+        public SASLException() : base(){}
+    }
+
+    /// <summary>
+    /// Authentication failed.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class AuthenticationFailedException : SASLException
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        public AuthenticationFailedException() : base()
+        {}
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="message"></param>
+        public AuthenticationFailedException(string message) : base(message)
+        {}
+    }
+
+    /// <summary>
+    /// A required directive wasn't supplied.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class MissingDirectiveException : SASLException
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="message"></param>
+        public MissingDirectiveException(string message) : base(message)
+        {}
+    }
+
+    /// <summary>
+    /// Server sent an invalid challenge
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class InvalidServerChallengeException : SASLException
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="message"></param>
+        public InvalidServerChallengeException(string message) : base(message)
+        {}
+    }
+    /// <summary>
+    /// Summary description for SASLProcessor.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public abstract class SASLProcessor
+    {
+        /// <summary>
+        /// SASL username
+        /// </summary>
+        public const string USERNAME = "username";
+        /// <summary>
+        /// SASL password
+        /// </summary>
+        public const string PASSWORD = "password";
+
+
+        /// <summary>
+        ///
+        /// </summary>
+        private Hashtable m_directives = new Hashtable();
+
+        /// <summary>
+        ///
+        /// </summary>
+        public SASLProcessor()
+        {
+        }
+
+        /// <summary>
+        /// Create a new SASLProcessor, of the best type possible
+        /// </summary>
+        /// <param name="mt">The types the server implements</param>
+        /// <param name="plaintextOK">Is it ok to select insecure types?</param>
+        /// <param name="mechs">The mechanisms supported by the server</param>
+        /// <returns></returns>
+        public static SASLProcessor createProcessor(MechanismType mt, bool plaintextOK, Mechanisms mechs)
+        {
+            if ((mt & MechanismType.EXTERNAL) == MechanismType.EXTERNAL)
+            {
+                return new ExternalProcessor();
+            }
+            if ((mt & MechanismType.GSSAPI) == MechanismType.GSSAPI)
+            {
+                string RemotePrincipal = "";
+                foreach (Mechanism mechanism in mechs.GetMechanisms())
+                {
+                    if (mechanism.MechanismName == "GSSAPI")
+                    {
+                        RemotePrincipal = mechanism.GetAttribute("kerb:principal");
+                        break;
+                    }
+                }
+                return new KerbProcessor(RemotePrincipal);
+            }
+            if ((mt & MechanismType.DIGEST_MD5) == MechanismType.DIGEST_MD5)
+            {
+                return new MD5Processor();
+            }
+            else if (plaintextOK && ((mt & MechanismType.PLAIN) == MechanismType.PLAIN))
+            {
+                return new PlainProcessor();
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// Data for performing SASL challenges and responses.
+        /// </summary>
+        public string this[string directive]
+        {
+            get { return (string) m_directives[directive]; }
+            set { m_directives[directive] = value; }
+        }
+
+        /// <summary>
+        /// Perform the next step
+        /// </summary>
+        /// <param name="s">Null if it's the initial response</param>
+        /// <param name="doc">Document to create Steps in</param>
+        /// <returns></returns>
+        public abstract Step step(Step s, XmlDocument doc);
+
+        /// <summary>
+        /// byte array as a hex string, two chars per byte.
+        /// </summary>
+        /// <param name="buf">Byte array</param>
+        /// <returns></returns>
+        protected static string HexString(byte[] buf)
+        {
+            StringBuilder sb = new StringBuilder();
+            foreach (byte b in buf)
+            {
+                sb.Append(b.ToString("x2"));
+            }
+            return sb.ToString();
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/AsynchElementStream.cs b/lib/jabber-net/jabber/protocol/AsynchElementStream.cs
new file mode 100644
index 0000000..b1d9575
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/AsynchElementStream.cs
@@ -0,0 +1,398 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Collections;
+using System.Diagnostics;
+using System.Xml;
+
+using xpnet;
+
+using bedrock.io;
+using bedrock.util;
+
+namespace jabber.protocol
+{
+    /// <summary>
+    /// Summary description for AsynchElementStream.
+    /// TODO: combine with ElementStream, since there's only one impl now.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class AsynchElementStream : ElementStream
+    {
+        private static System.Text.Encoding utf = System.Text.Encoding.UTF8;
+
+        private BufferAggregate m_buf   = new BufferAggregate();
+        private Encoding m_enc   = new UTF8Encoding();
+        private NS m_ns    = new NS();
+        private XmlElement m_elem  = null;
+        private XmlElement m_root  = null;
+        private bool m_cdata = false;
+
+        /// <summary>
+        /// Create an instance.
+        /// </summary>
+        public AsynchElementStream()
+        {
+        }
+
+        /// <summary>
+        /// Put bytes into parser.  Used by test routines, only, for convenience.
+        /// </summary>
+        /// <param name="buf"></param>
+        public void Push(byte[] buf)
+        {
+            Push(buf, 0, buf.Length);
+        }
+
+        /// <summary>
+        /// Put bytes into the parser.
+        /// </summary>
+        /// <param name="buf">The bytes to put into the parse stream</param>
+        /// <param name="offset">Offset into buf to start at</param>
+        /// <param name="length">Number of bytes to write</param>
+        public void Push(byte[] buf, int offset, int length)
+        {
+            // or assert, really, but this is a little nicer.
+            if (length == 0)
+                return;
+
+            // No locking is required.  Read() won't get called again
+            // until this method returns.  Keep in mind that we're
+            // already on a thread in a ThreadPool, which is created
+            // and managed by System.IO at the end of the day.
+
+            // TODO: only do this copy if we have a partial token at the
+            // end of parsing.
+            byte[] copy = new byte[length];
+            System.Buffer.BlockCopy(buf, offset, copy, 0, length);
+            m_buf.Write(copy);
+
+            byte[] b = m_buf.GetBuffer();
+            int off = 0;
+            TOK tok = TOK.END_TAG;
+            ContentToken ct = new ContentToken();
+
+            try
+            {
+                while (off < b.Length)
+                {
+
+
+                    if (m_cdata)
+                        tok = m_enc.tokenizeCdataSection(b, off, b.Length, ct);
+                    else
+                        tok = m_enc.tokenizeContent(b, off, b.Length, ct);
+
+                    switch (tok)
+                    {
+                    case TOK.EMPTY_ELEMENT_NO_ATTS:
+                    case TOK.EMPTY_ELEMENT_WITH_ATTS:
+                        StartTag(b, off, ct, tok);
+                        EndTag(b, off, ct, tok);
+                        break;
+                    case TOK.START_TAG_NO_ATTS:
+                    case TOK.START_TAG_WITH_ATTS:
+                        StartTag(b, off, ct, tok);
+                        break;
+                    case TOK.END_TAG:
+                        EndTag(b, off, ct, tok);
+                        break;
+                    case TOK.DATA_CHARS:
+                    case TOK.DATA_NEWLINE:
+                        AddText(utf.GetString(b, off, ct.TokenEnd - off));
+                        break;
+                    case TOK.CHAR_REF:
+                    case TOK.MAGIC_ENTITY_REF:
+                        AddText(new string(new char[] { ct.RefChar1 }));
+                        break;
+                    case TOK.CHAR_PAIR_REF:
+                        AddText(new string(new char[] {ct.RefChar1,
+                                                              ct.RefChar2}));
+                        break;
+                    case TOK.COMMENT:
+                        if (m_elem != null)
+                        {
+                            // <!-- 4
+                            //  --> 3
+                            int start = off + 4*m_enc.MinBytesPerChar;
+                            int end = ct.TokenEnd - off -
+                                    7*m_enc.MinBytesPerChar;
+                            string text = utf.GetString(b, start, end);
+                            m_elem.AppendChild(m_doc.CreateComment(text));
+                        }
+                        break;
+                    case TOK.CDATA_SECT_OPEN:
+                        m_cdata = true;
+                        break;
+                    case TOK.CDATA_SECT_CLOSE:
+                        m_cdata = false;
+                        break;
+                    case TOK.XML_DECL:
+                        // thou shalt use UTF8, and XML version 1.
+                        // i shall ignore evidence to the contrary...
+
+                        // TODO: Throw an exception if these assuptions are
+                        // wrong
+                        break;
+                    case TOK.ENTITY_REF:
+                    case TOK.PI:
+                        throw new System.NotImplementedException("Token type not implemented: " + tok);
+                    }
+                    off = ct.TokenEnd;
+                    ct.clearAttributes();
+                }
+            }
+            catch (PartialTokenException)
+            {
+                // Console.WriteLine("PartialTokenException: " + System.Text.Encoding.UTF8.GetString(copy));
+                // ignored;
+            }
+            catch (ExtensibleTokenException)
+            {
+                // ignored;
+            }
+            catch (xpnet.InvalidTokenException e)
+            {
+                throw new XMLParseException(e, this, buf, offset, length);
+            }
+            catch (Exception e)
+            {
+                throw new Exception("Unexpected exception", e);
+            }
+            finally
+            {
+                m_buf.Clear(off);
+                ct.clearAttributes();
+            }
+        }
+
+        private void StartTag(byte[] buf, int offset,
+                              ContentToken ct, TOK tok)
+        {
+            int colon;
+            string name;
+            string prefix;
+            Hashtable ht = new Hashtable();
+
+            m_ns.PushScope();
+
+            // if i have attributes
+            if ((tok == TOK.START_TAG_WITH_ATTS) ||
+                (tok == TOK.EMPTY_ELEMENT_WITH_ATTS))
+            {
+                int start;
+                int end;
+                string val;
+                for (int i=0; i<ct.getAttributeSpecifiedCount(); i++)
+                {
+                    start = ct.getAttributeNameStart(i);
+                    end = ct.getAttributeNameEnd(i);
+                    name = utf.GetString(buf, start, end - start);
+
+                    start = ct.getAttributeValueStart(i);
+                    end =  ct.getAttributeValueEnd(i);
+                    val = utf.GetString(buf, start, end - start);
+
+                    // <foo b='&'/>
+                    // <foo b='&amp;'
+                    // TODO: if val includes &, it gets double-escaped
+                    if (name.StartsWith("xmlns:"))
+                    {
+                        colon = name.IndexOf(':');
+                        prefix = name.Substring(colon+1);
+                        m_ns.AddNamespace(prefix, val);
+                    }
+                    else if (name == "xmlns")
+                    {
+                        m_ns.AddNamespace(string.Empty, val);
+                    }
+                    ht.Add(name, val);
+                }
+            }
+
+            name = utf.GetString(buf,
+                                 offset + m_enc.MinBytesPerChar,
+                                 ct.NameEnd - offset - m_enc.MinBytesPerChar);
+            colon = name.IndexOf(':');
+            string ns = "";
+            prefix = "";
+            if (colon > 0)
+            {
+                prefix = name.Substring(0, colon);
+                name = name.Substring(colon + 1);
+                ns = m_ns.LookupNamespace(prefix);
+            }
+            else
+            {
+                ns = m_ns.DefaultNamespace;
+            }
+
+            XmlQualifiedName q = new XmlQualifiedName(name, ns);
+            XmlElement elem = m_factory.GetElement(prefix, q, m_doc);
+
+
+            foreach (string attrname in ht.Keys)
+            {
+                colon = attrname.IndexOf(':');
+                if (colon > 0)
+                {
+                    prefix = attrname.Substring(0, colon);
+                    name = attrname.Substring(colon+1);
+
+                    XmlAttribute attr = m_doc.CreateAttribute(prefix,
+                                                              name,
+                                                              m_ns.LookupNamespace(prefix));
+                    attr.InnerXml = (string)ht[attrname];
+                    elem.SetAttributeNode(attr);
+                }
+                else
+                {
+                    XmlAttribute attr = m_doc.CreateAttribute(attrname);
+                    attr.InnerXml = (string)ht[attrname];
+                    elem.SetAttributeNode(attr);
+                }
+            }
+
+
+            if (m_root == null)
+            {
+                m_root = elem;
+                FireOnDocumentStart(m_root);
+            }
+            else
+            {
+                if (m_elem != null)
+                    m_elem.AppendChild(elem);
+                m_elem = elem;
+            }
+        }
+
+        private void EndTag(byte[] buf, int offset,
+                            ContentToken ct, TOK tok)
+        {
+            m_ns.PopScope();
+
+            if (m_elem == null)
+            {// end of doc
+                FireOnDocumentEnd();
+                return;
+            }
+
+            string name = null;
+
+            if ((tok == TOK.EMPTY_ELEMENT_WITH_ATTS) ||
+                (tok == TOK.EMPTY_ELEMENT_NO_ATTS))
+                name = utf.GetString(buf,
+                                     offset + m_enc.MinBytesPerChar,
+                                     ct.NameEnd - offset -
+                                     m_enc.MinBytesPerChar);
+            else
+                name = utf.GetString(buf,
+                                     offset + m_enc.MinBytesPerChar*2,
+                                     ct.NameEnd - offset -
+                                     m_enc.MinBytesPerChar*2);
+
+
+            if (m_elem.Name != name)
+                throw new XmlException("Invalid end tag: " + name +
+                                       " != " + m_elem.Name);
+
+            XmlElement parent = (XmlElement)m_elem.ParentNode;
+            if (parent == null)
+            {
+                FireOnElement(m_elem);
+            }
+            m_elem = parent;
+        }
+
+        private void AddText(string text)
+        {
+            if (m_elem != null)
+            {
+                m_elem.AppendChild(m_doc.CreateTextNode(text));
+            }
+        }
+
+        /// <summary>
+        /// There was an error parsing XML.  What was the context?
+        /// </summary>
+        [SVN(@"$Id$")]
+        public class XMLParseException : Exception
+        {
+            private string m_context = null;
+
+            /// <summary>
+            /// Some XML parsing error occurred.  Wrap it, and generate a little more context, so that we can try
+            /// to figure out where the actual error happened.
+            /// </summary>
+            /// <param name="innerException"></param>
+            /// <param name="stream"></param>
+            /// <param name="buf"></param>
+            /// <param name="offset"></param>
+            /// <param name="length"></param>
+            public XMLParseException(Exception innerException, AsynchElementStream stream, byte[] buf, int offset, int length)
+                : base("Parsing exception", innerException)
+            {
+                XmlElement e = stream.m_elem;
+                XmlElement last = null;
+                System.Text.StringBuilder sb = new System.Text.StringBuilder();
+
+                while (e != null)
+                {
+                    last = e;
+                    e = e.ParentNode as XmlElement;
+                }
+
+                if (last != null)
+                {
+                    sb.Append("Outer element: ");
+                    sb.Append(last.OuterXml);
+                    sb.Append("\n");
+                }
+                else
+                {
+                    sb.Append("Root stanza\n");
+                }
+
+                sb.Append("New text (note: it's normal to see what looks like extra close tags here): ");
+                try
+                {
+                    sb.Append(AsynchElementStream.utf.GetString(buf, offset, length));
+                }
+                catch (Exception)
+                {
+                    sb.Append("Error in UTF8 decode: ");
+                    sb.Append(Element.HexString(buf, offset, length));
+                }
+                m_context = sb.ToString();
+            }
+            /// <summary>
+            /// More context of where the error ocurred
+            /// </summary>
+            public string Context
+            {
+                get { return m_context; }
+            }
+
+            /// <summary>
+            /// String representation.
+            /// </summary>
+            /// <returns></returns>
+            public override string ToString()
+            {
+                return base.ToString() + "\n----------\n\nContext:\n" + m_context;
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/Element.cs b/lib/jabber-net/jabber/protocol/Element.cs
new file mode 100644
index 0000000..305bbf0
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/Element.cs
@@ -0,0 +1,958 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Collections;
+using System.Diagnostics;
+using System.Reflection;
+using System.Security.Cryptography;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol
+{
+    /// <summary>
+    /// An enum that should translate "_" into "-" for use externally.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class DashAttribute : Attribute
+    {
+        /// <summary>
+        /// This is just a flag attribute.
+        /// </summary>
+        public DashAttribute()
+        {
+        }
+    }
+
+    /// <summary>
+    /// An XmlElement with type-safe accessors.  This class is not much use by itself,
+    /// but provides a number of utility functions for its descendants.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Element : XmlElement
+    {
+        /// <summary>
+        /// UTF-8 encoding used throughout.
+        /// </summary>
+        protected static readonly Encoding ENCODING = Encoding.UTF8;
+
+        /// <summary>
+        /// Fix up bad namespaces that don't need to be sent on XML streams.
+        /// jabber:client and jabber:component:accept are removed from the root element,
+        /// and empty namespace declarations are removed throughout.
+        /// </summary>
+        private static readonly Regex s_RemoveNS = 
+            new Regex("(?:(?<=^[^>]*)( xmlns=\"(?:jabber:client|jabber:component:accept)\")| xmlns=\"\")",
+                      RegexOptions.Compiled);
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Element(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname.Name, qname.Namespace, doc)
+        {
+        }
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="localName"></param>
+        /// <param name="doc"></param>
+        public Element(string localName, XmlDocument doc) :
+            base("", localName, "", doc)
+        {
+        }
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="localName"></param>
+        /// <param name="namespaceURI"></param>
+        /// <param name="doc"></param>
+        public Element(string localName, string namespaceURI, XmlDocument doc) :
+            base("", localName, namespaceURI, doc)
+        {
+        }
+
+        /// <summary>
+        /// Returns the first child element with the given type.
+        /// 
+        /// You might expect this to be slower than this["name", "uri"], but it's 
+        /// probably actually faster, since that code has to check several different
+        /// things, and this code can just do a type comparison.
+        /// </summary>
+        /// <typeparam name="T">The type of child to search for</typeparam>
+        /// <returns>The first child with the given type, or null if none found</returns>
+        public T GetChildElement<T>()
+            where T : XmlElement
+        {
+            for (XmlNode node = this.FirstChild; node != null; node = node.NextSibling)
+            {
+                if (node is T)
+                    return (T)node;
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// The xml:lang of this element.
+        /// </summary>
+        public string Lang
+        {
+            get
+            {
+                if (!HasAttribute("lang", URI.XML))
+                    return null;
+                return GetAttribute("lang", URI.XML);
+            }
+            set
+            {
+                if (HasAttribute("lang", URI.XML))
+                    RemoveAttribute("lang", URI.XML);
+                if (value != null)
+                {
+                    XmlAttribute attr = OwnerDocument.CreateAttribute("xml:lang", URI.XML);
+                    attr.Value = value;
+                    this.Attributes.Append(attr);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Add a child element.  The element can be from a different document.
+        /// </summary>
+        /// <param name="value"></param>
+        public void AddChild(XmlElement value)
+        {
+            if (this.OwnerDocument == value.OwnerDocument)
+            {
+                this.AppendChild(value);
+            }
+            else
+            {
+                this.AppendChild(this.OwnerDocument.ImportNode(value, true));
+            }
+        }
+
+        /// <summary>
+        /// Get a string representation of this element and its children, with the default
+        /// namespace stripped off if and only if it is jabber:client or jabber:component:accept.
+        /// </summary>
+        public override string OuterXml
+        {
+            get
+            {
+                return s_RemoveNS.Replace(base.OuterXml, "");
+            }
+        }
+
+        /// <summary>
+        /// The implementation of OuterXml from XmlElement, without removing the jabber:client
+        /// namespace.  Needed for Stream.
+        /// </summary>
+        protected string OriginalOuterXml
+        {
+            get { return base.OuterXml; }
+        }
+
+        /// <summary>
+        /// Returns an XmlNodeList containing a list of child elements that match the specified localname and namespace URI.
+        /// </summary>
+        /// <param name="localName"></param>
+        /// <param name="namespaceURI"></param>
+        /// <returns></returns>
+        public override XmlNodeList GetElementsByTagName(string localName, string namespaceURI)
+        {
+            return new ElementList(this, localName, namespaceURI);
+        }
+
+        /// <summary>
+        /// Returns an XmlNodeList containing a list of child elements that match the specified localname.
+        /// </summary>
+        /// <param name="localName"></param>
+        /// <returns></returns>
+        public override XmlNodeList GetElementsByTagName(string localName)
+        {
+            return new ElementList(this, localName);
+        }
+
+        /// <summary>
+        /// Get a list of child elements that have the specified type.
+        /// </summary>
+        /// <typeparam name="T">The type of element to search for</typeparam>
+        /// <returns>A typed element list</returns>
+        public TypedElementList<T> GetElements<T>()
+            where T : XmlElement
+        {
+            return new TypedElementList<T>(this);
+        }
+
+        /// <summary>
+        /// Gett he text contents of the first sub-element with the specified type
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <returns></returns>
+        protected string GetElem<T>()
+            where T : Element
+        {
+            T e = GetChildElement<T>();
+            if (e == null)
+                return null;
+            if (!e.HasChildNodes)
+                return null;
+            return e.InnerText;
+        }
+
+        /// <summary>
+        /// Get the text contents of a sub-element.
+        /// </summary>
+        /// <param name="name"></param>
+        /// <returns></returns>
+        protected string GetElem(string name)
+        {
+            XmlElement e = this[name];
+            if (e == null)
+                return null;
+            if (!e.HasChildNodes)
+                return null;
+            return e.InnerText;
+        }
+
+        /// <summary>
+        /// Sets the text contents of a sub-element with a specified type.
+        /// Creates the element if it doesn't exist.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        public T SetElem<T>(string value)
+            where T : Element
+        {
+            T result = GetOrCreateElement<T>();
+            result.RemoveAll();
+            if (value != null)
+                result.InnerText = value;
+            return result;
+        }
+
+        /// <summary>
+        /// Sets the text contents of a sub-element.
+        /// Note: Do not use this if you want the sub-element to have a type that is not XmlElement.
+        /// Instead use <see cref="SetElem(string,string,Type)"/>
+        /// </summary>
+        /// <param name="name">The element tag.</param>
+        /// <param name="value">The inner text of the element.</param>
+        protected void SetElem(string name, string value)
+        {
+            XmlElement e = GetOrCreateElement(name, null, null);
+            e.RemoveAll();
+
+            if (value != null)
+                e.InnerText = value;
+        }
+
+        /// <summary>
+        /// Sets the text contents of a sub-element.
+        /// </summary>
+        /// <param name="name">The element tag.</param>
+        /// <param name="value">The inner text of the element.</param>
+        /// <param name="typeToCreate">If the element doesn't exist, create it with this type.  If null, then just use an XmlElement.</param>
+        protected void SetElem(string name, string value, Type typeToCreate)
+        {
+            XmlElement e = GetOrCreateElement(name, null, typeToCreate);
+            e.RemoveAll();
+
+            if (value != null)
+                e.InnerText = value;
+        }
+
+        /// <summary>
+        /// Create an element that is a child of this element, of the specified type.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <returns></returns>
+        protected T CreateChildElement<T>()
+            where T : Element
+        {
+            // Note: It would be cool to just do new T(OwnerDocument), but you can only call
+            // parameter-less constructors in generic-land.
+            ConstructorInfo constructor = typeof(T).GetConstructor(new Type[] { typeof(XmlDocument) });
+            Debug.Assert(constructor != null, "Type " + typeof(T).ToString() + " does not have a constructor taking an XmlDocument");
+            T c = (T)constructor.Invoke(new object[] { this.OwnerDocument });
+            AppendChild(c);
+            return c;
+        }
+
+        /// <summary>
+        /// If a child element exists with the given type, return it.  Otherwise,
+        /// gin up a new instance of the given type, add it as a child, 
+        /// and return the result.
+        /// 
+        /// This should not have the performance impact of GetOrCreateElement.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <returns></returns>
+        protected T GetOrCreateElement<T>()
+            where T : Element
+        {
+            T c = GetChildElement<T>();
+            if (c == null)
+                c = CreateChildElement<T>();
+            return c;
+        }
+
+        /// <summary>
+        /// If the named element exists as a child, return it.  Otherwise, gin up
+        /// a new instance of the given class (which must be a subclass of XmlElement)
+        /// add it as a child, and return the result.  Will often be paired with
+        /// ReplaceChild as the setter.
+        /// </summary>
+        /// <remarks>
+        /// This seems kind of around-the-barn.  Wish there was an easier way to do this,
+        /// rather than having to get the constructor, and whatnot.  Hopefully it won't
+        /// be called all that often, so the speed issue won't be too bad.
+        /// </remarks>
+        /// <param name="name"></param>
+        /// <param name="xmlns">Namespace URI.  Null to use parent's.</param>
+        /// <param name="typeToCreate">If the element doesn't exist, create it with this type.  If null, then just use an XmlElement.</param>
+        /// <returns></returns>
+        protected XmlElement GetOrCreateElement(string name, string xmlns, Type typeToCreate)
+        {
+            string ns = (xmlns!=null) ? xmlns : NamespaceURI;
+            XmlElement child = this[name, ns];
+            if (child != null)
+                return child;
+
+            if (typeToCreate == null)
+                child = this.OwnerDocument.CreateElement(name, ns);
+            else
+            {
+                Debug.Assert(typeToCreate.IsSubclassOf(typeof(XmlElement)));
+
+                ConstructorInfo constructor = typeToCreate.GetConstructor(new Type[] { typeof(XmlDocument) });
+                Debug.Assert(constructor != null);
+                child = constructor.Invoke(new object[] { this.OwnerDocument }) as XmlElement;
+                Debug.Assert(child != null);
+            }
+
+            this.AppendChild(child);
+            return child;
+        }
+
+        /// <summary>
+        /// Replaces the first element that has the specified type.
+        /// </summary>
+        /// <typeparam name="T">The type of sub-element to find</typeparam>
+        /// <param name="elem">The element to replace; if this is null, the old element is just deleted</param>
+        /// <returns>The replaced element</returns>
+        protected T ReplaceChild<T>(T elem)
+            where T : Element
+        {
+            T old = GetChildElement<T>();
+            if (old != null)
+                this.RemoveChild(old);
+            if (elem != null)
+                AddChild(elem);
+            return old;
+        }
+
+        /// <summary>
+        /// Replaces the first element that has the same name
+        /// with the passed in element.
+        /// </summary>
+        /// <param name="elem">The new element</param>
+        /// <returns>The replaced element</returns>
+        protected XmlElement ReplaceChild(XmlElement elem)
+        {
+            XmlElement old = this[elem.Name, elem.NamespaceURI];
+            if (old != null)
+            {
+                this.RemoveChild(old);
+            }
+            if (elem != null)
+                AddChild(elem);
+            return old;
+        }
+
+        /// <summary>
+        /// Remove a child element of the specified type
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <returns></returns>
+        protected T RemoveElem<T>()
+            where T : Element
+        {
+            T e = GetChildElement<T>();
+            if (e != null)
+                this.RemoveChild(e);
+            return e;
+        }
+
+        /// <summary>
+        /// Remove a child element
+        /// </summary>
+        /// <param name="name"></param>
+        /// <returns>The old element, or null if it didn't exist.</returns>
+        protected XmlElement RemoveElem(string name)
+        {
+            XmlElement e = this[name];
+            if (e != null)
+                this.RemoveChild(e);
+            return e;
+        }
+
+        /// <summary>
+        /// Remove each of the child elements with the specified type.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        protected void RemoveElems<T>()
+            where T : Element
+        {
+            foreach (T child in GetElements<T>())
+                this.RemoveChild(child);
+        }
+
+        /// <summary>
+        /// Removes all of the matching elements from this element.
+        /// </summary>
+        /// <param name="name">Element local name</param>
+        protected void RemoveElems(string name)
+        {
+            XmlNodeList nl = this.ChildNodes;
+            foreach (XmlNode n in nl)
+            {
+                if (n.NodeType != XmlNodeType.Element)
+                    continue;
+                if (n.Name == name)
+                    this.RemoveChild(n);
+            }
+        }
+        /// <summary>
+        /// Removes all of the matching elements from this element.
+        /// </summary>
+        /// <param name="name">Element local name</param>
+        /// <param name="namespaceURI">Element namespace URI.</param>
+        protected void RemoveElems(string name, string namespaceURI)
+        {
+            XmlNodeList nl = this.ChildNodes;
+            foreach (XmlNode n in nl)
+            {
+                if (n.NodeType != XmlNodeType.Element)
+                    continue;
+                if ((n.Name == name) && (n.NamespaceURI == namespaceURI))
+                    this.RemoveChild(n);
+            }
+        }
+
+        /// <summary>
+        /// I think GetAttribute should return null if the attribute is not found.
+        /// Use carefully, when translating to external semantics.
+        /// </summary>
+        /// <param name="name"></param>
+        protected string GetAttr(string name)
+        {
+            if (!HasAttribute(name))
+                return null;
+            return GetAttribute(name);
+        }
+
+        /// <summary>
+        /// I think calling SetAttr with null or "" should remove the attribute.
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="value"></param>
+        protected void SetAttr(string name, string value)
+        {
+            if ((value == null) || (value == ""))
+                // testing shows this is safe for non-existing attributes.
+                RemoveAttribute(name);
+            else
+                SetAttribute(name, value);
+        }
+
+        /// <summary>
+        /// Get the value of an attribute, as a value in the given Enum type.
+        /// The specified enum should have a member with value -1, which will
+        /// be returned if the attribute doesn't exist or is in the wrong format.
+        /// </summary>
+        /// <typeparam name="T">The enum type</typeparam>
+        /// <param name="name">The attribute name</param>
+        /// <returns>The enum value</returns>
+        protected T GetEnumAttr<T>(string name)
+        {
+            string a = this.GetAttribute(name);
+            return EnumParser.Parse<T>(a);
+        }
+
+        /// <summary>
+        /// Get the value of an attribute, as a value in the given Enum type.
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="enumType"></param>
+        /// <returns></returns>
+        protected object GetEnumAttr(string name, Type enumType)
+        {
+            string a = this.GetAttribute(name);
+            return EnumParser.Parse(a, enumType);
+        }
+
+        /// <summary>
+        /// Set the value of an attribute, with the value being a enum instance.
+        /// The enum in question should have an entry with int value -1, which
+        /// corresponds to no attribute.
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="value"></param>
+        protected void SetEnumAttr(string name, object value)
+        {
+            if ((value == null) || ((int)value == -1))
+            {
+                RemoveAttribute(name);
+                return;
+            }
+            SetAttribute(name, EnumParser.ToString(value));
+        }
+
+        /// <summary>
+        /// Get the value of a given attribute, as an integer.  Returns -1 for
+        /// most errors.   TODO: should this throw exceptions?
+        /// </summary>
+        /// <param name="name"></param>
+        /// <returns></returns>
+        protected int GetIntAttr(string name)
+        {
+            string a = this.GetAttribute(name);
+            if ((a == null) || (a.Length == 0))
+                return -1;
+            try
+            {
+                return int.Parse(a);
+            }
+            catch (FormatException)
+            {
+                return -1;
+            }
+            catch (OverflowException)
+            {
+                return -1;
+            }
+        }
+        /// <summary>
+        /// Set the value of a given attribute, as an integer.  Use -1
+        /// to remove the attribute.
+        /// </summary>
+        /// <param name="name">The attribute name</param>
+        /// <param name="val">The integer to set</param>
+        /// <returns></returns>
+        protected void SetIntAttr(string name, int val)
+        {
+            if (val < 0)
+                // testing shows this is safe for non-existing attributes.
+                RemoveAttribute(name);
+            else
+                SetAttribute(name, val.ToString());
+        }
+
+        /// <summary>
+        /// Get the value of a given attribute, as an unsigned long.  Returns -1L for
+        /// most errors.   TODO: should this throw exceptions?
+        /// </summary>
+        /// <param name="name"></param>
+        /// <returns></returns>
+        protected long GetLongAttr(string name)
+        {
+            string a = this.GetAttribute(name);
+            if ((a == null) || (a.Length == 0))
+                return -1L;
+            try
+            {
+                return long.Parse(a);
+            }
+            catch (FormatException)
+            {
+                return -1L;
+            }
+            catch (OverflowException)
+            {
+                return -1L;
+            }
+        }
+        /// <summary>
+        /// Set the value of a given attribute, as a long  Use -1L
+        /// to remove the attribute.
+        /// </summary>
+        /// <param name="name">The attribute name</param>
+        /// <param name="val">The integer to set</param>
+        /// <returns></returns>
+        protected void SetLongAttr(string name, long val)
+        {
+            if (val == -1L)
+                // testing shows this is safe for non-existing attributes.
+                RemoveAttribute(name);
+            else
+                SetAttribute(name, val.ToString());
+        }
+        
+        /// <summary>
+        /// Get an attribute cast to DateTime, using the DateTime profile
+        /// of XEP-82.
+        /// </summary>
+        /// <param name="name"></param>
+        /// <returns>DateTime.MinValue if attribute not found.</returns>
+        /// <exception cref="FormatException">Invalid format</exception>
+        protected DateTime GetDateTimeAttr(string name)
+        {
+            string val = GetAttr(name);
+            if (val == null)
+                return DateTime.MinValue;
+            return DateTimeProfile(val);
+        }
+
+        /// <summary>
+        /// Set with DateTime.MinValue to remove the attribute
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="value"></param>
+        protected void SetDateTimeAttr(string name, DateTime value)
+        {
+            if (value == DateTime.MinValue)
+                // testing shows this is safe for non-existing attributes.
+                RemoveAttribute(name);
+            else
+                SetAttribute(name, DateTimeProfile(value));
+        }
+
+        /// <summary>
+        /// Convert the given array of bytes into a string, having two characters
+        /// for each byte, corresponding to the hex representation of that byte.
+        /// </summary>
+        /// <param name="buf"></param>
+        /// <returns></returns>
+        public static string HexString(byte[] buf)
+        {
+            // it seems like there ought to be a better way to do this.
+            StringBuilder sb = new StringBuilder();
+            foreach (byte b in buf)
+            {
+                sb.Append(b.ToString("x2"));
+            }
+            return sb.ToString();
+        }
+        /// <summary>
+        /// Convert the given array of bytes into a string, having two characters
+        /// for each byte, corresponding to the hex representation of that byte.
+        /// </summary>
+        /// <param name="buf">The byte buffer</param>
+        /// <param name="offset">The offset into the buffer for the start</param>
+        /// <param name="length">The number of bytes to read, starting at the offset.</param>
+        /// <returns></returns>
+        public static string HexString(byte[] buf, int offset, int length)
+        {
+            // it seems like there ought to be a better way to do this.
+            StringBuilder sb = new StringBuilder();
+            for (int i=offset; i < length; i++)
+            {
+                sb.Append(buf[i].ToString("x2"));
+            }
+            return sb.ToString();
+        }
+
+        /// <summary>
+        /// Compute the SHA1 hash of the id and secret concatenated together.
+        /// </summary>
+        /// <param name="id">UTF8-encoded id</param>
+        /// <param name="secret">UTF8-encoded secret</param>
+        /// <returns></returns>
+        public static string ShaHash(string id, string secret)
+        {
+            Debug.Assert(id != null);
+            Debug.Assert(secret != null);
+            SHA1 sha = SHA1.Create();
+            byte[] hash = sha.ComputeHash(ENCODING.GetBytes(id + secret));
+            return HexString(hash);
+        }
+
+        /// <summary>
+        /// Compute a 0K hash
+        /// </summary>
+        /// <param name="password">The secret to hash in</param>
+        /// <param name="token">The token to permute the hash</param>
+        /// <param name="sequence">Number of times to hash</param>
+        /// <returns></returns>
+        public static string ZeroK(string password, string token, int sequence)
+        {
+            Debug.Assert(password != null);
+            Debug.Assert(token != null);
+            SHA1 sha = SHA1.Create();
+            string hash = HexString(sha.ComputeHash(ENCODING.GetBytes(password)));
+            hash = HexString(sha.ComputeHash(ENCODING.GetBytes(hash + token)));
+            for (int i = 0; i < sequence; i++)
+            {
+                hash = HexString(sha.ComputeHash(ENCODING.GetBytes(hash)));
+            }
+            return hash;
+        }
+
+        /// <summary>
+        /// Return a DateTime version of the given Jabber date.  Example date: 20020504T20:39:42
+        /// </summary>
+        /// <param name="dt">The pseudo-ISO-8601 formatted date (no milliseconds)</param>
+        /// <returns>A (usually UTC) DateTime</returns>
+        public static DateTime JabberDate(string dt)
+        {
+            if ((dt == null) || (dt == ""))
+                return DateTime.MinValue;
+            try
+            {
+                return new DateTime(int.Parse(dt.Substring(0, 4)),
+                                    int.Parse(dt.Substring(4, 2)),
+                                    int.Parse(dt.Substring(6, 2)),
+                                    int.Parse(dt.Substring(9,2)),
+                                    int.Parse(dt.Substring(12,2)),
+                                    int.Parse(dt.Substring(15,2)));
+            }
+            catch
+            {
+                return DateTime.MinValue;
+            }
+        }
+        /// <summary>
+        /// Get a jabber-formated date for the DateTime.   Example date: 20020504T20:39:42
+        /// </summary>
+        /// <param name="dt">The (usually UTC) DateTime to format</param>
+        /// <returns>The pseudo-ISO-8601 formatted date (no milliseconds)</returns>
+        public static string JabberDate(DateTime dt)
+        {
+            return string.Format("{0:yyyy}{0:MM}{0:dd}T{0:HH}:{0:mm}:{0:ss}", dt);
+        }
+
+        /// <summary>
+        /// XEP-82 Date/Time profile: http://www.xmpp.org/extensions/xep-0082.html#sect-id2601974
+        /// CCYY-MM-DDThh:mm:ss[.sss]TZD
+        /// 1969-07-21T02:56:15Z
+        /// </summary>
+        /// <param name="dt"></param>
+        /// <returns></returns>
+        public static DateTime DateTimeProfile(string dt)
+        {
+            string[] fmts =
+            {
+                "yyyy-MM-dd",
+                "yyyy-MM-ddTHH:mm:sszzz",
+                "yyyy-MM-ddTHH:mm:ss.fffzzz",
+                "HH:mm:ss",
+                "HH:mm:ss.fff",
+                "HH:mm:sszzz",
+                "HH:mm:ss.fffzzz",
+            };
+            string arg = dt.Replace("Z", "+00:00");
+            return DateTime.ParseExact(arg, fmts, null, System.Globalization.DateTimeStyles.AdjustToUniversal);
+        }
+
+        /// <summary>
+        /// XEP-82 Date/Time profile: http://www.xmpp.org/extensions/xep-0082.html#sect-id2601974
+        /// CCYY-MM-DDThh:mm:ss[.sss]TZD
+        /// 1969-07-21T02:56:15Z
+        /// </summary>
+        /// <param name="dt"></param>
+        /// <returns></returns>
+        public static string DateTimeProfile(DateTime dt)
+        {
+            return dt.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
+        }
+
+        /// <summary>
+        /// The XML for the packet.
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            return this.OuterXml;
+        }
+
+        /// <summary>
+        /// Return just the start tag for the element.
+        /// </summary>
+        /// <returns></returns>
+        public string StartTag()
+        {
+            StringBuilder sb = new StringBuilder("<");
+            sb.Append(this.Name);
+            if (this.NamespaceURI != null)
+            {
+                sb.Append(" xmlns");
+                if (this.Prefix != null)
+                {
+                    sb.Append(":");
+                    sb.Append(this.Prefix);
+                }
+                sb.Append("=\"");
+                sb.Append(this.NamespaceURI);
+                sb.Append("\"");
+            }
+            foreach (XmlAttribute attr in this.Attributes)
+            {
+                sb.Append(" ");
+                sb.Append(attr.Name);
+                sb.Append("=\"");
+                sb.Append(attr.Value);
+                sb.Append("\"");
+            }
+            sb.Append(">");
+            return sb.ToString();
+        }
+
+        /// <summary>
+        /// Get the first child element of this element.
+        /// </summary>
+        /// <returns>null if none found.</returns>
+        public XmlElement GetFirstChildElement()
+        {
+            foreach (XmlNode n in this)
+            {
+                if (n.NodeType == XmlNodeType.Element)
+                    return (XmlElement) n;
+            }
+            return null;
+        }
+
+        private static readonly Type[] s_constructor_parms =
+            new Type[]
+            {
+                typeof(string),
+                typeof(XmlQualifiedName),
+                typeof(XmlDocument)
+            };
+
+        /// <summary>
+        /// Clone this node, preserving type information.
+        /// </summary>
+        /// <param name="deep">Clone child nodes too?</param>
+        /// <returns>Cloned node, with type info intact</returns>
+        public override XmlNode CloneNode(bool deep)
+        {
+            return CloneNode(deep, this.OwnerDocument);
+        }
+
+        /// <summary>
+        /// Clone this node into the target document, preserving type information.
+        /// </summary>
+        /// <param name="deep"></param>
+        /// <param name="doc"></param>
+        /// <returns></returns>
+        public XmlNode CloneNode(bool deep, XmlDocument doc)
+        {
+            ConstructorInfo ci = this.GetType().GetConstructor(s_constructor_parms);
+            if (ci == null)
+                return doc.ImportNode(this, deep);
+            if (ci.DeclaringType != this.GetType())
+            {
+                Debug.WriteLine("Bad type: " + ci.DeclaringType.ToString());
+            }
+            XmlElement el = (Element)ci.Invoke(new object[] { this.Prefix, new XmlQualifiedName(this.LocalName, this.NamespaceURI), doc });
+            if (el.GetType() != this.GetType())
+            {
+                Debug.Assert(el.GetType() == this.GetType());
+            }
+
+            if (el.IsEmpty != this.IsEmpty)
+                el.IsEmpty = this.IsEmpty;
+
+
+            if (this.HasAttributes)
+            {
+                foreach (XmlAttribute attr in this.Attributes)
+                    el.Attributes.Append((XmlAttribute)doc.ImportNode(attr, true));
+            }
+
+            if (deep)
+            {
+                foreach (XmlNode n in this.ChildNodes)
+                {
+                    if (n is Element)
+                    {
+                        el.AppendChild(((Element)n).CloneNode(deep, doc));
+                    }
+                    else
+                    {
+                        el.AppendChild(doc.ImportNode(n, deep));
+                    }
+                }
+            }
+            return el;
+        }
+
+        /// <summary>
+        /// Convert the given source element to typed subclasses of Element, according
+        /// to the given ElementFactory.
+        /// </summary>
+        /// <param name="source"></param>
+        /// <param name="factory"></param>
+        /// <returns></returns>
+        public static Element AddTypes(XmlElement source, ElementFactory factory)
+        {
+            if (source is Element)
+                return (Element)source; // assume all kids are converted already.
+
+            XmlDocument doc = source.OwnerDocument;
+            XmlQualifiedName qn = new XmlQualifiedName(source.Name, source.NamespaceURI);
+            Element el = factory.GetElement(source.Prefix, qn, doc);
+
+            el.IsEmpty = source.IsEmpty;
+
+            if (source.HasAttributes)
+            {
+                foreach (XmlAttribute attr in source.Attributes)
+                    el.Attributes.Append((XmlAttribute)attr.CloneNode(true));
+            }
+
+            foreach (XmlNode n in source.ChildNodes)
+            {
+                if (n is XmlElement)
+                    el.AppendChild(AddTypes((XmlElement)n, factory));
+                else
+                    el.AppendChild(n.CloneNode(true));
+            }
+
+            return el;
+        }
+
+        /// <summary>
+        /// System-wide one-up counter, for numbering packets.
+        /// </summary>
+        static int s_counter = 0;
+        /// <summary>
+        /// Reset the packet ID counter.  This is ONLY to be used for test cases!   No locking!
+        /// </summary>
+        [Conditional("DEBUG")]
+        public static void ResetID()
+        {
+            s_counter = 0;
+        }
+
+        /// <summary>
+        /// Increment the ID counter, and get the new value.
+        /// </summary>
+        /// <returns>The new ID.</returns>
+        public static string NextID()
+        {
+            System.Threading.Interlocked.Increment(ref s_counter);
+            return "JN_" + s_counter.ToString();
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/ElementFactory.cs b/lib/jabber-net/jabber/protocol/ElementFactory.cs
new file mode 100644
index 0000000..e4879d6
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/ElementFactory.cs
@@ -0,0 +1,198 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using System.Diagnostics;
+using System.Reflection;
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol
+{
+    /// <summary>
+    /// Qname to type mapping.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class QnameType
+    {
+        /// <summary>
+        /// Element name
+        /// </summary>
+        protected internal string Name;
+        /// <summary>
+        /// Element namespace URI
+        /// </summary>
+        protected internal string NS;
+        /// <summary>
+        /// Type to create for NS/Name pair
+        /// </summary>
+        protected internal Type  ElementType;
+
+        /// <summary>
+        /// Create a QnameType
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="ns"></param>
+        /// <param name="typ"></param>
+        public QnameType(string name, string ns, Type typ)
+        {
+            this.Name  = name;
+            this.NS    = ns;
+            this.ElementType = typ;
+        }
+
+        /// <summary>
+        /// Is this the same qname by element name and namespace?
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <returns></returns>
+        public override bool Equals(object obj)
+        {
+            if (obj == (object)this)
+                return true;
+            QnameType other = obj as QnameType;
+            if (other == null)
+                return false;
+            return (other.Name == Name) && (other.NS == NS);
+        }
+
+        /// <summary>
+        /// Get a hash over the name and namespace.
+        /// </summary>
+        /// <returns></returns>
+        public override int GetHashCode()
+        {
+            return ToString().GetHashCode();
+        }
+
+        /// <summary>
+        /// Namespace|Name
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            return NS + "|" + Name;
+        }
+    }
+
+    /// <summary>
+    /// Interface for packet factories to implement.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public interface IPacketTypes
+    {
+        /// <summary>
+        /// QName to type mappings.
+        /// </summary>
+        QnameType[] Types { get; }
+    }
+
+    /// <summary>
+    /// A ElementFactory is a class that knows how to create packet instances of
+    /// a wide variety of different types.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ElementFactory
+    {
+        private Hashtable m_types = new Hashtable();
+        private static readonly Type[] s_constructorTypes =
+            new Type[] { typeof(string),
+                           typeof(XmlQualifiedName),
+                           typeof(XmlDocument) };
+        /// <summary>
+        /// Add a type to the packet factory.
+        /// </summary>
+        /// <param name="localName"></param>
+        /// <param name="ns"></param>
+        /// <param name="t"></param>
+        public void AddType(string localName, string ns, Type t)
+        {
+            Debug.Assert(t.IsSubclassOf(typeof(Element)));
+            ConstructorInfo ci = t.GetConstructor(s_constructorTypes);
+            Debug.Assert(ci != null);
+            AddType(new XmlQualifiedName(localName, ns), ci);
+        }
+        /// <summary>
+        /// Add a type to the packet factory.
+        /// </summary>
+        /// <param name="qname"></param>
+        /// <param name="t"></param>
+        public void AddType(XmlQualifiedName qname, Type t)
+        {
+            Debug.Assert(t.IsSubclassOf(typeof(Element)));
+            ConstructorInfo ci = t.GetConstructor(s_constructorTypes);
+            Debug.Assert(ci != null);
+            AddType(qname, ci);
+        }
+        /// <summary>
+        /// Add a type to the packet factory.
+        /// </summary>
+        /// <param name="qname"></param>
+        /// <param name="ci"></param>
+        public void AddType(XmlQualifiedName qname, ConstructorInfo ci)
+        {
+            Debug.Assert(ci != null);
+            if (m_types.Contains(qname))
+                Debug.WriteLine("Warning: overriding existing packet factory: " + qname.ToString());
+            m_types[qname] = ci;
+        }
+        /// <summary>
+        /// Add a type to the packet factory.
+        /// </summary>
+        /// <param name="list"></param>
+        public void AddType(IPacketTypes list)
+        {
+            foreach (QnameType qn in list.Types)
+            {
+                this.AddType(qn.Name, qn.NS, qn.ElementType);
+            }
+        }
+        /*
+        public void AddType(ElementFactory pf)
+        {
+            foreach (DictionaryEntry ent in (IDictionary)pf.m_types)
+            {
+                m_types.Add(ent.Key, ent.Value);
+            }
+        }
+*/
+        /// <summary>
+        /// Create an element of the appropriate type, based on the qname of the packet.
+        /// </summary>
+        /// <param name="prefix">The namespace prefix for the element</param>
+        /// <param name="qname">The namespaceURI/element name pair</param>
+        /// <param name="doc">The document to create the element in.</param>
+        /// <returns></returns>
+        public Element GetElement(string prefix, XmlQualifiedName qname, XmlDocument doc)
+        {
+            ConstructorInfo ci = (ConstructorInfo) m_types[qname];
+            if (ci == null)
+            {
+                return new Element(prefix, qname, doc);
+            }
+            return (Element) ci.Invoke
+                (new object[] {prefix, qname, doc});
+        }
+
+        /// <summary>
+        /// Get a constructor for the appropriate type for the given qname.
+        /// </summary>
+        public ConstructorInfo this[XmlQualifiedName qname]
+        {
+            get { return (ConstructorInfo) m_types[qname]; }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/ElementList.cs b/lib/jabber-net/jabber/protocol/ElementList.cs
new file mode 100644
index 0000000..05f49ea
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/ElementList.cs
@@ -0,0 +1,332 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using System.Xml;
+using bedrock.util;
+
+namespace jabber.protocol
+{
+    /// <summary>
+    /// Replacement for XmlElementList that removes the safety belt of checking for changes during traversal,
+    /// but removes the big old memory leak in MS's implementation.  Also, only returns first-level children,
+    /// rather than all children below here with the given name.  Thanks, MS.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ElementList : XmlNodeList
+    {
+        private XmlElement m_parent = null;
+        private string m_name = null;
+        private string m_uri = null;
+
+        /// <summary>
+        /// Create an element list that is for all child elements.
+        /// </summary>
+        /// <param name="parent">Parent to search</param>
+        public ElementList(XmlElement parent)
+        {
+            m_parent = parent;
+        }
+
+        /// <summary>
+        /// Create an element list that is for all child elements with the given name;
+        /// </summary>
+        /// <param name="parent"></param>
+        /// <param name="name"></param>
+        public ElementList(XmlElement parent, string name)
+            : this(parent)
+        {
+            m_name = name;
+        }
+
+        /// <summary>
+        /// Create an element list that is for all child elements with the given name and namespace URI.
+        /// </summary>
+        /// <param name="parent"></param>
+        /// <param name="name"></param>
+        /// <param name="namespaceURI"></param>
+        public ElementList(XmlElement parent, string name, string namespaceURI)
+            : this(parent)
+        {
+            m_name = name;
+            m_uri = namespaceURI;
+        }
+
+        /// <summary>
+        /// Get the next node in the enumeration.  Pass in null to start.
+        /// </summary>
+        /// <param name="start">Starting point for search.</param>
+        /// <returns></returns>
+        public XmlNode GetNextNode(XmlNode start)
+        {
+            XmlNode n = (start == null) ? m_parent.FirstChild : start.NextSibling;
+            while ((n != null) && !this.IsMatch(n))
+            {
+                n = n.NextSibling;
+            }
+            return n;
+        }
+
+        private bool IsMatch(XmlNode curNode)
+        {
+            if (curNode.NodeType != XmlNodeType.Element)
+                return false;
+
+            if (m_name == null)
+                return true;
+
+            if (m_uri == null)
+                return (curNode.LocalName == m_name);
+
+            return (curNode.LocalName == m_name) && (curNode.NamespaceURI == m_uri);
+        }
+
+        /// <summary>
+        /// Enumerate over the matching children.
+        /// </summary>
+        /// <returns></returns>
+        public override System.Collections.IEnumerator GetEnumerator()
+        {
+            return new ElementListEnumerator(this);
+        }
+
+        /// <summary>
+        /// Gets the number of matching children.
+        /// </summary>
+        public override int Count
+        {
+            get
+            {
+                int c = 0;
+                XmlNode n = null;
+                while ((n = GetNextNode(n)) != null)
+                {
+                    c++;
+                }
+                return c;
+            }
+        }
+
+        /*
+         * This breaks the Mono build, and shouldn't be necessary, since
+         * the base class implements exactly this.
+        /// <summary>
+        /// Retrieve a given child.
+        /// </summary>
+        public override XmlNode this[int i]
+        {
+            get { return Item(i); }
+        }
+        */
+
+        /// <summary>
+        /// Retrieve a given child.
+        /// </summary>
+        /// <param name="index"></param>
+        /// <returns></returns>
+        public override XmlNode Item(int index)
+        {
+            int c = 0;
+            XmlNode n = m_parent.FirstChild;
+            while (n != null)
+            {
+                if (c == index)
+                    return n;
+                c++;
+                n = GetNextNode(n);
+            }
+            return null;
+        }
+
+        private class ElementListEnumerator : IEnumerator
+        {
+            private ElementList m_list;
+            private XmlNode m_cur = null;
+
+            public ElementListEnumerator(ElementList list)
+            {
+                m_list = list;
+            }
+
+            #region IEnumerator Members
+
+            public void Reset()
+            {
+                m_cur = null;
+            }
+
+            public object Current
+            {
+                get { return m_cur; }
+            }
+
+            public bool MoveNext()
+            {
+                m_cur = m_list.GetNextNode(m_cur);
+                return (m_cur != null);
+            }
+
+            #endregion
+        }
+    }
+
+    /// <summary>
+    /// Parameterized version of ElementList.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class TypedElementList<T> : XmlNodeList, System.Collections.Generic.IEnumerable<T>
+        where T : XmlElement
+    {
+        private XmlElement m_parent = null;
+
+        /// <summary>
+        /// Create an element list that is for all child elements with the specified type
+        /// </summary>
+        /// <param name="parent"></param>
+        public TypedElementList(XmlElement parent)
+        {
+            m_parent = parent;
+        }
+
+        /// <summary>
+        /// Get the next node in the enumeration.  Pass in null to start.
+        /// </summary>
+        /// <param name="start">Starting point for search.</param>
+        /// <returns></returns>
+        public T GetNextNode(T start)
+        {
+            XmlNode n = (start == null) ? m_parent.FirstChild : start.NextSibling;
+            while ((n != null) && !(n is T))
+            {
+                n = n.NextSibling;
+            }
+            return (T)n;
+        }
+
+        /// <summary>
+        /// Enumerate over the matching children.
+        /// </summary>
+        /// <returns></returns>
+        public override System.Collections.IEnumerator GetEnumerator()
+        {
+            return new TypedElementListEnumerator(this);
+        }
+
+        System.Collections.Generic.IEnumerator<T> System.Collections.Generic.IEnumerable<T>.GetEnumerator()
+        {
+            return new TypedElementListEnumerator(this);
+        }
+
+        /// <summary>
+        /// Gets the number of matching children.
+        /// </summary>
+        public override int Count
+        {
+            get
+            {
+                int c = 0;
+                T n = null;
+                while ((n = GetNextNode(n)) != null)
+                {
+                    c++;
+                }
+                return c;
+            }
+        }
+
+        /// <summary>
+        /// Retrieve a given child.
+        /// </summary>
+        /// <param name="index"></param>
+        /// <returns></returns>
+        public override XmlNode Item(int index)
+        {
+            int c = 0;
+            T n = null;
+            while ((n = GetNextNode(n)) != null)
+            {
+                if (c == index)
+                    return n;
+                c++;
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// Create an aray from the list.
+        /// </summary>
+        /// <returns></returns>
+        public T[] ToArray()
+        {
+            T[] array = new T[Count];
+            int i = 0;
+            foreach (T item in this)
+            {
+                //T item = (T)o;
+                array[i++] = item;
+            }
+            return array;
+        }
+
+        private class TypedElementListEnumerator : IEnumerator, System.Collections.Generic.IEnumerator<T>
+        {
+            private TypedElementList<T> m_list;
+            private T m_cur = null;
+
+            public TypedElementListEnumerator(TypedElementList<T> list)
+            {
+                m_list = list;
+            }
+
+            #region IEnumerator Members
+
+            public void Reset()
+            {
+                m_cur = null;
+            }
+
+            public object Current
+            {
+                get { return m_cur; }
+            }
+
+            public bool MoveNext()
+            {
+                m_cur = m_list.GetNextNode(m_cur);
+                return (m_cur != null);
+            }
+
+            #endregion
+
+            #region IEnumerator<T> Members
+
+            T System.Collections.Generic.IEnumerator<T>.Current
+            {
+                get { return m_cur; }
+            }
+
+            #endregion
+
+            #region IDisposable Members
+
+            public void Dispose()
+            {
+                
+            }
+
+            #endregion
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/ElementStream.cs b/lib/jabber-net/jabber/protocol/ElementStream.cs
new file mode 100644
index 0000000..50741ca
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/ElementStream.cs
@@ -0,0 +1,166 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using System.Diagnostics;
+using System.IO;
+using System.Threading;
+using System.Xml;
+
+using bedrock.io;
+using bedrock.util;
+using jabber.protocol;
+
+namespace jabber.protocol
+{
+    /// <summary>
+    /// A packet was received.  The specified element will likely be a sub-class
+    /// of XmlElement, if the packet is found in the packet factory.
+    /// </summary>
+    public delegate void ProtocolHandler(Object sender, System.Xml.XmlElement rp);
+
+    /// <summary>
+    /// Async XML parsing, according to jabber protocol rules of "interesting".
+    /// The root node fires IElementStreamListener.OnDocumentStart(), and each
+    /// direct child of the root fires IElementStreamListener.OnTag().
+    ///
+    /// TODO: Combine with AsyncElementStream, since there's only one impl.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ElementStream
+    {
+        /// <summary>
+        /// The document to create elements in
+        /// </summary>
+        protected XmlDocument m_doc;
+
+        /// <summary>
+        /// The element factory.
+        /// </summary>
+        protected ElementFactory m_factory = new ElementFactory();
+
+        /// <summary>
+        /// The document started.  This will have a full element, even
+        /// though only the start tag has been received.
+        /// </summary>
+        public event ProtocolHandler OnDocumentStart;
+
+        /// <summary>
+        /// The document has completed.
+        /// TODO: This isn't fired as often as it needs to be, yet.
+        /// </summary>
+        public event bedrock.ObjectHandler OnDocumentEnd;
+
+        /// <summary>
+        /// A protocol element (child of the doc root) has been received.
+        /// </summary>
+        public event ProtocolHandler OnElement;
+
+        /// <summary>
+        /// An XML parsing error occurred.
+        /// </summary>
+        public event bedrock.ExceptionHandler OnError;
+
+        /// <summary>
+        /// Create a parser that will report events to the listener.
+        /// </summary>
+        protected ElementStream()
+        {
+            m_doc = new XmlDocument();
+            m_factory.AddType(new jabber.protocol.stream.Factory());
+        }
+
+        /// <summary>
+        /// The document being read into.  This document is used for creating nodes,
+        /// but does not actually contain the nodes.
+        /// </summary>
+        public XmlDocument Document
+        {
+            get { return m_doc; }
+        }
+
+        /// <summary>
+        /// Add PacketFactories to get XmlElements with type-safe accessors, for
+        /// all of the namespaces you care about.
+        /// </summary>
+        /// <param name="pf"></param>
+        public void AddFactory(IPacketTypes pf)
+        {
+            m_factory.AddType(pf);
+        }
+
+        /// <summary>
+        /// Add a type to the packet factory.
+        /// </summary>
+        /// <param name="localName">Local Name (e.g. query)</param>
+        /// <param name="ns">Namespace URI (e.g. jabber:iq:roster)</param>
+        /// <param name="t">Type to create</param>
+        public void AddType(string localName, string ns, Type t)
+        {
+            m_factory.AddType(localName, ns, t);
+        }
+
+        /// <summary>
+        /// Fire the OnDocumentStart event
+        /// </summary>
+        /// <param name="stream"></param>
+        protected void FireOnDocumentStart(XmlElement stream)
+        {
+            if (OnDocumentStart != null)
+                OnDocumentStart(this, stream);
+        }
+
+        /// <summary>
+        /// Fire the OnElement event
+        /// </summary>
+        /// <param name="elem"></param>
+        protected void FireOnElement(XmlElement elem)
+        {
+            if (OnElement != null)
+                OnElement(this, elem);
+        }
+
+        /// <summary>
+        /// Fire the OnDocumentEnd event
+        /// </summary>
+        protected void FireOnDocumentEnd()
+        {
+            if (OnDocumentEnd != null)
+                OnDocumentEnd(this);
+        }
+
+        /// <summary>
+        /// Fire the OnError event
+        /// </summary>
+        /// <param name="ex">The exception that was thrown</param>
+        protected void FireOnError(Exception ex)
+        {
+            if (OnError != null)
+                OnError(this, ex);
+        }
+
+        /// <summary>
+        /// Get an element by name using the current factory.
+        /// </summary>
+        /// <param name="name">The element name to use</param>
+        /// <param name="ns">The namespace URI of the element to get</param>
+        /// <returns></returns>
+        public Element GetElement(string name, string ns)
+        {
+            XmlQualifiedName q = new XmlQualifiedName(name, ns);
+            return m_factory.GetElement("", q, m_doc);
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/EnumParser.cs b/lib/jabber-net/jabber/protocol/EnumParser.cs
new file mode 100644
index 0000000..ab65ac2
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/EnumParser.cs
@@ -0,0 +1,189 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Reflection;
+using System.Diagnostics;
+
+using bedrock.util;
+
+namespace jabber.protocol
+{
+    /// <summary>
+    /// How should the marked-up entity be rendered in XML?  Only used
+    /// for enums that are going to be put in attributes at the moment.
+    /// TODO: support namespaces, use for element definitions.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [AttributeUsage(AttributeTargets.Field)]
+    public class XMLAttribute : Attribute
+    {
+        private string m_name;
+
+        /// <summary>
+        /// Create
+        /// </summary>
+        /// <param name="name"></param>
+        public XMLAttribute(string name)
+        {
+            m_name = name;
+        }
+
+        /// <summary>
+        /// The string to use when converting to and from XML.
+        /// </summary>
+        public string Name
+        {
+            get { return m_name; }
+        }
+    }
+
+    /// <summary>
+    /// Parse enums
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class EnumParser
+	{
+        private static Dictionary<Type, Dictionary<string, object>> s_vals = 
+            new Dictionary<Type, Dictionary<string, object>>();
+
+        private static Dictionary<Type, Dictionary<object, string>> s_strings =
+            new Dictionary<Type, Dictionary<object, string>>();
+
+        private static bool IsDash(Type t)
+        {
+            object[] da = t.GetCustomAttributes(typeof(DashAttribute), false);
+            return (da.Length > 0);
+        }
+
+        private static Dictionary<string, object> GetValHash(Type t)
+        {
+            Dictionary<string, object> map = null;
+            if (!s_vals.TryGetValue(t, out map))
+            {
+                s_vals[t] = map = new Dictionary<string, object>();
+                bool dash = IsDash(t);
+
+                FieldInfo[] fields = t.GetFields(BindingFlags.Public | BindingFlags.Static);
+                foreach (FieldInfo fi in fields)
+                {
+                    object[] attrs = fi.GetCustomAttributes(typeof(XMLAttribute), false);
+                    object val = fi.GetValue(null);
+                    if (attrs.Length > 0)
+                    {
+                        string name = ((XMLAttribute)attrs[0]).Name;
+                        map[name] = val;
+                    }
+                    if (dash)
+                        map[fi.Name.Replace("_", "-")] = val;
+                    else
+                        map[fi.Name] = val;
+                }
+            }
+            return map;
+        }
+
+        private static Dictionary<object, string> GetStringHash(Type t)
+        {
+            Dictionary<object, string> map = null;
+            string name;
+
+            if (!s_strings.TryGetValue(t, out map))
+            {
+                s_strings[t] = map = new Dictionary<object, string>();
+
+                bool dash = IsDash(t);
+
+                FieldInfo[] fields = t.GetFields(BindingFlags.Public | BindingFlags.Static);
+                foreach (FieldInfo fi in fields)
+                {
+                    object[] attrs = fi.GetCustomAttributes(typeof(XMLAttribute), false);
+                    object val = fi.GetValue(null);
+                    if (attrs.Length > 0)
+                        name = ((XMLAttribute)attrs[0]).Name;
+                    else
+                    {
+                        if (dash)
+                            name = fi.Name.Replace('_', '-');
+                        else
+                            name = fi.Name;
+                    }
+                    map[val] = name;
+                }
+            }
+            return map;
+        }
+
+        /// <summary>
+        /// Parse a string into an enum value for the given type T.  
+        /// Any errors map to -1.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        public static T Parse<T>(string value)
+        {
+            if (!typeof(T).IsEnum)
+                throw new ArgumentException("Type must be enum");
+
+            Dictionary<string, object> map = GetValHash(typeof(T));
+            object val = null;
+            if (!map.TryGetValue(value, out val))
+                return (T)(object)(-1);
+            return (T)val;
+        }
+
+        /// <summary>
+        /// Parse a string into an enum value for the given type.  
+        /// Any errors map to -1.
+        /// </summary>
+        /// <param name="value"></param>
+        /// <param name="t"></param>
+        /// <returns></returns>
+        public static object Parse(string value, Type t)
+        {
+            if (!t.IsEnum)
+                throw new ArgumentException("Type must be enum");
+
+            Dictionary<string, object> map = GetValHash(t);
+            object val = null;
+            if (!map.TryGetValue(value, out val))
+                return (object)(-1);
+            return val;
+        }
+
+        /// <summary>
+        /// Convert an enum value into its string representation.
+        /// any -1 value gets mapped to null.
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        public static string ToString(object value)
+        {
+            Type t = value.GetType();
+            if (!t.IsEnum)
+                throw new ArgumentException("Type must be enum");
+
+            if ((int)value == -1)
+                return null;
+
+            Dictionary<object, string> map = GetStringHash(t);
+            string val = null;
+            bool found = map.TryGetValue(value, out val);
+            Debug.Assert(found, "Tried to convert an unknown enum value to string");
+            return val;
+        }
+	}
+}
diff --git a/lib/jabber-net/jabber/protocol/NS.cs b/lib/jabber-net/jabber/protocol/NS.cs
new file mode 100644
index 0000000..6b6f45e
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/NS.cs
@@ -0,0 +1,106 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System.Collections;
+using bedrock.util;
+
+namespace jabber.protocol
+{
+    /// <summary>
+    /// Namespace stack.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class NS
+    {
+        private Stack m_stack = new Stack();
+
+        /// <summary>
+        /// Create a new stack, primed with xmlns and xml as prefixes.
+        /// </summary>
+        public NS()
+        {
+            PushScope();
+            AddNamespace("xmlns", URI.XMLNS);
+            AddNamespace("xml", URI.XML);
+        }
+
+        /// <summary>
+        /// Declare a new scope, typically at the start of each element
+        /// </summary>
+        public void PushScope()
+        {
+            m_stack.Push(new Hashtable());
+        }
+
+        /// <summary>
+        /// Pop the current scope off the stack.  Typically at the end of each element.
+        /// </summary>
+        public void PopScope()
+        {
+            m_stack.Pop();
+        }
+
+        /// <summary>
+        /// Add a namespace to the current scope.
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="uri"></param>
+        public void AddNamespace(string prefix, string uri)
+        {
+            Hashtable h = (Hashtable)m_stack.Peek();
+            h[prefix] = uri;
+        }
+
+        /// <summary>
+        /// Lookup a prefix to find a namespace.  Searches down the stack, starting at the current scope.
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <returns></returns>
+        public string LookupNamespace(string prefix)
+        {
+            foreach (Hashtable ht in m_stack)
+            {
+                if ((ht.Count > 0) && (ht.ContainsKey(prefix)))
+                    return (string)ht[prefix];
+            }
+            return "";
+        }
+
+        /// <summary>
+        /// The current default namespace.
+        /// </summary>
+        public string DefaultNamespace
+        {
+            get { return LookupNamespace(string.Empty); }
+        }
+
+        /// <summary>
+        /// Debug output only.
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            System.Text.StringBuilder sb = new System.Text.StringBuilder();
+
+            foreach (Hashtable ht in m_stack)
+            {
+                sb.Append("---\n");
+                foreach (string k in ht.Keys)
+                {
+                    sb.Append(string.Format("{0}={1}\n", k, ht[k]));
+                }
+            }
+            return sb.ToString();
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/Packet.cs b/lib/jabber-net/jabber/protocol/Packet.cs
new file mode 100644
index 0000000..60aa6b0
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/Packet.cs
@@ -0,0 +1,89 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using System.Diagnostics;
+using System.Text;
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol
+{
+    /// <summary>
+    /// Packets that have to/from information.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Packet : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Packet(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="localName"></param>
+        /// <param name="doc"></param>
+        public Packet(string localName, XmlDocument doc) :
+            base(localName, URI.CLIENT, doc)
+        {
+        }
+
+        /// <summary>
+        /// The TO address
+        /// </summary>
+        public JID To
+        {
+            get { return (JID)this.GetAttr("to"); }
+            set { SetAttr("to", value); }
+        }
+
+        /// <summary>
+        ///  The FROM address
+        /// </summary>
+        public JID From
+        {
+            get { return (JID)this.GetAttr("from"); }
+            set { SetAttr("from", value); }
+        }
+
+        /// <summary>
+        /// The packet ID.
+        /// </summary>
+        public string ID
+        {
+            get { return this.GetAttr("id"); }
+            set { this.SetAttr("id", value); }
+        }
+
+        /// <summary>
+        /// Swap the To and the From addresses.
+        /// </summary>
+        public virtual void Swap()
+        {
+            string tmp = this.GetAttribute("to");
+            this.SetAttribute("to", this.GetAttribute("from"));
+            this.SetAttribute("from", tmp);
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/SynchElementStream.cs b/lib/jabber-net/jabber/protocol/SynchElementStream.cs
new file mode 100644
index 0000000..0221b3c
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/SynchElementStream.cs
@@ -0,0 +1,177 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net can be used under either JOSL or the GPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Diagnostics;
+using System.IO;
+using System.Xml;
+
+using jabber.protocol;
+using bedrock.util;
+
+using Org.System.Xml.Sax;
+using Org.System.Xml.Sax.Helpers;
+
+namespace jabber.protocol
+{
+    /// <summary>
+    /// Summary description for SynchElementStream.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class SynchElementStream : ElementStream, IContentHandler, IErrorHandler
+    {
+        private XmlElement m_stanza = null;
+
+        /// <summary>
+        /// Create a parser that reads from the input stream synchronously, in a single thread.
+        /// </summary>
+        /// <param name="input"></param>
+        public SynchElementStream(Stream input) : base(input)
+        {
+        }
+
+        /// <summary>
+        /// Start parsing.  WARNING: this blocks until the stream is disconnected or end stream:stream is received.
+        /// </summary>
+        public void Start()
+        {
+            try
+            {
+                IXmlReader reader = new AElfred.SaxDriver();
+                reader.SetFeature(Constants.NamespacesFeature, true);
+                reader.SetFeature(AElfred.SaxDriver.FEATURE + "external-parameter-entities", false);
+                reader.SetFeature(AElfred.SaxDriver.FEATURE + "external-general-entities", false);
+                reader.ErrorHandler = this;
+                reader.ContentHandler = this;
+                InputSource inSource = new StreamInputSource(m_stream);
+                inSource.Encoding = "UTF-8";
+                reader.Parse(inSource);
+            }
+            catch (Exception e)
+            {
+                FireOnError(e);
+            }
+        }
+
+        private string Prefix(string qName)
+        {
+            string[] parts = qName.Split(new char[] {':'});
+            return (parts.Length == 2) ? parts[0] : "";
+        }
+
+        #region IContentHandler Members
+
+        void IContentHandler.StartDocument()
+        {
+        }
+
+        void IContentHandler.SkippedEntity(string name)
+        {
+        }
+
+        void IContentHandler.StartElement(string uri, string localName, string qName, IAttributes atts)
+        {
+            XmlQualifiedName q  = new XmlQualifiedName(localName, uri);
+
+            XmlElement elem = m_factory.GetElement(Prefix(qName), q, m_doc);
+            for (int i=0; i<atts.Length; i++)
+            {
+                XmlAttribute a = m_doc.CreateAttribute(Prefix(atts.GetQName(i)),
+                    atts.GetLocalName(i),
+                    atts.GetUri(i));
+                a.AppendChild(m_doc.CreateTextNode(atts.GetValue(i)));
+                elem.SetAttributeNode(a);
+            }
+
+            if ((elem.LocalName != "stream") || (elem.NamespaceURI != URI.STREAM))
+            {
+                if (m_stanza != null)
+                    m_stanza.AppendChild(elem);
+                m_stanza = elem;
+            }
+            else
+            {
+                FireOnDocumentStart(elem);
+            }
+        }
+
+        void IContentHandler.EndPrefixMapping(string prefix)
+        {
+            // TODO:  Add SynchElementStream.EndPrefixMapping implementation
+        }
+
+        void IContentHandler.SetDocumentLocator(ILocator locator)
+        {
+            // TODO:  Add SynchElementStream.SetDocumentLocator implementation
+        }
+
+        void IContentHandler.EndElement(string uri, string localName, string qName)
+        {
+            XmlElement last = m_stanza;
+            if (last != null)
+            {
+                m_stanza = (XmlElement) m_stanza.ParentNode;
+                if (m_stanza == null)
+                    FireOnElement(last);
+            }
+        }
+
+        void IContentHandler.EndDocument()
+        {
+            FireOnDocumentEnd();
+        }
+
+        void IContentHandler.Characters(char[] ch, int start, int length)
+        {
+            if (m_stanza != null)
+            {
+                m_stanza.AppendChild(
+                    m_doc.CreateTextNode(new string(ch, start, length)));
+            }
+        }
+
+        void IContentHandler.IgnorableWhitespace(char[] ch, int start, int length)
+        {
+        }
+
+        void IContentHandler.StartPrefixMapping(string prefix, string uri)
+        {
+        }
+
+        void IContentHandler.ProcessingInstruction(string target, string data)
+        {
+        }
+
+        #endregion
+
+        #region IErrorHandler Members
+
+        void IErrorHandler.FatalError(ParseError error)
+        {
+            FireOnError(new SaxParseException(error));
+        }
+
+        void IErrorHandler.Warning(ParseError error)
+        {
+            Debug.WriteLine("XML parse warning: " + error.Message + " at line number: " + error.LineNumber);
+        }
+
+        void IErrorHandler.Error(ParseError error)
+        {
+            FireOnError(new SaxParseException(error));
+        }
+
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/URI.cs b/lib/jabber-net/jabber/protocol/URI.cs
new file mode 100644
index 0000000..b60fbdc
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/URI.cs
@@ -0,0 +1,267 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+
+using bedrock.util;
+
+namespace jabber.protocol
+{
+    /// <summary>
+    /// Namespace constants for http://etherx.jabber.org/streams.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class URI
+    {
+        /// <summary>
+        /// Namespace for the prefix "xmlns".
+        /// </summary>
+        public const string XMLNS = "http://www.w3.org/2000/xmlns/";
+        /// <summary>
+        /// Namespace for the prefix "xml", like xml:lang.
+        /// </summary>
+        public const string XML = "http://www.w3.org/XML/1998/namespace";
+        /// <summary>
+        /// XHTML namespace, for <body> element
+        /// </summary>
+        public const string XHTML  = "http://www.w3.org/1999/xhtml";
+        /// <summary>
+        /// XHTML-IM namespace, for <html> element
+        /// </summary>
+        public const string XHTML_IM = "http://jabber.org/protocol/xhtml-im";
+        /// <summary>
+        /// stream:stream
+        /// </summary>
+        public const string STREAM = "http://etherx.jabber.org/streams";
+        /// <summary>
+        /// Start-TLS feature namespace
+        /// </summary>
+        public const string START_TLS = "urn:ietf:params:xml:ns:xmpp-tls";
+        /// <summary>
+        /// XEP-138 compression feature namespace.  Not the same as for the protocol!
+        /// </summary>
+        public const string COMPRESS_FEATURE = "http://jabber.org/features/compress";
+        /// <summary>
+        /// XEP-138 compression protocol namespace.  Not the same as the feature!
+        /// </summary>
+        public const string COMPRESS = "http://jabber.org/protocol/compress";
+        /// <summary>
+        /// SASL feature namespace
+        /// </summary>
+        public const string SASL = "urn:ietf:params:xml:ns:xmpp-sasl";
+        /// <summary>
+        /// Start a session
+        /// </summary>
+        public const string SESSION = "urn:ietf:params:xml:ns:xmpp-session";
+        /// <summary>
+        /// Bind a resource
+        /// </summary>
+        public const string BIND = "urn:ietf:params:xml:ns:xmpp-bind";
+        /// <summary>
+        /// Stanza errors.  See RFC 3920, section 9.3.
+        /// </summary>
+        public const string STANZA_ERROR = "urn:ietf:params:xml:ns:xmpp-stanzas";
+        /// <summary>
+        /// Stream errors.  See RFC 3920, section 4.7.
+        /// </summary>
+        public const string STREAM_ERROR = "urn:ietf:params:xml:ns:xmpp-streams";
+        /// <summary>
+        /// Jabber client connections
+        /// </summary>
+        public const string CLIENT = "jabber:client";
+        /// <summary>
+        /// Jabber HTTP Binding connections
+        /// </summary>
+        public const string HTTP_BIND = "http://jabber.org/protocol/httpbind";
+        /// <summary>
+        /// Jabber component connections
+        /// </summary>
+        public const string ACCEPT = "jabber:component:accept";
+        /// <summary>
+        /// Jabber component connections, from the router
+        /// </summary>
+        public const string CONNECT = "jabber:component:connect";
+        /// <summary>
+        /// S2S connection
+        /// </summary>
+        public const string SERVER = "jabber:server";
+        /// <summary>
+        /// S2S dialback
+        /// </summary>
+        public const string DIALBACK = "jabber:server:dialback";
+        // IQ
+        /// <summary>
+        /// Authentication
+        /// </summary>
+        public const string AUTH     = "jabber:iq:auth";
+        /// <summary>
+        /// Roster manipulation
+        /// </summary>
+        public const string ROSTER   = "jabber:iq:roster";
+        /// <summary>
+        /// Register users
+        /// </summary>
+        public const string REGISTER = "jabber:iq:register";
+        /// <summary>
+        /// Out-of-band (file transfer)
+        /// </summary>
+        public const string OOB      = "jabber:iq:oob";
+        /// <summary>
+        /// Server agents
+        /// </summary>
+        public const string AGENTS   = "jabber:iq:agents";
+        /// <summary>
+        /// Client or server current time
+        /// </summary>
+        public const string TIME     = "jabber:iq:time";
+        /// <summary>
+        /// Last activity
+        /// </summary>
+        public const string LAST     = "jabber:iq:last";
+        /// <summary>
+        /// Client or server version
+        /// </summary>
+        public const string VERSION  = "jabber:iq:version";
+        /// <summary>
+        /// Jabber Browsing
+        /// </summary>
+        public const string BROWSE   = "jabber:iq:browse";
+        /// <summary>
+        /// Profile information
+        /// </summary>
+        public const string VCARD    = "vcard-temp";
+
+        /// <summary>
+        /// Geographic locaiotn (lat/long).
+        /// See XEP-80 (http://www.xmpp.org/extensions/xep-0080.html)
+        /// </summary>
+        public const string GEOLOC   = "http://jabber.org/protocol/geoloc";
+
+        /// <summary>
+        /// Discover items from an entity.
+        /// </summary>
+        public const string DISCO_ITEMS = "http://jabber.org/protocol/disco#items";
+        /// <summary>
+        /// Discover info about an entity item.
+        /// </summary>
+        public const string DISCO_INFO = "http://jabber.org/protocol/disco#info";
+
+        // X
+        /// <summary>
+        /// Offline message timestamping.
+        /// </summary>
+        public const string XDELAY   = "jabber:x:delay";
+        /// <summary>
+        /// Modern, XEP-0203 delay.
+        /// </summary>
+        public const string DELAY    = "urn:xmpp:delay";
+        /// <summary>
+        /// Out-of-band (file transfer)
+        /// </summary>
+        public const string XOOB     = "jabber:x:oob";
+        /// <summary>
+        /// Send roster entries to another user.
+        /// </summary>
+        public const string XROSTER  = "jabber:x:roster";
+        /// <summary>
+        /// The jabber:x:event namespace qualifies extensions used to request and respond to
+        /// events relating to the delivery, display, and composition of messages.
+        /// </summary>
+        public const string XEVENT = "jabber:x:event";
+        /// <summary>
+        /// jabber:x:data, as described in XEP-0004.
+        /// </summary>
+        public const string XDATA = "jabber:x:data";
+
+        /// <summary>
+        /// jabber:iq:search.
+        /// See XEP-55 (http://www.xmpp.org/extensions/xep-0055.html)
+        /// </summary>
+        public const string SEARCH = "jabber:iq:search";
+
+        /// <summary>
+        /// Multi-user chat.
+        /// See XEP-45 (http://www.xmpp.org/extensions/xep-0045.html)
+        /// </summary>
+        public const string MUC = "http://jabber.org/protocol/muc";
+        /// <summary>
+        /// Multi-user chat user functions.
+        /// See XEP-45 (http://www.xmpp.org/extensions/xep-0045.html)
+        /// </summary>
+        public const string MUC_USER = "http://jabber.org/protocol/muc#user";
+        /// <summary>
+        /// Multi-user chat admin functions.
+        /// See XEP-45 (http://www.xmpp.org/extensions/xep-0045.html)
+        /// </summary>
+        public const string MUC_ADMIN = "http://jabber.org/protocol/muc#admin";
+        /// <summary>
+        /// Multi-user chat owner functions.
+        /// See XEP-45 (http://www.xmpp.org/extensions/xep-0045.html)
+        /// </summary>
+        public const string MUC_OWNER = "http://jabber.org/protocol/muc#owner";
+        /// <summary>
+        /// Multi-user chat; request a unique room name.
+        /// See XEP-45 (http://www.xmpp.org/extensions/xep-0045.html)
+        /// </summary>
+        public const string MUC_UNIQUE = "http://jabber.org/protocol/muc#unique";
+
+        /// <summary>
+        /// Entity Capabilities.
+        /// See XEP-115 (http://www.xmpp.org/extensions/xep-0115.html)
+        /// </summary>
+        public const string CAPS = "http://jabber.org/protocol/caps";
+
+        /// <summary>
+        /// Publish/Subscribe
+        /// See XEP-0060 (http://www.xmpp.org/extensions/xep-0060.html)
+        /// </summary>
+        public const string PUBSUB = "http://jabber.org/protocol/pubsub";
+
+        /// <summary>
+        /// Publish/Subscribe, Owner use cases
+        /// See XEP-0060 (http://www.xmpp.org/extensions/xep-0060.html)
+        /// </summary>
+        public const string PUBSUB_OWNER = "http://jabber.org/protocol/pubsub#owner";
+
+        /// <summary>
+        /// Pub/Sub node configuration.
+        /// See XEP-0060 (http://www.xmpp.org/extensions/xep-0060.html)
+        /// </summary>
+        public const string PUBSUB_NODE_CONFIG = "http://jabber.org/protocol/pubsub#node_config";
+
+        /// <summary>
+        /// Publish/Subscribe Event
+        /// See XEP-0060 (http://www.xmpp.org/extensions/xep-0060.html)
+        /// </summary>
+        public const string PUBSUB_EVENT = "http://jabber.org/protocol/pubsub#event";
+
+        /// <summary>
+        /// Publish/Subscribe Errors
+        /// See XEP-0060 (http://www.xmpp.org/extensions/xep-0060.html)
+        /// </summary>
+        public const string PUBSUB_ERRORS = "http://jabber.org/protocol/pubsub#errors";
+
+        /// <summary>
+        /// Bookmarks.
+        /// See XEP-0048 (http://www.xmpp.org/extensions/xep-0048.html)
+        /// </summary>
+        public const string BOOKMARKS = "storage:bookmarks";
+
+        /// <summary>
+        /// Private storage.
+        /// See XEP-0049 (http://www.xmpp.org/extensions/xep-0049.html)
+        /// </summary>
+        public const string PRIVATE = "jabber:iq:private";
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/accept/Factory.cs b/lib/jabber-net/jabber/protocol/accept/Factory.cs
new file mode 100644
index 0000000..f10a311
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/accept/Factory.cs
@@ -0,0 +1,41 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+
+using bedrock.util;
+using jabber.protocol;
+
+namespace jabber.protocol.accept
+{
+    /// <summary>
+    /// A packet factory for the jabber:component:accept namespace.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Factory : IPacketTypes
+    {
+        private static QnameType[] s_qnt = new QnameType[]
+        {
+            new QnameType("handshake", URI.ACCEPT, typeof(Handshake)),
+            new QnameType("route",     URI.ACCEPT, typeof(Route)),
+            new QnameType("xdb",       URI.ACCEPT, typeof(Xdb)),
+            new QnameType("log",       URI.ACCEPT, typeof(Log)),
+            new QnameType("handshake", URI.CONNECT, typeof(Handshake)),
+            new QnameType("route",     URI.CONNECT, typeof(Route)),
+            new QnameType("xdb",       URI.CONNECT, typeof(Xdb)),
+            new QnameType("log",       URI.CONNECT, typeof(Log))
+        };
+        QnameType[] IPacketTypes.Types { get { return s_qnt; } }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/accept/Handshake.cs b/lib/jabber-net/jabber/protocol/accept/Handshake.cs
new file mode 100644
index 0000000..ce20595
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/accept/Handshake.cs
@@ -0,0 +1,67 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.accept
+{
+    /// <summary>
+    /// The handshake tag, including digest calculation.  Call SetAuth() to calculate
+    /// the SHA1 hash.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Handshake : jabber.protocol.Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Handshake(XmlDocument doc) : base("handshake", doc)
+        {
+        }
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Handshake(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Set the auth information for this handshake tag,
+        /// performing the digest operation.
+        /// </summary>
+        /// <param name="secret"></param>
+        /// <param name="streamID"></param>
+        public void SetAuth(string secret, string streamID)
+        {
+            this.Digest = ShaHash(streamID, secret);
+        }
+
+        /// <summary>
+        /// The digest.
+        /// </summary>
+        public string Digest
+        {
+            get { return this.InnerText; }
+            set { this.InnerText = value; }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/accept/Log.cs b/lib/jabber-net/jabber/protocol/accept/Log.cs
new file mode 100644
index 0000000..0cd0039
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/accept/Log.cs
@@ -0,0 +1,121 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.accept
+{
+    /// <summary>
+    /// The type field in a log tag.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum LogType
+    {
+        /// <summary>
+        /// None specified
+        /// </summary>
+        NONE = -1,
+        /// <summary>
+        /// type='warn'
+        /// </summary>
+        warn,
+        /// <summary>
+        /// type='info'
+        /// </summary>
+        info,
+        /// <summary>
+        /// type='verbose'
+        /// </summary>
+        verbose,
+        /// <summary>
+        /// type='debug'
+        /// </summary>
+        debug
+    }
+
+    /// <summary>
+    /// The log packet.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Log : jabber.protocol.Packet
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Log(XmlDocument doc) : base("log", doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Log(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The element inside the route tag.
+        /// </summary>
+        public XmlElement Element
+        {
+            get { return this["element"]; }
+            set { AddChild(value); }
+        }
+
+        /// <summary>
+        /// The type attribute
+        /// </summary>
+        public LogType Type
+        {
+            get { return GetEnumAttr<LogType>("type"); }
+            set { SetEnumAttr("type", value); }
+        }
+
+        /// <summary>
+        /// The namespace for logging
+        /// </summary>
+        public string NS
+        {
+            get { return GetAttribute("ns"); }
+            set { SetAttribute("ns", value); }
+        }
+
+        /// <summary>
+        /// The server thread this came from
+        /// </summary>
+        public string Thread
+        {
+            get { return GetAttribute("thread"); }
+            set { SetAttribute("thread", value); }
+        }
+
+        /// <summary>
+        /// Time sent.
+        /// </summary>
+        public DateTime Timestamp
+        {
+            get { return JabberDate(GetAttribute("timestamp")); }
+            set { SetAttribute("timestamp", JabberDate(value)); }
+        }
+
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/accept/Route.cs b/lib/jabber-net/jabber/protocol/accept/Route.cs
new file mode 100644
index 0000000..3dc9180
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/accept/Route.cs
@@ -0,0 +1,93 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.accept
+{
+    /// <summary>
+    /// The type field in a route tag.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum RouteType
+    {
+        /// <summary>
+        /// None specified
+        /// </summary>
+        NONE = -1,
+        /// <summary>
+        /// type='error'
+        /// </summary>
+        error,
+        /// <summary>
+        /// type='auth'
+        /// </summary>
+        auth,
+        /// <summary>
+        /// type='session'
+        /// </summary>
+        session
+    }
+
+    /// <summary>
+    /// The route packet.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Route : jabber.protocol.Packet
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Route(XmlDocument doc) : base("route", doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Route(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The element inside the route tag.
+        /// </summary>
+        public XmlElement Contents
+        {
+            get { return (XmlElement) this.FirstChild; }
+            set
+            {
+                this.InnerXml = "";
+                AddChild(value);
+            }
+        }
+
+        /// <summary>
+        /// The type attribute
+        /// </summary>
+        public RouteType Type
+        {
+            get { return GetEnumAttr<RouteType>("type"); }
+            set { SetEnumAttr("type", value); }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/accept/Xdb.cs b/lib/jabber-net/jabber/protocol/accept/Xdb.cs
new file mode 100644
index 0000000..d86eb5f
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/accept/Xdb.cs
@@ -0,0 +1,136 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.accept
+{
+    /// <summary>
+    /// The type attribute
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum XdbType
+    {
+        /// <summary>
+        /// None specified
+        /// </summary>
+        NONE = -1,
+        /// <summary>
+        /// type='get'
+        /// </summary>
+        get,
+        /// <summary>
+        /// type='set'
+        /// </summary>
+        set,
+        /// <summary>
+        /// type='result'
+        /// </summary>
+        result,
+        /// <summary>
+        /// type='error'
+        /// </summary>
+        error
+    }
+
+    /// <summary>
+    /// The action attribute.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum XdbAction
+    {
+        /// <summary>
+        /// None specified
+        /// </summary>
+        NONE = -1,
+        /// <summary>
+        /// action='check'
+        /// </summary>
+        check,
+        /// <summary>
+        /// action='insert'
+        /// </summary>
+        insert
+    }
+
+    /// <summary>
+    /// The XDB packet.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Xdb : jabber.protocol.Packet
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Xdb(XmlDocument doc) : base("xdb", doc)
+        {
+            ID = NextID();
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Xdb(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The contents of the XDB packet
+        /// </summary>
+        public XmlElement Contents
+        {
+            get { return (XmlElement) this.FirstChild; }
+            set
+            {
+                this.InnerXml = "";
+                AddChild(value);
+            }
+        }
+
+        /// <summary>
+        /// The type attribute
+        /// </summary>
+        public XdbType Type
+        {
+            get { return GetEnumAttr<XdbType>("type"); }
+            set { SetEnumAttr("type", value); }
+        }
+
+        /// <summary>
+        /// The action attribute
+        /// </summary>
+        public XdbAction Action
+        {
+            get { return GetEnumAttr<XdbAction>("action"); }
+            set { SetEnumAttr("action", value); }
+        }
+
+        /// <summary>
+        /// The namespace to store/retrive from.
+        /// </summary>
+        public string NS
+        {
+            get { return GetAttribute("ns"); }
+            set { SetAttribute("ns", value); }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/client/Error.cs b/lib/jabber-net/jabber/protocol/client/Error.cs
new file mode 100644
index 0000000..6da56c8
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/client/Error.cs
@@ -0,0 +1,428 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.client
+{
+    /*
+    /// <summary>
+    /// Error codes for IQ and message
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum ErrorCode
+    {
+        /// <summary>
+        ///  None specified.
+        /// </summary>
+        none = -1,
+        /// <summary>
+        /// Gone (302)
+        /// </summary>
+        GONE = 302,
+        /// <summary>
+        /// Bad request (400)
+        /// </summary>
+        BAD_REQUEST             = 400,
+        /// <summary>
+        /// Unauthorized (401)
+        /// </summary>
+        UNAUTHORIZED            = 401,
+        /// <summary>
+        /// Payment required (402)
+        /// </summary>
+        PAYMENT_REQUIRED        = 402,
+        /// <summary>
+        /// Forbidden (403)
+        /// </summary>
+        FORBIDDEN               = 403,
+        /// <summary>
+        /// Not found (404)
+        /// </summary>
+        NOT_FOUND               = 404,
+        /// <summary>
+        /// Not allowed (405)
+        /// </summary>
+        NOT_ALLOWED             = 405,
+        /// <summary>
+        /// Not acceptable (406)
+        /// </summary>
+        NOT_ACCEPTABLE          = 406,
+        /// <summary>
+        /// Registration required (407)
+        /// </summary>
+        REGISTRATION_REQUIRED   = 407,
+        /// <summary>
+        /// Request timeout (408)
+        /// </summary>
+        REQUEST_TIMEOUT         = 408,
+        /// <summary>
+        /// Conflict (409)
+        /// </summary>
+        CONFLICT                = 409,
+        /// <summary>
+        /// Internal server error (500)
+        /// </summary>
+        INTERNAL_SERVER_ERROR   = 500,
+        /// <summary>
+        /// Not implemented (501)
+        /// </summary>
+        NOT_IMPLEMENTED         = 501,
+        /// <summary>
+        /// Remote server error (502)
+        /// </summary>
+        REMOTE_SERVER_ERROR     = 502,
+        /// <summary>
+        /// Service unavailable (503)
+        /// </summary>
+        SERVICE_UNAVAILABLE     = 503,
+        /// <summary>
+        /// Remote server timeout (504)
+        /// </summary>
+        REMOTE_SERVER_TIMEOUT   = 504,
+        /// <summary>
+        /// Disconnected (510)
+        /// </summary>
+        DISCONNECTED            = 510
+    }
+     */
+
+    /// <summary>
+    /// See RFC 3920, section 9.3.2.  These are the possible error types.
+    /// </summary>
+    public enum ErrorType
+    {
+        /// <summary>
+        /// None specified (protocol error)
+        /// </summary>
+        NONE = -1,
+        /// <summary>
+        /// do not retry (the error is unrecoverable)
+        /// </summary>
+        cancel,
+        /// <summary>
+        /// proceed (the condition was only a warning)
+        /// </summary>
+        @continue,
+        /// <summary>
+        /// retry after changing the data sent
+        /// </summary>
+        modify,
+        /// <summary>
+        /// retry after providing credentials
+        /// </summary>
+        auth,
+        /// <summary>
+        /// retry after waiting (the error is temporary)
+        /// </summary>
+        wait
+    }
+
+
+    /// <summary>
+    /// Error IQ
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class IQError : IQ
+    {
+        /// <summary>
+        /// Create an error IQ with the given code and message.
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="condition"></param>
+        public IQError(XmlDocument doc, string condition) : base(doc)
+        {
+            this.Type = IQType.error;
+            Error e = Error.GetStanzaError(doc, condition);
+            this.AppendChild(e);
+        }
+    }
+
+    /// <summary>
+    /// Error in a message or IQ.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Error : Element
+    {
+        /// <summary>
+        /// modify      400
+        /// </summary>
+        public const string BAD_REQUEST = "bad-request";
+        /// <summary>
+        /// cancel      409
+        /// </summary>
+        public const string CONFLICT = "conflict";
+        /// <summary>
+        /// cancel  501
+        /// </summary>
+        public const string FEATURE_NOT_IMPLEMENTED = "feature-not-implemented";
+        /// <summary>
+        /// auth    403
+        /// </summary>
+        public const string FORBIDDEN = "forbidden";
+        /// <summary>
+        ///     modify  302 (permanent)
+        /// </summary>
+        public const string GONE = "gone";
+        /// <summary>
+        ///     wait    500
+        /// </summary>
+        public const string INTERNAL_SERVER_ERROR = "internal-server-error";
+        /// <summary>
+        ///     cancel  404
+        /// </summary>
+        public const string ITEM_NOT_FOUND = "item-not-found";
+        /// <summary>
+        ///     modify  400
+        /// </summary>
+        public const string JID_MALFORMED = "jid-malformed";
+        /// <summary>
+        ///     modify  406
+        /// </summary>
+        public const string NOT_ACCEPTABLE = "not-acceptable";
+        /// <summary>
+        ///     cancel  405
+        /// </summary>
+        public const string NOT_ALLOWED = "not-allowed";
+        /// <summary>
+        ///     auth    401
+        /// </summary>
+        public const string NOT_AUTHORIZED = "not-authorized";
+        /// <summary>
+        ///     auth    402
+        /// </summary>
+        public const string PAYMENT_REQUIRED = "payment-required";
+        /// <summary>
+        ///     wait    404
+        /// </summary>
+        public const string RECIPIENT_UNAVAILABLE = "recipient-unavailable";
+        /// <summary>
+        ///     modify  302 (temporary)
+        /// </summary>
+        public const string REDIRECT = "redirect";
+        /// <summary>
+        ///     auth    407
+        /// </summary>
+        public const string REGISTRATION_REQUIRED = "registration-required";
+        /// <summary>
+        ///     cancel  404
+        /// </summary>
+        public const string REMOTE_SERVER_NOT_FOUND = "remote-server-not-found";
+        /// <summary>
+        ///     wait    504
+        /// </summary>
+        public const string REMOTE_SERVER_TIMEOUT = "remote-server-timeout";
+        /// <summary>
+        ///     wait    500
+        /// </summary>
+        public const string RESOURCE_CONSTRAINT = "resource-constraint";
+        /// <summary>
+        ///     cancel  503
+        /// </summary>
+        public const string SERVICE_UNAVAILABLE = "service-unavailable";
+        /// <summary>
+        ///     auth    407
+        /// </summary>
+        public const string SUBSCRIPTION_REQUIRED = "subscription-required";
+        /// <summary>
+        ///     [any]   500
+        /// </summary>
+        public const string UNDEFINED_CONDITION = "undefined-condition";
+        /// <summary>
+        ///     wait    400
+        /// </summary>
+        public const string UNEXPECTED_REQUEST = "unexpected-request";
+
+        private static System.Collections.Hashtable s_errors = new System.Collections.Hashtable();
+        private struct CodeType
+        {
+            public int Code;
+            public ErrorType Type;
+            public CodeType(int code, ErrorType type)
+            {
+                Code = code;
+                Type = type;
+            }
+        }
+
+        static Error()
+        {
+            // See XEP-86.  (http://www.xmpp.org/extensions/xep-0086.html)
+            s_errors.Add(BAD_REQUEST, new CodeType(400, ErrorType.modify));
+            s_errors.Add(CONFLICT, new CodeType(409, ErrorType.cancel));
+            s_errors.Add(FEATURE_NOT_IMPLEMENTED, new CodeType(501, ErrorType.cancel));
+            s_errors.Add(FORBIDDEN, new CodeType(403, ErrorType.auth));
+            s_errors.Add(GONE, new CodeType(302, ErrorType.modify));
+            s_errors.Add(INTERNAL_SERVER_ERROR, new CodeType(500, ErrorType.wait));
+            s_errors.Add(ITEM_NOT_FOUND, new CodeType(404, ErrorType.cancel));
+            s_errors.Add(JID_MALFORMED, new CodeType(400, ErrorType.modify));
+            s_errors.Add(NOT_ACCEPTABLE, new CodeType(406, ErrorType.modify));
+            s_errors.Add(NOT_ALLOWED, new CodeType(405, ErrorType.cancel));
+            s_errors.Add(NOT_AUTHORIZED, new CodeType(401, ErrorType.auth));
+            s_errors.Add(PAYMENT_REQUIRED, new CodeType(402, ErrorType.auth));
+            s_errors.Add(RECIPIENT_UNAVAILABLE, new CodeType(404, ErrorType.wait));
+            s_errors.Add(REDIRECT, new CodeType(302, ErrorType.modify));
+            s_errors.Add(REGISTRATION_REQUIRED, new CodeType(407, ErrorType.auth));
+            s_errors.Add(REMOTE_SERVER_NOT_FOUND, new CodeType(404, ErrorType.cancel));
+            s_errors.Add(REMOTE_SERVER_TIMEOUT, new CodeType(504, ErrorType.wait));
+            s_errors.Add(RESOURCE_CONSTRAINT, new CodeType(500, ErrorType.wait));
+            s_errors.Add(SERVICE_UNAVAILABLE, new CodeType(503, ErrorType.cancel));
+            s_errors.Add(SUBSCRIPTION_REQUIRED, new CodeType(407, ErrorType.auth));
+            s_errors.Add(UNDEFINED_CONDITION, new CodeType(500, ErrorType.NONE));
+            s_errors.Add(UNEXPECTED_REQUEST, new CodeType(400, ErrorType.wait));
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Error(XmlDocument doc) : base("error", doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Error(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create an error element with the element name of the error condition.
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="condition"></param>
+        /// <returns></returns>
+        public static Error GetStanzaError(XmlDocument doc, string condition)
+        {
+            if (!s_errors.Contains(condition))
+                throw new ArgumentException("Unknown condition: " + condition, "condition");
+
+            CodeType ct = (CodeType) s_errors[condition];
+            return GetStanzaError(doc, ct.Type, ct.Code, condition);
+        }
+
+        /// <summary>
+        /// Get an error element with a urn:ietf:params:xml:ns:xmpp-stanzas condition.
+        /// Likely, you want the GetStanzaError(doc, condition) instead.
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="type"></param>
+        /// <param name="code"></param>
+        /// <param name="condition"></param>
+        /// <returns></returns>
+        public static Error GetStanzaError(XmlDocument doc, ErrorType type, int code, string condition)
+        {
+            Error error = new Error(doc);
+            error.ErrorType = type;
+            error.Code = code;
+            error.AppendChild(doc.CreateElement(condition, URI.STANZA_ERROR));
+            return error;
+        }
+
+        /// <summary>
+        /// Get an error stanza with a urn:ietf:params:xml:ns:xmpp-streams condition.
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="type"></param>
+        /// <param name="code"></param>
+        /// <param name="condition"></param>
+        /// <returns></returns>
+        public static Error GetStreamError(XmlDocument doc, ErrorType type, int code, string condition)
+        {
+            Error error = new Error(doc);
+            error.ErrorType = type;
+            error.Code = code;
+            error.AppendChild(doc.CreateElement(condition, URI.STREAM));
+            return error;
+        }
+
+        /// <summary>
+        /// The error code, as an integer.
+        /// </summary>
+        public int Code
+        {
+            get { return GetIntAttr("code"); }
+            set { this.SetAttribute("code", value.ToString()); }
+        }
+
+        /// <summary>
+        /// The type of the error
+        /// </summary>
+        public ErrorType ErrorType
+        {
+            get { return this.GetEnumAttr<ErrorType>("type"); }
+            set { this.SetEnumAttr("type", value); }
+        }
+
+        /// <summary>
+        /// The inner error condition element.
+        /// </summary>
+        public string Condition
+        {
+            get
+            {
+                foreach (XmlNode n in this.ChildNodes)
+                {
+                    if (n.NodeType != XmlNodeType.Element)
+                        continue;
+                    if ((n.NamespaceURI != URI.STANZA_ERROR) &&
+                        (n.NamespaceURI != URI.STREAM_ERROR))
+                        continue;
+                    return n.LocalName;
+                }
+                // uh-oh.  Old-school error.  See section 3 of XEP-86.
+                switch (this.Code)
+                {
+                case 302: return REDIRECT;
+                case 400: return BAD_REQUEST;
+                case 401: return NOT_AUTHORIZED;
+                case 402: return PAYMENT_REQUIRED;
+                case 403: return FORBIDDEN;
+                case 404: return ITEM_NOT_FOUND;
+                case 405: return NOT_ALLOWED;
+                case 406: return NOT_ACCEPTABLE;
+                case 407: return REGISTRATION_REQUIRED;
+                case 408: return REMOTE_SERVER_TIMEOUT;
+                case 409: return CONFLICT;
+                case 500: return INTERNAL_SERVER_ERROR;
+                case 501: return FEATURE_NOT_IMPLEMENTED;
+                case 502: return SERVICE_UNAVAILABLE;
+                case 503: return SERVICE_UNAVAILABLE;
+                case 504: return REMOTE_SERVER_TIMEOUT;
+                case 510: return SERVICE_UNAVAILABLE;
+                }
+                // best we can do.
+                return UNDEFINED_CONDITION;
+            }
+            set { this.InnerXml = ""; this.AddChild(GetStanzaError(this.OwnerDocument, value)); }
+        }
+
+        /// <summary>
+        /// The error message.  Not used anymore (not I18N).
+        /// </summary>
+        public string Message
+        {
+            get { return this.InnerText; }
+            set { this.InnerText = value; }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/client/Factory.cs b/lib/jabber-net/jabber/protocol/client/Factory.cs
new file mode 100644
index 0000000..d8e48fa
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/client/Factory.cs
@@ -0,0 +1,41 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using bedrock.util;
+using jabber.protocol;
+
+namespace jabber.protocol.client
+{
+    /// <summary>
+    /// ElementFactory for the jabber:client namespace.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Factory : IPacketTypes
+    {
+        private static QnameType[] s_qnt = new QnameType[]
+        {
+            new QnameType("presence", URI.CLIENT, typeof(jabber.protocol.client.Presence)),
+            new QnameType("message",  URI.CLIENT, typeof(jabber.protocol.client.Message)),
+            new QnameType("iq",       URI.CLIENT, typeof(jabber.protocol.client.IQ)),
+            new QnameType("error",    URI.CLIENT, typeof(jabber.protocol.client.Error)),
+            // meh.  jabber protocol really isn't right WRT to namespaces.
+            new QnameType("presence", URI.ACCEPT, typeof(jabber.protocol.client.Presence)),
+            new QnameType("message",  URI.ACCEPT, typeof(jabber.protocol.client.Message)),
+            new QnameType("iq",       URI.ACCEPT, typeof(jabber.protocol.client.IQ)),
+            new QnameType("error",    URI.ACCEPT, typeof(jabber.protocol.client.Error))
+        };
+        QnameType[] IPacketTypes.Types { get { return s_qnt; } }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/client/IQ.cs b/lib/jabber-net/jabber/protocol/client/IQ.cs
new file mode 100644
index 0000000..de7ca33
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/client/IQ.cs
@@ -0,0 +1,230 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.client
+{
+    /// <summary>
+    /// IQ type attribute
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum IQType
+    {
+        /// <summary>
+        /// type='get'
+        /// </summary>
+        get,
+        /// <summary>
+        /// type='set'
+        /// </summary>
+        set,
+        /// <summary>
+        /// type='result'
+        /// </summary>
+        result,
+        /// <summary>
+        /// type='error'
+        /// </summary>
+        error
+    }
+
+    /// <summary>
+    /// All IQ packets start here.  The Query property holds the interesting part.
+    /// There should usually be a convenience class next to the Query type, which
+    /// creates an IQ with the appropriate type of query inside.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class IQ : Packet
+    {
+        private bool m_handled = false;
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public IQ(XmlDocument doc) : base("iq", doc)
+        {
+            ID   = NextID();
+            Type = IQType.get;  // get better errors than when there is no type specified.
+        }
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public IQ(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(qname.Name, doc) // Note:  *NOT* base(prefix, qname, doc), so that xpath matches are easier
+        {
+        }
+
+        /// <summary>
+        /// Has this IQ been handled?  Set automatically by GetResponse and GetErrorResponse.  If this is not
+        /// set to true, Jabber-Net will respond automatically with a 501 error.
+        /// </summary>
+        public bool Handled
+        {
+            get { return m_handled; }
+            set { m_handled = value; }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        public IQType Type
+        {
+            get { return GetEnumAttr<IQType>("type"); }
+            set 
+            {
+                IQType cur = this.Type;
+                if (cur == value)
+                    return;
+
+                if (value == IQType.error)
+                {
+                    this.InnerXml = "";
+                    this.GetOrCreateElement<Error>();
+                }
+                SetEnumAttr("type", value);
+            }
+        }
+
+        /// <summary>
+        /// IQ error.
+        /// </summary>
+        public Error Error
+        {
+            get { return GetChildElement<Error>(); }
+            set
+            {
+                this.Type = IQType.error;
+                ReplaceChild<Error>(value);
+            }
+        }
+
+        /// <summary>
+        /// The query tag inside, regardless of namespace.
+        /// If the iq contains something other than query,
+        /// use normal XmlElement routines.
+        /// </summary>
+        public XmlElement Query
+        {
+            get { return this.GetFirstChildElement(); }
+            set { this.InnerXml = ""; this.AddChild(value); }
+        }
+
+#if __MonoCS__
+#pragma warning disable 0809
+#endif
+        /// <summary>
+        /// Swap the To and the From addresses.
+        /// Obsolete: Use GetResponse or GetErrorResponse, now, for IQs.
+        /// </summary>
+        [Obsolete("Use GetResponse or GetErrorResponse, now.")]
+        public override void Swap()
+        {
+            base.Swap();
+        }
+#if __MonoCS__
+#pragma warning restore 0809
+#endif
+
+        /// <summary>
+        /// Swap the to and from, set the type to result.
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <returns></returns>
+        public IQ GetResponse(XmlDocument doc)
+        {
+            IQ resp = new IQ(doc);
+            resp.From = this.To;
+            resp.To = this.From;
+            resp.ID = this.ID;
+            resp.Type = IQType.result;
+
+            XmlElement q = this.Query;
+            if (q != null)
+            {
+                if (q is Element)
+                    resp.AppendChild((XmlElement)((Element)q).CloneNode(true, doc));
+                else
+                    resp.AppendChild(doc.ImportNode(q, true));
+            }
+
+            this.Handled = true;
+            return resp;
+        }
+
+        /// <summary>
+        /// Respond to this IQ with an error.
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="condition"></param>
+        /// <returns></returns>
+        public IQ GetErrorResponse(XmlDocument doc, string condition)
+        {
+            IQ resp = new IQError(doc, condition);
+            resp.From = this.To;
+            resp.To = this.From;
+            resp.ID = this.ID;
+            resp.Type = IQType.error;
+
+            XmlElement q = this.Query;
+            if (q != null)
+            {
+                if (q is Element)
+                    resp.AppendChild((XmlElement)((Element)q).CloneNode(true, doc));
+                else
+                    resp.AppendChild(doc.ImportNode(q, true));
+            }
+
+            this.Handled = true;
+            return resp;
+        }
+    }
+
+    /// <summary>
+    /// An IQ subclass that allows typed access to its first child,
+    /// through the Instruction property.
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    [SVN(@"$Id$")]
+    public class TypedIQ<T> : IQ
+        where T : Element
+    {
+        /// <summary>
+        /// Create an IQ to send out, with an instance of the specified
+        /// type as a child.
+        /// </summary>
+        /// <param name="doc"></param>
+        public TypedIQ(XmlDocument doc) : base(doc)
+        {
+            CreateChildElement<T>();
+        }
+
+        /// <summary>
+        /// The child element (often "query") with the command for this IQ.
+        /// </summary>
+        public T Instruction
+        {
+            get { return GetChildElement<T>(); }
+            set { ReplaceChild<T>(value); }
+        }
+    }
+
+}
diff --git a/lib/jabber-net/jabber/protocol/client/Message.cs b/lib/jabber-net/jabber/protocol/client/Message.cs
new file mode 100644
index 0000000..6954e94
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/client/Message.cs
@@ -0,0 +1,185 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.client
+{
+    /// <summary>
+    /// Message type attribute
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum MessageType
+    {
+        /// <summary>
+        /// Normal message
+        /// </summary>
+        normal = -1,
+        /// <summary>
+        /// Error message
+        /// </summary>
+        error,
+        /// <summary>
+        /// Chat (one-to-one) message
+        /// </summary>
+        chat,
+        /// <summary>
+        /// Groupchat
+        /// </summary>
+        groupchat,
+        /// <summary>
+        /// Headline
+        /// </summary>
+        headline
+    }
+    /// <summary>
+    /// A client-to-client message.
+    /// TODO: Some XHTML is supported by setting the .Html property,
+    /// but extra xmlns="" get put everywhere at the moment.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Message : Packet
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Message(XmlDocument doc) : base("message", doc)
+        {
+            ID = NextID();
+        }
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Message(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(qname.Name, doc)  // Note:  *NOT* base(prefix, qname, doc), so that xpath matches are easier
+        {
+        }
+
+        /// <summary>
+        /// The message type attribute
+        /// </summary>
+        public MessageType Type
+        {
+            get { return (MessageType) GetEnumAttr("type", typeof(MessageType)); }
+            set
+            {
+                if (value == MessageType.normal)
+                    RemoveAttribute("type");
+                else
+                    SetAttribute("type", value.ToString());
+            }
+        }
+
+        private void NormalizeHtml(XmlElement body, string html)
+        {
+            XmlDocument d = new XmlDocument();
+            d.LoadXml("<html xmlns='" + URI.XHTML + "'>" + html + "</html>");
+            foreach (XmlNode node in d.DocumentElement.ChildNodes)
+            {
+                body.AppendChild(this.OwnerDocument.ImportNode(node, true));
+            }
+        }
+
+        /// <summary>
+        /// On set, creates both an html element, and a body element, which will
+        /// have the de-html'd version of the html element.
+        /// </summary>
+        public string Html
+        {
+            get
+            {
+                // Thanks, Mr. Postel.
+                XmlElement h = this["html"];
+                if (h == null)
+                    return "";
+                XmlElement b = h["body"];
+                if (b == null)
+                    return "";
+                string xml = b.InnerXml;
+                // HACK: yeah, yeah, I know.
+                return xml.Replace(" xmlns=\"" + URI.XHTML + "\"", "");
+            }
+            set
+            {
+                XmlElement html = GetOrCreateElement("html", URI.XHTML_IM, null);
+                XmlElement body = html["body", URI.XHTML];
+                if (body == null)
+                {
+                    body =  this.OwnerDocument.CreateElement(null, "body", URI.XHTML);
+                    html.AppendChild(body);
+                }
+                else
+                    body.RemoveAll();
+                NormalizeHtml(body, value);
+                this.Body = body.InnerText;
+            }
+        }
+
+        /// <summary>
+        /// The message body
+        /// </summary>
+        public string Body
+        {
+            get { return GetElem("body"); }
+            set { SetElem("body", value); }
+        }
+
+        /// <summary>
+        /// The message thread
+        /// TODO: some help to generate these, please.
+        /// </summary>
+        public string Thread
+        {
+            get { return GetElem("thread"); }
+            set { SetElem("thread", value); }
+        }
+        /// <summary>
+        /// The message subject
+        /// </summary>
+        public string Subject
+        {
+            get { return GetElem("subject"); }
+            set { SetElem("subject", value); }
+        }
+        /// <summary>
+        /// The first x tag, regardless of namespace.
+        /// </summary>
+        [Obsolete("This almost certainly doesn't do what you want.")]
+        public XmlElement X
+        {
+            get { return this["x"]; }
+            set { this.AddChild(value); }
+        }
+
+        /// <summary>
+        /// Message error.
+        /// </summary>
+        public Error Error
+        {
+            get { return GetChildElement<Error>(); }
+            set
+            {
+                this.Type = MessageType.error;
+                ReplaceChild<Error>(value);
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/client/Presence.cs b/lib/jabber-net/jabber/protocol/client/Presence.cs
new file mode 100644
index 0000000..c832f80
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/client/Presence.cs
@@ -0,0 +1,362 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+using jabber.protocol.x;
+
+namespace jabber.protocol.client
+{
+    /// <summary>
+    /// Presence type attribute
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum PresenceType
+    {
+        /// <summary>
+        /// None specified
+        /// </summary>
+        available = -1,
+        /// <summary>
+        /// May I subscribe to you?
+        /// </summary>
+        subscribe,
+        /// <summary>
+        /// Yes, you may subscribe.
+        /// </summary>
+        subscribed,
+        /// <summary>
+        /// Unsubscribe from this entity.
+        /// </summary>
+        unsubscribe,
+        /// <summary>
+        /// No, you may not subscribe.
+        /// </summary>
+        unsubscribed,
+        /// <summary>
+        /// Offline
+        /// </summary>
+        unavailable,
+        /// <summary>
+        /// server-side only.
+        /// </summary>
+        probe,
+        /// <summary>
+        /// A presence error.
+        /// </summary>
+        error,
+        /// <summary>
+        /// Invisible presence: we're unavailable to them, but still see
+        /// theirs.
+        /// </summary>
+        invisible
+    }
+
+    /// <summary>
+    /// Client presence packet.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Presence : Packet, IComparable<Presence>, IComparable
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Presence(XmlDocument doc) :
+            base("presence", doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Presence(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(qname.Name, doc)  // Note:  *NOT* base(prefix, qname, doc), so that xpath matches are easier
+        {
+        }
+
+        /// <summary>
+        /// Presence type
+        /// </summary>
+        public PresenceType Type
+        {
+            get { return (PresenceType) GetEnumAttr("type", typeof(PresenceType)); }
+            set
+            {
+                if (value == PresenceType.available)
+                    RemoveAttribute("type");
+                else
+                    SetAttribute("type", value.ToString());
+            }
+        }
+
+        /// <summary>
+        /// Presence status
+        /// </summary>
+        public string Status
+        {
+            get { return GetElem("status"); }
+            set { SetElem("status", value); }
+        }
+
+        /// <summary>
+        /// Presence show
+        /// </summary>
+        public string Show
+        {
+            get { return GetElem("show"); }
+            set { SetElem("show", value); }
+        }
+
+        /// <summary>
+        /// Priority for this resource.
+        /// </summary>
+        public string Priority
+        {
+            get { return GetElem("priority"); }
+            set { SetElem("priority", value); }
+        }
+
+        /// <summary>
+        /// An integer version of the priority, constrained to -128..127.  0 if there was no priority element or it wasn't an integer.
+        /// </summary>
+        public int IntPriority
+        {
+            get
+            {
+                String pri = Priority;
+                if ((pri == null) || (pri == ""))
+                    return 0;
+                try
+                {
+                    int i = int.Parse(pri);
+                    if (i < -128)
+                        return -128;
+                    if (i > 127)
+                        return 127;
+                    return i;
+                }
+                catch (Exception)
+                {
+                    return 0;
+                }
+            }
+            set
+            {
+                SetElem("priority", value.ToString());
+            }
+        }
+
+        /// <summary>
+        /// Presence error.
+        /// </summary>
+        public Error Error
+        {
+            get { return (Error) this["error"]; }
+            set
+            {
+                this.Type = PresenceType.error;
+                ReplaceChild(value);
+            }
+        }
+
+        private static int IntShow(string show)
+        {
+            switch (show)
+            {
+            case "dnd":
+                return 0;
+            case "xa":
+                return 1;
+            case "away":
+                return 2;
+            case "chat":
+                return 4;
+            default:
+                return 3;
+            }
+        }
+        
+        /// <summary>
+        /// Date/Time stamp that the presence was originially received by the sending
+        /// server, if this presence is in response to a probe.
+        /// </summary>
+        public DateTime Stamp
+        {
+            get
+            {
+                jabber.protocol.x.ModernDelay md = GetChildElement<jabber.protocol.x.ModernDelay>();
+                if (md != null)
+                    return md.Stamp;
+                jabber.protocol.x.Delay delay = GetChildElement<jabber.protocol.x.Delay>();
+                if (delay != null)
+                    return delay.Stamp;
+                return DateTime.MinValue;
+            }
+            set
+            {
+                jabber.protocol.x.ModernDelay md = GetChildElement<jabber.protocol.x.ModernDelay>();
+                if (md != null)
+                {
+                    md.Stamp = value;
+                    return;
+                }
+                jabber.protocol.x.Delay delay = GetChildElement<jabber.protocol.x.Delay>();
+                if (delay != null)
+                {
+                    delay.Stamp = value;
+                    return;
+                }
+                md = new jabber.protocol.x.ModernDelay(this.OwnerDocument);
+                md.Stamp = value;
+                this.AddChild(md);
+            }
+        }
+
+        /// <summary>
+        /// If there is a stamp, returns it, otherwise looks for and adds a new stamp element.
+        /// This method should never be called for presence that is to be sent out, since it 
+        /// will add non-standard protocol to the presence.
+        /// </summary>
+        public DateTime ReceivedTime
+        {
+            get
+            {
+                DateTime dt = this.Stamp;
+                if (dt != DateTime.MinValue)
+                    return dt;
+                const string RECEIVED = "http://cursive.net/protocol/received";
+                XmlElement el = this["x", RECEIVED];
+                if (el != null)
+                    return Element.DateTimeProfile(el.InnerText);
+                dt = DateTime.Now;
+                el = OwnerDocument.CreateElement("x", RECEIVED);
+                el.InnerText = Element.DateTimeProfile(dt);
+                this.AppendChild(el);
+                return dt;
+            }
+        }
+
+        /// <summary>
+        /// Compare two presences (from the same bare JID, but from
+        /// different resources), to determine which is "more
+        /// available".
+        /// </summary>
+        /// <param name="first"></param>
+        /// <param name="second"></param>
+        /// <returns></returns>
+        public static bool operator<(Presence first, Presence second)
+        {
+            return (((IComparable<Presence>)first).CompareTo(second) == -1);
+        }
+
+        /// <summary>
+        /// Compare two presences (from the same bare JID, but from
+        /// different resources), to determine which is "more
+        /// available".
+        /// </summary>
+        /// <param name="first"></param>
+        /// <param name="second"></param>
+        /// <returns></returns>
+        public static bool operator>(Presence first, Presence second)
+        {
+            return (((IComparable<Presence>)first).CompareTo(second) == 1);
+        }
+
+        #region IComparable<Presence> Members
+
+        /// <summary>
+        /// Compare this presence element with another, first by priority, 
+        /// then by show, then by time received.
+        /// </summary>
+        /// <param name="other"></param>
+        /// <returns>
+        ///    Less than zero 
+        ///     This object is less than the other parameter.
+        ///    Zero 
+        ///     This object is equal to other. 
+        ///    Greater than zero 
+        ///     This object is greater than other. 
+        /// </returns>
+        public int CompareTo(Presence other)
+        {
+            /*
+            Less than zero 
+             This object is less than the other parameter.
+ 
+            Zero 
+             This object is equal to other. 
+ 
+            Greater than zero 
+             This object is greater than other. 
+
+             */
+            if ((object)this == (object)other)
+                return 0;
+
+            if (other == null)
+                return 1;
+
+            int tp = this.IntPriority;
+            int op = other.IntPriority;
+            if (tp > op)
+                return 1;
+            if (tp < op)
+                return -1;
+
+            // equal priority
+            int ts = IntShow(this.Show);
+            int os = IntShow(other.Show);
+
+            if (ts > os)
+                return 1;
+            if (ts < os)
+                return -1;
+
+            // equal show
+            return this.ReceivedTime.CompareTo(other.ReceivedTime);
+        }
+
+        #endregion
+
+        #region IComparable Members
+
+        /// <summary>
+        /// Compare this presence element with another, first by priority, 
+        /// then by show, then by time received.
+        /// </summary>
+        /// <param name="other"></param>
+        /// <returns>
+        ///    Less than zero 
+        ///     This object is less than the other parameter.
+        ///    Zero 
+        ///     This object is equal to other. 
+        ///    Greater than zero 
+        ///     This object is greater than other. 
+        /// </returns>
+        public int CompareTo(object other)
+        {
+            if (other is Presence)
+                return CompareTo((Presence)other);
+            return 1;
+        }
+
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/client/ProtocolException.cs b/lib/jabber-net/jabber/protocol/client/ProtocolException.cs
new file mode 100644
index 0000000..8f00f0c
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/client/ProtocolException.cs
@@ -0,0 +1,112 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.client
+{
+    /// <summary>
+    /// Invalid protocol received.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class BadProtocolException : Exception
+    {
+        private XmlElement m_proto = null;
+        private string m_msg = null;
+
+        /// <summary>
+        /// Create a protocol exception
+        /// </summary>
+        /// <param name="badProtocol">The protocol that was bad.  Typically the top-most (stanza) element.</param>
+        /// <param name="message">An optional message.  May be null.</param>
+        public BadProtocolException(XmlElement badProtocol, string message)
+        {
+            m_proto = badProtocol;
+            m_msg = message;
+        }
+
+        /// <summary>
+        /// Gets a message that describes the current exception.
+        /// </summary>
+        public override string Message
+        {
+            get
+            {
+                if (m_msg == null)
+                    return string.Format("Invalid protocol: {0}", m_proto.OuterXml);
+                return string.Format("Invalid protocol ({0}): {1}", m_proto.OuterXml, m_msg);
+            }
+        }
+    }
+
+    /// <summary>
+    /// A jabber error, in an IQ.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class IQException : Exception
+    {
+        // TODO: fix this up for new error codes.
+        private int m_code;
+        private string m_message;
+
+        /// <summary>
+        /// An authorization exception from an IQ.
+        /// TODO: Add constructor for code/message
+        /// TODO: understand v1 errors
+        /// </summary>
+        /// <param name="iq"></param>
+        public IQException(IQ iq)
+        {
+            if (iq == null)
+            {
+                //timeout
+                m_code = 504;
+                m_message = "Request timed out";
+            }
+            else
+            {
+                Error e = iq.Error;
+                m_code = e.Code;
+                m_message = e.InnerText;
+            }
+        }
+
+        /// <summary>
+        /// The Jabber error number
+        /// </summary>
+        public int Code
+        {
+            get { return m_code; }
+        }
+
+        /// <summary>
+        /// The text description of the message
+        /// </summary>
+        public string Description
+        {
+            get { return m_message; }
+        }
+
+        /// <summary>
+        /// Return the error code and message.
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            return string.Format("Error {0}: {1}", m_code, m_message);
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/Agents.cs b/lib/jabber-net/jabber/protocol/iq/Agents.cs
new file mode 100644
index 0000000..c11d0b0
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/Agents.cs
@@ -0,0 +1,229 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.iq
+{
+    // <pre>
+    // <iq from='jabber.org' id='jcl_17' to='hildjj at jabber.org/Work' type='result'>
+    //   <query xmlns='jabber:iq:agents'>
+    //     <agent jid='users.jabber.org'>
+    //       <name>Jabber User Directory</name>
+    //       <service>jud</service>
+    //       <search/>
+    //       <register/>
+    //     </agent>
+    //   </query>
+    // </iq>
+    // </pre>
+    /// <summary>
+    /// IQ packet with an agents query element inside.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class AgentsIQ : jabber.protocol.client.TypedIQ<AgentsQuery>
+    {
+        /// <summary>
+        /// Create an agents IQ packet.
+        /// </summary>
+        /// <param name="doc"></param>
+        public AgentsIQ(XmlDocument doc) : base(doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// An agents query element.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class AgentsQuery : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public AgentsQuery(XmlDocument doc) : base("query", URI.AGENTS, doc)
+        {
+        }
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public AgentsQuery(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Add an agent to the list
+        /// </summary>
+        /// <returns></returns>
+        public Agent AddAgent()
+        {
+            return CreateChildElement<Agent>();
+        }
+
+        /// <summary>
+        /// Get the list of agents
+        /// </summary>
+        /// <returns></returns>
+        public Agent[] GetAgents()
+        {
+            return GetElements<Agent>().ToArray();
+        }
+    }
+
+    /// <summary>
+    /// Agent items
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Agent : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Agent(XmlDocument doc) : base("agent", URI.AGENTS, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Agent(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The agent's JID
+        /// </summary>
+        public JID JID
+        {
+            get { return GetAttr("jid"); }
+            set { this.SetAttr("jid", value.ToString()); }
+        }
+
+        /// <summary>
+        /// The agent's name
+        /// </summary>
+        public string AgentName
+        {
+            get { return GetElem("name"); }
+            set { SetElem("name", value); }
+        }
+
+        /// <summary>
+        /// The agent's description
+        /// </summary>
+        public string Description
+        {
+            get { return GetElem("description"); }
+            set { SetElem("description", value); }
+        }
+
+        /// <summary>
+        /// Is the agent a transport?
+        /// </summary>
+        public bool Transport
+        {
+            get { return this["transport"] != null; }
+            set
+            {
+                if (value)
+                {
+                    SetElem("transport", null);
+                }
+                else
+                {
+                    RemoveElem("transport");
+                }
+            }
+        }
+
+        /// <summary>
+        /// Is the agent for groupchat?
+        /// </summary>
+        public bool Groupchat
+        {
+            get { return this["groupchat"] != null; }
+            set
+            {
+                if (value)
+                {
+                    SetElem("groupchat", null);
+                }
+                else
+                {
+                    RemoveElem("groupchat");
+                }
+            }
+        }
+
+        /// <summary>
+        /// The agent service name.
+        /// </summary>
+        public string Service
+        {
+            get { return GetElem("service"); }
+            set { SetElem("service", value); }
+        }
+
+        /// <summary>
+        /// Is the agent a registrar?
+        /// </summary>
+        public bool Register
+        {
+            get { return this["register"] != null; }
+            set
+            {
+                if (value)
+                {
+                    SetElem("register", null);
+                }
+                else
+                {
+                    RemoveElem("register");
+                }
+            }
+        }
+
+        /// <summary>
+        /// Is the agent for JUD?
+        /// </summary>
+        public bool Search
+        {
+            get { return this["search"] != null; }
+            set
+            {
+                if (value)
+                {
+                    SetElem("search", null);
+                }
+                else
+                {
+                    RemoveElem("search");
+                }
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/Auth.cs b/lib/jabber-net/jabber/protocol/iq/Auth.cs
new file mode 100644
index 0000000..2d0be22
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/Auth.cs
@@ -0,0 +1,175 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Diagnostics;
+using System.Security.Cryptography;
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.iq
+{
+    /// <summary>
+    /// An auth IQ.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class AuthIQ : jabber.protocol.client.TypedIQ<Auth>
+    {
+        /// <summary>
+        /// Create an Auth IQ.
+        /// </summary>
+        /// <param name="doc"></param>
+        public AuthIQ(XmlDocument doc) : base(doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Client authentication, with digest support.  Call SetAuth() to compute
+    /// the digest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Auth : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Auth(XmlDocument doc) :
+            base("query", URI.AUTH, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Auth(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Set the authentication information.
+        /// TODO: 0k
+        /// </summary>
+        /// <param name="username">The user name.  NOT the JID.</param>
+        /// <param name="password">The user's password.</param>
+        /// <param name="StreamID">The id from the stream:stream
+        /// that the server sent, or null for plaintext.</param>
+        public void SetDigest(string username, string password, string StreamID)
+        {
+            Debug.Assert(username != null);
+            Debug.Assert(password != null);
+            Debug.Assert(StreamID != null);
+            this.Username = username;
+            this.Digest = ShaHash(StreamID, password);
+        }
+        /// <summary>
+        /// Set the authentication information, for plaintext auth.
+        /// </summary>
+        /// <param name="username">The user name.  NOT the JID.</param>
+        /// <param name="password">The user's password.</param>
+        public void SetAuth(string username, string password)
+        {
+            Debug.Assert(username != null);
+            Debug.Assert(password != null);
+            this.Username = username;
+            this.Password = password;
+        }
+
+        /// <summary>
+        /// Set the zero-knowledge information for this iq.
+        /// </summary>
+        /// <param name="username"></param>
+        /// <param name="password"></param>
+        /// <param name="token"></param>
+        /// <param name="sequence"></param>
+        public void SetZeroK(string username,
+            string password,
+            string token,
+            int    sequence)
+        {
+            Debug.Assert(username != null);
+            this.Username = username;
+            this.Hash = Element.ZeroK(password, token, sequence);
+        }
+
+        /// <summary>
+        /// The user's account name.  NOT the JID.
+        /// </summary>
+        public string Username
+        {
+            get { return GetElem("username"); }
+            set { SetElem("username", value); }
+        }
+
+        /// <summary>
+        /// The plaintext password.
+        /// </summary>
+        public string Password
+        {
+            get { return GetElem("password"); }
+            set { SetElem("password", value); }
+        }
+
+        /// <summary>
+        /// SHA1 hash of the StreamID and the password.
+        /// </summary>
+        public string Digest
+        {
+            get { return GetElem("digest"); }
+            set { SetElem("digest", value); }
+        }
+
+        /// <summary>
+        /// The resource to connect with.
+        /// </summary>
+        public string Resource
+        {
+            get { return GetElem("resource"); }
+            set { SetElem("resource", value); }
+        }
+
+        /// <summary>
+        /// Gets the zero-k token.
+        /// </summary>
+        public string Token
+        {
+            get { return GetElem("token"); }
+            set { SetElem("token", value); }
+        }
+
+        /// <summary>
+        /// Zero-k sequence
+        /// </summary>
+        public int Sequence
+        {
+            get { return Int32.Parse(GetElem("sequence")); }
+            set { SetElem("sequence", value.ToString()); }
+        }
+
+        /// <summary>
+        /// Zero-k hash.  NOT DIGEST!
+        /// </summary>
+        public string Hash
+        {
+            get { return GetElem("hash"); }
+            set { SetElem("hash", value); }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/Bookmarks.cs b/lib/jabber-net/jabber/protocol/iq/Bookmarks.cs
new file mode 100644
index 0000000..6bca23f
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/Bookmarks.cs
@@ -0,0 +1,344 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Diagnostics;
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.iq
+{
+    /// <summary>
+    /// An IQ in jabber:iq:private, with a bookmarks body.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class BookmarksIQ : PrivateIQ
+	{
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public BookmarksIQ(XmlDocument doc) : base(doc)
+        {
+            this.Instruction.AddChild(new Bookmarks(doc));
+        }
+
+        /// <summary>
+        /// Get the bookmarks element.
+        /// </summary>
+        public Bookmarks Bookmarks
+        {
+            get { return this.Instruction.GetChildElement<Bookmarks>(); }
+        }
+	}
+
+    /// <summary>
+    /// The bookmarks to be stored.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Bookmarks : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public Bookmarks(XmlDocument doc) :
+            base("storage", URI.BOOKMARKS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound.
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Bookmarks(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Get all of the URLs contained in the bookmark list.
+        /// </summary>
+        /// <returns></returns>
+        public BookmarkURL[] GetUrls()
+        {
+            return this.GetElements<BookmarkURL>().ToArray();
+        }
+
+        /// <summary>
+        /// Add a URL bookmark
+        /// </summary>
+        /// <param name="URL">The URL to add</param>
+        /// <param name="name">Descriptive text</param>
+        /// <returns></returns>
+        public BookmarkURL AddURL(string URL, string name)
+        {
+            BookmarkURL u = new BookmarkURL(this.OwnerDocument);
+            u.URL = URL;
+            u.URLName = name;
+            this.AddChild(u);
+            return u;
+        }
+
+        /// <summary>
+        /// Get all of the conferences contained in the bookmark list.
+        /// </summary>
+        /// <returns></returns>
+        public BookmarkConference[] GetConferences()
+        {
+            return this.GetElements<BookmarkConference>().ToArray();
+        }
+
+        /// <summary>
+        /// Add a conference room to the bookmark list
+        /// </summary>
+        /// <param name="jid"></param>
+        /// <param name="name"></param>
+        /// <param name="autoJoin"></param>
+        /// <param name="nick"></param>
+        /// <returns></returns>
+        public BookmarkConference AddConference(JID jid, string name, bool autoJoin, string nick)
+        {
+            BookmarkConference c = new BookmarkConference(this.OwnerDocument);
+            c.JID = jid;
+            c.ConferenceName = name;
+            c.AutoJoin = autoJoin;
+            if (nick != null)
+                c.Nick = nick;
+            this.AddChild(c);
+            return c;
+        }
+
+        /// <summary>
+        /// Get all of the notes contained in the bookmark list.
+        /// </summary>
+        /// <returns></returns>
+        public BookmarkNote[] GetNotes()
+        {
+            return this.GetElements<BookmarkNote>().ToArray();
+        }
+
+        /// <summary>
+        /// Add a note to the bookmark list.
+        /// </summary>
+        /// <param name="jid"></param>
+        /// <param name="text"></param>
+        /// <returns></returns>
+        public BookmarkNote AddNote(JID jid, string text)
+        {
+            BookmarkNote n = new BookmarkNote(this.OwnerDocument);
+            n.JID = jid;
+            n.Text = text;
+            this.AddChild(n);
+            return n;
+        }
+    }
+
+    /// <summary>
+    /// A URL stored in bookmarks.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class BookmarkURL : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public BookmarkURL(XmlDocument doc) :
+            base("url", URI.BOOKMARKS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound.
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public BookmarkURL(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The HTTP or HTTPS URL of the web page, according to spec.
+        /// In practice, any URI.
+        /// </summary>
+        public string URL
+        {
+            get { return GetAttr("url"); }
+            set { SetAttr("url", value); }
+        }
+
+        /// <summary>
+        /// A friendly name for the bookmark.
+        /// </summary>
+        public string URLName
+        {
+            get { return GetAttr("name"); }
+            set { SetAttr("name", value); }
+        }
+    }
+
+    /// <summary>
+    /// A conference room name stored in bookmarks
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class BookmarkConference : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public BookmarkConference(XmlDocument doc) :
+            base("conference", URI.BOOKMARKS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound.
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public BookmarkConference(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Should the room be joined on startup?
+        /// </summary>
+        public bool AutoJoin
+        {
+            get 
+            {
+                string aj = GetAttr("autojoin");
+                return (aj == "true") || (aj == "1");
+            }
+            set 
+            {
+                if (value)
+                    SetAttr("autojoin", "true");
+                else
+                    RemoveAttribute("autojoin");
+            }
+        }
+
+        /// <summary>
+        /// The room at service JID of the room.
+        /// </summary>
+        public JID JID
+        {
+            get { return (JID)GetAttr("jid"); }
+            set { SetAttr("jid", value); }
+        }
+
+        /// <summary>
+        /// A friendly name for the bookmark.
+        /// </summary>
+        public string ConferenceName
+        {
+            get { return GetAttr("name"); }
+            set { SetAttr("name", value); }
+        }
+
+        /// <summary>
+        /// The user's preferred roomnick for the chatroom.
+        /// </summary>
+        public string Nick
+        {
+            get { return GetElem("nick");  }
+            set { SetElem("nick", value);  }
+        }
+
+        /// <summary>
+        /// Plain-text string for the password needed to enter a password-protected room. 
+        /// For security reasons, use of this element is NOT RECOMMENDED.
+        /// 
+        /// TODO: should this be marked Obsolete?
+        /// </summary>
+        public string Password
+        {
+            get { return GetElem("password"); }
+            set { SetElem("password", value); }
+        }
+    }
+
+    /// <summary>
+    /// A note stored in bookmarks.  Un-specified, but hinted at in version 1.1 of XEP-48.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class BookmarkNote : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public BookmarkNote(XmlDocument doc) :
+            base("note", URI.BOOKMARKS, doc)
+        {
+            Modified = Created = DateTime.UtcNow;
+        }
+
+        /// <summary>
+        /// Create for inbound.
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public BookmarkNote(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The JID to which the note pertains.
+        /// </summary>
+        public JID JID
+        {
+            get { return (JID)GetAttr("jid"); }
+            set { SetAttr("jid", value); }
+        }
+
+        /// <summary>
+        /// The UTC date/time the note was created.
+        /// </summary>
+        public DateTime Created
+        {
+            get { return GetDateTimeAttr("cdate"); }
+            set { SetDateTimeAttr("cdate", value); }
+        }
+
+        /// <summary>
+        /// The UTC date/time the note last modified.
+        /// </summary>
+        public DateTime Modified
+        {
+            get { return GetDateTimeAttr("mdate"); }
+            set { SetDateTimeAttr("mdate", value); }
+        }
+
+        /// <summary>
+        /// The text of the note.
+        /// </summary>
+        public string Text
+        {
+            get { return this.InnerText; }
+            set { this.InnerText = value; }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/Browse.cs b/lib/jabber-net/jabber/protocol/iq/Browse.cs
new file mode 100644
index 0000000..53975de
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/Browse.cs
@@ -0,0 +1,158 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Diagnostics;
+using System.Security.Cryptography;
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.iq
+{
+    /// <summary>
+    /// An browse IQ.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class BrowseIQ : jabber.protocol.client.TypedIQ<Browse>
+    {
+        /// <summary>
+        /// Create a Browse IQ.
+        /// </summary>
+        /// <param name="doc"></param>
+        public BrowseIQ(XmlDocument doc) : base(doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Browse IQ query.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Browse : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Browse(XmlDocument doc) :
+            base("query", URI.BROWSE, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Browse(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The full JabberID of the entity described.
+        /// </summary>
+        public JID JID
+        {
+            get { return GetAttribute("jid"); }
+            set { SetAttribute("jid", value.ToString()); }
+        }
+
+        /// <summary>
+        /// One of the categories from the category list, or a non-standard category prefixed with the string "x-".
+        /// </summary>
+        public string Category
+        {
+            get { return GetAttribute("category"); }
+            set { SetAttribute("category", value); }
+        }
+
+        /// <summary>
+        /// One of the official types from the specified category, or a non-standard type prefixed with the string "x-".
+        /// </summary>
+        public string Type
+        {
+            get { return GetAttribute("type"); }
+            set { SetAttribute("type", value); }
+        }
+
+        /// <summary>
+        /// A friendly name that may be used in a user interface.
+        /// </summary>
+        public string BrowseName
+        {
+            get { return GetAttribute("name"); }
+            set { SetAttribute("name", value); }
+        }
+
+        /// <summary>
+        /// A string containing the version of the node, equivalent to the response provided to a
+        /// query in the 'jabber:iq:version' namespace. This is useful for servers, especially for lists of services
+        /// (see the 'service/serverlist' category/type above).
+        /// </summary>
+        public string Version
+        {
+            get { return GetAttribute("version"); }
+            set { SetAttribute("version", value); }
+        }
+
+        /// <summary>
+        /// Sub-items of this item
+        /// </summary>
+        /// <returns></returns>
+        public Browse[] GetItems()
+        {
+            return GetElements<Browse>().ToArray();
+        }
+
+        /// <summary>
+        /// Add an item to the sub-item list.
+        /// </summary>
+        /// <returns></returns>
+        public Browse AddItem()
+        {
+            return CreateChildElement<Browse>();
+        }
+
+        /// <summary>
+        /// The namespaces advertised by this item.
+        /// </summary>
+        /// <returns></returns>
+        public string[] GetNamespaces()
+        {
+            XmlNodeList nl = GetElementsByTagName("ns", URI.BROWSE);
+            string[] items = new string[nl.Count];
+            int i=0;
+            foreach (XmlNode n in nl)
+            {
+                items[i] = n.InnerText;
+                i++;
+            }
+            return items;
+        }
+
+        /// <summary>
+        /// Add a namespace to the namespaces supported by this item.
+        /// </summary>
+        /// <param name="ns"></param>
+        public void AddNamespace(string ns)
+        {
+            XmlElement e = this.OwnerDocument.CreateElement(null, "ns", URI.BROWSE);
+            e.InnerText = ns;
+            this.AppendChild(e);
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/Disco.cs b/lib/jabber-net/jabber/protocol/iq/Disco.cs
new file mode 100644
index 0000000..b2bc63b
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/Disco.cs
@@ -0,0 +1,552 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Xml;
+
+using bedrock.util;
+using jabber.protocol.x;
+using bedrock.collections;
+
+namespace jabber.protocol.iq
+{
+    /*
+     * <iq
+     *     type='result'
+     *     from='shakespeare.lit'
+     *     to='romeo at montague.net/orchard'
+     *     id='items1'>
+     *   <query xmlns='http://jabber.org/protocol/disco#items' node='music'>
+     *     <item
+     *         jid='people.shakespeare.lit'
+     *         name='Directory of Characters'/>
+     *     <item
+     *         jid='plays.shakespeare.lit'
+     *         name='Play-Specific Chatrooms'/>
+     * </iq>
+     */
+    /// <summary>
+    /// IQ packet with a disco#items query element inside.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class DiscoItemsIQ : jabber.protocol.client.TypedIQ<DiscoItems>
+    {
+        /// <summary>
+        /// Create a disco#items IQ
+        /// </summary>
+        /// <param name="doc"></param>
+        public DiscoItemsIQ(XmlDocument doc) : base(doc)
+        {
+        }
+
+        /// <summary>
+        /// The node on the query.
+        /// </summary>
+        public string Node
+        {
+            get { return this.Instruction.Node; }
+            set { this.Instruction.Node = value; }
+        }
+    }
+
+    /// <summary>
+    /// IQ packet with a disco#info query element inside.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class DiscoInfoIQ : jabber.protocol.client.TypedIQ<DiscoInfo>
+    {
+        /// <summary>
+        /// Create a disco#items IQ
+        /// </summary>
+        /// <param name="doc"></param>
+        public DiscoInfoIQ(XmlDocument doc) : base(doc)
+        {
+        }
+
+        /// <summary>
+        /// The node on the query.
+        /// </summary>
+        public string Node
+        {
+            get {return this.Instruction.Node; }
+            set { this.Instruction.Node = value; }
+        }
+    }
+
+    /*
+     * <iq
+     *     type='result'
+     *     from='plays.shakespeare.lit'
+     *     to='romeo at montague.net/orchard'
+     *     id='info1'>
+     *   <query xmlns='http://jabber.org/protocol/disco#info'>
+     *     <identity
+     *         category='conference'
+     *         type='text'
+     *         name='Play-Specific Chatrooms'/>
+     *     <identity
+     *         category='directory'
+     *         type='room'
+     *         name='Play-Specific Chatrooms'/>
+     * 
+     *     <feature var='gc-1.0'/>
+     *     <feature var='http://jabber.org/protocol/muc'/>
+     *     <feature var='jabber:iq:register'/>
+     *     <feature var='jabber:iq:search'/>
+     *     <feature var='jabber:iq:time'/>
+     *     <feature var='jabber:iq:version'/>
+     *   </query>
+     * </iq>
+     */
+
+
+    /// <summary>
+    /// A disco#items query element.
+    /// See <a href="http://www.xmpp.org/extensions/xep-0030.html">XEP-0030</a> for more information.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class DiscoItems : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public DiscoItems(XmlDocument doc) : base("query", URI.DISCO_ITEMS, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public DiscoItems(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The sub-address of the discovered entity.
+        /// </summary>
+        public string Node
+        {
+            get { return GetAttr("node"); }
+            set { SetAttr("node", value); }
+        }
+
+        /// <summary>
+        /// Add a disco item
+        /// </summary>
+        /// <returns></returns>
+        public DiscoItem AddItem()
+        {
+            return CreateChildElement<DiscoItem>();
+        }
+
+        /// <summary>
+        /// List of disco items
+        /// </summary>
+        /// <returns></returns>
+        public DiscoItem[] GetItems()
+        {
+            return GetElements<DiscoItem>().ToArray();
+        }
+    }
+
+    /// <summary>
+    /// Actions for iq/set in the disco#items namespace.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum DiscoAction
+    {
+        /// <summary>
+        /// None specified
+        /// </summary>
+        NONE = -1,
+        /// <summary>
+        /// Remove this item
+        /// </summary>
+        remove,
+        /// <summary>
+        /// Update this item
+        /// </summary>
+        update
+    }
+
+    /// <summary>
+    /// An item inside a disco#items result.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class DiscoItem : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public DiscoItem(XmlDocument doc) : base("item", URI.DISCO_ITEMS, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public DiscoItem(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The Jabber ID associated with the item.
+        /// </summary>
+        public JID Jid
+        {
+            get { return GetAttr("jid"); }
+            set { SetAttr("jid", value.ToString()); }
+        }
+
+        /// <summary>
+        /// The user-visible name of this node
+        /// </summary>
+        public string Named
+        {
+            get { return GetAttr("name"); }
+            set { SetAttr("name", value); }
+        }
+
+        /// <summary>
+        /// The sub-node associated with this item.
+        /// </summary>
+        public string Node
+        {
+            get { return GetAttr("node"); }
+            set { SetAttr("node", value); }
+        }
+
+        /// <summary>
+        /// Actions for iq/set in the disco#items namespace.
+        /// </summary>
+        public DiscoAction Action
+        {
+            get { return GetEnumAttr<DiscoAction>("action"); }
+            set { SetEnumAttr("action", value); }
+        }
+    }
+
+/*
+<iq
+    type='result'
+    from='balconyscene at plays.shakespeare.lit'
+    to='juliet at capulet.com/balcony'
+    id='info2'>
+  <query xmlns='http://jabber.org/protocol/disco#info'>
+    <identity
+        category='conference'
+        type='text'
+        name='Romeo and Juliet, Act II, Scene II'/>
+    <feature var='gc-1.0'/>
+    <feature var='http://jabber.org/protocol/muc'/>
+    <feature var='http://jabber.org/protocol/feature-neg'/>
+    <feature var='muc-password'/>
+    <feature var='muc-hidden'/>
+    <feature var='muc-temporary'/>
+    <feature var='muc-open'/>
+    <feature var='muc-unmoderated'/>
+    <feature var='muc-nonanonymous'/>
+    <x xmlns='jabber:x:data' type='result'>
+      <field var='FORM_TYPE' type='hidden'>
+        <value>http://jabber.org/network/serverinfo</value>
+      </field>
+      <field var='c2s_port'>
+        <value>5222</value>
+      </field>
+    </x>
+  </query>
+</iq>
+*/
+    /// <summary>
+    /// The information associated with a disco node.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class DiscoInfo : Element
+    {
+        private StringSet m_features = null;
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public DiscoInfo(XmlDocument doc) : base("query", URI.DISCO_INFO, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public DiscoInfo(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The sub-node associated with this item.
+        /// </summary>
+        public string Node
+        {
+            get { return GetAttr("node"); }
+            set { SetAttr("node", value); }
+        }
+
+        /// <summary>
+        /// Add an identity
+        /// </summary>
+        /// <param name="category">The category of the identity.  Required.</param>
+        /// <param name="discoType">The sub-type</param>
+        /// <param name="name">A human-readable string</param>
+        /// <param name="language">The xml:lang, or null to take the requestor's default</param>
+        /// <returns></returns>
+        public DiscoIdentity AddIdentity(string category, string discoType, string name, string language)
+        {
+            DiscoIdentity i = CreateChildElement<DiscoIdentity>();
+            i.Category = category;
+            i.Type = discoType;
+            i.Named = name;
+            i.Lang = language;
+            return i;
+        }
+
+        /// <summary>
+        /// List of identities
+        /// </summary>
+        /// <returns></returns>
+        public DiscoIdentity[] GetIdentities()
+        {
+            return GetElements<DiscoIdentity>().ToArray();
+        }
+
+        /// <summary>
+        /// Add a feature
+        /// </summary>
+        /// <returns></returns>
+        public DiscoFeature AddFeature(string featureURI)
+        {
+            DiscoFeature i = CreateChildElement<DiscoFeature>();
+            i.Var = featureURI;
+            if (m_features != null)
+                m_features.Add(featureURI);
+            return i;
+        }
+
+        /// <summary>
+        /// List of features
+        /// </summary>
+        /// <returns></returns>
+        public DiscoFeature[] GetFeatures()
+        {
+            return GetElements<DiscoFeature>().ToArray();
+        }
+
+        /// <summary>
+        /// Is the given feature URI supported by this entity?
+        /// </summary>
+        /// <param name="featureURI">The URI to check</param>
+        /// <returns></returns>
+        public bool HasFeature(string featureURI)
+        {
+            if (m_features != null)
+                return m_features.Contains(featureURI);
+
+            foreach (DiscoFeature feat in GetElements<DiscoFeature>())
+            {
+                if (feat.Var == featureURI)
+                    return true;
+            }
+            return false;
+        }
+
+        /// <summary>
+        /// Clear all of the features from the 
+        /// </summary>
+        public void ClearFeatures()
+        {
+            this.RemoveElems<DiscoFeature>();
+            m_features = null;
+        }
+
+        /// <summary>
+        /// Get or set a compressed set of features.
+        /// Setting this has the side-effect of removing all existing features, and
+        /// replacing them with the specified ones.
+        /// </summary>
+        public StringSet FeatureSet
+        {
+            get
+            {
+                if (m_features == null)
+                {
+                    m_features = new StringSet();
+                    foreach (DiscoFeature f in GetElements<DiscoFeature>())
+                        m_features.Add(f.Var);
+                }
+                return m_features;
+            }
+            set
+            {
+                ClearFeatures();
+                m_features = new StringSet();
+                foreach (string s in value)
+                    AddFeature(s);
+            }
+        }
+
+        /// <summary>
+        /// Create a XEP-0128 x:data extension, or return the first existing one.
+        /// </summary>
+        /// <returns></returns>
+        public Data CreateExtension()
+        {
+            Data d = GetOrCreateElement<Data>();
+            d.Type = XDataType.result;
+            return d;
+        }
+
+        /// <summary>
+        /// Get or set the first XEP-0128 x:data extension.
+        /// </summary>
+        public Data Extension
+        {
+            get { return GetChildElement<jabber.protocol.x.Data>(); }
+            set { ReplaceChild<Data>(value); }
+        }
+
+        /// <summary>
+        /// In the unlikely event that there are multiple extensions, we need to be able
+        /// to retrieve all of them.  
+        /// </summary>
+        /// <returns></returns>
+        public Data[] GetExtensions()
+        {
+            return GetElements<Data>().ToArray();
+        }
+
+        /// <summary>
+        /// Get the extension with the given XEP-0068 form type.
+        /// </summary>
+        /// <param name="formType">The value of the FORM_TYPE field to search for.</param>
+        /// <returns>null if none found</returns>
+        public Data GetExtension(string formType)
+        {
+            foreach (Data d in GetElements<Data>())
+            {
+                if (d.FormType == formType)
+                    return d;
+            }
+            return null;
+        }
+    }
+
+    /// <summary>
+    /// The identitiy associated with a disco node.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class DiscoIdentity : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public DiscoIdentity(XmlDocument doc) : base("identity", URI.DISCO_INFO, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public DiscoIdentity(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The user-visible name of this node
+        /// </summary>
+        public string Named
+        {
+            get { return GetAttr("name"); }
+            set { SetAttr("name", value); }
+        }
+
+        /// <summary>
+        /// The category of the node
+        /// </summary>
+        public string Category
+        {
+            get { return GetAttr("category"); }
+            set { SetAttr("category", value); }
+        }
+
+        /// <summary>
+        /// The type of the node
+        /// </summary>
+        public string Type
+        {
+            get { return GetAttr("type"); }
+            set { SetAttr("type", value); }
+        }
+
+    }
+
+    /// <summary>
+    /// A feature associated with a disco node.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class DiscoFeature : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public DiscoFeature(XmlDocument doc) : base("feature", URI.DISCO_INFO, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public DiscoFeature(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The namespace name or feature name.
+        /// </summary>
+        public string Var
+        {
+            get { return GetAttr("var"); }
+            set { SetAttr("var", value); }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/Factory.cs b/lib/jabber-net/jabber/protocol/iq/Factory.cs
new file mode 100644
index 0000000..a1c9450
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/Factory.cs
@@ -0,0 +1,151 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+
+using bedrock.util;
+using jabber.protocol;
+
+namespace jabber.protocol.iq
+{
+    /// <summary>
+    /// ElementFactory for all currently supported IQ namespaces.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Factory : IPacketTypes
+    {
+        private static QnameType[] s_qnt = new QnameType[]
+        {
+            new QnameType("query", URI.AUTH,     typeof(jabber.protocol.iq.Auth)),
+            new QnameType("query", URI.REGISTER, typeof(jabber.protocol.iq.Register)),
+            new QnameType("query", URI.ROSTER,   typeof(jabber.protocol.iq.Roster)),
+            new QnameType("item",  URI.ROSTER,   typeof(jabber.protocol.iq.Item)),
+            new QnameType("group", URI.ROSTER,   typeof(jabber.protocol.iq.Group)),
+            new QnameType("query", URI.AGENTS,   typeof(jabber.protocol.iq.AgentsQuery)),
+            new QnameType("agent", URI.AGENTS,   typeof(jabber.protocol.iq.Agent)),
+            new QnameType("query", URI.OOB,      typeof(jabber.protocol.iq.OOB)),
+            new QnameType("query", URI.TIME,     typeof(jabber.protocol.iq.Time)),
+            new QnameType("query", URI.VERSION,  typeof(jabber.protocol.iq.Version)),
+            new QnameType("query", URI.LAST,     typeof(jabber.protocol.iq.Last)),
+            new QnameType("item",  URI.BROWSE,   typeof(jabber.protocol.iq.Browse)),
+            new QnameType("geoloc",URI.GEOLOC,   typeof(jabber.protocol.iq.GeoLoc)),
+            
+            
+            new QnameType("query",      URI.PRIVATE,   typeof(jabber.protocol.iq.Private)),
+            new QnameType("storage",    URI.BOOKMARKS, typeof(jabber.protocol.iq.Bookmarks)),
+            new QnameType("url",        URI.BOOKMARKS, typeof(jabber.protocol.iq.BookmarkURL)),
+            new QnameType("conference", URI.BOOKMARKS, typeof(jabber.protocol.iq.BookmarkConference)),
+            new QnameType("note",       URI.BOOKMARKS, typeof(jabber.protocol.iq.BookmarkNote)),
+
+            // VCard
+            new QnameType("vCard", URI.VCARD, typeof(jabber.protocol.iq.VCard)),
+            new QnameType("N",     URI.VCARD, typeof(jabber.protocol.iq.VCard.VName)),
+            new QnameType("ORG",   URI.VCARD, typeof(jabber.protocol.iq.VCard.VOrganization)),
+            new QnameType("TEL",   URI.VCARD, typeof(jabber.protocol.iq.VCard.VTelephone)),
+            new QnameType("EMAIL", URI.VCARD, typeof(jabber.protocol.iq.VCard.VEmail)),
+            new QnameType("GEO",   URI.VCARD, typeof(jabber.protocol.iq.VCard.VGeo)),
+            new QnameType("PHOTO", URI.VCARD, typeof(jabber.protocol.iq.VCard.VPhoto)),
+            new QnameType("ADR", URI.VCARD, typeof(jabber.protocol.iq.VCard.VAddress)),
+
+            // Disco
+            new QnameType("query",    URI.DISCO_ITEMS, typeof(jabber.protocol.iq.DiscoItems)),
+            new QnameType("item",     URI.DISCO_ITEMS, typeof(jabber.protocol.iq.DiscoItem)),
+            new QnameType("query",    URI.DISCO_INFO, typeof(jabber.protocol.iq.DiscoInfo)),
+            new QnameType("identity", URI.DISCO_INFO, typeof(jabber.protocol.iq.DiscoIdentity)),
+            new QnameType("feature",  URI.DISCO_INFO, typeof(jabber.protocol.iq.DiscoFeature)),
+
+            // PubSub
+            new QnameType("pubsub",        URI.PUBSUB, typeof(jabber.protocol.iq.PubSub)),
+            new QnameType("affiliations",  URI.PUBSUB, typeof(jabber.protocol.iq.Affiliations)),
+            new QnameType("create",        URI.PUBSUB, typeof(jabber.protocol.iq.Create)),
+            new QnameType("items",         URI.PUBSUB, typeof(jabber.protocol.iq.Items)),
+            new QnameType("publish",       URI.PUBSUB, typeof(jabber.protocol.iq.Publish)),
+            new QnameType("retract",       URI.PUBSUB, typeof(jabber.protocol.iq.Retract)),
+            new QnameType("subscribe",     URI.PUBSUB, typeof(jabber.protocol.iq.Subscribe)),
+            new QnameType("subscriptions", URI.PUBSUB, typeof(jabber.protocol.iq.Subscriptions)),
+            new QnameType("unsubscribe",   URI.PUBSUB, typeof(jabber.protocol.iq.Unsubscribe)),
+
+            new QnameType("configure",     URI.PUBSUB, typeof(jabber.protocol.iq.Configure)),
+            new QnameType("options",       URI.PUBSUB, typeof(jabber.protocol.iq.PubSubOptions)),
+            new QnameType("affiliation",   URI.PUBSUB, typeof(jabber.protocol.iq.Affiliation)),
+            new QnameType("item",          URI.PUBSUB, typeof(jabber.protocol.iq.PubSubItem)),
+            new QnameType("subscription",  URI.PUBSUB, typeof(jabber.protocol.iq.PubSubSubscription)),
+
+            // Pubsub event notifications
+            new QnameType("event",         URI.PUBSUB_EVENT, typeof(jabber.protocol.iq.PubSubEvent)),
+            new QnameType("associate",     URI.PUBSUB_EVENT, typeof(jabber.protocol.iq.EventAssociate)),
+            new QnameType("collection",    URI.PUBSUB_EVENT, typeof(jabber.protocol.iq.EventCollection)),
+            new QnameType("configuration", URI.PUBSUB_EVENT, typeof(jabber.protocol.iq.EventConfiguration)),
+            new QnameType("disassociate",  URI.PUBSUB_EVENT, typeof(jabber.protocol.iq.EventDisassociate)),
+            new QnameType("items",         URI.PUBSUB_EVENT, typeof(jabber.protocol.iq.EventItems)),
+            new QnameType("item",          URI.PUBSUB_EVENT, typeof(jabber.protocol.iq.PubSubItem)),
+            new QnameType("purge",         URI.PUBSUB_EVENT, typeof(jabber.protocol.iq.EventPurge)),
+            new QnameType("retract",       URI.PUBSUB_EVENT, typeof(jabber.protocol.iq.EventRetract)),
+            new QnameType("subscription",  URI.PUBSUB_EVENT, typeof(jabber.protocol.iq.EventSubscription)),
+
+            // Pubsub owner use cases
+            new QnameType("pubsub",        URI.PUBSUB_OWNER, typeof(jabber.protocol.iq.PubSubOwner)),
+            new QnameType("affiliations",  URI.PUBSUB_OWNER, typeof(jabber.protocol.iq.OwnerAffliliations)),
+            new QnameType("affiliation",   URI.PUBSUB_OWNER, typeof(jabber.protocol.iq.OwnerAffiliation)),
+            new QnameType("configure",     URI.PUBSUB_OWNER, typeof(jabber.protocol.iq.OwnerConfigure)),
+            new QnameType("default",       URI.PUBSUB_OWNER, typeof(jabber.protocol.iq.OwnerDefault)),
+            new QnameType("delete",        URI.PUBSUB_OWNER, typeof(jabber.protocol.iq.OwnerDelete)),
+            new QnameType("purge",         URI.PUBSUB_OWNER, typeof(jabber.protocol.iq.OwnerPurge)),
+            new QnameType("subscriptions", URI.PUBSUB_OWNER, typeof(jabber.protocol.iq.OwnerSubscriptions)),
+            new QnameType("subscription",  URI.PUBSUB_OWNER, typeof(jabber.protocol.iq.PubSubSubscription)),
+
+            // Pubsub errors
+            new QnameType("closed-node",                    URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.ClosedNode)),
+            new QnameType("configuration-required",         URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.ConfigurationRequired)),
+            new QnameType("invalid-jid",                    URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.InvalidJID)),
+            new QnameType("invalid-options",                URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.InvalidOptions)),
+            new QnameType("invalid-payload",                URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.InvalidPayload)),
+            new QnameType("invalid-subid",                  URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.InvalidSubid)),
+            new QnameType("item-forbidden",                 URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.ItemForbidden)),
+            new QnameType("item-required",                  URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.ItemRequired)),
+            new QnameType("jid-required",                   URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.JIDRequired)),
+            new QnameType("max-items-exceeded",             URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.MaxItemsExceeded)),
+            new QnameType("max-nodes-exceeded",             URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.MaxNodesExceeded)),
+            new QnameType("nodeid-required",                URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.NodeIDRequired)),
+            new QnameType("not-in-roster-group",            URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.NotInRosterGroup)),
+            new QnameType("not-subscribed",                 URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.NotSubscribed)),
+            new QnameType("payload-too-big",                URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.PayloadTooBig)),
+            new QnameType("payload-required",               URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.PayloadRequired)),
+            new QnameType("pending-subscription",           URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.PendingSubscription)),
+            new QnameType("presence-subscription-required", URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.PresenceSubscriptionRequired)),
+            new QnameType("subid-required",                 URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.SubidRequired)),
+            new QnameType("unsupported",                    URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.Unsupported)),
+            new QnameType("unsupported-access-model",       URI.PUBSUB_ERRORS, typeof(jabber.protocol.iq.UnsupportedAccessModel)),
+
+            // Multi-user chat
+            new QnameType("x",       URI.MUC, typeof(jabber.protocol.iq.RoomX)),
+            new QnameType("history", URI.MUC, typeof(jabber.protocol.iq.History)),
+
+            new QnameType("x",       URI.MUC_USER, typeof(jabber.protocol.iq.UserX)),
+            new QnameType("decline", URI.MUC_USER, typeof(jabber.protocol.iq.Decline)),
+            new QnameType("invite",  URI.MUC_USER, typeof(jabber.protocol.iq.Invite)),
+            new QnameType("destroy", URI.MUC_USER, typeof(jabber.protocol.iq.Destroy)),
+            new QnameType("item",    URI.MUC_USER, typeof(jabber.protocol.iq.RoomItem)),
+            new QnameType("actor",   URI.MUC_USER, typeof(jabber.protocol.iq.RoomActor)),
+
+            new QnameType("query",   URI.MUC_ADMIN, typeof(jabber.protocol.iq.AdminQuery)),
+            new QnameType("item",    URI.MUC_ADMIN, typeof(jabber.protocol.iq.AdminItem)),
+
+            new QnameType("query",   URI.MUC_OWNER, typeof(jabber.protocol.iq.OwnerQuery)),
+            new QnameType("destroy", URI.MUC_OWNER, typeof(jabber.protocol.iq.OwnerDestroy)),
+        };
+
+        QnameType[] IPacketTypes.Types { get { return s_qnt; } }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/GeoLoc.cs b/lib/jabber-net/jabber/protocol/iq/GeoLoc.cs
new file mode 100644
index 0000000..964a0c9
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/GeoLoc.cs
@@ -0,0 +1,146 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Diagnostics;
+using System.Security.Cryptography;
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.iq
+{
+    /// <summary>
+    /// A GeoLoc IQ.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class GeoLocIQ : jabber.protocol.client.TypedIQ<GeoLoc>
+    {
+        /// <summary>
+        /// Create a GeoLoc IQ.
+        /// </summary>
+        /// <param name="doc"></param>
+        public GeoLocIQ(XmlDocument doc) : base(doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Geographic location.  See http://www.xmpp.org/extensions/xep-0080.html.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class GeoLoc : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public GeoLoc(XmlDocument doc) :
+            base("geoloc", URI.GEOLOC, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public GeoLoc(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        ///  Altitude above/below sea level, in meters.
+        /// </summary>
+        public double Altitude
+
+        {
+            get { return double.Parse(GetElem("alt")); }
+            set { SetElem("alt", value.ToString()); }
+        }
+
+        /// <summary>
+        /// Assuming decimal degrees to true north.
+        /// Note: this is being further specified in the XEP.
+        /// </summary>
+        public double Bearing
+        {
+            get { return double.Parse(GetElem("bearing")); }
+            set { SetElem("bearing", value.ToString()); }
+        }
+
+        /// <summary>
+        /// GPS datum, defaults to WGS84.
+        /// </summary>
+        public string Datum
+        {
+            get
+            {
+                string datum = GetElem("datum");
+                if ((datum == null) || (datum == ""))
+                    datum = "WGS84";
+                return datum;
+            }
+            set { SetElem("datum", value); }
+        }
+
+        /// <summary>
+        /// A natural-language description of the location.
+        /// </summary>
+        public string Description
+        {
+            get { return GetElem("description"); }
+            set { SetElem("description", value); }
+        }
+
+        /// <summary>
+        /// Horizontal GPS error in arc minutes.
+        /// </summary>
+        public double Error
+        {
+            get { return double.Parse(GetElem("error")); }
+            set { SetElem("error", value.ToString()); }
+        }
+
+        /// <summary>
+        /// Latitude in decimal degrees North.
+        /// </summary>
+        public double Latitude
+        {
+            get { return double.Parse(GetElem("lat")); }
+            set { SetElem("lat", value.ToString()); }
+        }
+
+        /// <summary>
+        /// Longitude in decimal degrees East.
+        /// </summary>
+        public double Longitude
+        {
+            get { return double.Parse(GetElem("lon")); }
+            set { SetElem("lon", value.ToString()); }
+        }
+
+        /// <summary>
+        /// UTC timestamp specifying the moment when the reading was taken.
+        /// </summary>
+        public DateTime Timestamp
+        {
+            get { return DateTimeProfile(GetElem("timestamp")); }
+            set { SetElem("timestamp", DateTimeProfile(value)); }
+        }
+
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/Last.cs b/lib/jabber-net/jabber/protocol/iq/Last.cs
new file mode 100644
index 0000000..17aa73b
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/Last.cs
@@ -0,0 +1,87 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.iq
+{
+    /*
+     *  <iq id='l4' type='result' from='user at host'>
+     *    <query xmlns='jabber:iq:last' seconds='903'>
+     *      Heading home
+     *    </query>
+     *  </iq>
+     */
+    /// <summary>
+    /// IQ packet with an Last query element inside.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class LastIQ : jabber.protocol.client.TypedIQ<Last>
+    {
+        /// <summary>
+        /// Create a Last IQ
+        /// </summary>
+        /// <param name="doc"></param>
+        public LastIQ(XmlDocument doc) : base(doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// A Last query element, which requests the last activity from an entity.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Last : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Last(XmlDocument doc) : base("query", URI.LAST, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Last(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The message inside the Last element.
+        /// </summary>
+        public string Message
+        {
+            get { return this.InnerText; }
+            set { this.InnerText = value; }
+        }
+
+        /// <summary>
+        /// How many seconds since the last activity.
+        /// </summary>
+        public int Seconds
+        {
+            get { return GetIntAttr("seconds");}
+            set { SetAttribute("seconds", value.ToString()); }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/MUC.cs b/lib/jabber-net/jabber/protocol/iq/MUC.cs
new file mode 100644
index 0000000..863ad1a
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/MUC.cs
@@ -0,0 +1,1145 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Xml;
+
+using bedrock.util;
+using jabber;
+using jabber.protocol;
+
+namespace jabber.protocol.iq
+{
+#region enums
+    /// <summary>
+    /// Affiliation with a MUC room, per user.
+    /// </summary>
+    public enum RoomAffiliation
+    {
+        /// <summary>
+        /// No attribute specified
+        /// </summary>
+        UNSPECIFIED = -1,
+        /// <summary>
+        /// Administrator
+        /// </summary>
+        admin = 0,
+        /// <summary>
+        /// Member
+        /// </summary>
+        member,
+        /// <summary>
+        /// No affiliation
+        /// </summary>
+        none,
+        /// <summary>
+        /// Banned
+        /// </summary>
+        outcast,
+        /// <summary>
+        /// Room owner
+        /// </summary>
+        owner,
+    }
+
+    /// <summary>
+    /// Current role in the room.  Initial role is set by affiliation, if it exits.
+    /// </summary>
+    public enum RoomRole
+    {
+        /// <summary>
+        /// No attribute specified
+        /// </summary>
+        UNSPECIFIED = -1,
+        /// <summary>
+        /// Room moderator.  Can grant/revoke voice
+        /// </summary>
+        moderator = 0,
+        /// <summary>
+        /// No role
+        /// </summary>
+        none,
+        /// <summary>
+        /// Can speak
+        /// </summary>
+        participant,
+        /// <summary>
+        /// Can listen
+        /// </summary>
+        visitor,
+    }
+
+    /// <summary>
+    /// Possible room status values.
+    /// </summary>
+    public enum RoomStatus
+    {
+        /// <summary>
+        /// An invalid or unknown RoomStatus
+        /// </summary>
+        UNKNOWN = -1,
+
+        /// <summary>
+        /// Inform user that any occupant is allowed to see the user's full JID.
+        /// </summary>
+        NON_ANONYMOUS_JOIN = 100,
+
+        /// <summary>
+        /// Inform user that his or her affiliation changed while not in the room
+        /// </summary>
+        AFILLIATION_CHANGE = 101,
+
+        /// <summary>
+        /// Inform occupants that room now shows unavailable members
+        /// </summary>
+        SHOW_UNAVAILABLE = 102,
+
+        /// <summary>
+        /// Inform occupants that room now does not show unavailable members
+        /// </summary>
+        NO_SHOW_UNAVAILABLE = 103,
+
+        /// <summary>
+        /// Inform occupants that a non-privacy-related room configuration change has occurred
+        /// </summary>
+        PRIVACY_CHANGE = 104,
+
+        /// <summary>
+        /// Inform user that presence refers to one of its own room occupants
+        /// </summary>
+        SELF = 110,
+
+        /// <summary>
+        /// Inform occupants that room logging is now enabled
+        /// </summary>
+        LOGGING_ENABLED = 170,
+
+        /// <summary>
+        /// Inform occupants that room logging is now disabled
+        /// </summary>
+        LOGGING_DISABLED = 171,
+
+        /// <summary>
+        /// Inform occupants that the room is now non-anonymous
+        /// </summary>
+        NON_ANONYMOUS = 172,
+
+        /// <summary>
+        /// Inform occupants that the room is now semi-anonymous
+        /// </summary>
+        SEMI_ANONYMOUS = 173,
+
+        /// <summary>
+        /// Inform occupants that the room is now fully-anonymous
+        /// </summary>
+        ANONYMOUS = 174,
+
+        /// <summary>
+        /// Inform user that a new room has been created
+        /// </summary>
+        CREATED = 201,
+
+        /// <summary>
+        /// Inform user that service has assigned or modified occupant's roomnick
+        /// </summary>
+        NICK_CHANGED = 210,
+
+        /// <summary>
+        /// Inform user that he or she has been banned from the room
+        /// </summary>
+        BANNED = 301,
+
+        /// <summary>
+        /// Inform all occupants of new room nickname
+        /// </summary>
+        NEW_NICK = 303,
+
+        /// <summary>
+        /// Inform user that he or she has been kicked from the room
+        /// </summary>
+        KICKED = 307,
+
+        /// <summary>
+        /// Inform user that he or she is being removed from the room
+        /// because of an affiliation change
+        /// </summary>
+        REMOVED_AFFILIATION = 321,
+
+        /// <summary>
+        /// Inform user that he or she is being removed from the room
+        /// because the room has been changed to members-only and the user
+        /// is not a member
+        /// </summary>
+        REMOVED_NONMEMBER = 322,
+
+        /// <summary>
+        /// Inform user that he or she is being removed from the room
+        /// because of a system shutdown
+        /// </summary>
+        REMOVED_SHUTDOWN = 332,
+    }
+#endregion
+
+#region base protocol
+    /// <summary>
+    /// Presence to join a multi-user chat.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class RoomPresence : jabber.protocol.client.Presence
+    {
+        /// <summary>
+        /// Create, taking default room history, with no password.
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="roomAndNick">A jid of the form room at conferenceServer/nick, where nick is the desired
+        /// room nickname for this user</param>
+        public RoomPresence(XmlDocument doc, JID roomAndNick)
+            : base(doc)
+        {
+            this.To = roomAndNick;
+            this.CreateChildElement<RoomX>();
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="roomAndNick"></param>
+        /// <param name="password">Null for non-password rooms</param>
+        /// TODO: getHistory?
+        public RoomPresence(XmlDocument doc, JID roomAndNick, string password)
+            : base(doc)
+        {
+            this.To = roomAndNick;
+            this.CreateChildElement<RoomX>().Password = password;
+        }
+
+        /// <summary>
+        /// The X tag denoting MUC-ness.  Use this to access passord and history
+        /// after creation.
+        /// </summary>
+        public RoomX X
+        {
+            get { return GetChildElement<RoomX>(); }
+            set { ReplaceChild<RoomX>(value); }
+        }
+    }
+
+
+    /// <summary>
+    /// X tag for presence when joining a room.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class RoomX : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public RoomX(XmlDocument doc)
+            : base("x", URI.MUC, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public RoomX(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Password to join room.  Null for no password.
+        /// </summary>
+        public string Password
+        {
+            get { return GetElem("password"); }
+            set { SetElem("password", value); }
+        }
+
+        /// <summary>
+        /// Add a history element, or return the existing one.
+        /// </summary>
+        /// <returns></returns>
+        public History AddHistory()
+        {
+            return GetOrCreateElement<History>();
+        }
+
+        /// <summary>
+        /// History options
+        /// </summary>
+        public History History
+        {
+            get { return GetChildElement<History>(); }
+            set { this.ReplaceChild<History>(value); }
+        }
+    }
+
+    /// <summary>
+    /// How much history to retrieve upon joining a room.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class History : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public History(XmlDocument doc)
+            : base("history", URI.MUC, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public History(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Maximum number of characters.  -1 if not specified.
+        /// </summary>
+        public int MaxChars
+        {
+            get { return GetIntAttr("maxchars"); }
+            set { SetIntAttr("maxchars", value); }
+        }
+        /// <summary>
+        /// Maximum number of stanzas.  -1 if not specified.
+        /// </summary>
+        public int MaxStanzas
+        {
+            get { return GetIntAttr("maxstanzas"); }
+            set { SetIntAttr("maxstanzas", value); }
+        }
+        /// <summary>
+        /// Number of seconds of history to retreive.
+        /// </summary>
+        public int Seconds
+        {
+            get { return GetIntAttr("seconds"); }
+            set { SetIntAttr("seconds", value); }
+        }
+        /// <summary>
+        /// Date of earliest history desired.
+        /// DateTime.MinValue for not specified.
+        /// </summary>
+        public DateTime since
+        {
+            get { return GetDateTimeAttr("since"); }
+            set { SetDateTimeAttr("since", value); }
+        }
+    }
+#endregion
+
+
+#region Users
+    /// <summary>
+    /// Information about users
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class UserX : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public UserX(XmlDocument doc)
+            : base("x", URI.MUC_USER, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public UserX(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Add a decline element, or return the existing one.
+        /// </summary>
+        /// <returns></returns>
+        public Decline AddDecline()
+        {
+            return GetOrCreateElement<Decline>();
+        }
+
+        /// <summary>
+        /// Invite was declined
+        /// </summary>
+        public Decline Decline
+        {
+            get { return GetChildElement<Decline>(); }
+            set { ReplaceChild<Decline>(value); }
+        }
+
+        /// <summary>
+        /// Add a destroy element, or return the existing one.
+        /// </summary>
+        /// <returns></returns>
+        public Destroy AddDestroy()
+        {
+            return GetOrCreateElement<Destroy>();
+        }
+
+        /// <summary>
+        /// Room was destroyed
+        /// </summary>
+        public Destroy Destroy
+        {
+            get { return GetChildElement<Destroy>();  }
+            set { ReplaceChild<Destroy>(value); }
+        }
+
+        /// <summary>
+        /// The list of invites
+        /// </summary>
+        public Invite[] GetInvites()
+        {
+            return GetElements<Invite>().ToArray();
+        }
+
+        /// <summary>
+        /// Add new invite
+        /// </summary>
+        /// <param name="to">Who to send the invite to?</param>
+        /// <param name="reason">Why?  Null if none.</param>
+        /// <returns></returns>
+        public Invite AddInvite(JID to, string reason)
+        {
+            Invite inv = CreateChildElement<Invite>();
+            inv.To = to;
+            if (reason != null)
+                inv.Reason = reason;
+            return inv;
+        }
+
+        /// <summary>
+        /// Add a room item element, or return the existing one.
+        /// </summary>
+        /// <returns></returns>
+        public RoomItem AddRoomItem()
+        {
+            return GetOrCreateElement<RoomItem>();
+        }
+
+        /// <summary>
+        /// The associated item
+        /// </summary>
+        public RoomItem RoomItem
+        {
+            get { return GetChildElement<RoomItem>(); }
+            set { ReplaceChild<RoomItem>(value); }
+        }
+
+        /// <summary>
+        /// The password to join the room.
+        /// </summary>
+        public string Password
+        {
+            get { return GetElem("password"); }
+            set { SetElem("password", value); }
+        }
+
+        /// <summary>
+        /// Sorted list of statuses of the request.
+        /// </summary>
+        /// <exception cref="FormatException">Invalid code</exception>
+        public RoomStatus[] Status
+        {
+            get
+            {
+                XmlNodeList nl = this.GetElementsByTagName("status");
+                RoomStatus[] ret = new RoomStatus[nl.Count];
+                int i = 0;
+                foreach (XmlElement status in nl)
+                {
+                    try
+                    {
+                        ret[i] = (RoomStatus)int.Parse(status.GetAttribute("code"));
+                    }
+                    catch
+                    {
+                        ret[i] = RoomStatus.UNKNOWN;
+                    }
+                    i++;
+                }
+                Array.Sort(ret);
+                return ret;
+            }
+            set
+            {
+                RemoveElems("status");
+                foreach (RoomStatus i in value)
+                {
+                    XmlElement status = this.OwnerDocument.CreateElement("status");
+                    status.SetAttribute("code", ((int)i).ToString());
+                    this.AppendChild(status);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Did we receive a given status?
+        /// </summary>
+        /// <param name="status"></param>
+        /// <returns></returns>
+        public bool HasStatus(RoomStatus status)
+        {
+            string s = ((int)status).ToString();
+            XmlNodeList nl = this.GetElementsByTagName("status");
+            foreach (XmlElement stat in nl)
+            {
+                if (s == stat.GetAttribute("code"))
+                    return true;
+            }
+            return false;
+        }
+    }
+
+    /// <summary>
+    /// Invitee Declines Invitation
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Decline : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Decline(XmlDocument doc)
+            : base("decline", URI.MUC_USER, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Decline(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The From address
+        /// </summary>
+        public JID From
+        {
+            get
+            {
+                string from = this.GetAttr("from");
+                if (from == null)
+                    return null;
+                return new JID(from);
+            }
+            set { SetAttr("from", (string)value); }
+        }
+
+        /// <summary>
+        /// The TO address
+        /// </summary>
+        public JID To
+        {
+            get
+            {
+                string to = this.GetAttr("to");
+                if (to == null)
+                    return null;
+                return new JID(to);
+            }
+            set { SetAttr("to", (string)value); }
+        }
+
+        /// <summary>
+        /// The reason the invitation was declined.  May be null.
+        /// </summary>
+        public string Reason
+        {
+            get { return GetElem("reason"); }
+            set { SetElem("reason", value); }
+        }
+    }
+
+    /// <summary>
+    /// An invite to a room
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Invite : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Invite(XmlDocument doc)
+            : base("invite", URI.MUC_USER, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Invite(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The From address
+        /// </summary>
+        public JID From
+        {
+            get
+            {
+                string from = this.GetAttr("from");
+                if (from == null)
+                    return null;
+                return new JID(from);
+            }
+            set { SetAttr("from", (string)value); }
+        }
+
+        /// <summary>
+        /// The TO address
+        /// </summary>
+        public JID To
+        {
+            get
+            {
+                string to = this.GetAttr("to");
+                if (to == null)
+                    return null;
+                return new JID(to);
+            }
+            set { SetAttr("to", (string)value); }
+        }
+
+        /// <summary>
+        /// The reason the invitation was declined.  May be null.
+        /// </summary>
+        public string Reason
+        {
+            get { return GetElem("reason"); }
+            set { SetElem("reason", value); }
+        }
+    }
+
+    /// <summary>
+    /// A room was destroyed
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Destroy : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Destroy(XmlDocument doc)
+            : base("destroy", URI.MUC_USER, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Destroy(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The JID of the destroyer
+        /// </summary>
+        public JID JID
+        {
+            get
+            {
+                string jid = this.GetAttr("jid");
+                if (jid == null)
+                    return null;
+                return new JID(jid);
+            }
+            set { SetAttr("jid", (string)value); }
+        }
+
+        /// <summary>
+        /// The reason the room was destroyed.  May be null.
+        /// </summary>
+        public string Reason
+        {
+            get { return GetElem("reason"); }
+            set { SetElem("reason", value); }
+        }
+    }
+
+    /// <summary>
+    /// Item associated with a room.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class RoomItem : AdminItem
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public RoomItem(XmlDocument doc)
+            : base("item", URI.MUC_USER, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public RoomItem(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// This is a continuation from 1-to-1 chat.  Not widely implemented yet.
+        /// </summary>
+        public bool Continue
+        {
+            get
+            {
+                XmlElement c = this["continue", URI.MUC_USER];
+                return (c != null);
+            }
+            set
+            {
+                if (value)
+                    GetOrCreateElement("continue", URI.MUC_USER, null);
+                else
+                    RemoveElem("continue");
+            }
+        }
+    }
+
+    /// <summary>
+    /// The JID associated with an item
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class RoomActor : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public RoomActor(XmlDocument doc)
+            : base("actor", URI.MUC_USER, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public RoomActor(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The JID of the destroyer
+        /// </summary>
+        public JID JID
+        {
+            get
+            {
+                string jid = this.GetAttr("jid");
+                if (jid == null)
+                    return null;
+                return new JID(jid);
+            }
+            set { SetAttr("jid", (string)value); }
+        }
+    }
+#endregion
+
+#region admin
+    /// <summary>
+    /// An IQ with a AdminQuery inside.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class RoomAdminIQ : jabber.protocol.client.TypedIQ<AdminQuery>
+    {
+        /// <summary>
+        /// Create a admin IQ, with a single muc#admin query element.
+        /// </summary>
+        /// <param name="doc"></param>
+        public RoomAdminIQ(XmlDocument doc)
+            : base(doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Moderator use cases
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class AdminQuery : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public AdminQuery(XmlDocument doc)
+            : base("query", URI.MUC_ADMIN, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public AdminQuery(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The list of invites
+        /// </summary>
+        public AdminItem[] GetItems()
+        {
+            XmlNodeList nl = GetElementsByTagName("item", URI.MUC_ADMIN);
+            AdminItem[] items = new AdminItem[nl.Count];
+            int i=0;
+            foreach (XmlNode n in nl)
+            {
+                items[i] = (AdminItem)n;
+                i++;
+            }
+            return items;
+        }
+
+        /// <summary>
+        /// Add new item
+        /// </summary>
+        /// <returns></returns>
+        public AdminItem AddItem()
+        {
+            AdminItem item = new AdminItem(this.OwnerDocument);
+            this.AddChild(item);
+            return item;
+        }
+    }
+
+
+    /// <summary>
+    /// Item associated with a room.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class AdminItem : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public AdminItem(XmlDocument doc)
+            : base("item", URI.MUC_ADMIN, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public AdminItem(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Pass through.  I really wish C# would let me just call grand-superclass constructors.
+        /// </summary>
+        /// <param name="localName"></param>
+        /// <param name="namespaceURI"></param>
+        /// <param name="doc"></param>
+        protected AdminItem(string localName, string namespaceURI, XmlDocument doc)
+            : base(localName, namespaceURI, doc)
+        {
+        }
+
+        /// <summary>
+        /// The JID associated with this item
+        /// </summary>
+        public RoomActor Actor
+        {
+            get { return GetOrCreateElement("actor", null, typeof(RoomActor)) as RoomActor; }
+            set { ReplaceChild(value); }
+        }
+
+        /// <summary>
+        /// The reason the room was destroyed.  May be null.
+        /// </summary>
+        public string Reason
+        {
+            get { return GetElem("reason"); }
+            set { SetElem("reason", value); }
+        }
+
+        /// <summary>
+        /// The affiliation of the item
+        /// </summary>
+        public RoomAffiliation Affiliation
+        {
+            get { return (RoomAffiliation)GetEnumAttr("affiliation", typeof(RoomAffiliation)); }
+            set { SetEnumAttr("affiliation", value); }
+        }
+
+        /// <summary>
+        /// The role of the item
+        /// </summary>
+        public RoomRole Role
+        {
+            get { return (RoomRole)GetEnumAttr("role", typeof(RoomRole)); }
+            set { SetEnumAttr("role", value); }
+        }
+
+        /// <summary>
+        /// The JID of the item
+        /// </summary>
+        public JID JID
+        {
+            get
+            {
+                string jid = this.GetAttr("jid");
+                if (jid == null)
+                    return null;
+                return new JID(jid);
+            }
+            set { SetAttr("jid", (string)value); }
+        }
+
+        /// <summary>
+        /// The nickname of the item
+        /// </summary>
+        public string Nick
+        {
+            get { return GetAttr("nick"); }
+            set { SetAttr("nick", value); }
+        }
+    }
+#endregion
+
+#region owner
+    /// <summary>
+    /// IQ with an OwnerQuery inside
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class OwnerIQ : jabber.protocol.client.TypedIQ<OwnerQuery>
+    {
+        /// <summary>
+        /// Create
+        /// </summary>
+        /// <param name="doc"></param>
+        public OwnerIQ(XmlDocument doc)
+            : base(doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// The query element inside an owner IQ.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class OwnerQuery : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public OwnerQuery(XmlDocument doc)
+            : base("query", URI.MUC_OWNER, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public OwnerQuery(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The jabber:x:data form for configuration
+        /// </summary>
+        public jabber.protocol.x.Data Form
+        {
+            get { return GetOrCreateElement("x", URI.XDATA, typeof(jabber.protocol.x.Data)) as jabber.protocol.x.Data; }
+            set { ReplaceChild(value); }
+        }
+
+        /// <summary>
+        /// Should we destroy the room?
+        /// </summary>
+        public OwnerDestroy Destroy
+        {
+            get { return GetOrCreateElement("destroy", URI.MUC_OWNER, typeof(OwnerDestroy)) as OwnerDestroy; }
+            set { ReplaceChild(value); }
+        }
+    }
+
+    /// <summary>
+    /// Destroy the room
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class OwnerDestroy : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public OwnerDestroy(XmlDocument doc)
+            : base("destroy", URI.MUC_OWNER, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public OwnerDestroy(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Password to destroy room.  Null for no password.
+        /// </summary>
+        public string Password
+        {
+            get { return GetElem("password"); }
+            set { SetElem("password", value); }
+        }
+
+        /// <summary>
+        /// Reason to destroy room.  Null for no reason.
+        /// </summary>
+        public string Reason
+        {
+            get { return GetElem("reason"); }
+            set { SetElem("reason", value); }
+        }
+
+        /// <summary>
+        /// The JID of the destroyer.
+        /// </summary>
+        public JID JID
+        {
+            get
+            {
+                string jid = this.GetAttr("jid");
+                if (jid == null)
+                    return null;
+                return new JID(jid);
+            }
+            set { SetAttr("jid", (string)value); }
+        }
+    }
+#endregion
+
+    /// <summary>
+    /// Request for a unique room name.  Seems like just using a GUID on the
+    /// create request would be enough, but it's in XEP-45.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class UniqueIQ : jabber.protocol.client.IQ
+    {
+        /// <summary>
+        /// Create
+        /// </summary>
+        /// <param name="doc"></param>
+        public UniqueIQ(XmlDocument doc)
+            : base(doc)
+        {
+            AppendChild(new UniqueRoom(doc));
+        }
+    }
+
+    /// <summary>
+    /// A unique name for a room.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class UniqueRoom : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public UniqueRoom(XmlDocument doc)
+            : base("unique", URI.MUC_UNIQUE, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public UniqueRoom(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The room name returned by the server.  Note: must add conference server to this,
+        /// it is just the node.
+        /// </summary>
+        public string RoomNode
+        {
+            get { return this.InnerText; }
+            set { this.InnerText = value; }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/OOB.cs b/lib/jabber-net/jabber/protocol/iq/OOB.cs
new file mode 100644
index 0000000..8e7fcff
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/OOB.cs
@@ -0,0 +1,87 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.iq
+{
+    /*
+     * <iq type="set" to="horatio at denmark" from="sailor at sea" id="i_oob_001">
+     *   <query xmlns="jabber:iq:oob">
+     *     <url>http://denmark/act4/letter-1.html</url>
+     *     <desc>There's a letter for you sir.</desc>
+     *   </query>
+     * </iq>
+     */
+    /// <summary>
+    /// IQ packet with an oob query element inside.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class OobIQ : jabber.protocol.client.TypedIQ<OOB>
+    {
+        /// <summary>
+        /// Create an OOB IQ.
+        /// </summary>
+        /// <param name="doc"></param>
+        public OobIQ(XmlDocument doc) : base(doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// An oob query element for file transfer.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class OOB : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public OOB(XmlDocument doc) : base("query", URI.OOB, doc)
+        {
+        }
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public OOB(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// URL to send/receive from
+        /// </summary>
+        public string Url
+        {
+            get { return GetElem("url"); }
+            set { SetElem("url", value); }
+        }
+
+        /// <summary>
+        /// File description
+        /// </summary>
+        public string Desc
+        {
+            get { return GetElem("desc"); }
+            set { SetElem("desc", value); }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/Private.cs b/lib/jabber-net/jabber/protocol/iq/Private.cs
new file mode 100644
index 0000000..167fc74
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/Private.cs
@@ -0,0 +1,66 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Diagnostics;
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.iq
+{
+    /// <summary>
+    /// Private storage IQ.
+    /// See XEP-0049 (http://www.xmpp.org/extensions/xep-0049.html)
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PrivateIQ : jabber.protocol.client.TypedIQ<Private>
+    {
+        /// <summary>
+        /// Create an IQ for the jabber:iq:private namespace.
+        /// Make sure to add a body to the query before sending.
+        /// </summary>
+        /// <param name="doc"></param>
+        public PrivateIQ(XmlDocument doc) : base(doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Private storage query.
+    /// See XEP-0049 (http://www.xmpp.org/extensions/xep-0049.html)
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Private : Element
+    {
+        /// <summary>
+        /// Create for outbound
+        /// </summary>
+        /// <param name="doc"></param>
+        public Private(XmlDocument doc) : 
+            base("query", URI.PRIVATE, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound.
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Private(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/PubSub.cs b/lib/jabber-net/jabber/protocol/iq/PubSub.cs
new file mode 100644
index 0000000..7c0559c
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/PubSub.cs
@@ -0,0 +1,1278 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Xml;
+
+using bedrock.util;
+using jabber.protocol.x;
+
+namespace jabber.protocol.iq
+{
+    /// <summary>
+    /// Different pubsub operations
+    /// </summary>
+    public enum PubSubCommandType
+    {
+        /// <summary>
+        /// Retrieve the affiliations.  See: http://www.xmpp.org/extensions/xep-0060.html#entity-affiliations
+        /// </summary>
+        affiliations,
+        /// <summary>
+        /// Create a node. See: http://www.xmpp.org/extensions/xep-0060.html#owner-create
+        /// </summary>
+        create,
+        /// <summary>
+        /// Retrieve the items for a node. See http://www.xmpp.org/extensions/xep-0060.html#subscriber-retrieve
+        /// </summary>
+        items,
+        /// <summary>
+        /// Publish to a node.  See http://www.xmpp.org/extensions/xep-0060.html#publisher-publish
+        /// </summary>
+        publish,
+        /// <summary>
+        /// Delete an item from a node.  See: http://www.xmpp.org/extensions/xep-0060.html#publisher-delete
+        /// </summary>
+        retract,
+        /// <summary>
+        /// Subscribe to a node. See: http://www.xmpp.org/extensions/xep-0060.html#subscriber-subscribe
+        /// </summary>
+        subscribe,
+        /// <summary>
+        /// Retrieve subscriptions.  See: http://www.xmpp.org/extensions/xep-0060.html#entity-subscriptions
+        /// </summary>
+        subscriptions,
+        /// <summary>
+        /// Unsubscribe from a node.  See: http://www.xmpp.org/extensions/xep-0060.html#subscriber-unsubscribe
+        /// </summary>
+        unsubscribe,
+        /// <summary>
+        /// Delete a node. See: http://www.xmpp.org/extensions/xep-0060.html#owner-delete
+        /// </summary>
+        delete,
+
+        /// <summary>
+        /// Collection modification
+        /// </summary>
+        collection,
+        /// <summary>
+        /// Node configuration change
+        /// </summary>
+        configuration,
+        /// <summary>
+        /// All items purged
+        /// </summary>
+        purge,
+        /// <summary>
+        /// A new subscription
+        /// </summary>
+        subscription,
+
+        /// <summary>
+        /// Owner configuring the node
+        /// </summary>
+        configure,
+        /// <summary>
+        /// Owner-level defaults, in a "default" element.  "default" is a C# keyword, though.
+        /// </summary>
+        defaults
+    }
+
+    /// <summary>
+    /// A PubSub IQ
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PubSubIQ : jabber.protocol.client.TypedIQ<PubSub>
+    {
+        /// <summary>
+        /// Create a pubsub IQ, with a single pubsub query element.
+        /// </summary>
+        /// <param name="doc"></param>
+        public PubSubIQ(XmlDocument doc) : base(doc)
+        {
+        }
+
+        /// <summary>
+        /// Create a pubsub IQ, with a pubusub query element and the given subelement.
+        /// </summary>
+        /// <param name="doc">Document to create in</param>
+        /// <param name="command">The pubsub command</param>
+        /// <param name="node">Add this as a node attrbute of the command</param>
+        public PubSubIQ(XmlDocument doc, PubSubCommandType command, string node)
+            : base(doc)
+        {
+            PubSubCommand cmd = null;
+            switch (command)
+            {
+            case PubSubCommandType.affiliations:
+                cmd = new Affiliations(doc);
+                break;
+            case PubSubCommandType.create:
+                cmd = new Create(doc);
+                break;
+            case PubSubCommandType.items:
+                cmd = new Items(doc);
+                break;
+            case PubSubCommandType.publish:
+                cmd = new Publish(doc);
+                break;
+            case PubSubCommandType.retract:
+                cmd = new Retract(doc);
+                break;
+            case PubSubCommandType.subscribe:
+                cmd = new Subscribe(doc);
+                break;
+            case PubSubCommandType.subscriptions:
+                cmd = new Subscriptions(doc);
+                break;
+            case PubSubCommandType.unsubscribe:
+                cmd = new Unsubscribe(doc);
+                break;
+            default:
+                throw new ArgumentException("Command not understood: " + command.ToString(), "command");
+            }
+
+            if (node != null)
+                cmd.Node = node;
+            this.Instruction.AppendChild(cmd);
+        }
+
+        /// <summary>
+        /// Get the command from the pubsub element.
+        /// </summary>
+        public PubSubCommand Command
+        {
+            get
+            {
+                PubSub ps = this.Instruction;
+                if (ps == null)
+                    return null;
+                return ps.Command;
+            }
+        }
+    }
+
+    /// <summary>
+    /// A type-safe PubSub IQ.
+    /// </summary>
+    /// <typeparam name="T">The type of command to create</typeparam>
+    [SVN(@"$Id$")]
+    public class PubSubCommandIQ<T> : jabber.protocol.client.TypedIQ<TypedPubSub<T>>
+        where T : PubSubCommand
+    {
+        /// <summary>
+        /// Create
+        /// </summary>
+        /// <param name="doc"></param>
+        public PubSubCommandIQ(XmlDocument doc)
+            : base(doc)
+        {
+        }
+
+        /// <summary>
+        /// Create, with node
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="node"></param>
+        public PubSubCommandIQ(XmlDocument doc, string node)
+            : base(doc)
+        {
+            Command.Node = node;
+        }
+
+        /// <summary>
+        /// The command inside the pubsub element.
+        /// </summary>
+        public T Command
+        {
+            get { return Instruction.Command; }
+            set { Instruction.Command = value; }
+        }
+    }
+
+    /// <summary>
+    /// A type-safe pubsub element.
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    [SVN(@"$Id$")]
+    public class TypedPubSub<T> : Element
+        where T : PubSubCommand
+    {
+        /// <summary>
+        /// Create
+        /// </summary>
+        /// <param name="doc"></param>
+        public TypedPubSub(XmlDocument doc)
+            : base("pubsub", URI.PUBSUB, doc)
+        {
+            CreateChildElement<T>();
+        }
+
+        /// <summary>
+        /// The pubsub command
+        /// </summary>
+        public T Command
+        {
+            get { return GetChildElement<T>(); }
+            set { ReplaceChild<T>(value); }
+        }
+
+        /// <summary>
+        /// The type of pubsub command
+        /// </summary>
+        public PubSubCommandType CommandType
+        {
+            get { return Command.CommandType; }
+        }
+    }
+
+    /// <summary>
+    /// Publish/Subscribe.  See XEP-60: http://www.xmpp.org/extensions/xep-0060.html
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PubSub : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public PubSub(XmlDocument doc) : base("pubsub", URI.PUBSUB, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public PubSub(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The PubSub command associated with this instruction
+        /// </summary>
+        public PubSubCommand Command
+        {
+            get { return GetChildElement<PubSubCommand>(); }
+        }
+    }
+
+    /// <summary>
+    /// A PubSub command
+    /// </summary>
+    [SVN(@"$Id$")]
+    public abstract class PubSubCommand : Element
+    {
+        /// <summary>
+        /// Create a pubsub command.  Should not be called directly.
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        protected PubSubCommand(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for outbound, in the namespace of the parent element,
+        /// then attach to the parent element.
+        /// </summary>
+        /// <param name="elementName">The name of the element to create</param>
+        /// <param name="parent">The parent element</param>
+        public PubSubCommand(string elementName, XmlElement parent)
+            : base(elementName, parent.NamespaceURI, parent.OwnerDocument)
+        {
+            parent.AppendChild(this);
+        }
+
+        /// <summary>
+        /// Create a pubsub command.  Should not be called directly.
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="ns"></param>
+        /// <param name="doc"></param>
+        protected PubSubCommand(string prefix, string ns, XmlDocument doc)
+            : base(prefix, ns, doc)
+        {
+        }
+
+        /// <summary>
+        /// The node this command applies to.
+        /// </summary>
+        public string Node
+        {
+            get { return GetAttr("node"); }
+            set { SetAttr("node", value); }
+        }
+
+        /// <summary>
+        /// What type of command?
+        /// </summary>
+        public abstract PubSubCommandType CommandType
+        {
+            get;
+        }
+    }
+
+
+    /// <summary>
+    /// Retrieve the affiliations.  See: http://www.xmpp.org/extensions/xep-0060.html#entity-affiliations
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Affiliations : PubSubCommand
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Affiliations(XmlDocument doc)
+            : base("affiliations", URI.PUBSUB, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Affiliations(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// What type of command?
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.affiliations; }
+        }
+
+        /// <summary>
+        /// Retrieve all of the affiliations
+        /// </summary>
+        /// <returns></returns>
+        public Affiliation[] GetAffiliations()
+        {
+            return GetElements<Affiliation>().ToArray();
+        }
+
+        /// <summary>
+        /// Add a new affiliation to the list.
+        /// </summary>
+        /// <param name="type"></param>
+        /// <param name="node"></param>
+        /// <returns></returns>
+        public Affiliation AddAffiliation(AffiliationType type, string node)
+        {
+            Affiliation afil = CreateChildElement<Affiliation>();
+            afil.Type = type;
+            afil.Node = node;
+            return afil;
+        }
+    }
+
+    /// <summary>
+    /// What affiliation does an entity have with respect to a node?
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum AffiliationType
+    {
+        /// <summary>
+        /// No affiliation specified
+        /// </summary>
+        NONE_SPECIFIED=-1,
+        /// <summary>
+        /// Can receive
+        /// </summary>
+        member=0,
+        /// <summary>
+        /// No affiliation
+        /// </summary>
+        none,
+        /// <summary>
+        /// Can't join
+        /// </summary>
+        outcast,
+        /// <summary>
+        /// All permisions
+        /// </summary>
+        owner,
+        /// <summary>
+        /// Can publish
+        /// </summary>
+        publisher,
+    }
+
+    /// <summary>
+    /// The actual affiliation.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Affiliation : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Affiliation(XmlDocument doc)
+            : base("affiliation", URI.PUBSUB, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create a new instance for output, specifying the namespace.  This 
+        /// exists for things in pubsub#owner.
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="namespaceURI"></param>
+        public Affiliation(XmlDocument doc, string namespaceURI)
+            : base("affiliation", namespaceURI, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Affiliation(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The node this affiliation applies to.
+        /// </summary>
+        public string Node
+        {
+            get { return GetAttribute("node"); }
+            set { SetAttribute("node", value); }
+        }
+
+        /// <summary>
+        /// Which affiliation?
+        /// </summary>
+        public AffiliationType Type
+        {
+            get { return GetEnumAttr<AffiliationType>("affiliation"); }
+            set { SetEnumAttr("affiliation", value); }
+        }
+
+    }
+
+    /// <summary>
+    /// Create a node. See: http://www.xmpp.org/extensions/xep-0060.html#owner-create
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Create : PubSubCommand
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Create(XmlDocument doc)
+            : base("create", URI.PUBSUB, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Create(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// What type of command?
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.create; }
+        }
+
+        /// <summary>
+        /// Does the element have a configure sibling?
+        /// </summary>
+        public bool HasConfigure
+        {
+            get
+            {
+                Configure config = GetConfiguration();
+                return (config != null);
+            }
+            set
+            {
+                Configure config = GetConfiguration();
+                if (value)
+                {
+                    if (config != null)
+                        return;
+                    config = new Configure(this.OwnerDocument);
+                    ParentNode.AppendChild(config);
+                }
+                else
+                {
+                    if (config == null)
+                        return;
+                    ParentNode.RemoveChild(config);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Get the configuration.  Null if none exists.
+        /// </summary>
+        public Configure GetConfiguration()
+        {
+            return ParentNode["configure", URI.PUBSUB] as Configure;
+        }
+
+        /// <summary>
+        /// Add a (or return a pre-exisitng) configuration section to the creation request, complete with x:data.
+        /// </summary>
+        /// <returns>The x:data form</returns>
+        public Data CreateConfiguration()
+        {
+            return CreateConfiguration(null);
+        }
+
+        /// <summary>
+        /// Add a configuration section to the creation request, using the given x:data.
+        /// </summary>
+        /// <param name="form"></param>
+        /// <returns></returns>
+        public Data CreateConfiguration(Data form)
+        {
+            Configure config = GetConfiguration();
+            if (config == null)
+            {
+                config = new Configure(this.OwnerDocument);
+                ParentNode.AppendChild(config);
+            }
+            return config.CreateForm(form);
+        }
+    }
+
+    /// <summary>
+    /// Configuring a pubsub node.  If the default is desired, it will be empty.  Otherwise it will contain an x:data.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Configure : PubSubCommand
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Configure(XmlDocument doc) : base("configure", URI.PUBSUB, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Configure(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// What type of command?
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.configuration; }
+        }
+
+        /// <summary>
+        /// Create or return the existing x:data form, with the appropriate form type.
+        /// </summary>
+        /// <returns></returns>
+        public Data CreateForm()
+        {
+            Data x = GetChildElement<Data>();
+            if (x == null)
+            {
+                x = CreateChildElement<Data>();
+                x.FormType = URI.PUBSUB_NODE_CONFIG;
+            }
+            return x;
+        }
+
+        /// <summary>
+        /// Add the given form to the configuration, removing any existing form, and ensuring that the
+        /// form type is correct.
+        /// </summary>
+        /// <param name="form"></param>
+        /// <returns></returns>
+        public Data CreateForm(Data form)
+        {
+            ReplaceChild<Data>(form);
+            if (form != null)
+            {
+                form.FormType = URI.PUBSUB_NODE_CONFIG;
+                form.Type = XDataType.submit;
+            }
+            return form;
+        }
+    }
+
+    /// <summary>
+    /// Commands that deal with items.
+    /// </summary>
+    public abstract class PubSubItemCommand : PubSubCommand
+    {
+        /// <summary>
+        /// Create a pubsub command.  Should not be called directly.
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        protected PubSubItemCommand(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create a pubsub command.  Should not be called directly.
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="ns"></param>
+        /// <param name="doc"></param>
+        protected PubSubItemCommand(string prefix, string ns, XmlDocument doc)
+            : base(prefix, ns, doc)
+        {
+        }
+
+        /// <summary>
+        /// Retrieve all of the items
+        /// </summary>
+        /// <returns></returns>
+        public PubSubItem[] GetItems()
+        {
+            return GetElements<PubSubItem>().ToArray();
+        }
+
+        /// <summary>
+        /// Add a new item to the list
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public PubSubItem AddItem(string id)
+        {
+            PubSubItem item = CreateChildElement<PubSubItem>();
+            item.ID = id;
+            return item;
+        }
+    }
+
+
+    /// <summary>
+    /// Retrieve the items for a node. See http://www.xmpp.org/extensions/xep-0060.html#subscriber-retrieve
+    /// Note: this same type is used for event notifications, in the pubsub#event namespace
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Items : PubSubItemCommand
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Items(XmlDocument doc)
+            : base("items", URI.PUBSUB, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Items(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// What type of command?
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.items; }
+        }
+
+        /// <summary>
+        /// The subscription ID these items apply to.
+        /// </summary>
+        public string SubID
+        {
+            get { return GetAttr("subid"); }
+            set { SetAttr("subid", value); }
+        }
+
+        /// <summary>
+        /// The maximum number of items to return
+        /// </summary>
+        public int MaxItems
+        {
+            get { return GetIntAttr("max_items"); }
+            set { SetIntAttr("max_items", value); }
+        }
+    }
+
+
+    /// <summary>
+    /// The items in a node
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PubSubItem : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public PubSubItem(XmlDocument doc)
+            : base("item", URI.PUBSUB, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create a new instance for output, specifying the namespace.  This 
+        /// exists for things in pubsub#event.
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="namespaceURI"></param>
+        public PubSubItem(XmlDocument doc, string namespaceURI)
+            : base("item", namespaceURI, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public PubSubItem(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The node of the published item, when doing hierachical subscribes
+        /// </summary>
+        public string Node
+        {
+            get { return GetAttr("node"); }
+            set { SetAttr("node", value); }
+        }
+
+        /// <summary>
+        /// The item id number
+        /// </summary>
+        public string ID
+        {
+            get { return GetAttr("id"); }
+            set { SetAttr("id", value); }
+        }
+
+        /// <summary>
+        /// The actual contents to publish.  Make sure to set a namespace!
+        /// </summary>
+        public XmlElement Contents
+        {
+            get { return GetFirstChildElement(); }
+            set { this.InnerXml = ""; this.AddChild(value); }
+        }
+    }
+
+    /// <summary>
+    /// Publish to a node.  See http://www.xmpp.org/extensions/xep-0060.html#publisher-publish
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Publish : PubSubItemCommand
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Publish(XmlDocument doc)
+            : base("publish", URI.PUBSUB, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Publish(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// What type of command?
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.publish; }
+        }
+    }
+
+    /// <summary>
+    /// Delete an item from a node.  See: http://www.xmpp.org/extensions/xep-0060.html#publisher-delete
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Retract : PubSubItemCommand
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Retract(XmlDocument doc)
+            : base("retract", URI.PUBSUB, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Retract(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// What type of command?
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.retract; }
+        }
+
+        /// <summary>
+        /// When in an event, there may be an ID as an attribute.
+        /// </summary>
+        public string ID
+        {
+            get { return GetAttr("id"); }
+            set { SetAttr("id", value); }
+        }
+
+        /// <summary>
+        /// Don notifications?
+        /// </summary>
+        public bool Notify
+        {
+            get
+            {
+                string notify = GetAttribute("notify");
+                if (notify == "true")
+                    return true;
+                if (notify == "1")
+                    return true;
+                return false;
+            }
+            set { SetAttribute("notify", value ? "true": "false"); }
+        }
+    }
+
+    /// <summary>
+    /// Subscribe to a node. See: http://www.xmpp.org/extensions/xep-0060.html#subscriber-subscribe
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Subscribe : PubSubCommand
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Subscribe(XmlDocument doc)
+            : base("subscribe", URI.PUBSUB, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Subscribe(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// What type of command?
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.subscribe; }
+        }
+
+        /// <summary>
+        /// The Jabber ID for this subscription
+        /// </summary>
+        public JID JID
+        {
+            get { return GetAttr("jid"); }
+            set { SetAttr("jid", value); }
+        }
+
+        /// <summary>
+        /// Does the element have a options sibling?
+        /// </summary>
+        public bool HasOptions
+        {
+            get
+            {
+                PubSubOptions opts = GetOptions();
+                return (opts != null);
+            }
+            set
+            {
+                PubSubOptions opts = GetOptions();
+                if (value)
+                {
+                    if (opts != null)
+                        return;
+                    opts = new PubSubOptions(this.OwnerDocument);
+                    ParentNode.AppendChild(opts);
+                }
+                else
+                {
+                    if (opts == null)
+                        return;
+                    ParentNode.RemoveChild(opts);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Get the configuration.  Null if none exists.
+        /// </summary>
+        public PubSubOptions GetOptions()
+        {
+            return ParentNode["options", URI.PUBSUB] as PubSubOptions;
+        }
+    }
+
+    /// <summary>
+    /// PubSub subscription options
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PubSubOptions : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public PubSubOptions(XmlDocument doc)
+            : base("options", URI.PUBSUB, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public PubSubOptions(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The node these options apply to.
+        /// </summary>
+        public string Node
+        {
+            get { return GetAttr("node"); }
+            set { SetAttr("node", value); }
+        }
+
+        /// <summary>
+        /// The Jabber ID these options apply to.
+        /// </summary>
+        public JID JID
+        {
+            get { return GetAttr("jid"); }
+            set { SetAttr("jid", value); }
+        }
+
+        /// <summary>
+        /// The subscription ID these options apply to.
+        /// </summary>
+        public string SubID
+        {
+            get { return GetAttr("subid"); }
+            set { SetAttr("subid", value); }
+        }
+
+
+        /// <summary>
+        /// Does the element have an XData child?
+        /// </summary>
+        public bool HasXData
+        {
+            get { return (GetXData() != null); }
+            set
+            {
+                if (value)
+                    GetOrCreateElement<Data>().Type = XDataType.submit;
+                else
+                    RemoveElem<Data>();
+            }
+        }
+
+        /// <summary>
+        /// Get the XData child, if it exists.
+        /// </summary>
+        /// <returns></returns>
+        public Data GetXData()
+        {
+            return GetChildElement<Data>();
+        }
+
+    }
+
+    /// <summary>
+    /// Retrieve subscriptions.  See: http://www.xmpp.org/extensions/xep-0060.html#entity-subscriptions
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Subscriptions : PubSubCommand
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Subscriptions(XmlDocument doc)
+            : base("subscriptions", URI.PUBSUB, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create a new instance for output, specifying the namespace.  This 
+        /// exists for things in pubsub#owner.
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="namespaceURI"></param>
+        public Subscriptions(XmlDocument doc, string namespaceURI)
+            : base("subscriptions", namespaceURI, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Subscriptions(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// What type of command?
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.subscriptions; }
+        }
+
+        /// <summary>
+        /// Retrieve all of the subscriptions
+        /// </summary>
+        /// <returns></returns>
+        public PubSubSubscription[] GetSubscriptions()
+        {
+            return GetElements<PubSubSubscription>().ToArray();
+        }
+
+        /// <summary>
+        /// Add a new subscription to the list
+        /// </summary>
+        /// <returns></returns>
+        public PubSubSubscription AddSubscription()
+        {
+            return CreateChildElement<PubSubSubscription>();
+        }
+    }
+
+
+    /// <summary>
+    /// A single subscription
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PubSubSubscription : Element
+    {
+      /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public PubSubSubscription(XmlDocument doc)
+            : base("subscription", URI.PUBSUB, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public PubSubSubscription(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The node these options apply to.
+        /// </summary>
+        public string Node
+        {
+            get { return GetAttr("node"); }
+            set { SetAttr("node", value); }
+        }
+
+        /// <summary>
+        /// The Jabber ID these options apply to.
+        /// </summary>
+        public JID JID
+        {
+            get { return GetAttr("jid"); }
+            set { SetAttr("jid", value); }
+        }
+
+        /// <summary>
+        /// The subscription ID these options apply to.
+        /// </summary>
+        public string SubID
+        {
+            get { return GetAttr("subid"); }
+            set { SetAttr("subid", value); }
+        }
+
+        /// <summary>
+        /// The subscription state
+        /// </summary>
+        public PubSubSubscriptionType Type
+        {
+            get { return GetEnumAttr<PubSubSubscriptionType>("subscription"); }
+            set { SetEnumAttr("subscription", value); }
+        }
+    }
+
+    /// <summary>
+    /// The subscription state of a given pubsub node.
+    /// </summary>
+    public enum PubSubSubscriptionType
+    {
+        /// <summary>
+        /// No type given
+        /// </summary>
+        NONE_SPECIFIED = -1,
+        /// <summary>
+        /// No subscription
+        /// </summary>
+        none = 0,
+        /// <summary>
+        /// Sub is pending
+        /// </summary>
+        pending,
+        /// <summary>
+        /// Subscribed
+        /// </summary>
+        subscribed,
+        /// <summary>
+        /// Subscription needs to be configured
+        /// </summary>
+        unconfigured
+    }
+
+    /// <summary>
+    /// Unsubscribe from a node.  See: http://www.xmpp.org/extensions/xep-0060.html#subscriber-unsubscribe
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Unsubscribe : PubSubCommand
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Unsubscribe(XmlDocument doc)
+            : base("unsubscribe", URI.PUBSUB, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Unsubscribe(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// What type of command?
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.unsubscribe; }
+        }
+
+        /// <summary>
+        /// The Jabber ID these options apply to.
+        /// </summary>
+        public JID JID
+        {
+            get { return GetAttr("jid"); }
+            set { SetAttr("jid", value); }
+        }
+
+        /// <summary>
+        /// The subscription ID these options apply to.
+        /// </summary>
+        public string SubID
+        {
+            get { return GetAttr("subid"); }
+            set { SetAttr("subid", value); }
+        }
+    }
+
+
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/PubSubErrors.cs b/lib/jabber-net/jabber/protocol/iq/PubSubErrors.cs
new file mode 100644
index 0000000..584cd0d
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/PubSubErrors.cs
@@ -0,0 +1,779 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Xml;
+
+using jabber;
+using jabber.protocol;
+
+using bedrock.util;
+
+namespace jabber.protocol.iq
+{
+    /// <summary>
+    /// For nodes with a node access model of "whitelist", if the requesting 
+    /// entity is not on the whitelist then the service MUST return a 
+    /// not-allowed error, specifying a pubsub-specific error condition of closed-node.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ClosedNode : Element
+	{
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public ClosedNode(XmlDocument doc)
+            : base("closed-node", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public ClosedNode(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+	}
+
+    /// <summary>
+    /// The node must be configured.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ConfigurationRequired : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public ConfigurationRequired(XmlDocument doc)
+            : base("configuration-required", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public ConfigurationRequired(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+    /// <summary>
+    /// An invalid JID was specified
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class InvalidJID : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public InvalidJID(XmlDocument doc)
+            : base("invalid-jid", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public InvalidJID(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Invalid options were specified
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class InvalidOptions : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public InvalidOptions(XmlDocument doc)
+            : base("invalid-options", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public InvalidOptions(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// An invalid item was specified.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class InvalidPayload : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public InvalidPayload(XmlDocument doc)
+            : base("invalid-payload", URI.PUBSUB_ERRORS, doc)
+        {
+            
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public InvalidPayload(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// An invalid ID was specified.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class InvalidSubid : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public InvalidSubid(XmlDocument doc)
+            : base("invalid-subid", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public InvalidSubid(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// An item was forbidden.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ItemForbidden : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public ItemForbidden(XmlDocument doc)
+            : base("item-forbidden", URI.PUBSUB_ERRORS, doc)
+        {
+            // lambda, the forbidden function
+            // cf: http://snurl.com/2gduz 
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public ItemForbidden(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// An item was required, but was not specified.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ItemRequired : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public ItemRequired(XmlDocument doc)
+            : base("item-required", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public ItemRequired(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// A JID was required, but not specified.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class JIDRequired : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public JIDRequired(XmlDocument doc)
+            : base("jid-required", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public JIDRequired(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// The maximum number of items was exceeded.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class MaxItemsExceeded : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public MaxItemsExceeded(XmlDocument doc)
+            : base("max-items-exceeded", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public MaxItemsExceeded(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// The maximum number of nodes was exceeded.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class MaxNodesExceeded : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public MaxNodesExceeded(XmlDocument doc)
+            : base("max-nodes-exceeded", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public MaxNodesExceeded(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// The node was required, but not specified.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class NodeIDRequired : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public NodeIDRequired(XmlDocument doc)
+            : base("nodeid-required", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public NodeIDRequired(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+    /// <summary>
+    /// Not allowed to subscribe, because you aren't in one of the correct roster
+    /// groups of the publisher.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class NotInRosterGroup : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public NotInRosterGroup(XmlDocument doc)
+            : base("not-in-roster-group", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public NotInRosterGroup(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// You must be subscribed to perform this function.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class NotSubscribed : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public NotSubscribed(XmlDocument doc)
+            : base("not-subscribed", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public NotSubscribed(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// The item is too large.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PayloadTooBig : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public PayloadTooBig(XmlDocument doc)
+            : base("payload-too-big", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public PayloadTooBig(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// An item is required, but was not specified.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PayloadRequired : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public PayloadRequired(XmlDocument doc)
+            : base("payload-required", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public PayloadRequired(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+    /// <summary>
+    /// The subscription is pending.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PendingSubscription : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public PendingSubscription(XmlDocument doc)
+            : base("pending-subscription", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public PendingSubscription(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// You must be subscribed first.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PresenceSubscriptionRequired : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public PresenceSubscriptionRequired(XmlDocument doc)
+            : base("presence-subscription-required", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public PresenceSubscriptionRequired(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// An subscription ID is required, but was not specified.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class SubidRequired : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public SubidRequired(XmlDocument doc)
+            : base("subid-required", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public SubidRequired(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+    
+    /// <summary>
+    /// Supported features
+    /// </summary>
+    [SVN(@"$Id$")]
+    [Dash]
+    public enum PubSubFeature
+    {
+        /// <summary>
+        /// None specified
+        /// </summary>
+        UNSPECIFIED = -1,
+        /// <summary>
+        /// Access authorizations
+        /// </summary>
+        access_authorize,
+        /// <summary>
+        /// Open Access
+        /// </summary>
+        access_open,
+        /// <summary>
+        /// Presence-based access control
+        /// </summary>
+        access_presence,
+        /// <summary>
+        /// Roster-based access control
+        /// </summary>
+        access_roster,
+        /// <summary>
+        /// Whitelist-based access control
+        /// </summary>
+        access_whitelist,
+        /// <summary>
+        /// Auto-creation of nodes
+        /// </summary>
+        auto_create,
+        /// <summary>
+        /// Auto-subscription to nodes
+        /// </summary>
+        auto_subscribe,
+        /// <summary>
+        /// Collection support
+        /// </summary>
+        collections,
+        /// <summary>
+        /// Configuration
+        /// </summary>
+        config_node,
+        /// <summary>
+        /// Create and configure atomically
+        /// </summary>
+        create_and_configure,
+        /// <summary>
+        /// Node creation
+        /// </summary>
+        create_nodes,
+        /// <summary>
+        /// Delete items
+        /// </summary>
+        delete_any,
+        /// <summary>
+        /// Delete nodes
+        /// </summary>
+        delete_nodes,
+        /// <summary>
+        /// Notify on some criteria, only
+        /// </summary>
+        filtered_notifications,
+        /// <summary>
+        /// Process pending subscription requests
+        /// </summary>
+        get_pending,
+        /// <summary>
+        /// The server can create unused node names
+        /// </summary>
+        instant_nodes,
+        /// <summary>
+        /// Items have IDs
+        /// </summary>
+        item_ids,
+        /// <summary>
+        /// Geting the last published item
+        /// </summary>
+        last_published,
+        /// <summary>
+        /// Time-based subscriptions are supported.
+        /// </summary>
+        leased_subscription,
+        /// <summary>
+        /// Node owners may manage subscriptions
+        /// </summary>
+        manage_subscriptions,
+        /// <summary>
+        /// The member affiliation is supported
+        /// </summary>
+        member_affiliation,
+        /// <summary>
+        /// Node meta-data is supported.
+        /// </summary>
+        meta_data,
+        /// <summary>
+        /// Node owners may modify affiliations.
+        /// </summary>
+        modify_affiliations,
+        /// <summary>
+        /// A single leaf node may be associated with multiple collections
+        /// </summary>
+        multi_collection,
+        /// <summary>
+        /// A single entity may subscribe to a node multiple times.
+        /// </summary>
+        multi_subscribe,
+        /// <summary>
+        /// The outcast affiliation is supported
+        /// </summary>
+        outcast_affiliation,
+        /// <summary>
+        /// Persistent items are supported.
+        /// </summary>
+        persistent_items,
+        /// <summary>
+        /// Presence-based delivery of event notifications is supported
+        /// </summary>
+        presence_notifications,
+        /// <summary>
+        /// Authorized contacts are automatically subscribed to a user's virtual pubsub service.
+        /// </summary>
+        presence_subscribe,
+        /// <summary>
+        /// Publishing items is supported (note: not valid for collection nodes).
+        /// </summary>
+        publish,
+        /// <summary>
+        /// Publishing an item with options is supported.
+        /// </summary>
+        publish_options,
+        /// <summary>
+        /// The publisher affiliation is supported.
+        /// </summary>
+        publisher_affiliation,
+        /// <summary>
+        /// Purging of nodes is supported.
+        /// </summary>
+        purge_nodes,
+        /// <summary>
+        /// Item retraction is supported.
+        /// </summary>
+        retract_items,
+        /// <summary>
+        /// Retrieval of current affiliations is supported.
+        /// </summary>
+        retrieve_affiliations,
+        /// <summary>
+        /// Retrieval of default node configuration is supported.
+        /// </summary>
+        retrieve_default,
+        /// <summary>
+        /// Item retrieval is supported.
+        /// </summary>
+        retrieve_items,
+        /// <summary>
+        /// Retrieval of current subscriptions is supported.
+        /// </summary>
+        retrieve_subscriptions,
+        /// <summary>
+        /// Subscribing and unsubscribing are supported.
+        /// </summary>
+        subscribe,
+        /// <summary>
+        /// Configuration of subscription options is supported.
+        /// </summary>
+        subscription_options,
+        /// <summary>
+        /// Notification of subscription state changes is supported.
+        /// </summary>
+        subscription_notifications,
+    }
+
+    /// <summary>
+    /// An unsupported protocol was used.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Unsupported : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public Unsupported(XmlDocument doc)
+            : base("unsupported", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Unsupported(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Which feature was unsupported?
+        /// </summary>
+        public PubSubFeature Feature
+        {
+            get { return GetEnumAttr<PubSubFeature>("feature"); }
+            set { SetEnumAttr("feature", value); }
+        }
+    }
+
+    /// <summary>
+    /// An invalid access model was specified.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class UnsupportedAccessModel : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public UnsupportedAccessModel(XmlDocument doc)
+            : base("unsupported-access-model", URI.PUBSUB_ERRORS, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public UnsupportedAccessModel(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/PubSubEvent.cs b/lib/jabber-net/jabber/protocol/iq/PubSubEvent.cs
new file mode 100644
index 0000000..5ef571a
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/PubSubEvent.cs
@@ -0,0 +1,459 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Xml;
+
+using bedrock.util;
+using jabber;
+using jabber.protocol;
+
+namespace jabber.protocol.iq
+{
+    /// <summary>
+    /// Publish/Subscribe.  See XEP-60: http://www.xmpp.org/extensions/xep-0060.html
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PubSubEvent : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public PubSubEvent(XmlDocument doc)
+            : base("event", URI.PUBSUB_EVENT, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public PubSubEvent(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The PubSub command associated with this instruction
+        /// </summary>
+        public PubSubCommand Command
+        {
+            get { return GetChildElement<PubSubCommand>(); }
+        }
+    }
+
+    /// <summary>
+    /// Notification for item deletion.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class EventRetract : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public EventRetract(XmlDocument doc)
+            : base("retract", URI.PUBSUB_EVENT, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public EventRetract(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// When in an event, there may be an ID as an attribute.
+        /// </summary>
+        public string ID
+        {
+            get { return GetAttr("id"); }
+            set { SetAttr("id", value); }
+        }
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class EventCollection : PubSubCommand
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public EventCollection(XmlDocument doc)
+            : base("collection", URI.PUBSUB_EVENT, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public EventCollection(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// A collection notification
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.collection; }
+        }
+
+        /// <summary>
+        /// The new node associated with the collection
+        /// </summary>
+        public EventAssociate Associate
+        {
+            get { return GetChildElement<EventAssociate>(); }
+            set { ReplaceChild<EventAssociate>(value); }
+        }
+        /// <summary>
+        /// The node removed from the collection
+        /// </summary>
+        public EventDisassociate Disassociate
+        {
+            get { return GetChildElement<EventDisassociate>(); }
+            set { ReplaceChild <EventDisassociate>(value); }
+        }
+    }
+
+    /// <summary>
+    /// Nodes added to a collection
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class EventAssociate : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public EventAssociate(XmlDocument doc)
+            : base("associate", URI.PUBSUB_EVENT, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public EventAssociate(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The new node name
+        /// </summary>
+        public string Node
+        {
+            get { return GetAttr("node"); }
+            set { SetAttr("node", value); }
+        }
+
+        /// <summary>
+        /// An x:data form that describes the new node
+        /// </summary>
+        public jabber.protocol.x.Data MetaData
+        {
+            get { return GetChildElement<jabber.protocol.x.Data>(); }
+            set { ReplaceChild<jabber.protocol.x.Data>(value); }
+        }
+    }
+
+    /// <summary>
+    /// Nodes removed from a collection
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class EventDisassociate : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public EventDisassociate(XmlDocument doc)
+            : base("disassociate", URI.PUBSUB_EVENT, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public EventDisassociate(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The removed node name
+        /// </summary>
+        public string Node
+        {
+            get { return GetAttr("node"); }
+            set { SetAttr("node", value); }
+        }
+    }
+
+    /// <summary>
+    /// Pubsub items notification.  This is the main reason for XEP-60 to have been written.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class EventItems : PubSubCommand
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public EventItems(XmlDocument doc)
+            : base("items", URI.PUBSUB_EVENT, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public EventItems(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Retrieve all of the new items
+        /// </summary>
+        /// <returns></returns>
+        public PubSubItem[] GetItems()
+        {
+            return GetElements<PubSubItem>().ToArray();
+        }
+
+        /// <summary>
+        /// Add a new item to the list
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public PubSubItem AddItem(string id)
+        {
+            PubSubItem item = new PubSubItem(OwnerDocument, URI.PUBSUB_EVENT);
+            AddChild(item);
+            item.ID = id;
+            return item;
+        }
+
+        /// <summary>
+        /// Get a list of id's of deleted items.
+        /// </summary>
+        /// <returns></returns>
+        public string[] GetRetractions()
+        {
+            TypedElementList<EventRetract> nl = GetElements<EventRetract>();
+            string[] ids = new string[nl.Count];
+            int i = 0;
+            foreach (EventRetract item in nl)
+                ids[i++] = item.ID;
+            return ids;
+        }
+
+        /// <summary>
+        /// Add a new item to the list
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public EventRetract AddRetract(string id)
+        {
+            EventRetract item = CreateChildElement<EventRetract>();
+            item.ID = id;
+            return item;
+        }
+
+        /// <summary>
+        /// A configuration event
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.items; }
+        }
+    }
+
+    /// <summary>
+    /// New node configuration
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class EventConfiguration : PubSubCommand
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public EventConfiguration(XmlDocument doc)
+            : base("configuration", URI.PUBSUB_EVENT, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public EventConfiguration(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// A configuration event
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.configuration; }
+        }
+
+        /// <summary>
+        /// An x:data form that describes the new configuration
+        /// </summary>
+        public jabber.protocol.x.Data MetaData
+        {
+            get { return GetChildElement<jabber.protocol.x.Data>(); }
+            set { ReplaceChild<jabber.protocol.x.Data>(value); }
+        }
+    }
+
+    /// <summary>
+    /// All of the items in a node have been deleted.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class EventPurge : PubSubCommand
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public EventPurge(XmlDocument doc)
+            : base("purge", URI.PUBSUB_EVENT, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public EventPurge(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// A purge event
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.purge; }
+        }
+    }
+
+    /// <summary>
+    /// Subscription state has changed
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class EventSubscription : PubSubCommand
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public EventSubscription(XmlDocument doc)
+            : base("subscription", URI.PUBSUB_EVENT, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public EventSubscription(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// A subscription event
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.subscription; }
+        }
+
+        /// <summary>
+        /// When does this subscription expire?  DateTime.MIN_VALUE for none.
+        /// </summary>
+        public DateTime Expiry
+        {
+            get { return GetDateTimeAttr("expiry"); }
+            set { SetDateTimeAttr("expiry", value); }
+        }
+
+        /// <summary>
+        /// The JID of the subscriber
+        /// </summary>
+        public JID JID
+        {
+            get { return GetAttr("jid"); }
+            set { SetAttr("jid", value); }
+        }
+
+        /// <summary>
+        /// The ID of the subscription
+        /// </summary>
+        public string SubscriptionID
+        {
+            get { return GetAttr("subid"); }
+            set { SetAttr("subid", value); }
+        }
+
+        /// <summary>
+        /// The subscription state
+        /// </summary>
+        public PubSubSubscriptionType Subscription
+        {
+            get { return GetEnumAttr<PubSubSubscriptionType>("subscription"); }
+            set { SetEnumAttr("subscription", value); }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/PubSubOwner.cs b/lib/jabber-net/jabber/protocol/iq/PubSubOwner.cs
new file mode 100644
index 0000000..f4fb170
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/PubSubOwner.cs
@@ -0,0 +1,419 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Text;
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.iq
+{
+    /// <summary>
+    /// A type-safe PubSub IQ for owner actions.
+    /// </summary>
+    /// <typeparam name="T">The type of command to create</typeparam>
+    [SVN(@"$Id$")]
+    public class OwnerPubSubCommandIQ<T> : jabber.protocol.client.TypedIQ<OwnerPubSub<T>>
+        where T : PubSubCommand
+    {
+        /// <summary>
+        /// Create
+        /// </summary>
+        /// <param name="doc"></param>
+        public OwnerPubSubCommandIQ(XmlDocument doc)
+            : base(doc)
+        {
+        }
+
+        /// <summary>
+        /// Create, with node
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="node"></param>
+        public OwnerPubSubCommandIQ(XmlDocument doc, string node)
+            : base(doc)
+        {
+            Command.Node = node;
+        }
+
+        /// <summary>
+        /// The command inside the pubsub element.
+        /// </summary>
+        public T Command
+        {
+            get { return Instruction.Command; }
+            set { Instruction.Command = value; }
+        }
+    }
+
+    /// <summary>
+    /// A type-safe pubsub element.
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    [SVN(@"$Id$")]
+    public class OwnerPubSub<T> : Element
+        where T : PubSubCommand
+    {
+        /// <summary>
+        /// Create
+        /// </summary>
+        /// <param name="doc"></param>
+        public OwnerPubSub(XmlDocument doc)
+            : base("pubsub", URI.PUBSUB_OWNER, doc)
+        {
+            CreateChildElement<T>();
+        }
+
+        /// <summary>
+        /// The pubsub command
+        /// </summary>
+        public T Command
+        {
+            get { return GetChildElement<T>(); }
+            set { ReplaceChild<T>(value); }
+        }
+
+        /// <summary>
+        /// The type of pubsub command
+        /// </summary>
+        public PubSubCommandType CommandType
+        {
+            get { return Command.CommandType; }
+        }
+    }
+
+    /// <summary>
+    /// The pubsub container for owner operations.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PubSubOwner : Element
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public PubSubOwner(XmlDocument doc)
+            : base("pubsub", URI.PUBSUB_OWNER, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public PubSubOwner(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The command inside.
+        /// </summary>
+        public PubSubCommand Command
+        {
+            get { return GetChildElement<PubSubCommand>(); }
+        }
+
+        /// <summary>
+        /// The type of the included command
+        /// </summary>
+        public PubSubCommandType CommandType
+        {
+            get { return Command.CommandType; }
+        }
+    }
+
+    /// <summary>
+    /// Affiliations of all folks associated with a node
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class OwnerAffliliations : PubSubCommand
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public OwnerAffliliations(XmlDocument doc)
+            : base("affiliations", URI.PUBSUB_OWNER, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public OwnerAffliliations(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Affiliations command
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.affiliations; }
+        }
+
+        /// <summary>
+        /// Retrieve all of the affiliations
+        /// </summary>
+        /// <returns></returns>
+        public OwnerAffiliation[] GetAffiliations()
+        {
+            return GetElements<OwnerAffiliation>().ToArray();
+        }
+
+        /// <summary>
+        /// Add a new affiliation to the list.
+        /// </summary>
+        /// <param name="type"></param>
+        /// <param name="node"></param>
+        /// <returns></returns>
+        public OwnerAffiliation AddAffiliation(AffiliationType type, string node)
+        {
+            OwnerAffiliation afil = CreateChildElement<OwnerAffiliation>();
+            afil.Type = type;
+            afil.Node = node;
+            return afil;
+        }
+    }
+
+    /// <summary>
+    /// An affiliation for another user, retrieved by the owner.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class OwnerAffiliation : Affiliation
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public OwnerAffiliation(XmlDocument doc)
+            : base(doc, URI.PUBSUB_OWNER)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public OwnerAffiliation(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The JID of the affiliate.
+        /// </summary>
+        public JID JID
+        {
+            get { return GetAttr("jid"); }
+            set { SetAttr("jid", value); }
+        }
+    }
+
+    /// <summary>
+    /// Owner-level configuration
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class OwnerConfigure : PubSubCommand
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public OwnerConfigure(XmlDocument doc)
+            : base("configure", URI.PUBSUB_OWNER, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public OwnerConfigure(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Configure
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.configure; }
+        }
+
+        /// <summary>
+        /// An x:data form that describes the node
+        /// </summary>
+        public jabber.protocol.x.Data MetaData
+        {
+            get { return GetChildElement<jabber.protocol.x.Data>(); }
+            set { ReplaceChild<jabber.protocol.x.Data>(value); }
+        }
+    }
+
+    /// <summary>
+    /// The default configuration parameters
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class OwnerDefault : PubSubCommand
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public OwnerDefault(XmlDocument doc)
+            : base("default", URI.PUBSUB_OWNER, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public OwnerDefault(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Configure
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.defaults; }
+        }
+
+        /// <summary>
+        /// An x:data form that describes the node
+        /// </summary>
+        public jabber.protocol.x.Data MetaData
+        {
+            get { return GetChildElement<jabber.protocol.x.Data>(); }
+            set { ReplaceChild<jabber.protocol.x.Data>(value); }
+        }
+    }
+
+    /// <summary>
+    /// Delete a node
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class OwnerDelete : PubSubCommand
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public OwnerDelete(XmlDocument doc)
+            : base("delete", URI.PUBSUB_OWNER, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public OwnerDelete(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Delete
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.delete; }
+        }
+    }
+
+    /// <summary>
+    /// Purge all items from a node
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class OwnerPurge : PubSubCommand
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public OwnerPurge(XmlDocument doc)
+            : base("purge", URI.PUBSUB_OWNER, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public OwnerPurge(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Purge
+        /// </summary>
+        public override PubSubCommandType CommandType
+        {
+            get { return PubSubCommandType.purge;  }
+        }
+    }
+
+    /// <summary>
+    /// The subscription list
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class OwnerSubscriptions : Subscriptions
+    {
+        /// <summary>
+        /// Create for outbound.
+        /// </summary>
+        /// <param name="doc"></param>
+        public OwnerSubscriptions(XmlDocument doc)
+            : base(doc, URI.PUBSUB_OWNER)
+        {
+        }
+
+        /// <summary>
+        /// Create for inbound
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public OwnerSubscriptions(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+    }
+
+}
+    
\ No newline at end of file
diff --git a/lib/jabber-net/jabber/protocol/iq/Register.cs b/lib/jabber-net/jabber/protocol/iq/Register.cs
new file mode 100644
index 0000000..1a061e1
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/Register.cs
@@ -0,0 +1,278 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.iq
+{
+
+    /// <summary>
+    /// IQ packet with a register query element inside.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class RegisterIQ : jabber.protocol.client.TypedIQ<Register>
+    {
+        /// <summary>
+        /// Create a Register IQ.
+        /// </summary>
+        /// <param name="doc"></param>
+        public RegisterIQ(XmlDocument doc) : base(doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// User registration
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Register : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Register(XmlDocument doc) :
+            base("query", URI.REGISTER, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Register(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Instructions to the user.
+        /// </summary>
+        public string Instructions
+        {
+            get { return GetElem("instructions"); }
+            set { SetElem("instructions", value); }
+        }
+
+        /// <summary>
+        /// Username to register
+        /// </summary>
+        public string Username
+        {
+            get { return GetElem("username"); }
+            set { SetElem("username", value); }
+        }
+
+        /// <summary>
+        /// User nickname
+        /// </summary>
+        public string Nick
+        {
+            get { return GetElem("nick"); }
+            set { SetElem("nick", value); }
+        }
+
+        /// <summary>
+        /// User password
+        /// </summary>
+        public string Password
+        {
+            get { return GetElem("password"); }
+            set { SetElem("password", value); }
+        }
+
+        /// <summary>
+        /// The name element.... what's this for?
+        /// </summary>
+        public string JName
+        {
+            get { return GetElem("name"); }
+            set { SetElem("name", value); }
+        }
+
+        /// <summary>
+        /// The first name
+        /// </summary>
+        public string First
+        {
+            get { return GetElem("first"); }
+            set { SetElem("first", value); }
+        }
+
+        /// <summary>
+        /// Last name
+        /// </summary>
+        public string Last
+        {
+            get { return GetElem("last"); }
+            set { SetElem("last", value); }
+        }
+
+        /// <summary>
+        /// E-mail address
+        /// TODO: add format checking?
+        /// </summary>
+        public string Email
+        {
+            get { return GetElem("email"); }
+            set { SetElem("email", value); }
+        }
+
+        /// <summary>
+        /// User's mailing address
+        /// </summary>
+        public string Address
+        {
+            get { return GetElem("address"); }
+            set { SetElem("address", value); }
+        }
+
+        /// <summary>
+        /// User's city
+        /// </summary>
+        public string City
+        {
+            get { return GetElem("city"); }
+            set { SetElem("city", value); }
+        }
+
+        /// <summary>
+        /// User's state
+        /// </summary>
+        public string State
+        {
+            get { return GetElem("state"); }
+            set { SetElem("state", value); }
+        }
+
+        /// <summary>
+        /// User's zip code
+        /// </summary>
+        public string Zip
+        {
+            get { return GetElem("zip"); }
+            set { SetElem("zip", value); }
+        }
+
+        /// <summary>
+        /// User's phone number
+        /// </summary>
+        public string Phone
+        {
+            get { return GetElem("phone"); }
+            set { SetElem("phone", value); }
+        }
+
+        /// <summary>
+        /// URL for user
+        /// </summary>
+        public string Url
+        {
+            get { return GetElem("url"); }
+            set { SetElem("url", value); }
+        }
+
+        /// <summary>
+        /// Current date
+        /// </summary>
+        public string Date
+        {
+            get { return GetElem("date"); }
+            set { SetElem("date", value); }
+        }
+
+        /// <summary>
+        /// Miscellaneous information
+        /// </summary>
+        public string Misc
+        {
+            get { return GetElem("misc"); }
+            set { SetElem("misc", value); }
+        }
+
+        /// <summary>
+        /// Text... what is this used for?
+        /// </summary>
+        public string Text
+        {
+            get { return GetElem("text"); }
+            set { SetElem("text", value); }
+        }
+
+        /// <summary>
+        /// Public key?
+        /// </summary>
+        public string Key
+        {
+            get { return GetElem("key"); }
+            set { SetElem("key", value); }
+        }
+
+        /// <summary>
+        /// Is the user already registered?
+        /// </summary>
+        public bool Registered
+        {
+            get { return (this["registered"] != null); }
+            set
+            {
+                if (value)
+                {
+                    SetElem("registered", null);
+                }
+                else
+                {
+                    XmlNode child = this["registered"];
+                    if (child != null)
+                        RemoveChild(child);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Remove the current user.
+        /// </summary>
+        public bool Remove
+        {
+            get { return GetElem("remove") != null; }
+            set
+            {
+                if (value)
+                {
+                    SetElem("remove", null);
+                }
+                else
+                {
+                    XmlNode child = this["remove"];
+                    if (child != null)
+                        RemoveChild(child);
+                }
+            }
+        }
+
+        /// <summary>
+        /// The x:data form for the registration request.  Null if none specified.
+        /// </summary>
+        public jabber.protocol.x.Data Form
+        {
+            get { return GetChildElement<jabber.protocol.x.Data>(); }
+            set { ReplaceChild <jabber.protocol.x.Data>(value); }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/Roster.cs b/lib/jabber-net/jabber/protocol/iq/Roster.cs
new file mode 100644
index 0000000..0e8a9d2
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/Roster.cs
@@ -0,0 +1,300 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.iq
+{
+    /// <summary>
+    /// IQ packet with a roster query element inside.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class RosterIQ : jabber.protocol.client.TypedIQ<Roster>
+    {
+        /// <summary>
+        /// Create a roster IQ.
+        /// </summary>
+        /// <param name="doc"></param>
+        public RosterIQ(XmlDocument doc) : base(doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// A roster query element.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Roster : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Roster(XmlDocument doc) : base("query", URI.ROSTER, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Roster(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Add a roster item
+        /// </summary>
+        /// <returns></returns>
+        public Item AddItem()
+        {
+            return CreateChildElement<Item>();
+        }
+
+        /// <summary>
+        /// List of roster items
+        /// </summary>
+        /// <returns></returns>
+        public Item[] GetItems()
+        {
+            return GetElements<Item>().ToArray();
+        }
+    }
+
+    /// <summary>
+    /// The current status of the subscription related to this item.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum Subscription
+    {
+        /// <summary>
+        /// No subscription state has been specified.
+        /// </summary>
+        UNSPECIFIED = -1,
+        /// <summary>
+        /// Subscription to this person.  They are a lurkee.
+        /// </summary>
+        to,
+        /// <summary>
+        /// Subscription from this person.  They are a lurker.
+        /// </summary>
+        from,
+        /// <summary>
+        /// subscriptions in both ways.
+        /// </summary>
+        both,
+        /// <summary>
+        /// No subscription yet.  Often an Ask on this item.
+        /// </summary>
+        none,
+        /// <summary>
+        /// Remove this subscription from the local roster.
+        /// </summary>
+        remove,
+    }
+
+    /// <summary>
+    /// An optional attribute specifying the current status of a request to this contact.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum Ask
+    {
+        /// <summary>
+        /// No Ask specified.
+        /// </summary>
+        NONE = -1,
+        /// <summary>
+        /// this entity is asking to subscribe to that contact's presence
+        /// </summary>
+        subscribe,
+        /// <summary>
+        /// this entity is asking unsubscribe from that contact's presence
+        /// </summary>
+        unsubscribe
+    }
+
+    /// <summary>
+    /// Roster items.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Item : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Item(XmlDocument doc) : base("item", URI.ROSTER, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Item(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Item JID
+        /// </summary>
+        public JID JID
+        {
+            get { return GetAttr("jid"); }
+            set { this.SetAttr("jid", value); }
+        }
+
+        /// <summary>
+        /// The user's nick
+        /// </summary>
+        public string Nickname
+        {
+            get { return GetAttr("name"); }
+            set { SetAttr("name", value); }
+        }
+
+        /// <summary>
+        /// How are we subscribed?
+        /// </summary>
+        public Subscription Subscription
+        {
+            get { return GetEnumAttr<Subscription>("subscription"); }
+            set { SetEnumAttr("subscription", value); }
+        }
+
+        /// <summary>
+        /// Pending?
+        /// </summary>
+        public Ask Ask
+        {
+            get { return GetEnumAttr<Ask>("ask"); }
+            set { SetEnumAttr("ask", value); }
+        }
+
+        /// <summary>
+        /// Add an item group, or return an existing group with the given name
+        /// </summary>
+        /// <returns></returns>
+        public Group AddGroup(string name)
+        {
+            Group g = GetGroup(name);
+            if (g == null)
+            {
+                g = CreateChildElement<Group>();
+                g.GroupName = name;
+            }
+            return g;
+        }
+
+        /// <summary>
+        /// Remove a group of the given name.  Does nothing if that group is not found.
+        /// </summary>
+        /// <param name="name"></param>
+        public void RemoveGroup(string name)
+        {
+            foreach (Group g in GetElements<Group>())
+            {
+                if (g.GroupName == name)
+                {
+                    this.RemoveChild(g);
+                    return;
+                }
+            }
+        }
+
+        /// <summary>
+        /// List of item groups
+        /// </summary>
+        /// <returns></returns>
+        public Group[] GetGroups()
+        {
+            return GetElements<Group>().ToArray();
+        }
+
+        /// <summary>
+        /// Is this item in the specified group?
+        /// </summary>
+        /// <param name="name">The name of the group to check</param>
+        /// <returns></returns>
+        public bool HasGroup(string name)
+        {
+            foreach (Group g in GetElements<Group>())
+            {
+                if (g.GroupName == name)
+                    return true;
+            }
+            return false;
+        }
+
+        /// <summary>
+        /// Get the group object of the given name in this item.
+        /// If there is no group of that name, returns null.
+        /// </summary>
+        /// <param name="name">The name of the group to return</param>
+        /// <returns>null if none found.</returns>
+        public Group GetGroup(string name)
+        {
+            foreach (Group g in GetElements<Group>())
+            {
+                if (g.GroupName == name)
+                    return g;
+            }
+            return null;
+        }
+    }
+
+    /// <summary>
+    /// Roster item groups.  <group>GroupName</group>
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Group : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Group(XmlDocument doc) : base("group", URI.ROSTER, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Group(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Name of the group.
+        /// </summary>
+        public string GroupName
+        {
+            get { return this.InnerText; }
+            set { this.InnerText = value; }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/Time.cs b/lib/jabber-net/jabber/protocol/iq/Time.cs
new file mode 100644
index 0000000..7e7b35d
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/Time.cs
@@ -0,0 +1,113 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.iq
+{
+    /*
+     * <iq type="result" to="romeo at montague.net/orchard"
+     *                   from="juliet at capulet.com/balcony"
+     *                   id="i_time_001">
+     *   <query xmlns="jabber:iq:time">
+     *     <utc>20020214T23:55:06</utc>
+     *     <tz>WET</tz>
+     *     <display>14 Feb 2002 11:55:06 PM</display>
+     *   </query>
+     * </iq>
+     */
+    /// <summary>
+    /// IQ packet with an time query element inside.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class TimeIQ : jabber.protocol.client.TypedIQ<Time>
+    {
+        /// <summary>
+        /// Create a time IQ
+        /// </summary>
+        /// <param name="doc"></param>
+        public TimeIQ(XmlDocument doc) : base(doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// A time query element.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Time : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Time(XmlDocument doc) : base("query", URI.TIME, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Time(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Set the current UTC, TZ, and Display based on the machine's current settings/locale.
+        /// </summary>
+        public void SetCurrentTime()
+        {
+            DateTime dt = DateTime.Now;
+            UTC = dt.ToUniversalTime();
+            TZ = TimeZone.CurrentTimeZone.IsDaylightSavingTime(dt) ?
+                TimeZone.CurrentTimeZone.DaylightName : TimeZone.CurrentTimeZone.StandardName;
+            Display = dt.ToLongDateString() + " " + dt.ToLongTimeString();
+        }
+
+        /// <summary>
+        /// Universal coordinated time.  (More or less GMT).
+        /// </summary>
+        public DateTime UTC
+        {
+            get { return JabberDate(GetElem("utc")); }
+            set { SetElem("utc", JabberDate(value)); }
+        }
+
+        /// <summary>
+        /// Timezone
+        /// </summary>
+        //TODO: return System.TimeZone?
+        public string TZ
+        {
+            get { return GetElem("tz"); }
+            set { SetElem("tz", value); }
+        }
+
+        /// <summary>
+        /// Human-readable date/time.
+        /// </summary>
+        public string Display
+        {
+            get { return GetElem("display"); }
+            set { SetElem("display", value); }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/VCard.cs b/lib/jabber-net/jabber/protocol/iq/VCard.cs
new file mode 100644
index 0000000..e760728
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/VCard.cs
@@ -0,0 +1,965 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+// http://www.xmpp.org/extensions/xep-0054.html
+
+namespace jabber.protocol.iq
+{
+    /// <summary>
+    /// Type of telephone number.
+    /// </summary>
+    public enum TelephoneType
+    {
+        /// <summary>
+        /// None specified
+        /// </summary>
+        unknown = -1,
+        /// <summary>
+        /// voice
+        /// </summary>
+        voice,
+        /// <summary>
+        /// fax
+        /// </summary>
+        fax,
+        /// <summary>
+        /// pager
+        /// </summary>
+        pager,
+        /// <summary>
+        /// voice mail
+        /// </summary>
+        msg,
+        /// <summary>
+        /// mobile
+        /// </summary>
+        cell,
+        /// <summary>
+        /// video phone
+        /// </summary>
+        video,
+        /// <summary>
+        /// Bulletin Board System
+        /// </summary>
+        bbs,
+        /// <summary>
+        /// Modem
+        /// </summary>
+        modem,
+        /// <summary>
+        /// ISDN
+        /// </summary>
+        isdn,
+        /// <summary>
+        /// dunno.
+        /// </summary>
+        pcs
+    };
+
+    /// <summary>
+    /// Telephone location
+    /// </summary>
+    public enum TelephoneLocation
+    {
+        /// <summary>
+        /// Home
+        /// </summary>
+        home,
+        /// <summary>
+        /// Work
+        /// </summary>
+        work,
+        /// <summary>
+        /// Unknown
+        /// </summary>
+        unknown
+    }
+
+    /// <summary>
+    /// Address location
+    /// </summary>
+    public enum AddressLocation
+    {
+        /// <summary>
+        /// Home
+        /// </summary>
+        home,
+        /// <summary>
+        /// Work
+        /// </summary>
+        work,
+        /// <summary>
+        /// Unknown
+        /// </summary>
+        unknown
+    }
+
+    /// <summary>
+    /// Email type attribute
+    /// </summary>
+    public enum EmailType
+    {
+        /// <summary>
+        /// None specified
+        /// </summary>
+        NONE = -1,
+        /// <summary>
+        /// Home
+        /// </summary>
+        home,
+        /// <summary>
+        /// Work
+        /// </summary>
+        work,
+        /// <summary>
+        /// Internet
+        /// </summary>
+        internet,
+        /// <summary>
+        /// x400
+        /// </summary>
+        x400
+    }
+
+    /// <summary>
+    /// IQ packet with a version query element inside.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class VCardIQ : jabber.protocol.client.TypedIQ<VCard>
+    {
+        /// <summary>
+        /// Create a vCard IQ
+        /// </summary>
+        /// <param name="doc"></param>
+        public VCardIQ(XmlDocument doc) : base(doc)
+        {
+        }
+
+        /// <summary>
+        /// returns the vCard element for this iq.
+        /// </summary>
+        public VCard VCard
+        {
+            get { return Instruction; }
+        }
+    }
+
+    /// <summary>
+    /// A vCard element.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class VCard : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public VCard(XmlDocument doc) : base("vCard", URI.VCARD, doc)
+        {
+        //  SetElem("PRODID", "jabber-net: " + this.GetType().Assembly.FullName);
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public VCard(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Full name of the individual, as a single string
+        /// </summary>
+        public string FullName
+        {
+            get { return GetElem("FN"); }
+            set { SetElem("FN", value); }
+        }
+
+        /// <summary>
+        /// Pieces of the name, split apart
+        /// </summary>
+        public VName ComplexName
+        {
+            get { return this["N"] as VName; }
+            set { ReplaceChild(value); }
+        }
+
+        /// <summary>
+        /// Person's nick name.  This might be a good choice for a default roster nick,
+        /// for instance.
+        /// </summary>
+        public string Nickname
+        {
+            get { return GetElem("NICKNAME"); }
+            set { SetElem("NICKNAME", value); }
+        }
+
+        /// <summary>
+        /// User's photograph
+        /// </summary>
+        public VPhoto Photo
+        {
+            get { return this["PHOTO"] as VPhoto; }
+            set { ReplaceChild(value); }
+        }
+
+        /// <summary>
+        /// Date of birth
+        /// </summary>
+        public DateTime Birthday
+        {
+            get { return DateTime.Parse(GetElem("BDAY")); }
+            set { SetElem("BDAY", string.Format("yyyy-MM-dd", value)); }
+        }
+
+        /// <summary>
+        /// Associated URL
+        /// </summary>
+        public System.Uri Url
+        {
+            get
+            {
+                string url = GetElem("URL");
+                if ((url == null) || (url == ""))
+                    return null;
+                try
+                {
+                    Uri uri = new Uri(url);
+                    return uri;
+                }
+                catch (UriFormatException)
+                {
+                    return null;
+                }
+            }
+            set { SetElem("URL", value.ToString()); }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        public VOrganization Organization
+        {
+            get { return this["ORG"] as VOrganization; }
+            set { this.ReplaceChild(value); }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        public string Title
+        {
+            get { return GetElem("TITLE"); }
+            set { SetElem("TITLE", value); }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        public string Role
+        {
+            get { return GetElem("ROLE"); }
+            set { SetElem("ROLE", value); }
+        }
+
+        /// <summary>
+        /// Jabber ID
+        /// </summary>
+        public JID JabberId
+        {
+            get { return GetElem("JABBERID"); }
+            set { SetElem("JABBERID", value); }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        public string Description
+        {
+            get { return GetElem("DESC"); }
+            set { SetElem("DESC", value); }
+        }
+
+        /// <summary>
+        /// List of telephone numbers
+        /// </summary>
+        /// <returns></returns>
+        public VTelephone[] GetTelephoneList()
+        {
+            XmlNodeList nl = GetElementsByTagName("TEL", URI.VCARD);
+            VTelephone[] numbers = new VTelephone[nl.Count];
+            int i=0;
+            foreach (XmlNode n in nl)
+            {
+                numbers[i] = (VTelephone) n;
+                i++;
+            }
+            return numbers;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="type"></param>
+        /// <param name="location"></param>
+        /// <returns></returns>
+        public VTelephone GetTelephone(TelephoneType type, TelephoneLocation location)
+        {
+            foreach (VTelephone tel in GetTelephoneList())
+            {
+                if ((tel.Location == location) && (tel.Type == type))
+                    return tel;
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// List of addresses
+        /// </summary>
+        /// <returns></returns>
+        public VAddress[] GetAddressList()
+        {
+            XmlNodeList nl = GetElementsByTagName("ADR", URI.VCARD);
+            VAddress[] addresses = new VAddress[nl.Count];
+            int i=0;
+            foreach (XmlNode n in nl)
+            {
+                addresses[i] = (VAddress) n;
+                i++;
+            }
+            return addresses;
+        }
+
+        /// <summary>
+        /// Get the address for the given location.
+        /// </summary>
+        /// <param name="location"></param>
+        /// <returns></returns>
+        public VAddress GetAddress(AddressLocation location)
+        {
+            foreach (VAddress adr in GetAddressList())
+            {
+                if (adr.Location == location)
+                    return adr;
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// List of Email addresses
+        /// </summary>
+        /// <returns></returns>
+        public VEmail[] GetEmailList()
+        {
+            XmlNodeList nl = GetElementsByTagName("EMAIL", URI.VCARD);
+            VEmail[] emails = new VEmail[nl.Count];
+            int i=0;
+            foreach (XmlNode n in nl)
+            {
+                emails[i] = (VEmail)n;
+                i++;
+            }
+            return emails;
+        }
+
+        /// <summary>
+        /// Get the email address for the given type.
+        /// </summary>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        public VEmail GetEmail(EmailType type)
+        {
+            foreach (VEmail email in GetEmailList())
+            {
+                if (email.Type == type)
+                    return email;
+            }
+            return null;
+        }
+
+        /// <summary>
+        ///  Sets the email address for the given type.
+        /// </summary>
+        /// <param name="email"></param>
+        public void SetEmail(VEmail email)
+        {
+            VEmail existing = GetEmail(email.Type);
+            if (existing == null)
+            {
+                AddChild(email);
+            }
+            else
+            {
+                existing.UserId = email.UserId;
+            }
+        }
+
+        /// <summary>
+        /// Get the internet email address (default)
+        /// </summary>
+        /// <returns></returns>
+        public string Email
+        {
+            get
+            {
+                VEmail vemail = GetEmail(EmailType.internet);
+                return vemail == null ? null : vemail.UserId;
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        [SVN(@"$Id$")]
+        public class VName : Element
+        {
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="doc"></param>
+            public VName(XmlDocument doc) : base("N", URI.VCARD, doc)
+            {
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="prefix"></param>
+            /// <param name="qname"></param>
+            /// <param name="doc"></param>
+            public VName(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+                base(prefix, qname, doc)
+            {
+            }
+
+            /// <summary>
+            /// Given (first) name
+            /// </summary>
+            public string Given
+            {
+                get { return GetElem("GIVEN"); }
+                set { SetElem("GIVEN", value); }
+            }
+
+            /// <summary>
+            /// Family (last) name
+            /// </summary>
+            public string Family
+            {
+                get { return GetElem("FAMILY"); }
+                set { SetElem("FAMILY", value); }
+            }
+
+            /// <summary>
+            /// Middle name
+            /// </summary>
+            public string Middle
+            {
+                get { return GetElem("MIDDLE"); }
+                set { SetElem("MIDDLE", value); }
+            }
+        }
+
+        /// <summary>
+        /// vCard Org Element
+        /// </summary>
+        [SVN(@"$Id$")]
+        public class VOrganization : Element
+        {
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="doc"></param>
+            public VOrganization(XmlDocument doc) : base("ORG", URI.VCARD, doc)
+            {
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="prefix"></param>
+            /// <param name="qname"></param>
+            /// <param name="doc"></param>
+            public VOrganization(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+                base(prefix, qname, doc)
+            {
+            }
+
+            /// <summary>
+            /// Orginization Name
+            /// </summary>
+            public string OrgName
+            {
+                get { return GetElem("ORGNAME"); }
+                set { SetElem("ORGNAME", value); }
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            public string Unit
+            {
+                get { return GetElem("ORGUNIT"); }
+                set { SetElem("ORGUNIT", value); }
+            }
+        }
+
+        /// <summary>
+        /// vCard Telephone Element
+        /// </summary>
+        [SVN(@"$Id$")]
+        public class VTelephone : Element
+        {
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="doc"></param>
+            public VTelephone(XmlDocument doc) : base("TEL", URI.VCARD, doc)
+            {
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="prefix"></param>
+            /// <param name="qname"></param>
+            /// <param name="doc"></param>
+            public VTelephone(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+                base(prefix, qname, doc)
+            {
+            }
+
+            /// <summary>
+            /// Phone number
+            /// </summary>
+            public string Number
+            {
+                get { return GetElem("NUMBER"); }
+                set { SetElem("NUMBER", value); }
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            public TelephoneType Type
+            {
+                get
+                {
+                    if (this["VOICE"] != null) return TelephoneType.voice;
+                    else if (this["FAX"] != null) return TelephoneType.fax;
+                    else if (this["MSG"] != null) return TelephoneType.msg;
+                    else return TelephoneType.unknown;
+                }
+                set
+                {
+                    RemoveElem("VOICE");
+                    RemoveElem("FAX");
+                    RemoveElem("MSG");
+
+                    switch (value)
+                    {
+                        case TelephoneType.voice:
+                            SetElem("VOICE", null);
+                            break;
+                        case TelephoneType.fax:
+                            SetElem("FAX", null);
+                            break;
+                        case TelephoneType.msg:
+                            SetElem("MSG", null);
+                            break;
+                    }
+                }
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            public TelephoneLocation Location
+            {
+                get
+                {
+                    if (this["WORK"] != null) return TelephoneLocation.work;
+                    else if (this["HOME"] != null) return TelephoneLocation.home;
+                    else return TelephoneLocation.unknown;
+                }
+                set
+                {
+                    this.RemoveElem("WORK");
+                    this.RemoveElem("HOME");
+
+                    switch (value)
+                    {
+                        case TelephoneLocation.work:
+                            SetElem("WORK", null);
+                            break;
+                        case TelephoneLocation.home:
+                            SetElem("HOME", null);
+                            break;
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// vCard Address Element
+        /// </summary>
+        [SVN(@"$Id$")]
+        public class VAddress : Element
+        {
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="doc"></param>
+            public VAddress(XmlDocument doc) : base("ADR", URI.VCARD, doc)
+            {
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="prefix"></param>
+            /// <param name="qname"></param>
+            /// <param name="doc"></param>
+            public VAddress(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+                base(prefix, qname, doc)
+            {
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            public string Street
+            {
+                get { return GetElem("STREET"); }
+                set { SetElem("STREET", value); }
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            public string Locality
+            {
+                get { return GetElem("LOCALITY"); }
+                set { SetElem("LOCALITY", value); }
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            public string Region
+            {
+                get { return GetElem("REGION"); }
+                set { SetElem("REGION", value); }
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            public string PostalCode
+            {
+                get { return GetElem("PCODE"); }
+                set { SetElem("PCODE", value); }
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            public string Country
+            {
+                get { return GetElem("CTRY"); }
+                set { SetElem("CTRY", value); }
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            public string Extra
+            {
+                get { return GetElem("EXTADD"); }
+                set { SetElem("EXTADD", value); }
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            public AddressLocation Location
+            {
+                get
+                {
+                    if (this["WORK"] != null) return AddressLocation.work;
+                    else if (this["HOME"] != null) return AddressLocation.home;
+                    else return AddressLocation.unknown;
+                }
+                set
+                {
+                    this.RemoveElem("WORK");
+                    this.RemoveElem("HOME");
+
+                    switch (value)
+                    {
+                        case AddressLocation.work:
+                            SetElem("WORK", null);
+                            break;
+                        case AddressLocation.home:
+                            SetElem("HOME", null);
+                            break;
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// vCard Email Element
+        /// </summary>
+        [SVN(@"$Id$")]
+        public class VEmail : Element
+        {
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="doc"></param>
+            public VEmail(XmlDocument doc) : base("EMAIL", URI.VCARD, doc)
+            {
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="prefix"></param>
+            /// <param name="qname"></param>
+            /// <param name="doc"></param>
+            public VEmail(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+                base(prefix, qname, doc)
+            {
+            }
+
+            /// <summary>
+            /// The e-mail address
+            /// </summary>
+            public string UserId
+            {
+                get { return GetElem("USERID"); }
+                set { SetElem("USERID", value); }
+            }
+
+            /// <summary>
+            /// Is this the preferred e-mail address?
+            /// </summary>
+            public bool IsPreferred
+            {
+                get { return (this["PREF"] != null); }
+                set
+                {
+                    if (value)
+                        SetElem("PREF", null);
+                    else
+                        RemoveElem("PREF");
+                }
+            }
+
+            /// <summary>
+            /// What kind of address is this?
+            /// </summary>
+            public EmailType Type
+            {
+                get
+                {
+                    if (this["HOME"] != null) return EmailType.home;
+                    else if (this["WORK"] != null) return EmailType.work;
+                    else if (this["INTERNET"] != null) return EmailType.internet;
+                    else if (this["X400"] != null) return EmailType.x400;
+                    else return EmailType.NONE;
+                }
+                set
+                {
+                    RemoveElem("HOME");
+                    RemoveElem("WORK");
+                    RemoveElem("INTERNET");
+                    RemoveElem("X400");
+
+                    switch (value)
+                    {
+                        case EmailType.home:
+                            SetElem("HOME", null);
+                            break;
+                        case EmailType.work:
+                            SetElem("WORK", null);
+                            break;
+                        case EmailType.internet:
+                            SetElem("INTERNET", null);
+                            break;
+                        case EmailType.x400:
+                            SetElem("X400", null);
+                            break;
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Geographic location
+        /// </summary>
+        [SVN(@"$Id$")]
+        public class VGeo : Element
+        {
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="doc"></param>
+            public VGeo(XmlDocument doc) : base("GEO", URI.VCARD, doc)
+            {
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="prefix"></param>
+            /// <param name="qname"></param>
+            /// <param name="doc"></param>
+            public VGeo(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+                base(prefix, qname, doc)
+            {
+            }
+
+            /// <summary>
+            /// Latitude
+            /// </summary>
+            public double Lat
+            {
+                get { return double.Parse(GetElem("LAT")); }
+                set { SetElem("LAT", string.Format("{0:6f}", value)); }
+            }
+
+            /// <summary>
+            /// Longitude
+            /// </summary>
+            public double Lon
+            {
+                get { return double.Parse(GetElem("LON")); }
+                set { SetElem("LON", string.Format("{0:6f}", value)); }
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        [SVN(@"$Id$")]
+        public class VPhoto : Element
+        {
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="doc"></param>
+            public VPhoto(XmlDocument doc) : base("PHOTO", URI.VCARD, doc)
+            {
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="prefix"></param>
+            /// <param name="qname"></param>
+            /// <param name="doc"></param>
+            public VPhoto(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+                base(prefix, qname, doc)
+            {
+            }
+
+            /// <summary>
+            /// The MIME type of the image.  Must be set before
+            /// calling Image.set.
+            /// </summary>
+            public System.Drawing.Imaging.ImageFormat ImageType
+            {
+                get 
+                {
+                    System.Drawing.Imaging.ImageFormat def = System.Drawing.Imaging.ImageFormat.Png;
+
+                    // Strip off all but everything after the last slash,
+                    // if any.
+                    string t = GetElem("TYPE");
+                    if ((t == null) || (t == ""))
+                        return def;
+                    string[] parts = t.Split("/".ToCharArray());
+                    if (parts.Length == 0)
+                        return def;
+                    t = parts[parts.Length - 1].ToLower();
+                    switch (t)
+                    {
+                        case "jpeg":
+                        case "jpg":
+                            return System.Drawing.Imaging.ImageFormat.Jpeg;
+                        case "png":
+                            return System.Drawing.Imaging.ImageFormat.Png;
+                        case "bmp":
+                            return System.Drawing.Imaging.ImageFormat.Bmp;
+                        case "gif":
+                            return System.Drawing.Imaging.ImageFormat.Gif;
+                        case "tif":
+                        case "tiff":
+                            return System.Drawing.Imaging.ImageFormat.Tiff;
+                    }
+                    return def;
+                }
+                set { SetElem("TYPE", value.ToString().ToLower()); }
+            }
+
+            /// <summary>
+            /// The bytes associated with the picture
+            /// </summary>
+            public byte[] BinVal
+            {
+                get
+                {
+                    string b64 = GetElem("BINVAL");
+                    if (b64 == null)
+                        return null;
+                    return Convert.FromBase64String(b64);
+                }
+                set { SetElem("BINVAL", Convert.ToBase64String(value)); }
+            }
+
+            /// <summary>
+            /// An Image representation of the bytes in the picture.
+            /// The MimeType MUST be set before calling set.
+            /// </summary>
+            public System.Drawing.Image Image
+            {
+                get
+                {
+                    byte[] bin = this.BinVal;
+                    if (bin == null)
+                        return null;
+                    System.IO.MemoryStream ms = new System.IO.MemoryStream(bin);
+                    return System.Drawing.Image.FromStream(ms);
+                }
+                set
+                {
+                    System.IO.MemoryStream ms = new System.IO.MemoryStream();
+                    Image.Save(ms, this.ImageType);
+                    this.BinVal = ms.GetBuffer();
+                }
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/iq/Version.cs b/lib/jabber-net/jabber/protocol/iq/Version.cs
new file mode 100644
index 0000000..a8ebd01
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/iq/Version.cs
@@ -0,0 +1,88 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.iq
+{
+    /// <summary>
+    /// IQ packet with a version query element inside.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class VersionIQ : jabber.protocol.client.TypedIQ<Version>
+    {
+        /// <summary>
+        /// Create a version IQ
+        /// </summary>
+        /// <param name="doc"></param>
+        public VersionIQ(XmlDocument doc) : base(doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// A time query element.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Version : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Version(XmlDocument doc) : base("query", URI.VERSION, doc)
+        {
+        }
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Version(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Name of the entity.
+        /// </summary>
+        public string EntityName
+        {
+            get { return GetElem("name"); }
+            set { SetElem("name", value); }
+        }
+
+        /// <summary>
+        /// Enitity version.  (Version was a keyword, or something)
+        /// </summary>
+        public string Ver
+        {
+            get { return GetElem("version"); }
+            set { SetElem("version", value); }
+        }
+
+        /// <summary>
+        /// Operating system of the entity.
+        /// </summary>
+        public string OS
+        {
+            get { return GetElem("os"); }
+            set { SetElem("os", value); }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/stream/Bind.cs b/lib/jabber-net/jabber/protocol/stream/Bind.cs
new file mode 100644
index 0000000..d142564
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/stream/Bind.cs
@@ -0,0 +1,65 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.stream
+{
+    /// <summary>
+    /// Bind start after binding
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Bind : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Bind(XmlDocument doc) :
+            base("", new XmlQualifiedName("bind", jabber.protocol.URI.BIND), doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Bind(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The resource to bind to.  Null says for the server to pick.
+        /// </summary>
+        public string Resource
+        {
+            get { return GetElem("resource"); }
+            set { SetElem("resource", value); }
+        }
+
+        /// <summary>
+        /// The JID that the server selected for us.
+        /// </summary>
+        public string JID
+        {
+            get { return GetElem("jid"); }
+            set { SetElem("jid", value); }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/stream/Compression.cs b/lib/jabber-net/jabber/protocol/stream/Compression.cs
new file mode 100644
index 0000000..feaf9e4
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/stream/Compression.cs
@@ -0,0 +1,194 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.stream
+{
+    /// <summary>
+    /// XEP-138 compression.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Compression : Element
+    {
+        /// <summary>
+        /// Create a new compression feature element.
+        /// </summary>
+        /// <param name="doc"></param>
+        public Compression(XmlDocument doc) :
+            base("", new XmlQualifiedName("compression", jabber.protocol.URI.COMPRESS_FEATURE), doc)
+        {
+        }
+
+        /// <summary>
+        /// Create a new compression element.
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Compression(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The list of methods offered by the server.  Typically today, this will be one string: "zlib".
+        /// </summary>
+        public string[] Methods
+        {
+            get
+            {
+                XmlNodeList nl = GetElementsByTagName("method", URI.COMPRESS_FEATURE);
+                string[] meths = new string[nl.Count];
+                int i=0;
+                foreach (XmlElement m in nl)
+                {
+                    meths[i] = m.InnerText;
+                    i++;
+                }
+                return meths;
+            }
+            set
+            {
+                this.RemoveElems("method", URI.COMPRESS_FEATURE);
+                foreach (string m in value)
+                    SetElem("method", m);
+            }
+        }
+
+        /// <summary>
+        /// Does this compression element have the given method in it?
+        /// </summary>
+        /// <param name="method">The method to search for.  Typically: "zlib"</param>
+        /// <returns></returns>
+        public bool HasMethod(string method)
+        {
+            foreach (XmlElement meth in GetElementsByTagName("method", URI.COMPRESS_FEATURE))
+            {
+                if (meth.InnerText == method)
+                    return true;
+            }
+            return false;
+        }
+    }
+
+    /// <summary>
+    /// XEP-138 compression failure.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class CompressionFailure : Element
+    {
+        /// <summary>
+        /// Create a new compression element.
+        /// </summary>
+        /// <param name="doc"></param>
+        public CompressionFailure(XmlDocument doc) :
+            base("", new XmlQualifiedName("failure", jabber.protocol.URI.COMPRESS), doc)
+        {
+        }
+
+        /// <summary>
+        /// Create a new compression element.
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public CompressionFailure(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The error described by this failure.  One of:
+        /// setup-failed
+        /// processing-failed
+        /// unsupported-method
+        /// </summary>
+        public string Error
+        {
+            get { return GetFirstChildElement().Name; }
+            set
+            {
+                this.RemoveAll();
+                this.AddChild(this.OwnerDocument.CreateElement(value));
+            }
+        }
+    }
+
+    /// <summary>
+    /// XEP-138 compression start.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Compress : Element
+    {
+        /// <summary>
+        /// Create a new compress element.
+        /// </summary>
+        /// <param name="doc"></param>
+        public Compress(XmlDocument doc) :
+            base("", new XmlQualifiedName("compress", jabber.protocol.URI.COMPRESS), doc)
+        {
+        }
+
+        /// <summary>
+        /// Create a new compress element.
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Compress(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// What compression method should be used?
+        /// </summary>
+        public string Method
+        {
+            get { return GetElem("method"); }
+            set { SetElem("method", value); }
+        }
+    }
+
+
+    /// <summary>
+    /// XEP-138 compression success.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Compressed : Element
+    {
+        /// <summary>
+        /// Create a new compression element.
+        /// </summary>
+        /// <param name="doc"></param>
+        public Compressed(XmlDocument doc) :
+            base("", new XmlQualifiedName("compressed", jabber.protocol.URI.COMPRESS), doc)
+        {
+        }
+
+        /// <summary>
+        /// Create a new compression element.
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Compressed(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/stream/Error.cs b/lib/jabber-net/jabber/protocol/stream/Error.cs
new file mode 100644
index 0000000..07603aa
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/stream/Error.cs
@@ -0,0 +1,56 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.stream
+{
+    /// <summary>
+    /// Stream error packet.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Error : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Error(XmlDocument doc) : base("stream", new XmlQualifiedName("error", URI.STREAM), doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Error(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The error message
+        /// </summary>
+        public string Message
+        {
+            get { return this.InnerText; }
+            set { this.InnerXml = value; }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/stream/Factory.cs b/lib/jabber-net/jabber/protocol/stream/Factory.cs
new file mode 100644
index 0000000..b5a04ff
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/stream/Factory.cs
@@ -0,0 +1,59 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+
+using bedrock.util;
+using jabber.protocol;
+
+namespace jabber.protocol.stream
+{
+    /// <summary>
+    /// ElementFactory for http://etherx.jabber.org/streams
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Factory : jabber.protocol.IPacketTypes
+    {
+        private static QnameType[] s_qnt = new QnameType[]
+        {
+            new QnameType("stream",     URI.STREAM,    typeof(Stream)),
+            new QnameType("error",      URI.STREAM,    typeof(Error)),
+            new QnameType("features",   URI.STREAM,    typeof(Features)),
+
+            new QnameType("starttls",   URI.START_TLS, typeof(StartTLS)),
+            new QnameType("proceed",    URI.START_TLS, typeof(Proceed)),
+            new QnameType("failure",    URI.START_TLS, typeof(TLSFailure)),
+
+            new QnameType("compression", URI.COMPRESS_FEATURE, typeof(Compression)),
+            new QnameType("failure",    URI.COMPRESS,  typeof(CompressionFailure)),
+            new QnameType("compress",   URI.COMPRESS,  typeof(Compressed)),
+            new QnameType("compressed", URI.COMPRESS,  typeof(Compressed)),
+
+            new QnameType("mechanisms", URI.SASL,      typeof(Mechanisms)),
+            new QnameType("mechanism",  URI.SASL,      typeof(Mechanism)),
+            new QnameType("auth",       URI.SASL,      typeof(Auth)),
+            new QnameType("challenge",  URI.SASL,      typeof(Challenge)),
+            new QnameType("response",   URI.SASL,      typeof(Response)),
+            new QnameType("failure",    URI.SASL,      typeof(SASLFailure)),
+            new QnameType("abort",      URI.SASL,      typeof(Abort)),
+            new QnameType("success",    URI.SASL,      typeof(Success)),
+
+            new QnameType("session",    URI.SESSION,   typeof(Session)),
+            new QnameType("bind",       URI.BIND,      typeof(Bind)),
+
+            new QnameType("body",       URI.HTTP_BIND, typeof(Body)),
+        };
+        QnameType[] IPacketTypes.Types { get { return s_qnt; } }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/stream/Features.cs b/lib/jabber-net/jabber/protocol/stream/Features.cs
new file mode 100644
index 0000000..28cdd7a
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/stream/Features.cs
@@ -0,0 +1,77 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Xml;
+using bedrock.util;
+
+namespace jabber.protocol.stream
+{
+    /// <summary>
+    /// Stream Features handler
+    /// </summary>
+    public delegate void FeaturesHandler(Object sender, Features feat);
+
+    /// <summary>
+    /// Stream features.  Will only be set by a version="1.0" or higher XMPP server.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Features : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Features(XmlDocument doc) :
+            base("stream", new XmlQualifiedName("features", jabber.protocol.URI.STREAM), doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Features(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The starttls element, or null if none found.
+        /// </summary>
+        public StartTLS StartTLS
+        {
+            get { return this["starttls", jabber.protocol.URI.START_TLS] as StartTLS; }
+            set { ReplaceChild(value); }
+        }
+
+        /// <summary>
+        /// The SASL mechanisms, or null if none found.
+        /// </summary>
+        public Mechanisms Mechanisms
+        {
+            get { return this["mechanisms", jabber.protocol.URI.SASL] as Mechanisms; }
+            set { ReplaceChild(value); }
+        }
+
+        /// <summary>
+        /// The compression element, or null if none found.
+        /// </summary>
+        public Compression Compression
+        {
+            get { return this["compression", jabber.protocol.URI.COMPRESS_FEATURE] as Compression; }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/stream/HttpBind.cs b/lib/jabber-net/jabber/protocol/stream/HttpBind.cs
new file mode 100644
index 0000000..b317f59
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/stream/HttpBind.cs
@@ -0,0 +1,461 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Xml;
+
+using bedrock.util;
+using jabber.protocol;
+
+namespace jabber.protocol.stream
+{
+    /// <summary>
+    /// These error conditions may be read by constrained clients. 
+    /// They are used for connection manager problems, abstracting stream errors, 
+    /// communication problems between the connection manager and the server, 
+    /// and invalid client requests (binding syntax errors, possible attacks, etc.)
+    /// </summary>
+    [Dash]
+    public enum ConditionType
+    {
+        /// <summary>
+        ///  None specified
+        /// </summary>
+        UNSPECIFIED = -1,
+        /// <summary>
+        /// The target domain specified in the 'to' attribute or the target host or
+        /// port specified in the 'route' attribute is no longer serviced by 
+        /// the connection manager.
+        /// </summary>
+        host_gone,
+        /// <summary>
+        /// The target domain specified in the 'to' attribute or the target host
+        /// or port specified in the 'route' attribute is unknown to the connection manager.
+        /// </summary>
+        host_unknown,
+        /// <summary>
+        /// The initialization element lacks a 'to' or 'route' attribute (or the 
+        /// attribute has no value) but the connection manager requires one.
+        /// </summary>
+        improper_addressing,
+        /// <summary>
+        /// The connection manager has experienced an internal error that prevents 
+        /// it from servicing the request.
+        /// </summary>
+        internal_server_error,
+        /// <summary>
+        /// The connection manager was unable to connect to, or unable to 
+        /// connect securely to, or has lost its connection to, the server.
+        /// </summary>
+        remote_connection_failed,
+        /// <summary>
+        /// Encapsulates an error in the protocol being transported.
+        /// </summary>
+        remote_stream_error,
+        /// <summary>
+        /// The connection manager does not operate at this URI 
+        /// (e.g., the connection manager accepts only SSL or TLS connections at 
+        /// some https: URI rather than the http: URI requested by the client). 
+        /// The client may try POSTing to the URI in the content of the <uri/> child element.
+        /// </summary>
+        see_other_uri,
+        /// <summary>
+        /// The connection manager is being shut down. All active HTTP sessions are
+        /// being terminated. No new sessions can be created.
+        /// </summary>
+        system_shutdown,
+        /// <summary>
+        /// The error is not one of those defined herein; the connection manager SHOULD 
+        /// include application-specific information in the content of the <body/> wrapper.
+        /// </summary>
+        undefined_condition
+    };
+
+    /// <summary>
+    /// Is this an error or a termination?
+    /// </summary>
+    public enum BodyType
+    {
+        /// <summary>
+        /// None specified
+        /// </summary>
+        UNSPECIFIED = -1,
+        /// <summary>
+        /// Error encapsulated in response
+        /// </summary>
+        error,
+        /// <summary>
+        /// Terminate the stream
+        /// </summary>
+        terminate
+    };
+    
+    /// <summary>
+    /// An HTTP Binding body element, which encapsulates stanzas.
+    /// See XEP-124 and XEP-206 for details.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Body : Element
+    {
+        /// <summary>
+        /// Create for outbound
+        /// </summary>
+        /// <param name="doc"></param>
+        public Body(XmlDocument doc) : base("body", URI.HTTP_BIND, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create inbound instance
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Body(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The child elements of the body.  0 or more stanzas.
+        /// </summary>
+        public ElementList Contents
+        {
+            get { return new ElementList(this); }
+            set
+            {
+                InnerXml = "";
+                foreach (XmlElement el in value)
+                    AddChild(el);
+            }
+        }
+
+        /// <summary>
+        /// The content encodings that server can handle.
+        /// </summary>
+        public string[] Accept
+        {
+            get { return GetAttr("accept").Split(new char[] {','}); }
+            set { SetAttr("accept", string.Join(",", value)); }
+        }
+
+        /// <summary>
+        /// Acknowledgement of a given RID.
+        /// </summary>
+        public long Ack
+        {
+            get { return GetLongAttr("ack"); }
+            set { SetLongAttr("ack", value); }
+        }
+
+        /// <summary>
+        /// Stream ID for digest auth calculations
+        /// </summary>
+        public string AuthID
+        {
+            get { return GetAttr("authid"); }
+            set { SetAttr("authid", value); }
+        }
+
+        /// <summary>
+        /// The charsets supported by the server.  Almost always just UTF8, if it exists.
+        /// </summary>
+        public string[] Charsets
+        {
+            get { return GetAttr("accept").Split(new char[] {' '}); }
+            set { SetAttr("accept", string.Join(" ", value)); }
+        }
+
+        /// <summary>
+        /// The error condition, if this is an error.
+        /// </summary>
+        public ConditionType Condition
+        {
+            get { return GetEnumAttr<ConditionType>("condition"); }
+            set { SetEnumAttr("condition", value); }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public string Content
+        {
+            get { return GetAttr("content"); }
+            set { SetAttr("content", value); }
+        }
+
+        /// <summary>
+        /// A client MAY include a 'from' attribute to enable the 
+        /// connection manager to forward its identity to the server.
+        /// </summary>
+        public string From
+        {
+            get { return GetAttr("from"); }
+            set { SetAttr("from", value); }
+        }
+
+        /// <summary>
+        /// This attribute specifies the maximum number of requests the connection manager 
+        /// is allowed to keep waiting at any one time during the session. If the client 
+        /// is not able to use HTTP Pipelining then this SHOULD be set to "1".
+        /// </summary>
+        public int Hold
+        {
+            get { return GetIntAttr("hold"); }
+            set { SetIntAttr("hold", value); }
+        }
+
+        /// <summary>
+        /// This attribute specifies the longest allowable inactivity period (in seconds). 
+        /// This enables the client to ensure that the periods with no requests pending 
+        /// are never too long (see Polling Sessions and Inactivity).
+        /// </summary>
+        public int Inactivity
+        {
+            get { return GetIntAttr("inactivity"); }
+            set { SetIntAttr("inactivity", value); }
+        }
+        
+        /// <summary>
+        /// The client MUST set the 'key' attribute of all subsequent requests to the 
+        /// value of the next key in the generated sequence (decrementing from K(n-1) 
+        /// towards K(1) with each request sent).
+        /// </summary>
+        public string Key
+        {
+            get { return GetAttr("key"); }
+            set { SetAttr("key", value); }
+        }
+        
+        /// <summary>
+        /// If the connection manager supports session pausing (see Inactivity) then it 
+        /// SHOULD advertise that to the client by including a 'maxpause' attribute in 
+        /// the session creation response element. The value of the attribute indicates 
+        /// the maximum length of a temporary session pause (in seconds) that a client
+        /// MAY request.
+        /// </summary>
+        public int MaxPause
+        {
+            get { return GetIntAttr("maxpause"); }
+            set { SetIntAttr("maxpause", value); }
+        }
+        
+        /// <summary>
+        /// The client MUST set the 'newkey' attribute of the first request in the session to the value K(n).
+        /// </summary>
+        public string NewKey
+        {
+            get { return GetAttr("newkey"); }
+            set { SetAttr("newkey", value); }
+        }
+        
+        /// <summary>
+        /// If a client encounters an exceptional temporary situation during which it 
+        /// will be unable to send requests to the connection manager for a period of 
+        /// time greater than the maximum inactivity period (e.g., while a runtime 
+        /// environment changes from one web page to another), and if the connection 
+        /// manager included a 'maxpause' attribute in its Session Creation Response,
+        /// then the client MAY request a temporary increase to the maximum inactivity 
+        /// period by including a 'pause' attribute in a request.
+        /// </summary>
+        public int Pause
+        {
+            get { return GetIntAttr("pause"); }
+            set { SetIntAttr("pause", value); }
+        }
+        
+        /// <summary>
+        /// This attribute specifies the shortest allowable polling interval (in seconds). 
+        /// This enables the client to not send empty request elements more often than desired.
+        /// </summary>
+        public int Polling
+        {
+            get { return GetIntAttr("polling"); }
+            set { SetIntAttr("polling", value); }
+        }
+        
+        /// <summary>
+        /// After receiving a request with an 'ack' value less than the 'rid' of the last
+        /// request that it has already responded to, the connection manager MAY inform 
+        /// the client of the situation by sending its next response immediately instead
+        /// of waiting until it has stanzas to send to the client (e.g., if some time
+        /// has passed since it responded). In this case it SHOULD include a 'report'
+        /// attribute set to one greater than the 'ack' attribute it received from the 
+        /// client, and a 'time' attribute set to the number of milliseconds since it 
+        /// sent the response associated with the 'report' attribute.
+        /// </summary>
+        public int Report
+        {
+            get { return GetIntAttr("report"); }
+            set { SetIntAttr("report", value); }
+        }
+        
+        /// <summary>
+        /// This attribute enables the connection manager to limit the number of 
+        /// simultaneous requests the client makes. The RECOMMENDED values are 
+        /// either "2" or one more than the value of the 'hold' attribute specified 
+        /// in the session request.
+        /// </summary>
+        public int Requests
+        {
+            get { return GetIntAttr("requests"); }
+            set { SetIntAttr("requests", value); }
+        }
+
+        /// <summary>
+        /// Request ID.  Needs to start out random, and increment by one for each new BOSH
+        /// request.
+        /// </summary>
+        public long RID
+        {
+            get { return GetLongAttr("rid"); }
+            set { SetLongAttr("rid", value); }
+        }
+
+        /// <summary>
+        /// connection manager MAY be configured to enable sessions with more than one 
+        /// server in different domains.  When requesting a session with such a 'proxy' 
+        /// connection manager, a client SHOULD include a 'route' attribute that 
+        /// specifies the protocol, hostname, and port of the server with which it 
+        /// wants to communicate, formatted as "proto:host:port" 
+        /// (e.g., "xmpp:jabber.org:9999").
+        /// </summary>
+        public string Route
+        {
+            get { return GetAttr("route"); }
+            set { SetAttr("route", value); }
+        }
+
+        /// <summary>
+        /// A client MAY include a 'secure' attribute to specify that communications 
+        /// between the connection manager and the server must be "secure". (Note: The
+        /// 'secure' attribute is of type xs:boolean (see XML Schema Part 2) and the 
+        /// default value is "false". [17]) If a connection manager receives a session
+        /// request with the 'secure' attribute set to "true" or "1", then it MUST 
+        /// respond to the client with a remote-connection-failed error as soon as it
+        /// determines that it cannot communicate in a secure way with the server.
+        /// </summary>
+        public bool Secure
+        {
+            get
+            {
+                string s = GetAttr("secure");
+                switch (s)
+                {
+                case "true":
+                    return true;
+                case "1":
+                    return true;
+                default:
+                    return false;
+                }
+            }
+            set
+            {
+                if (value)
+                    SetAttr("secure", "true");
+                else
+                    SetAttr("secure", null);
+            }
+        }
+
+        /// <summary>
+        /// Stream ID
+        /// </summary>
+        public string SID
+        {
+            get { return GetAttr("sid"); }
+            set { SetAttr("sid", value); }
+        }
+        
+        /// <summary>
+        /// If a connection manager supports the multi-streams feature, it MUST 
+        /// include a 'stream' attribute in its Session Creation Response. If a
+        /// client does not receive the 'stream' attribute then it MUST assume 
+        /// that the connection manager does not support the feature. [22]
+        /// 
+        /// The 'stream' attribute identifies the first stream to be opened for 
+        /// the session. The value of each 'stream' attribute MUST be an opaque 
+        /// and unpredictable name that is unique within the context of the 
+        /// connection manager application.
+        /// </summary>
+        public string Stream
+        {
+            get { return GetAttr("stream"); }
+            set { SetAttr("stream", value); }
+        }
+        
+        /// <summary>
+        /// After receiving a request with an 'ack' value less than the 'rid' 
+        /// of the last request that it has already responded to, the connection 
+        /// manager MAY inform the client of the situation by sending its next
+        /// response immediately instead of waiting until it has stanzas to
+        /// send to the client (e.g., if some time has passed since it responded).
+        /// In this case it SHOULD include a 'report' attribute set to one greater
+        /// than the 'ack' attribute it received from the client, and a 'time' 
+        /// attribute set to the number of milliseconds since it sent the response
+        /// associated with the 'report' attribute.
+        /// </summary>
+        public int Time
+        {
+            get { return GetIntAttr("time"); }
+            set { SetIntAttr("time", value); }
+        }
+
+        /// <summary>
+        /// This attribute specifies the target domain of the first stream.
+        /// </summary>
+        public string To
+        {
+            get { return GetAttr("to"); }
+            set { SetAttr("to", value); }
+        }
+
+        /// <summary>
+        /// At any time, the client MAY gracefully terminate the session by sending a <body/> 
+        /// element with a 'type' attribute set to "terminate". The termination request 
+        /// MAY include one or more stanzas that the connection manager MUST forward to 
+        /// the server to ensure graceful logoff.
+        /// </summary>
+        public BodyType Type
+        {
+            get { return GetEnumAttr<BodyType>("type"); }
+            set { SetEnumAttr("type", value); }         
+        }
+        
+        /// <summary>
+        /// This attribute specifies the highest version of the BOSH protocol 
+        /// that the client supports. The numbering scheme is "major.minor" 
+        /// (where the minor number MAY be incremented higher than a single digit, 
+        /// so it MUST be treated as a separate integer). Note: The 'ver' attribute 
+        /// should not be confused with the version of any protocol being transported.
+        /// </summary>
+        public string Ver
+        {
+            get { return GetAttr("ver"); }
+            set { SetAttr("ver", value); }
+        }
+
+        /// <summary>
+        /// This attribute specifies the longest time (in seconds) that the connection
+        /// manager is allowed to wait before responding to any request during the session. 
+        /// This enables the client to limit the delay before it discovers any network failure, 
+        /// and to prevent its HTTP/TCP connection from expiring due to inactivity.
+        /// </summary>
+        public int Wait
+        {
+            get { return GetIntAttr("wait"); }
+            set { SetIntAttr("wait", value); }
+        }
+   }
+}
\ No newline at end of file
diff --git a/lib/jabber-net/jabber/protocol/stream/SASL.cs b/lib/jabber-net/jabber/protocol/stream/SASL.cs
new file mode 100644
index 0000000..1a22713
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/stream/SASL.cs
@@ -0,0 +1,559 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.stream
+{
+    /// <summary>
+    /// SASL mechanisms registered with IANA as of 5/16/2004.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [Flags]
+    public enum MechanismType
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        NONE = 0,
+        /// <summary>
+        /// LIMITED  [RFC2222]   IESG <iesg at ietf.org>
+        /// </summary>
+        KERBEROS_V4 = (1 << 0),
+        /// <summary>
+        /// COMMON   [RFC2222]   IESG <iesg at ietf.org>
+        /// </summary>
+        GSSAPI = (1 << 1),
+        /// <summary>
+        /// OBSOLETE [RFC2444]   IESG <iesg at ietf.org>
+        /// </summary>
+        SKEY  = (1 << 2),
+        /// <summary>
+        /// COMMON   [RFC2222]   IESG <iesg at ietf.org>
+        /// </summary>
+        EXTERNAL = (1 << 3),
+        /// <summary>
+        /// LIMITED  [RFC2195]   IESG <iesg at ietf.org>
+        /// </summary>
+        CRAM_MD5 = (1 << 4),
+        /// <summary>
+        /// COMMON   [RFC2245]   IESG <iesg at ietf.org>
+        /// </summary>
+        ANONYMOUS = (1 << 5),
+        /// <summary>
+        /// COMMON   [RFC2444]   IESG <iesg at ietf.org>
+        /// </summary>
+        OTP = (1 << 6),
+        /// <summary>
+        /// LIMITED  [Leach]     Paul Leach <paulle at microsoft.com>
+        /// </summary>
+        GSS_SPNEGO = (1 << 7),
+        /// <summary>
+        /// COMMON   [RFC2595]   IESG <iesg at ietf.org>
+        /// </summary>
+        PLAIN = (1 << 8),
+        /// <summary>
+        /// COMMON   [RFC2808]   Magnus Nystrom <magnus at rsasecurity.com>
+        /// </summary>
+        SECURID = (1 << 9),
+        /// <summary>
+        /// LIMITED  [Leach]     Paul Leach <paulle at microsoft.com>
+        /// </summary>
+        NTLM = (1 << 10),
+        /// <summary>
+        /// LIMITED  [Gayman]    Mark G. Gayman <mgayman at novell.com>
+        /// </summary>
+        NMAS_LOGIN = (1 << 11),
+        /// <summary>
+        /// LIMITED  [Gayman]    Mark G. Gayman <mgayman at novell.com>
+        /// </summary>
+        NMAS_AUTHEN = (1 << 12),
+        /// <summary>
+        /// COMMON   [RFC2831]   IESG <iesg at ietf.org>
+        /// </summary>
+        DIGEST_MD5 = (1 << 13),
+        /// <summary>
+        /// [RFC3163]  robert.zuccherato at entrust.com
+        /// </summary>
+        ISO_9798_U_RSA_SHA1_ENC = (1 << 14),
+        /// <summary>
+        /// COMMON   [RFC3163]   robert.zuccherato at entrust.com
+        /// </summary>
+        ISO_9798_M_RSA_SHA1_ENC = (1 << 15),
+        /// <summary>
+        /// COMMON   [RFC3163]   robert.zuccherato at entrust.com
+        /// </summary>
+        ISO_9798_U_DSA_SHA1 = (1 << 16),
+        /// <summary>
+        /// COMMON   [RFC3163]   robert.zuccherato at entrust.com
+        /// </summary>
+        ISO_9798_M_DSA_SHA1 = (1 << 17),
+        /// <summary>
+        /// COMMON   [RFC3163]   robert.zuccherato at entrust.com
+        /// </summary>
+        ISO_9798_U_ECDSA_SHA1 = (1 << 18),
+        /// <summary>
+        /// COMMON   [RFC3163]   robert.zuccherato at entrust.com
+        /// </summary>
+        ISO_9798_M_ECDSA_SHA1 = (1 << 19),
+        /// <summary>
+        /// COMMON   [Josefsson] Simon Josefsson <simon at josefsson.org>
+        /// </summary>
+        KERBEROS_V5 = (1 << 20),
+        /// <summary>
+        /// LIMITED  [Brimhall]  Vince Brimhall <vbrimhall at novell.com>
+        /// </summary>
+        NMAS_SAMBA_AUTH = (1 << 21)
+    }
+
+    /// <summary>
+    /// SASL mechanisms in stream features.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Mechanisms : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Mechanisms(XmlDocument doc) :
+            base("", new XmlQualifiedName("mechanisms", jabber.protocol.URI.SASL), doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Mechanisms(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The SASL mechanisms valid for this stream.
+        /// </summary>
+        /// <returns></returns>
+        public Mechanism[] GetMechanisms()
+        {
+            XmlNodeList nl = GetElementsByTagName("mechanism", URI.SASL);
+            Mechanism[] items = new Mechanism[nl.Count];
+            int i=0;
+            foreach (XmlNode n in nl)
+            {
+                items[i] = (Mechanism) n;
+                i++;
+            }
+            return items;
+        }
+
+        /// <summary>
+        /// A bitmap of all of the implemented types.
+        /// </summary>
+        public MechanismType Types
+        {
+            get
+            {
+                MechanismType ret = MechanismType.NONE;
+                foreach (Mechanism m in GetMechanisms())
+                {
+                    ret |= m.MechanismType;
+                }
+                return ret;
+            }
+        }
+    }
+
+    /// <summary>
+    /// Stores SASL mechanisms in stream features.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Mechanism : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Mechanism(XmlDocument doc) :
+            base("", new XmlQualifiedName("mechanism", jabber.protocol.URI.SASL), doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Mechanism(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The IANA-registered SASL mechanism name.
+        /// </summary>
+        public string MechanismName
+        {
+            get { return this.InnerText; }
+            set { this.InnerText = value; }
+        }
+
+        /// <summary>
+        /// SASL mechanism, as an enum
+        /// </summary>
+        public MechanismType MechanismType
+        {
+            get { return GetMechanismType(MechanismName); }
+            set { MechanismName = GetMechanism(value); }
+        }
+
+        /// <summary>
+        /// The SASL mechanism, as an enum.
+        /// </summary>
+        public static MechanismType GetMechanismType(string name)
+        {
+            switch (name)
+            {
+                case "KERBEROS_V4":
+                    return MechanismType.KERBEROS_V4;
+                case "GSSAPI":
+                    return MechanismType.GSSAPI;
+                case "SKEY":
+                    return MechanismType.SKEY;
+                case "EXTERNAL":
+                    return MechanismType.EXTERNAL;
+                case "CRAM-MD5":
+                    return MechanismType.CRAM_MD5;
+                case "ANONYMOUS":
+                    return MechanismType.ANONYMOUS;
+                case "OTP":
+                    return MechanismType.OTP;
+                case "GSS-SPNEGO":
+                    return MechanismType.GSS_SPNEGO;
+                case "PLAIN":
+                    return MechanismType.PLAIN;
+                case "SECURID":
+                    return MechanismType.SECURID;
+                case "NTLM":
+                    return MechanismType.NTLM;
+                case "NMAS_LOGIN":
+                    return MechanismType.NMAS_LOGIN;
+                case "NMAS_AUTHEN":
+                    return MechanismType.NMAS_AUTHEN;
+                case "DIGEST-MD5":
+                    return MechanismType.DIGEST_MD5;
+                case "9798-U-RSA-SHA1-ENC":
+                    return MechanismType.ISO_9798_U_RSA_SHA1_ENC;
+                case "9798-M-RSA-SHA1-ENC":
+                    return MechanismType.ISO_9798_M_RSA_SHA1_ENC;
+                case "9798-U-DSA-SHA1":
+                    return MechanismType.ISO_9798_U_DSA_SHA1;
+                case "9798-M-DSA-SHA1":
+                    return MechanismType.ISO_9798_M_DSA_SHA1;
+                case "9798-U-ECDSA-SHA1":
+                    return MechanismType.ISO_9798_U_ECDSA_SHA1;
+                case "9798-M-ECDSA-SHA1":
+                    return MechanismType.ISO_9798_M_ECDSA_SHA1;
+                case "KERBEROS_V5":
+                    return MechanismType.KERBEROS_V5;
+                case "NMAS-SAMBA-AUTH":
+                    return MechanismType.NMAS_SAMBA_AUTH;
+                default:
+                    return MechanismType.NONE;
+            }
+        }
+
+        /// <summary>
+        /// The SASL mechanism, as a string.
+        /// </summary>
+        public static string GetMechanism(MechanismType type)
+        {
+            switch (type)
+            {
+                case MechanismType.KERBEROS_V4:
+                    return "KERBEROS_V4";
+                case MechanismType.GSSAPI:
+                    return "GSSAPI";
+                case MechanismType.SKEY:
+                    return "SKEY";
+                case MechanismType.EXTERNAL:
+                    return "EXTERNAL";
+                case MechanismType.CRAM_MD5:
+                    return "CRAM-MD5";
+                case MechanismType.ANONYMOUS:
+                    return "ANONYMOUS";
+                case MechanismType.OTP:
+                    return "OTP";
+                case MechanismType.GSS_SPNEGO:
+                    return "GSS-SPNEGO";
+                case MechanismType.PLAIN:
+                    return "PLAIN";
+                case MechanismType.SECURID:
+                    return "SECURID";
+                case MechanismType.NTLM:
+                    return "NTLM";
+                case MechanismType.NMAS_LOGIN:
+                    return "NMAS_LOGIN";
+                case MechanismType.NMAS_AUTHEN:
+                    return "NMAS_AUTHEN";
+                case MechanismType.DIGEST_MD5:
+                    return "DIGEST-MD5";
+                case MechanismType.ISO_9798_U_RSA_SHA1_ENC:
+                    return "9798-U-RSA-SHA1-ENC";
+                case MechanismType.ISO_9798_M_RSA_SHA1_ENC:
+                    return "9798-M-RSA-SHA1-ENC";
+                case MechanismType.ISO_9798_U_DSA_SHA1:
+                    return "9798-U-DSA-SHA1";
+                case MechanismType.ISO_9798_M_DSA_SHA1:
+                    return "9798-M-DSA-SHA1";
+                case MechanismType.ISO_9798_U_ECDSA_SHA1:
+                    return "9798-U-ECDSA-SHA1";
+                case MechanismType.ISO_9798_M_ECDSA_SHA1:
+                    return "9798-M-ECDSA-SHA1";
+                case MechanismType.KERBEROS_V5:
+                    return "KERBEROS_V5";
+                case MechanismType.NMAS_SAMBA_AUTH:
+                    return "NMAS-SAMBA-AUTH";
+                default:
+                    return null;
+            }
+        }
+    }
+
+    /// <summary>
+    /// Auth, Challenge, and Response.
+    /// </summary>
+    public abstract class Step : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Step(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The innards of the step.  If it is "=", it
+        /// means an intentionally blank response, not one waiting for a challenge.
+        /// </summary>
+        public byte[] Bytes
+        {
+            get
+            {
+                string it = this.InnerText;
+                if (it == "")
+                    return null;
+                if (it == "=")
+                    return new byte[0];
+                return Convert.FromBase64String(it);
+            }
+            set
+            {
+                if (value == null)
+                    this.InnerText = "";
+                else if (value.Length == 0)
+                    this.InnerText = "=";
+                else
+                    this.InnerText = Convert.ToBase64String(value);
+            }
+        }
+    }
+
+    /// <summary>
+    /// First phase of SASL auth.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Auth : Step
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Auth(XmlDocument doc) :
+            base("", new XmlQualifiedName("auth", jabber.protocol.URI.SASL), doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Auth(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The chosen mechanism
+        /// </summary>
+        public MechanismType Mechanism
+        {
+            get
+            {
+                string m = GetAttribute("mechanism");
+                return jabber.protocol.stream.Mechanism.GetMechanismType(m);
+            }
+            set
+            {
+                string m = jabber.protocol.stream.Mechanism.GetMechanism(value);
+                SetAttribute("mechanism", m);
+            }
+        }
+    }
+    /// <summary>
+    /// Subsequent phases of SASL auth sent by server.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Challenge : Step
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Challenge(XmlDocument doc) :
+            base("", new XmlQualifiedName("challenge", jabber.protocol.URI.SASL), doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Challenge(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// First phase of SASL auth.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Response : Step
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Response(XmlDocument doc) :
+            base("", new XmlQualifiedName("response", jabber.protocol.URI.SASL), doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Response(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// SASL auth failed.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class SASLFailure : Step
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public SASLFailure(XmlDocument doc) :
+            base("", new XmlQualifiedName("failure", jabber.protocol.URI.SASL), doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public SASLFailure(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Abort SASL auth.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Abort : Step
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Abort(XmlDocument doc) :
+            base("", new XmlQualifiedName("abort", jabber.protocol.URI.SASL), doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Abort(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// SASL auth successfult.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Success : Step
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Success(XmlDocument doc) :
+            base("", new XmlQualifiedName("success", jabber.protocol.URI.SASL), doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Success(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/stream/Session.cs b/lib/jabber-net/jabber/protocol/stream/Session.cs
new file mode 100644
index 0000000..740f43c
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/stream/Session.cs
@@ -0,0 +1,47 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.stream
+{
+    /// <summary>
+    /// Session start after binding
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Session : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Session(XmlDocument doc) :
+            base("", new XmlQualifiedName("session", jabber.protocol.URI.SESSION), doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Session(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/stream/StartTLS.cs b/lib/jabber-net/jabber/protocol/stream/StartTLS.cs
new file mode 100644
index 0000000..e5dc860
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/stream/StartTLS.cs
@@ -0,0 +1,127 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.stream
+{
+    /// <summary>
+    /// Start-TLS in stream features.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class StartTLS : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public StartTLS(XmlDocument doc) :
+            base("", new XmlQualifiedName("starttls", jabber.protocol.URI.START_TLS), doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public StartTLS(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Is starttls required?
+        /// </summary>
+        public bool Required
+        {
+            get { return this["required"] != null; }
+            set
+            {
+                if (value)
+                {
+                    if (this["required"] == null)
+                    {
+                        SetElem("required", null);
+                    }
+                }
+                else
+                {
+                    if (this["required"] != null)
+                    {
+                        RemoveElem("required");
+                    }
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    /// Start-TLS proceed.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Proceed : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Proceed(XmlDocument doc) :
+            base("", new XmlQualifiedName("proceed", jabber.protocol.URI.START_TLS), doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Proceed(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Start-TLS failure.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class TLSFailure : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="xmlns"></param>
+        public TLSFailure(XmlDocument doc, string xmlns) :
+            base("", new XmlQualifiedName("failure", jabber.protocol.URI.START_TLS), doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public TLSFailure(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/stream/Stream.cs b/lib/jabber-net/jabber/protocol/stream/Stream.cs
new file mode 100644
index 0000000..bdd2823
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/stream/Stream.cs
@@ -0,0 +1,82 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Security.Cryptography;
+using System.Xml;
+using bedrock.util;
+using jabber.protocol;
+
+namespace jabber.protocol.stream
+{
+    /// <summary>
+    /// The fabled stream:stream packet.  Id's get assigned automatically on allocation.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Stream : Packet
+    {
+        private static readonly RandomNumberGenerator RNG = RandomNumberGenerator.Create();
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="xmlns"></param>
+        public Stream(XmlDocument doc, string xmlns) :
+            base("stream", new XmlQualifiedName("stream", jabber.protocol.URI.STREAM), doc)
+        {
+            byte[] buf = new byte[4];
+            RNG.GetBytes(buf);
+            ID = HexString(buf);
+            NS = xmlns;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Stream(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Default stream namespace.  xmlns=''.
+        /// </summary>
+        public string NS
+        {
+            get { return this.GetAttribute("xmlns"); }
+            set { this.SetAttribute("xmlns", value); }
+        }
+
+        /// <summary>
+        /// The version attribute.  "1.0" for an XMPP-core-compliant stream.
+        /// </summary>
+        public string Version
+        {
+            get { return this.GetAttribute("version"); }
+            set { this.SetAttribute("version", value); }
+        }
+
+        /// <summary>
+        /// Make sure that the namespace from this stream gets output.
+        /// </summary>
+        public override string OuterXml
+        {
+            get { return this.OriginalOuterXml; }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/x/Caps.cs b/lib/jabber-net/jabber/protocol/x/Caps.cs
new file mode 100644
index 0000000..d7aa7c5
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/x/Caps.cs
@@ -0,0 +1,125 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Xml;
+
+using bedrock.util;
+
+
+namespace jabber.protocol.x
+{
+    /// <summary>
+    /// Entity Capabilities.  See http://www.xmpp.org/extensions/xep-0115.html.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Caps : Element
+    {
+        private static readonly char[] SPLIT = " ".ToCharArray();
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Caps(XmlDocument doc)
+            : base("c", URI.CAPS, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Caps(string prefix, XmlQualifiedName qname, XmlDocument doc)
+            : base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The URI that describes the entity.
+        /// </summary>
+        public string Node
+        {
+            get { return GetAttr("node"); }
+            set { SetAttr("node", value); }
+        }
+
+        /// <summary>
+        /// The version of the entity.
+        /// </summary>
+        public string Version
+        {
+            get { return GetAttr("ver"); }
+            set { SetAttr("ver", value); }
+        }
+
+        /// <summary>
+        /// The hash type being used, or null for pre-v1.5 of XEP-115.
+        /// </summary>
+        public string Hash
+        {
+            get { return GetAttr("hash"); }
+            set { SetAttr("hash", value); }
+        }
+
+        /// <summary>
+        /// Is this a new-style (post v1.5) caps?
+        /// </summary>
+        public bool NewStyle
+        {
+            get { return HasAttribute("hash"); }
+        }
+
+        /// <summary>
+        /// The extensions currently on in the entity.
+        /// </summary>
+        [Obsolete]
+        public string[] Extensions
+        {
+            get { return GetAttr("ext").Split(SPLIT); }
+            set
+            {
+                if (value.Length == 0)
+                {
+                    if (this.HasAttribute("ext"))
+                        RemoveAttribute("ext");
+                }
+                else
+                    SetAttr("ext", string.Join(" ", value));
+            }
+        }
+
+        /// <summary>
+        /// All of the combinations of node#ver, node#ext.
+        /// </summary>
+        [Obsolete]
+        public string[] DiscoInfoNodes
+        {
+            get
+            {
+                string[] exts = Extensions;
+                string[] nodes = new string[exts.Length + 1];
+                int count = 0;
+                nodes[count] = Node + "#" + Version;
+                foreach (string ext in exts)
+                {
+                    nodes[++count] = Node + "#" + ext;
+                }
+
+                return nodes;
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/x/Data.cs b/lib/jabber-net/jabber/protocol/x/Data.cs
new file mode 100644
index 0000000..d96d384
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/x/Data.cs
@@ -0,0 +1,640 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.x
+{
+    /// <summary>
+    /// XData types.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum XDataType
+    {
+        /// <summary>
+        /// This packet contains a form to fill out. Display it to the user (if your program can).
+        /// </summary>
+        form,
+        /// <summary>
+        /// The form is filled out, and this is the data that is being returned from the form.
+        /// </summary>
+        submit,
+        /// <summary>
+        /// Data results being returned from a search, or some other query.
+        /// </summary>
+        result,
+        /// <summary>
+        /// A form was cancelled.
+        /// </summary>
+        cancel
+    }
+
+    /// <summary>
+    /// Compare two x:data forms by form type.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class FormTypeComparer : System.Collections.Generic.Comparer<Data>
+    {
+        /// <summary>
+        /// Compare two x:data forms by form type
+        /// </summary>
+        /// <param name="x"></param>
+        /// <param name="y"></param>
+        /// <returns></returns>
+        public override int Compare(Data x, Data y)
+        {
+            return string.Compare(x.FormType, y.FormType);
+        }
+    }
+
+    /// <summary>
+    /// jabber:x:data support, as in http://www.xmpp.org/extensions/xep-0004.html.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Data : Element
+    {
+        /// <summary>
+        /// XEP-68 field that describes the type of the form.
+        /// </summary>
+        public const string FORM_TYPE = "FORM_TYPE";
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Data(XmlDocument doc) : base("x", URI.XDATA, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Data(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+
+        /// <summary>
+        /// Form instructions.
+        /// </summary>
+        public string Instructions
+        {
+            get { return GetElem("instructions"); }
+            set { SetElem("instructions", value); }
+        }
+
+        /// <summary>
+        /// The form title, for display at the top of a window.
+        /// </summary>
+        public string Title
+        {
+            get { return GetElem("title"); }
+            set { SetElem("title", value); }
+        }
+
+        /// <summary>
+        /// Type of this XData.
+        /// </summary>
+        public XDataType Type
+        {
+            get { return (XDataType)GetEnumAttr("type", typeof(XDataType)); }
+            set { SetAttribute("type", value.ToString());}
+        }
+
+        /// <summary>
+        /// List of form fields
+        /// </summary>
+        /// <returns></returns>
+        public Field[] GetFields()
+        {
+            XmlNodeList nl = GetElementsByTagName("field", URI.XDATA);
+            Field[] fields = new Field[nl.Count];
+            int i=0;
+            foreach (XmlNode n in nl)
+            {
+                fields[i] = (Field) n;
+                i++;
+            }
+            return fields;
+        }
+
+        /// <summary>
+        /// Add a form field
+        /// </summary>
+        /// <returns></returns>
+        public Field AddField()
+        {
+            Field f = new Field(this.OwnerDocument);
+            AddChild(f);
+            return f;
+        }
+
+        /// <summary>
+        /// Add a form field, with just the field name.
+        /// </summary>
+        /// <param name="var">Variable name</param>
+        /// <returns></returns>
+        public Field AddField(string var)
+        {
+            Field f = new Field(this.OwnerDocument);
+            if (var != null)
+                f.Var = var;
+            AddChild(f);
+            return f;
+        }
+
+        /// <summary>
+        /// Add a form field
+        /// </summary>
+        /// <param name="var">Variable name</param>
+        /// <param name="typ">Field Type</param>
+        /// <param name="label">Field label</param>
+        /// <param name="val">Field value</param>
+        /// <param name="desc">Description</param>
+        /// <returns></returns>
+        public Field AddField(string var, FieldType typ, string label, string val, string desc)
+        {
+            Field f = new Field(this.OwnerDocument);
+            if (var != null)
+                f.Var = var;
+            if (label != null)
+                f.Label = label;
+            f.Type = typ;
+            if (val != null)
+                f.Val = val;
+            if (desc != null)
+                f.Desc = desc;
+
+            AddChild(f);
+            return f;
+        }
+
+        /// <summary>
+        /// Get a field with the specified variable name.
+        /// </summary>
+        /// <param name="var"></param>
+        /// <returns></returns>
+        public Field GetField(string var)
+        {
+            XmlNodeList nl = GetElementsByTagName("field", URI.XDATA);
+            foreach (XmlNode n in nl)
+            {
+                Field f = (Field) n;
+                if (f.Var == var)
+                    return f;
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// Remove the first field with the var specified
+        /// </summary>
+        /// <param name="var"></param>
+        /// <returns></returns>
+        public Field RemoveField(string var)
+        {
+            XmlNodeList nl = GetElementsByTagName("field", URI.XDATA);
+            foreach (XmlNode n in nl)
+            {
+                Field f = (Field)n;
+                if (f.Var == var)
+                    return (Field)this.RemoveChild(f);
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// The XEP-68 type of this form.
+        /// </summary>
+        public string FormType
+        {
+            get 
+            {
+                Field f = GetField(FORM_TYPE);
+                if (f == null)
+                    return null;
+                return f.Val;
+            }
+            set
+            {
+                if (value == null)
+                {
+                    RemoveField(FORM_TYPE);
+                    return;
+                }
+                Field f = GetField(FORM_TYPE);
+                if (f == null)
+                    f = this.AddField(FORM_TYPE, FieldType.hidden, null, value, null);
+                else
+                    f.Val = value;
+            }
+        }
+    }
+
+    /// <summary>
+    /// Types of fields.  This enum doesn't exactly match the XEP,
+    /// since most of the field types aren't valid identifiers in C#.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum FieldType
+    {
+        /// <summary>
+        /// Single-line text, and default.
+        /// </summary>
+        text_single,
+        /// <summary>
+        /// Password-style single line text.  Text obscured by *'s.
+        /// </summary>
+        text_private,
+        /// <summary>
+        /// Multi-line text
+        /// </summary>
+        text_multi,
+        /// <summary>
+        /// Multi-select list
+        /// </summary>
+        list_multi,
+        /// <summary>
+        /// Single-select list
+        /// </summary>
+        list_single,
+        /// <summary>
+        /// Checkbox
+        /// </summary>
+        boolean,
+        /// <summary>
+        /// Fixed text.
+        /// </summary>
+        Fixed,
+        /// <summary>
+        /// Hidden field.  Value is returned to sender as sent.
+        /// </summary>
+        hidden,
+        /// <summary>
+        /// Jabber ID.
+        /// </summary>
+        jid_single,
+        /// <summary>
+        /// A list of jabber ID's.
+        /// </summary>
+        jid_multi
+    }
+
+    /// <summary>
+    /// Form field.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Field : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Field(XmlDocument doc) : base("field", URI.XDATA, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Field(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Field type.
+        /// </summary>
+        public FieldType Type
+        {
+            get
+            {
+                switch (GetAttribute("type"))
+                {
+                    case "text-single":
+                        return FieldType.text_single;
+                    case "text-private":
+                        return FieldType.text_private;
+                    case "text-multi":
+                        return FieldType.text_multi;
+                    case "list-multi":
+                        return FieldType.list_multi;
+                    case "list-single":
+                        return FieldType.list_single;
+                    case "boolean":
+                        return FieldType.boolean;
+                    case "fixed":
+                        return FieldType.Fixed;
+                    case "hidden":
+                        return FieldType.hidden;
+                    case "jid-single":
+                        return FieldType.jid_single;
+                    case "jid-multi":
+                        return FieldType.jid_multi;
+                    default:
+                        throw new ArgumentException("Unknown x:data field type: " + GetAttribute("type"));
+                }
+            }
+            set
+            {
+                switch (value)
+                {
+                    case FieldType.text_single:
+                        SetAttribute("type", "text-single");
+                        break;
+                    case FieldType.text_private:
+                        SetAttribute("type", "text-private");
+                        break;
+                    case FieldType.text_multi:
+                        SetAttribute("type", "text-multi");
+                        break;
+                    case FieldType.list_multi:
+                        SetAttribute("type", "list-multi");
+                        break;
+                    case FieldType.list_single:
+                        SetAttribute("type", "list-single");
+                        break;
+                    case FieldType.boolean:
+                        SetAttribute("type", "boolean");
+                        break;
+                    case FieldType.Fixed:
+                        SetAttribute("type", "fixed");
+                        break;
+                    case FieldType.hidden:
+                        SetAttribute("type", "hidden");
+                        break;
+                    case FieldType.jid_single:
+                        SetAttribute("type", "jid-single");
+                        break;
+                    case FieldType.jid_multi:
+                        SetAttribute("type", "jid-multi");
+                        break;
+                    default:
+                        throw new ArgumentException("Unknown x:data field type: " + value);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Field label.  Will return Var if no label is found.
+        /// </summary>
+        public string Label
+        {
+            get
+            {
+                string lbl = GetAttribute("label");
+                if (lbl == null)
+                    lbl = Var;
+                return lbl;
+            }
+            set { SetAttribute("label", value); }
+        }
+
+        /// <summary>
+        /// Field variable name.
+        /// </summary>
+        public string Var
+        {
+            get { return GetAttribute("var"); }
+            set { SetAttribute("var", value); }
+        }
+
+        /// <summary>
+        /// Is this a required field?
+        /// </summary>
+        public bool IsRequired
+        {
+            get { return this["required"] != null; }
+            set
+            {
+                if (value)
+                    this.SetElem("required", null);
+                else
+                    this.RemoveElem("required");
+            }
+        }
+
+        /// <summary>
+        /// The field value.
+        /// </summary>
+        public string Val
+        {
+            get { return GetElem("value"); }
+            set { SetElem("value", value); }
+        }
+
+        /// <summary>
+        /// Value for type='boolean' fields
+        /// </summary>
+        public bool BoolVal
+        {
+            get
+            {
+                string sval = Val;
+                return !((sval == null) || (sval == "0"));
+            }
+            set
+            {
+                Val = value ? "1" : "0";
+            }
+        }
+
+        /// <summary>
+        /// Values for type='list-multi' fields
+        /// </summary>
+        public string[] Vals
+        {
+            get
+            {
+                XmlNodeList nl = GetElementsByTagName("value", URI.XDATA);
+                string[] results = new string[nl.Count];
+                int i=0;
+                foreach (XmlElement el in nl)
+                {
+                    results[i++] = el.InnerText;
+                }
+                return results;
+            }
+            set
+            {
+                RemoveElems("value", URI.XDATA);
+                foreach (string s in value)
+                {
+                    XmlElement val = this.OwnerDocument.CreateElement("value", URI.XDATA);
+                    val.InnerText = s;
+                    this.AppendChild(val);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Is the given value in Vals?
+        /// </summary>
+        /// <param name="val"></param>
+        /// <returns></returns>
+        public bool IsValSet(string val)
+        {
+            XmlNodeList nl = GetElementsByTagName("value", URI.XDATA);
+            foreach (XmlElement el in nl)
+            {
+                if (el.InnerText == val)
+                    return true;
+            }
+            return false;
+        }
+
+        /// <summary>
+        /// Add a value to a multi-value field.
+        /// </summary>
+        /// <param name="newvalue"></param>
+        public void AddValue(string newvalue)
+        {
+            XmlElement val = this.OwnerDocument.CreateElement("value", URI.XDATA);
+            val.InnerText = newvalue;
+            this.AppendChild(val);
+        }
+
+        /// <summary>
+        /// The field description
+        /// </summary>
+        public string Desc
+        {
+            get { return GetElem("desc"); }
+            set { SetElem("desc", value); }
+        }
+
+        /// <summary>
+        /// List of field options
+        /// </summary>
+        /// <returns></returns>
+        public Option[] GetOptions()
+        {
+            XmlNodeList nl = GetElementsByTagName("option", URI.XDATA);
+            Option[] options = new Option[nl.Count];
+            int i=0;
+            foreach (XmlNode n in nl)
+            {
+                options[i] = (Option) n;
+                i++;
+            }
+            return options;
+        }
+
+        /// <summary>
+        /// Add a field option
+        /// </summary>
+        /// <returns></returns>
+        public Option AddOption()
+        {
+            Option o = new Option(this.OwnerDocument);
+            AddChild(o);
+            return o;
+        }
+
+        /// <summary>
+        /// Add a field option, with a value
+        /// </summary>
+        /// <param name="val">Value of the option</param>
+        /// <returns></returns>
+        public Option AddOption(String val)
+        {
+            Option o = new Option(this.OwnerDocument);
+            AddChild(o);
+            o.Val = val;
+            return o;
+        }
+
+        /// <summary>
+        /// Add a field option, with a value
+        /// </summary>
+        /// <param name="label">Label for the option</param>
+        /// <param name="val">Value of the option</param>
+        /// <returns></returns>
+        public Option AddOption(String label, String val)
+        {
+            Option o = new Option(this.OwnerDocument);
+            AddChild(o);
+            o.Val = val;
+            o.Label = label;
+            return o;
+        }
+    }
+
+    /// <summary>
+    /// Field options, for list-single and list-multi type fields.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Option : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Option(XmlDocument doc) : base("option", URI.XDATA, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Option(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// Option label
+        /// </summary>
+        public string Label
+        {
+            get { return GetAttribute("label"); }
+            set { SetAttribute("label", value); }
+        }
+
+        /// <summary>
+        /// The option value.
+        /// </summary>
+        public string Val
+        {
+            get { return GetElem("value"); }
+            set { SetElem("value", value); }
+        }
+
+        /// <summary>
+        /// Return the label for this option, so that a ComboBox.ObjectCollection can manage these directly.
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            string l = Label;
+            if (l != "")
+                return l;
+            return Val;
+        }
+
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/x/Delay.cs b/lib/jabber-net/jabber/protocol/x/Delay.cs
new file mode 100644
index 0000000..aa4c437
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/x/Delay.cs
@@ -0,0 +1,134 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.x
+{
+    /// <summary>
+    /// A delay x element.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Delay : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Delay(XmlDocument doc) : base("x", URI.XDELAY, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Delay(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// From whom?
+        /// </summary>
+        public string From
+        {
+            get { return GetAttribute("from"); }
+            set { SetAttribute("from", value); }
+        }
+
+        /// <summary>
+        /// Date/time stamp.
+        /// </summary>
+        public DateTime Stamp
+        {
+            get { return JabberDate(GetAttribute("stamp")); }
+            set { SetAttribute("stamp", JabberDate(value)); }
+        }
+
+        /// <summary>
+        /// Description
+        /// </summary>
+        public string Desc
+        {
+            get { return this.InnerText; }
+            set { this.InnerText = value; }
+        }
+    }
+
+    /// <summary>
+    /// A modern, XEP-0203 delay element
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ModernDelay : Element
+    {
+/*
+ <delay xmlns='urn:xmpp:delay'
+     from='capulet.com'
+     stamp='2002-09-10T23:08:25Z'>
+    Offline Storage
+  </delay>
+*/
+        /// <summary>
+        ///Create a delay element for sending
+        /// </summary>
+        /// <param name="doc"></param>
+        public ModernDelay(XmlDocument doc) : base("delay", URI.DELAY, doc)
+        {
+        }
+
+        /// <summary>
+        /// Create a delay element from the received stream.
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public ModernDelay(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// From whom?
+        /// </summary>
+        public string From
+        {
+            get { return GetAttribute("from"); }
+            set { SetAttribute("from", value); }
+        }
+
+        /// <summary>
+        /// Date/time stamp.
+        /// </summary>
+        public DateTime Stamp
+        {
+            get { return Element.DateTimeProfile(GetAttribute("stamp")); }
+            set { SetAttribute("stamp", Element.DateTimeProfile(value)); }
+        }
+
+        /// <summary>
+        /// Description
+        /// </summary>
+        public string Desc
+        {
+            get { return this.InnerText; }
+            set { this.InnerText = value; }
+        } 
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/x/Event.cs b/lib/jabber-net/jabber/protocol/x/Event.cs
new file mode 100644
index 0000000..153f2cc
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/x/Event.cs
@@ -0,0 +1,183 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+
+using bedrock.util;
+
+namespace jabber.protocol.x
+{
+    /// <summary>
+    /// Types of events
+    /// </summary>
+    [Flags]
+    [SVN(@"$Id$")]
+    public enum EventType
+    {
+        /// <summary>
+        /// No event type specified.
+        /// </summary>
+        NONE = 0,
+        /// <summary>
+        /// Indicates that the message has been stored offline by the server, because the
+        /// intended recipient is not available. This event is to be raised by the Jabber server.
+        /// </summary>
+        offline = 1,
+        /// <summary>
+        /// Indicates that the message has been delivered to the recipient. This signifies
+        /// that the message has reached the Jabber client, but does not necessarily mean
+        /// that the message has been displayed. This event is to be raised by the Jabber client.
+        /// </summary>
+        delivered = 2,
+        /// <summary>
+        /// Once the message has been received by the Jabber client, it may be displayed
+        /// to the user. This event indicates that the message has been displayed, and is
+        /// to be raised by the Jabber client. Even if a message is displayed multiple times,
+        /// this event should only be raised once.
+        /// </summary>
+        displayed = 4,
+        /// <summary>
+        /// In threaded chat conversations, this indicates that the recipient is composing
+        /// a reply to a message that was just sent. The event is to be raised by the Jabber
+        /// client. A Jabber client is allowed to raise this event multiple times in response
+        /// to the same request, providing that a specific sequence is followed.
+        /// </summary>
+        composing = 8
+    }
+
+    /// <summary>
+    /// A event x element, described by XEP-0022.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Event : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public Event(XmlDocument doc) : base("x", URI.XEVENT, doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public Event(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+            base(prefix, qname, doc)
+        {
+        }
+
+        /// <summary>
+        /// The message to which this event refers.
+        /// </summary>
+        public string ID
+        {
+            get { return GetElem("id"); }
+            set { SetElem("id", value); }
+        }
+
+        /// <summary>
+        /// The type of the event.
+        /// </summary>
+        public EventType Type
+        {
+            get
+            {
+                EventType res = EventType.NONE;
+                if (IsOffline) res |= EventType.offline;
+                if (IsDelivered) res |= EventType.delivered;
+                if (IsDisplayed) res |= EventType.displayed;
+                if (IsComposing) res |= EventType.composing;
+                return res;
+            }
+            set
+            {
+                IsOffline = ((value & EventType.offline) == EventType.offline);
+                IsDelivered = ((value & EventType.delivered) == EventType.delivered);
+                IsDisplayed = ((value & EventType.displayed) == EventType.displayed);
+                IsComposing = ((value & EventType.composing) == EventType.composing);
+            }
+        }
+
+        /// <summary>
+        /// Indicates that the message has been stored offline by the server, because the
+        /// intended recipient is not available. This event is to be raised by the Jabber server.
+        /// </summary>
+        public bool IsOffline
+        {
+            get { return this["offline"] != null; }
+            set
+            {
+                if (value)
+                    this.SetElem("offline", null);
+                else
+                    this.RemoveElem("offline");
+            }
+        }
+        /// <summary>
+        /// Indicates that the message has been delivered to the recipient. This signifies
+        /// that the message has reached the Jabber client, but does not necessarily mean
+        /// that the message has been displayed. This event is to be raised by the Jabber client.
+        /// </summary>
+        public bool IsDelivered
+        {
+            get { return this["delivered"] != null; }
+            set
+            {
+                if (value)
+                    this.SetElem("delivered", null);
+                else
+                    this.RemoveElem("delivered");
+            }
+        }
+        /// <summary>
+        /// Once the message has been received by the Jabber client, it may be displayed
+        /// to the user. This event indicates that the message has been displayed, and is
+        /// to be raised by the Jabber client. Even if a message is displayed multiple times,
+        /// this event should only be raised once.
+        /// </summary>
+        public bool IsDisplayed
+        {
+            get { return this["displayed"] != null; }
+            set
+            {
+                if (value)
+                    this.SetElem("displayed", null);
+                else
+                    this.RemoveElem("displayed");
+            }
+        }
+        /// <summary>
+        /// In threaded chat conversations, this indicates that the recipient is composing
+        /// a reply to a message that was just sent. The event is to be raised by the Jabber
+        /// client. A Jabber client is allowed to raise this event multiple times in response
+        /// to the same request, providing that a specific sequence is followed.
+        /// </summary>
+        public bool IsComposing
+        {
+            get { return this["composing"] != null; }
+            set
+            {
+                if (value)
+                    this.SetElem("composing", null);
+                else
+                    this.RemoveElem("composing");
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/jabber/protocol/x/Factory.cs b/lib/jabber-net/jabber/protocol/x/Factory.cs
new file mode 100644
index 0000000..779af59
--- /dev/null
+++ b/lib/jabber-net/jabber/protocol/x/Factory.cs
@@ -0,0 +1,45 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+
+using bedrock.util;
+using jabber.protocol;
+
+namespace jabber.protocol.x
+{
+    /// <summary>
+    /// ElementFactory for all currently supported IQ namespaces.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Factory : IPacketTypes
+    {
+        private static QnameType[] s_qnt = new QnameType[]
+        {
+                    new QnameType("x",     URI.XDELAY,    typeof(jabber.protocol.x.Delay)),
+                    new QnameType("x",     URI.XEVENT,    typeof(jabber.protocol.x.Event)),
+                    new QnameType("x",     URI.XOOB,      typeof(jabber.protocol.iq.OOB)),
+                    new QnameType("x",     URI.XROSTER,   typeof(jabber.protocol.iq.Roster)),
+                    new QnameType("item",  URI.XROSTER,   typeof(jabber.protocol.iq.Item)),
+                    new QnameType("group", URI.XROSTER,   typeof(jabber.protocol.iq.Group)),
+
+                    new QnameType("x",     URI.XDATA,     typeof(jabber.protocol.x.Data)),
+                    new QnameType("field", URI.XDATA,     typeof(jabber.protocol.x.Field)),
+                    new QnameType("option",URI.XDATA,     typeof(jabber.protocol.x.Option)),
+
+                    new QnameType("c",     URI.CAPS,      typeof(jabber.protocol.x.Caps)),
+        };
+        QnameType[] IPacketTypes.Types { get { return s_qnt; } }
+    }
+}
diff --git a/lib/jabber-net/jabber/server/JabberService.bmp b/lib/jabber-net/jabber/server/JabberService.bmp
new file mode 100644
index 0000000..39e44ba
Binary files /dev/null and b/lib/jabber-net/jabber/server/JabberService.bmp differ
diff --git a/lib/jabber-net/jabber/server/JabberService.cs b/lib/jabber-net/jabber/server/JabberService.cs
new file mode 100644
index 0000000..45bdda6
--- /dev/null
+++ b/lib/jabber-net/jabber/server/JabberService.cs
@@ -0,0 +1,466 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Threading;
+using System.Xml;
+
+using bedrock.net;
+using bedrock.util;
+
+using jabber.connection;
+using jabber.protocol;
+using jabber.protocol.accept;
+using jabber.protocol.stream;
+
+namespace jabber.server
+{
+    /// <summary>
+    /// Type of connection to the server, with respect to jabberd.
+    /// This list will grow over time to include
+    /// queued connections, direct (in-proc) connections, etc.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum ComponentType
+    {
+        /// <summary>
+        /// Jabberd will accept the connetion; the component will
+        /// initiate the connection.  </summary>
+        Accept,
+        /// <summary>
+        /// Jabberd will connect to the component; jabberd will
+        /// initiate the connection.  </summary>
+        Connect
+    }
+
+    /// <summary>
+    /// Received a route element
+    /// </summary>
+    public delegate void RouteHandler(object sender, jabber.protocol.accept.Route route);
+
+    /// <summary>
+    /// Received an XDB element.
+    /// </summary>
+    public delegate void XdbHandler(object sender, jabber.protocol.accept.Xdb xdb);
+
+    /// <summary>
+    /// Received a Log element.
+    /// </summary>
+    public delegate void LogHandler(object sender, jabber.protocol.accept.Log log);
+
+    /// <summary>
+    /// Summary description for ServerComponent.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class JabberService : jabber.connection.XmppStream
+    {
+        private static readonly object[][] DEFAULTS = new object[][] {
+            new object[] {Options.COMPONENT_DIRECTION, ComponentType.Accept},
+            new object[] {Options.PORT, 7400},
+            new object[] {Options.OVERRIDE_FROM, null},
+        };
+
+        private void init()
+        {
+            SetDefaults(DEFAULTS);
+            this.OnStreamInit += new jabber.connection.StreamHandler(JabberService_OnStreamInit);
+            this.OnSASLStart += new jabber.connection.sasl.SASLProcessorHandler(JabberService_OnSASLStart);
+        }
+
+        /// <summary>
+        /// Create a a connect component.
+        /// </summary>
+        public JabberService() : base()
+        {
+            init();
+        }
+
+        /// <summary>
+        /// Create an accept component.  (Component connects to server)
+        /// </summary>
+        /// <param name="host">Jabberd host to connect to</param>
+        /// <param name="port">Jabberd port to connect to</param>
+        /// <param name="name">Component name</param>
+        /// <param name="secret">Component secret</param>
+        public JabberService(string host,
+            int port,
+            string name,
+            string secret) : base()
+        {
+            init();
+            this.ComponentID = name;
+            this.NetworkHost = host;
+            this.Port = port;
+
+            this[Options.PASSWORD] = secret;
+            this[Options.COMPONENT_DIRECTION] = ComponentType.Accept;
+        }
+
+        /// <summary>
+        /// Create a connect component. (Server connects to component)
+        /// </summary>
+        /// <param name="port">Port jabberd will connect to</param>
+        /// <param name="name">Component name</param>
+        /// <param name="secret">Component secret</param>
+        public JabberService(int port, string name, string secret) : base()
+        {
+            init();
+            this.ComponentID = name;
+            this.Port = port;
+
+            this[Options.PASSWORD] = secret;
+            this[Options.COMPONENT_DIRECTION] = ComponentType.Connect;
+        }
+
+        /// <summary>
+        /// We received a route packet.
+        /// </summary>
+        [Category("Protocol")]
+        [Description("We received a route packet.")]
+        public event RouteHandler OnRoute;
+
+        /// <summary>
+        /// We received an XDB packet.
+        /// </summary>
+        [Category("Protocol")]
+        [Description("We received an XDB packet.")]
+        public event XdbHandler OnXdb;
+
+        /// <summary>
+        /// We received a Log packet.
+        /// </summary>
+        [Category("Protocol")]
+        [Description("We received a Log packet.")]
+        public event LogHandler OnLog;
+
+        /// <summary>
+        /// The service name.  Needs to be in the id attribute in the
+        /// jabber.xml file.  </summary>
+        [Description("The service name.  The id attribute in the jabber.xml file.")]
+        [DefaultValue(null)]
+        [Category("Component")]
+        public string ComponentID
+        {
+            get { return (string)this[Options.TO]; }
+            set
+            {
+                this[Options.JID] = value;
+                this[Options.TO] = value;
+            }
+        }
+
+        /// <summary>
+        /// Should not be used for components.  Set NetworkHost instead.
+        /// </summary>
+        [Description("The name of the Jabber server.")]
+        [DefaultValue("jabber.com")]
+        [Category("Jabber")]
+        [Browsable(false)]
+        [Obsolete]
+        public override string Server
+        {
+            get { return base.NetworkHost; }
+            set { base.NetworkHost = value; }
+        }
+
+        /// <summary>
+        /// Component secret.
+        /// </summary>
+        [Description("Component secret.")]
+        [DefaultValue(null)]
+        [Category("Component")]
+        [PasswordPropertyText]
+        public string Secret
+        {
+            get { return (string)this[Options.PASSWORD]; }
+            set { this[Options.PASSWORD] = value; }
+        }
+
+        /// <summary>
+        /// Is this an outgoing connection (base_accept), or an incoming
+        /// connection (base_connect).
+        /// </summary>
+        [Description("Is this an outgoing connection (base_accept), or an incoming connection (base_connect).")]
+        [DefaultValue(ComponentType.Accept)]
+        [Category("Component")]
+        public ComponentType Type
+        {
+            get { return (ComponentType)this[Options.COMPONENT_DIRECTION]; }
+            set
+            {
+                if ((ComponentType)this[Options.COMPONENT_DIRECTION] != value)
+                {
+                    this[Options.COMPONENT_DIRECTION] = value;
+                    if ((ComponentType)this[Options.COMPONENT_DIRECTION] == ComponentType.Connect)
+                    {
+                        this.AutoReconnect = 0;
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// The stream namespace for this connection.
+        /// </summary>
+        [Browsable(false)]
+        protected override string NS
+        {
+            get
+            {
+                return (this.Type == ComponentType.Accept) ? URI.ACCEPT : URI.CONNECT;
+            }
+        }
+
+        /// <summary>
+        /// Override the from address that is stamped on all outbound stanzas that 
+        /// have no from address.
+        /// </summary>
+        public JID OverrideFrom
+        {
+            get { return this[Options.OVERRIDE_FROM] as JID; }
+            set { this[Options.OVERRIDE_FROM] = value; }
+        }
+
+        /// <summary>
+        /// Connect to the jabberd, or wait for it to connect to us.
+        /// Either way, this call returns immediately.
+        /// </summary>
+        /// <param name="address">The address to connect to.</param>
+        public void Connect(bedrock.net.Address address)
+        {
+            this.NetworkHost = address.Hostname;
+            this.Port = address.Port;
+
+            Connect();
+        }
+
+        /// <summary>
+        /// Connect to the jabberd, or wait for it to connect to us.
+        /// Either way, this call returns immediately.
+        /// </summary>
+        public override void Connect()
+        {
+            this[Options.SERVER_ID] = this[Options.NETWORK_HOST];
+            this[Options.JID] = new JID((string)this[Options.TO]);
+            if (this.Type == ComponentType.Accept)
+                base.Connect();
+            else
+            {
+                Accept();
+            }
+        }
+
+        /// <summary>
+        /// Make sure there's a from address, then write the stanza.
+        /// </summary>
+        /// <param name="elem">The stanza to write</param>
+        public override void Write(XmlElement elem)
+        {
+            if (State == RunningState.Instance)
+            {
+                if (elem.GetAttribute("from") == "")
+                {
+                    JID from = this[Options.OVERRIDE_FROM] as JID;
+                    if (from == null)
+                        from = this.ComponentID;
+
+                    elem.SetAttribute("from", from);
+                }
+            }
+            base.Write(elem);
+        }
+
+        /// <summary>
+        /// Got the stream:stream.  Start the handshake.
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="tag"></param>
+        protected override void OnDocumentStart(object sender, System.Xml.XmlElement tag)
+        {
+            base.OnDocumentStart(sender, tag);
+            if (this.Type == ComponentType.Connect)
+            {
+                lock (StateLock)
+                {
+                    State = HandshakingState.Instance;
+                }
+
+                jabber.protocol.stream.Stream str = new jabber.protocol.stream.Stream(this.Document, NS);
+                str.To = this.ComponentID;
+                this.StreamID = str.ID;
+                if (ServerVersion.StartsWith("1."))
+                    str.Version = "1.0";
+
+
+                WriteStartTag(str);
+
+                if (ServerVersion.StartsWith("1."))
+                {
+                    Features f = new Features(this.Document);
+                    if (AutoStartTLS && !SSLon && (this[Options.LOCAL_CERTIFICATE] != null))
+                        f.StartTLS = new StartTLS(this.Document);
+                    Write(f);
+                }
+            }
+        }
+
+        private void Handshake(System.Xml.XmlElement tag)
+        {
+            Handshake hs = tag as Handshake;
+
+            if (hs == null)
+            {
+                FireOnError(new System.Security.SecurityException("Bad protocol.  Needs handshake, got: " + tag.OuterXml));
+                return;
+            }
+
+            if (this.Type == ComponentType.Accept)
+                IsAuthenticated = true;
+            else
+            {
+                string test = hs.Digest;
+                string good = Element.ShaHash(StreamID, this.Secret);
+                if (test == good)
+                {
+                    IsAuthenticated = true;
+                    Write(new Handshake(this.Document));
+                }
+                else
+                {
+                    Write(new Error(this.Document));
+                    FireOnError(new System.Security.SecurityException("Bad handshake."));
+                }
+            }
+        }
+
+        /// <summary>
+        /// Received an element.
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="tag"></param>
+        protected override void OnElement(object sender, System.Xml.XmlElement tag)
+        {
+            lock (StateLock)
+            {
+                StartTLS start = tag as StartTLS;
+                if (start != null)
+                {
+                    State = ConnectedState.Instance;
+                    InitializeStream();
+                    this.Write(new Proceed(this.Document));
+                    this.StartTLS();
+                    return;
+                }
+                if (State == HandshakingState.Instance)
+                {
+                    // sets IsConnected
+                    Handshake(tag);
+                    return;
+                }
+            }
+
+            base.OnElement(sender, tag);
+
+            if (OnRoute != null)
+            {
+                Route route = tag as Route;
+                if (route != null)
+                {
+                    if (InvokeRequired)
+                        CheckedInvoke(OnRoute, new object[] {this, route});
+                    else
+                        OnRoute(this, route);
+                }
+            }
+            // TODO: add XdbTracker stuff
+            if (OnXdb != null)
+            {
+                Xdb xdb = tag as Xdb;
+                if (xdb != null)
+                {
+                    if (InvokeRequired)
+                        CheckedInvoke(OnXdb, new object[] {this, xdb});
+                    else
+                        OnXdb(this, xdb);
+                }
+            }
+            if (OnLog != null)
+            {
+                Log log = tag as Log;
+                if (log != null)
+                {
+                    if (InvokeRequired)
+                        CheckedInvoke(OnLog, new object[] {this, log});
+                    else
+                        OnLog(this, log);
+                }
+            }
+        }
+
+        private void JabberService_OnSASLStart(object sender, jabber.connection.sasl.SASLProcessor proc)
+        {
+            jabber.connection.BaseState s = null;
+            lock (StateLock)
+            {
+                s = State;
+            }
+
+            if (s == jabber.connection.NonSASLAuthState.Instance)
+            {
+                lock (StateLock)
+                {
+                    State = HandshakingState.Instance;
+                }
+
+                if (this.Type == ComponentType.Accept)
+                {
+                    Handshake hand = new Handshake(this.Document);
+                    hand.SetAuth(this.Secret, StreamID);
+                    Write(hand);
+                }
+            }
+        }
+
+        private void JabberService_OnStreamInit(Object sender, ElementStream stream)
+        {
+            stream.AddFactory(new jabber.protocol.accept.Factory());
+        }
+    }
+
+    /// <summary>
+    /// Waiting for handshake result.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class HandshakingState : jabber.connection.BaseState
+    {
+        /// <summary>
+        /// The instance that is always used.
+        /// </summary>
+        public static readonly jabber.connection.BaseState Instance = new HandshakingState();
+    }
+
+    /// <summary>
+    /// Waiting for socket connection.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class AcceptingState : jabber.connection.BaseState
+    {
+        /// <summary>
+        /// The instance that is always used.
+        /// </summary>
+        public static readonly jabber.connection.BaseState Instance = new AcceptingState();
+    }
+}
diff --git a/lib/jabber-net/jabber/server/JabberService.resx b/lib/jabber-net/jabber/server/JabberService.resx
new file mode 100644
index 0000000..7e32396
--- /dev/null
+++ b/lib/jabber-net/jabber/server/JabberService.resx
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<root>
+	<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+		<xsd:element name="root" msdata:IsDataSet="true">
+			<xsd:complexType>
+				<xsd:choice maxOccurs="unbounded">
+					<xsd:element name="data">
+						<xsd:complexType>
+							<xsd:sequence>
+								<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+								<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+							</xsd:sequence>
+							<xsd:attribute name="name" type="xsd:string" />
+							<xsd:attribute name="type" type="xsd:string" />
+							<xsd:attribute name="mimetype" type="xsd:string" />
+						</xsd:complexType>
+					</xsd:element>
+					<xsd:element name="resheader">
+						<xsd:complexType>
+							<xsd:sequence>
+								<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+							</xsd:sequence>
+							<xsd:attribute name="name" type="xsd:string" use="required" />
+						</xsd:complexType>
+					</xsd:element>
+				</xsd:choice>
+			</xsd:complexType>
+		</xsd:element>
+	</xsd:schema>
+	<resheader name="ResMimeType">
+		<value>text/microsoft-resx</value>
+	</resheader>
+	<resheader name="Version">
+		<value>1.0.0.0</value>
+	</resheader>
+	<resheader name="Reader">
+		<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+	</resheader>
+	<resheader name="Writer">
+		<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+	</resheader>
+</root>
diff --git a/lib/jabber-net/jabber/server/XdbTracker.cs b/lib/jabber-net/jabber/server/XdbTracker.cs
new file mode 100644
index 0000000..0896712
--- /dev/null
+++ b/lib/jabber-net/jabber/server/XdbTracker.cs
@@ -0,0 +1,166 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using System.Diagnostics;
+using System.Xml;
+
+using bedrock.util;
+using jabber.protocol.accept;
+
+namespace jabber.server
+{
+    /// <summary>
+    /// Received a response to an XDB request.
+    /// </summary>
+    public delegate void XdbCB(object sender, Xdb xdb, object data);
+
+    /// <summary>
+    /// Track outstanding XDB requests.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class XdbTracker
+    {
+        // this hash doesn't need concurrency control, i don't think,
+        // since no id will be re-used.
+        private Hashtable       m_pending = new Hashtable();
+        private JabberService   m_comp    = null;
+
+        /// <summary>
+        /// Create a new XDB tracker
+        /// </summary>
+        /// <param name="comp">The component to send/receive on</param>
+        public XdbTracker(JabberService comp)
+        {
+            m_comp = comp;
+            m_comp.OnXdb += new XdbHandler(OnXdb);
+        }
+
+        /// <summary>
+        /// Received an XDB element on Component.
+        /// Is this a response to a tracked request?
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="xdb"></param>
+        private void OnXdb(object sender, Xdb xdb)
+        {
+            string id = xdb.ID;
+            TrackerData td;
+
+            lock (m_pending)
+            {
+                td = (TrackerData) m_pending[id];
+
+                // this wasn't one that was being tracked.
+                if (td == null)
+                {
+                    return;
+                }
+                m_pending.Remove(id);
+            }
+
+            // don't need to check for null.  protected by assert below.
+            td.cb(this, xdb, td.data);
+        }
+
+        /// <summary>
+        /// Start an XDB request.
+        /// </summary>
+        /// <param name="owner"></param>
+        /// <param name="ns"></param>
+        /// <param name="cb"></param>
+        /// <param name="cbArg"></param>
+        public void BeginXdbGet(string owner, string ns,
+            XdbCB cb, object cbArg)
+        {
+            BeginXdb(null, XdbType.get, owner, ns, XdbAction.NONE, cb, cbArg);
+        }
+
+        /// <summary>
+        /// Start an XDB request.
+        /// </summary>
+        /// <param name="root"></param>
+        /// <param name="owner"></param>
+        /// <param name="ns"></param>
+        /// <param name="cb"></param>
+        /// <param name="cbArg"></param>
+        public void BeginXdbSet(XmlElement root, string owner, string ns,
+            XdbCB cb, object cbArg)
+        {
+            BeginXdb(root, XdbType.set, owner, ns, XdbAction.NONE, cb, cbArg);
+        }
+
+        /// <summary>
+        /// Start an XDB request.
+        /// </summary>
+        /// <param name="root"></param>
+        /// <param name="xtype"></param>
+        /// <param name="owner"></param>
+        /// <param name="ns"></param>
+        /// <param name="cb"></param>
+        /// <param name="cbArg"></param>
+        public void BeginXdb(XmlElement root, XdbType xtype,
+            string owner, string ns,
+            XdbCB cb, object cbArg)
+        {
+            BeginXdb(root, xtype, owner, ns, XdbAction.NONE, cb, cbArg);
+        }
+
+        /// <summary>
+        /// Start an XDB request.
+        /// </summary>
+        /// <param name="root"></param>
+        /// <param name="xtype"></param>
+        /// <param name="owner"></param>
+        /// <param name="ns"></param>
+        /// <param name="action"></param>
+        /// <param name="cb"></param>
+        /// <param name="cbArg"></param>
+        public void BeginXdb(XmlElement root, XdbType xtype,
+            string owner, string ns, XdbAction action,
+            XdbCB cb, object cbArg)
+        {
+            Debug.Assert(owner != null);
+            Debug.Assert(ns    != null);
+            Xdb xdb  = new Xdb(m_comp.Document);
+            xdb.NS   = ns;
+            xdb.Type = xtype;
+            xdb.To   = owner;
+            xdb.From = m_comp.ComponentID;
+            if (action != XdbAction.NONE)
+                xdb.Action = action;
+            if (root != null)
+                xdb.AddChild(root);
+            // if no callback, ignore response.
+            if (cb != null)
+            {
+                TrackerData td = new TrackerData();
+                td.cb   = cb;
+                td.data = cbArg;
+                lock (m_pending)
+                {
+                    m_pending[xdb.ID] = td;
+                }
+            }
+            m_comp.Write(xdb);
+        }
+
+        private class TrackerData
+        {
+            public XdbCB  cb;
+            public object data;
+        }
+    }
+}
diff --git a/lib/jabber-net/muzzle/AssemblyInfo.cs b/lib/jabber-net/muzzle/AssemblyInfo.cs
new file mode 100644
index 0000000..3e5a5f5
--- /dev/null
+++ b/lib/jabber-net/muzzle/AssemblyInfo.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:2.0.50727.1433
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Muzzle library")]
+[assembly: AssemblyDescription("GUI helper functions to be used with Jabber-Net.")]
+[assembly: AssemblyCompany("Cursive Systems, Inc.")]
+[assembly: AssemblyProduct("jabber-net")]
+[assembly: AssemblyCopyright("Copyright (c) Cursive, Inc. 2000-2008")]
+[assembly: AssemblyVersion("2.0.0.613")]
+[assembly: AssemblyDelaySign(false)]
+[assembly: CLSCompliant(true)]
+[assembly: AssemblyKeyFile("../../../jabbernet.key")]
+
+
diff --git a/lib/jabber-net/muzzle/BottomScrollRichText.cs b/lib/jabber-net/muzzle/BottomScrollRichText.cs
new file mode 100644
index 0000000..9fe388a
--- /dev/null
+++ b/lib/jabber-net/muzzle/BottomScrollRichText.cs
@@ -0,0 +1,414 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Runtime.InteropServices;
+
+using bedrock.util;
+using System.Diagnostics;
+
+namespace muzzle
+{
+
+    /// <summary>
+    /// Summary description for BottomScrollRichText.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class BottomScrollRichText : System.Windows.Forms.RichTextBox
+    {
+        private const int SB_HORZ             = 0;
+        private const int SB_VERT             = 1;
+        private const int SB_CTL              = 2;
+        private const int SB_BOTH             = 3;
+
+        private const int SB_LINEUP           = 0;
+        private const int SB_LINELEFT         = 0;
+        private const int SB_LINEDOWN         = 1;
+        private const int SB_LINERIGHT        = 1;
+        private const int SB_PAGEUP           = 2;
+        private const int SB_PAGELEFT         = 2;
+        private const int SB_PAGEDOWN         = 3;
+        private const int SB_PAGERIGHT        = 3;
+        private const int SB_THUMBPOSITION    = 4;
+        private const int SB_THUMBTRACK       = 5;
+        private const int SB_TOP              = 6;
+        private const int SB_LEFT             = 6;
+        private const int SB_BOTTOM           = 7;
+        private const int SB_RIGHT            = 7;
+        private const int SB_ENDSCROLL        = 8;
+
+        private const int SIF_RANGE           = 0x0001;
+        private const int SIF_PAGE            = 0x0002;
+        private const int SIF_POS             = 0x0004;
+        private const int SIF_DISABLENOSCROLL = 0x0008;
+        private const int SIF_TRACKPOS        = 0x0010;
+        private const int SIF_ALL             = (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS);
+
+        private const int WM_HSCROLL          = 0x0114;
+        private const int WM_VSCROLL          = 0x0115;
+
+        private const int EM_SETSCROLLPOS = 0x0400 + 222;
+
+        private const int CCHILDREN_SCROLLBAR = 5;
+        private const int STATE_SYSTEM_INVISIBLE   = 0x00008000;
+        private const int STATE_SYSTEM_OFFSCREEN   = 0x00010000;
+        private const int STATE_SYSTEM_PRESSED     = 0x00000008;
+        private const int STATE_SYSTEM_UNAVAILABLE = 0x00000001;
+
+        private const uint OBJID_CLIENT  = 0xFFFFFFFC;
+        private const uint OBJID_VSCROLL = 0xFFFFFFFB;
+        private const uint OBJID_HSCROLL = 0xFFFFFFFA;
+
+        private bool m_bottom = true;
+        private int m_maxLines = 500;
+
+        /// <summary>
+        /// Maximum number of lines to keep
+        /// </summary>
+        [Category("Appearance")]
+        public int MaxLines
+        {
+            get { return m_maxLines; }
+            set { m_maxLines = value; }
+        }
+
+        [StructLayout(LayoutKind.Sequential)]
+        private struct SCROLLINFO
+        {
+            public int  cbSize;
+            public uint fMask;
+            public int  nMin;
+            public int  nMax;
+            public uint nPage;
+            public int  nPos;
+            public int  nTrackPos;
+        }
+
+        [StructLayout(LayoutKind.Sequential)]
+        private struct RECT
+        {
+            public int left;
+            public int top;
+            public int right;
+            public int bottom;
+        }
+
+        [StructLayout(LayoutKind.Sequential)]
+        private struct SCROLLBARINFO
+        {
+            public int cbSize;
+            public RECT rcScrollBar;
+            public int dxyLineButton;
+            public int xyThumbTop;
+            public int xyThumbBottom;
+            public int reserved;
+            [MarshalAs(UnmanagedType.ByValArray, SizeConst=CCHILDREN_SCROLLBAR+1)]
+            public int[] rgstate;
+        }
+
+        [StructLayout(LayoutKind.Sequential)]
+        private class POINT
+        {
+            public int x;
+            public int y;
+
+            public POINT()
+            {
+            }
+
+            public POINT(int x, int y)
+            {
+                this.x = x;
+                this.y = y;
+            }
+        }
+
+        [DllImport("user32", CharSet=CharSet.Auto)]
+        private static extern bool GetScrollRange(IntPtr hWnd, int nBar, out int lpMinPos, out int lpMaxPos);
+
+        [DllImport("user32", CharSet=CharSet.Auto)]
+        private static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, POINT lParam);
+
+        [DllImport("user32", CharSet=CharSet.Auto)]
+        private static extern bool GetScrollInfo(IntPtr hWnd, int nBar, ref SCROLLINFO lpsi);
+
+        [DllImport("user32", CharSet=CharSet.Auto)]
+        private static extern int SetScrollInfo(IntPtr hWnd, int fnBar, ref SCROLLINFO lpsi, bool fRedraw);
+
+        [DllImport("user32", SetLastError=true, EntryPoint="GetScrollBarInfo")]
+        private static extern int GetScrollBarInfo(IntPtr hWnd, uint idObject, ref SCROLLBARINFO psbi);
+
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.Container components = null;
+
+        /// <summary>
+        /// Create a RichText that can scroll to the bottom easily.
+        /// </summary>
+        public BottomScrollRichText()
+        {
+            // This call is required by the Windows.Forms Form Designer.
+            InitializeComponent();
+        }
+
+        /// <summary>
+        /// Is the text currently scrolled to the bottom?
+        /// </summary>
+        public bool IsAtBottom
+        {
+            get { return m_bottom; }
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        protected override void Dispose( bool disposing )
+        {
+            if( disposing )
+            {
+                if(components != null)
+                {
+                    components.Dispose();
+                }
+            }
+            base.Dispose( disposing );
+        }
+
+        #region Component Designer generated code
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            components = new System.ComponentModel.Container();
+        }
+        #endregion
+
+        /// <summary>
+        /// The message pump.  Overriden to catch the WM_VSCROLL events.
+        /// </summary>
+        /// <param name="m"></param>
+        protected override void WndProc(ref Message m)
+        {
+            if (m.Msg == WM_VSCROLL)
+            {
+                SCROLLINFO si = GetScroll();
+                m_bottom = (si.nPos + si.nPage + 5 >= si.nMax);
+            }
+            base.WndProc(ref m);
+        }
+
+        /// <summary>
+        /// Clear the text, and scroll back to the top.
+        /// </summary>
+        public void ClearAndScroll()
+        {
+            this.Text = "";
+            this.Select(0, 0);
+            this.ScrollToCaret();
+            m_bottom = true;
+
+            //SendMessage(this.Handle, EM_SETSCROLLPOS, 0, new POINT(0, 0));
+        }
+
+        private SCROLLINFO GetScroll()
+        {
+            SCROLLINFO si = new SCROLLINFO();
+            si.cbSize = Marshal.SizeOf(si);
+            si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
+            GetScrollInfo(this.Handle, SB_VERT, ref si);
+            return si;
+        }
+
+        private SCROLLBARINFO GetBars()
+        {
+            SCROLLBARINFO si = new SCROLLBARINFO();
+            si.cbSize = Marshal.SizeOf(si);
+            int ret = GetScrollBarInfo(this.Handle, OBJID_VSCROLL, ref si);
+            if (ret == 0)
+                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
+            return si;
+        }
+
+        /// <summary>
+        /// Scroll to the bottom of the current text.
+        /// </summary>
+        public void ScrollToBottom()
+        {
+            SCROLLBARINFO sbi = GetBars();
+            if (sbi.rgstate[0] == 0)
+            {
+                SCROLLINFO si = GetScroll();
+                SendMessage(this.Handle, EM_SETSCROLLPOS, 0, new POINT(0, si.nMax - (int)si.nPage + 5));
+            }
+        }
+
+        private static string EscapeRTF(string plain)
+        {
+            System.Text.StringBuilder sb = new System.Text.StringBuilder(plain.Length);
+
+            char state = 'c';
+
+            foreach (char c in plain)
+            {
+                if (state == 'r')
+                {
+                    if (c == '\n')
+                        state = 'n';
+                    else
+                    {
+                        state = 'c';
+                    }
+                }
+                else if (state == 'n')
+                {
+                    state = 'c';
+                }
+
+                if (state == 'c')
+                {
+                    if (c > 127)
+                    {
+                        sb.Append(@"\u");
+                        sb.Append((int)c);
+                        sb.Append('?');
+                    }
+                    else
+                    {
+                        switch (c)
+                        {
+                            case '{':
+                            case '}':
+                            case '\\':
+                                sb.Append('\\');
+                                sb.Append(c);
+                                break;
+                            case '\r':
+                                sb.Append("\\\r\n");
+                                state = 'r';
+                                break;
+                            case '\n':
+                                sb.Append("\\\r\n");
+                                state = 'n';
+                                break;
+                            default:
+                                sb.Append(c);
+                                break;
+                        }
+                    }
+                }
+            }
+            return sb.ToString();
+        }
+
+        private static string RTFColor(Color c)
+        {
+            return String.Format("\\red{0}\\green{1}\\blue{2};", c.R, c.G, c.B);
+        }
+
+        /// <summary>
+        /// Append text with the given color to the end of the text area.
+        /// Side effect: the existing selection is modified.  Save the selection
+        /// if you want to keep it.
+        /// </summary>
+        /// <param name="c"></param>
+        /// <param name="text"></param>
+        public void AppendText(Color c, string text)
+        {
+            this.SelectionLength = 0;
+            this.SelectionStart = this.TextLength;
+            string rtf = "{\\rtf1\\ansi{{\\colortbl ;" + RTFColor(c) +
+                               "}\\cf1 " + EscapeRTF(text) + "}";
+            this.SelectedRtf = rtf;
+        }
+
+        /// <summary>
+        /// Append text.  If we were at the bottom, scroll to the bottom.  Otherwise leave the scroll position
+        /// where it is.
+        /// </summary>
+        /// <param name="text"></param>
+        public void AppendMaybeScroll(string text)
+        {
+            bool bottom = m_bottom;
+            this.AppendText(text);
+            if (bottom)
+                ScrollToBottom();
+        }
+
+        /// <summary>
+        /// Add a line that has a colored tag string, followed by a space, followed by
+        /// a chunk of text in the default color, followed by a newline.
+        ///
+        /// Note: Although this seems kind of random, it's needed in several places.
+        /// </summary>
+        /// <param name="tagColor">The color to use for the tag</param>
+        /// <param name="tag">The tag string</param>
+        /// <param name="text">The main text</param>
+        public void AppendMaybeScroll(Color tagColor, string tag, string text)
+        {
+            this.SuspendLayout();
+
+            // This should always be called on the GUI thread, right?
+            // Assume so.  No locking.
+
+            bool bottom = m_bottom;
+            int start = 0;
+            int len = 0;
+            if (!bottom)
+            {
+                start = this.SelectionStart;
+                len = this.SelectionLength;
+            }
+
+            AppendText(tagColor, tag);
+            AppendText(" ");
+            AppendText(ForeColor, text);
+            AppendText("\r\n");
+
+            string[] lines = this.Lines;
+            if (lines.Length > m_maxLines)
+            {
+                int rm = 0;
+                bool ro = this.ReadOnly;
+                this.ReadOnly = false;
+                for (int i = 0; i < (lines.Length - m_maxLines); i++)
+                {
+                    rm += lines[i].Length + 1;
+                }
+                this.Select(0, rm);
+                this.SelectedText = "";
+                this.ReadOnly = ro;
+            }
+
+            if (bottom)
+            {
+                ScrollToBottom();
+                this.SelectionStart = this.TextLength;
+                this.SelectionLength = 0;
+            }
+            else
+            {
+                this.SelectionStart = start;
+                this.SelectionLength = len;
+            }
+
+            this.ResumeLayout();
+        }
+    }
+}
diff --git a/lib/jabber-net/muzzle/ChatHistory.cs b/lib/jabber-net/muzzle/ChatHistory.cs
new file mode 100644
index 0000000..3a83214
--- /dev/null
+++ b/lib/jabber-net/muzzle/ChatHistory.cs
@@ -0,0 +1,101 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Drawing;
+
+using bedrock.util;
+
+using jabber;
+using jabber.client;
+
+namespace muzzle
+{
+    /// <summary>
+    /// Keep track of the history of a conversation or room.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ChatHistory : BottomScrollRichText
+    {
+        // TODO: create a manager class that knows these prefs, and sets them easily every time.
+        private Color m_sendColor = Color.Blue;
+        private Color m_recvColor = Color.Red;
+        private Color m_actionColor = Color.Purple;
+        private Color m_presenceColor = Color.Green;
+
+        private string m_nick;
+
+
+        /// <summary>
+        /// Create.  Make sure to set Client and From, at least.
+        /// </summary>
+        public ChatHistory()
+        {
+        }
+
+
+        /// <summary>
+        /// Nickname for the associated user.  If null, the resource will be used (e.g. MUC).
+        /// </summary>
+        public string Nickname
+        {
+            get { return m_nick; }
+            set { m_nick = value; }
+        }
+
+        /// <summary>
+        /// Insert the given message into the history.  The timestamp on the message will be used, if
+        /// included, otherwise the current time will be used.
+        /// Messages without bodies will be ignored.
+        /// </summary>
+        /// <param name="msg"></param>
+        public void InsertMessage(jabber.protocol.client.Message msg)
+        {
+            string body = msg.Body;
+            if (body == null)
+                return;  // typing indicator, e.g.
+
+            string nick = (m_nick == null) ? msg.From.Resource : m_nick;
+            AppendMaybeScroll(m_recvColor, nick + ":", body);
+        }
+
+        /// <summary>
+        /// We sent some text; insert it.
+        /// </summary>
+        /// <param name="text"></param>
+        public void InsertSend(string text)
+        {
+            AppendMaybeScroll(m_sendColor, "Me:", text);
+        }
+
+        private void m_cli_OnPresence(object sender, jabber.protocol.client.Presence pres)
+        {
+            throw new Exception("The method or operation is not implemented.");
+        }
+
+        #region Component Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+
+        }
+        #endregion
+
+    }
+}
diff --git a/lib/jabber-net/muzzle/ClientLogin.cs b/lib/jabber-net/muzzle/ClientLogin.cs
new file mode 100644
index 0000000..e57657a
--- /dev/null
+++ b/lib/jabber-net/muzzle/ClientLogin.cs
@@ -0,0 +1,663 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Drawing;
+using System.Collections;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Windows.Forms;
+using System.Xml;
+
+using bedrock.util;
+using jabber.connection;
+using jabber.connection.sasl;
+
+namespace muzzle
+{
+    /// <summary>
+    /// A login form for client connections.
+    /// </summary>
+    /// <example>
+    /// ClientLogin l = new ClientLogin(jc);
+    ///
+    /// if (l.ShowDialog(this) == DialogResult.OK)
+    /// {
+    ///     jc.Connect();
+    /// }
+    /// </example>
+    [SVN(@"$Id$")]
+    public class ClientLogin : OptionForm
+    {
+        private System.Windows.Forms.CheckBox cbSSL;
+        private System.Windows.Forms.TabControl tabControl1;
+        /// <summary>
+        /// The basic configuration tab.
+        /// </summary>
+        protected TabPage tpBasic;
+        private System.Windows.Forms.TextBox txtPass;
+        private System.Windows.Forms.TextBox txtServer;
+        private System.Windows.Forms.TextBox txtUser;
+        private System.Windows.Forms.Label label4;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.TabPage tpNetwork;
+        private System.Windows.Forms.NumericUpDown numPort;
+        private System.Windows.Forms.Label label3;
+        private System.Windows.Forms.Label label5;
+        private System.Windows.Forms.TextBox txtNetworkHost;
+        private System.Windows.Forms.TabPage tpProxy;
+        private System.Windows.Forms.Label label6;
+        private System.Windows.Forms.ComboBox cmbProxy;
+        private System.Windows.Forms.Label label7;
+        private System.Windows.Forms.Label label8;
+        private System.Windows.Forms.Label label9;
+        private System.Windows.Forms.Label label10;
+        private System.Windows.Forms.NumericUpDown numProxyPort;
+        private System.Windows.Forms.TextBox txtProxyUser;
+        private System.Windows.Forms.TextBox txtProxyPassword;
+        private System.Windows.Forms.TextBox txtProxyHost;
+        private System.Windows.Forms.CheckBox cbPlaintext;
+        private TabPage tpConnection;
+        private TextBox txtURL;
+        private Label label12;
+        private ComboBox cmbConnectionType;
+        private CheckBox cbUseWinCreds;
+        private Label label11;
+
+        /// <summary>
+        /// Create a Client Login dialog box
+        /// </summary>
+        public ClientLogin() : base()
+        {
+            //
+            // Required for Windows Form Designer support
+            //
+            InitializeComponent();
+#if NO_SSL
+            cbSSL.Visible = false;
+#endif
+
+            for (ProxyType pt=ProxyType.None; pt <= ProxyType.HTTP; pt++)
+            {
+                cmbProxy.Items.Add(pt);
+            }
+            cmbProxy.SelectedItem = ProxyType.None;
+
+            for (ConnectionType ct=ConnectionType.Socket; ct <= ConnectionType.HTTP_Binding; ct++)
+            {
+                cmbConnectionType.Items.Add(ct);
+            }
+            cmbConnectionType.SelectedItem = ConnectionType.Socket;
+
+            cbSSL.Tag = Options.SSL;
+            txtPass.Tag = Options.PASSWORD;
+            txtServer.Tag = Options.TO;
+            txtUser.Tag = Options.USER;
+            numPort.Tag = Options.PORT;
+            txtNetworkHost.Tag = Options.NETWORK_HOST;
+            cmbProxy.Tag = Options.PROXY_TYPE;
+            numProxyPort.Tag = Options.PROXY_PORT;
+            txtProxyUser.Tag = Options.PROXY_USER;
+            txtProxyPassword.Tag = Options.PROXY_PW;
+            txtProxyHost.Tag = Options.PROXY_HOST;
+            cbPlaintext.Tag = Options.PLAINTEXT;
+            txtURL.Tag = Options.POLL_URL;
+            cmbConnectionType.Tag = Options.CONNECTION_TYPE;
+            cbUseWinCreds.Tag = KerbProcessor.USE_WINDOWS_CREDS;
+        }
+
+        /// <summary>
+        /// Log in to the server
+        /// </summary>
+        /// <param name="cli">The JabberClient instance to connect</param>
+        /// <param name="propertyFile">The name of an XML file to store properties in.</param>
+        /// <returns>True if the user clicked OK, false on cancel</returns>
+        public static bool Login(jabber.client.JabberClient cli, string propertyFile)
+        {
+            return new ClientLogin(cli).Login(propertyFile);
+        }
+
+        /// <summary>
+        /// Create a Client Login dialog box than manages the connection properties of a particular client
+        /// connection.
+        /// </summary>
+        /// <param name="cli">The client connection to modify</param>
+        public ClientLogin(jabber.client.JabberClient cli) : this()
+        {
+            this.Xmpp = cli;
+        }
+
+        #region Windows Form Designer generated code
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.txtServer = new System.Windows.Forms.TextBox();
+            this.txtUser = new System.Windows.Forms.TextBox();
+            this.cbSSL = new System.Windows.Forms.CheckBox();
+            this.numPort = new System.Windows.Forms.NumericUpDown();
+            this.tabControl1 = new System.Windows.Forms.TabControl();
+            this.tpBasic = new System.Windows.Forms.TabPage();
+            this.cbUseWinCreds = new System.Windows.Forms.CheckBox();
+            this.cbPlaintext = new System.Windows.Forms.CheckBox();
+            this.txtPass = new System.Windows.Forms.TextBox();
+            this.label4 = new System.Windows.Forms.Label();
+            this.label2 = new System.Windows.Forms.Label();
+            this.label1 = new System.Windows.Forms.Label();
+            this.tpNetwork = new System.Windows.Forms.TabPage();
+            this.txtNetworkHost = new System.Windows.Forms.TextBox();
+            this.label5 = new System.Windows.Forms.Label();
+            this.label3 = new System.Windows.Forms.Label();
+            this.tpConnection = new System.Windows.Forms.TabPage();
+            this.txtURL = new System.Windows.Forms.TextBox();
+            this.label12 = new System.Windows.Forms.Label();
+            this.cmbConnectionType = new System.Windows.Forms.ComboBox();
+            this.label11 = new System.Windows.Forms.Label();
+            this.tpProxy = new System.Windows.Forms.TabPage();
+            this.txtProxyPassword = new System.Windows.Forms.TextBox();
+            this.txtProxyUser = new System.Windows.Forms.TextBox();
+            this.numProxyPort = new System.Windows.Forms.NumericUpDown();
+            this.txtProxyHost = new System.Windows.Forms.TextBox();
+            this.label10 = new System.Windows.Forms.Label();
+            this.label9 = new System.Windows.Forms.Label();
+            this.label8 = new System.Windows.Forms.Label();
+            this.label7 = new System.Windows.Forms.Label();
+            this.label6 = new System.Windows.Forms.Label();
+            this.cmbProxy = new System.Windows.Forms.ComboBox();
+            ((System.ComponentModel.ISupportInitialize)(this.error)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.numPort)).BeginInit();
+            this.tabControl1.SuspendLayout();
+            this.tpBasic.SuspendLayout();
+            this.tpNetwork.SuspendLayout();
+            this.tpConnection.SuspendLayout();
+            this.tpProxy.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.numProxyPort)).BeginInit();
+            this.SuspendLayout();
+            // 
+            // txtServer
+            // 
+            this.txtServer.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtServer.Location = new System.Drawing.Point(72, 72);
+            this.txtServer.Name = "txtServer";
+            this.txtServer.Size = new System.Drawing.Size(189, 20);
+            this.txtServer.TabIndex = 5;
+            this.tip.SetToolTip(this.txtServer, "The name of the Jabber server");
+            this.txtServer.Validated += new System.EventHandler(this.onValidated);
+            this.txtServer.Validating += new System.ComponentModel.CancelEventHandler(this.Required_Validating);
+            // 
+            // txtUser
+            // 
+            this.txtUser.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtUser.Location = new System.Drawing.Point(72, 8);
+            this.txtUser.Name = "txtUser";
+            this.txtUser.Size = new System.Drawing.Size(189, 20);
+            this.txtUser.TabIndex = 1;
+            this.txtUser.Tag = "";
+            this.tip.SetToolTip(this.txtUser, "The user portion of the JID only.");
+            this.txtUser.Validated += new System.EventHandler(this.onValidated);
+            this.txtUser.Validating += new System.ComponentModel.CancelEventHandler(this.Required_Validating);
+            // 
+            // cbSSL
+            // 
+            this.cbSSL.AccessibleDescription = "";
+            this.cbSSL.Location = new System.Drawing.Point(8, 64);
+            this.cbSSL.Name = "cbSSL";
+            this.cbSSL.Size = new System.Drawing.Size(48, 24);
+            this.cbSSL.TabIndex = 4;
+            this.cbSSL.Text = "SSL";
+            this.tip.SetToolTip(this.cbSSL, "Connect using old-style Secure Socket Layer encryption");
+            this.cbSSL.CheckedChanged += new System.EventHandler(this.cbSSL_CheckedChanged);
+            // 
+            // numPort
+            // 
+            this.numPort.Location = new System.Drawing.Point(88, 10);
+            this.numPort.Maximum = new decimal(new int[] {
+            65535,
+            0,
+            0,
+            0});
+            this.numPort.Minimum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+            this.numPort.Name = "numPort";
+            this.numPort.Size = new System.Drawing.Size(94, 20);
+            this.numPort.TabIndex = 1;
+            this.tip.SetToolTip(this.numPort, "TCP port to connect on");
+            this.numPort.Value = new decimal(new int[] {
+            5222,
+            0,
+            0,
+            0});
+            // 
+            // tabControl1
+            // 
+            this.tabControl1.Controls.Add(this.tpBasic);
+            this.tabControl1.Controls.Add(this.tpNetwork);
+            this.tabControl1.Controls.Add(this.tpConnection);
+            this.tabControl1.Controls.Add(this.tpProxy);
+            this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.tabControl1.Location = new System.Drawing.Point(0, 0);
+            this.tabControl1.Name = "tabControl1";
+            this.tabControl1.SelectedIndex = 0;
+            this.tabControl1.Size = new System.Drawing.Size(292, 182);
+            this.tabControl1.TabIndex = 0;
+            // 
+            // tpBasic
+            // 
+            this.tpBasic.Controls.Add(this.cbUseWinCreds);
+            this.tpBasic.Controls.Add(this.cbPlaintext);
+            this.tpBasic.Controls.Add(this.txtPass);
+            this.tpBasic.Controls.Add(this.txtServer);
+            this.tpBasic.Controls.Add(this.txtUser);
+            this.tpBasic.Controls.Add(this.label4);
+            this.tpBasic.Controls.Add(this.label2);
+            this.tpBasic.Controls.Add(this.label1);
+            this.tpBasic.Location = new System.Drawing.Point(4, 22);
+            this.tpBasic.Name = "tpBasic";
+            this.tpBasic.Size = new System.Drawing.Size(284, 156);
+            this.tpBasic.TabIndex = 0;
+            this.tpBasic.Text = "Basic";
+            // 
+            // cbUseWinCreds
+            // 
+            this.cbUseWinCreds.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.cbUseWinCreds.Location = new System.Drawing.Point(8, 130);
+            this.cbUseWinCreds.Name = "cbUseWinCreds";
+            this.cbUseWinCreds.Size = new System.Drawing.Size(268, 17);
+            this.cbUseWinCreds.TabIndex = 7;
+            this.cbUseWinCreds.Text = "Use Windows credentials or a client certificate";
+            this.tip.SetToolTip(this.cbUseWinCreds, "Attempt to do single sign-on using Kerberos/GSSAPI or an X.509 certificate from t" +
+                    "he Windows certificate store.");
+            this.cbUseWinCreds.CheckedChanged += new System.EventHandler(this.cbUseWinCreds_CheckedChanged);
+            // 
+            // cbPlaintext
+            // 
+            this.cbPlaintext.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.cbPlaintext.Location = new System.Drawing.Point(8, 104);
+            this.cbPlaintext.Name = "cbPlaintext";
+            this.cbPlaintext.Size = new System.Drawing.Size(268, 20);
+            this.cbPlaintext.TabIndex = 6;
+            this.cbPlaintext.Text = "Allow plaintext authentication";
+            this.tip.SetToolTip(this.cbPlaintext, "Allow sending plaintext passwords over non-encrypted channels.  Do not use in pro" +
+                    "duction!");
+            // 
+            // txtPass
+            // 
+            this.txtPass.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtPass.Location = new System.Drawing.Point(72, 40);
+            this.txtPass.Name = "txtPass";
+            this.txtPass.PasswordChar = '*';
+            this.txtPass.Size = new System.Drawing.Size(189, 20);
+            this.txtPass.TabIndex = 3;
+            this.tip.SetToolTip(this.txtPass, "The password for this user.  Not used if \"Use Windows credentials or a client cer" +
+                    "tificate\" is set.");
+            this.txtPass.Validated += new System.EventHandler(this.onValidated);
+            this.txtPass.Validating += new System.ComponentModel.CancelEventHandler(this.Required_Validating);
+            // 
+            // label4
+            // 
+            this.label4.Location = new System.Drawing.Point(8, 39);
+            this.label4.Name = "label4";
+            this.label4.Size = new System.Drawing.Size(64, 23);
+            this.label4.TabIndex = 2;
+            this.label4.Text = "Password:";
+            this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // label2
+            // 
+            this.label2.Location = new System.Drawing.Point(8, 71);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(48, 23);
+            this.label2.TabIndex = 4;
+            this.label2.Text = "Server:";
+            this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // label1
+            // 
+            this.label1.Location = new System.Drawing.Point(8, 7);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(48, 23);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "User:";
+            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // tpNetwork
+            // 
+            this.tpNetwork.Controls.Add(this.txtNetworkHost);
+            this.tpNetwork.Controls.Add(this.label5);
+            this.tpNetwork.Controls.Add(this.cbSSL);
+            this.tpNetwork.Controls.Add(this.numPort);
+            this.tpNetwork.Controls.Add(this.label3);
+            this.tpNetwork.Location = new System.Drawing.Point(4, 22);
+            this.tpNetwork.Name = "tpNetwork";
+            this.tpNetwork.Size = new System.Drawing.Size(284, 156);
+            this.tpNetwork.TabIndex = 2;
+            this.tpNetwork.Text = "Network";
+            // 
+            // txtNetworkHost
+            // 
+            this.txtNetworkHost.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtNetworkHost.Location = new System.Drawing.Point(88, 37);
+            this.txtNetworkHost.Name = "txtNetworkHost";
+            this.txtNetworkHost.Size = new System.Drawing.Size(184, 20);
+            this.txtNetworkHost.TabIndex = 3;
+            this.tip.SetToolTip(this.txtNetworkHost, "An alternate connect host.  If this is not specified, a DNS SRV lookup will be at" +
+                    "tempted.  If that fails, the Server will be connected to.");
+            // 
+            // label5
+            // 
+            this.label5.Location = new System.Drawing.Point(8, 36);
+            this.label5.Name = "label5";
+            this.label5.Size = new System.Drawing.Size(80, 23);
+            this.label5.TabIndex = 2;
+            this.label5.Text = "Network Host:";
+            this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // label3
+            // 
+            this.label3.Location = new System.Drawing.Point(8, 9);
+            this.label3.Name = "label3";
+            this.label3.Size = new System.Drawing.Size(80, 23);
+            this.label3.TabIndex = 0;
+            this.label3.Text = "Port:";
+            this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // tpConnection
+            // 
+            this.tpConnection.Controls.Add(this.txtURL);
+            this.tpConnection.Controls.Add(this.label12);
+            this.tpConnection.Controls.Add(this.cmbConnectionType);
+            this.tpConnection.Controls.Add(this.label11);
+            this.tpConnection.Location = new System.Drawing.Point(4, 22);
+            this.tpConnection.Name = "tpConnection";
+            this.tpConnection.Size = new System.Drawing.Size(284, 156);
+            this.tpConnection.TabIndex = 3;
+            this.tpConnection.Text = "Connection";
+            // 
+            // txtURL
+            // 
+            this.txtURL.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtURL.Enabled = false;
+            this.txtURL.Location = new System.Drawing.Point(50, 40);
+            this.txtURL.Name = "txtURL";
+            this.txtURL.Size = new System.Drawing.Size(222, 20);
+            this.txtURL.TabIndex = 3;
+            this.tip.SetToolTip(this.txtURL, "The URL to connect on for binding or polling.  TXT lookup will be done if none is" +
+                    " specified.");
+            // 
+            // label12
+            // 
+            this.label12.AutoSize = true;
+            this.label12.Location = new System.Drawing.Point(14, 43);
+            this.label12.Name = "label12";
+            this.label12.Size = new System.Drawing.Size(32, 13);
+            this.label12.TabIndex = 2;
+            this.label12.Text = "URL:";
+            // 
+            // cmbConnectionType
+            // 
+            this.cmbConnectionType.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.cmbConnectionType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.cmbConnectionType.Location = new System.Drawing.Point(50, 9);
+            this.cmbConnectionType.Name = "cmbConnectionType";
+            this.cmbConnectionType.Size = new System.Drawing.Size(222, 21);
+            this.cmbConnectionType.TabIndex = 1;
+            this.tip.SetToolTip(this.cmbConnectionType, "Prefer \"Socket\", unless your firewall won\'t allow connections.  Then try \"Binding" +
+                    "\".");
+            this.cmbConnectionType.SelectedIndexChanged += new System.EventHandler(this.cmbConnectionType_SelectedIndexChanged);
+            // 
+            // label11
+            // 
+            this.label11.AutoSize = true;
+            this.label11.Location = new System.Drawing.Point(10, 12);
+            this.label11.Name = "label11";
+            this.label11.Size = new System.Drawing.Size(34, 13);
+            this.label11.TabIndex = 0;
+            this.label11.Text = "Type:";
+            // 
+            // tpProxy
+            // 
+            this.tpProxy.Controls.Add(this.txtProxyPassword);
+            this.tpProxy.Controls.Add(this.txtProxyUser);
+            this.tpProxy.Controls.Add(this.numProxyPort);
+            this.tpProxy.Controls.Add(this.txtProxyHost);
+            this.tpProxy.Controls.Add(this.label10);
+            this.tpProxy.Controls.Add(this.label9);
+            this.tpProxy.Controls.Add(this.label8);
+            this.tpProxy.Controls.Add(this.label7);
+            this.tpProxy.Controls.Add(this.label6);
+            this.tpProxy.Controls.Add(this.cmbProxy);
+            this.tpProxy.Location = new System.Drawing.Point(4, 22);
+            this.tpProxy.Name = "tpProxy";
+            this.tpProxy.Size = new System.Drawing.Size(284, 156);
+            this.tpProxy.TabIndex = 1;
+            this.tpProxy.Text = "Proxy";
+            // 
+            // txtProxyPassword
+            // 
+            this.txtProxyPassword.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtProxyPassword.Enabled = false;
+            this.txtProxyPassword.Location = new System.Drawing.Point(72, 117);
+            this.txtProxyPassword.Name = "txtProxyPassword";
+            this.txtProxyPassword.PasswordChar = '*';
+            this.txtProxyPassword.Size = new System.Drawing.Size(200, 20);
+            this.txtProxyPassword.TabIndex = 9;
+            this.tip.SetToolTip(this.txtProxyPassword, "Proxy authentication password.");
+            // 
+            // txtProxyUser
+            // 
+            this.txtProxyUser.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtProxyUser.Enabled = false;
+            this.txtProxyUser.Location = new System.Drawing.Point(72, 90);
+            this.txtProxyUser.Name = "txtProxyUser";
+            this.txtProxyUser.Size = new System.Drawing.Size(200, 20);
+            this.txtProxyUser.TabIndex = 7;
+            this.tip.SetToolTip(this.txtProxyUser, "Proxy authentication user name.");
+            // 
+            // numProxyPort
+            // 
+            this.numProxyPort.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.numProxyPort.Enabled = false;
+            this.numProxyPort.Location = new System.Drawing.Point(72, 63);
+            this.numProxyPort.Maximum = new decimal(new int[] {
+            65535,
+            0,
+            0,
+            0});
+            this.numProxyPort.Minimum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+            this.numProxyPort.Name = "numProxyPort";
+            this.numProxyPort.Size = new System.Drawing.Size(200, 20);
+            this.numProxyPort.TabIndex = 5;
+            this.tip.SetToolTip(this.numProxyPort, "Proxy server\'s port number");
+            this.numProxyPort.Value = new decimal(new int[] {
+            1080,
+            0,
+            0,
+            0});
+            // 
+            // txtProxyHost
+            // 
+            this.txtProxyHost.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtProxyHost.Enabled = false;
+            this.txtProxyHost.Location = new System.Drawing.Point(72, 36);
+            this.txtProxyHost.Name = "txtProxyHost";
+            this.txtProxyHost.Size = new System.Drawing.Size(200, 20);
+            this.txtProxyHost.TabIndex = 3;
+            this.tip.SetToolTip(this.txtProxyHost, "Proxy server to connect to");
+            // 
+            // label10
+            // 
+            this.label10.Location = new System.Drawing.Point(8, 116);
+            this.label10.Name = "label10";
+            this.label10.Size = new System.Drawing.Size(64, 23);
+            this.label10.TabIndex = 8;
+            this.label10.Text = "Password:";
+            this.label10.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // label9
+            // 
+            this.label9.Location = new System.Drawing.Point(8, 89);
+            this.label9.Name = "label9";
+            this.label9.Size = new System.Drawing.Size(64, 23);
+            this.label9.TabIndex = 6;
+            this.label9.Text = "User:";
+            this.label9.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // label8
+            // 
+            this.label8.Location = new System.Drawing.Point(8, 62);
+            this.label8.Name = "label8";
+            this.label8.Size = new System.Drawing.Size(64, 23);
+            this.label8.TabIndex = 4;
+            this.label8.Text = "Port:";
+            this.label8.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // label7
+            // 
+            this.label7.Location = new System.Drawing.Point(8, 35);
+            this.label7.Name = "label7";
+            this.label7.Size = new System.Drawing.Size(64, 23);
+            this.label7.TabIndex = 2;
+            this.label7.Text = "Server:";
+            this.label7.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // label6
+            // 
+            this.label6.Location = new System.Drawing.Point(8, 7);
+            this.label6.Name = "label6";
+            this.label6.Size = new System.Drawing.Size(64, 23);
+            this.label6.TabIndex = 0;
+            this.label6.Text = "Type:";
+            this.label6.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // cmbProxy
+            // 
+            this.cmbProxy.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.cmbProxy.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.cmbProxy.Location = new System.Drawing.Point(72, 8);
+            this.cmbProxy.Name = "cmbProxy";
+            this.cmbProxy.Size = new System.Drawing.Size(200, 21);
+            this.cmbProxy.TabIndex = 1;
+            this.tip.SetToolTip(this.cmbProxy, "The type of proxy to use.  Prefer \"None\", if possible.");
+            this.cmbProxy.SelectedIndexChanged += new System.EventHandler(this.cmbProxy_SelectedIndexChanged);
+            // 
+            // ClientLogin
+            // 
+            this.ClientSize = new System.Drawing.Size(292, 222);
+            this.Controls.Add(this.tabControl1);
+            this.MinimizeBox = false;
+            this.Name = "ClientLogin";
+            this.Text = "Login";
+            this.Controls.SetChildIndex(this.tabControl1, 0);
+            ((System.ComponentModel.ISupportInitialize)(this.error)).EndInit();
+            ((System.ComponentModel.ISupportInitialize)(this.numPort)).EndInit();
+            this.tabControl1.ResumeLayout(false);
+            this.tpBasic.ResumeLayout(false);
+            this.tpBasic.PerformLayout();
+            this.tpNetwork.ResumeLayout(false);
+            this.tpNetwork.PerformLayout();
+            this.tpConnection.ResumeLayout(false);
+            this.tpConnection.PerformLayout();
+            this.tpProxy.ResumeLayout(false);
+            this.tpProxy.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.numProxyPort)).EndInit();
+            this.ResumeLayout(false);
+
+        }
+        #endregion
+
+
+        private void cbSSL_CheckedChanged(object sender, System.EventArgs e)
+        {
+            if (cbSSL.Checked)
+            {
+                if (numPort.Value == 5222)
+                    numPort.Value = 5223;
+            }
+            else
+            {
+                if (numPort.Value == 5223)
+                    numPort.Value = 5222;
+            }
+        }
+
+        private void cmbConnectionType_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            bool socket = (cmbConnectionType.SelectedIndex == 0);
+            bool prox = (cmbProxy.SelectedIndex != 0);
+            txtURL.Enabled = !socket;
+
+            txtNetworkHost.Enabled = socket;
+            cbSSL.Enabled = socket;
+            numPort.Enabled = socket;
+
+            txtProxyHost.Enabled = prox;
+            numProxyPort.Enabled = prox;
+            txtProxyUser.Enabled = prox;
+            txtProxyPassword.Enabled = prox;
+        }
+
+        private void cmbProxy_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            bool prox = (cmbProxy.SelectedIndex != 0);
+            txtProxyHost.Enabled = prox;
+            numProxyPort.Enabled = prox;
+            txtProxyUser.Enabled = prox;
+            txtProxyPassword.Enabled = prox;
+        }
+
+        private void Required_Validating(object sender, CancelEventArgs e)
+        {
+            this.Required(sender, e);
+        }
+
+        private void onValidated(object sender, EventArgs e)
+        {
+            this.ClearError(sender, e);
+        }
+
+        private void cbUseWinCreds_CheckedChanged(object sender, EventArgs e)
+        {
+            if (cbUseWinCreds.Checked)
+            {
+                txtUser.Clear();
+                txtPass.Clear();
+                this.ClearError(txtUser, null);
+                this.ClearError(txtPass, null);
+            }
+			txtUser.Enabled = txtPass.Enabled = !cbUseWinCreds.Checked;
+		}
+    }
+}
diff --git a/lib/jabber-net/muzzle/ComponentLogin.cs b/lib/jabber-net/muzzle/ComponentLogin.cs
new file mode 100644
index 0000000..2abe362
--- /dev/null
+++ b/lib/jabber-net/muzzle/ComponentLogin.cs
@@ -0,0 +1,277 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Windows.Forms;
+using System.Xml;
+
+using bedrock.util;
+
+using jabber.connection;
+using jabber.server;
+
+namespace muzzle
+{
+    /// <summary>
+    /// A login form for client connections.
+    /// </summary>
+    /// <example>
+    /// ComponentLogin l = new ComponentLogin(jc);
+    ///
+    /// if (l.ShowDialog(this) == DialogResult.OK)
+    /// {
+    ///     jc.Connect();
+    /// }
+    /// </example>
+    [SVN(@"$Id$")]
+    public class ComponentLogin : OptionForm
+    {
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.Label label3;
+        private System.Windows.Forms.Label label4;
+        private System.Windows.Forms.TextBox txtUser;
+        private System.Windows.Forms.TextBox txtServer;
+        private System.Windows.Forms.NumericUpDown numPort;
+        private System.Windows.Forms.TextBox txtPass;
+        private ComboBox cmbType;
+        private Label label5;
+
+        /// <summary>
+        /// Create a Client Login dialog box
+        /// </summary>
+        public ComponentLogin()
+        {
+            //
+            // Required for Windows Form Designer support
+            //
+            InitializeComponent();
+
+            for (ComponentType ct=ComponentType.Accept; ct <= ComponentType.Connect; ct++)
+            {
+                cmbType.Items.Add(ct);
+            }
+            cmbType.SelectedItem = ComponentType.Accept;
+
+            txtUser.Tag = Options.TO;
+            txtServer.Tag = Options.NETWORK_HOST;
+            numPort.Tag = Options.PORT;
+            txtPass.Tag = Options.PASSWORD;
+            cmbType.Tag = Options.COMPONENT_DIRECTION;
+        }
+
+        /// <summary>
+        /// Log in to the server
+        /// </summary>
+        /// <param name="service">The JabberClient instance to connect</param>
+        /// <param name="propertyFile">The name of an XML file to store properties in.</param>
+        /// <returns>True if the user clicked OK, false on cancel</returns>
+        public static bool Login(jabber.server.JabberService service, string propertyFile)
+        {
+            return new ComponentLogin(service).Login(propertyFile);
+        }
+
+        /// <summary>
+        /// Create a Client Login dialog box that manages a component
+        /// </summary>
+        /// <param name="service">The component to manage</param>
+        public ComponentLogin(jabber.server.JabberService service) : this()
+        {
+            this.Xmpp = service;
+        }
+
+#region Windows Form Designer generated code
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.label2 = new System.Windows.Forms.Label();
+            this.label3 = new System.Windows.Forms.Label();
+            this.txtUser = new System.Windows.Forms.TextBox();
+            this.txtServer = new System.Windows.Forms.TextBox();
+            this.numPort = new System.Windows.Forms.NumericUpDown();
+            this.txtPass = new System.Windows.Forms.TextBox();
+            this.label4 = new System.Windows.Forms.Label();
+            this.cmbType = new System.Windows.Forms.ComboBox();
+            this.label5 = new System.Windows.Forms.Label();
+            ((System.ComponentModel.ISupportInitialize)(this.error)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.numPort)).BeginInit();
+            this.SuspendLayout();
+            //
+            // label1
+            //
+            this.label1.Location = new System.Drawing.Point(8, 7);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(48, 23);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "Host:";
+            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            //
+            // label2
+            //
+            this.label2.Location = new System.Drawing.Point(8, 63);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(48, 23);
+            this.label2.TabIndex = 4;
+            this.label2.Text = "ID:";
+            this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            //
+            // label3
+            //
+            this.label3.Location = new System.Drawing.Point(8, 35);
+            this.label3.Name = "label3";
+            this.label3.Size = new System.Drawing.Size(48, 23);
+            this.label3.TabIndex = 2;
+            this.label3.Text = "Port:";
+            this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            //
+            // txtUser
+            //
+            this.txtUser.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtUser.Location = new System.Drawing.Point(56, 64);
+            this.txtUser.Name = "txtUser";
+            this.txtUser.Size = new System.Drawing.Size(220, 20);
+            this.txtUser.TabIndex = 5;
+            this.tip.SetToolTip(this.txtUser, "Service ID for this component");
+            this.txtUser.Validated += new System.EventHandler(this.onValidated);
+            this.txtUser.Validating += new System.ComponentModel.CancelEventHandler(this.Required_Validating);
+            //
+            // txtServer
+            //
+            this.txtServer.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtServer.Location = new System.Drawing.Point(56, 8);
+            this.txtServer.Name = "txtServer";
+            this.txtServer.Size = new System.Drawing.Size(220, 20);
+            this.txtServer.TabIndex = 1;
+            this.tip.SetToolTip(this.txtServer, "DNS name or IP address of router to connect to.  Not required if in Listen mode.");
+            this.txtServer.Validated += new System.EventHandler(this.onValidated);
+            this.txtServer.Validating += new System.ComponentModel.CancelEventHandler(this.Required_Validating);
+            //
+            // numPort
+            //
+            this.numPort.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.numPort.Location = new System.Drawing.Point(56, 36);
+            this.numPort.Maximum = new decimal(new int[] {
+            65535,
+            0,
+            0,
+            0});
+            this.numPort.Minimum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+            this.numPort.Name = "numPort";
+            this.numPort.Size = new System.Drawing.Size(220, 20);
+            this.numPort.TabIndex = 3;
+            this.tip.SetToolTip(this.numPort, "TCP port to connect to, or port to listen on if in Listen mode.");
+            this.numPort.Value = new decimal(new int[] {
+            7400,
+            0,
+            0,
+            0});
+            //
+            // txtPass
+            //
+            this.txtPass.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtPass.Location = new System.Drawing.Point(56, 92);
+            this.txtPass.Name = "txtPass";
+            this.txtPass.PasswordChar = '*';
+            this.txtPass.Size = new System.Drawing.Size(220, 20);
+            this.txtPass.TabIndex = 7;
+            this.tip.SetToolTip(this.txtPass, "Secret shared with router");
+            this.txtPass.Validated += new System.EventHandler(this.onValidated);
+            this.txtPass.Validating += new System.ComponentModel.CancelEventHandler(this.Required_Validating);
+            //
+            // label4
+            //
+            this.label4.Location = new System.Drawing.Point(8, 91);
+            this.label4.Name = "label4";
+            this.label4.Size = new System.Drawing.Size(48, 23);
+            this.label4.TabIndex = 6;
+            this.label4.Text = "Secret:";
+            this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            //
+            // cmbType
+            //
+            this.cmbType.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.cmbType.Location = new System.Drawing.Point(56, 118);
+            this.cmbType.Name = "cmbType";
+            this.cmbType.Size = new System.Drawing.Size(221, 21);
+            this.cmbType.TabIndex = 9;
+            //
+            // label5
+            //
+            this.label5.Location = new System.Drawing.Point(8, 116);
+            this.label5.Name = "label5";
+            this.label5.Size = new System.Drawing.Size(48, 23);
+            this.label5.TabIndex = 8;
+            this.label5.Text = "Type:";
+            this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            //
+            // ComponentLogin
+            //
+            this.ClientSize = new System.Drawing.Size(292, 266);
+            this.Controls.Add(this.label5);
+            this.Controls.Add(this.txtPass);
+            this.Controls.Add(this.cmbType);
+            this.Controls.Add(this.numPort);
+            this.Controls.Add(this.txtServer);
+            this.Controls.Add(this.txtUser);
+            this.Controls.Add(this.label4);
+            this.Controls.Add(this.label3);
+            this.Controls.Add(this.label2);
+            this.Controls.Add(this.label1);
+            this.Name = "ComponentLogin";
+            this.Text = "Connection";
+            this.Controls.SetChildIndex(this.label1, 0);
+            this.Controls.SetChildIndex(this.label2, 0);
+            this.Controls.SetChildIndex(this.label3, 0);
+            this.Controls.SetChildIndex(this.label4, 0);
+            this.Controls.SetChildIndex(this.txtUser, 0);
+            this.Controls.SetChildIndex(this.txtServer, 0);
+            this.Controls.SetChildIndex(this.numPort, 0);
+            this.Controls.SetChildIndex(this.cmbType, 0);
+            this.Controls.SetChildIndex(this.txtPass, 0);
+            this.Controls.SetChildIndex(this.label5, 0);
+            ((System.ComponentModel.ISupportInitialize)(this.error)).EndInit();
+            ((System.ComponentModel.ISupportInitialize)(this.numPort)).EndInit();
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+#endregion
+
+        private void Required_Validating(object sender, CancelEventArgs e)
+        {
+            this.Required(sender, e);
+        }
+
+        private void onValidated(object sender, EventArgs e)
+        {
+            this.ClearError(sender, e);
+        }
+    }
+}
diff --git a/lib/jabber-net/muzzle/InputBox.cs b/lib/jabber-net/muzzle/InputBox.cs
new file mode 100644
index 0000000..1bbd250
--- /dev/null
+++ b/lib/jabber-net/muzzle/InputBox.cs
@@ -0,0 +1,168 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+
+using bedrock.util;
+
+namespace muzzle
+{
+
+    /// <summary>
+    /// A generic input getter dialog.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class InputBox : Form
+    {
+        private Label label1;
+        private TextBox textBox1;
+        private Button btnOK;
+        private Button btnCancel;
+        private Panel panel1;
+
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Create
+        /// </summary>
+        public InputBox()
+        {
+            InitializeComponent();
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.textBox1 = new System.Windows.Forms.TextBox();
+            this.btnOK = new System.Windows.Forms.Button();
+            this.btnCancel = new System.Windows.Forms.Button();
+            this.panel1 = new System.Windows.Forms.Panel();
+            this.panel1.SuspendLayout();
+            this.SuspendLayout();
+            //
+            // label1
+            //
+            this.label1.AutoSize = true;
+            this.label1.Dock = System.Windows.Forms.DockStyle.Left;
+            this.label1.Location = new System.Drawing.Point(0, 0);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(35, 16);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "label1";
+            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            //
+            // textBox1
+            //
+            this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.textBox1.Location = new System.Drawing.Point(35, 0);
+            this.textBox1.Name = "textBox1";
+            this.textBox1.Size = new System.Drawing.Size(184, 20);
+            this.textBox1.TabIndex = 1;
+            //
+            // btnOK
+            //
+            this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
+            this.btnOK.Location = new System.Drawing.Point(75, 42);
+            this.btnOK.Name = "btnOK";
+            this.btnOK.Size = new System.Drawing.Size(75, 23);
+            this.btnOK.TabIndex = 1;
+            this.btnOK.Text = "OK";
+            //
+            // btnCancel
+            //
+            this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+            this.btnCancel.Location = new System.Drawing.Point(156, 42);
+            this.btnCancel.Name = "btnCancel";
+            this.btnCancel.Size = new System.Drawing.Size(75, 23);
+            this.btnCancel.TabIndex = 2;
+            this.btnCancel.Text = "Cancel";
+            //
+            // panel1
+            //
+            this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.panel1.Controls.Add(this.textBox1);
+            this.panel1.Controls.Add(this.label1);
+            this.panel1.Location = new System.Drawing.Point(12, 10);
+            this.panel1.Name = "panel1";
+            this.panel1.Size = new System.Drawing.Size(219, 26);
+            this.panel1.TabIndex = 0;
+            //
+            // InputBox
+            //
+            this.AcceptButton = this.btnOK;
+            this.CancelButton = this.btnCancel;
+            this.ClientSize = new System.Drawing.Size(243, 77);
+            this.Controls.Add(this.panel1);
+            this.Controls.Add(this.btnCancel);
+            this.Controls.Add(this.btnOK);
+            this.Name = "InputBox";
+            this.panel1.ResumeLayout(false);
+            this.panel1.PerformLayout();
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        /// <summary>
+        /// Pop up the input box with the given parameters
+        /// </summary>
+        /// <param name="title">The text of the window title</param>
+        /// <param name="prompt">Prompt value.  Include colon if desired.</param>
+        /// <param name="defaultValue">Initial value of the input box</param>
+        /// <returns></returns>
+        public DialogResult ShowDialog(string title, string prompt, string defaultValue)
+        {
+            this.Text = title;
+            label1.Text = prompt;
+            textBox1.Text = defaultValue;
+            return this.ShowDialog();
+        }
+
+        /// <summary>
+        /// The value entered by the user
+        /// </summary>
+        public string Value
+        {
+            get { return textBox1.Text; }
+            set { textBox1.Text = value; }
+        }
+    }
+}
diff --git a/lib/jabber-net/muzzle/JidMulti.cs b/lib/jabber-net/muzzle/JidMulti.cs
new file mode 100644
index 0000000..5594499
--- /dev/null
+++ b/lib/jabber-net/muzzle/JidMulti.cs
@@ -0,0 +1,226 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+
+using bedrock.util;
+
+namespace muzzle
+{
+    /// <summary>
+    /// Summary description for JidMulti.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class JidMulti : System.Windows.Forms.UserControl
+    {
+        private System.Windows.Forms.ListBox lstJID;
+        private System.Windows.Forms.ToolTip tip;
+        private System.Windows.Forms.ErrorProvider error;
+        private System.Windows.Forms.Panel panel1;
+        private System.Windows.Forms.Button btnRemove;
+        private System.Windows.Forms.Button btnAdd;
+        private System.Windows.Forms.TextBox txtEntry;
+        private System.ComponentModel.IContainer components;
+
+        /// <summary>
+        /// Create a JidMulti control
+        /// </summary>
+        public JidMulti()
+        {
+            // This call is required by the Windows.Forms Form Designer.
+            InitializeComponent();
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        protected override void Dispose( bool disposing )
+        {
+            if( disposing )
+            {
+                if(components != null)
+                {
+                    components.Dispose();
+                }
+            }
+            base.Dispose( disposing );
+        }
+
+        /// <summary>
+        /// Add a range of JIDs or strings to the list.
+        /// </summary>
+        /// <param name="range"></param>
+        public void AddRange(object[] range)
+        {
+            lstJID.Items.AddRange(range);
+        }
+
+        /// <summary>
+        /// Get the list of JIDs in the control currently.
+        /// </summary>
+        /// <returns></returns>
+        public string[] GetValues()
+        {
+            string[] vals = new string[lstJID.Items.Count];
+            for (int i=0; i < vals.Length; i++)
+            {
+                vals[i] = lstJID.Items[i].ToString();
+            }
+            return vals;
+        }
+
+        #region Component Designer generated code
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.components = new System.ComponentModel.Container();
+            this.lstJID = new System.Windows.Forms.ListBox();
+            this.tip = new System.Windows.Forms.ToolTip(this.components);
+            this.error = new System.Windows.Forms.ErrorProvider();
+            this.panel1 = new System.Windows.Forms.Panel();
+            this.btnRemove = new System.Windows.Forms.Button();
+            this.btnAdd = new System.Windows.Forms.Button();
+            this.txtEntry = new System.Windows.Forms.TextBox();
+            this.panel1.SuspendLayout();
+            this.SuspendLayout();
+            //
+            // lstJID
+            //
+            this.lstJID.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.lstJID.IntegralHeight = false;
+            this.lstJID.Location = new System.Drawing.Point(0, 32);
+            this.lstJID.Name = "lstJID";
+            this.lstJID.Size = new System.Drawing.Size(256, 88);
+            this.lstJID.Sorted = true;
+            this.lstJID.TabIndex = 0;
+            this.lstJID.SelectedIndexChanged += new System.EventHandler(this.lstJID_SelectedIndexChanged);
+            //
+            // error
+            //
+            this.error.ContainerControl = this;
+            //
+            // panel1
+            //
+            this.panel1.Controls.Add(this.btnRemove);
+            this.panel1.Controls.Add(this.btnAdd);
+            this.panel1.Controls.Add(this.txtEntry);
+            this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
+            this.panel1.Location = new System.Drawing.Point(0, 0);
+            this.panel1.Name = "panel1";
+            this.panel1.Size = new System.Drawing.Size(256, 32);
+            this.panel1.TabIndex = 4;
+            //
+            // btnRemove
+            //
+            this.btnRemove.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnRemove.Location = new System.Drawing.Point(232, 5);
+            this.btnRemove.Name = "btnRemove";
+            this.btnRemove.Size = new System.Drawing.Size(24, 23);
+            this.btnRemove.TabIndex = 6;
+            this.btnRemove.Text = "-";
+            this.tip.SetToolTip(this.btnRemove, "Remove from the list the Jabber ID on the left");
+            this.btnRemove.Click += new System.EventHandler(this.btnRemove_Click);
+            //
+            // btnAdd
+            //
+            this.btnAdd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnAdd.Location = new System.Drawing.Point(208, 5);
+            this.btnAdd.Name = "btnAdd";
+            this.btnAdd.Size = new System.Drawing.Size(24, 23);
+            this.btnAdd.TabIndex = 5;
+            this.btnAdd.Text = "+";
+            this.tip.SetToolTip(this.btnAdd, "Add to the list the Jabber ID to the left");
+            this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click);
+            //
+            // txtEntry
+            //
+            this.txtEntry.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtEntry.Location = new System.Drawing.Point(0, 6);
+            this.txtEntry.Name = "txtEntry";
+            this.txtEntry.Size = new System.Drawing.Size(184, 20);
+            this.txtEntry.TabIndex = 4;
+            this.txtEntry.Text = "";
+            this.tip.SetToolTip(this.txtEntry, "Enter a Jabber ID here, and press the + or - button to add or remove it from the " +
+                "list.");
+            //
+            // JidMulti
+            //
+            this.Controls.Add(this.lstJID);
+            this.Controls.Add(this.panel1);
+            this.Name = "JidMulti";
+            this.Size = new System.Drawing.Size(256, 120);
+            this.panel1.ResumeLayout(false);
+            this.ResumeLayout(false);
+
+        }
+        #endregion
+
+        private void btnAdd_Click(object sender, System.EventArgs e)
+        {
+            this.Cursor = Cursors.WaitCursor;
+            try
+            {
+                jabber.JID jid = new jabber.JID(txtEntry.Text);
+                lstJID.Items.Add(jid);
+                txtEntry.Clear();
+                error.SetError(txtEntry, null);
+            }
+            catch
+            {
+                error.SetError(txtEntry, "Invalid JID");
+            }
+            this.Cursor = Cursors.Default;
+        }
+
+        private void btnRemove_Click(object sender, System.EventArgs e)
+        {
+            this.Cursor = Cursors.WaitCursor;
+            try
+            {
+                jabber.JID jid = new jabber.JID(txtEntry.Text);
+                int i = 0;
+                foreach (object o in lstJID.Items)
+                {
+                    if (jid.Equals(o))
+                    {
+                        lstJID.Items.RemoveAt(i);
+                        txtEntry.Clear();
+                        error.SetError(txtEntry, null);
+                        break;
+                    }
+                    i++;
+                }
+            }
+            catch (Exception ex)
+            {
+                error.SetError(txtEntry, "Invalid JID: " + ex.ToString());
+            }
+            this.Cursor = Cursors.Default;
+        }
+
+        private void lstJID_SelectedIndexChanged(object sender, System.EventArgs e)
+        {
+            if (lstJID.SelectedIndex >= 0)
+                txtEntry.Text = lstJID.Items[lstJID.SelectedIndex].ToString();
+        }
+    }
+}
diff --git a/lib/jabber-net/muzzle/Litmus.cs b/lib/jabber-net/muzzle/Litmus.cs
new file mode 100644
index 0000000..e3edf6d
--- /dev/null
+++ b/lib/jabber-net/muzzle/Litmus.cs
@@ -0,0 +1,272 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+
+using bedrock.util;
+
+namespace muzzle
+{
+    /// <summary>
+    /// How should colors be picked?
+    /// </summary>
+    public enum LitmusColorScheme
+    {
+        /// <summary>
+        /// Just shades of blue
+        /// </summary>
+        Blue,
+        /// <summary>
+        /// More colors for non-ASCII
+        /// </summary>
+        Multicolor
+    }
+    /// <summary>
+    /// Litmus is like StripChart, but shows a graphical representation of protocol going by.
+    /// This was inspired by DW & Craig's suggestion that the next generation protocol should
+    /// just be shades of blue.
+    ///
+    /// Good gracious.  Did I really take the time to write this?
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Litmus : System.Windows.Forms.UserControl
+    {
+        private int               m_hist  = -1;
+        private int               m_max   = 0;
+        private bool              m_pause = false;
+        private Queue             m_list  = new Queue(100);
+        private LitmusColorScheme m_scheme = LitmusColorScheme.Blue;
+        private System.Windows.Forms.PictureBox pictureBox1;
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.Container components = null;
+
+        /// <summary>
+        /// Create a new Litmus object
+        /// </summary>
+        public Litmus()
+        {
+            // This call is required by the Windows.Forms Form Designer.
+            InitializeComponent();
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        protected override void Dispose( bool disposing )
+        {
+            if( disposing )
+            {
+                if(components != null)
+                {
+                    components.Dispose();
+                }
+            }
+            base.Dispose( disposing );
+        }
+        /// <summary>
+        /// Color scheme to use.
+        /// </summary>
+        [Description("Color scheme to use")]
+        [DefaultValue(LitmusColorScheme.Blue)]
+        [Category("Chart")]
+        public LitmusColorScheme ColorScheme
+        {
+            get
+            {
+                return m_scheme;
+            }
+            set
+            {
+                m_scheme = value;
+            }
+        }
+        /// <summary>
+        /// Number of points to show.  -1 means all
+        /// </summary>
+        [Description("Number of points to show.  -1 means all")]
+        [DefaultValue(-1)]
+        [Category("Chart")]
+        public int History
+        {
+            get
+            {
+                return m_hist;
+            }
+            set
+            {
+                m_hist = value;
+            }
+        }
+        /// <summary>
+        /// Don't update the display for now.  Useful for bulk loads.
+        /// </summary>
+        public bool Paused
+        {
+            get
+            {
+                return m_pause;
+            }
+            set
+            {
+                m_pause = value;
+                ReDraw();
+            }
+        }
+
+        /// <summary>
+        /// Clear all data in the window
+        /// </summary>
+        public void Clear()
+        {
+            m_list.Clear();
+            ReDraw();
+        }
+
+        /// <summary>
+        /// Add a string to the window.  Each byte will become roughly a
+        /// pixel with color based on the byte's value.
+        /// </summary>
+        /// <param name="text"></param>
+        public void AddText(string text)
+        {
+            if (m_hist != -1)
+                while (m_list.Count > m_hist)
+                    m_list.Dequeue();
+            byte[] buf = System.Text.Encoding.UTF8.GetBytes(text);
+            m_list.Enqueue(buf);
+            if (buf.Length > m_max)
+                m_max = buf.Length;
+            ReDraw();
+        }
+
+        /// <summary>
+        /// Add bytes to the window.  Each byte will become roughly a
+        /// pixel with color based on the byte's value.
+        /// </summary>
+        /// <param name="buf"></param>
+        /// <param name="offset"></param>
+        /// <param name="length"></param>
+        public void AddBytes(byte[] buf, int offset, int length)
+        {
+            if (m_hist != -1)
+                while (m_list.Count > m_hist)
+                    m_list.Dequeue();
+            byte[] copy = new byte[length];
+            Array.Copy(buf, offset, copy, 0, length);
+            m_list.Enqueue(copy);
+            if (length > m_max)
+                m_max = length;
+            ReDraw();
+        }
+        private void ReDraw()
+        {
+            if (m_pause)
+                return;
+            Bitmap bm = new Bitmap(this.Width, this.Height);
+            Graphics g = Graphics.FromImage(bm);
+            g.SmoothingMode = SmoothingMode.AntiAlias;
+            g.Clear(this.BackColor);
+            SolidBrush brush = new SolidBrush(this.ForeColor);
+            float h = this.Height;
+            float w = this.Width;
+            float stripw = w / ((float)m_list.Count - 1F);
+            float striph = h / ((float)m_max  - 1F);
+            int sc = 0;
+            int cc = 0;
+            switch (m_scheme)
+            {
+                case LitmusColorScheme.Blue:
+                    foreach (byte[] buf in m_list)
+                    {
+                        cc = 0;
+                        foreach (byte b in buf)
+                        {
+                            /*
+                            */
+                            brush.Color = Color.FromArgb(0, 0, 255 - b);
+                            g.FillRectangle(brush, sc * stripw, cc * striph, stripw, striph);
+                            cc++;
+                        }
+                        sc++;
+                    }
+                    break;
+                case LitmusColorScheme.Multicolor:
+                    foreach (byte[] buf in m_list)
+                    {
+                        cc = 0;
+                        foreach (byte b in buf)
+                        {
+                            if (b == 0)
+                                brush.Color = Color.White;
+                            else if (b < 65)
+                                brush.Color = Color.FromArgb(b * 4 - 1, 0, 0);
+                            else if (b < 128)
+                                brush.Color = Color.FromArgb(0, 0, b * 2);
+                            else
+                                brush.Color = Color.FromArgb(0, (b - 128) * 2, 0);
+                            g.FillRectangle(brush, sc * stripw, cc * striph, stripw, striph);
+                            cc++;
+                        }
+                        sc++;
+                    }
+                    break;
+            }
+            pictureBox1.Image = bm;
+        }
+        #region Component Designer generated code
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.pictureBox1 = new System.Windows.Forms.PictureBox();
+            this.SuspendLayout();
+            //
+            // pictureBox1
+            //
+            this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.pictureBox1.Name = "pictureBox1";
+            this.pictureBox1.Size = new System.Drawing.Size(150, 150);
+            this.pictureBox1.TabIndex = 0;
+            this.pictureBox1.TabStop = false;
+            //
+            // Litmus
+            //
+            this.Controls.AddRange(new System.Windows.Forms.Control[] {
+                                                                          this.pictureBox1});
+            this.Name = "Litmus";
+            this.Resize += new System.EventHandler(this.Litmus_Resize);
+            this.Load += new System.EventHandler(this.Litmus_Load);
+            this.ResumeLayout(false);
+
+        }
+        #endregion
+        private void Litmus_Load(object sender, System.EventArgs e)
+        {
+            ReDraw();
+        }
+        private void Litmus_Resize(object sender, System.EventArgs e)
+        {
+            ReDraw();
+        }
+    }
+}
diff --git a/lib/jabber-net/muzzle/OptionForm.cs b/lib/jabber-net/muzzle/OptionForm.cs
new file mode 100644
index 0000000..ba48d69
--- /dev/null
+++ b/lib/jabber-net/muzzle/OptionForm.cs
@@ -0,0 +1,501 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Xml;
+
+using bedrock.util;
+using jabber.connection;
+
+namespace muzzle
+{
+    /// <summary>
+    /// Base class for forms that configure XmppStream subclasses.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class OptionForm : Form
+    {
+        private Button btnCancel;
+        private Button btnOK;
+        private Panel panel1;
+
+        private XmppStream m_xmpp;
+        private Hashtable m_extra = new Hashtable();
+
+        /// <summary>
+        /// ToolTips.
+        /// </summary>
+        protected ToolTip tip;
+        /// <summary>
+        /// Error notifications.
+        /// </summary>
+        protected ErrorProvider error;
+        private IContainer components;
+
+        /// <summary>
+        /// Create new form
+        /// </summary>
+        protected OptionForm()
+        {
+            InitializeComponent();
+			this.AutoValidate = System.Windows.Forms.AutoValidate.Disable;
+        }
+
+        /// <summary>
+        /// Create new form.
+        /// </summary>
+        /// <param name="xmpp"></param>
+        protected OptionForm(XmppStream xmpp)
+            : this()
+        {
+            m_xmpp = xmpp;
+        }
+
+
+        /// <summary>
+        /// The client connection to manage
+        /// </summary>
+        public XmppStream Xmpp
+        {
+            get
+            {
+                // If we are running in the designer, let's try to auto-hook a JabberClient
+                if ((m_xmpp == null) && DesignMode)
+                {
+                    IDesignerHost host = (IDesignerHost)base.GetService(typeof(IDesignerHost));
+                    if (host == null)
+                        return null;
+                    m_xmpp = StreamComponent.GetStreamFromHost(host);
+                }
+                return m_xmpp;
+            }
+            set
+            {
+                m_xmpp = value;
+                if (!DesignMode)
+                    ReadXmpp();
+            }
+        }
+
+        private void WriteValues(Control parent, XmppStream stream)
+        {
+            if (parent.Tag != null)
+            {
+                stream[(string)parent.Tag] = GetControlValue(parent);
+            }
+            if (parent.HasChildren)
+            {
+                foreach (Control child in parent.Controls)
+                {
+                    WriteValues(child, stream);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Write to the XmppStream the current values.
+        /// </summary>
+        protected void WriteXmpp()
+        {
+            if (m_xmpp != null)
+                WriteValues(this, m_xmpp);
+        }
+
+        /// <summary>
+        /// Write the configuration values to the given XmppStream.
+        /// </summary>
+        /// <param name="stream">The stream to configure</param>
+        public void Configure(XmppStream stream)
+        {
+            WriteValues(this, stream);
+        }
+
+        private void WriteElem(XmlElement root, Control c)
+        {
+            if (c.Tag != null)
+            {
+                root.AppendChild(root.OwnerDocument.CreateElement((string)c.Tag)).InnerText =
+                    GetControlValue(c).ToString();
+            }
+            if (c.HasChildren)
+            {
+                foreach (Control child in c.Controls)
+                {
+                    WriteElem(root, child);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Write the current connection properties to an XML config file.
+        /// TODO: Replace this with a better ConfigFile implementation that can write.
+        /// </summary>
+        /// <param name="file"></param>
+        public void WriteToFile(string file)
+        {
+            XmlDocument doc = new XmlDocument();
+            string name = "JabberClient";
+            if (m_xmpp != null)
+                name = m_xmpp.GetType().Name;
+            XmlElement root = (XmlElement)doc.CreateElement(name);
+            doc.AppendChild(root);
+
+            WriteElem(root, this);
+
+            foreach (DictionaryEntry ent in m_extra)
+            {
+                root.AppendChild(doc.CreateElement((string)ent.Key)).InnerText = ent.Value.ToString();
+            }
+
+            XmlTextWriter xw = new XmlTextWriter(file, System.Text.Encoding.UTF8);
+            xw.Formatting = Formatting.Indented;
+            doc.WriteContentTo(xw);
+            xw.Close();
+        }
+
+        private void ReadControls(Control parent)
+        {
+            if (parent == null)
+                return;
+            if (m_xmpp == null)
+                return;
+
+            if (parent.Tag != null)
+                SetControlValue(parent, m_xmpp[(string)parent.Tag]);
+            if (parent.HasChildren)
+            {
+                foreach (Control child in parent.Controls)
+                {
+                    ReadControls(child);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Read current values from the XmppStream
+        /// </summary>
+        protected void ReadXmpp()
+        {
+            ReadControls(this);
+        }
+
+        /// <summary>
+        /// Read connection properties from the given file,
+        /// pop up the dialog to see if the user wants to change them,
+        /// save the changes, and
+        /// connect to the server.
+        /// </summary>
+        /// <param name="propertyFile">The name of the file to store connection information in.</param>
+        /// <returns>True if the user hit OK, otherwise false</returns>
+        public bool Login(string propertyFile)
+        {
+            if (this.Xmpp == null)
+                throw new ArgumentNullException("Client must be set", "Xmpp");
+            if (propertyFile != null)
+                ReadFromFile(propertyFile);
+            if (ShowDialog() != DialogResult.OK)
+                return false;
+            if (propertyFile != null)
+                WriteToFile(propertyFile);
+            this.Xmpp.Connect();
+            return true;
+        }
+
+        /// <summary>
+        /// Set the connection properties from an XML config file.
+        /// TODO: Replace this with a better ConfigFile implementation that can write.
+        /// </summary>
+        /// <param name="file"></param>
+        public void ReadFromFile(string file)
+        {
+            XmlDocument doc = new XmlDocument();
+            try
+            {
+                doc.Load(file);
+            }
+            catch (XmlException)
+            {
+                return;
+            }
+            catch (System.IO.FileNotFoundException)
+            {
+                return;
+            }
+
+            XmlElement root = doc.DocumentElement;
+            if (root == null)
+                return;
+            foreach (XmlNode node in root.ChildNodes)
+            {
+                XmlElement elem = node as XmlElement;
+                if (elem == null)
+                    continue;
+                try
+                {
+                    this[elem.Name] = elem.InnerText;
+                }
+                catch (ArgumentException)
+                {
+                    // ignored
+                }
+            }
+            WriteXmpp();
+        }
+
+        private Control FindComponentByTag(Control parent, string tag)
+        {
+            if ((string)parent.Tag == tag)
+                return parent;
+            if (parent.HasChildren)
+            {
+                foreach (Control c in parent.Controls)
+                {
+                    Control possible = FindComponentByTag(c, tag);
+                    if (possible != null)
+                        return possible;
+                }
+            }
+            return null;
+        }
+
+        private object GetControlValue(Control c)
+        {
+            if (c == null)
+                return null;
+            CheckBox chk = c as CheckBox;
+            if (chk != null)
+                return chk.Checked;
+            TextBox txt = c as TextBox;
+            if (txt != null)
+                return txt.Text;
+            ComboBox cmb = c as ComboBox;
+            if (cmb != null)
+                return cmb.SelectedItem;
+            NumericUpDown num = c as NumericUpDown;
+            if (num != null)
+                return (int)num.Value;
+            throw new ArgumentException("Control with no tag", c.Name);
+        }
+
+        private void SetControlValue(Control c, object val)
+        {
+            CheckBox chk = c as CheckBox;
+            if (chk != null)
+            {
+                if (val is bool)
+                    chk.Checked = (bool)val;
+                else if (val is string)
+                    chk.Checked = bool.Parse((string)val);
+                return;
+            }
+            TextBox txt = c as TextBox;
+            if (txt != null)
+            {
+                txt.Text = (string)val;
+                return;
+            }
+            ComboBox cmb = c as ComboBox;
+            if (cmb != null)
+            {
+                if (cmb.SelectedItem.GetType().IsAssignableFrom(val.GetType()))
+                    cmb.SelectedItem = val;
+                else if (val is string)
+                {
+                    cmb.SelectedItem = Enum.Parse(cmb.SelectedItem.GetType(), (string)val);
+                }
+                return;
+            }
+            NumericUpDown num = c as NumericUpDown;
+            if (num != null)
+            {
+                if (val is int)
+                    num.Value = (int)val;
+                else if (val is string)
+                {
+                    num.Value = int.Parse((string)val);
+                }
+
+                return;
+            }
+        }
+
+        /// <summary>
+        /// Set/Get the value of an option, as it currently exists in a control.
+        /// </summary>
+        /// <param name="option"></param>
+        /// <returns></returns>
+        public object this[string option]
+        {
+            get
+            {
+                Control c = FindComponentByTag(this, option);
+                if (c == null)
+                {
+                    if (m_extra.Contains(option))
+                        return m_extra[option];
+                    return null;
+                }
+                return GetControlValue(c);
+            }
+            set
+            {
+                Control c = FindComponentByTag(this, option);
+                if (c == null)
+                {
+                    //throw new ArgumentException("Unknown option", option);
+                    m_extra[option] = value;
+                }
+                else
+                    SetControlValue(c, value);
+            }
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.components = new System.ComponentModel.Container();
+            this.btnCancel = new System.Windows.Forms.Button();
+            this.btnOK = new System.Windows.Forms.Button();
+            this.panel1 = new System.Windows.Forms.Panel();
+            this.tip = new System.Windows.Forms.ToolTip(this.components);
+            this.error = new System.Windows.Forms.ErrorProvider(this);
+            this.panel1.SuspendLayout();
+            this.SuspendLayout();
+            //
+            // btnCancel
+            //
+            this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnCancel.CausesValidation = false;
+            this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+            this.btnCancel.Location = new System.Drawing.Point(228, 8);
+            this.btnCancel.Name = "btnCancel";
+            this.btnCancel.Size = new System.Drawing.Size(48, 23);
+            this.btnCancel.TabIndex = 1;
+            this.btnCancel.Text = "Cancel";
+            this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
+            //
+            // btnOK
+            //
+            this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnOK.Location = new System.Drawing.Point(172, 8);
+            this.btnOK.Name = "btnOK";
+            this.btnOK.Size = new System.Drawing.Size(48, 23);
+            this.btnOK.TabIndex = 0;
+            this.btnOK.Text = "OK";
+            this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
+            //
+            // panel1
+            //
+            this.panel1.CausesValidation = false;
+            this.panel1.Controls.Add(this.btnCancel);
+            this.panel1.Controls.Add(this.btnOK);
+            this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
+            this.panel1.Location = new System.Drawing.Point(0, 226);
+            this.panel1.Name = "panel1";
+            this.panel1.Size = new System.Drawing.Size(292, 40);
+            this.panel1.TabIndex = 1000;
+            //
+            // error
+            //
+            this.error.ContainerControl = this;
+            //
+            // OptionForm
+            //
+            this.AcceptButton = this.btnOK;
+            this.CancelButton = this.btnCancel;
+            this.ClientSize = new System.Drawing.Size(292, 266);
+            this.Controls.Add(this.panel1);
+            this.Name = "OptionForm";
+            this.Text = "OptionForm";
+            this.Load += new System.EventHandler(this.OptionForm_Load);
+            this.panel1.ResumeLayout(false);
+            this.ResumeLayout(false);
+
+        }
+        #endregion
+
+        /// <summary>
+        /// This field is required.
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        protected void Required(object sender, System.ComponentModel.CancelEventArgs e)
+        {
+            TextBox box = (TextBox)sender;
+            if (!box.Enabled)
+                return;
+            if ((box.Text == null) || (box.Text == ""))
+            {
+                e.Cancel = true;
+                error.SetError(box, "Required");
+            }
+        }
+
+        /// <summary>
+        /// Clear any error blinkies.
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        public void ClearError(object sender, System.EventArgs e)
+        {
+            error.SetError((Control)sender, "");
+        }
+
+        private void btnOK_Click(object sender, EventArgs e)
+        {
+            if (!this.ValidateChildren())
+                return;
+
+            WriteXmpp();
+
+            this.DialogResult = DialogResult.OK;
+            this.Close();
+        }
+
+        private void btnCancel_Click(object sender, EventArgs e)
+        {
+            this.DialogResult = DialogResult.Cancel;
+            this.Close();
+        }
+
+        private void OptionForm_Load(object sender, EventArgs e)
+        {
+            if (!DesignMode)
+                ReadXmpp();
+        }
+    }
+}
diff --git a/lib/jabber-net/muzzle/RosterTree.cs b/lib/jabber-net/muzzle/RosterTree.cs
new file mode 100644
index 0000000..4a69e36
--- /dev/null
+++ b/lib/jabber-net/muzzle/RosterTree.cs
@@ -0,0 +1,699 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Drawing;
+using System.Diagnostics;
+using System.Windows.Forms;
+
+using bedrock.collections;
+using bedrock.util;
+using jabber;
+using jabber.client;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+
+namespace muzzle
+{
+    /// <summary>
+    /// A TreeView optimized for showing Jabber roster items.  Make sure that the
+    /// form you drop this on has a JabberClient, a PresenceManager, and a RosterManager
+    /// on the form first, and this widget will automatically connect to them.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class RosterTree : System.Windows.Forms.TreeView
+    {
+        // image list offsets
+        private const int OFFLINE    = 0;
+        private const int ONLINE     = 1;
+        private const int AWAY       = 2;
+        private const int XA         = 3;
+        private const int DND        = 4;
+        private const int CHATTY     = 5;
+        private const int EXPANDED   = 6;
+        private const int COLLAPSED  = 7;
+
+        private const string UNFILED = "Unfiled";
+
+        private RosterManager   m_roster = null;
+        private PresenceManager m_pres   = null;
+        private JabberClient    m_client = null;
+
+        private IDictionary m_groups = new SkipList();
+        private IDictionary m_items  = new SkipList();
+
+        private System.Windows.Forms.ImageList il;
+        private System.Windows.Forms.ToolTip tt;
+        private Color m_statusColor = Color.Teal;
+
+        private System.ComponentModel.IContainer components;
+
+        /// <summary>
+        /// Create a new RosterTree
+        /// </summary>
+        public RosterTree()
+        {
+            // This call is required by the Windows.Forms Form Designer.
+            InitializeComponent();
+            this.ImageIndex = 1;
+            this.ImageList = il;
+            this.ShowRootLines = false;
+            this.ShowLines = false;
+            this.Sorted = true;
+
+            this.AllowDrop = true;
+            this.ItemDrag += new ItemDragEventHandler(RosterTree_ItemDrag);
+            this.DragEnter += new DragEventHandler(RosterTree_DragEnter);
+            this.DragOver += new DragEventHandler(RosterTree_DragOver);
+            this.DragDrop += new DragEventHandler(RosterTree_DragDrop);
+            this.AfterSelect += new TreeViewEventHandler(RosterTree_AfterSelect);
+            this.DrawMode = TreeViewDrawMode.OwnerDrawText;
+            this.DrawNode += new DrawTreeNodeEventHandler(RosterTree_DrawNode);
+        }
+
+        private void RosterTree_AfterSelect(object sender, TreeViewEventArgs e)
+        {
+        }
+
+        private void DrawGroup(DrawTreeNodeEventArgs e)
+        {
+            GroupNode node = (GroupNode)e.Node;
+            string counts = String.Format("({0}/{1})", node.Current, node.Total);
+
+            if (node.IsSelected)
+            {
+                string newText = node.GroupName + " " + counts;
+                e.DrawDefault = true;
+                if (node.Text != newText)
+                    node.Text = newText;
+                return;
+            }
+            Graphics g = e.Graphics;
+            Brush fg = new SolidBrush(this.ForeColor);
+            Brush stat_fg = new SolidBrush(this.StatusColor);
+
+            g.DrawString(node.GroupName, this.Font, fg, new Point(e.Bounds.Left, e.Bounds.Top), StringFormat.GenericTypographic);
+            if (node.Total > 0)
+            {
+                SizeF name_size = g.MeasureString(node.GroupName, this.Font);
+                g.DrawString(counts, this.Font, stat_fg, new PointF(e.Bounds.Left + name_size.Width, e.Bounds.Top), StringFormat.GenericTypographic);
+            }
+        }
+
+        private void DrawItem(DrawTreeNodeEventArgs e)
+        {
+            ItemNode node = (ItemNode)e.Node;
+            if (node.IsSelected)
+            {
+                e.DrawDefault = true;
+                return;
+            }
+
+            Graphics g = e.Graphics;
+            Brush fg = new SolidBrush(this.ForeColor);
+            Brush stat_fg = new SolidBrush(this.StatusColor);
+
+            g.DrawString(node.Nickname, this.Font, fg, new Point(e.Bounds.Left, e.Bounds.Top), StringFormat.GenericTypographic);
+            if (node.Status != null)
+            {
+                SizeF nick_size = g.MeasureString(node.Nickname, this.Font);
+                g.DrawString("(" + node.Status + ")", this.Font, stat_fg, new PointF(e.Bounds.Left + nick_size.Width, e.Bounds.Top), StringFormat.GenericTypographic);
+            }
+        }
+
+
+        private void RosterTree_DrawNode(object sender, DrawTreeNodeEventArgs e)
+        {
+            if (e.Node is GroupNode)
+                DrawGroup(e);
+            else if (e.Node is ItemNode)
+                DrawItem(e);
+            else
+                e.DrawDefault = true; // or assert(false)
+        }
+
+        private GroupNode GetDropGroup(DragEventArgs e)
+        {
+            if (!e.Data.GetDataPresent(typeof(ItemNode)))
+                return null;
+
+            Point pt = this.PointToClient(new Point(e.X, e.Y));
+            TreeNode node = this.GetNodeAt(pt);
+            while (!(node is GroupNode) && (node != null))
+            {
+                node = node.Parent;
+            }
+            if (node == null)
+                return null;
+
+            ItemNode item = e.Data.GetData(typeof(ItemNode)) as ItemNode;
+            if (item.Parent == node)
+                return null;
+            return (GroupNode)node;
+        }
+
+        private void RosterTree_DragDrop(object sender, DragEventArgs e)
+        {
+            GroupNode group = GetDropGroup(e);
+            if (group == null)
+                return;
+            ItemNode item = e.Data.GetData(typeof(ItemNode)) as ItemNode;
+            GroupNode parent = (GroupNode)item.Parent;
+            Item i = (Item)item.Item.CloneNode(true, m_client.Document);
+            i.RemoveGroup(parent.GroupName);
+            i.AddGroup(group.GroupName);
+            m_roster.Modify(i);
+        }
+
+
+        private void RosterTree_DragOver(object sender, DragEventArgs e)
+        {
+            if (GetDropGroup(e) == null)
+                e.Effect = DragDropEffects.None;
+            else
+                e.Effect = DragDropEffects.Move;
+        }
+
+
+        private void RosterTree_DragEnter(object sender, DragEventArgs e)
+        {
+            if (e.Data.GetDataPresent(typeof(ItemNode)))
+                e.Effect = DragDropEffects.Move;
+            else
+                e.Effect = DragDropEffects.None;
+        }
+
+        private void RosterTree_ItemDrag(object sender, ItemDragEventArgs e)
+        {
+            if (e.Item is ItemNode)
+                this.DoDragDrop(e.Item, DragDropEffects.Move);
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        protected override void Dispose( bool disposing )
+        {
+            if( disposing )
+            {
+                if(components != null)
+                {
+                    components.Dispose();
+                }
+            }
+            base.Dispose( disposing );
+        }
+
+        #region Component Designer generated code
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.components = new System.ComponentModel.Container();
+            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RosterTree));
+            this.il = new System.Windows.Forms.ImageList(this.components);
+            this.tt = new System.Windows.Forms.ToolTip(this.components);
+            this.SuspendLayout();
+            //
+            // il
+            //
+            this.il.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("il.ImageStream")));
+            this.il.TransparentColor = System.Drawing.Color.Magenta;
+            this.il.Images.SetKeyName(0, "");
+            this.il.Images.SetKeyName(1, "");
+            this.il.Images.SetKeyName(2, "");
+            this.il.Images.SetKeyName(3, "");
+            this.il.Images.SetKeyName(4, "");
+            this.il.Images.SetKeyName(5, "");
+            this.il.Images.SetKeyName(6, "");
+            this.il.Images.SetKeyName(7, "");
+            this.il.Images.SetKeyName(8, "blank");
+            this.ResumeLayout(false);
+
+        }
+        #endregion
+
+        /// <summary>
+        /// The RosterManager for this view
+        /// </summary>
+        [Category("Managers")]
+        public RosterManager RosterManager
+        {
+            get
+            {
+                // If we are running in the designer, let's try to auto-hook a RosterManager
+                if ((m_roster == null) && DesignMode)
+                {
+                    IDesignerHost host = (IDesignerHost)base.GetService(typeof(IDesignerHost));
+                    this.RosterManager = (RosterManager)jabber.connection.StreamComponent.GetComponentFromHost(host, typeof(RosterManager));
+                }
+                return m_roster;
+            }
+            set
+            {
+                if ((object)m_roster == (object)value)
+                    return;
+                m_roster = value;
+                if (m_roster != null)
+                {
+                    m_roster.OnRosterBegin += new bedrock.ObjectHandler(m_roster_OnRosterBegin);
+                    m_roster.OnRosterEnd += new bedrock.ObjectHandler(m_roster_OnRosterEnd);
+                    m_roster.OnRosterItem += new RosterItemHandler(m_roster_OnRosterItem);
+                }
+            }
+        }
+
+        /// <summary>
+        /// The PresenceManager for this view
+        /// </summary>
+        [Category("Managers")]
+        public PresenceManager PresenceManager
+        {
+            get
+            {
+                // If we are running in the designer, let's try to auto-hook a PresenceManager
+                if ((m_pres == null) && DesignMode)
+                {
+                    IDesignerHost host = (IDesignerHost) base.GetService(typeof(IDesignerHost));
+                    this.PresenceManager = (PresenceManager)jabber.connection.StreamComponent.GetComponentFromHost(host, typeof(PresenceManager));
+                }
+                return m_pres;
+            }
+            set
+            {
+                if ((object)m_pres == (object)value)
+                    return;
+                m_pres = value;
+                if (m_pres != null)
+                    m_pres.OnPrimarySessionChange += new PrimarySessionHandler(m_pres_OnPrimarySessionChange);
+            }
+        }
+
+        /// <summary>
+        /// The PresenceManager for this view
+        /// </summary>
+        [Category("Managers")]
+        public JabberClient Client
+        {
+            get
+            {
+                // If we are running in the designer, let's try to auto-hook a JabberClient
+                if ((m_client == null) && DesignMode)
+                {
+                    IDesignerHost host = (IDesignerHost) base.GetService(typeof(IDesignerHost));
+                    this.Client = (JabberClient)jabber.connection.StreamComponent.GetComponentFromHost(host, typeof(JabberClient));
+                }
+                return m_client;
+            }
+            set
+            {
+                if ((object)m_client == (object)value)
+                    return;
+                m_client = value;
+                if (m_client != null)
+                    m_client.OnDisconnect += new bedrock.ObjectHandler(m_client_OnDisconnect);
+            }
+        }
+
+        /// <summary>
+        /// Color to draw status text with.  Not applicable until .Net 2.0.
+        /// </summary>
+        [Category("Appearance")]
+        public Color StatusColor
+        {
+            get { return m_statusColor; }
+            set { m_statusColor = value; }
+        }
+
+        /// <summary>
+        /// Should we draw status text next to each roster item?  Not applicable until .Net 2.0.
+        /// </summary>
+        [Category("Appearance")]
+        [DefaultValue(true)]
+        public bool DrawStatus
+        {
+            get
+            {
+                return (this.DrawMode == TreeViewDrawMode.OwnerDrawText);
+            }
+            set
+            {
+                if (value)
+                    this.DrawMode = TreeViewDrawMode.OwnerDrawText;
+                else
+                    this.DrawMode = TreeViewDrawMode.Normal;
+            }
+        }
+
+        /// <summary>
+        /// The group names for the roster
+        /// </summary>
+        public string[] Groups
+        {
+            get
+            {
+                string[] g = new string[m_groups.Count];
+                m_groups.Keys.CopyTo(g, 0);
+                return g;
+            }
+        }
+
+        /// <summary>
+        /// Add a new, empty group, if this group doesn't exist, otherwise a no-op.
+        /// </summary>
+        /// <param name="groupName"></param>
+        public TreeNode AddGroup(string groupName)
+        {
+            Group g = new Group(m_client.Document);
+            g.GroupName = groupName;
+            return AddGroupNode(g);
+        }
+
+        private void m_roster_OnRosterBegin(object sender)
+        {
+            this.BeginUpdate();
+        }
+
+        private void m_roster_OnRosterEnd(object sender)
+        {
+            this.EndUpdate();
+        }
+
+        /// <summary>
+        /// After a group node is expanded, change to the down-triangle image.
+        /// </summary>
+        /// <param name="e"></param>
+        protected override void OnAfterExpand(TreeViewEventArgs e)
+        {
+            e.Node.ImageIndex = EXPANDED;
+            e.Node.SelectedImageIndex = EXPANDED;
+
+            base.OnAfterExpand (e);
+        }
+
+        /// <summary>
+        /// After a group node is collapsed, change to the right-triangle image.
+        /// </summary>
+        /// <param name="e"></param>
+        protected override void OnAfterCollapse(TreeViewEventArgs e)
+        {
+            e.Node.ImageIndex = COLLAPSED;
+            e.Node.SelectedImageIndex = COLLAPSED;
+
+            base.OnAfterCollapse (e);
+        }
+
+        /// <summary>
+        /// When mousing over a node, show a tooltip with the full JID.
+        /// </summary>
+        /// <param name="e"></param>
+        protected override void OnMouseMove(MouseEventArgs e)
+        {
+            base.OnMouseMove(e);
+            ItemNode node = this.GetNodeAt(e.X, e.Y) as ItemNode;
+            if (node == null)
+            { // none selected, or a group
+                tt.SetToolTip(this, "");
+                return;
+            }
+            if (node.JID.ToString() != tt.GetToolTip(this))
+            {
+                tt.SetToolTip(this, node.JID.ToString());
+            }
+        }
+
+        private GroupNode AddGroupNode(Group g)
+        {
+            GroupNode gn = (GroupNode)m_groups[g.GroupName];
+            if (gn == null)
+            {
+                gn = new GroupNode(g);
+                m_groups.Add(g.GroupName, gn);
+                this.Nodes.Add(gn);
+            }
+            return gn;
+        }
+
+        private void m_roster_OnRosterItem(object sender, jabber.protocol.iq.Item ri)
+        {
+            bool remove = (ri.Subscription == Subscription.remove);
+
+            LinkedList nodelist = (LinkedList)m_items[ri.JID.ToString()];
+            if (nodelist == null)
+            {
+                // First time through.
+                if (!remove)
+                {
+                    nodelist = new LinkedList();
+                    m_items.Add(ri.JID.ToString(), nodelist);
+                }
+            }
+            else
+            {
+                // update to an existing item.  remove all of them, and start over.
+                foreach (ItemNode i in nodelist)
+                {
+                    GroupNode gn = i.Parent as GroupNode;
+                    i.Remove();
+                    if ((gn != null) && (gn.Nodes.Count == 0))
+                    {
+                        m_groups.Remove(gn.GroupName);
+                        gn.Remove();
+                    }
+                }
+                nodelist.Clear();
+                if (remove)
+                    m_items.Remove(ri.JID.ToString());
+            }
+
+            if (remove)
+                return;
+
+            // add the new ones back
+            Hashtable ghash = new Hashtable();
+            Group[] groups = ri.GetGroups();
+            for (int i=groups.Length-1; i>=0; i--)
+            {
+                if (groups[i].GroupName == "")
+                    groups[i].GroupName = UNFILED;
+            }
+
+            if (groups.Length == 0)
+            {
+                groups = new Group[] { new Group(ri.OwnerDocument) };
+                groups[0].GroupName = UNFILED;
+            }
+
+            foreach (Group g in groups)
+            {
+                GroupNode gn = AddGroupNode(g);
+                // might have the same group twice.
+                if (ghash.Contains(g.GroupName))
+                    continue;
+                ghash.Add(g.GroupName, g);
+
+                ItemNode i = new ItemNode(ri);
+                i.ChangePresence(m_pres[ri.JID]);
+                nodelist.Add(i);
+                gn.Nodes.Add(i);
+            }
+        }
+
+        private void m_client_OnDisconnect(object sender)
+        {
+            this.Nodes.Clear();
+            m_groups.Clear();
+            m_items.Clear();
+        }
+
+
+        private void m_pres_OnPrimarySessionChange(object sender, JID bare)
+        {
+            Presence pres = m_pres[bare];
+            LinkedList nodelist = (LinkedList) m_items[bare.ToString()];
+            if (nodelist == null)
+                return;
+
+            foreach (ItemNode n in nodelist)
+            {
+                n.ChangePresence(pres);
+            }
+        }
+
+
+        /// <summary>
+        /// A TreeNode to hold a Roster Group
+        /// </summary>
+        [SVN(@"$Id$")]
+        public class GroupNode : TreeNode
+        {
+            private jabber.protocol.iq.Group m_group;
+
+            /// <summary>
+            /// Create a GroupNode
+            /// </summary>
+            /// <param name="rg"></param>
+            public GroupNode(jabber.protocol.iq.Group rg) : base(rg.GroupName, COLLAPSED, COLLAPSED)
+            {
+                m_group = rg;
+            }
+
+            /// <summary>
+            /// The name of the group
+            /// </summary>
+            public string GroupName
+            {
+                get { return m_group.GroupName; }
+            }
+
+            /// <summary>
+            /// Total number of members of the group
+            /// </summary>
+            public int Total
+            {
+                // TODO: what if we're not showing offline?
+                get { return this.Nodes.Count; }
+            }
+
+            /// <summary>
+            /// Current number of online members of the group
+            /// </summary>
+            public int Current
+            {
+                get
+                {
+                    int count = 0;
+                    foreach (ItemNode i in this.Nodes)
+                    {
+                        if (i.ImageIndex != OFFLINE)
+                            count++;
+                    }
+                    return count;
+                }
+            }
+        }
+
+        /// <summary>
+        /// A TreeNode to hold a RosterItem
+        /// </summary>
+        [SVN(@"$Id$")]
+        public class ItemNode : TreeNode
+        {
+            private jabber.protocol.iq.Item m_item;
+            private string m_status = null;
+            private string m_nick = null;
+
+            /// <summary>
+            /// Create an ItemNode
+            /// </summary>
+            /// <param name="ri">The roster item to create from</param>
+            public ItemNode(jabber.protocol.iq.Item ri)
+            {
+                m_item = ri;
+                m_nick = ri.Nickname;
+                if ((m_nick == null) || (m_nick == ""))
+                {
+                    m_nick = ri.JID.User;
+                    if ((m_nick == null) || (m_nick == ""))
+                        m_nick = ri.JID.ToString(); // punt.
+                }
+                this.Text = m_nick;
+            }
+
+            /// <summary>
+            /// The JID of this Roster Item
+            /// </summary>
+            public JID JID
+            {
+                get { return m_item.JID; }
+            }
+
+            /// <summary>
+            /// Roster nickname for this user.
+            /// </summary>
+            public string Nickname
+            {
+                get { return m_nick; }
+            }
+
+            /// <summary>
+            /// Last presence status for this item
+            /// </summary>
+            public string Status
+            {
+                get { return m_status; }
+            }
+
+            /// <summary>
+            /// The roster item.  Please make a clone before using it.
+            /// </summary>
+            public Item Item
+            {
+                get { return m_item; }
+            }
+
+            /// <summary>
+            /// Update this roster item with new presence information
+            /// </summary>
+            /// <param name="p"></param>
+            public void ChangePresence(Presence p)
+            {
+                SelectedImageIndex = ImageIndex = getPresenceImage(p);
+
+                string txt = null;
+                if ((p == null) || (p.Status == null) || (p.Status == ""))
+                {
+                    txt = m_nick;
+                    m_status = null;
+                }
+                else
+                {
+                    m_status = p.Status;
+                    txt = m_nick + " (" + m_status + ")";
+                }
+                if (Text != txt)
+                    Text = txt;
+            }
+
+            private static int getPresenceImage(Presence p)
+            {
+                if ((p == null) || (p.Type == PresenceType.unavailable))
+                    return OFFLINE;
+
+                switch (p.Show)
+                {
+                    case null:
+                    case "":
+                        return ONLINE;
+                    case "away":
+                        return AWAY;
+                    case "xa":
+                        return XA;
+                    case "dnd":
+                        return DND;
+                    case "chat":
+                        return CHATTY;
+                }
+
+                return OFFLINE;
+            }
+        }
+
+    }
+}
diff --git a/lib/jabber-net/muzzle/StreamControl.cs b/lib/jabber-net/muzzle/StreamControl.cs
new file mode 100644
index 0000000..63cc8ec
--- /dev/null
+++ b/lib/jabber-net/muzzle/StreamControl.cs
@@ -0,0 +1,111 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Text;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Xml;
+
+using bedrock.util;
+using jabber;
+using jabber.connection;
+using jabber.protocol.client;
+
+namespace muzzle
+{
+    /// <summary>
+    /// A UserControl that references an XmppStream.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class StreamControl : System.Windows.Forms.UserControl
+    {
+        /// <summary>
+        /// The XmppStream for this control.  Set at design time when a subclass control is dragged onto a form.
+        /// </summary>
+        protected XmppStream m_stream = null;
+
+        /// <summary>
+        /// The XmppStream was changed.  Often at design time.  The object will be this StreamControl.
+        /// </summary>
+        public event bedrock.ObjectHandler OnStreamChanged;
+
+        /// <summary>
+        /// The JabberClient or JabberService to hook up to.
+        /// </summary>
+        [Description("The JabberClient or JabberService to hook up to.")]
+        [Category("Jabber")]
+        public virtual XmppStream Stream
+        {
+            get
+            {
+                // If we are running in the designer, let's try to get an XmppStream control
+                // from the environment.
+                if ((this.m_stream == null) && DesignMode)
+                {
+                    IDesignerHost host = (IDesignerHost)base.GetService(typeof(IDesignerHost));
+                    this.Stream = StreamComponent.GetStreamFromHost(host);
+                }
+                return m_stream;
+            }
+            set
+            {
+                if ((object)m_stream != (object)value)
+                {
+                    m_stream = value;
+                    if (OnStreamChanged != null)
+                        OnStreamChanged(this);
+                }
+            }
+        }
+
+        private JID m_overrideFrom = null;
+
+        /// <summary>
+        /// Override the from address that will be stamped on outbound packets.
+        /// Unless your server implemets XEP-193, you shouldn't use this for 
+        /// client connections.
+        /// </summary>
+        public JID OverrideFrom
+        {
+            get { return m_overrideFrom; }
+            set { m_overrideFrom = value; }
+        }
+
+        /// <summary>
+        /// Write the specified stanza to the stream.
+        /// </summary>
+        /// <param name="elem"></param>
+        public void Write(XmlElement elem)
+        {
+            if ((m_overrideFrom != null) && (elem.GetAttribute("from") == ""))
+                elem.SetAttribute("from", m_overrideFrom);
+            m_stream.Write(elem);
+        }
+
+        ///<summary>
+        /// Does an asynchronous IQ call.
+        /// If the from address hasn't been set, and an OverrideFrom has been set,
+        /// the from address will be set to the value of OverrideFrom.
+        ///</summary>
+        ///<param name="iq">IQ packet to send.</param>
+        ///<param name="cb">Callback to execute when the result comes back.</param>
+        ///<param name="cbArg">Arguments to pass to the callback.</param>
+        public void BeginIQ(IQ iq, IqCB cb, object cbArg)
+        {
+            if ((m_overrideFrom != null) && (iq.From == null))
+                iq.From = m_overrideFrom;
+            m_stream.Tracker.BeginIQ(iq, cb, cbArg);
+        }
+    }
+}
diff --git a/lib/jabber-net/muzzle/StripChart.cs b/lib/jabber-net/muzzle/StripChart.cs
new file mode 100644
index 0000000..baa0539
--- /dev/null
+++ b/lib/jabber-net/muzzle/StripChart.cs
@@ -0,0 +1,755 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Drawing.Drawing2D;
+using System.Drawing.Imaging;
+using System.Diagnostics;
+using System.Threading;
+
+using bedrock.util;
+
+namespace muzzle
+{
+    /// <summary>
+    /// How should the chart be rendered?
+    /// </summary>
+    public enum ChartStyle
+    {
+        /// <summary>
+        /// Bar char
+        /// </summary>
+        Bar,
+        /// <summary>
+        /// Lines
+        /// </summary>
+        Line,
+        /// <summary>
+        /// Points
+        /// </summary>
+        Point
+    }
+
+    // TODO: Add vertical scrolling as an option.
+    /// <summary>
+    /// A StripChart is a scrolling window showing a set number of data points.
+    /// As new points are added, old points get shifted along.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class StripChart : System.Windows.Forms.UserControl
+    {
+        private bool       m_first     = true;
+        private float      m_min       = 0F;
+        private float      m_max       = 100F;
+        private float      m_last      = 0F;
+        private double     m_mean      = 0F;
+        private double     m_var_s     = 0F;
+        private long       m_count     = 0;
+
+        private int        m_hist      = 100;
+        private int        m_pointSize = 5;
+        private bool       m_auto      = true;
+        private bool       m_label     = true;
+        private bool       m_zero      = true;
+        private bool       m_showLast  = false;
+        private bool       m_showStats = false;
+        private string     m_title     = null;
+        private Queue      m_list      = new Queue(100);
+        private ChartStyle m_style     = ChartStyle.Bar;
+        private Color      m_textColor = Color.Red;
+        private Color      m_zeroColor = Color.Black;
+        private Color      m_statsColor = Color.Wheat;
+        private System.Windows.Forms.PictureBox pictureBox1;
+
+        private static float[] s_sampleData = new float[] {
+            .9800F,
+            .7572F,
+            .8259F,
+            .3314F,
+            .6175F,
+            .9606F,
+            .7810F,
+            .7958F,
+            .4636F,
+            .0264F };
+
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.Container components = null;
+
+        /// <summary>
+        /// Create a stripchart.
+        /// </summary>
+        public StripChart()
+        {
+            // This call is required by the Windows.Forms Form Designer.
+            InitializeComponent();
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        protected override void Dispose( bool disposing )
+        {
+            if( disposing )
+            {
+                if( components != null )
+                    components.Dispose();
+            }
+            base.Dispose( disposing );
+        }
+
+        /// <summary>
+        /// Display the last value sent to the chart, in the upper right.
+        /// </summary>
+        [Description("Display the last value sent to the chart, in the upper right.")]
+        [DefaultValue(false)]
+        [Category("Chart")]
+        public bool ShowLastValue
+        {
+            get { return m_showLast; }
+            set
+            {
+                if (m_showLast != value)
+                {
+                    m_showLast = value;
+                    DesignReDraw();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Display the mean and standard deviation, graphically.
+        /// </summary>
+        [Description("Display the mean and standard deviation, graphically.")]
+        [DefaultValue(false)]
+        [Category("Chart")]
+        public bool ShowStatistics
+        {
+            get { return m_showStats; }
+            set
+            {
+                if (m_showStats != value)
+                {
+                    m_showStats = value;
+                    DesignReDraw();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Title to display in the chart.  Null for none.
+        /// </summary>
+        [Description("Title to display in the chart.  Null for none.")]
+        [DefaultValue(null)]
+        [Category("Chart")]
+        public string Title
+        {
+            get { return m_title; }
+            set
+            {
+                if (m_title != value)
+                {
+                    m_title = value;
+                    DesignReDraw();
+                }
+            }
+        }
+
+        /// <summary>
+        /// The size of points, when in point style.  Ignored otherwise.
+        /// </summary>
+        [Description("The size of points, when in point style.  Ignored otherwise.")]
+        [DefaultValue(5)]
+        [Category("Chart")]
+        public int PointSize
+        {
+            get
+            {
+                return m_pointSize;
+            }
+            set
+            {
+                if (m_pointSize != value)
+                {
+                    m_pointSize = value;
+                    DesignReDraw();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Chart drawing style.
+        /// </summary>
+        [Description("Chart drawing style")]
+        [DefaultValue(ChartStyle.Bar)]
+        [Category("Chart")]
+        public ChartStyle Style
+        {
+            get
+            {
+                return m_style;
+            }
+            set
+            {
+                if (m_style != value)
+                {
+                    m_style = value;
+                    DesignReDraw();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Initial minimum value shown
+        /// </summary>
+        [Description("Initial minimum value shown")]
+        [DefaultValue(0F)]
+        [Category("Chart")]
+        public float Min
+        {
+            get
+            {
+                return m_min;
+            }
+            set
+            {
+                if (m_min != value)
+                {
+                    m_min = value;
+                    DesignReDraw();
+                }
+            }
+        }
+        /// <summary>
+        /// Initial maximum value shown
+        /// </summary>
+        [Description("Initial maximum value shown")]
+        [DefaultValue(100F)]
+        [Category("Chart")]
+        public float Max
+        {
+            get
+            {
+                return m_max;
+            }
+            set
+            {
+                if (m_max != value)
+                {
+                    m_max = value;
+                    DesignReDraw();
+                }
+            }
+        }
+        /// <summary>
+        /// Reset min and max as necessary to show all points.
+        /// This must be set before adding any points.
+        /// </summary>
+        [Description("Reset min and max as necessary to show all points.  " +
+             "This must be set before adding any points.")]
+        [DefaultValue(true)]
+        [Category("Chart")]
+        public bool AutoScale
+        {
+            get
+            {
+                return m_auto;
+            }
+            set
+            {
+                m_auto = value;
+            }
+        }
+
+        /// <summary>
+        /// Draw labels with min and max of chart.  Useful with AutoSize set to true.
+        /// </summary>
+        [Description("Draw labels with min and max of chart.  Useful with AutoSize set to true.")]
+        [DefaultValue(true)]
+        [Category("Chart")]
+        public bool Labels
+        {
+            get
+            {
+                return m_label;
+            }
+            set
+            {
+                if (m_label != value)
+                {
+                    m_label = value;
+                    DesignReDraw();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Draw a line at zero?
+        /// </summary>
+        [Description("Draw a line at zero?")]
+        [DefaultValue(true)]
+        [Category("Chart")]
+        public bool ZeroLine
+        {
+            get
+            {
+                return m_zero;
+            }
+            set
+            {
+                if (m_zero != value)
+                {
+                    m_zero = value;
+                    DesignReDraw();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Number of points to show
+        /// </summary>
+        [Description("Number of points to show")]
+        [DefaultValue(100)]
+        [Category("Chart")]
+        public int History
+        {
+            get
+            {
+                return m_hist;
+            }
+            set
+            {
+                if (m_hist != value)
+                {
+                    m_hist = value;
+                    lock (m_list)
+                    {
+                        while (m_list.Count > m_hist)
+                            m_list.Dequeue();
+                    }
+                    DesignReDraw();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Color to draw the min/max value in, if Labels is true
+        /// </summary>
+        [Description("Color to draw the min/max value in, if Labels is true")]
+        [DefaultValue("Red")]
+        [Category("Appearance")]
+        public Color TextColor
+        {
+            get
+            {
+                return m_textColor;
+            }
+            set
+            {
+                if (m_textColor != value)
+                {
+                    m_textColor = value;
+                    DesignReDraw();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Color to draw zero line in, if ZeroLine is true
+        /// </summary>
+        [Description("Color to draw zero line in, if ZeroLine is true")]
+        [DefaultValue("Black")]
+        [Category("Appearance")]
+        public Color ZeroColor
+        {
+            get
+            {
+                return m_zeroColor;
+            }
+            set
+            {
+                if (m_zeroColor != value)
+                {
+                    m_zeroColor = value;
+                    DesignReDraw();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Color to draw the min/max value in, if Labels is true
+        /// </summary>
+        [Description("Color to draw the standard deviation range in, if ShowStats is true")]
+        [DefaultValue("Wheat")]
+        [Category("Appearance")]
+        public Color StatsColor
+        {
+            get
+            {
+                return m_statsColor;
+            }
+            set
+            {
+                if (m_statsColor != value)
+                {
+                    m_statsColor = value;
+                    DesignReDraw();
+                }
+            }
+        }
+
+
+        /// <summary>
+        /// Foreground color
+        /// </summary>
+        public override Color ForeColor
+        {
+            get
+            {
+                return base.ForeColor;
+            }
+            set
+            {
+                if (base.ForeColor != value)
+                {
+                    base.ForeColor = value;
+                    DesignReDraw();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Background color
+        /// </summary>
+        public override Color BackColor
+        {
+            get
+            {
+                return base.BackColor;
+            }
+            set
+            {
+                if (base.BackColor != value)
+                {
+                    base.BackColor = value;
+                    pictureBox1.BackColor = value;
+                    DesignReDraw();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Add a point to the strip chart.  If more than the history size are already
+        /// in the chart, extras are dropped.
+        /// </summary>
+        /// <param name="val">The value to add</param>
+        public void AddPoint(float val)
+        {
+            lock (m_list)
+            {
+                while (m_list.Count >= m_hist)
+                    m_list.Dequeue();
+                m_list.Enqueue(val);
+            }
+            m_last = val;
+            if (m_auto)
+            {
+                if (val > m_max)
+                    m_max = val;
+                if (val < m_min)
+                    m_min = val;
+            }
+
+            if (m_showStats)
+            {
+                // See:  http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Algorithm_III
+                m_count++;
+                double delta = val - m_mean;
+                m_mean += delta / (double)m_count;
+                m_var_s += delta * (val - m_mean);
+            }
+            if (!DesignMode)
+                ReDraw();
+        }
+
+        /// <summary>
+        /// The last value inserted into the chart.
+        /// </summary>
+        [Browsable(false)]
+        public float Last
+        {
+            get { return m_last; }
+        }
+
+        /// <summary>
+        /// Clear all of the points from the chart
+        /// </summary>
+        public void Clear()
+        {
+            lock(m_list)
+                m_list.Clear();
+            ReDraw();
+        }
+
+        /// <summary>
+        /// Save the current image to the specified filename.
+        /// </summary>
+        /// <param name="filename"></param>
+        public void SaveTo(string filename)
+        {
+            pictureBox1.Image = ReDrawNoInvoke();
+            pictureBox1.Image.Save(filename);
+        }
+
+        private void DesignReDraw()
+        {
+            if (!DesignMode)
+                return;
+            lock (m_list)
+            {
+                bool cleanup = false;
+                double mean = m_mean;
+                double var_s = m_var_s;
+                if (m_list.Count == 0)
+                {
+                    cleanup = true;
+                    foreach (float x in s_sampleData)
+                        AddPoint(m_min + (x * (m_max - m_min)));
+                }
+                ExecReDraw();
+                if (cleanup)
+                {
+                    m_list.Clear();
+                    m_mean = mean;
+                    m_var_s = var_s;
+                }
+            }
+        }
+
+        private void ReDraw()
+        {
+            if (DesignMode)
+                ExecReDraw();
+            else
+            {
+                Thread t = new Thread(new ThreadStart(ExecReDraw));
+                t.IsBackground = true;
+                t.Start();
+            }
+        }
+
+        private delegate void BMCB(Bitmap bm);
+
+        private void BitBlt(Bitmap bm)
+        {
+            pictureBox1.Image = bm;
+        }
+
+        private Bitmap ReDrawNoInvoke()
+        {
+            Font font = this.Font;
+            int fh = font.Height + 2;
+
+            if ((this.Width == 0) || (this.Height == 0)) return null;
+
+            float    h  = this.Height - (2*fh);
+            float    w  = this.Width;
+            float    s  = m_max - m_min;
+            if (s <= float.Epsilon)
+                return null;
+
+            if ((this.Height <= 0) || (this.Width <= 0))
+                return null;
+
+            Bitmap   bm = new Bitmap(this.Width, this.Height);
+            Graphics g  = Graphics.FromImage(bm);
+            g.SmoothingMode     = SmoothingMode.AntiAlias;
+            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
+            g.Clear(BackColor);
+            lock (m_list)
+            {
+                if (m_list.Count > 0)
+                {
+                    float stripw = w / ((float)m_hist - 1F);
+                    Debug.Assert(s != 0);
+                    float y   = 0F;
+                    int count = 0;
+
+                    // this is kinda ugly, because of the repeated code.
+                    // But it's better, perf-wise, than repeating the switch statement
+                    // every time through the loop.
+                    switch (m_style)
+                    {
+                    case ChartStyle.Bar:
+                        RectangleF[] rects = new RectangleF[m_list.Count];
+                        foreach (float val in m_list)
+                        {
+                            y = h * (1 - (val - m_min) / s) + fh;
+                            rects[count] = new RectangleF(count * stripw, y, stripw, h - y);
+                            count++;
+                        }
+                        g.FillRectangles(new SolidBrush(ForeColor), rects);
+                        break;
+                    case ChartStyle.Point:
+                        Brush brush = new SolidBrush(ForeColor);
+                        float p2 = fh - (m_pointSize / 2F);
+                        foreach (float val in m_list)
+                        {
+                            y = h * (1 - (val - m_min) / s) + p2;
+                            g.FillEllipse(brush, count * stripw, y, m_pointSize, m_pointSize);
+                            count++;
+                        }
+                        break;
+                    case ChartStyle.Line:
+                        if (m_list.Count > 1)
+                        {
+                            PointF[] points = new PointF[m_list.Count];
+                            foreach (float val in m_list)
+                            {
+                                y = h * (1 - (val - m_min) / s) + fh;
+                                points[count] = new PointF(count * stripw, y);
+                                count++;
+                            }
+                            g.DrawLines(new Pen(ForeColor), points);
+                        }
+                        break;
+                    }
+                }
+            }
+            Brush textBrush = new SolidBrush(m_textColor);
+
+            if (m_zero)
+            {
+                float y = h * (1 + m_min / s) + fh;
+                g.DrawLine(new Pen(m_zeroColor, 1F), 0, y, w, y);
+            }
+            if (m_showStats)
+            {
+                float y = (float)(h * (1 - (m_mean - m_min) / s) + fh);
+                Color stats_color = Color.FromArgb(120, m_zeroColor);
+                Pen stats_pen = new Pen(stats_color, 1.0F);
+                stats_pen.DashStyle = DashStyle.Dash;
+                g.DrawLine(stats_pen, 0, y, w, y);
+                if (m_count > 1)
+                {
+                    stats_pen.DashStyle = DashStyle.Dot;
+                    double stddev = Math.Sqrt(m_var_s / (m_count - 1));
+                    y = (float)(h * (1 - (m_mean + stddev - m_min) / s) + fh);
+                    g.DrawLine(stats_pen, 0, y, w, y);
+                    y = (float)(h * (1 - (m_mean - stddev - m_min) / s) + fh);
+                    g.DrawLine(stats_pen, 0, y, w, y);
+
+                    Brush b = new SolidBrush(Color.FromArgb(120, m_statsColor));
+                    float std = (float)(2.0F * h * (stddev / s));
+                    g.FillRectangle(b, 0, y - std, w, std);
+                }
+            }
+            if (m_label)
+            {
+                g.DrawString(m_min.ToString(), font, textBrush, 2, h + fh);
+                g.DrawString(m_max.ToString(), font, textBrush, 2, 2);
+            }
+            if (m_showLast)
+            {
+                string last = m_last.ToString();
+                float fw = g.MeasureString(last, font).Width + 2;
+                g.DrawString(last, font, textBrush, (w - fw), 2);
+            }
+            if (m_title != null)
+            {
+                float fw = g.MeasureString(m_title, font).Width;
+                g.DrawString(m_title, font, textBrush, (w - fw)/2F, 2);
+            }
+            return bm;
+        }
+
+        private void ExecReDraw()
+        {
+            Bitmap bm = ReDrawNoInvoke();
+            if (bm == null)
+                return;
+
+            if (this.IsHandleCreated)
+            {
+                if (this.InvokeRequired)
+                    Invoke(new BMCB(BitBlt), new object[] { bm });
+                else
+                    BitBlt(bm);
+            }
+        }
+
+        #region Component Designer generated code
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.pictureBox1 = new System.Windows.Forms.PictureBox();
+            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
+            this.SuspendLayout();
+            //
+            // pictureBox1
+            //
+            this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.pictureBox1.Location = new System.Drawing.Point(0, 0);
+            this.pictureBox1.Name = "pictureBox1";
+            this.pictureBox1.Size = new System.Drawing.Size(150, 150);
+            this.pictureBox1.TabIndex = 0;
+            this.pictureBox1.TabStop = false;
+            this.pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
+            //
+            // StripChart
+            //
+            this.Controls.Add(this.pictureBox1);
+            this.Name = "StripChart";
+            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
+            this.ResumeLayout(false);
+
+        }
+        #endregion
+
+        /// <summary>
+        /// The control has been resized.  Redraw.
+        /// </summary>
+        /// <param name="e"></param>
+        protected override void OnResize(System.EventArgs e)
+        {
+            base.OnResize(e);
+            ReDraw();
+        }
+        /// <summary>
+        /// Control has been loaded.  Redraw.
+        /// </summary>
+        /// <param name="e"></param>
+        protected override void OnLoad(System.EventArgs e)
+        {
+            ReDraw();
+        }
+
+        private void pictureBox1_Paint(object sender, PaintEventArgs e)
+        {
+            if (!m_first)
+                return;
+            m_first = false;
+            ReDraw();
+        }
+    }
+}
diff --git a/lib/jabber-net/muzzle/XDataForm.cs b/lib/jabber-net/muzzle/XDataForm.cs
new file mode 100644
index 0000000..1103200
--- /dev/null
+++ b/lib/jabber-net/muzzle/XDataForm.cs
@@ -0,0 +1,715 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Drawing;
+using System.Collections;
+using System.ComponentModel;
+using System.Windows.Forms;
+using System.Text.RegularExpressions;
+using System.Xml;
+
+using bedrock.util;
+
+using jabber.protocol;
+using jabber.protocol.x;
+using jabber.protocol.client;
+using Msg = jabber.protocol.client.Message;
+using System.Diagnostics;
+
+namespace muzzle
+{
+    /// <summary>
+    /// Summary description for XData.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class XDataForm : System.Windows.Forms.Form
+    {
+        private static Regex WS = new Regex("\\s+", RegexOptions.Compiled);
+
+        private Packet      m_stanza = null;
+        private Element     m_parent = null;
+        private FormField[] m_fields = null;
+        private XDataType   m_type;
+
+        private System.Windows.Forms.Panel panel1;
+        private System.Windows.Forms.Button btnCancel;
+        private System.Windows.Forms.Button btnOK;
+        private System.Windows.Forms.Label lblInstructions;
+        private System.Windows.Forms.Panel pnlFields;
+        private System.Windows.Forms.ErrorProvider error;
+        private System.Windows.Forms.ToolTip tip;
+        private System.Windows.Forms.Panel panel2;
+        private System.Windows.Forms.Panel panel3;
+        private System.ComponentModel.IContainer components;
+
+        /// <summary>
+        /// Create an x:data form with no contents.
+        /// </summary>
+        public XDataForm()
+        {
+            //
+            // Required for Windows Form Designer support
+            //
+            InitializeComponent();
+        }
+
+        /// <summary>
+        /// Create an x:data form from the given message stanza.
+        /// </summary>
+        /// <param name="parent">Original stanza</param>
+        public XDataForm(jabber.protocol.client.Message parent) : this(FindData(parent) as jabber.protocol.x.Data)
+        {
+            m_stanza = (Packet) parent.CloneNode(true);
+            Data d = FindData(m_stanza);
+            Debug.Assert(d != null);
+            m_parent = (Element)d.ParentNode;
+            m_parent.RemoveChild(d);
+        }
+
+        /// <summary>
+        /// Create an x:data form from the given iq stanza.
+        /// </summary>
+        /// <param name="parent">Original stanza</param>
+        public XDataForm(jabber.protocol.client.IQ parent) : this(FindData(parent))
+        {
+            m_stanza = (Packet) parent.CloneNode(true);
+            Data d = FindData(m_stanza);
+            m_parent = (Element)d.ParentNode;
+            m_parent.RemoveChild(d);
+        }
+
+        private static jabber.protocol.x.Data FindData(Element el)
+        {
+            if (el is Data)
+                return (Data)el;
+            foreach (Element c in el.GetElements<Element>())
+            {
+                Data d = FindData(c);
+                if (d != null)
+                    return d;
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// Create an x:data form from the given XML form description
+        /// </summary>
+        /// <param name="x">x:data form to render</param>
+        public XDataForm(jabber.protocol.x.Data x) : this()
+        {
+            if (x == null)
+                throw new ArgumentException("x:data form must not be null", "x");
+
+            m_type = x.Type;
+
+            this.SuspendLayout();
+            if (x.Title != null)
+                this.Text = x.Title;
+            if (m_type == XDataType.cancel)
+            {
+                lblInstructions.Text = "Form canceled.";  // TODO: Localize!
+                lblInstructions.Resize += new EventHandler(lblInstructions_Resize);
+                lblInstructions_Resize(lblInstructions, null);
+            }
+            else if (x.Instructions == null)
+                lblInstructions.Visible = false;
+            else
+            {
+                lblInstructions.Text = DeWhitespace(x.Instructions);
+                lblInstructions.Resize += new EventHandler(lblInstructions_Resize);
+                lblInstructions_Resize(lblInstructions, null);
+            }
+
+            pnlFields.SuspendLayout();
+            Field[] fields = x.GetFields();
+            m_fields = new FormField[fields.Length];
+            for (int i=fields.Length-1; i>=0; i--)
+            {
+                m_fields[i] = new FormField(fields[i], this, i);
+            }
+
+            panel1.TabIndex = fields.Length;
+
+            if (m_type != XDataType.form)
+            {
+                btnOK.Location = btnCancel.Location;
+                btnCancel.Visible = false;
+            }
+
+            pnlFields.ResumeLayout(true);
+            this.ResumeLayout(true);
+
+            for (int i=0; i<fields.Length; i++)
+            {
+                if ((fields[i].Type != FieldType.hidden) &&
+                    (fields[i].Type != FieldType.Fixed))
+                    m_fields[i].Focus();
+            }
+        }
+
+        private string DeWhitespace(string input)
+        {
+            return WS.Replace(input, " ");
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        protected override void Dispose( bool disposing )
+        {
+            if( disposing )
+            {
+                if(components != null)
+                {
+                    components.Dispose();
+                }
+            }
+            base.Dispose( disposing );
+        }
+
+        #region Windows Form Designer generated code
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.components = new System.ComponentModel.Container();
+            this.panel1 = new System.Windows.Forms.Panel();
+            this.panel2 = new System.Windows.Forms.Panel();
+            this.btnCancel = new System.Windows.Forms.Button();
+            this.btnOK = new System.Windows.Forms.Button();
+            this.lblInstructions = new System.Windows.Forms.Label();
+            this.pnlFields = new System.Windows.Forms.Panel();
+            this.error = new System.Windows.Forms.ErrorProvider();
+            this.tip = new System.Windows.Forms.ToolTip(this.components);
+            this.panel3 = new System.Windows.Forms.Panel();
+            this.panel1.SuspendLayout();
+            this.SuspendLayout();
+            //
+            // panel1
+            //
+            this.panel1.CausesValidation = false;
+            this.panel1.Controls.Add(this.panel2);
+            this.panel1.Controls.Add(this.btnCancel);
+            this.panel1.Controls.Add(this.btnOK);
+            this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
+            this.panel1.Location = new System.Drawing.Point(0, 232);
+            this.panel1.Name = "panel1";
+            this.panel1.Size = new System.Drawing.Size(292, 34);
+            this.panel1.TabIndex = 2;
+            //
+            // panel2
+            //
+            this.panel2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
+            this.panel2.Dock = System.Windows.Forms.DockStyle.Top;
+            this.panel2.Location = new System.Drawing.Point(0, 0);
+            this.panel2.Name = "panel2";
+            this.panel2.Size = new System.Drawing.Size(292, 4);
+            this.panel2.TabIndex = 2;
+            //
+            // btnCancel
+            //
+            this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnCancel.CausesValidation = false;
+            this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+            this.btnCancel.Location = new System.Drawing.Point(212, 7);
+            this.btnCancel.Name = "btnCancel";
+            this.btnCancel.TabIndex = 1;
+            this.btnCancel.Text = "Cancel";
+            //
+            // btnOK
+            //
+            this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnOK.Location = new System.Drawing.Point(132, 7);
+            this.btnOK.Name = "btnOK";
+            this.btnOK.TabIndex = 0;
+            this.btnOK.Text = "OK";
+            this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
+            //
+            // lblInstructions
+            //
+            this.lblInstructions.BackColor = System.Drawing.SystemColors.Control;
+            this.lblInstructions.Dock = System.Windows.Forms.DockStyle.Top;
+            this.lblInstructions.ForeColor = System.Drawing.SystemColors.HotTrack;
+            this.lblInstructions.Location = new System.Drawing.Point(0, 0);
+            this.lblInstructions.Name = "lblInstructions";
+            this.lblInstructions.Size = new System.Drawing.Size(292, 16);
+            this.lblInstructions.TabIndex = 1;
+            //
+            // pnlFields
+            //
+            this.pnlFields.AutoScroll = true;
+            this.pnlFields.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.pnlFields.DockPadding.Bottom = 3;
+            this.pnlFields.DockPadding.Left = 6;
+            this.pnlFields.DockPadding.Right = 6;
+            this.pnlFields.DockPadding.Top = 3;
+            this.pnlFields.Location = new System.Drawing.Point(0, 20);
+            this.pnlFields.Name = "pnlFields";
+            this.pnlFields.Size = new System.Drawing.Size(292, 212);
+            this.pnlFields.TabIndex = 0;
+            //
+            // error
+            //
+            this.error.ContainerControl = this;
+            //
+            // panel3
+            //
+            this.panel3.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
+            this.panel3.Dock = System.Windows.Forms.DockStyle.Top;
+            this.panel3.Location = new System.Drawing.Point(0, 16);
+            this.panel3.Name = "panel3";
+            this.panel3.Size = new System.Drawing.Size(292, 4);
+            this.panel3.TabIndex = 3;
+            //
+            // XDataForm
+            //
+            this.AcceptButton = this.btnOK;
+            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
+            this.CancelButton = this.btnCancel;
+            this.ClientSize = new System.Drawing.Size(292, 266);
+            this.ControlBox = false;
+            this.Controls.Add(this.pnlFields);
+            this.Controls.Add(this.panel3);
+            this.Controls.Add(this.panel1);
+            this.Controls.Add(this.lblInstructions);
+            this.HelpButton = true;
+            this.Name = "XDataForm";
+            this.Text = "XData Form";
+            this.panel1.ResumeLayout(false);
+            this.ResumeLayout(false);
+
+        }
+        #endregion
+
+        private void btnOK_Click(object sender, System.EventArgs e)
+        {
+            for (int i=0; i<m_fields.Length; i++)
+            {
+                if (!m_fields[i].Validate())
+                {
+                    m_fields[i].Focus();
+                    return;
+                }
+            }
+            this.DialogResult = DialogResult.OK;
+        }
+
+        private void lblInstructions_Resize(object sender, EventArgs e)
+        {
+            Graphics graphics = lblInstructions.CreateGraphics();
+            SizeF s = lblInstructions.Size;
+            s.Height = 0;
+            SizeF textSize = graphics.MeasureString(lblInstructions.Text, lblInstructions.Font, s);
+            lblInstructions.Height = (int) (textSize.Height) + 2;
+        }
+
+        /// <summary>
+        /// Get a response to the original stanza that caused this form to be popped up.
+        /// </summary>
+        /// <returns>A stanza ready to be sent back to the originator.</returns>
+        public Packet GetResponse()
+        {
+            if (m_stanza == null)
+                throw new ArgumentException("parent was null", "parent");
+            if (m_type != XDataType.form)
+                throw new InvalidOperationException("Can only generate a submit response for x:data of type 'form'");
+
+            m_stanza.Swap();
+
+            Data x = new Data(m_stanza.OwnerDocument);
+            m_parent.AppendChild(x);
+            if (m_stanza is IQ)
+                m_stanza.SetAttribute("type", "set");
+
+            if (this.DialogResult == DialogResult.Cancel)
+            {
+                x.Type = XDataType.cancel;
+                return m_stanza;
+            }
+
+            x.Type = XDataType.submit;
+            foreach (FormField f in m_fields)
+            {
+                f.AppendField(x);
+            }
+
+            return m_stanza;
+        }
+
+        /// <summary>
+        /// Modify the given x:data element to contain the response data.
+        /// </summary>
+        /// <param name="x"></param>
+        public void FillInResponse(Data x)
+        {
+            x.RemoveAll();
+            x.Type = XDataType.result;
+            foreach (FormField f in m_fields)
+            {
+                f.AppendField(x);
+            }
+        }
+
+        private class FormField
+        {
+            private FieldType m_type;
+            private string m_var;
+            private string[] m_val;
+            private XDataForm m_form;
+            private bool m_required = false;
+            private Control m_control = null;
+            private Label m_label = null;
+            private Field m_field;
+
+            public FormField(Field f, XDataForm form, int tabIndex)
+            {
+                m_field = f;
+                m_type = f.Type;
+                m_var = f.Var;
+                m_val = f.Vals;
+                m_required = f.IsRequired;
+                m_form = form;
+
+                Panel p = null;
+                if (m_type != FieldType.hidden)
+                {
+                    p = new Panel();
+                    p.Parent = m_form.pnlFields;
+                    p.TabIndex = tabIndex;
+                }
+
+                switch (m_type)
+                {
+                    case FieldType.hidden:
+                        break;
+                    case FieldType.boolean:
+                        CheckBox cb = new CheckBox();
+                        cb.Checked = f.BoolVal;
+                        cb.Text = null;
+                        m_control = cb;
+                        break;
+                    case FieldType.text_multi:
+                        TextBox mtxt = new TextBox();
+                        mtxt.Multiline = true;
+                        mtxt.ScrollBars = ScrollBars.Vertical;
+                        mtxt.Lines = m_val;
+                        mtxt.Height = m_form.btnOK.Height * 3;
+                        m_control = mtxt;
+                        break;
+                    case FieldType.text_private:
+                        TextBox ptxt = new TextBox();
+                        ptxt.Lines = m_val;
+                        ptxt.PasswordChar = '*';
+                        m_control = ptxt;
+                        break;
+                    case FieldType.list_single:
+                        ComboBox box = new ComboBox();
+                        box.DropDownStyle = ComboBoxStyle.DropDownList;
+                        box.BeginUpdate();
+                        string v = null;
+                        if (m_val.Length > 0)
+                            v = m_val[0];
+                        foreach (Option o in f.GetOptions())
+                        {
+                            int i = box.Items.Add(o);
+
+                            if (o.Val == v)
+                            {
+                                box.SelectedIndex = i;
+                            }
+                        }
+                        box.EndUpdate();
+                        m_control = box;
+                        break;
+
+                    case FieldType.list_multi:
+                        //ListBox lb = new ListBox();
+                        CheckedListBox lb = new CheckedListBox();
+                        //lb.SelectionMode = SelectionMode.MultiExtended;
+                        lb.VisibleChanged += new EventHandler(lb_VisibleChanged);
+                        m_control = lb;
+                        break;
+
+                    case FieldType.jid_single:
+                        TextBox jtxt = new TextBox();
+                        jtxt.Lines = m_val;
+                        jtxt.Validating += new CancelEventHandler(jid_Validating);
+                        jtxt.Validated += new EventHandler(jid_Validated);
+                        m_control = jtxt;
+                        m_form.error.SetIconAlignment(m_control, ErrorIconAlignment.MiddleLeft);
+                        break;
+
+                    case FieldType.jid_multi:
+                        JidMulti multi = new JidMulti();
+                        multi.AddRange(m_val);
+                        m_control = multi;
+                        break;
+
+                    case FieldType.Fixed:
+                        // All of this so that we can detect URLs.
+                        // We can't just make it disabled, because then the URL clicked
+                        // event handler doesn't fire, and there's no way to set the
+                        // text foreground color.
+                        // It would be cool to make copy work, but it doesn't work for
+                        // labels, either.
+                        RichTextBox rich = new RichTextBox();
+                        rich.DetectUrls = true;
+                        rich.Text = string.Join("\r\n", f.Vals);
+                        rich.ScrollBars = RichTextBoxScrollBars.None;
+                        rich.Resize += new EventHandler(lbl_Resize);
+                        rich.BorderStyle = BorderStyle.None;
+                        rich.LinkClicked += new LinkClickedEventHandler(rich_LinkClicked);
+                        rich.BackColor = System.Drawing.SystemColors.Control;
+                        rich.KeyPress += new KeyPressEventHandler(rich_KeyPress);
+                        rich.GotFocus += new EventHandler(rich_GotFocus);
+                        rich.AcceptsTab = false;
+                        rich.AutoSize = false;
+                        m_control = rich;
+                        break;
+                    default:
+                        TextBox txt = new TextBox();
+                        txt.Lines = m_val;
+                        m_control = txt;
+                        break;
+                }
+
+                if (m_type != FieldType.hidden)
+                {
+                    m_control.Parent = p;
+
+                    if (f.Desc != null)
+                        form.tip.SetToolTip(m_control, f.Desc);
+
+                    String lblText = "";
+
+                    if (f.Label != "")
+                        lblText = f.Label + ":";
+                    else if (f.Var != "")
+                        lblText = f.Var + ":";
+
+                    if (lblText != "")
+                    {
+                        m_label = new Label();
+                        m_label.Parent = p;
+                        m_label.Text = lblText;
+
+                        if (m_required)
+                        {
+                            m_label.Text = "* " + m_label.Text;
+                            m_form.error.SetIconAlignment(m_control, ErrorIconAlignment.MiddleLeft);
+
+                            m_control.Validating += new CancelEventHandler(m_control_Validating);
+                            m_control.Validated += new EventHandler(m_control_Validated);
+                        }
+                        Graphics graphics = m_label.CreateGraphics();
+                        SizeF s = m_label.Size;
+                        s.Height = 0;
+                        int chars;
+                        int lines;
+                        SizeF textSize = graphics.MeasureString(m_label.Text, m_label.Font, s, StringFormat.GenericDefault, out chars, out lines);
+                        m_label.Height = (int) (textSize.Height);
+
+                        if (lines > 1)
+                            m_label.TextAlign = ContentAlignment.MiddleLeft;
+                        else
+                            m_label.TextAlign = ContentAlignment.TopLeft;
+
+                        m_label.Top = 0;
+                        p.Controls.Add(m_label);
+                        m_control.Location = new Point(m_label.Width + 3, 0);
+                        m_control.Width = p.Width - m_label.Width - 6;
+                        p.Height = Math.Max(m_label.Height, m_control.Height) + 4;
+                    }
+                    else
+                    {
+                        m_control.Location = new Point(0, 0);
+                        m_control.Width = p.Width - 6;
+                        p.Height = m_control.Height + 4;
+                    }
+                    m_control.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+                    p.Controls.Add(m_control);
+                    p.Dock = DockStyle.Top;
+                    m_form.pnlFields.Controls.Add(p);
+
+                    if (m_form.m_type != XDataType.form)
+                        m_control.Enabled = false;
+                }
+            }
+
+            public void Focus()
+            {
+                if (m_control != null)
+                    m_control.Focus();
+            }
+
+            public string[] Value
+            {
+                get
+                {
+                    if (m_control == null)
+                        return m_val;
+                    if (m_control is TextBox)
+                        return ((TextBox)m_control).Lines;
+                    if (m_control is CheckBox)
+                        return new string[] { ((CheckBox)m_control).Checked ? "1" : "0" };
+                    if (m_control is ComboBox)
+                    {
+                        Option o = (Option)((ComboBox) m_control).SelectedItem;
+                        if (o == null) return new string[] {};
+                        return new string[] { o.Val };
+                    }
+
+                    return null;
+                }
+            }
+
+            public bool Validate()
+            {
+                if (m_control == null)
+                    return true;
+                if (!m_required)
+                    return true;
+
+                if ((Value == null) || (Value.Length == 0))
+                {
+                    m_form.error.SetError(m_control, "Required");
+                    return false;
+                }
+
+                return true;
+            }
+
+            private void m_control_Validating(object sender, CancelEventArgs e)
+            {
+                if (!Validate())
+                    e.Cancel = true;
+            }
+
+            private void m_control_Validated(object sender, EventArgs e)
+            {
+                m_form.error.SetError(m_control, "");
+            }
+
+            private void jid_Validated(object sender, EventArgs e)
+            {
+                m_form.error.SetError(m_control, "");
+            }
+
+            private void lbl_Resize(object sender, EventArgs e)
+            {
+                RichTextBox lbl = (RichTextBox) sender;
+
+                Graphics graphics = lbl.CreateGraphics();
+                SizeF s = lbl.Size;
+                s.Height = 0;
+                SizeF textSize = graphics.MeasureString(lbl.Text, lbl.Font, s);
+                lbl.Height = (int) (textSize.Height) + 4;
+                if (e != null)
+                {
+                    lbl.Parent.Height = Math.Max(lbl.Height, m_control.Height) + 4;
+                }
+            }
+
+            private void lb_VisibleChanged(object sender, EventArgs e)
+            {
+                // HACK: Oh.  My.  God.
+                // This was found through trial and error, and I'm NOT happy with it.
+                // The deal is that there is a bug in the MS implementation of ListBox, such
+                // that if you call SetSelected before the underlying window has been created,
+                // the SetSelected call gets ignored.
+
+                // So, what we do here is wait for VisibleChanged events...  this is the only event
+                // I could find that always fires after the Handle is set.  But, it also fires before
+                // the handle is set, and several times so quickly in succession that the remove
+                // event handler code below can happen while there is an event still in the queue.
+                // Apparently that message that is already in the queue fires this callback again,
+                // even though it's been removed.
+                CheckedListBox lb = (CheckedListBox) sender;
+                if (lb.Handle == IntPtr.Zero)
+                    return;
+
+                if (lb.Items.Count > 0)
+                    return;
+
+                lb.VisibleChanged -= new EventHandler(lb_VisibleChanged);
+
+                lb.BeginUpdate();
+                foreach (Option o in m_field.GetOptions())
+                {
+                    int i = lb.Items.Add(o);
+                    if (m_field.IsValSet(o.Val))
+                        //lb.SetSelected(i, true);
+                        lb.SetItemChecked(i, true);
+                }
+                lb.EndUpdate();
+
+            }
+
+            private void jid_Validating(object sender, CancelEventArgs e)
+            {
+                TextBox jtxt = (TextBox) sender;
+                if (jtxt.Text == "")
+                    return;
+
+                try
+                {
+                    jabber.JID j = new jabber.JID(jtxt.Text);
+                }
+                catch
+                {
+                    e.Cancel = true;
+                    m_form.error.SetError(jtxt, "Invalid JID");
+                }
+            }
+
+            public void AppendField(Data x)
+            {
+                String[] vals = this.Value;
+                if ((vals != null) && (vals.Length > 0))
+                {
+                    Field f = x.AddField(m_var, m_type, null, null, null);
+                    foreach (String v in vals)
+                    {
+                        f.AddValue(v);
+                    }
+                }
+            }
+
+            private void rich_LinkClicked(object sender, LinkClickedEventArgs e)
+            {
+                System.Diagnostics.Process.Start(e.LinkText);
+            }
+
+            private void rich_KeyPress(object sender, KeyPressEventArgs e)
+            {
+                e.Handled = true;
+            }
+
+            private void rich_GotFocus(object sender, EventArgs e)
+            {
+                // gyrate, trying to prevent focus from ever landing on the
+                // richtext box.
+                RichTextBox rich = (RichTextBox) sender;
+                Control nxt = m_form.GetNextControl(rich, true);
+                while ((nxt != null) && (nxt != rich) && ((!nxt.CanFocus) || (nxt is Panel)))
+                    nxt = m_form.GetNextControl(nxt, true);
+                if ((nxt != null) && (nxt != rich))
+                    nxt.Focus();
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/muzzle/XmppDebugger.cs b/lib/jabber-net/muzzle/XmppDebugger.cs
new file mode 100644
index 0000000..658f306
--- /dev/null
+++ b/lib/jabber-net/muzzle/XmppDebugger.cs
@@ -0,0 +1,390 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Diagnostics;
+using System.Windows.Forms;
+using System.Xml;
+
+using bedrock.util;
+
+namespace muzzle
+{
+    /// <summary>
+    /// Debug stream for XMPP, so I don't have write it every time.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class XmppDebugger : StreamControl
+    {
+        private RichTextBox rtSend;
+        private Splitter splitter1;
+        private BottomScrollRichText rtDebug;
+
+        private Color m_sendColor = Color.Blue;
+        private Color m_recvColor = Color.Orange;
+        private Color m_errColor = Color.Red;
+        private Color m_otherColor = Color.Green;
+        private string m_send = "SEND:";
+        private string m_recv = "RECV:";
+        private string m_err = "ERROR:";
+        private string m_last = "";
+
+
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Create
+        /// </summary>
+        public XmppDebugger()
+        {
+            InitializeComponent();
+            this.OnStreamChanged += new bedrock.ObjectHandler(XmppDebugger_OnStreamChanged);
+        }
+
+        /// <summary>
+        /// What color to use for the "SEND:" string.
+        /// </summary>
+        [Category("Appearance")]
+        public Color SendColor
+        {
+            get { return m_sendColor; }
+            set { m_sendColor = value; }
+        }
+
+        /// <summary>
+        /// What color to use for the "RECV:" string.
+        /// </summary>
+        [Category("Appearance")]
+        public Color ReceiveColor
+        {
+            get { return m_recvColor; }
+            set { m_recvColor = value; }
+        }
+
+        /// <summary>
+        /// What color to use for the "ERROR:" string.
+        /// </summary>
+        [Category("Appearance")]
+        public Color ErrorColor
+        {
+            get { return m_errColor; }
+            set { m_errColor = value; }
+        }
+
+        /// <summary>
+        /// What color to use for the sent and received text.
+        /// </summary>
+        [Category("Appearance")]
+        public Color TextColor
+        {
+            get { return rtDebug.ForeColor; }
+            set { rtDebug.ForeColor = value; }
+        }
+
+        /// <summary>
+        /// What color to use for other text inserted
+        /// </summary>
+        [Category("Appearance")]
+        public Color OtherColor
+        {
+            get { return m_otherColor; }
+            set { m_otherColor = value; }
+        }
+
+        /// <summary>
+        /// Maximum number of lines to keep
+        /// </summary>
+        [Category("Appearance")]
+        [DefaultValue(500)]
+        public int MaxLines
+        {
+            get { return rtDebug.MaxLines; }
+            set { rtDebug.MaxLines = value; }
+        }
+
+        /// <summary>
+        /// The string to prefix on sent bytes.
+        /// </summary>
+        [Category("Text")]
+        [DefaultValue("SEND:")]
+        public string SendPrefix
+        {
+            get { return m_send; }
+            set { m_send = value; }
+        }
+
+        /// <summary>
+        /// The string to prefix on sent bytes.
+        /// </summary>
+        [Category("Text")]
+        [DefaultValue("RECV:")]
+        public string ReceivePrefix
+        {
+            get { return m_recv; }
+            set { m_recv = value; }
+        }
+
+        /// <summary>
+        /// The string to prefix on errors.
+        /// </summary>
+        [Category("Text")]
+        [DefaultValue("ERROR:")]
+        public string ErrorPrefix
+        {
+            get { return m_err; }
+            set { m_err = value; }
+        }
+
+        private void XmppDebugger_OnStreamChanged(object sender)
+        {
+            if (m_stream == null)
+                return;
+
+            m_stream.OnConnect += new jabber.connection.StanzaStreamHandler(m_stream_OnConnect);
+            m_stream.OnReadText += new bedrock.TextHandler(m_stream_OnReadText);
+            m_stream.OnWriteText += new bedrock.TextHandler(m_stream_OnWriteText);
+            m_stream.OnError += new bedrock.ExceptionHandler(m_stream_OnError);
+        }
+
+        private void Write(Color color, string tag, string text)
+        {
+            Debug.WriteLine(tag + " " + text);
+            rtDebug.AppendMaybeScroll(color, tag, text);
+        }
+
+        /// <summary>
+        /// Write an error to the log.
+        /// </summary>
+        /// <param name="error"></param>
+        public void WriteError(string error)
+        {
+            Write(m_errColor, m_err, error);
+        }
+
+        private void m_stream_OnError(object sender, Exception ex)
+        {
+            WriteError(ex.ToString());
+        }
+
+        private void m_stream_OnConnect(object sender, jabber.connection.StanzaStream stream)
+        {
+            // I think this is right.  Double check.
+            rtDebug.Clear();
+        }
+
+        private void m_stream_OnReadText(object sender, string txt)
+        {
+            // keepalive
+            if (txt == " ")
+                return;
+
+            Write(m_recvColor, m_recv, txt);
+        }
+
+        private void m_stream_OnWriteText(object sender, string txt)
+        {
+            // keepalive
+            if (txt == " ")
+                return;
+
+            Write(m_sendColor, m_send, txt);
+        }
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        /// <summary>
+        /// Clear both text boxes
+        /// </summary>
+        public void Clear()
+        {
+            rtDebug.Clear();
+            rtSend.Clear();
+        }
+
+        /// <summary>
+        /// Write other text to the debug log
+        /// </summary>
+        /// <param name="tag">The tag to prefix with</param>
+        /// <param name="text">The text after the tag</param>
+        public void Write(string tag, string text)
+        {
+            Write(m_otherColor, tag, text);
+        }
+
+        private XmlElement ValidateXML()
+        {
+            try
+            {
+                XmlDocument doc = new XmlDocument();
+                doc.LoadXml(rtSend.Text);
+                XmlElement elem = doc.DocumentElement;
+                if (elem != null)
+                {
+                    return elem;
+                }
+            }
+            catch (XmlException ex)
+            {
+                int offset = ex.LinePosition;
+                for (int i=0; (i<ex.LineNumber-1) && (i < rtSend.Lines.Length); i++)
+                {
+                    offset += rtSend.Lines[i].Length + 2;
+                }
+                rtSend.Select(offset, 1);
+            }
+            return null;
+        }
+
+        private void ValidateAndSend()
+        {
+            XmlElement elem = ValidateXML();
+            if (elem != null)
+            {
+                Write(elem);
+                rtSend.Clear();
+            }
+        }
+
+        private void rtSend_KeyUp(object sender, KeyEventArgs e)
+        {
+            if ((e.KeyCode == Keys.Enter) && e.Control)
+            {
+                ValidateAndSend();
+            }
+            else if ((e.KeyCode == Keys.Delete) && e.Control)
+            {
+                Clear();
+            }
+        }
+
+        private void Search(string txt)
+        {
+            string t = (txt == null) ? m_last : txt;
+            if (t == "")
+                return;
+            m_last = t;
+            int start = rtDebug.SelectionStart + 1;
+            if ((start < 0) || (start > rtDebug.Text.Length))
+                start = 0;
+            int offset = rtDebug.Text.IndexOf(t, start);
+            if (offset < 0)
+            {
+                Console.Beep();
+                offset = 0;
+            }
+            rtDebug.Select(offset, t.Length);
+            rtDebug.ScrollToCaret();
+        }
+
+        private void rtDebug_KeyUp(object sender, KeyEventArgs e)
+        {
+            if ((e.KeyCode == Keys.Delete) && e.Control)
+            {
+                Clear();
+            }
+            else if ((e.KeyCode == Keys.F) && e.Control)
+            {
+                InputBox inp = new InputBox();
+                if (inp.ShowDialog("Find text", "Find:", "") != DialogResult.OK)
+                    return;
+                Search(inp.Value);
+            }
+            else if (e.KeyCode == Keys.F3)
+            {
+                Search(null);
+            }
+        }
+
+        private void XmppDebugger_KeyUp(object sender, KeyEventArgs e)
+        {
+            if ((e.KeyCode == Keys.Delete) && e.Control)
+            {
+                Clear();
+            }
+        }
+
+        #region Component Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.rtSend = new System.Windows.Forms.RichTextBox();
+            this.splitter1 = new System.Windows.Forms.Splitter();
+            this.rtDebug = new muzzle.BottomScrollRichText();
+            this.SuspendLayout();
+            //
+            // rtSend
+            //
+            this.rtSend.Dock = System.Windows.Forms.DockStyle.Bottom;
+            this.rtSend.Location = new System.Drawing.Point(0, 110);
+            this.rtSend.Name = "rtSend";
+            this.rtSend.Size = new System.Drawing.Size(150, 40);
+            this.rtSend.TabIndex = 0;
+            this.rtSend.Text = "";
+            this.rtSend.KeyUp += new System.Windows.Forms.KeyEventHandler(this.rtSend_KeyUp);
+            //
+            // splitter1
+            //
+            this.splitter1.Dock = System.Windows.Forms.DockStyle.Bottom;
+            this.splitter1.Location = new System.Drawing.Point(0, 107);
+            this.splitter1.Name = "splitter1";
+            this.splitter1.Size = new System.Drawing.Size(150, 3);
+            this.splitter1.TabIndex = 1;
+            this.splitter1.TabStop = false;
+            //
+            // rtDebug
+            //
+            this.rtDebug.BackColor = System.Drawing.SystemColors.Window;
+            this.rtDebug.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.rtDebug.Location = new System.Drawing.Point(0, 0);
+            this.rtDebug.Name = "rtDebug";
+            this.rtDebug.ReadOnly = true;
+            this.rtDebug.Size = new System.Drawing.Size(150, 107);
+            this.rtDebug.TabIndex = 2;
+            this.rtDebug.Text = "";
+            this.rtDebug.KeyUp += new System.Windows.Forms.KeyEventHandler(this.rtDebug_KeyUp);
+            //
+            // XmppDebugger
+            //
+            this.Controls.Add(this.rtDebug);
+            this.Controls.Add(this.splitter1);
+            this.Controls.Add(this.rtSend);
+            this.Name = "XmppDebugger";
+            this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.XmppDebugger_KeyUp);
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+    }
+}
diff --git a/lib/jabber-net/netlib.Dns/Properties/AssemblyInfo.cs b/lib/jabber-net/netlib.Dns/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..db37d32
--- /dev/null
+++ b/lib/jabber-net/netlib.Dns/Properties/AssemblyInfo.cs
@@ -0,0 +1,31 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("netlib.Dns")]
+[assembly: AssemblyDescription("Allows for a complete DNS record lookup on a given domain using the Windows API.")]
+[assembly: AssemblyVersion("1.1.*")]
+
+[assembly: AssemblyCompany("The ASP Emporium (http://www.aspemporium.com/)")]
+[assembly: AssemblyProduct("The ASP Emporium (http://www.aspemporium.com/)")]
+[assembly: AssemblyCopyright("The ASP Emporium (http://www.aspemporium.com/)")]
+[assembly: AssemblyTrademark("The ASP Emporium (http://www.aspemporium.com/)")]
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("f0ccd899-310f-40e3-aa25-ff151d23b11a")]
+
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyName("")]
+
diff --git a/lib/jabber-net/netlib.Dns/dns.cs b/lib/jabber-net/netlib.Dns/dns.cs
new file mode 100644
index 0000000..7e9f1a7
--- /dev/null
+++ b/lib/jabber-net/netlib.Dns/dns.cs
@@ -0,0 +1,2087 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Net;
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+using netlib.Dns.Records;
+
+namespace netlib.Dns
+{
+    /// <summary>
+    /// Represents a complete DNS record (DNS_RECORD)
+    /// </summary>
+    /// <remarks>
+    /// This structure is used to hold a complete DNS record
+    /// as returned from the DnsQuery API.
+    /// </remarks>
+    [StructLayout(LayoutKind.Sequential)]
+    struct DnsRecord
+    {
+        /// <summary>
+        /// Gets or sets the next record.
+        /// </summary>
+        public IntPtr Next;// 4 bytes
+
+        /// <summary>
+        /// Gets or sets the name of the record.
+        /// </summary>
+        public string Name;// 4 bytes
+
+        /// <summary>
+        /// Gets or sets the type.
+        /// </summary>
+        [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U2)]
+        public DnsRecordType    RecordType;// 2 bytes
+
+        /// <summary>
+        /// Gets or sets the data length.
+        /// </summary>
+        [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U2)]
+        public ushort   DataLength;// 2 bytes
+
+        /// <summary>
+        /// Represents the flags of a <see cref="DnsRecord"/>.
+        /// </summary>
+        [ StructLayout( LayoutKind.Explicit )]// 4 bytes
+            internal struct DnsRecordFlags
+        {
+            /// <summary>
+            /// Reserved.
+            /// </summary>
+            [ FieldOffset( 0 )]
+            [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
+            public uint DW;
+
+            /// <summary>
+            /// Reserved.
+            /// </summary>
+            [ FieldOffset( 0 )]
+            [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
+            public uint  S;
+        }
+
+        /// <summary>
+        /// Gets or sets the flags.
+        /// </summary>
+        public DnsRecordFlags Flags;
+
+        /// <summary>
+        /// Gets or sets the TTL count
+        /// </summary>
+        [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
+        public uint Ttl;// 4 bytes
+
+        /// <summary>
+        /// Reserved.
+        /// </summary>
+        [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
+        public uint Reserved;// 4 bytes
+        // Can't fill in rest of the structure because if it doesn't line up, c# will complain.
+    }
+
+    /// <summary>
+    /// DNS query types
+    /// </summary>
+    /// <remarks>
+    /// This enum is used by the DnsQuery API call to describe the
+    /// options to be given to a DNS server along with a query.
+    /// </remarks>
+    [Flags]
+    enum DnsQueryType: uint
+    {
+        /// <summary>
+        /// Standard
+        /// </summary>
+        STANDARD                  = 0x00000000,
+
+        /// <summary>
+        /// Accept truncated response
+        /// </summary>
+        ACCEPT_TRUNCATED_RESPONSE = 0x00000001,
+
+        /// <summary>
+        /// Use TCP only
+        /// </summary>
+        USE_TCP_ONLY              = 0x00000002,
+
+        /// <summary>
+        /// No recursion
+        /// </summary>
+        NO_RECURSION              = 0x00000004,
+
+        /// <summary>
+        /// Bypass cache
+        /// </summary>
+        BYPASS_CACHE              = 0x00000008,
+
+        /// <summary>
+        /// Cache only
+        /// </summary>
+        NO_WIRE_QUERY                = 0x00000010,
+
+        /// <summary>
+        /// Directs DNS to ignore the local name.
+        /// </summary>
+        NO_LOCAL_NAME      =      0x00000020,
+
+        /// <summary>
+        /// Prevents the DNS query from consulting the HOSTS file.
+        /// </summary>
+        NO_HOSTS_FILE      =      0x00000040,
+
+        /// <summary>
+        /// Prevents the DNS query from using NetBT for resolution.
+        /// </summary>
+        NO_NETBT           =      0x00000080,
+
+        /// <summary>
+        /// Directs DNS to perform a query using the network only,
+        /// bypassing local information.
+        /// </summary>
+        WIRE_ONLY          = 0x00000100,
+
+        /// <summary>
+        /// Treat as FQDN
+        /// </summary>
+        TREAT_AS_FQDN             = 0x00001000,
+
+        /// <summary>
+        /// Allow empty auth response
+        /// </summary>
+        [Obsolete]
+        ALLOW_EMPTY_AUTH_RESP     = 0x00010000,
+
+        /// <summary>
+        /// Don't reset TTL values
+        /// </summary>
+        DONT_RESET_TTL_VALUES     = 0x00100000,
+
+        /// <summary>
+        /// Reserved.
+        /// </summary>
+        RESERVED                  = 0xff000000,
+
+        /// <summary>
+        /// obsolete.
+        /// </summary>
+        [Obsolete("use NO_WIRE_QUERY instead")]
+        CACHE_ONLY = NO_WIRE_QUERY,
+
+        /// <summary>
+        /// Directs DNS to return the entire DNS response message.
+        /// </summary>
+        RETURN_MESSAGE     =       0x00000200
+
+    }
+
+    /// <summary>
+    /// The possible return codes of the DNS API call. This enum can
+    /// be used to decypher the <see cref="DnsException.ErrorCode"/>
+    /// property's return value.
+    /// </summary>
+    /// <remarks>
+    /// This enum is used to describe a failed return code by the
+    /// DnsQuery API used in the <see cref="DnsRequest"/> class.
+    /// </remarks>
+    public enum DnsQueryReturnCode: ulong
+    {
+        /// <summary>
+        /// Successful query
+        /// </summary>
+        SUCCESS = 0L,
+
+        /// <summary>
+        /// Base DNS error code
+        /// </summary>
+        UNSPECIFIED_ERROR = 9000,
+
+        /// <summary>
+        /// Base DNS error code
+        /// </summary>
+        MASK = 0x00002328, // 9000 or RESPONSE_CODES_BASE
+
+        /// <summary>
+        /// DNS server unable to interpret format.
+        /// </summary>
+        FORMAT_ERROR   =   9001L,
+
+        /// <summary>
+        /// DNS server failure.
+        /// </summary>
+        SERVER_FAILURE =   9002L,
+
+        /// <summary>
+        /// DNS name does not exist.
+        /// </summary>
+        NAME_ERROR    =    9003L,
+
+        /// <summary>
+        /// DNS request not supported by name server.
+        /// </summary>
+        NOT_IMPLEMENTED =  9004L,
+
+        /// <summary>
+        /// DNS operation refused.
+        /// </summary>
+        REFUSED       =    9005L,
+
+        /// <summary>
+        /// DNS name that ought not exist, does exist.
+        /// </summary>
+        YXDOMAIN     =     9006L,
+
+        /// <summary>
+        /// DNS RR set that ought not exist, does exist.
+        /// </summary>
+        YXRRSET     =      9007L,
+
+        /// <summary>
+        /// DNS RR set that ought to exist, does not exist.
+        /// </summary>
+        NXRRSET      =     9008L,
+
+        /// <summary>
+        /// DNS server not authoritative for zone.
+        /// </summary>
+        NOTAUTH      =     9009L,
+
+        /// <summary>
+        /// DNS name in update or prereq is not in zone.
+        /// </summary>
+        NOTZONE      =     9010L,
+
+        /// <summary>
+        /// DNS signature failed to verify.
+        /// </summary>
+        BADSIG      =      9016L,
+
+        /// <summary>
+        /// DNS bad key.
+        /// </summary>
+        BADKEY      =      9017L,
+
+        /// <summary>
+        /// DNS signature validity expired.
+        /// </summary>
+        BADTIME     =      9018L,
+
+        /// <summary>
+        /// Packet format
+        /// </summary>
+        PACKET_FMT_BASE = 9500,
+
+        /// <summary>
+        /// No records found for given DNS query.
+        /// </summary>
+        NO_RECORDS      =         9501L,
+
+        /// <summary>
+        /// Bad DNS packet.
+        /// </summary>
+        BAD_PACKET     =         9502L,
+
+        /// <summary>
+        /// No DNS packet.
+        /// </summary>
+        NO_PACKET      =         9503L,
+
+        /// <summary>
+        /// DNS error, check rcode.
+        /// </summary>
+        RCODE          =         9504L,
+
+        /// <summary>
+        /// Unsecured DNS packet.
+        /// </summary>
+        UNSECURE_PACKET   =      9505L
+    }
+
+    /// <summary>
+    /// Possible arguments for the DnsRecordListFree api
+    /// </summary>
+    /// <remarks>
+    /// This enum is used by the DnsRecordListFree API.
+    /// </remarks>
+    enum DnsFreeType: uint
+    {
+        /// <summary>
+        /// Reserved.
+        /// </summary>
+        FreeFlat = 0,
+
+        /// <summary>
+        /// Frees the record list returned by the DnsQuery API
+        /// </summary>
+        FreeRecordList
+    }
+
+    /// <summary>
+    /// Represents the exception that occurs when a <see cref="DnsRequest"/>
+    /// fails.
+    /// </summary>
+    /// <remarks>
+    /// <para>
+    /// The exception that occurs when a DNS request fails at any level.
+    /// </para>
+    /// <para>
+    /// This class is used to represent two broad types of exceptions:
+    /// <list type="bullet">
+    ///     <item>Win32 API Exceptions that occurred when calling the DnsQuery API</item>
+    ///     <item>Exceptions of other types that occurred when working with
+    ///     the <see cref="DnsRequest"/> and <see cref="DnsResponse"/>
+    ///     classes.</item>
+    /// </list>
+    /// </para>
+    /// <para>
+    /// Win32 errors that are DNS specific are specified in the
+    /// <see cref="DnsQueryReturnCode"/> enumeration but if the
+    /// <see cref="ErrorCode"/> returned is not defined in that
+    /// enum then the number returned will be defined in WinError.h.
+    /// </para>
+    /// <para>
+    /// Exceptions of other types are available through the
+    /// InnerException property.
+    /// </para>
+    /// </remarks>
+    [Serializable]
+    public class DnsException: ApplicationException, ISerializable
+    {
+        private readonly uint errcode = (uint) DnsQueryReturnCode.SUCCESS;
+
+        /// <summary>
+        /// Initializes a new instance of <see cref="DnsException"/>
+        /// </summary>
+        /// <remarks>
+        /// Used to raise a <see cref="DnsException"/> with all the default
+        /// properties. The message property will return: Unspecified
+        /// DNS exception.
+        /// </remarks>
+        public DnsException(): base("Unspecified DNS exception")
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of <see cref="DnsException"/>
+        /// </summary>
+        /// <param name="message">the human readable description of the problem</param>
+        /// <remarks>
+        /// Used to raise a <see cref="DnsException"/> where the only important
+        /// information is a description about the error. The <see cref="ErrorCode"/>
+        /// property will return 0 or SUCCESS indicating that the DNS API calls
+        /// succeeded, regardless of whether they did or did not.
+        /// </remarks>
+        public DnsException(string message): base(message)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of <see cref="DnsException"/>
+        /// </summary>
+        /// <param name="message">the human readable description of the problem</param>
+        /// <param name="errcode">the error code (<see cref="DnsQueryReturnCode"/>)
+        /// if the DnsQuery api failed</param>
+        /// <remarks>
+        /// Used to raise a <see cref="DnsException"/> where the underlying DNS
+        /// API call fails. In this case, the <see cref="ErrorCode"/> property
+        /// is the most important information about the exception. In most cases,
+        /// the number returned is a value in the <see cref="DnsQueryReturnCode"/>
+        /// enum however, if it is not, the error is defined in WinError.h.
+        /// </remarks>
+        public DnsException(string message, uint errcode): base(message)
+        {
+            this.errcode = errcode;
+        }
+
+        /// <summary>
+        /// Gets the error code (<see cref="DnsQueryReturnCode"/>)
+        /// if the DnsQuery api failed. Will be set to success (0) if the API
+        /// didn't fail but another part of the code did.
+        /// </summary>
+        /// <remarks>
+        /// Win32 errors that are DNS specific are specified in the
+        /// <see cref="DnsQueryReturnCode"/> enumeration but if the
+        /// <see cref="ErrorCode"/> returned is not defined in that
+        /// enum then the number returned will be defined in WinError.h.
+        /// </remarks>
+        /// <value>Value will be defined in WinError.h if not defined in the
+        /// <see cref="DnsQueryReturnCode"/> enum.</value>
+        /// <example>
+        /// This example shows how to decypher the return of the
+        /// ErrorCode property.
+        /// <code>
+        /// try
+        /// {
+        ///     ...
+        /// }
+        /// catch(DnsException dnsEx)
+        /// {
+        ///     int errcode = dnsEx.ErrorCode;
+        ///     if (! Enum.IsDefined(typeof(DnsQueryReturnCode), errcode))
+        ///     {
+        ///         //defined in winerror.h
+        ///         Console.WriteLine("WIN32 Error: {0}", errcode);
+        ///         return;
+        ///     }
+        ///
+        ///     DnsQueryReturnCode errretcode = (DnsQueryReturnCode) errcode;
+        ///     if (errretcode == DnsQueryReturnCode.SUCCESS)
+        ///     {
+        ///         //inner exception contains the goodies
+        ///         Console.WriteLine(dnsEx.InnerException.ToString());
+        ///         return;
+        ///     }
+        ///
+        ///     //dns error
+        ///     Console.WriteLine("DNS Error: {0}", errretcode.ToString("g"));
+        /// }
+        /// </code>
+        /// </example>
+        public uint ErrorCode
+        {
+            get
+            {
+                return errcode;
+            }
+        }
+
+        /// <summary>
+        /// Initializes a new instance of <see cref="DnsException"/>
+        /// </summary>
+        /// <param name="message">the human readable description of the
+        /// problem</param>
+        /// <param name="innerException">the exception that caused the
+        /// underlying error</param>
+        /// <remarks>
+        /// Used to raise a <see cref="DnsException"/> where the exception is
+        /// some other type but a typeof(DnsException) is desired to be raised
+        /// instead. In this case, the <see cref="ErrorCode"/> property
+        /// always returns 0 or SUCCESS and is a useless property.
+        /// </remarks>
+        public DnsException(string message, Exception innerException): base(message, innerException)
+        {
+        }
+
+        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
+        {
+            info.AddValue("errcode", errcode);
+            base.GetObjectData(info, context);
+        }
+
+        /// <summary>
+        /// Initializes a new instance of <see cref="DnsException"/> for <see cref="ISerializable"/>
+        /// </summary>
+        /// <param name="info">the serialization information</param>
+        /// <param name="context">the context</param>
+        /// <remarks>
+        /// Used by the <see cref="ISerializable"/> interface.
+        /// </remarks>
+        public DnsException(SerializationInfo info, StreamingContext context): base(info, context)
+        {
+            errcode = info.GetUInt32("errcode");
+        }
+    }
+
+    /// <summary>
+    /// DNS record types
+    /// </summary>
+    /// <remarks>
+    /// This enum represents all possible DNS record types that
+    /// could be returned by the DnsQuery API.
+    /// </remarks>
+    [Flags]
+    public enum DnsRecordType: ushort
+    {
+        /// <summary>
+        /// Address record
+        /// </summary>
+        A          = 0x0001,      //  1
+
+        /// <summary>
+        /// Canonical Name record
+        /// </summary>
+        CNAME      = 0x0005,      //  5
+
+        /// <summary>
+        /// Start Of Authority record
+        /// </summary>
+        SOA        = 0x0006,      //  6
+
+        /// <summary>
+        /// Pointer record
+        /// </summary>
+        PTR        = 0x000c,      //  12
+
+        /// <summary>
+        /// Mail Exchange record
+        /// </summary>
+        MX         = 0x000f,      //  15
+
+        /// <summary>
+        /// Text record
+        /// </summary>
+        TEXT       = 0x0010,      //  16
+
+        //  RFC 2052    (Service location)
+        /// <summary>
+        /// Server record
+        /// </summary>
+        SRV        = 0x0021,      //  33
+
+        /// <summary>
+        /// All records
+        /// </summary>
+        ALL        = 0x00ff,      //  255
+
+        /// <summary>
+        /// Any records
+        /// </summary>
+        ANY        = 0x00ff,      //  255
+    }
+
+    /// <summary>
+    /// Represents a container for a DNS record of any type
+    /// </summary>
+    /// <remarks>
+    /// The <see cref="DnsWrapper.RecordType"/> property's value
+    /// helps determine what type real type of the
+    /// <see cref="DnsWrapper.RecordData"/> property returns as
+    /// noted in this chart:
+    /// <list type="table">
+    ///     <listheader>
+    ///         <term>RecordType</term>
+    ///         <term>RecordData</term>
+    ///     </listheader>
+    ///     <item>
+    ///         <term>A</term>
+    ///         <description><see cref="netlib.Dns.Records.ARecord"/></description>
+    ///     </item>
+    ///     <item>
+    ///         <term>CNAME</term>
+    ///         <description><see cref="netlib.Dns.Records.PTRRecord"/></description>
+    ///     </item>
+    ///     <item>
+    ///         <term>PTR</term>
+    ///         <description><see cref="netlib.Dns.Records.PTRRecord"/></description>
+    ///     </item>
+    ///     <item>
+    ///         <term>MX</term>
+    ///         <description><see cref="netlib.Dns.Records.MXRecord"/></description>
+    ///     </item>
+    ///     <item>
+    ///         <term>SOA</term>
+    ///         <description><see cref="netlib.Dns.Records.SOARecord"/></description>
+    ///     </item>
+    ///     <item>
+    ///         <term>SRV</term>
+    ///         <description><see cref="netlib.Dns.Records.SRVRecord"/></description>
+    ///     </item>
+    ///     <item>
+    ///         <term>TEXT</term>
+    ///         <description><see cref="netlib.Dns.Records.TXTRecord"/></description>
+    ///     </item>
+    /// </list>
+    /// </remarks>
+    public struct DnsWrapper: IComparable
+    {
+        /// <summary>
+        /// Gets or sets the type of DNS record contained in the
+        /// <see cref="RecordData"/> property.
+        /// </summary>
+        /// <remarks>
+        /// This property indicates the type of DNS record
+        /// that the <see cref="RecordData"/> property is
+        /// holding.
+        /// </remarks>
+        public DnsRecordType RecordType;
+
+        /// <summary>
+        /// Gets or sets the DNS record object as denoted in the
+        /// <see cref="RecordType"/> field.
+        /// </summary>
+        /// <remarks>
+        /// This property holds the actual DNS record.
+        /// </remarks>
+        public object RecordData;
+
+        /// <summary>
+        /// Determines whether or not this <see cref="DnsWrapper"/>
+        /// instance is equal to a specific <see cref="DnsRecordType"/>
+        /// by comparing the <see cref="RecordType"/> property of the
+        /// current <see cref="DnsWrapper"/> against the
+        /// <see cref="DnsRecordType"/> argument.
+        /// </summary>
+        /// <param name="type">The <see cref="DnsRecordType"/> to compare to.</param>
+        /// <returns>A boolean indicating whether or not this <see cref="DnsWrapper"/>
+        /// object contains a DNS record matching the entered type.</returns>
+        /// <remarks>
+        /// Determines if this <see cref="DnsWrapper"/> is of a specific
+        /// <see cref="DnsRecordType"/>. The comparison does not test the
+        /// <see cref="RecordData"/> field.
+        /// </remarks>
+        public bool Equals(DnsRecordType type)
+        {
+            if( RecordType == type)
+                return true;
+
+            return false;
+        }
+
+        /// <summary>
+        /// Determines whether or not this <see cref="DnsWrapper"/> instance
+        /// is equal to another <see cref="DnsWrapper"/> or to a
+        /// <see cref="DnsRecordType"/> instance.
+        /// </summary>
+        /// <param name="obj">The object to compare to this instance.</param>
+        /// <returns>A boolean indicating whether or not this <see cref="DnsWrapper"/>
+        /// object equals the entered object.</returns>
+        /// <remarks>
+        /// Determines if this <see cref="DnsWrapper"/> instance is equal to
+        /// an object. If the object is a <see cref="DnsRecordType"/>, the
+        /// <see cref="Equals(DnsRecordType)"/> method is used to determine
+        /// equality based on the record type. If the object is a <see cref="DnsWrapper"/>
+        /// object, the <see cref="CompareTo"/> method is used to determine
+        /// equality. If the object is any other type, the <see cref="Object"/>
+        /// class's Equal method is used for comparison.
+        /// </remarks>
+        public override bool Equals(object obj)
+        {
+            if (obj == null)
+                return false;
+
+            if (obj is DnsRecordType)
+                return Equals((DnsRecordType) obj);
+
+            if (obj is DnsWrapper)
+                return (CompareTo(obj) == 0 ? true : false);
+
+            return base.Equals(obj);
+        }
+
+        /// <summary>
+        /// Serves as a hash function for a particular type, suitable
+        /// for use in hashing algorithms and data structures like a
+        /// hash table.
+        /// </summary>
+        /// <returns>Integer value representing the hashcode of this
+        /// instance of <see cref="DnsWrapper"/>.</returns>
+        /// <remarks>
+        /// The GetHashCode method uses the hash codes of the <see cref="RecordData"/>
+        /// and <see cref="RecordType"/> properties to generate a unique code
+        /// for this particular record type/data combination.
+        /// </remarks>
+        public override int GetHashCode()
+        {
+            return RecordData.GetHashCode() ^ RecordType.GetHashCode();
+        }
+
+        #region IComparable Members
+
+        /// <summary>
+        /// Compares the current instance with another object of the same type.
+        /// </summary>
+        /// <param name="obj">The object to compare with this instance.</param>
+        /// <returns>
+        /// A 32-bit signed integer that indicates the relative order of the
+        /// comparands. The return value has these meanings:
+        /// <list type="table">
+        ///     <listheader>
+        ///         <term>Value</term>
+        ///         <term>Meaning</term>
+        ///     </listheader>
+        ///     <item>
+        ///         <term>Less than zero</term>
+        ///         <description>This instance is less than obj. The <see cref="RecordData"/>
+        ///         types do not match.</description>
+        ///     </item>
+        ///     <item>
+        ///         <term>Zero</term>
+        ///         <description>This instance is equal to obj. </description>
+        ///     </item>
+        ///     <item>
+        ///         <term>Greater than zero</term>
+        ///         <description>This instance is greater than obj. The <see cref="RecordType"/>
+        ///         do not match.</description>
+        ///     </item>
+        /// </list>
+        /// </returns>
+        /// <remarks>
+        /// Compares a <see cref="DnsWrapper"/> to this instance by its
+        /// <see cref="RecordType"/> and <see cref="RecordData"/> properties.
+        /// </remarks>
+        /// <exception cref="ArgumentException">
+        /// obj is not the same type as this instance.
+        /// </exception>
+        public int CompareTo(object obj)
+        {
+            if (! (obj is DnsWrapper))
+                throw new ArgumentException();
+
+            DnsWrapper dnsw = (DnsWrapper) obj;
+            if (RecordData.GetType() != dnsw.RecordData.GetType())
+                return -1;
+
+            if (RecordType != dnsw.RecordType)
+                return 1;
+
+            return 0;
+        }
+
+        #endregion
+    }
+
+    /// <summary>
+    /// Represents a collection of <see cref="DnsWrapper"/> objects.
+    /// </summary>
+    /// <remarks>
+    /// The DnsWrapperCollection is a collection of <see cref="DnsWrapper"/>
+    /// objects. The resultant collection represents all of the DNS records
+    /// for the given domain that was looked up. This class cannot be directly
+    /// created - it is created by the <see cref="DnsRequest"/> and
+    /// <see cref="DnsResponse"/> classes to hold the returned DNS
+    /// records for the given domain.
+    /// </remarks>
+    public class DnsWrapperCollection: ReadOnlyCollectionBase, IEnumerable
+    {
+        internal DnsWrapperCollection()
+        {
+        }
+
+        internal bool Contains(DnsWrapper w)
+        {
+            foreach(DnsWrapper wrapper in InnerList)
+                if (w.Equals(wrapper))
+                    return true;
+
+            return false;
+        }
+
+        internal void Add(DnsWrapper w)
+        {
+            InnerList.Add(w);
+        }
+
+        /// <summary>
+        /// Gets the <see cref="DnsWrapper"/> at the specified
+        /// ordinal in the collection
+        /// </summary>
+        /// <remarks>
+        /// Gets the <see cref="DnsWrapper"/> at the specified
+        /// index of the collection.
+        /// </remarks>
+        /// <param name="i">The index to retrieve from the collection.</param>
+        /// <value>The <see cref="DnsWrapper"/> at the specified index of
+        /// the collection.</value>
+        public DnsWrapper this[int i]
+        {
+            get
+            {
+                return (DnsWrapper) InnerList[i];
+            }
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return new DnsWrapperCollectionEnumerator(this);
+        }
+
+        class DnsWrapperCollectionEnumerator: IEnumerator
+        {
+            private int idx = -1;
+            private readonly DnsWrapperCollection coll;
+
+            public DnsWrapperCollectionEnumerator(DnsWrapperCollection coll)
+            {
+                this.coll = coll;
+            }
+
+            void IEnumerator.Reset()
+            {
+                idx=-1;
+            }
+
+            bool IEnumerator.MoveNext()
+            {
+                idx++;
+
+                return idx < coll.Count;
+            }
+
+            object IEnumerator.Current
+            {
+                get
+                {
+                    return coll[idx];
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    /// Represents one DNS request. Allows for a complete DNS record lookup
+    /// on a given _Domain using the Windows API.
+    /// </summary>
+    /// <remarks>
+    /// <para>
+    /// The DnsRequest class represents a complete DNS request for a given
+    /// _Domain on a specified DNS server, including all options. The
+    /// DnsRequest class uses the Windows API to do the query and the dlls
+    /// used are only found on Windows 2000 or higher machines. The class
+    /// will throw a <see cref="NotSupportedException"/> exception if run
+    /// on an machine not capable of using the APIs that are required.
+    /// </para>
+    /// <para>
+    /// Version Information
+    /// </para>
+    /// <para>
+    ///         3/8/2003 v1.1 (C#) - Released on 5/31/2003
+    /// </para>
+    /// <para>
+    /// Created by: Bill Gearhart. Based on code by Patrik Lundin.
+    /// See version 1.0 remarks below. Specific attention was given
+    /// to the exposed interface which got a 110% overhaul.
+    /// </para>
+    /// <para>
+    /// Notable changes from the previous version:
+    /// <list type="bullet">
+    ///     <item>
+    ///         <description>
+    ///             structs filled with constants were changed to enums
+    ///         </description>
+    ///     </item>
+    ///     <item>
+    ///         <description>
+    ///             .net datatypes were changed to c# datatypes
+    ///         </description>
+    ///     </item>
+    ///     <item>
+    ///         <description>
+    ///             every object is now in it's own *.cs file
+    ///         </description>
+    ///     </item>
+    ///     <item>
+    ///         <description>
+    ///             custom collections and exceptions added
+    ///         </description>
+    ///     </item>
+    ///     <item>
+    ///         <description>
+    ///             better object orientation - request and response classes
+    ///             created for the dns query request/response session so that
+    ///             it follows the .NET model
+    ///         </description>
+    ///     </item>
+    ///     <item>
+    ///         <description>
+    ///             eliminated duplicate recs returned by an ALL query
+    ///         </description>
+    ///     </item>
+    ///     <item>
+    ///         <description>
+    ///             bad api return code enumeration added
+    ///         </description>
+    ///     </item>
+    ///     <item>
+    ///         <description>
+    ///             ToString() overridden to provide meaningful info for many
+    ///             of the dns data structs
+    ///         </description>
+    ///     </item>
+    ///     <item>
+    ///         <description>
+    ///             documentation and notes were created for all classes
+    ///         </description>
+    ///     </item>
+    ///     <item>
+    ///         <description>
+    ///             added check to ensure code only runs on w2k or better
+    ///         </description>
+    ///     </item>
+    ///     <item>
+    ///         <description>
+    ///             obsolete DNS record types are now marked as such
+    ///         </description>
+    ///     </item>
+    ///     <item>
+    ///         <description>
+    ///             newer enum values added to DnsQueryType enum
+    ///         </description>
+    ///     </item>
+    ///     <item>
+    ///         <description>
+    ///             compiled html documentation was written which always takes
+    ///             20 times longer than writing the code does.
+    ///         </description>
+    ///     </item>
+    ///     <item>
+    ///         <description>
+    ///             this list of changes was compiled by your's truly...
+    ///         </description>
+    ///     </item>
+    ///     <item>
+    ///         <description>
+    ///             smoothed out object and member names so they were more
+    ///             intuitive - for instance: DNS_MX_DATA became MXRecord
+    ///         </description>
+    ///     </item>
+    ///     <item>
+    ///         <description>
+    ///             added call to DnsRecordListFree API to free resources after
+    ///             DnsQuery call
+    ///         </description>
+    ///     </item>
+    ///     <item>
+    ///         <description>
+    ///             altered DnsQuery API call to allow for servers other than the
+    ///             local DNS server from being queried
+    ///         </description>
+    ///     </item>
+    /// </list>
+    /// </para>
+    /// <para>
+    ///     4/15/2002 v1.0 (C#)
+    /// </para>
+    /// <para>
+    /// Created by: Patrik Lundin
+    /// </para>
+    /// <para>
+    /// Based on code found at:
+    /// <a href="http://www.c-sharpcorner.com/Code/2002/April/DnsResolver.asp">http://www.c-sharpcorner.com/Code/2002/April/DnsResolver.asp</a>
+    ///
+    /// <list type="bullet">
+    ///     <item>
+    ///         <description>
+    ///             Initial implementation.
+    ///         </description>
+    ///     </item>
+    /// </list>
+    /// </para>
+    /// </remarks>
+    /// <example>
+    /// Use the <see cref="DnsRequest"/> and <see cref="DnsResponse"/> objects
+    /// together to get DNS information for aspemporium.com from the nameserver
+    /// where the site is hosted.
+    /// <code>
+    /// using System;
+    /// using netlib.Dns;
+    /// using netlib.Dns.Records;
+    ///
+    /// namespace ClassLibrary1
+    /// {
+    ///     class __loader
+    ///     {
+    ///         static void Main()
+    ///         {
+    ///             try
+    ///             {
+    ///                 DnsRequest request = new DnsRequest();
+    ///                 request.TreatAsFQDN=true;
+    ///                 request.BypassCache=true;
+    ///                 request.Servers.Add("dns.compresolve.com");
+    ///                 request._domain = "aspemporium.com";
+    ///                 DnsResponse response = request.GetResponse();
+    ///
+    ///                 Console.WriteLine("Addresses");
+    ///                 Console.WriteLine("--------------------------");
+    ///                 foreach(ARecord addr in response.ARecords)
+    ///                     Console.WriteLine("\t{0}", addr.ToString());
+    ///                 Console.WriteLine();
+    ///
+    ///                 Console.WriteLine("Name Servers");
+    ///                 Console.WriteLine("--------------------------");
+    ///                 foreach(PTRRecord ns in response.NSRecords)
+    ///                     Console.WriteLine("\t{0}", ns.ToString());
+    ///                 Console.WriteLine();
+    ///
+    ///                 Console.WriteLine("Mail Exchanges");
+    ///                 Console.WriteLine("--------------------------");
+    ///                 foreach(MXRecord exchange in response.MXRecords)
+    ///                     Console.WriteLine("\t{0}", exchange.ToString());
+    ///                 Console.WriteLine();
+    ///
+    ///                 Console.WriteLine("Canonical Names");
+    ///                 Console.WriteLine("--------------------------");
+    ///                 foreach(PTRRecord cname in response.GetRecords(DnsRecordType.CNAME))
+    ///                     Console.WriteLine("\t{0}", cname.ToString());
+    ///                 Console.WriteLine();
+    ///
+    ///                 Console.WriteLine("Start of Authority Records");
+    ///                 Console.WriteLine("--------------------------");
+    ///                 foreach(SOARecord soa in response.GetRecords(DnsRecordType.SOA))
+    ///                     Console.WriteLine("\t{0}", soa.ToString());
+    ///                 Console.WriteLine();
+    ///
+    ///                 //foreach(DnsWrapper wrap in response.RawRecords)
+    ///                 //{
+    ///                 //  Console.WriteLine(wrap.RecordType);
+    ///                 //}
+    ///
+    ///                 response = null;
+    ///                 request = null;
+    ///             }
+    ///             catch(DnsException ex)
+    ///             {
+    ///                 Console.WriteLine("EXCEPTION DOING DNS QUERY:");
+    ///                 Console.WriteLine("\t{0}", ((DnsQueryReturnCode) ex.ErrorCode).ToString("g"));
+    ///
+    ///                 if (ex.InnerException != null)
+    ///                     Console.WriteLine(ex.InnerException.ToString());
+    ///             }
+    ///         }
+    ///     }
+    /// }
+    ///
+    /// </code>
+    /// </example>
+    ///
+    public class DnsRequest
+    {
+        /// <summary>
+        /// http://msdn.microsoft.com/library/en-us/dns/dns/dnsquery.asp
+        /// </summary>
+        [DllImport("dnsapi", EntryPoint="DnsQuery_A")]
+        private static extern uint DnsQuery(
+            [MarshalAs(UnmanagedType.LPStr)]
+            string Name,
+
+            [MarshalAs(UnmanagedType.U2)]
+            DnsRecordType Type,
+
+            [MarshalAs(UnmanagedType.U4)]
+            DnsQueryType Options,
+
+            IntPtr Servers,
+
+            [In, Out]
+            ref IntPtr QueryResultsSet,
+
+            IntPtr Reserved
+            );
+
+        /// <summary>
+        /// http://msdn.microsoft.com/library/en-us/dns/dns/dnsrecordlistfree.asp
+        /// </summary>
+        [DllImport("dnsapi", EntryPoint="DnsRecordListFree")]
+        private static extern void DnsRecordListFree(
+            IntPtr RecordList,
+
+            DnsFreeType FreeType
+            );
+
+        private DnsQueryType QueryType;
+        private string _Domain;
+
+        /// <summary>
+        /// Gets or sets whether or not to use TCP only for the query.
+        /// </summary>
+        /// <value>Boolean indicating whether or not to use TCP instead of UDP for the query</value>
+        /// <remarks>
+        /// If set to true, the DNS query will be done via TCP rather than UDP. This
+        /// is useful if the DNS service you are trying to reach is running on
+        /// TCP but not on UDP.
+        /// </remarks>
+        public bool UseTCPOnly
+        {
+            get
+            {
+                return GetSetting(DnsQueryType.USE_TCP_ONLY);
+            }
+
+            set
+            {
+                SetSetting(DnsQueryType.USE_TCP_ONLY, value);
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets whether or not to accept truncated results —
+        /// does not retry under TCP.
+        /// </summary>
+        /// <value>Boolean indicating whether or not to accept truncated results.</value>
+        /// <remarks>
+        /// Determines wherher or not the server will be re-queried in the event
+        /// that a response was truncated.
+        /// </remarks>
+        public bool AcceptTruncatedResponse
+        {
+            get
+            {
+                return GetSetting(DnsQueryType.ACCEPT_TRUNCATED_RESPONSE);
+            }
+
+            set
+            {
+                SetSetting(DnsQueryType.ACCEPT_TRUNCATED_RESPONSE, value);
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets whether or not to perform an iterative query
+        /// </summary>
+        /// <value>Boolean indicating whether or not to use recursion
+        /// to resolve the query.</value>
+        /// <remarks>
+        /// Specifically directs the DNS server not to perform
+        /// recursive resolution to resolve the query.
+        /// </remarks>
+        public bool NoRecursion
+        {
+            get
+            {
+                return GetSetting(DnsQueryType.NO_RECURSION);
+            }
+
+            set
+            {
+                SetSetting(DnsQueryType.NO_RECURSION, value);
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets whether or not to bypass the resolver cache
+        /// on the lookup.
+        /// </summary>
+        /// <remarks>
+        /// Setting this to true allows you to specify one or more DNS servers
+        /// to query instead of querying the local DNS cache and server.
+        /// If false is set, the list of servers is ignored and the local DNS
+        /// cache and server is used to resolve the query.
+        /// </remarks>
+        public bool BypassCache
+        {
+            get
+            {
+                return GetSetting(DnsQueryType.BYPASS_CACHE);
+            }
+
+            set
+            {
+                SetSetting(DnsQueryType.BYPASS_CACHE, value);
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets whether or not to direct DNS to perform a
+        /// query on the local cache only
+        /// </summary>
+        /// <value>Boolean indicating whether or not to only use the
+        /// DNS cache to resolve a query.</value>
+        /// <remarks>
+        /// This option allows you to query the local DNS cache only instead
+        /// of making a DNS request over either UDP or TCP.
+        /// This property represents the logical opposite of the
+        /// <see cref="WireOnly"/> property.
+        /// </remarks>
+        public bool QueryCacheOnly
+        {
+            get
+            {
+                return GetSetting(DnsQueryType.NO_WIRE_QUERY);
+            }
+
+            set
+            {
+                SetSetting(DnsQueryType.NO_WIRE_QUERY, value);
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets whether or not to direct DNS to perform a
+        /// query using the network only, bypassing local information.
+        /// </summary>
+        /// <value>Boolean indicating whether or not to use the
+        /// network only instead of local information.</value>
+        /// <remarks>
+        /// This property represents the logical opposite of the
+        /// <see cref="QueryCacheOnly"/> property.
+        /// </remarks>
+        public bool WireOnly
+        {
+            get
+            {
+                return GetSetting(DnsQueryType.WIRE_ONLY);
+            }
+
+            set
+            {
+                SetSetting(DnsQueryType.WIRE_ONLY, value);
+            }
+        }
+
+
+        /// <summary>
+        /// Gets or sets whether or not to direct DNS to ignore the
+        /// local name.
+        /// </summary>
+        /// <value>Boolean indicating whether or not to ignore the local name.</value>
+        /// <remarks>
+        /// Determines how the DNS query handles local names.
+        /// </remarks>
+        public bool NoLocalName
+        {
+            get
+            {
+                return GetSetting(DnsQueryType.NO_LOCAL_NAME);
+            }
+
+            set
+            {
+                SetSetting(DnsQueryType.NO_LOCAL_NAME, value);
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets whether or not to prevent the DNS query from
+        /// consulting the HOSTS file.
+        /// </summary>
+        /// <value>Boolean indicating whether or not to deny access to
+        /// the HOSTS file when querying.</value>
+        /// <remarks>
+        /// Determines how the DNS query handles accessing the HOSTS file when
+        /// querying for DNS information.
+        /// </remarks>
+        public bool NoHostsFile
+        {
+            get
+            {
+                return GetSetting(DnsQueryType.NO_HOSTS_FILE);
+            }
+
+            set
+            {
+                SetSetting(DnsQueryType.NO_HOSTS_FILE, value);
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets whether or not to prevent the DNS query from
+        /// using NetBT for resolution.
+        /// </summary>
+        /// <value>Boolean indicating whether or not to deny access to
+        /// NetBT during the query.</value>
+        /// <remarks>
+        /// Determines how the DNS query handles accessing NetBT when
+        /// querying for DNS information.
+        /// </remarks>
+        public bool NoNetbt
+        {
+            get
+            {
+                return GetSetting(DnsQueryType.NO_NETBT);
+            }
+
+            set
+            {
+                SetSetting(DnsQueryType.NO_NETBT, value);
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets whether or not to direct DNS to return
+        /// the entire DNS response message.
+        /// </summary>
+        /// <value>Boolean indicating whether or not to return the entire
+        /// response.</value>
+        /// <remarks>
+        /// Determines how the DNS query expects the response to be
+        /// received from the server.
+        /// </remarks>
+        public bool QueryReturnMessage
+        {
+            get
+            {
+                return GetSetting(DnsQueryType.RETURN_MESSAGE);
+            }
+
+            set
+            {
+                SetSetting(DnsQueryType.RETURN_MESSAGE, value);
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets whether or not to prevent the DNS
+        /// response from attaching suffixes to the submitted
+        /// name in a name resolution process.
+        /// </summary>
+        /// <value>Boolean indicating whether or not to allow
+        /// suffix attachment during resolution.</value>
+        /// <remarks>
+        /// Determines how the DNS server handles suffix appending
+        /// to the submitted name during name resolution.
+        /// </remarks>
+        public bool TreatAsFQDN
+        {
+            get
+            {
+                return GetSetting(DnsQueryType.TREAT_AS_FQDN);
+            }
+
+            set
+            {
+                SetSetting(DnsQueryType.TREAT_AS_FQDN, value);
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets whether or not to store records
+        /// with the TTL corresponding to the minimum value
+        /// TTL from among all records
+        /// </summary>
+        /// <value>Boolean indicating whether or not to
+        /// use TTL values from all records.</value>
+        /// <remarks>
+        /// Determines how the DNS query handles TTL values.
+        /// </remarks>
+        public bool DontResetTTLValues
+        {
+            get
+            {
+                return GetSetting(DnsQueryType.DONT_RESET_TTL_VALUES);
+            }
+
+            set
+            {
+                SetSetting(DnsQueryType.DONT_RESET_TTL_VALUES, value);
+            }
+        }
+
+        private bool GetSetting(DnsQueryType type)
+        {
+            DnsQueryType srchval = type;
+            bool isset = (QueryType & srchval) == srchval;
+            return isset;
+        }
+
+        private void SetSetting(DnsQueryType type, bool newvalue)
+        {
+            DnsQueryType srchval = type;
+            bool isset = (QueryType & srchval) == srchval;
+            bool newset = newvalue;
+
+            //compare
+            if (isset.CompareTo(newset) == 0)
+                return;
+
+            //toggle
+            QueryType ^= srchval;
+        }
+
+        /// <summary>
+        /// Gets or sets the _Domain to query. The _Domain must be a hostname,
+        /// not an IP address.
+        /// </summary>
+        /// <remarks>
+        /// This method is expecting a hostname, not an IP address. The
+        /// system will fail with a <see cref="DnsException"/> when
+        /// <see cref="GetResponse"/> is called if _domain is an IP address.
+        /// </remarks>
+        /// <value>String representing the _Domain that DNS information
+        /// is desired for. This should be set to a hostname and not an
+        /// IP Address.</value>
+        public string _domain
+        {
+            get
+            {
+                return _Domain;
+            }
+            set
+            {
+                _Domain=value;
+            }
+        }
+
+        /// <summary>
+        /// Creates a new instance of <see cref="DnsRequest"/>
+        /// </summary>
+        /// <remarks>
+        /// The <see cref="_domain"/> property is set to null
+        /// and all other properties have their default value
+        /// of false, except for <see cref="TreatAsFQDN"/> which has a value
+        /// of true. The system is set to use the local DNS
+        /// server for all queries.
+        /// </remarks>
+        public DnsRequest()
+        {
+            Initialize(null);
+        }
+
+        /// <summary>
+        /// Creates a new instance of <see cref="DnsRequest"/>
+        /// </summary>
+        /// <remarks>
+        /// The <see cref="_domain"/> property is set to the domain
+        /// argument and all other properties have their default value
+        /// of false, except for <see cref="TreatAsFQDN"/> which has a value
+        /// of true. The system is set to use the local DNS
+        /// server for all queries.
+        /// </remarks>
+        /// <param name="domain">The hostname that DNS information is desired for.
+        /// This should not be an ip address. For example: yahoo.com</param>
+        public DnsRequest(string domain)
+        {
+            Initialize(domain);
+        }
+
+        private void Initialize(string domain)
+        {
+            _domain=domain;
+            QueryType = DnsQueryType.STANDARD|DnsQueryType.TREAT_AS_FQDN;
+        }
+
+        /// <summary>
+        /// Queries the local DNS server for information about
+        /// this instance of <see cref="DnsRequest"/> and returns
+        /// the response as a <see cref="DnsResponse"/>
+        /// </summary>
+        /// <returns>A <see cref="DnsResponse"/> object containing the response
+        /// from the DNS server.</returns>
+        /// <exception cref="NotSupportedException">
+        /// The code is running on a machine lesser than Windows 2000
+        /// </exception>
+        /// <exception cref="ArgumentNullException">
+        /// The <see cref="_domain"/> property is null
+        /// </exception>
+        /// <exception cref="DnsException">
+        /// The DNS query itself failed or parsing of the returned
+        /// response failed
+        /// </exception>
+        /// <remarks>
+        /// Returns a <see cref="DnsResponse"/> representing the response
+        /// from the DNS server or one of the exceptions noted in the
+        /// exceptions area, the most common of which is the
+        /// <see cref="DnsException"/>.
+        /// </remarks>
+        public DnsResponse GetResponse(DnsRecordType dnstype)
+        {
+            if (Environment.OSVersion.Platform != PlatformID.Win32NT)
+                throw new NotSupportedException("This API is found only on Windows NT or better.");
+
+            if (_domain == null)
+                throw new ArgumentNullException();
+
+            string strDomain = _domain;
+            DnsQueryType querytype = QueryType;
+
+            object Data = new object();
+
+            IntPtr ppQueryResultsSet = IntPtr.Zero;
+            try
+            {
+                uint ret = DnsQuery(strDomain, dnstype, querytype, IntPtr.Zero, ref ppQueryResultsSet, IntPtr.Zero);
+                if (ret != 0)
+                    throw new DnsException("DNS query fails", ret);
+
+                DnsResponse resp = new DnsResponse();
+                // Parse the records.
+                // Call function to loop through linked list and fill an array of records
+                do
+                {
+                    // Get the DNS_RECORD
+                    DnsRecord dnsrec = (DnsRecord)Marshal.PtrToStructure(
+                        ppQueryResultsSet,
+                        typeof(DnsRecord)
+                        );
+
+                    // Get the Data part
+                    GetData(ppQueryResultsSet, ref dnsrec, ref Data);
+
+                    // Wrap data in a struct with the type and data
+                    DnsWrapper wrapper = new DnsWrapper();
+                    wrapper.RecordType = dnsrec.RecordType;
+                    wrapper.RecordData = Data;
+
+                    // Note: this is *supposed* to return many records of the same type.  Don't check for uniqueness.
+                    // Add wrapper to array
+                    //if (! resp.RawRecords.Contains(wrapper))
+                    resp.RawRecords.Add( wrapper );
+
+                    ppQueryResultsSet = dnsrec.Next;
+                } while (ppQueryResultsSet != IntPtr.Zero);
+
+                return resp;
+            }
+            catch(DnsException)
+            {
+                throw;
+            }
+            catch(Exception ex)
+            {
+                throw new DnsException("unspecified error", ex);
+            }
+            finally
+            {
+                //ensure unmanaged code cleanup occurs
+
+                //free pointer to DNS record block
+                DnsRecordListFree(ppQueryResultsSet, DnsFreeType.FreeRecordList);
+            }
+        }
+
+        private static void GetData(IntPtr ptr, ref DnsRecord dnsrec, ref object Data)
+        {
+            int size = ptr.ToInt32() + Marshal.SizeOf( dnsrec );
+            ptr = new IntPtr(size);// Skip over the header portion of the DNS_RECORD to the data portion.
+            switch ( dnsrec.RecordType )
+            {
+                case DnsRecordType.A:
+                    Data = (ARecord)Marshal.PtrToStructure( ptr, typeof(ARecord) );
+                    break;
+
+                case DnsRecordType.CNAME:
+                case DnsRecordType.PTR:
+                    Data = (PTRRecord)Marshal.PtrToStructure( ptr, typeof(PTRRecord) );
+                    break;
+
+                case DnsRecordType.MX:
+                    Data = (MXRecord)Marshal.PtrToStructure( ptr, typeof(MXRecord) );
+                    break;
+
+                case DnsRecordType.SOA:
+                    Data = (SOARecord)Marshal.PtrToStructure( ptr, typeof(SOARecord) );
+                    break;
+
+                case DnsRecordType.SRV:
+                    Data = (SRVRecord)Marshal.PtrToStructure( ptr, typeof(SRVRecord) );
+                    break;
+
+                case DnsRecordType.TEXT:
+                    Data = (TXTRecord)Marshal.PtrToStructure(ptr, typeof(TXTRecord));
+                    break;
+
+                default:
+                    Data = null;
+                    break;
+            }
+        }
+    }
+
+    /// <summary>
+    /// Represents one DNS response. This class cannot be directly created -
+    /// it is returned by the <see cref="DnsRequest.GetResponse"/> method.
+    /// </summary>
+    /// <remarks>
+    /// The DnsResponse class represents the information returned by a DNS
+    /// server in response to a <see cref="DnsRequest"/>. The DnsResponse
+    /// class offers easy access to all of the returned DNS records for a given
+    /// domain.
+    /// </remarks>
+    public class DnsResponse
+    {
+        private readonly DnsWrapperCollection rawrecords;
+
+        internal DnsResponse()
+        {
+            rawrecords = new DnsWrapperCollection();
+        }
+
+        /// <summary>
+        /// Gets a <see cref="DnsWrapperCollection" /> containing
+        /// all of the DNS information that the server returned about
+        /// the queried domain.
+        /// </summary>
+        /// <remarks>
+        /// Returns all of the DNS records retrieved about the domain
+        /// as a <see cref="DnsWrapperCollection"/>. This property
+        /// is wrapped by the <see cref="GetRecords"/> method.
+        /// </remarks>
+        /// <value>Gets a collection of <see cref="DnsWrapper"/> objects.</value>
+        public DnsWrapperCollection RawRecords
+        {
+            get
+            {
+                return rawrecords;
+            }
+        }
+
+        /// <summary>
+        /// Returns a collection of DNS records of a specified
+        /// <see cref="DnsRecordType"/>. The collection's data type
+        /// is determined by the type of record being sought in the
+        /// type argument.
+        /// </summary>
+        /// <param name="type">A <see cref="DnsRecordType"/> enumeration
+        /// value indicating the type of DNS record to get from the list of
+        /// all DNS records (available in the <see cref="RawRecords"/>
+        /// property.</param>
+        /// <returns>an <see cref="ArrayList"/> of one of the types
+        /// specified in the <see cref="netlib.Dns.Records"/> namespace based
+        /// on the <see cref="DnsRecordType"/> argument representing the
+        /// type of DNS record desired.
+        /// </returns>
+        /// <remarks>
+        /// It is recommended that you loop through the results of this
+        /// method as follows for maximum convenience:
+        /// <code>
+        /// foreach (<see cref="netlib.Dns.Records"/> record in obj.GetRecords(<see cref="DnsRecordType"/>))
+        /// {
+        ///     string s = record.ToString();
+        /// }
+        /// </code>
+        /// The following table indicates the DNS record type you can expect to get
+        /// back based on the <see cref="DnsRecordType"/> requested. Any items returning
+        /// null are not currently supported.
+        /// <list type="table">
+        ///     <listheader>
+        ///         <term>DnsRecordType enumeration value</term>
+        ///         <term>GetRecords() returns</term>
+        ///     </listheader>
+        ///     <item>
+        ///         <term>A</term>
+        ///         <description><see cref="netlib.Dns.Records.ARecord"/></description>
+        ///     </item>
+        ///     <item>
+        ///         <term>CNAME</term>
+        ///         <description><see cref="netlib.Dns.Records.PTRRecord"/></description>
+        ///     </item>
+        ///     <item>
+        ///         <term>PTR</term>
+        ///         <description><see cref="netlib.Dns.Records.PTRRecord"/></description>
+        ///     </item>
+        ///     <item>
+        ///         <term>MX</term>
+        ///         <description><see cref="netlib.Dns.Records.MXRecord"/></description>
+        ///     </item>
+        ///     <item>
+        ///         <term>SRV</term>
+        ///         <description><see cref="netlib.Dns.Records.SRVRecord"/></description>
+        ///     </item>
+        ///     <item>
+        ///         <term>TEXT</term>
+        ///         <description><see cref="netlib.Dns.Records.TXTRecord"/></description>
+        ///     </item>
+        /// </list>
+        /// </remarks>
+        public ArrayList GetRecords(DnsRecordType type)
+        {
+            ArrayList arr = new ArrayList();
+            foreach(DnsWrapper dnsentry in rawrecords)
+                if (dnsentry.Equals(type))
+                    arr.Add(dnsentry.RecordData);
+
+            return arr;
+        }
+
+        /// <summary>
+        /// Gets all the <see cref="SRVRecord"/> for the queried domain.
+        /// </summary>
+        /// <remarks>
+        /// Uses the <see cref="GetRecords"/> method to retrieve an
+        /// array of <see cref="SRVRecord"/>s representing all the Address
+        /// records for the domain.
+        /// </remarks>
+        /// <value>An array of <see cref="SRVRecord"/> objects.</value>
+        public SRVRecord[] SRVRecords
+        {
+            get
+            {
+                ArrayList arr = GetRecords(DnsRecordType.SRV);
+                return (SRVRecord[])arr.ToArray(typeof(SRVRecord));
+            }
+        }
+
+        /// <summary>
+        /// Gets all the <see cref="TXTRecord"/> for the queried domain.
+        /// </summary>
+        /// <remarks>
+        /// Uses the <see cref="GetRecords"/> method to retrieve an
+        /// array of <see cref="TXTRecord"/>s representing all the Address
+        /// records for the domain.
+        /// </remarks>
+        /// <value>An array of <see cref="SRVRecord"/> objects.</value>
+        public TXTRecord[] TXTRecords
+        {
+            get
+            {
+                ArrayList arr = GetRecords(DnsRecordType.TEXT);
+                return (TXTRecord[])arr.ToArray(typeof(TXTRecord));
+            }
+        }
+        /// <summary>
+        /// Gets all the <see cref="MXRecord"/> for the queried domain.
+        /// </summary>
+        /// <remarks>
+        /// Uses the <see cref="GetRecords"/> method to retrieve an
+        /// array of <see cref="MXRecord"/>s representing all the Mail Exchanger
+        /// records for the domain.
+        /// </remarks>
+        /// <value>An array of <see cref="MXRecord"/> objects.</value>
+        public MXRecord[] MXRecords
+        {
+            get
+            {
+                ArrayList arr = GetRecords(DnsRecordType.MX);
+                return (MXRecord[]) arr.ToArray(typeof(MXRecord));
+            }
+        }
+    }
+
+    namespace Records
+    {
+        /// <summary>
+        /// Represents a DNS Text record (DNS_TXT_DATA)
+        /// </summary>
+        /// <remarks>
+        /// The TXTRecord structure is used in conjunction with
+        /// the <see cref="DnsRequest"/> and <see cref="DnsResponse"/>
+        /// classes to programmatically manage DNS entries.
+        /// </remarks>
+        [StructLayout(LayoutKind.Sequential)]
+        public struct TXTRecord
+        {
+            /// <summary>
+            /// Gets or sets the string count
+            /// </summary>
+            /// <remarks>
+            /// Number of strings represented in pStringArray.
+            /// </remarks>
+            public uint StringCount;
+
+            /// <summary>
+            /// Gets or sets the string array
+            /// </summary>
+            /// <remarks>
+            /// Array of strings representing the descriptive text of the
+            /// TXT resource record.
+            /// </remarks>
+            public string StringArray;
+
+            /// <summary>
+            /// Returns a string representation of this record.
+            /// </summary>
+            /// <returns></returns>
+            /// <remarks>
+            /// The string returned looks like:
+            /// <code>
+            /// string count: [COUNT] string array: [ARR]
+            /// where [COUNT] = string representation of <see cref="StringCount"/>
+            /// and   [ARR] = string representation of <see cref="StringArray"/>
+            /// </code>
+            /// </remarks>
+            public override string ToString()
+            {
+                return String.Format(
+                    "string count: {0} string array: {1}",
+                    StringCount,
+                    StringArray
+                    );
+            }
+        }
+
+        /// <summary>
+        /// Represents a DNS Server record. (DNS_SRV_DATA)
+        /// </summary>
+        /// <remarks>
+        /// The SRVRecord structure is used in conjunction with
+        /// the <see cref="DnsRequest"/> and <see cref="DnsResponse"/>
+        /// classes to programmatically manage DNS entries.
+        /// </remarks>
+        [StructLayout(LayoutKind.Sequential)]
+        public struct SRVRecord
+        {
+            /// <summary>
+            /// Gets or sets the name
+            /// </summary>
+            /// <remarks>
+            /// Pointer to a string representing the target host.
+            /// </remarks>
+            public string NameNext;
+
+            /// <summary>
+            /// Gets or sets the priority
+            /// </summary>
+            /// <remarks>
+            /// Priority of the target host specified in the owner name. Lower numbers imply higher priority.
+            /// </remarks>
+            public ushort Priority;
+
+            /// <summary>
+            /// Gets or sets the weight
+            /// </summary>
+            /// <remarks>
+            /// Weight of the target host. Useful when selecting among hosts with the same priority. The chances of using this host should be proportional to its weight.
+            /// </remarks>
+            public ushort Weight;
+
+            /// <summary>
+            /// Gets or sets the port
+            /// </summary>
+            /// <remarks>
+            /// Port used on the terget host for the service.
+            /// </remarks>
+            public ushort Port;
+
+            /// <summary>
+            /// Reserved.
+            /// </summary>
+            /// <remarks>
+            /// Reserved. Used to keep pointers DWORD aligned.
+            /// </remarks>
+            public ushort Pad;
+
+            /// <summary>
+            /// Returns a string representation of this record.
+            /// </summary>
+            /// <returns></returns>
+            /// <remarks>
+            /// The string returned looks like:
+            /// <code>
+            /// name next: [SERVER] priority: [PRIOR] weight: [WEIGHT] port: [PORT]
+            /// where [SERVER] = string representation of <see cref="NameNext"/>
+            /// and   [PRIOR] = string representation of <see cref="Priority"/>
+            /// and   [WEIGHT] = string representation of <see cref="Weight"/>
+            /// and   [PORT] = string representation of <see cref="Port"/>
+            /// </code>
+            /// </remarks>
+            public override string ToString()
+            {
+                return String.Format(
+                    "name next: {0} priority: {1} weight: {2} port: {3}",
+                    NameNext,
+                    Priority,
+                    Weight,
+                    Port
+                    );
+            }
+        }
+
+        /// <summary>
+        /// Represents a DNS Start Of Authority record (DNS_SOA_DATA)
+        /// </summary>
+        /// <remarks>
+        /// The SOARecord structure is used in conjunction with
+        /// the <see cref="DnsRequest"/> and <see cref="DnsResponse"/>
+        /// classes to programmatically manage DNS entries.
+        /// </remarks>
+        [StructLayout(LayoutKind.Sequential)]
+        public struct SOARecord
+        {
+            /// <summary>
+            /// Gets or sets the primary server
+            /// </summary>
+            /// <remarks>
+            /// Pointer to a string representing the name of the authoritative
+            /// DNS server for the zone to which the record belongs.
+            /// </remarks>
+            public string PrimaryServer;
+
+            /// <summary>
+            /// Gets or sets the name of the administrator
+            /// </summary>
+            /// <remarks>
+            /// Pointer to a string representing the name of the responsible party
+            /// for the zone to which the record belongs.
+            /// </remarks>
+            public string Administrator;
+
+            /// <summary>
+            /// Gets or sets the serial number
+            /// </summary>
+            /// <remarks>
+            /// Serial number of the SOA record.
+            /// </remarks>
+            public uint SerialNo;
+
+            /// <summary>
+            /// Gets or sets the refresh
+            /// </summary>
+            /// <remarks>
+            /// Time, in seconds, before the zone containing this record should be
+            /// refreshed.
+            /// </remarks>
+            public uint Refresh;
+
+            /// <summary>
+            /// Gets or sets the retry count
+            /// </summary>
+            /// <remarks>
+            /// Time, in seconds, before retrying a failed refresh of the zone to
+            /// which this record belongs
+            /// </remarks>
+            public uint Retry;
+
+            /// <summary>
+            /// Gets or sets the expiration
+            /// </summary>
+            /// <remarks>
+            /// Time, in seconds, before an unresponsive zone is no longer authoritative.
+            /// </remarks>
+            public uint Expire;
+
+            /// <summary>
+            /// Gets or sets the default ttl
+            /// </summary>
+            /// <remarks>
+            /// Lower limit on the time, in seconds, that a DNS server or caching
+            /// resolver are allowed to cache any RRs from the zone to which this
+            /// record belongs.
+            /// </remarks>
+            public uint DefaultTtl;
+
+            /// <summary>
+            /// Returns a string representation of the Start Of Authority record.
+            /// </summary>
+            /// <returns></returns>
+            /// <remarks>
+            /// The string returned looks like:
+            /// <code>
+            /// administrator: [ADMIN] TTL: [TTL] primary server: [SERVER] refresh: [REFRESH] retry: [RETRY] serial number: [SERIAL]
+            /// where [ADMIN] = string representation of <see cref="Administrator"/>
+            /// and   [TTL] = string representation of <see cref="DefaultTtl"/>
+            /// and   [SERVER] = string representation of <see cref="PrimaryServer"/>
+            /// and   [REFRESH] = string representation of <see cref="Refresh"/>
+            /// and   [RETRY] = string representation of <see cref="Retry"/>
+            /// and   [SERIAL] = string representation of <see cref="SerialNo"/>
+            /// </code>
+            /// </remarks>
+            public override string ToString()
+            {
+                return String.Format(
+                    "administrator: {0} TTL: {1} primary server: {2} refresh: {3} retry: {4} serial number: {5}",
+                    Administrator,
+                    DefaultTtl,
+                    PrimaryServer,
+                    Refresh,
+                    Retry,
+                    SerialNo
+                    );
+            }
+        }
+
+        /// <summary>
+        /// Represents the DNS pointer record (DNS_PTR_DATA)
+        /// </summary>
+        /// <remarks>
+        /// The PTRRecord structure is used in conjunction with
+        /// the <see cref="DnsRequest"/> and <see cref="DnsResponse"/>
+        /// classes to programmatically manage DNS entries.
+        /// </remarks>
+        [StructLayout(LayoutKind.Sequential)]
+        public struct PTRRecord
+        {
+            /// <summary>
+            /// Gets or sets the hostname of the record.
+            /// </summary>
+            /// <remarks>
+            /// Pointer to a string representing the pointer (PTR) record data.
+            /// </remarks>
+            public string HostName;
+
+            /// <summary>
+            /// Returns a string representation of the pointer record.
+            /// </summary>
+            /// <returns></returns>
+            /// <remarks>
+            /// The string returned looks like:
+            /// <code>
+            /// Hostname: [HOST]
+            /// where [HOST] = string representation of <see cref="HostName"/>
+            /// </code>
+            /// </remarks>
+            public override string ToString()
+            {
+                return String.Format("Hostname: {0}", HostName);
+            }
+        }
+
+        /// <summary>
+        /// Represents a DNS Mail Exchange record (DNS_MX_DATA).
+        /// </summary>
+        /// <remarks>
+        /// The MXRecord structure is used in conjunction with
+        /// the <see cref="DnsRequest"/> and <see cref="DnsResponse"/>
+        /// classes to programmatically manage DNS entries.
+        /// </remarks>
+        [StructLayout(LayoutKind.Sequential)]
+        public struct MXRecord
+        {
+            /// <summary>
+            /// Gets or sets the exchange's host name
+            /// </summary>
+            /// <remarks>
+            /// Pointer to a string representing the fully qualified domain name
+            /// (FQDN) of the host willing to act as a mail exchange.
+            /// </remarks>
+            public string Exchange;
+
+            /// <summary>
+            /// Gets or sets the preference of the exchange.
+            /// </summary>
+            /// <remarks>
+            /// Preference given to this resource record among others at the same
+            /// owner. Lower values are preferred.
+            /// </remarks>
+            public ushort Preference;
+
+            /// <summary>
+            /// Reserved.
+            /// </summary>
+            /// <remarks>
+            /// Reserved. Used to keep pointers DWORD aligned.
+            /// </remarks>
+            public ushort Pad; // to keep dword aligned
+
+            /// <summary>
+            /// Returns a string representation of this mail exchange.
+            /// </summary>
+            /// <returns></returns>
+            /// <remarks>
+            /// The string returned looks like:
+            /// <code>
+            /// exchange (preference): [EXCH] ([PREF])
+            /// where [EXCH] = string representation of <see cref="Exchange"/>
+            /// and   [PREF] = hexadecimal representation of <see cref="Preference"/>
+            /// </code>
+            /// </remarks>
+            public override string ToString()
+            {
+                return String.Format(
+                    "exchange (preference): {0} ({1})",
+                    Exchange,
+                    Preference
+                    );
+            }
+        }
+
+        /// <summary>
+        /// Represents a DNS Address record (DNS_A_DATA)
+        /// </summary>
+        /// <remarks>
+        /// The ARecord structure is used in conjunction with
+        /// the <see cref="DnsRequest"/> and <see cref="DnsResponse"/>
+        /// classes to programmatically manage DNS entries.
+        /// </remarks>
+        [StructLayout(LayoutKind.Sequential)]
+        public struct ARecord
+        {
+            /// <summary>
+            /// Gets or sets the ip address.
+            /// </summary>
+            /// <remarks>
+            /// IPv4 address, in the form of an uint datatype.
+            /// <see cref="System.Net.IPAddress"/> could be
+            /// used to fill this property.
+            /// </remarks>
+            public uint Address;
+
+            /// <summary>
+            /// Returns a string representation of the A Record
+            /// </summary>
+            /// <returns></returns>
+            /// <remarks>
+            /// The string returned looks like:
+            /// <code>
+            /// ip address: [ADDRESS]
+            /// where [ADDRESS] = <see cref="System.Net.IPAddress.ToString()"/>
+            /// </code>
+            /// </remarks>
+            public override string ToString()
+            {
+                return String.Format(
+                    "ip address: {0}",
+                    new IPAddress(Address)
+                    );
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/stringprep/AssemblyInfo.cs b/lib/jabber-net/stringprep/AssemblyInfo.cs
new file mode 100644
index 0000000..4a03ff5
--- /dev/null
+++ b/lib/jabber-net/stringprep/AssemblyInfo.cs
@@ -0,0 +1,74 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net can be used under either JOSL or the GPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System.Reflection;
+
+using System.Runtime.CompilerServices;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly: AssemblyTitle("")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+//
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly: AssemblyVersion("1.0.*")]
+
+//
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly signing.
+//
+// Use the attributes below to control which key is used for signing.
+//
+// Notes:
+//   (*) If no key is specified, the assembly is not signed.
+//   (*) KeyName refers to a key that has been installed in the Crypto Service
+//       Provider (CSP) on your machine. KeyFile refers to a file which contains
+//       a key.
+//   (*) If the KeyFile and the KeyName values are both specified, the
+//       following processing occurs:
+//       (1) If the KeyName can be found in the CSP, that key is used.
+//       (2) If the KeyName does not exist and the KeyFile does exist, the key
+//           in the KeyFile is installed into the CSP and used.
+//   (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
+//       When specifying the KeyFile, the location of the KeyFile should be
+//       relative to the project output directory which is
+//       %Project Directory%\obj\<configuration>. For example, if your KeyFile is
+//       located in the project directory, you would specify the AssemblyKeyFile
+//       attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
+//   (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
+//       documentation for more information on this.
+//
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyName("")]
+#if !NET20
+[assembly: AssemblyKeyFile(@"..\..\..\jabbernet.key")]
+#endif
diff --git a/lib/jabber-net/stringprep/Nameprep.cs b/lib/jabber-net/stringprep/Nameprep.cs
new file mode 100644
index 0000000..7c93247
--- /dev/null
+++ b/lib/jabber-net/stringprep/Nameprep.cs
@@ -0,0 +1,35 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using stringprep.steps;
+
+namespace stringprep
+{
+    /// <summary>
+    /// RFC 3491, "nameprep" profile, for internationalized domain names.
+    /// </summary>
+    public class Nameprep : Profile
+    {
+        /// <summary>
+        /// Create a nameprep instance.
+        /// </summary>
+        public Nameprep() :
+            base( new ProfileStep[] {   B_1, B_2, NFKC,
+                                        C_1_2, C_2_2, C_3, C_4, C_5, C_6, C_7, C_8, C_9,
+                                        BIDI, UNASSIGNED} )
+        {
+        }
+    }
+}
diff --git a/lib/jabber-net/stringprep/Plain.cs b/lib/jabber-net/stringprep/Plain.cs
new file mode 100644
index 0000000..5107bc1
--- /dev/null
+++ b/lib/jabber-net/stringprep/Plain.cs
@@ -0,0 +1,35 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using stringprep.steps;
+
+namespace stringprep
+{
+    /// <summary>
+    /// A relatively plain stringprep profile, that doesn't do case folding, or prevent unassigned characters.
+    /// </summary>
+    public class Plain : Profile
+    {
+        /// <summary>
+        /// Create a Plain instance.
+        /// </summary>
+        public Plain() :
+            base( new ProfileStep[] {   C_2_1, C_2_2,
+                                        C_3, C_4, C_5, C_6, C_8, C_9,
+                                        BIDI } )
+        {
+        }
+    }
+}
diff --git a/lib/jabber-net/stringprep/Profile.cs b/lib/jabber-net/stringprep/Profile.cs
new file mode 100644
index 0000000..b0dca52
--- /dev/null
+++ b/lib/jabber-net/stringprep/Profile.cs
@@ -0,0 +1,137 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Text;
+using System.Diagnostics;
+using stringprep.steps;
+
+namespace stringprep
+{
+
+    /// <summary>
+    /// Summary description for Prep.
+    /// </summary>
+    public class Profile
+    {
+        /// <summary>
+        /// RFC 3454, Appendix B.1
+        /// </summary>
+        public static readonly MapStep B_1 = new MapStep(RFC3454.B_1, "RFC3454.B_1");
+        /// <summary>
+        /// RFC 3454, Appendix B.2
+        /// </summary>
+        public static readonly MapStep B_2 = new MapStep(RFC3454.B_2, "RFC3454.B_2");
+        /// <summary>
+        /// RFC 3454, Appendix B.3
+        /// </summary>
+        public static readonly MapStep B_3 = new MapStep(RFC3454.B_3, "RFC3454.B_3");
+
+        /// <summary>
+        /// RFC 3454, Appendix C.1.1
+        /// </summary>
+        public static readonly ProhibitStep C_1_1 = new ProhibitStep(RFC3454.C_1_1, "RFC3454.C_1_1");
+        /// <summary>
+        /// RFC 3454, Appendix C.1.2
+        /// </summary>
+        public static readonly ProhibitStep C_1_2 = new ProhibitStep(RFC3454.C_1_2, "RFC3454.C_1_2");
+        /// <summary>
+        /// RFC 3454, Appendix C.2.1
+        /// </summary>
+        public static readonly ProhibitStep C_2_1 = new ProhibitStep(RFC3454.C_2_1, "RFC3454.C_2_1");
+        /// <summary>
+        /// RFC 3454, Appendix C.2.2
+        /// </summary>
+        public static readonly ProhibitStep C_2_2 = new ProhibitStep(RFC3454.C_2_2, "RFC3454.C_2_2");
+        /// <summary>
+        /// RFC 3454, Appendix C.3
+        /// </summary>
+        public static readonly ProhibitStep C_3   = new ProhibitStep(RFC3454.C_3, "RFC3454.C_3");
+        /// <summary>
+        /// RFC 3454, Appendix C.4
+        /// </summary>
+        public static readonly ProhibitStep C_4   = new ProhibitStep(RFC3454.C_4, "RFC3454.C_4");
+        /// <summary>
+        /// RFC 3454, Appendix C.5
+        /// </summary>
+        public static readonly ProhibitStep C_5   = new ProhibitStep(RFC3454.C_5, "RFC3454.C_5");
+        /// <summary>
+        /// RFC 3454, Appendix C.6
+        /// </summary>
+        public static readonly ProhibitStep C_6   = new ProhibitStep(RFC3454.C_6, "RFC3454.C_6");
+        /// <summary>
+        /// RFC 3454, Appendix C.7
+        /// </summary>
+        public static readonly ProhibitStep C_7   = new ProhibitStep(RFC3454.C_7, "RFC3454.C_7");
+        /// <summary>
+        /// RFC 3454, Appendix C.8
+        /// </summary>
+        public static readonly ProhibitStep C_8   = new ProhibitStep(RFC3454.C_8, "RFC3454.C_8");
+        /// <summary>
+        /// RFC 3454, Appendix C.9
+        /// </summary>
+        public static readonly ProhibitStep C_9   = new ProhibitStep(RFC3454.C_9, "RFC3454.C_9");
+
+        /// <summary>
+        /// RFC 3454, Section 4
+        /// </summary>
+        public static readonly NFKCStep NFKC = new NFKCStep();
+        /// <summary>
+        /// RFC 3454, Section 6
+        /// </summary>
+        public static readonly BidiStep BIDI = new BidiStep();
+        /// <summary>
+        /// RFC 3454, Section 7
+        /// </summary>
+        public static readonly ProhibitStep UNASSIGNED = new ProhibitStep(RFC3454.A_1, "RFC3454.A_1");
+
+        private ProfileStep[] m_profile;
+
+        /// <summary>
+        /// Create a new profile, with the given steps.
+        /// </summary>
+        /// <param name="profile">The steps to perform</param>
+        public Profile(ProfileStep[] profile)
+        {
+            m_profile = profile;
+        }
+
+        /// <summary>
+        /// Prepare a string, according to the specified profile.
+        /// </summary>
+        /// <param name="input">The string to prepare</param>
+        /// <returns>The prepared string</returns>
+        public string Prepare(string input)
+        {
+            StringBuilder result = new StringBuilder(input);
+            Prepare(result);
+            return result.ToString();
+        }
+
+        /// <summary>
+        /// Prepare a string, according to the specified profile, in place.
+        /// Not thread safe; make sure the input is locked, if appropriate.
+        /// (this is the canonical version, that should be overriden by
+        /// subclasses if necessary)
+        /// </summary>
+        /// <param name="result">The string to prepare in place</param>
+        public virtual void Prepare(StringBuilder result)
+        {
+            foreach (ProfileStep step in m_profile)
+            {
+                step.Prepare(result);
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/stringprep/ResTool/AssemblyInfo.cs b/lib/jabber-net/stringprep/ResTool/AssemblyInfo.cs
new file mode 100644
index 0000000..b38a2c6
--- /dev/null
+++ b/lib/jabber-net/stringprep/ResTool/AssemblyInfo.cs
@@ -0,0 +1,72 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net can be used under either JOSL or the GPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System.Reflection;
+
+using System.Runtime.CompilerServices;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly: AssemblyTitle("")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+//
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly: AssemblyVersion("1.0.*")]
+
+//
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly signing.
+//
+// Use the attributes below to control which key is used for signing.
+//
+// Notes:
+//   (*) If no key is specified, the assembly is not signed.
+//   (*) KeyName refers to a key that has been installed in the Crypto Service
+//       Provider (CSP) on your machine. KeyFile refers to a file which contains
+//       a key.
+//   (*) If the KeyFile and the KeyName values are both specified, the
+//       following processing occurs:
+//       (1) If the KeyName can be found in the CSP, that key is used.
+//       (2) If the KeyName does not exist and the KeyFile does exist, the key
+//           in the KeyFile is installed into the CSP and used.
+//   (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
+//       When specifying the KeyFile, the location of the KeyFile should be
+//       relative to the project output directory which is
+//       %Project Directory%\obj\<configuration>. For example, if your KeyFile is
+//       located in the project directory, you would specify the AssemblyKeyFile
+//       attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
+//   (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
+//       documentation for more information on this.
+//
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyKeyName("")]
diff --git a/lib/jabber-net/stringprep/ResTool/Main.cs b/lib/jabber-net/stringprep/ResTool/Main.cs
new file mode 100644
index 0000000..dc0d763
--- /dev/null
+++ b/lib/jabber-net/stringprep/ResTool/Main.cs
@@ -0,0 +1,55 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net can be used under either JOSL or the GPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Resources;
+using System.Reflection;
+
+namespace ResTool
+{
+    /// <summary>
+    /// Summary description for Class1.
+    /// </summary>
+    class MainApp
+    {
+        /// <summary>
+        /// The main entry point for the application.
+        /// </summary>
+        [STAThread]
+        static void Main(string[] args)
+        {
+            if (args.Length < 2)
+            {
+                Console.WriteLine("Usage: ResTool <assembly> <resxfile>");
+                Environment.Exit(64);
+            }
+            Assembly asy = Assembly.LoadFrom(args[0]);
+            ResXResourceWriter resx = new ResXResourceWriter(args[1]);
+            foreach (Type t in asy.GetTypes())
+            {
+                foreach (FieldInfo fi in t.GetFields())
+                {
+                    if (!fi.IsStatic)
+                        continue;
+
+                    string n = t.Name + "." + fi.Name;
+                    Console.WriteLine(n);
+
+                    resx.AddResource(n, fi.GetValue(null));
+                }
+            }
+            resx.Close();
+        }
+    }
+}
diff --git a/lib/jabber-net/stringprep/XmppNode.cs b/lib/jabber-net/stringprep/XmppNode.cs
new file mode 100644
index 0000000..43e863b
--- /dev/null
+++ b/lib/jabber-net/stringprep/XmppNode.cs
@@ -0,0 +1,50 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using stringprep.steps;
+
+namespace stringprep
+{
+    /// <summary>
+    /// A stringprep profile for draft-ietf-xmpp-nodeprep-02, for Jabber nodes (the "user" part).
+    /// </summary>
+    public class XmppNode : Profile
+    {
+        private static readonly ProhibitStep XmppNodeprepProhibit =
+            new ProhibitStep(new char[][]
+                {   // note: these *must* be sorted by code.
+                    new char[] {'"', '\x0000'},
+                    new char[] {'&', '\x0000'},
+                    new char[] {'\'', '\x0000'},
+                    new char[] {'/', '\x0000'},
+                    new char[] {':', '\x0000'},
+                    new char[] {'<', '\x0000'},
+                    new char[] {'>', '\x0000'},
+                    new char[] {'@', '\x0000'},
+                }, "XMPP Node");
+
+        /// <summary>
+        /// Create a new XmppNode profile instance.
+        /// </summary>
+        public XmppNode() :
+            base( new ProfileStep[] {   B_1, B_2, NFKC,
+                                        C_1_1, C_1_2, C_2_1, C_2_2,
+                                        C_3, C_4, C_5, C_6, C_7, C_8, C_9,
+                                        XmppNodeprepProhibit,
+                                        BIDI, UNASSIGNED} )
+        {
+        }
+    }
+}
diff --git a/lib/jabber-net/stringprep/XmppResource.cs b/lib/jabber-net/stringprep/XmppResource.cs
new file mode 100644
index 0000000..31a0693
--- /dev/null
+++ b/lib/jabber-net/stringprep/XmppResource.cs
@@ -0,0 +1,36 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using stringprep.steps;
+
+namespace stringprep
+{
+    /// <summary>
+    /// A stringprep profile for draft-ietf-xmpp-resourceprep-02, used for Jabber resources.
+    /// </summary>
+    public class XmppResource : Profile
+    {
+        /// <summary>
+        /// Create an instance of an XmppResource
+        /// </summary>
+        public XmppResource() :
+            base( new ProfileStep[] {   B_1, NFKC,
+                                        C_1_2, C_2_1, C_2_2,
+                                        C_3, C_4, C_5, C_6, C_7, C_8, C_9,
+                                        BIDI, UNASSIGNED} )
+        {
+        }
+    }
+}
diff --git a/lib/jabber-net/stringprep/steps/BidiStep.cs b/lib/jabber-net/stringprep/steps/BidiStep.cs
new file mode 100644
index 0000000..baffcd3
--- /dev/null
+++ b/lib/jabber-net/stringprep/steps/BidiStep.cs
@@ -0,0 +1,106 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+
+namespace stringprep.steps
+{
+    /// <summary>
+    /// There was a problem with the Bidirection nature of a string to be prepped.
+    /// </summary>
+    public class BidiException : Exception
+    {
+        /// <summary>
+        /// Create a new BidiException
+        /// </summary>
+        /// <param name="message"></param>
+        public BidiException(string message) : base(message)
+        {
+        }
+    }
+
+    /// <summary>
+    /// A stringprep profile step to check for Bidirectional correctness.
+    /// If the NO_BIDI flag is set, this is a no-op.
+    /// </summary>
+    public class BidiStep : ProfileStep
+    {
+        private static ProhibitStep m_prohibit = new ProhibitStep(RFC3454.C_8, "RFC3454.C_8");
+        private static BidiRALStep  m_ral      = new BidiRALStep();
+        private static ProhibitStep m_lcat     = new ProhibitStep(RFC3454.D_2, "RFC3454.D_2");
+
+        /// <summary>
+        /// Create a new BidiStep.
+        /// </summary>
+        public BidiStep() : base("BIDI")
+        {
+        }
+
+        /// <summary>
+        /// Perform BiDi checks.
+        ///
+        /// From RFC 3454, Section 6:
+        /// In any profile that specifies bidirectional character handling, all
+        /// three of the following requirements MUST be met:
+        /// <ol>
+        /// <li>The characters in section 5.8 MUST be prohibited.</li>
+        /// <li>If a string contains any RandALCat character, the string MUST NOT
+        /// contain any LCat character.</li>
+        /// <li> If a string contains any RandALCat character, a RandALCat
+        /// character MUST be the first character of the string, and a
+        /// RandALCat character MUST be the last character of the string.</li>
+        /// </ol>
+        /// </summary>
+        /// <param name="result">Result is modified in place.</param>
+        /// <exception cref="BidiException">A BiDi problem exists</exception>
+        public override void Prepare(System.Text.StringBuilder result)
+        {
+            // prohibit section 5.8
+            m_prohibit.Prepare(result);
+
+            if (m_ral.FindStringInTable(result) >= 0)
+            {
+                // If a string contains any RandALCat character, the string MUST NOT
+                // contain any LCat character.
+                if (m_lcat.FindStringInTable(result) >= 0)
+                {
+                    throw new BidiException("String contains both L and RAL characters");
+                }
+
+                m_ral.CheckEnds(result);
+            }
+
+        }
+
+        private class BidiRALStep : ProhibitStep
+        {
+            public BidiRALStep() : base(RFC3454.D_1, "RFC3454.D_1")
+            {
+            }
+
+            public void CheckEnds(System.Text.StringBuilder result)
+            {
+                //  3) If a string contains any RandALCat character, a RandALCat
+                // character MUST be the first character of the string, and a
+                // RandALCat character MUST be the last character of the string.
+                if (!Contains(result[0]) || !Contains(result[result.Length - 1]))
+                {
+                    throw new BidiException("Bidi string does not start/end with RAL characters");
+                }
+            }
+        }
+    }
+
+
+}
diff --git a/lib/jabber-net/stringprep/steps/MapStep.cs b/lib/jabber-net/stringprep/steps/MapStep.cs
new file mode 100644
index 0000000..3fa477e
--- /dev/null
+++ b/lib/jabber-net/stringprep/steps/MapStep.cs
@@ -0,0 +1,87 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Text;
+using System.Collections;
+
+namespace stringprep.steps
+{
+    /// <summary>
+    /// A stringprep profile step to map one input character into 0 or
+    /// more output characters.
+    /// </summary>
+    public class MapStep : ProfileStep
+    {
+        private string[] m_table = null;
+        private static IComparer m_comp = new CharMapComparer();
+
+        /// <summary>
+        /// Map from one character to 0+
+        /// </summary>
+        /// <param name="table"></param>
+        /// <param name="name"></param>
+        public MapStep(string[] table, string name): base(name)
+        {
+            m_table = table;
+        }
+
+        /// <summary>
+        /// Perform mapping for each character of input.
+        /// </summary>
+        /// <param name="result">Result is modified in place.</param>
+        public override void Prepare(System.Text.StringBuilder result)
+        {
+            // From RFC3454, section 3: Mapped characters are not
+            // re-scanned during the mapping step.  That is, if
+            // character A at position X is mapped to character B,
+            // character B which is now at position X is not checked
+            // against the mapping table.
+            int pos;
+            string map;
+            int len;
+            for (int i=0; i<result.Length; i++)
+            {
+                pos = Array.BinarySearch(m_table, result[i], m_comp);
+                if (pos < 0)
+                    continue;
+
+                map = m_table[pos];
+                len = map.Length;
+                if (len == 1)
+                {
+                    result.Remove(i, 1);
+                    i--;
+                }
+                else
+                {
+                    result[i] = map[1];
+                    if (len > 2)
+                    {
+                        result.Insert(i+1, map.ToCharArray(2, len - 2));
+                        i += len - 2;
+                    }
+                }
+            }
+        }
+
+        private class CharMapComparer : IComparer
+        {
+            public int Compare(object x, object y)
+            {
+                return ((string)x)[0].CompareTo(y);
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/stringprep/steps/NFKCStep.cs b/lib/jabber-net/stringprep/steps/NFKCStep.cs
new file mode 100644
index 0000000..4a2ab9b
--- /dev/null
+++ b/lib/jabber-net/stringprep/steps/NFKCStep.cs
@@ -0,0 +1,177 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+
+
+/*
+ * Assumption: UCS2.  The astral planes don't exist.  At least according to windows?
+ *
+ * Look over here.  Something shiny!
+ */
+using System;
+using System.Text;
+using stringprep.unicode;
+
+namespace stringprep.steps
+{
+    /// <summary>
+    /// Perform Unicode Normalization Form KC.
+    /// </summary>
+    public class NFKCStep : ProfileStep
+    {
+        /// <summary>
+        /// Create an NFKC step.
+        /// </summary>
+        public NFKCStep() : base("NFKC")
+        {
+        }
+
+        /// <summary>
+        /// Perform NFKC.  General overview: Decompose, Reorder, Compose
+        /// </summary>
+        /// <param name="result"></param>
+        public override void Prepare(StringBuilder result)
+        {
+            // From Unicode TR15: (http://www.unicode.org/reports/tr15)
+            // R1. Normalization Form C
+            // The Normalization Form C for a string S is obtained by applying the following process,
+            // or any other process that leads to the same result:
+            //
+            // 1) Generate the canonical decomposition for the source string S according to the
+            // decomposition mappings in the latest supported version of the Unicode Character Database.
+            //
+            // 2) Iterate through each character C in that decomposition, from first to last.
+            // If C is not blocked from the last starter L, and it can be primary combined with L,
+            // then replace L by the composite L-C, and remove C.
+            Decomp(result);
+
+            if (result.Length > 0)
+            {
+                CanonicalOrdering(result);
+                Comp(result);
+            }
+        }
+
+
+        private void Decomp(StringBuilder result)
+        {
+            int len;
+            string ex;
+
+            // Decompose
+            for (int i=0; i< result.Length; i++)
+            {
+                ex = Decompose.Find(result[i]);
+                if (ex == null)
+                    continue;
+
+                result[i] = ex[0];
+                len = ex.Length - 1;
+                if (len > 0)
+                {
+                    result.Insert(i+1, ex.ToCharArray(1, ex.Length-1));
+                    i += len;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Reorder characters in the given range into their correct cannonical ordering with
+        /// respect to combining class.
+        /// </summary>
+        /// <param name="buf">Buffer to reorder</param>
+        private void CanonicalOrdering(StringBuilder buf)
+        {
+            int i, j;
+            bool swap = false;
+            int p_a, p_b;
+            char t;
+            int start = 0;
+            int stop = buf.Length - 1;
+
+            // From Unicode 3.0, section 3.10
+            // R1 For each character x in D, let p(x) be the combining class of x
+            // R2 Wenever any pair (A, B) of adjacent characters in D is such that p(B)!=0 and
+            //    p(A)>p(B), exchange those characters
+            // R3 Repeat step R2 until no exchanges can be made among any of the characters in D
+            do
+            {
+                swap = false;
+                p_a = Combining.Class(buf[start]);
+
+                for (i = start; i < stop; i++)
+                {
+                    p_b = Combining.Class(buf[i + 1]);
+                    if ((p_b != 0) && (p_a > p_b))
+                    {
+                        for (j = i; j > 0; j--)
+                        {
+                            if (Combining.Class(buf[j]) <= p_b)
+                                break;
+
+                            t = buf[j + 1];
+                            buf[j + 1] = buf[j];
+                            buf[j] = t;
+                            swap = true;
+                        }
+                        /* We're re-entering the loop looking at the old
+                           character again.  Don't reset p_a.*/
+                        continue;
+                    }
+                    p_a = p_b;
+
+                    // once we get to a start character without any swaps,
+                    // there can be no further changes.  No sense constantly
+                    // rechecking stuff we've already checked.
+                    if (!swap && (p_a == 0))
+                        start = i;
+                }
+            } while (swap);
+        }
+
+        private void Comp(StringBuilder result)
+        {
+            // All decomposed and reordered.
+            // Combine all combinable characters.
+            int cc;
+            int last_cc = 0;
+            char c;
+            int last_start = 0;
+
+            for (int i=0; i<result.Length; i++)
+            {
+                cc = Combining.Class(result[i]);
+                if ((i > 0) &&
+                    ((last_cc == 0) || (last_cc != cc)) &&
+                    Compose.Combine(result[last_start], result[i], out c))
+                {
+                    result[last_start] = c;
+                    result.Remove(i, 1);
+                    i--;
+
+                    if (i == last_start)
+                        last_cc = 0;
+                    else
+                        last_cc = Combining.Class(result[i - 1]);
+
+                    continue;
+                }
+
+                if (cc == 0)
+                    last_start = i;
+
+                last_cc = cc;
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/stringprep/steps/ProfileStep.cs b/lib/jabber-net/stringprep/steps/ProfileStep.cs
new file mode 100644
index 0000000..8094ec6
--- /dev/null
+++ b/lib/jabber-net/stringprep/steps/ProfileStep.cs
@@ -0,0 +1,50 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Text;
+
+namespace stringprep.steps
+{
+    /// <summary>
+    /// Base class for steps in a stringprep profile.
+    /// </summary>
+    public abstract class ProfileStep
+    {
+        private string m_name;
+
+        /// <summary>
+        /// Create a named profile step, with no flags.
+        /// </summary>
+        /// <param name="name">The profile name</param>
+        protected ProfileStep(string name)
+        {
+            m_name = name;
+        }
+
+        /// <summary>
+        /// The name of the step.
+        /// </summary>
+        public virtual string Name
+        {
+            get { return m_name; }
+        }
+
+        /// <summary>
+        /// This is the workhorse function, to be implemented in each subclass.
+        /// </summary>
+        /// <param name="result">Result will be modified in place</param>
+        public abstract void Prepare(StringBuilder result);
+    }
+}
diff --git a/lib/jabber-net/stringprep/steps/ProhibitStep.cs b/lib/jabber-net/stringprep/steps/ProhibitStep.cs
new file mode 100644
index 0000000..b138a97
--- /dev/null
+++ b/lib/jabber-net/stringprep/steps/ProhibitStep.cs
@@ -0,0 +1,138 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using System.Text;
+
+namespace stringprep.steps
+{
+    /// <summary>
+    /// A character that is forbidden by the current stringprep profile exists in the input.
+    /// </summary>
+    public class ProhibitedCharacterException : Exception
+    {
+        /// <summary>
+        /// The character that was invalid.
+        /// </summary>
+        public char InvalidChar;
+
+        /// <summary>
+        /// Create an instance.
+        /// </summary>
+        /// <param name="step">In which step did this occur?</param>
+        /// <param name="c">The offending character</param>
+        public ProhibitedCharacterException(ProfileStep step, char c) :
+            base(string.Format("Step {0} prohibits string (character U+{1:x04}).", step.Name, (ushort) c))
+        {
+            InvalidChar = c;
+        }
+    }
+
+    /// <summary>
+    /// A stringprep profile step that checks for prohibited characters
+    /// </summary>
+    public class ProhibitStep : ProfileStep
+    {
+        private char[][] m_table = null;
+        private ProhibitComparer m_comp = new ProhibitComparer();
+
+        /*
+        /// <summary>
+        /// Create an instance.
+        /// </summary>
+        /// <param name="tab">The prohibit table to be checked</param>
+        /// <param name="name">The name of the step (for debugging purposes)</param>
+        public ProhibitStep(string name) : base(name)
+        {
+        }
+        */
+
+        /// <summary>
+        /// These characters are prohibited
+        /// </summary>
+        /// <param name="table"></param>
+        /// <param name="name"></param>
+        public ProhibitStep(char[][] table, string name): base(name)
+        {
+            m_table = table;
+        }
+
+        /// <summary>
+        /// Does this step prohibit the given character?
+        /// </summary>
+        /// <param name="c">The character to check</param>
+        /// <returns>True if the character is prohibited</returns>
+        protected bool Contains(char c)
+        {
+            return (Array.BinarySearch(m_table, c, m_comp) >= 0);
+        }
+
+        /// <summary>
+        /// Check all of the characters for prohbition.
+        /// </summary>
+        /// <param name="s">String to check</param>
+        /// <returns>If one of the characters is prohibited, returns the index of that character.
+        /// If all are allowed, returns -1.</returns>
+        public int FindStringInTable(StringBuilder s)
+        {
+            for (int j=0; j<s.Length; j++)
+            {
+                if (Contains(s[j]))
+                {
+                    return j;
+                }
+            }
+            return -1;
+        }
+
+        /// <summary>
+        /// Check for prohibited characters
+        /// </summary>
+        /// <param name="result">No modifications</param>
+        /// <exception cref="ProhibitedCharacterException">Invalid character detected.</exception>
+        public override void Prepare(System.Text.StringBuilder result)
+        {
+            int j = FindStringInTable(result);
+            if (j >= 0)
+                throw new ProhibitedCharacterException(this, result[j]);
+        }
+
+        private class ProhibitComparer : IComparer
+        {
+            #region IComparer Members
+
+            public int Compare(object x, object y)
+            {
+                char[] bounds = (char[]) x;
+                if (bounds[1] == '\x0000')
+                    return bounds[0].CompareTo(y);
+
+                char c = (char) y;
+                if (c < bounds[0])
+                    return 1;
+
+                if (c > bounds[1])
+                    return -1;
+
+                return 0;
+            }
+
+            #endregion
+        }
+
+    }
+
+
+}
diff --git a/lib/jabber-net/stringprep/steps/RFC3454.cs b/lib/jabber-net/stringprep/steps/RFC3454.cs
new file mode 100644
index 0000000..70c345e
--- /dev/null
+++ b/lib/jabber-net/stringprep/steps/RFC3454.cs
@@ -0,0 +1,2655 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+/* This file is auto-generated.  DO NOT EDIT! */
+
+using System;
+namespace stringprep
+{
+    /// <summary>
+    /// Constants from RFC 3454, Stringprep.
+    /// </summary>
+    public class RFC3454
+    {
+
+        /// <summary>
+        /// A.1 Unassigned code points in Unicode 3.2
+        ///
+        /// </summary>
+        public static readonly char[][] A_1 = new char[][]
+        {
+            new char[] {'\x0221', '\x0000'},    /* 0221 */
+            new char[] {'\x0234', '\x024F'},    /* 0234-024F */
+            new char[] {'\x02AE', '\x02AF'},    /* 02AE-02AF */
+            new char[] {'\x02EF', '\x02FF'},    /* 02EF-02FF */
+            new char[] {'\x0350', '\x035F'},    /* 0350-035F */
+            new char[] {'\x0370', '\x0373'},    /* 0370-0373 */
+            new char[] {'\x0376', '\x0379'},    /* 0376-0379 */
+            new char[] {'\x037B', '\x037D'},    /* 037B-037D */
+            new char[] {'\x037F', '\x0383'},    /* 037F-0383 */
+            new char[] {'\x038B', '\x0000'},    /* 038B */
+            new char[] {'\x038D', '\x0000'},    /* 038D */
+            new char[] {'\x03A2', '\x0000'},    /* 03A2 */
+            new char[] {'\x03CF', '\x0000'},    /* 03CF */
+            new char[] {'\x03F7', '\x03FF'},    /* 03F7-03FF */
+            new char[] {'\x0487', '\x0000'},    /* 0487 */
+            new char[] {'\x04CF', '\x0000'},    /* 04CF */
+            new char[] {'\x04F6', '\x04F7'},    /* 04F6-04F7 */
+            new char[] {'\x04FA', '\x04FF'},    /* 04FA-04FF */
+            new char[] {'\x0510', '\x0530'},    /* 0510-0530 */
+            new char[] {'\x0557', '\x0558'},    /* 0557-0558 */
+            new char[] {'\x0560', '\x0000'},    /* 0560 */
+            new char[] {'\x0588', '\x0000'},    /* 0588 */
+            new char[] {'\x058B', '\x0590'},    /* 058B-0590 */
+            new char[] {'\x05A2', '\x0000'},    /* 05A2 */
+            new char[] {'\x05BA', '\x0000'},    /* 05BA */
+            new char[] {'\x05C5', '\x05CF'},    /* 05C5-05CF */
+            new char[] {'\x05EB', '\x05EF'},    /* 05EB-05EF */
+            new char[] {'\x05F5', '\x060B'},    /* 05F5-060B */
+            new char[] {'\x060D', '\x061A'},    /* 060D-061A */
+            new char[] {'\x061C', '\x061E'},    /* 061C-061E */
+            new char[] {'\x0620', '\x0000'},    /* 0620 */
+            new char[] {'\x063B', '\x063F'},    /* 063B-063F */
+            new char[] {'\x0656', '\x065F'},    /* 0656-065F */
+            new char[] {'\x06EE', '\x06EF'},    /* 06EE-06EF */
+            new char[] {'\x06FF', '\x0000'},    /* 06FF */
+            new char[] {'\x070E', '\x0000'},    /* 070E */
+            new char[] {'\x072D', '\x072F'},    /* 072D-072F */
+            new char[] {'\x074B', '\x077F'},    /* 074B-077F */
+            new char[] {'\x07B2', '\x0900'},    /* 07B2-0900 */
+            new char[] {'\x0904', '\x0000'},    /* 0904 */
+            new char[] {'\x093A', '\x093B'},    /* 093A-093B */
+            new char[] {'\x094E', '\x094F'},    /* 094E-094F */
+            new char[] {'\x0955', '\x0957'},    /* 0955-0957 */
+            new char[] {'\x0971', '\x0980'},    /* 0971-0980 */
+            new char[] {'\x0984', '\x0000'},    /* 0984 */
+            new char[] {'\x098D', '\x098E'},    /* 098D-098E */
+            new char[] {'\x0991', '\x0992'},    /* 0991-0992 */
+            new char[] {'\x09A9', '\x0000'},    /* 09A9 */
+            new char[] {'\x09B1', '\x0000'},    /* 09B1 */
+            new char[] {'\x09B3', '\x09B5'},    /* 09B3-09B5 */
+            new char[] {'\x09BA', '\x09BB'},    /* 09BA-09BB */
+            new char[] {'\x09BD', '\x0000'},    /* 09BD */
+            new char[] {'\x09C5', '\x09C6'},    /* 09C5-09C6 */
+            new char[] {'\x09C9', '\x09CA'},    /* 09C9-09CA */
+            new char[] {'\x09CE', '\x09D6'},    /* 09CE-09D6 */
+            new char[] {'\x09D8', '\x09DB'},    /* 09D8-09DB */
+            new char[] {'\x09DE', '\x0000'},    /* 09DE */
+            new char[] {'\x09E4', '\x09E5'},    /* 09E4-09E5 */
+            new char[] {'\x09FB', '\x0A01'},    /* 09FB-0A01 */
+            new char[] {'\x0A03', '\x0A04'},    /* 0A03-0A04 */
+            new char[] {'\x0A0B', '\x0A0E'},    /* 0A0B-0A0E */
+            new char[] {'\x0A11', '\x0A12'},    /* 0A11-0A12 */
+            new char[] {'\x0A29', '\x0000'},    /* 0A29 */
+            new char[] {'\x0A31', '\x0000'},    /* 0A31 */
+            new char[] {'\x0A34', '\x0000'},    /* 0A34 */
+            new char[] {'\x0A37', '\x0000'},    /* 0A37 */
+            new char[] {'\x0A3A', '\x0A3B'},    /* 0A3A-0A3B */
+            new char[] {'\x0A3D', '\x0000'},    /* 0A3D */
+            new char[] {'\x0A43', '\x0A46'},    /* 0A43-0A46 */
+            new char[] {'\x0A49', '\x0A4A'},    /* 0A49-0A4A */
+            new char[] {'\x0A4E', '\x0A58'},    /* 0A4E-0A58 */
+            new char[] {'\x0A5D', '\x0000'},    /* 0A5D */
+            new char[] {'\x0A5F', '\x0A65'},    /* 0A5F-0A65 */
+            new char[] {'\x0A75', '\x0A80'},    /* 0A75-0A80 */
+            new char[] {'\x0A84', '\x0000'},    /* 0A84 */
+            new char[] {'\x0A8C', '\x0000'},    /* 0A8C */
+            new char[] {'\x0A8E', '\x0000'},    /* 0A8E */
+            new char[] {'\x0A92', '\x0000'},    /* 0A92 */
+            new char[] {'\x0AA9', '\x0000'},    /* 0AA9 */
+            new char[] {'\x0AB1', '\x0000'},    /* 0AB1 */
+            new char[] {'\x0AB4', '\x0000'},    /* 0AB4 */
+            new char[] {'\x0ABA', '\x0ABB'},    /* 0ABA-0ABB */
+            new char[] {'\x0AC6', '\x0000'},    /* 0AC6 */
+            new char[] {'\x0ACA', '\x0000'},    /* 0ACA */
+            new char[] {'\x0ACE', '\x0ACF'},    /* 0ACE-0ACF */
+            new char[] {'\x0AD1', '\x0ADF'},    /* 0AD1-0ADF */
+            new char[] {'\x0AE1', '\x0AE5'},    /* 0AE1-0AE5 */
+            new char[] {'\x0AF0', '\x0B00'},    /* 0AF0-0B00 */
+            new char[] {'\x0B04', '\x0000'},    /* 0B04 */
+            new char[] {'\x0B0D', '\x0B0E'},    /* 0B0D-0B0E */
+            new char[] {'\x0B11', '\x0B12'},    /* 0B11-0B12 */
+            new char[] {'\x0B29', '\x0000'},    /* 0B29 */
+            new char[] {'\x0B31', '\x0000'},    /* 0B31 */
+            new char[] {'\x0B34', '\x0B35'},    /* 0B34-0B35 */
+            new char[] {'\x0B3A', '\x0B3B'},    /* 0B3A-0B3B */
+            new char[] {'\x0B44', '\x0B46'},    /* 0B44-0B46 */
+            new char[] {'\x0B49', '\x0B4A'},    /* 0B49-0B4A */
+            new char[] {'\x0B4E', '\x0B55'},    /* 0B4E-0B55 */
+            new char[] {'\x0B58', '\x0B5B'},    /* 0B58-0B5B */
+            new char[] {'\x0B5E', '\x0000'},    /* 0B5E */
+            new char[] {'\x0B62', '\x0B65'},    /* 0B62-0B65 */
+            new char[] {'\x0B71', '\x0B81'},    /* 0B71-0B81 */
+            new char[] {'\x0B84', '\x0000'},    /* 0B84 */
+            new char[] {'\x0B8B', '\x0B8D'},    /* 0B8B-0B8D */
+            new char[] {'\x0B91', '\x0000'},    /* 0B91 */
+            new char[] {'\x0B96', '\x0B98'},    /* 0B96-0B98 */
+            new char[] {'\x0B9B', '\x0000'},    /* 0B9B */
+            new char[] {'\x0B9D', '\x0000'},    /* 0B9D */
+            new char[] {'\x0BA0', '\x0BA2'},    /* 0BA0-0BA2 */
+            new char[] {'\x0BA5', '\x0BA7'},    /* 0BA5-0BA7 */
+            new char[] {'\x0BAB', '\x0BAD'},    /* 0BAB-0BAD */
+            new char[] {'\x0BB6', '\x0000'},    /* 0BB6 */
+            new char[] {'\x0BBA', '\x0BBD'},    /* 0BBA-0BBD */
+            new char[] {'\x0BC3', '\x0BC5'},    /* 0BC3-0BC5 */
+            new char[] {'\x0BC9', '\x0000'},    /* 0BC9 */
+            new char[] {'\x0BCE', '\x0BD6'},    /* 0BCE-0BD6 */
+            new char[] {'\x0BD8', '\x0BE6'},    /* 0BD8-0BE6 */
+            new char[] {'\x0BF3', '\x0C00'},    /* 0BF3-0C00 */
+            new char[] {'\x0C04', '\x0000'},    /* 0C04 */
+            new char[] {'\x0C0D', '\x0000'},    /* 0C0D */
+            new char[] {'\x0C11', '\x0000'},    /* 0C11 */
+            new char[] {'\x0C29', '\x0000'},    /* 0C29 */
+            new char[] {'\x0C34', '\x0000'},    /* 0C34 */
+            new char[] {'\x0C3A', '\x0C3D'},    /* 0C3A-0C3D */
+            new char[] {'\x0C45', '\x0000'},    /* 0C45 */
+            new char[] {'\x0C49', '\x0000'},    /* 0C49 */
+            new char[] {'\x0C4E', '\x0C54'},    /* 0C4E-0C54 */
+            new char[] {'\x0C57', '\x0C5F'},    /* 0C57-0C5F */
+            new char[] {'\x0C62', '\x0C65'},    /* 0C62-0C65 */
+            new char[] {'\x0C70', '\x0C81'},    /* 0C70-0C81 */
+            new char[] {'\x0C84', '\x0000'},    /* 0C84 */
+            new char[] {'\x0C8D', '\x0000'},    /* 0C8D */
+            new char[] {'\x0C91', '\x0000'},    /* 0C91 */
+            new char[] {'\x0CA9', '\x0000'},    /* 0CA9 */
+            new char[] {'\x0CB4', '\x0000'},    /* 0CB4 */
+            new char[] {'\x0CBA', '\x0CBD'},    /* 0CBA-0CBD */
+            new char[] {'\x0CC5', '\x0000'},    /* 0CC5 */
+            new char[] {'\x0CC9', '\x0000'},    /* 0CC9 */
+            new char[] {'\x0CCE', '\x0CD4'},    /* 0CCE-0CD4 */
+            new char[] {'\x0CD7', '\x0CDD'},    /* 0CD7-0CDD */
+            new char[] {'\x0CDF', '\x0000'},    /* 0CDF */
+            new char[] {'\x0CE2', '\x0CE5'},    /* 0CE2-0CE5 */
+            new char[] {'\x0CF0', '\x0D01'},    /* 0CF0-0D01 */
+            new char[] {'\x0D04', '\x0000'},    /* 0D04 */
+            new char[] {'\x0D0D', '\x0000'},    /* 0D0D */
+            new char[] {'\x0D11', '\x0000'},    /* 0D11 */
+            new char[] {'\x0D29', '\x0000'},    /* 0D29 */
+            new char[] {'\x0D3A', '\x0D3D'},    /* 0D3A-0D3D */
+            new char[] {'\x0D44', '\x0D45'},    /* 0D44-0D45 */
+            new char[] {'\x0D49', '\x0000'},    /* 0D49 */
+            new char[] {'\x0D4E', '\x0D56'},    /* 0D4E-0D56 */
+            new char[] {'\x0D58', '\x0D5F'},    /* 0D58-0D5F */
+            new char[] {'\x0D62', '\x0D65'},    /* 0D62-0D65 */
+            new char[] {'\x0D70', '\x0D81'},    /* 0D70-0D81 */
+            new char[] {'\x0D84', '\x0000'},    /* 0D84 */
+            new char[] {'\x0D97', '\x0D99'},    /* 0D97-0D99 */
+            new char[] {'\x0DB2', '\x0000'},    /* 0DB2 */
+            new char[] {'\x0DBC', '\x0000'},    /* 0DBC */
+            new char[] {'\x0DBE', '\x0DBF'},    /* 0DBE-0DBF */
+            new char[] {'\x0DC7', '\x0DC9'},    /* 0DC7-0DC9 */
+            new char[] {'\x0DCB', '\x0DCE'},    /* 0DCB-0DCE */
+            new char[] {'\x0DD5', '\x0000'},    /* 0DD5 */
+            new char[] {'\x0DD7', '\x0000'},    /* 0DD7 */
+            new char[] {'\x0DE0', '\x0DF1'},    /* 0DE0-0DF1 */
+            new char[] {'\x0DF5', '\x0E00'},    /* 0DF5-0E00 */
+            new char[] {'\x0E3B', '\x0E3E'},    /* 0E3B-0E3E */
+            new char[] {'\x0E5C', '\x0E80'},    /* 0E5C-0E80 */
+            new char[] {'\x0E83', '\x0000'},    /* 0E83 */
+            new char[] {'\x0E85', '\x0E86'},    /* 0E85-0E86 */
+            new char[] {'\x0E89', '\x0000'},    /* 0E89 */
+            new char[] {'\x0E8B', '\x0E8C'},    /* 0E8B-0E8C */
+            new char[] {'\x0E8E', '\x0E93'},    /* 0E8E-0E93 */
+            new char[] {'\x0E98', '\x0000'},    /* 0E98 */
+            new char[] {'\x0EA0', '\x0000'},    /* 0EA0 */
+            new char[] {'\x0EA4', '\x0000'},    /* 0EA4 */
+            new char[] {'\x0EA6', '\x0000'},    /* 0EA6 */
+            new char[] {'\x0EA8', '\x0EA9'},    /* 0EA8-0EA9 */
+            new char[] {'\x0EAC', '\x0000'},    /* 0EAC */
+            new char[] {'\x0EBA', '\x0000'},    /* 0EBA */
+            new char[] {'\x0EBE', '\x0EBF'},    /* 0EBE-0EBF */
+            new char[] {'\x0EC5', '\x0000'},    /* 0EC5 */
+            new char[] {'\x0EC7', '\x0000'},    /* 0EC7 */
+            new char[] {'\x0ECE', '\x0ECF'},    /* 0ECE-0ECF */
+            new char[] {'\x0EDA', '\x0EDB'},    /* 0EDA-0EDB */
+            new char[] {'\x0EDE', '\x0EFF'},    /* 0EDE-0EFF */
+            new char[] {'\x0F48', '\x0000'},    /* 0F48 */
+            new char[] {'\x0F6B', '\x0F70'},    /* 0F6B-0F70 */
+            new char[] {'\x0F8C', '\x0F8F'},    /* 0F8C-0F8F */
+            new char[] {'\x0F98', '\x0000'},    /* 0F98 */
+            new char[] {'\x0FBD', '\x0000'},    /* 0FBD */
+            new char[] {'\x0FCD', '\x0FCE'},    /* 0FCD-0FCE */
+            new char[] {'\x0FD0', '\x0FFF'},    /* 0FD0-0FFF */
+            new char[] {'\x1022', '\x0000'},    /* 1022 */
+            new char[] {'\x1028', '\x0000'},    /* 1028 */
+            new char[] {'\x102B', '\x0000'},    /* 102B */
+            new char[] {'\x1033', '\x1035'},    /* 1033-1035 */
+            new char[] {'\x103A', '\x103F'},    /* 103A-103F */
+            new char[] {'\x105A', '\x109F'},    /* 105A-109F */
+            new char[] {'\x10C6', '\x10CF'},    /* 10C6-10CF */
+            new char[] {'\x10F9', '\x10FA'},    /* 10F9-10FA */
+            new char[] {'\x10FC', '\x10FF'},    /* 10FC-10FF */
+            new char[] {'\x115A', '\x115E'},    /* 115A-115E */
+            new char[] {'\x11A3', '\x11A7'},    /* 11A3-11A7 */
+            new char[] {'\x11FA', '\x11FF'},    /* 11FA-11FF */
+            new char[] {'\x1207', '\x0000'},    /* 1207 */
+            new char[] {'\x1247', '\x0000'},    /* 1247 */
+            new char[] {'\x1249', '\x0000'},    /* 1249 */
+            new char[] {'\x124E', '\x124F'},    /* 124E-124F */
+            new char[] {'\x1257', '\x0000'},    /* 1257 */
+            new char[] {'\x1259', '\x0000'},    /* 1259 */
+            new char[] {'\x125E', '\x125F'},    /* 125E-125F */
+            new char[] {'\x1287', '\x0000'},    /* 1287 */
+            new char[] {'\x1289', '\x0000'},    /* 1289 */
+            new char[] {'\x128E', '\x128F'},    /* 128E-128F */
+            new char[] {'\x12AF', '\x0000'},    /* 12AF */
+            new char[] {'\x12B1', '\x0000'},    /* 12B1 */
+            new char[] {'\x12B6', '\x12B7'},    /* 12B6-12B7 */
+            new char[] {'\x12BF', '\x0000'},    /* 12BF */
+            new char[] {'\x12C1', '\x0000'},    /* 12C1 */
+            new char[] {'\x12C6', '\x12C7'},    /* 12C6-12C7 */
+            new char[] {'\x12CF', '\x0000'},    /* 12CF */
+            new char[] {'\x12D7', '\x0000'},    /* 12D7 */
+            new char[] {'\x12EF', '\x0000'},    /* 12EF */
+            new char[] {'\x130F', '\x0000'},    /* 130F */
+            new char[] {'\x1311', '\x0000'},    /* 1311 */
+            new char[] {'\x1316', '\x1317'},    /* 1316-1317 */
+            new char[] {'\x131F', '\x0000'},    /* 131F */
+            new char[] {'\x1347', '\x0000'},    /* 1347 */
+            new char[] {'\x135B', '\x1360'},    /* 135B-1360 */
+            new char[] {'\x137D', '\x139F'},    /* 137D-139F */
+            new char[] {'\x13F5', '\x1400'},    /* 13F5-1400 */
+            new char[] {'\x1677', '\x167F'},    /* 1677-167F */
+            new char[] {'\x169D', '\x169F'},    /* 169D-169F */
+            new char[] {'\x16F1', '\x16FF'},    /* 16F1-16FF */
+            new char[] {'\x170D', '\x0000'},    /* 170D */
+            new char[] {'\x1715', '\x171F'},    /* 1715-171F */
+            new char[] {'\x1737', '\x173F'},    /* 1737-173F */
+            new char[] {'\x1754', '\x175F'},    /* 1754-175F */
+            new char[] {'\x176D', '\x0000'},    /* 176D */
+            new char[] {'\x1771', '\x0000'},    /* 1771 */
+            new char[] {'\x1774', '\x177F'},    /* 1774-177F */
+            new char[] {'\x17DD', '\x17DF'},    /* 17DD-17DF */
+            new char[] {'\x17EA', '\x17FF'},    /* 17EA-17FF */
+            new char[] {'\x180F', '\x0000'},    /* 180F */
+            new char[] {'\x181A', '\x181F'},    /* 181A-181F */
+            new char[] {'\x1878', '\x187F'},    /* 1878-187F */
+            new char[] {'\x18AA', '\x1DFF'},    /* 18AA-1DFF */
+            new char[] {'\x1E9C', '\x1E9F'},    /* 1E9C-1E9F */
+            new char[] {'\x1EFA', '\x1EFF'},    /* 1EFA-1EFF */
+            new char[] {'\x1F16', '\x1F17'},    /* 1F16-1F17 */
+            new char[] {'\x1F1E', '\x1F1F'},    /* 1F1E-1F1F */
+            new char[] {'\x1F46', '\x1F47'},    /* 1F46-1F47 */
+            new char[] {'\x1F4E', '\x1F4F'},    /* 1F4E-1F4F */
+            new char[] {'\x1F58', '\x0000'},    /* 1F58 */
+            new char[] {'\x1F5A', '\x0000'},    /* 1F5A */
+            new char[] {'\x1F5C', '\x0000'},    /* 1F5C */
+            new char[] {'\x1F5E', '\x0000'},    /* 1F5E */
+            new char[] {'\x1F7E', '\x1F7F'},    /* 1F7E-1F7F */
+            new char[] {'\x1FB5', '\x0000'},    /* 1FB5 */
+            new char[] {'\x1FC5', '\x0000'},    /* 1FC5 */
+            new char[] {'\x1FD4', '\x1FD5'},    /* 1FD4-1FD5 */
+            new char[] {'\x1FDC', '\x0000'},    /* 1FDC */
+            new char[] {'\x1FF0', '\x1FF1'},    /* 1FF0-1FF1 */
+            new char[] {'\x1FF5', '\x0000'},    /* 1FF5 */
+            new char[] {'\x1FFF', '\x0000'},    /* 1FFF */
+            new char[] {'\x2053', '\x2056'},    /* 2053-2056 */
+            new char[] {'\x2058', '\x205E'},    /* 2058-205E */
+            new char[] {'\x2064', '\x2069'},    /* 2064-2069 */
+            new char[] {'\x2072', '\x2073'},    /* 2072-2073 */
+            new char[] {'\x208F', '\x209F'},    /* 208F-209F */
+            new char[] {'\x20B2', '\x20CF'},    /* 20B2-20CF */
+            new char[] {'\x20EB', '\x20FF'},    /* 20EB-20FF */
+            new char[] {'\x213B', '\x213C'},    /* 213B-213C */
+            new char[] {'\x214C', '\x2152'},    /* 214C-2152 */
+            new char[] {'\x2184', '\x218F'},    /* 2184-218F */
+            new char[] {'\x23CF', '\x23FF'},    /* 23CF-23FF */
+            new char[] {'\x2427', '\x243F'},    /* 2427-243F */
+            new char[] {'\x244B', '\x245F'},    /* 244B-245F */
+            new char[] {'\x24FF', '\x0000'},    /* 24FF */
+            new char[] {'\x2614', '\x2615'},    /* 2614-2615 */
+            new char[] {'\x2618', '\x0000'},    /* 2618 */
+            new char[] {'\x267E', '\x267F'},    /* 267E-267F */
+            new char[] {'\x268A', '\x2700'},    /* 268A-2700 */
+            new char[] {'\x2705', '\x0000'},    /* 2705 */
+            new char[] {'\x270A', '\x270B'},    /* 270A-270B */
+            new char[] {'\x2728', '\x0000'},    /* 2728 */
+            new char[] {'\x274C', '\x0000'},    /* 274C */
+            new char[] {'\x274E', '\x0000'},    /* 274E */
+            new char[] {'\x2753', '\x2755'},    /* 2753-2755 */
+            new char[] {'\x2757', '\x0000'},    /* 2757 */
+            new char[] {'\x275F', '\x2760'},    /* 275F-2760 */
+            new char[] {'\x2795', '\x2797'},    /* 2795-2797 */
+            new char[] {'\x27B0', '\x0000'},    /* 27B0 */
+            new char[] {'\x27BF', '\x27CF'},    /* 27BF-27CF */
+            new char[] {'\x27EC', '\x27EF'},    /* 27EC-27EF */
+            new char[] {'\x2B00', '\x2E7F'},    /* 2B00-2E7F */
+            new char[] {'\x2E9A', '\x0000'},    /* 2E9A */
+            new char[] {'\x2EF4', '\x2EFF'},    /* 2EF4-2EFF */
+            new char[] {'\x2FD6', '\x2FEF'},    /* 2FD6-2FEF */
+            new char[] {'\x2FFC', '\x2FFF'},    /* 2FFC-2FFF */
+            new char[] {'\x3040', '\x0000'},    /* 3040 */
+            new char[] {'\x3097', '\x3098'},    /* 3097-3098 */
+            new char[] {'\x3100', '\x3104'},    /* 3100-3104 */
+            new char[] {'\x312D', '\x3130'},    /* 312D-3130 */
+            new char[] {'\x318F', '\x0000'},    /* 318F */
+            new char[] {'\x31B8', '\x31EF'},    /* 31B8-31EF */
+            new char[] {'\x321D', '\x321F'},    /* 321D-321F */
+            new char[] {'\x3244', '\x3250'},    /* 3244-3250 */
+            new char[] {'\x327C', '\x327E'},    /* 327C-327E */
+            new char[] {'\x32CC', '\x32CF'},    /* 32CC-32CF */
+            new char[] {'\x32FF', '\x0000'},    /* 32FF */
+            new char[] {'\x3377', '\x337A'},    /* 3377-337A */
+            new char[] {'\x33DE', '\x33DF'},    /* 33DE-33DF */
+            new char[] {'\x33FF', '\x0000'},    /* 33FF */
+            new char[] {'\x4DB6', '\x4DFF'},    /* 4DB6-4DFF */
+            new char[] {'\x9FA6', '\x9FFF'},    /* 9FA6-9FFF */
+            new char[] {'\xA48D', '\xA48F'},    /* A48D-A48F */
+            new char[] {'\xA4C7', '\xABFF'},    /* A4C7-ABFF */
+            new char[] {'\xD7A4', '\xD7FF'},    /* D7A4-D7FF */
+            new char[] {'\xFA2E', '\xFA2F'},    /* FA2E-FA2F */
+            new char[] {'\xFA6B', '\xFAFF'},    /* FA6B-FAFF */
+            new char[] {'\xFB07', '\xFB12'},    /* FB07-FB12 */
+            new char[] {'\xFB18', '\xFB1C'},    /* FB18-FB1C */
+            new char[] {'\xFB37', '\x0000'},    /* FB37 */
+            new char[] {'\xFB3D', '\x0000'},    /* FB3D */
+            new char[] {'\xFB3F', '\x0000'},    /* FB3F */
+            new char[] {'\xFB42', '\x0000'},    /* FB42 */
+            new char[] {'\xFB45', '\x0000'},    /* FB45 */
+            new char[] {'\xFBB2', '\xFBD2'},    /* FBB2-FBD2 */
+            new char[] {'\xFD40', '\xFD4F'},    /* FD40-FD4F */
+            new char[] {'\xFD90', '\xFD91'},    /* FD90-FD91 */
+            new char[] {'\xFDC8', '\xFDCF'},    /* FDC8-FDCF */
+            new char[] {'\xFDFD', '\xFDFF'},    /* FDFD-FDFF */
+            new char[] {'\xFE10', '\xFE1F'},    /* FE10-FE1F */
+            new char[] {'\xFE24', '\xFE2F'},    /* FE24-FE2F */
+            new char[] {'\xFE47', '\xFE48'},    /* FE47-FE48 */
+            new char[] {'\xFE53', '\x0000'},    /* FE53 */
+            new char[] {'\xFE67', '\x0000'},    /* FE67 */
+            new char[] {'\xFE6C', '\xFE6F'},    /* FE6C-FE6F */
+            new char[] {'\xFE75', '\x0000'},    /* FE75 */
+            new char[] {'\xFEFD', '\xFEFE'},    /* FEFD-FEFE */
+            new char[] {'\xFF00', '\x0000'},    /* FF00 */
+            new char[] {'\xFFBF', '\xFFC1'},    /* FFBF-FFC1 */
+            new char[] {'\xFFC8', '\xFFC9'},    /* FFC8-FFC9 */
+            new char[] {'\xFFD0', '\xFFD1'},    /* FFD0-FFD1 */
+            new char[] {'\xFFD8', '\xFFD9'},    /* FFD8-FFD9 */
+            new char[] {'\xFFDD', '\xFFDF'},    /* FFDD-FFDF */
+            new char[] {'\xFFE7', '\x0000'},    /* FFE7 */
+            new char[] {'\xFFEF', '\xFFF8'},    /* FFEF-FFF8 */
+        };
+
+
+        /// <summary>
+        /// B.1 Commonly mapped to nothing
+        ///
+        /// </summary>
+        public static readonly string[] B_1 = new string[]
+        {
+            "\x00AD",                          /* 00AD; ; Map to nothing */
+            "\x034F",                          /* 034F; ; Map to nothing */
+            "\x1806",                          /* 1806; ; Map to nothing */
+            "\x180B",                          /* 180B; ; Map to nothing */
+            "\x180C",                          /* 180C; ; Map to nothing */
+            "\x180D",                          /* 180D; ; Map to nothing */
+            "\x200B",                          /* 200B; ; Map to nothing */
+            "\x200C",                          /* 200C; ; Map to nothing */
+            "\x200D",                          /* 200D; ; Map to nothing */
+            "\x2060",                          /* 2060; ; Map to nothing */
+            "\xFE00",                          /* FE00; ; Map to nothing */
+            "\xFE01",                          /* FE01; ; Map to nothing */
+            "\xFE02",                          /* FE02; ; Map to nothing */
+            "\xFE03",                          /* FE03; ; Map to nothing */
+            "\xFE04",                          /* FE04; ; Map to nothing */
+            "\xFE05",                          /* FE05; ; Map to nothing */
+            "\xFE06",                          /* FE06; ; Map to nothing */
+            "\xFE07",                          /* FE07; ; Map to nothing */
+            "\xFE08",                          /* FE08; ; Map to nothing */
+            "\xFE09",                          /* FE09; ; Map to nothing */
+            "\xFE0A",                          /* FE0A; ; Map to nothing */
+            "\xFE0B",                          /* FE0B; ; Map to nothing */
+            "\xFE0C",                          /* FE0C; ; Map to nothing */
+            "\xFE0D",                          /* FE0D; ; Map to nothing */
+            "\xFE0E",                          /* FE0E; ; Map to nothing */
+            "\xFE0F",                          /* FE0F; ; Map to nothing */
+            "\xFEFF",                          /* FEFF; ; Map to nothing */
+        };
+
+
+        /// <summary>
+        /// B.2 Mapping for case-folding used with NFKC
+        ///
+        /// </summary>
+        public static readonly string[] B_2 = new string[]
+        {
+            "\x0041\x0061",                      /* 0041; 0061; Case map */
+            "\x0042\x0062",                      /* 0042; 0062; Case map */
+            "\x0043\x0063",                      /* 0043; 0063; Case map */
+            "\x0044\x0064",                      /* 0044; 0064; Case map */
+            "\x0045\x0065",                      /* 0045; 0065; Case map */
+            "\x0046\x0066",                      /* 0046; 0066; Case map */
+            "\x0047\x0067",                      /* 0047; 0067; Case map */
+            "\x0048\x0068",                      /* 0048; 0068; Case map */
+            "\x0049\x0069",                      /* 0049; 0069; Case map */
+            "\x004A\x006A",                      /* 004A; 006A; Case map */
+            "\x004B\x006B",                      /* 004B; 006B; Case map */
+            "\x004C\x006C",                      /* 004C; 006C; Case map */
+            "\x004D\x006D",                      /* 004D; 006D; Case map */
+            "\x004E\x006E",                      /* 004E; 006E; Case map */
+            "\x004F\x006F",                      /* 004F; 006F; Case map */
+            "\x0050\x0070",                      /* 0050; 0070; Case map */
+            "\x0051\x0071",                      /* 0051; 0071; Case map */
+            "\x0052\x0072",                      /* 0052; 0072; Case map */
+            "\x0053\x0073",                      /* 0053; 0073; Case map */
+            "\x0054\x0074",                      /* 0054; 0074; Case map */
+            "\x0055\x0075",                      /* 0055; 0075; Case map */
+            "\x0056\x0076",                      /* 0056; 0076; Case map */
+            "\x0057\x0077",                      /* 0057; 0077; Case map */
+            "\x0058\x0078",                      /* 0058; 0078; Case map */
+            "\x0059\x0079",                      /* 0059; 0079; Case map */
+            "\x005A\x007A",                      /* 005A; 007A; Case map */
+            "\x00B5\x03BC",                      /* 00B5; 03BC; Case map */
+            "\x00C0\x00E0",                      /* 00C0; 00E0; Case map */
+            "\x00C1\x00E1",                      /* 00C1; 00E1; Case map */
+            "\x00C2\x00E2",                      /* 00C2; 00E2; Case map */
+            "\x00C3\x00E3",                      /* 00C3; 00E3; Case map */
+            "\x00C4\x00E4",                      /* 00C4; 00E4; Case map */
+            "\x00C5\x00E5",                      /* 00C5; 00E5; Case map */
+            "\x00C6\x00E6",                      /* 00C6; 00E6; Case map */
+            "\x00C7\x00E7",                      /* 00C7; 00E7; Case map */
+            "\x00C8\x00E8",                      /* 00C8; 00E8; Case map */
+            "\x00C9\x00E9",                      /* 00C9; 00E9; Case map */
+            "\x00CA\x00EA",                      /* 00CA; 00EA; Case map */
+            "\x00CB\x00EB",                      /* 00CB; 00EB; Case map */
+            "\x00CC\x00EC",                      /* 00CC; 00EC; Case map */
+            "\x00CD\x00ED",                      /* 00CD; 00ED; Case map */
+            "\x00CE\x00EE",                      /* 00CE; 00EE; Case map */
+            "\x00CF\x00EF",                      /* 00CF; 00EF; Case map */
+            "\x00D0\x00F0",                      /* 00D0; 00F0; Case map */
+            "\x00D1\x00F1",                      /* 00D1; 00F1; Case map */
+            "\x00D2\x00F2",                      /* 00D2; 00F2; Case map */
+            "\x00D3\x00F3",                      /* 00D3; 00F3; Case map */
+            "\x00D4\x00F4",                      /* 00D4; 00F4; Case map */
+            "\x00D5\x00F5",                      /* 00D5; 00F5; Case map */
+            "\x00D6\x00F6",                      /* 00D6; 00F6; Case map */
+            "\x00D8\x00F8",                      /* 00D8; 00F8; Case map */
+            "\x00D9\x00F9",                      /* 00D9; 00F9; Case map */
+            "\x00DA\x00FA",                      /* 00DA; 00FA; Case map */
+            "\x00DB\x00FB",                      /* 00DB; 00FB; Case map */
+            "\x00DC\x00FC",                      /* 00DC; 00FC; Case map */
+            "\x00DD\x00FD",                      /* 00DD; 00FD; Case map */
+            "\x00DE\x00FE",                      /* 00DE; 00FE; Case map */
+            "\x00DF\x0073\x0073",                /* 00DF; 0073 0073; Case map */
+            "\x0100\x0101",                      /* 0100; 0101; Case map */
+            "\x0102\x0103",                      /* 0102; 0103; Case map */
+            "\x0104\x0105",                      /* 0104; 0105; Case map */
+            "\x0106\x0107",                      /* 0106; 0107; Case map */
+            "\x0108\x0109",                      /* 0108; 0109; Case map */
+            "\x010A\x010B",                      /* 010A; 010B; Case map */
+            "\x010C\x010D",                      /* 010C; 010D; Case map */
+            "\x010E\x010F",                      /* 010E; 010F; Case map */
+            "\x0110\x0111",                      /* 0110; 0111; Case map */
+            "\x0112\x0113",                      /* 0112; 0113; Case map */
+            "\x0114\x0115",                      /* 0114; 0115; Case map */
+            "\x0116\x0117",                      /* 0116; 0117; Case map */
+            "\x0118\x0119",                      /* 0118; 0119; Case map */
+            "\x011A\x011B",                      /* 011A; 011B; Case map */
+            "\x011C\x011D",                      /* 011C; 011D; Case map */
+            "\x011E\x011F",                      /* 011E; 011F; Case map */
+            "\x0120\x0121",                      /* 0120; 0121; Case map */
+            "\x0122\x0123",                      /* 0122; 0123; Case map */
+            "\x0124\x0125",                      /* 0124; 0125; Case map */
+            "\x0126\x0127",                      /* 0126; 0127; Case map */
+            "\x0128\x0129",                      /* 0128; 0129; Case map */
+            "\x012A\x012B",                      /* 012A; 012B; Case map */
+            "\x012C\x012D",                      /* 012C; 012D; Case map */
+            "\x012E\x012F",                      /* 012E; 012F; Case map */
+            "\x0130\x0069\x0307",                /* 0130; 0069 0307; Case map */
+            "\x0132\x0133",                      /* 0132; 0133; Case map */
+            "\x0134\x0135",                      /* 0134; 0135; Case map */
+            "\x0136\x0137",                      /* 0136; 0137; Case map */
+            "\x0139\x013A",                      /* 0139; 013A; Case map */
+            "\x013B\x013C",                      /* 013B; 013C; Case map */
+            "\x013D\x013E",                      /* 013D; 013E; Case map */
+            "\x013F\x0140",                      /* 013F; 0140; Case map */
+            "\x0141\x0142",                      /* 0141; 0142; Case map */
+            "\x0143\x0144",                      /* 0143; 0144; Case map */
+            "\x0145\x0146",                      /* 0145; 0146; Case map */
+            "\x0147\x0148",                      /* 0147; 0148; Case map */
+            "\x0149\x02BC\x006E",                /* 0149; 02BC 006E; Case map */
+            "\x014A\x014B",                      /* 014A; 014B; Case map */
+            "\x014C\x014D",                      /* 014C; 014D; Case map */
+            "\x014E\x014F",                      /* 014E; 014F; Case map */
+            "\x0150\x0151",                      /* 0150; 0151; Case map */
+            "\x0152\x0153",                      /* 0152; 0153; Case map */
+            "\x0154\x0155",                      /* 0154; 0155; Case map */
+            "\x0156\x0157",                      /* 0156; 0157; Case map */
+            "\x0158\x0159",                      /* 0158; 0159; Case map */
+            "\x015A\x015B",                      /* 015A; 015B; Case map */
+            "\x015C\x015D",                      /* 015C; 015D; Case map */
+            "\x015E\x015F",                      /* 015E; 015F; Case map */
+            "\x0160\x0161",                      /* 0160; 0161; Case map */
+            "\x0162\x0163",                      /* 0162; 0163; Case map */
+            "\x0164\x0165",                      /* 0164; 0165; Case map */
+            "\x0166\x0167",                      /* 0166; 0167; Case map */
+            "\x0168\x0169",                      /* 0168; 0169; Case map */
+            "\x016A\x016B",                      /* 016A; 016B; Case map */
+            "\x016C\x016D",                      /* 016C; 016D; Case map */
+            "\x016E\x016F",                      /* 016E; 016F; Case map */
+            "\x0170\x0171",                      /* 0170; 0171; Case map */
+            "\x0172\x0173",                      /* 0172; 0173; Case map */
+            "\x0174\x0175",                      /* 0174; 0175; Case map */
+            "\x0176\x0177",                      /* 0176; 0177; Case map */
+            "\x0178\x00FF",                      /* 0178; 00FF; Case map */
+            "\x0179\x017A",                      /* 0179; 017A; Case map */
+            "\x017B\x017C",                      /* 017B; 017C; Case map */
+            "\x017D\x017E",                      /* 017D; 017E; Case map */
+            "\x017F\x0073",                      /* 017F; 0073; Case map */
+            "\x0181\x0253",                      /* 0181; 0253; Case map */
+            "\x0182\x0183",                      /* 0182; 0183; Case map */
+            "\x0184\x0185",                      /* 0184; 0185; Case map */
+            "\x0186\x0254",                      /* 0186; 0254; Case map */
+            "\x0187\x0188",                      /* 0187; 0188; Case map */
+            "\x0189\x0256",                      /* 0189; 0256; Case map */
+            "\x018A\x0257",                      /* 018A; 0257; Case map */
+            "\x018B\x018C",                      /* 018B; 018C; Case map */
+            "\x018E\x01DD",                      /* 018E; 01DD; Case map */
+            "\x018F\x0259",                      /* 018F; 0259; Case map */
+            "\x0190\x025B",                      /* 0190; 025B; Case map */
+            "\x0191\x0192",                      /* 0191; 0192; Case map */
+            "\x0193\x0260",                      /* 0193; 0260; Case map */
+            "\x0194\x0263",                      /* 0194; 0263; Case map */
+            "\x0196\x0269",                      /* 0196; 0269; Case map */
+            "\x0197\x0268",                      /* 0197; 0268; Case map */
+            "\x0198\x0199",                      /* 0198; 0199; Case map */
+            "\x019C\x026F",                      /* 019C; 026F; Case map */
+            "\x019D\x0272",                      /* 019D; 0272; Case map */
+            "\x019F\x0275",                      /* 019F; 0275; Case map */
+            "\x01A0\x01A1",                      /* 01A0; 01A1; Case map */
+            "\x01A2\x01A3",                      /* 01A2; 01A3; Case map */
+            "\x01A4\x01A5",                      /* 01A4; 01A5; Case map */
+            "\x01A6\x0280",                      /* 01A6; 0280; Case map */
+            "\x01A7\x01A8",                      /* 01A7; 01A8; Case map */
+            "\x01A9\x0283",                      /* 01A9; 0283; Case map */
+            "\x01AC\x01AD",                      /* 01AC; 01AD; Case map */
+            "\x01AE\x0288",                      /* 01AE; 0288; Case map */
+            "\x01AF\x01B0",                      /* 01AF; 01B0; Case map */
+            "\x01B1\x028A",                      /* 01B1; 028A; Case map */
+            "\x01B2\x028B",                      /* 01B2; 028B; Case map */
+            "\x01B3\x01B4",                      /* 01B3; 01B4; Case map */
+            "\x01B5\x01B6",                      /* 01B5; 01B6; Case map */
+            "\x01B7\x0292",                      /* 01B7; 0292; Case map */
+            "\x01B8\x01B9",                      /* 01B8; 01B9; Case map */
+            "\x01BC\x01BD",                      /* 01BC; 01BD; Case map */
+            "\x01C4\x01C6",                      /* 01C4; 01C6; Case map */
+            "\x01C5\x01C6",                      /* 01C5; 01C6; Case map */
+            "\x01C7\x01C9",                      /* 01C7; 01C9; Case map */
+            "\x01C8\x01C9",                      /* 01C8; 01C9; Case map */
+            "\x01CA\x01CC",                      /* 01CA; 01CC; Case map */
+            "\x01CB\x01CC",                      /* 01CB; 01CC; Case map */
+            "\x01CD\x01CE",                      /* 01CD; 01CE; Case map */
+            "\x01CF\x01D0",                      /* 01CF; 01D0; Case map */
+            "\x01D1\x01D2",                      /* 01D1; 01D2; Case map */
+            "\x01D3\x01D4",                      /* 01D3; 01D4; Case map */
+            "\x01D5\x01D6",                      /* 01D5; 01D6; Case map */
+            "\x01D7\x01D8",                      /* 01D7; 01D8; Case map */
+            "\x01D9\x01DA",                      /* 01D9; 01DA; Case map */
+            "\x01DB\x01DC",                      /* 01DB; 01DC; Case map */
+            "\x01DE\x01DF",                      /* 01DE; 01DF; Case map */
+            "\x01E0\x01E1",                      /* 01E0; 01E1; Case map */
+            "\x01E2\x01E3",                      /* 01E2; 01E3; Case map */
+            "\x01E4\x01E5",                      /* 01E4; 01E5; Case map */
+            "\x01E6\x01E7",                      /* 01E6; 01E7; Case map */
+            "\x01E8\x01E9",                      /* 01E8; 01E9; Case map */
+            "\x01EA\x01EB",                      /* 01EA; 01EB; Case map */
+            "\x01EC\x01ED",                      /* 01EC; 01ED; Case map */
+            "\x01EE\x01EF",                      /* 01EE; 01EF; Case map */
+            "\x01F0\x006A\x030C",                /* 01F0; 006A 030C; Case map */
+            "\x01F1\x01F3",                      /* 01F1; 01F3; Case map */
+            "\x01F2\x01F3",                      /* 01F2; 01F3; Case map */
+            "\x01F4\x01F5",                      /* 01F4; 01F5; Case map */
+            "\x01F6\x0195",                      /* 01F6; 0195; Case map */
+            "\x01F7\x01BF",                      /* 01F7; 01BF; Case map */
+            "\x01F8\x01F9",                      /* 01F8; 01F9; Case map */
+            "\x01FA\x01FB",                      /* 01FA; 01FB; Case map */
+            "\x01FC\x01FD",                      /* 01FC; 01FD; Case map */
+            "\x01FE\x01FF",                      /* 01FE; 01FF; Case map */
+            "\x0200\x0201",                      /* 0200; 0201; Case map */
+            "\x0202\x0203",                      /* 0202; 0203; Case map */
+            "\x0204\x0205",                      /* 0204; 0205; Case map */
+            "\x0206\x0207",                      /* 0206; 0207; Case map */
+            "\x0208\x0209",                      /* 0208; 0209; Case map */
+            "\x020A\x020B",                      /* 020A; 020B; Case map */
+            "\x020C\x020D",                      /* 020C; 020D; Case map */
+            "\x020E\x020F",                      /* 020E; 020F; Case map */
+            "\x0210\x0211",                      /* 0210; 0211; Case map */
+            "\x0212\x0213",                      /* 0212; 0213; Case map */
+            "\x0214\x0215",                      /* 0214; 0215; Case map */
+            "\x0216\x0217",                      /* 0216; 0217; Case map */
+            "\x0218\x0219",                      /* 0218; 0219; Case map */
+            "\x021A\x021B",                      /* 021A; 021B; Case map */
+            "\x021C\x021D",                      /* 021C; 021D; Case map */
+            "\x021E\x021F",                      /* 021E; 021F; Case map */
+            "\x0220\x019E",                      /* 0220; 019E; Case map */
+            "\x0222\x0223",                      /* 0222; 0223; Case map */
+            "\x0224\x0225",                      /* 0224; 0225; Case map */
+            "\x0226\x0227",                      /* 0226; 0227; Case map */
+            "\x0228\x0229",                      /* 0228; 0229; Case map */
+            "\x022A\x022B",                      /* 022A; 022B; Case map */
+            "\x022C\x022D",                      /* 022C; 022D; Case map */
+            "\x022E\x022F",                      /* 022E; 022F; Case map */
+            "\x0230\x0231",                      /* 0230; 0231; Case map */
+            "\x0232\x0233",                      /* 0232; 0233; Case map */
+            "\x0345\x03B9",                      /* 0345; 03B9; Case map */
+            "\x037A\x0020\x03B9",      /* 037A; 0020 03B9; Additional folding */
+            "\x0386\x03AC",                      /* 0386; 03AC; Case map */
+            "\x0388\x03AD",                      /* 0388; 03AD; Case map */
+            "\x0389\x03AE",                      /* 0389; 03AE; Case map */
+            "\x038A\x03AF",                      /* 038A; 03AF; Case map */
+            "\x038C\x03CC",                      /* 038C; 03CC; Case map */
+            "\x038E\x03CD",                      /* 038E; 03CD; Case map */
+            "\x038F\x03CE",                      /* 038F; 03CE; Case map */
+            "\x0390\x03B9\x0308\x0301",          /* 0390; 03B9 0308 0301; Case map */
+            "\x0391\x03B1",                      /* 0391; 03B1; Case map */
+            "\x0392\x03B2",                      /* 0392; 03B2; Case map */
+            "\x0393\x03B3",                      /* 0393; 03B3; Case map */
+            "\x0394\x03B4",                      /* 0394; 03B4; Case map */
+            "\x0395\x03B5",                      /* 0395; 03B5; Case map */
+            "\x0396\x03B6",                      /* 0396; 03B6; Case map */
+            "\x0397\x03B7",                      /* 0397; 03B7; Case map */
+            "\x0398\x03B8",                      /* 0398; 03B8; Case map */
+            "\x0399\x03B9",                      /* 0399; 03B9; Case map */
+            "\x039A\x03BA",                      /* 039A; 03BA; Case map */
+            "\x039B\x03BB",                      /* 039B; 03BB; Case map */
+            "\x039C\x03BC",                      /* 039C; 03BC; Case map */
+            "\x039D\x03BD",                      /* 039D; 03BD; Case map */
+            "\x039E\x03BE",                      /* 039E; 03BE; Case map */
+            "\x039F\x03BF",                      /* 039F; 03BF; Case map */
+            "\x03A0\x03C0",                      /* 03A0; 03C0; Case map */
+            "\x03A1\x03C1",                      /* 03A1; 03C1; Case map */
+            "\x03A3\x03C3",                      /* 03A3; 03C3; Case map */
+            "\x03A4\x03C4",                      /* 03A4; 03C4; Case map */
+            "\x03A5\x03C5",                      /* 03A5; 03C5; Case map */
+            "\x03A6\x03C6",                      /* 03A6; 03C6; Case map */
+            "\x03A7\x03C7",                      /* 03A7; 03C7; Case map */
+            "\x03A8\x03C8",                      /* 03A8; 03C8; Case map */
+            "\x03A9\x03C9",                      /* 03A9; 03C9; Case map */
+            "\x03AA\x03CA",                      /* 03AA; 03CA; Case map */
+            "\x03AB\x03CB",                      /* 03AB; 03CB; Case map */
+            "\x03B0\x03C5\x0308\x0301",          /* 03B0; 03C5 0308 0301; Case map */
+            "\x03C2\x03C3",                      /* 03C2; 03C3; Case map */
+            "\x03D0\x03B2",                      /* 03D0; 03B2; Case map */
+            "\x03D1\x03B8",                      /* 03D1; 03B8; Case map */
+            "\x03D2\x03C5",            /* 03D2; 03C5; Additional folding */
+            "\x03D3\x03CD",            /* 03D3; 03CD; Additional folding */
+            "\x03D4\x03CB",            /* 03D4; 03CB; Additional folding */
+            "\x03D5\x03C6",                      /* 03D5; 03C6; Case map */
+            "\x03D6\x03C0",                      /* 03D6; 03C0; Case map */
+            "\x03D8\x03D9",                      /* 03D8; 03D9; Case map */
+            "\x03DA\x03DB",                      /* 03DA; 03DB; Case map */
+            "\x03DC\x03DD",                      /* 03DC; 03DD; Case map */
+            "\x03DE\x03DF",                      /* 03DE; 03DF; Case map */
+            "\x03E0\x03E1",                      /* 03E0; 03E1; Case map */
+            "\x03E2\x03E3",                      /* 03E2; 03E3; Case map */
+            "\x03E4\x03E5",                      /* 03E4; 03E5; Case map */
+            "\x03E6\x03E7",                      /* 03E6; 03E7; Case map */
+            "\x03E8\x03E9",                      /* 03E8; 03E9; Case map */
+            "\x03EA\x03EB",                      /* 03EA; 03EB; Case map */
+            "\x03EC\x03ED",                      /* 03EC; 03ED; Case map */
+            "\x03EE\x03EF",                      /* 03EE; 03EF; Case map */
+            "\x03F0\x03BA",                      /* 03F0; 03BA; Case map */
+            "\x03F1\x03C1",                      /* 03F1; 03C1; Case map */
+            "\x03F2\x03C3",                      /* 03F2; 03C3; Case map */
+            "\x03F4\x03B8",                      /* 03F4; 03B8; Case map */
+            "\x03F5\x03B5",                      /* 03F5; 03B5; Case map */
+            "\x0400\x0450",                      /* 0400; 0450; Case map */
+            "\x0401\x0451",                      /* 0401; 0451; Case map */
+            "\x0402\x0452",                      /* 0402; 0452; Case map */
+            "\x0403\x0453",                      /* 0403; 0453; Case map */
+            "\x0404\x0454",                      /* 0404; 0454; Case map */
+            "\x0405\x0455",                      /* 0405; 0455; Case map */
+            "\x0406\x0456",                      /* 0406; 0456; Case map */
+            "\x0407\x0457",                      /* 0407; 0457; Case map */
+            "\x0408\x0458",                      /* 0408; 0458; Case map */
+            "\x0409\x0459",                      /* 0409; 0459; Case map */
+            "\x040A\x045A",                      /* 040A; 045A; Case map */
+            "\x040B\x045B",                      /* 040B; 045B; Case map */
+            "\x040C\x045C",                      /* 040C; 045C; Case map */
+            "\x040D\x045D",                      /* 040D; 045D; Case map */
+            "\x040E\x045E",                      /* 040E; 045E; Case map */
+            "\x040F\x045F",                      /* 040F; 045F; Case map */
+            "\x0410\x0430",                      /* 0410; 0430; Case map */
+            "\x0411\x0431",                      /* 0411; 0431; Case map */
+            "\x0412\x0432",                      /* 0412; 0432; Case map */
+            "\x0413\x0433",                      /* 0413; 0433; Case map */
+            "\x0414\x0434",                      /* 0414; 0434; Case map */
+            "\x0415\x0435",                      /* 0415; 0435; Case map */
+            "\x0416\x0436",                      /* 0416; 0436; Case map */
+            "\x0417\x0437",                      /* 0417; 0437; Case map */
+            "\x0418\x0438",                      /* 0418; 0438; Case map */
+            "\x0419\x0439",                      /* 0419; 0439; Case map */
+            "\x041A\x043A",                      /* 041A; 043A; Case map */
+            "\x041B\x043B",                      /* 041B; 043B; Case map */
+            "\x041C\x043C",                      /* 041C; 043C; Case map */
+            "\x041D\x043D",                      /* 041D; 043D; Case map */
+            "\x041E\x043E",                      /* 041E; 043E; Case map */
+            "\x041F\x043F",                      /* 041F; 043F; Case map */
+            "\x0420\x0440",                      /* 0420; 0440; Case map */
+            "\x0421\x0441",                      /* 0421; 0441; Case map */
+            "\x0422\x0442",                      /* 0422; 0442; Case map */
+            "\x0423\x0443",                      /* 0423; 0443; Case map */
+            "\x0424\x0444",                      /* 0424; 0444; Case map */
+            "\x0425\x0445",                      /* 0425; 0445; Case map */
+            "\x0426\x0446",                      /* 0426; 0446; Case map */
+            "\x0427\x0447",                      /* 0427; 0447; Case map */
+            "\x0428\x0448",                      /* 0428; 0448; Case map */
+            "\x0429\x0449",                      /* 0429; 0449; Case map */
+            "\x042A\x044A",                      /* 042A; 044A; Case map */
+            "\x042B\x044B",                      /* 042B; 044B; Case map */
+            "\x042C\x044C",                      /* 042C; 044C; Case map */
+            "\x042D\x044D",                      /* 042D; 044D; Case map */
+            "\x042E\x044E",                      /* 042E; 044E; Case map */
+            "\x042F\x044F",                      /* 042F; 044F; Case map */
+            "\x0460\x0461",                      /* 0460; 0461; Case map */
+            "\x0462\x0463",                      /* 0462; 0463; Case map */
+            "\x0464\x0465",                      /* 0464; 0465; Case map */
+            "\x0466\x0467",                      /* 0466; 0467; Case map */
+            "\x0468\x0469",                      /* 0468; 0469; Case map */
+            "\x046A\x046B",                      /* 046A; 046B; Case map */
+            "\x046C\x046D",                      /* 046C; 046D; Case map */
+            "\x046E\x046F",                      /* 046E; 046F; Case map */
+            "\x0470\x0471",                      /* 0470; 0471; Case map */
+            "\x0472\x0473",                      /* 0472; 0473; Case map */
+            "\x0474\x0475",                      /* 0474; 0475; Case map */
+            "\x0476\x0477",                      /* 0476; 0477; Case map */
+            "\x0478\x0479",                      /* 0478; 0479; Case map */
+            "\x047A\x047B",                      /* 047A; 047B; Case map */
+            "\x047C\x047D",                      /* 047C; 047D; Case map */
+            "\x047E\x047F",                      /* 047E; 047F; Case map */
+            "\x0480\x0481",                      /* 0480; 0481; Case map */
+            "\x048A\x048B",                      /* 048A; 048B; Case map */
+            "\x048C\x048D",                      /* 048C; 048D; Case map */
+            "\x048E\x048F",                      /* 048E; 048F; Case map */
+            "\x0490\x0491",                      /* 0490; 0491; Case map */
+            "\x0492\x0493",                      /* 0492; 0493; Case map */
+            "\x0494\x0495",                      /* 0494; 0495; Case map */
+            "\x0496\x0497",                      /* 0496; 0497; Case map */
+            "\x0498\x0499",                      /* 0498; 0499; Case map */
+            "\x049A\x049B",                      /* 049A; 049B; Case map */
+            "\x049C\x049D",                      /* 049C; 049D; Case map */
+            "\x049E\x049F",                      /* 049E; 049F; Case map */
+            "\x04A0\x04A1",                      /* 04A0; 04A1; Case map */
+            "\x04A2\x04A3",                      /* 04A2; 04A3; Case map */
+            "\x04A4\x04A5",                      /* 04A4; 04A5; Case map */
+            "\x04A6\x04A7",                      /* 04A6; 04A7; Case map */
+            "\x04A8\x04A9",                      /* 04A8; 04A9; Case map */
+            "\x04AA\x04AB",                      /* 04AA; 04AB; Case map */
+            "\x04AC\x04AD",                      /* 04AC; 04AD; Case map */
+            "\x04AE\x04AF",                      /* 04AE; 04AF; Case map */
+            "\x04B0\x04B1",                      /* 04B0; 04B1; Case map */
+            "\x04B2\x04B3",                      /* 04B2; 04B3; Case map */
+            "\x04B4\x04B5",                      /* 04B4; 04B5; Case map */
+            "\x04B6\x04B7",                      /* 04B6; 04B7; Case map */
+            "\x04B8\x04B9",                      /* 04B8; 04B9; Case map */
+            "\x04BA\x04BB",                      /* 04BA; 04BB; Case map */
+            "\x04BC\x04BD",                      /* 04BC; 04BD; Case map */
+            "\x04BE\x04BF",                      /* 04BE; 04BF; Case map */
+            "\x04C1\x04C2",                      /* 04C1; 04C2; Case map */
+            "\x04C3\x04C4",                      /* 04C3; 04C4; Case map */
+            "\x04C5\x04C6",                      /* 04C5; 04C6; Case map */
+            "\x04C7\x04C8",                      /* 04C7; 04C8; Case map */
+            "\x04C9\x04CA",                      /* 04C9; 04CA; Case map */
+            "\x04CB\x04CC",                      /* 04CB; 04CC; Case map */
+            "\x04CD\x04CE",                      /* 04CD; 04CE; Case map */
+            "\x04D0\x04D1",                      /* 04D0; 04D1; Case map */
+            "\x04D2\x04D3",                      /* 04D2; 04D3; Case map */
+            "\x04D4\x04D5",                      /* 04D4; 04D5; Case map */
+            "\x04D6\x04D7",                      /* 04D6; 04D7; Case map */
+            "\x04D8\x04D9",                      /* 04D8; 04D9; Case map */
+            "\x04DA\x04DB",                      /* 04DA; 04DB; Case map */
+            "\x04DC\x04DD",                      /* 04DC; 04DD; Case map */
+            "\x04DE\x04DF",                      /* 04DE; 04DF; Case map */
+            "\x04E0\x04E1",                      /* 04E0; 04E1; Case map */
+            "\x04E2\x04E3",                      /* 04E2; 04E3; Case map */
+            "\x04E4\x04E5",                      /* 04E4; 04E5; Case map */
+            "\x04E6\x04E7",                      /* 04E6; 04E7; Case map */
+            "\x04E8\x04E9",                      /* 04E8; 04E9; Case map */
+            "\x04EA\x04EB",                      /* 04EA; 04EB; Case map */
+            "\x04EC\x04ED",                      /* 04EC; 04ED; Case map */
+            "\x04EE\x04EF",                      /* 04EE; 04EF; Case map */
+            "\x04F0\x04F1",                      /* 04F0; 04F1; Case map */
+            "\x04F2\x04F3",                      /* 04F2; 04F3; Case map */
+            "\x04F4\x04F5",                      /* 04F4; 04F5; Case map */
+            "\x04F8\x04F9",                      /* 04F8; 04F9; Case map */
+            "\x0500\x0501",                      /* 0500; 0501; Case map */
+            "\x0502\x0503",                      /* 0502; 0503; Case map */
+            "\x0504\x0505",                      /* 0504; 0505; Case map */
+            "\x0506\x0507",                      /* 0506; 0507; Case map */
+            "\x0508\x0509",                      /* 0508; 0509; Case map */
+            "\x050A\x050B",                      /* 050A; 050B; Case map */
+            "\x050C\x050D",                      /* 050C; 050D; Case map */
+            "\x050E\x050F",                      /* 050E; 050F; Case map */
+            "\x0531\x0561",                      /* 0531; 0561; Case map */
+            "\x0532\x0562",                      /* 0532; 0562; Case map */
+            "\x0533\x0563",                      /* 0533; 0563; Case map */
+            "\x0534\x0564",                      /* 0534; 0564; Case map */
+            "\x0535\x0565",                      /* 0535; 0565; Case map */
+            "\x0536\x0566",                      /* 0536; 0566; Case map */
+            "\x0537\x0567",                      /* 0537; 0567; Case map */
+            "\x0538\x0568",                      /* 0538; 0568; Case map */
+            "\x0539\x0569",                      /* 0539; 0569; Case map */
+            "\x053A\x056A",                      /* 053A; 056A; Case map */
+            "\x053B\x056B",                      /* 053B; 056B; Case map */
+            "\x053C\x056C",                      /* 053C; 056C; Case map */
+            "\x053D\x056D",                      /* 053D; 056D; Case map */
+            "\x053E\x056E",                      /* 053E; 056E; Case map */
+            "\x053F\x056F",                      /* 053F; 056F; Case map */
+            "\x0540\x0570",                      /* 0540; 0570; Case map */
+            "\x0541\x0571",                      /* 0541; 0571; Case map */
+            "\x0542\x0572",                      /* 0542; 0572; Case map */
+            "\x0543\x0573",                      /* 0543; 0573; Case map */
+            "\x0544\x0574",                      /* 0544; 0574; Case map */
+            "\x0545\x0575",                      /* 0545; 0575; Case map */
+            "\x0546\x0576",                      /* 0546; 0576; Case map */
+            "\x0547\x0577",                      /* 0547; 0577; Case map */
+            "\x0548\x0578",                      /* 0548; 0578; Case map */
+            "\x0549\x0579",                      /* 0549; 0579; Case map */
+            "\x054A\x057A",                      /* 054A; 057A; Case map */
+            "\x054B\x057B",                      /* 054B; 057B; Case map */
+            "\x054C\x057C",                      /* 054C; 057C; Case map */
+            "\x054D\x057D",                      /* 054D; 057D; Case map */
+            "\x054E\x057E",                      /* 054E; 057E; Case map */
+            "\x054F\x057F",                      /* 054F; 057F; Case map */
+            "\x0550\x0580",                      /* 0550; 0580; Case map */
+            "\x0551\x0581",                      /* 0551; 0581; Case map */
+            "\x0552\x0582",                      /* 0552; 0582; Case map */
+            "\x0553\x0583",                      /* 0553; 0583; Case map */
+            "\x0554\x0584",                      /* 0554; 0584; Case map */
+            "\x0555\x0585",                      /* 0555; 0585; Case map */
+            "\x0556\x0586",                      /* 0556; 0586; Case map */
+            "\x0587\x0565\x0582",                /* 0587; 0565 0582; Case map */
+            "\x1E00\x1E01",                      /* 1E00; 1E01; Case map */
+            "\x1E02\x1E03",                      /* 1E02; 1E03; Case map */
+            "\x1E04\x1E05",                      /* 1E04; 1E05; Case map */
+            "\x1E06\x1E07",                      /* 1E06; 1E07; Case map */
+            "\x1E08\x1E09",                      /* 1E08; 1E09; Case map */
+            "\x1E0A\x1E0B",                      /* 1E0A; 1E0B; Case map */
+            "\x1E0C\x1E0D",                      /* 1E0C; 1E0D; Case map */
+            "\x1E0E\x1E0F",                      /* 1E0E; 1E0F; Case map */
+            "\x1E10\x1E11",                      /* 1E10; 1E11; Case map */
+            "\x1E12\x1E13",                      /* 1E12; 1E13; Case map */
+            "\x1E14\x1E15",                      /* 1E14; 1E15; Case map */
+            "\x1E16\x1E17",                      /* 1E16; 1E17; Case map */
+            "\x1E18\x1E19",                      /* 1E18; 1E19; Case map */
+            "\x1E1A\x1E1B",                      /* 1E1A; 1E1B; Case map */
+            "\x1E1C\x1E1D",                      /* 1E1C; 1E1D; Case map */
+            "\x1E1E\x1E1F",                      /* 1E1E; 1E1F; Case map */
+            "\x1E20\x1E21",                      /* 1E20; 1E21; Case map */
+            "\x1E22\x1E23",                      /* 1E22; 1E23; Case map */
+            "\x1E24\x1E25",                      /* 1E24; 1E25; Case map */
+            "\x1E26\x1E27",                      /* 1E26; 1E27; Case map */
+            "\x1E28\x1E29",                      /* 1E28; 1E29; Case map */
+            "\x1E2A\x1E2B",                      /* 1E2A; 1E2B; Case map */
+            "\x1E2C\x1E2D",                      /* 1E2C; 1E2D; Case map */
+            "\x1E2E\x1E2F",                      /* 1E2E; 1E2F; Case map */
+            "\x1E30\x1E31",                      /* 1E30; 1E31; Case map */
+            "\x1E32\x1E33",                      /* 1E32; 1E33; Case map */
+            "\x1E34\x1E35",                      /* 1E34; 1E35; Case map */
+            "\x1E36\x1E37",                      /* 1E36; 1E37; Case map */
+            "\x1E38\x1E39",                      /* 1E38; 1E39; Case map */
+            "\x1E3A\x1E3B",                      /* 1E3A; 1E3B; Case map */
+            "\x1E3C\x1E3D",                      /* 1E3C; 1E3D; Case map */
+            "\x1E3E\x1E3F",                      /* 1E3E; 1E3F; Case map */
+            "\x1E40\x1E41",                      /* 1E40; 1E41; Case map */
+            "\x1E42\x1E43",                      /* 1E42; 1E43; Case map */
+            "\x1E44\x1E45",                      /* 1E44; 1E45; Case map */
+            "\x1E46\x1E47",                      /* 1E46; 1E47; Case map */
+            "\x1E48\x1E49",                      /* 1E48; 1E49; Case map */
+            "\x1E4A\x1E4B",                      /* 1E4A; 1E4B; Case map */
+            "\x1E4C\x1E4D",                      /* 1E4C; 1E4D; Case map */
+            "\x1E4E\x1E4F",                      /* 1E4E; 1E4F; Case map */
+            "\x1E50\x1E51",                      /* 1E50; 1E51; Case map */
+            "\x1E52\x1E53",                      /* 1E52; 1E53; Case map */
+            "\x1E54\x1E55",                      /* 1E54; 1E55; Case map */
+            "\x1E56\x1E57",                      /* 1E56; 1E57; Case map */
+            "\x1E58\x1E59",                      /* 1E58; 1E59; Case map */
+            "\x1E5A\x1E5B",                      /* 1E5A; 1E5B; Case map */
+            "\x1E5C\x1E5D",                      /* 1E5C; 1E5D; Case map */
+            "\x1E5E\x1E5F",                      /* 1E5E; 1E5F; Case map */
+            "\x1E60\x1E61",                      /* 1E60; 1E61; Case map */
+            "\x1E62\x1E63",                      /* 1E62; 1E63; Case map */
+            "\x1E64\x1E65",                      /* 1E64; 1E65; Case map */
+            "\x1E66\x1E67",                      /* 1E66; 1E67; Case map */
+            "\x1E68\x1E69",                      /* 1E68; 1E69; Case map */
+            "\x1E6A\x1E6B",                      /* 1E6A; 1E6B; Case map */
+            "\x1E6C\x1E6D",                      /* 1E6C; 1E6D; Case map */
+            "\x1E6E\x1E6F",                      /* 1E6E; 1E6F; Case map */
+            "\x1E70\x1E71",                      /* 1E70; 1E71; Case map */
+            "\x1E72\x1E73",                      /* 1E72; 1E73; Case map */
+            "\x1E74\x1E75",                      /* 1E74; 1E75; Case map */
+            "\x1E76\x1E77",                      /* 1E76; 1E77; Case map */
+            "\x1E78\x1E79",                      /* 1E78; 1E79; Case map */
+            "\x1E7A\x1E7B",                      /* 1E7A; 1E7B; Case map */
+            "\x1E7C\x1E7D",                      /* 1E7C; 1E7D; Case map */
+            "\x1E7E\x1E7F",                      /* 1E7E; 1E7F; Case map */
+            "\x1E80\x1E81",                      /* 1E80; 1E81; Case map */
+            "\x1E82\x1E83",                      /* 1E82; 1E83; Case map */
+            "\x1E84\x1E85",                      /* 1E84; 1E85; Case map */
+            "\x1E86\x1E87",                      /* 1E86; 1E87; Case map */
+            "\x1E88\x1E89",                      /* 1E88; 1E89; Case map */
+            "\x1E8A\x1E8B",                      /* 1E8A; 1E8B; Case map */
+            "\x1E8C\x1E8D",                      /* 1E8C; 1E8D; Case map */
+            "\x1E8E\x1E8F",                      /* 1E8E; 1E8F; Case map */
+            "\x1E90\x1E91",                      /* 1E90; 1E91; Case map */
+            "\x1E92\x1E93",                      /* 1E92; 1E93; Case map */
+            "\x1E94\x1E95",                      /* 1E94; 1E95; Case map */
+            "\x1E96\x0068\x0331",                /* 1E96; 0068 0331; Case map */
+            "\x1E97\x0074\x0308",                /* 1E97; 0074 0308; Case map */
+            "\x1E98\x0077\x030A",                /* 1E98; 0077 030A; Case map */
+            "\x1E99\x0079\x030A",                /* 1E99; 0079 030A; Case map */
+            "\x1E9A\x0061\x02BE",                /* 1E9A; 0061 02BE; Case map */
+            "\x1E9B\x1E61",                      /* 1E9B; 1E61; Case map */
+            "\x1EA0\x1EA1",                      /* 1EA0; 1EA1; Case map */
+            "\x1EA2\x1EA3",                      /* 1EA2; 1EA3; Case map */
+            "\x1EA4\x1EA5",                      /* 1EA4; 1EA5; Case map */
+            "\x1EA6\x1EA7",                      /* 1EA6; 1EA7; Case map */
+            "\x1EA8\x1EA9",                      /* 1EA8; 1EA9; Case map */
+            "\x1EAA\x1EAB",                      /* 1EAA; 1EAB; Case map */
+            "\x1EAC\x1EAD",                      /* 1EAC; 1EAD; Case map */
+            "\x1EAE\x1EAF",                      /* 1EAE; 1EAF; Case map */
+            "\x1EB0\x1EB1",                      /* 1EB0; 1EB1; Case map */
+            "\x1EB2\x1EB3",                      /* 1EB2; 1EB3; Case map */
+            "\x1EB4\x1EB5",                      /* 1EB4; 1EB5; Case map */
+            "\x1EB6\x1EB7",                      /* 1EB6; 1EB7; Case map */
+            "\x1EB8\x1EB9",                      /* 1EB8; 1EB9; Case map */
+            "\x1EBA\x1EBB",                      /* 1EBA; 1EBB; Case map */
+            "\x1EBC\x1EBD",                      /* 1EBC; 1EBD; Case map */
+            "\x1EBE\x1EBF",                      /* 1EBE; 1EBF; Case map */
+            "\x1EC0\x1EC1",                      /* 1EC0; 1EC1; Case map */
+            "\x1EC2\x1EC3",                      /* 1EC2; 1EC3; Case map */
+            "\x1EC4\x1EC5",                      /* 1EC4; 1EC5; Case map */
+            "\x1EC6\x1EC7",                      /* 1EC6; 1EC7; Case map */
+            "\x1EC8\x1EC9",                      /* 1EC8; 1EC9; Case map */
+            "\x1ECA\x1ECB",                      /* 1ECA; 1ECB; Case map */
+            "\x1ECC\x1ECD",                      /* 1ECC; 1ECD; Case map */
+            "\x1ECE\x1ECF",                      /* 1ECE; 1ECF; Case map */
+            "\x1ED0\x1ED1",                      /* 1ED0; 1ED1; Case map */
+            "\x1ED2\x1ED3",                      /* 1ED2; 1ED3; Case map */
+            "\x1ED4\x1ED5",                      /* 1ED4; 1ED5; Case map */
+            "\x1ED6\x1ED7",                      /* 1ED6; 1ED7; Case map */
+            "\x1ED8\x1ED9",                      /* 1ED8; 1ED9; Case map */
+            "\x1EDA\x1EDB",                      /* 1EDA; 1EDB; Case map */
+            "\x1EDC\x1EDD",                      /* 1EDC; 1EDD; Case map */
+            "\x1EDE\x1EDF",                      /* 1EDE; 1EDF; Case map */
+            "\x1EE0\x1EE1",                      /* 1EE0; 1EE1; Case map */
+            "\x1EE2\x1EE3",                      /* 1EE2; 1EE3; Case map */
+            "\x1EE4\x1EE5",                      /* 1EE4; 1EE5; Case map */
+            "\x1EE6\x1EE7",                      /* 1EE6; 1EE7; Case map */
+            "\x1EE8\x1EE9",                      /* 1EE8; 1EE9; Case map */
+            "\x1EEA\x1EEB",                      /* 1EEA; 1EEB; Case map */
+            "\x1EEC\x1EED",                      /* 1EEC; 1EED; Case map */
+            "\x1EEE\x1EEF",                      /* 1EEE; 1EEF; Case map */
+            "\x1EF0\x1EF1",                      /* 1EF0; 1EF1; Case map */
+            "\x1EF2\x1EF3",                      /* 1EF2; 1EF3; Case map */
+            "\x1EF4\x1EF5",                      /* 1EF4; 1EF5; Case map */
+            "\x1EF6\x1EF7",                      /* 1EF6; 1EF7; Case map */
+            "\x1EF8\x1EF9",                      /* 1EF8; 1EF9; Case map */
+            "\x1F08\x1F00",                      /* 1F08; 1F00; Case map */
+            "\x1F09\x1F01",                      /* 1F09; 1F01; Case map */
+            "\x1F0A\x1F02",                      /* 1F0A; 1F02; Case map */
+            "\x1F0B\x1F03",                      /* 1F0B; 1F03; Case map */
+            "\x1F0C\x1F04",                      /* 1F0C; 1F04; Case map */
+            "\x1F0D\x1F05",                      /* 1F0D; 1F05; Case map */
+            "\x1F0E\x1F06",                      /* 1F0E; 1F06; Case map */
+            "\x1F0F\x1F07",                      /* 1F0F; 1F07; Case map */
+            "\x1F18\x1F10",                      /* 1F18; 1F10; Case map */
+            "\x1F19\x1F11",                      /* 1F19; 1F11; Case map */
+            "\x1F1A\x1F12",                      /* 1F1A; 1F12; Case map */
+            "\x1F1B\x1F13",                      /* 1F1B; 1F13; Case map */
+            "\x1F1C\x1F14",                      /* 1F1C; 1F14; Case map */
+            "\x1F1D\x1F15",                      /* 1F1D; 1F15; Case map */
+            "\x1F28\x1F20",                      /* 1F28; 1F20; Case map */
+            "\x1F29\x1F21",                      /* 1F29; 1F21; Case map */
+            "\x1F2A\x1F22",                      /* 1F2A; 1F22; Case map */
+            "\x1F2B\x1F23",                      /* 1F2B; 1F23; Case map */
+            "\x1F2C\x1F24",                      /* 1F2C; 1F24; Case map */
+            "\x1F2D\x1F25",                      /* 1F2D; 1F25; Case map */
+            "\x1F2E\x1F26",                      /* 1F2E; 1F26; Case map */
+            "\x1F2F\x1F27",                      /* 1F2F; 1F27; Case map */
+            "\x1F38\x1F30",                      /* 1F38; 1F30; Case map */
+            "\x1F39\x1F31",                      /* 1F39; 1F31; Case map */
+            "\x1F3A\x1F32",                      /* 1F3A; 1F32; Case map */
+            "\x1F3B\x1F33",                      /* 1F3B; 1F33; Case map */
+            "\x1F3C\x1F34",                      /* 1F3C; 1F34; Case map */
+            "\x1F3D\x1F35",                      /* 1F3D; 1F35; Case map */
+            "\x1F3E\x1F36",                      /* 1F3E; 1F36; Case map */
+            "\x1F3F\x1F37",                      /* 1F3F; 1F37; Case map */
+            "\x1F48\x1F40",                      /* 1F48; 1F40; Case map */
+            "\x1F49\x1F41",                      /* 1F49; 1F41; Case map */
+            "\x1F4A\x1F42",                      /* 1F4A; 1F42; Case map */
+            "\x1F4B\x1F43",                      /* 1F4B; 1F43; Case map */
+            "\x1F4C\x1F44",                      /* 1F4C; 1F44; Case map */
+            "\x1F4D\x1F45",                      /* 1F4D; 1F45; Case map */
+            "\x1F50\x03C5\x0313",                /* 1F50; 03C5 0313; Case map */
+            "\x1F52\x03C5\x0313\x0300",          /* 1F52; 03C5 0313 0300; Case map */
+            "\x1F54\x03C5\x0313\x0301",          /* 1F54; 03C5 0313 0301; Case map */
+            "\x1F56\x03C5\x0313\x0342",          /* 1F56; 03C5 0313 0342; Case map */
+            "\x1F59\x1F51",                      /* 1F59; 1F51; Case map */
+            "\x1F5B\x1F53",                      /* 1F5B; 1F53; Case map */
+            "\x1F5D\x1F55",                      /* 1F5D; 1F55; Case map */
+            "\x1F5F\x1F57",                      /* 1F5F; 1F57; Case map */
+            "\x1F68\x1F60",                      /* 1F68; 1F60; Case map */
+            "\x1F69\x1F61",                      /* 1F69; 1F61; Case map */
+            "\x1F6A\x1F62",                      /* 1F6A; 1F62; Case map */
+            "\x1F6B\x1F63",                      /* 1F6B; 1F63; Case map */
+            "\x1F6C\x1F64",                      /* 1F6C; 1F64; Case map */
+            "\x1F6D\x1F65",                      /* 1F6D; 1F65; Case map */
+            "\x1F6E\x1F66",                      /* 1F6E; 1F66; Case map */
+            "\x1F6F\x1F67",                      /* 1F6F; 1F67; Case map */
+            "\x1F80\x1F00\x03B9",                /* 1F80; 1F00 03B9; Case map */
+            "\x1F81\x1F01\x03B9",                /* 1F81; 1F01 03B9; Case map */
+            "\x1F82\x1F02\x03B9",                /* 1F82; 1F02 03B9; Case map */
+            "\x1F83\x1F03\x03B9",                /* 1F83; 1F03 03B9; Case map */
+            "\x1F84\x1F04\x03B9",                /* 1F84; 1F04 03B9; Case map */
+            "\x1F85\x1F05\x03B9",                /* 1F85; 1F05 03B9; Case map */
+            "\x1F86\x1F06\x03B9",                /* 1F86; 1F06 03B9; Case map */
+            "\x1F87\x1F07\x03B9",                /* 1F87; 1F07 03B9; Case map */
+            "\x1F88\x1F00\x03B9",                /* 1F88; 1F00 03B9; Case map */
+            "\x1F89\x1F01\x03B9",                /* 1F89; 1F01 03B9; Case map */
+            "\x1F8A\x1F02\x03B9",                /* 1F8A; 1F02 03B9; Case map */
+            "\x1F8B\x1F03\x03B9",                /* 1F8B; 1F03 03B9; Case map */
+            "\x1F8C\x1F04\x03B9",                /* 1F8C; 1F04 03B9; Case map */
+            "\x1F8D\x1F05\x03B9",                /* 1F8D; 1F05 03B9; Case map */
+            "\x1F8E\x1F06\x03B9",                /* 1F8E; 1F06 03B9; Case map */
+            "\x1F8F\x1F07\x03B9",                /* 1F8F; 1F07 03B9; Case map */
+            "\x1F90\x1F20\x03B9",                /* 1F90; 1F20 03B9; Case map */
+            "\x1F91\x1F21\x03B9",                /* 1F91; 1F21 03B9; Case map */
+            "\x1F92\x1F22\x03B9",                /* 1F92; 1F22 03B9; Case map */
+            "\x1F93\x1F23\x03B9",                /* 1F93; 1F23 03B9; Case map */
+            "\x1F94\x1F24\x03B9",                /* 1F94; 1F24 03B9; Case map */
+            "\x1F95\x1F25\x03B9",                /* 1F95; 1F25 03B9; Case map */
+            "\x1F96\x1F26\x03B9",                /* 1F96; 1F26 03B9; Case map */
+            "\x1F97\x1F27\x03B9",                /* 1F97; 1F27 03B9; Case map */
+            "\x1F98\x1F20\x03B9",                /* 1F98; 1F20 03B9; Case map */
+            "\x1F99\x1F21\x03B9",                /* 1F99; 1F21 03B9; Case map */
+            "\x1F9A\x1F22\x03B9",                /* 1F9A; 1F22 03B9; Case map */
+            "\x1F9B\x1F23\x03B9",                /* 1F9B; 1F23 03B9; Case map */
+            "\x1F9C\x1F24\x03B9",                /* 1F9C; 1F24 03B9; Case map */
+            "\x1F9D\x1F25\x03B9",                /* 1F9D; 1F25 03B9; Case map */
+            "\x1F9E\x1F26\x03B9",                /* 1F9E; 1F26 03B9; Case map */
+            "\x1F9F\x1F27\x03B9",                /* 1F9F; 1F27 03B9; Case map */
+            "\x1FA0\x1F60\x03B9",                /* 1FA0; 1F60 03B9; Case map */
+            "\x1FA1\x1F61\x03B9",                /* 1FA1; 1F61 03B9; Case map */
+            "\x1FA2\x1F62\x03B9",                /* 1FA2; 1F62 03B9; Case map */
+            "\x1FA3\x1F63\x03B9",                /* 1FA3; 1F63 03B9; Case map */
+            "\x1FA4\x1F64\x03B9",                /* 1FA4; 1F64 03B9; Case map */
+            "\x1FA5\x1F65\x03B9",                /* 1FA5; 1F65 03B9; Case map */
+            "\x1FA6\x1F66\x03B9",                /* 1FA6; 1F66 03B9; Case map */
+            "\x1FA7\x1F67\x03B9",                /* 1FA7; 1F67 03B9; Case map */
+            "\x1FA8\x1F60\x03B9",                /* 1FA8; 1F60 03B9; Case map */
+            "\x1FA9\x1F61\x03B9",                /* 1FA9; 1F61 03B9; Case map */
+            "\x1FAA\x1F62\x03B9",                /* 1FAA; 1F62 03B9; Case map */
+            "\x1FAB\x1F63\x03B9",                /* 1FAB; 1F63 03B9; Case map */
+            "\x1FAC\x1F64\x03B9",                /* 1FAC; 1F64 03B9; Case map */
+            "\x1FAD\x1F65\x03B9",                /* 1FAD; 1F65 03B9; Case map */
+            "\x1FAE\x1F66\x03B9",                /* 1FAE; 1F66 03B9; Case map */
+            "\x1FAF\x1F67\x03B9",                /* 1FAF; 1F67 03B9; Case map */
+            "\x1FB2\x1F70\x03B9",                /* 1FB2; 1F70 03B9; Case map */
+            "\x1FB3\x03B1\x03B9",                /* 1FB3; 03B1 03B9; Case map */
+            "\x1FB4\x03AC\x03B9",                /* 1FB4; 03AC 03B9; Case map */
+            "\x1FB6\x03B1\x0342",                /* 1FB6; 03B1 0342; Case map */
+            "\x1FB7\x03B1\x0342\x03B9",          /* 1FB7; 03B1 0342 03B9; Case map */
+            "\x1FB8\x1FB0",                      /* 1FB8; 1FB0; Case map */
+            "\x1FB9\x1FB1",                      /* 1FB9; 1FB1; Case map */
+            "\x1FBA\x1F70",                      /* 1FBA; 1F70; Case map */
+            "\x1FBB\x1F71",                      /* 1FBB; 1F71; Case map */
+            "\x1FBC\x03B1\x03B9",                /* 1FBC; 03B1 03B9; Case map */
+            "\x1FBE\x03B9",                      /* 1FBE; 03B9; Case map */
+            "\x1FC2\x1F74\x03B9",                /* 1FC2; 1F74 03B9; Case map */
+            "\x1FC3\x03B7\x03B9",                /* 1FC3; 03B7 03B9; Case map */
+            "\x1FC4\x03AE\x03B9",                /* 1FC4; 03AE 03B9; Case map */
+            "\x1FC6\x03B7\x0342",                /* 1FC6; 03B7 0342; Case map */
+            "\x1FC7\x03B7\x0342\x03B9",          /* 1FC7; 03B7 0342 03B9; Case map */
+            "\x1FC8\x1F72",                      /* 1FC8; 1F72; Case map */
+            "\x1FC9\x1F73",                      /* 1FC9; 1F73; Case map */
+            "\x1FCA\x1F74",                      /* 1FCA; 1F74; Case map */
+            "\x1FCB\x1F75",                      /* 1FCB; 1F75; Case map */
+            "\x1FCC\x03B7\x03B9",                /* 1FCC; 03B7 03B9; Case map */
+            "\x1FD2\x03B9\x0308\x0300",          /* 1FD2; 03B9 0308 0300; Case map */
+            "\x1FD3\x03B9\x0308\x0301",          /* 1FD3; 03B9 0308 0301; Case map */
+            "\x1FD6\x03B9\x0342",                /* 1FD6; 03B9 0342; Case map */
+            "\x1FD7\x03B9\x0308\x0342",          /* 1FD7; 03B9 0308 0342; Case map */
+            "\x1FD8\x1FD0",                      /* 1FD8; 1FD0; Case map */
+            "\x1FD9\x1FD1",                      /* 1FD9; 1FD1; Case map */
+            "\x1FDA\x1F76",                      /* 1FDA; 1F76; Case map */
+            "\x1FDB\x1F77",                      /* 1FDB; 1F77; Case map */
+            "\x1FE2\x03C5\x0308\x0300",          /* 1FE2; 03C5 0308 0300; Case map */
+            "\x1FE3\x03C5\x0308\x0301",          /* 1FE3; 03C5 0308 0301; Case map */
+            "\x1FE4\x03C1\x0313",                /* 1FE4; 03C1 0313; Case map */
+            "\x1FE6\x03C5\x0342",                /* 1FE6; 03C5 0342; Case map */
+            "\x1FE7\x03C5\x0308\x0342",          /* 1FE7; 03C5 0308 0342; Case map */
+            "\x1FE8\x1FE0",                      /* 1FE8; 1FE0; Case map */
+            "\x1FE9\x1FE1",                      /* 1FE9; 1FE1; Case map */
+            "\x1FEA\x1F7A",                      /* 1FEA; 1F7A; Case map */
+            "\x1FEB\x1F7B",                      /* 1FEB; 1F7B; Case map */
+            "\x1FEC\x1FE5",                      /* 1FEC; 1FE5; Case map */
+            "\x1FF2\x1F7C\x03B9",                /* 1FF2; 1F7C 03B9; Case map */
+            "\x1FF3\x03C9\x03B9",                /* 1FF3; 03C9 03B9; Case map */
+            "\x1FF4\x03CE\x03B9",                /* 1FF4; 03CE 03B9; Case map */
+            "\x1FF6\x03C9\x0342",                /* 1FF6; 03C9 0342; Case map */
+            "\x1FF7\x03C9\x0342\x03B9",          /* 1FF7; 03C9 0342 03B9; Case map */
+            "\x1FF8\x1F78",                      /* 1FF8; 1F78; Case map */
+            "\x1FF9\x1F79",                      /* 1FF9; 1F79; Case map */
+            "\x1FFA\x1F7C",                      /* 1FFA; 1F7C; Case map */
+            "\x1FFB\x1F7D",                      /* 1FFB; 1F7D; Case map */
+            "\x1FFC\x03C9\x03B9",                /* 1FFC; 03C9 03B9; Case map */
+            "\x20A8\x0072\x0073",      /* 20A8; 0072 0073; Additional folding */
+            "\x2102\x0063",            /* 2102; 0063; Additional folding */
+            "\x2103\x00B0\x0063",      /* 2103; 00B0 0063; Additional folding */
+            "\x2107\x025B",            /* 2107; 025B; Additional folding */
+            "\x2109\x00B0\x0066",      /* 2109; 00B0 0066; Additional folding */
+            "\x210B\x0068",            /* 210B; 0068; Additional folding */
+            "\x210C\x0068",            /* 210C; 0068; Additional folding */
+            "\x210D\x0068",            /* 210D; 0068; Additional folding */
+            "\x2110\x0069",            /* 2110; 0069; Additional folding */
+            "\x2111\x0069",            /* 2111; 0069; Additional folding */
+            "\x2112\x006C",            /* 2112; 006C; Additional folding */
+            "\x2115\x006E",            /* 2115; 006E; Additional folding */
+            "\x2116\x006E\x006F",      /* 2116; 006E 006F; Additional folding */
+            "\x2119\x0070",            /* 2119; 0070; Additional folding */
+            "\x211A\x0071",            /* 211A; 0071; Additional folding */
+            "\x211B\x0072",            /* 211B; 0072; Additional folding */
+            "\x211C\x0072",            /* 211C; 0072; Additional folding */
+            "\x211D\x0072",            /* 211D; 0072; Additional folding */
+            "\x2120\x0073\x006D",      /* 2120; 0073 006D; Additional folding */
+            "\x2121\x0074\x0065\x006C",  /* 2121; 0074 0065 006C; Additional folding */
+            "\x2122\x0074\x006D",      /* 2122; 0074 006D; Additional folding */
+            "\x2124\x007A",            /* 2124; 007A; Additional folding */
+            "\x2126\x03C9",                      /* 2126; 03C9; Case map */
+            "\x2128\x007A",            /* 2128; 007A; Additional folding */
+            "\x212A\x006B",                      /* 212A; 006B; Case map */
+            "\x212B\x00E5",                      /* 212B; 00E5; Case map */
+            "\x212C\x0062",            /* 212C; 0062; Additional folding */
+            "\x212D\x0063",            /* 212D; 0063; Additional folding */
+            "\x2130\x0065",            /* 2130; 0065; Additional folding */
+            "\x2131\x0066",            /* 2131; 0066; Additional folding */
+            "\x2133\x006D",            /* 2133; 006D; Additional folding */
+            "\x213E\x03B3",            /* 213E; 03B3; Additional folding */
+            "\x213F\x03C0",            /* 213F; 03C0; Additional folding */
+            "\x2145\x0064",            /* 2145; 0064; Additional folding */
+            "\x2160\x2170",                      /* 2160; 2170; Case map */
+            "\x2161\x2171",                      /* 2161; 2171; Case map */
+            "\x2162\x2172",                      /* 2162; 2172; Case map */
+            "\x2163\x2173",                      /* 2163; 2173; Case map */
+            "\x2164\x2174",                      /* 2164; 2174; Case map */
+            "\x2165\x2175",                      /* 2165; 2175; Case map */
+            "\x2166\x2176",                      /* 2166; 2176; Case map */
+            "\x2167\x2177",                      /* 2167; 2177; Case map */
+            "\x2168\x2178",                      /* 2168; 2178; Case map */
+            "\x2169\x2179",                      /* 2169; 2179; Case map */
+            "\x216A\x217A",                      /* 216A; 217A; Case map */
+            "\x216B\x217B",                      /* 216B; 217B; Case map */
+            "\x216C\x217C",                      /* 216C; 217C; Case map */
+            "\x216D\x217D",                      /* 216D; 217D; Case map */
+            "\x216E\x217E",                      /* 216E; 217E; Case map */
+            "\x216F\x217F",                      /* 216F; 217F; Case map */
+            "\x24B6\x24D0",                      /* 24B6; 24D0; Case map */
+            "\x24B7\x24D1",                      /* 24B7; 24D1; Case map */
+            "\x24B8\x24D2",                      /* 24B8; 24D2; Case map */
+            "\x24B9\x24D3",                      /* 24B9; 24D3; Case map */
+            "\x24BA\x24D4",                      /* 24BA; 24D4; Case map */
+            "\x24BB\x24D5",                      /* 24BB; 24D5; Case map */
+            "\x24BC\x24D6",                      /* 24BC; 24D6; Case map */
+            "\x24BD\x24D7",                      /* 24BD; 24D7; Case map */
+            "\x24BE\x24D8",                      /* 24BE; 24D8; Case map */
+            "\x24BF\x24D9",                      /* 24BF; 24D9; Case map */
+            "\x24C0\x24DA",                      /* 24C0; 24DA; Case map */
+            "\x24C1\x24DB",                      /* 24C1; 24DB; Case map */
+            "\x24C2\x24DC",                      /* 24C2; 24DC; Case map */
+            "\x24C3\x24DD",                      /* 24C3; 24DD; Case map */
+            "\x24C4\x24DE",                      /* 24C4; 24DE; Case map */
+            "\x24C5\x24DF",                      /* 24C5; 24DF; Case map */
+            "\x24C6\x24E0",                      /* 24C6; 24E0; Case map */
+            "\x24C7\x24E1",                      /* 24C7; 24E1; Case map */
+            "\x24C8\x24E2",                      /* 24C8; 24E2; Case map */
+            "\x24C9\x24E3",                      /* 24C9; 24E3; Case map */
+            "\x24CA\x24E4",                      /* 24CA; 24E4; Case map */
+            "\x24CB\x24E5",                      /* 24CB; 24E5; Case map */
+            "\x24CC\x24E6",                      /* 24CC; 24E6; Case map */
+            "\x24CD\x24E7",                      /* 24CD; 24E7; Case map */
+            "\x24CE\x24E8",                      /* 24CE; 24E8; Case map */
+            "\x24CF\x24E9",                      /* 24CF; 24E9; Case map */
+            "\x3371\x0068\x0070\x0061",  /* 3371; 0068 0070 0061; Additional folding */
+            "\x3373\x0061\x0075",      /* 3373; 0061 0075; Additional folding */
+            "\x3375\x006F\x0076",      /* 3375; 006F 0076; Additional folding */
+            "\x3380\x0070\x0061",      /* 3380; 0070 0061; Additional folding */
+            "\x3381\x006E\x0061",      /* 3381; 006E 0061; Additional folding */
+            "\x3382\x03BC\x0061",      /* 3382; 03BC 0061; Additional folding */
+            "\x3383\x006D\x0061",      /* 3383; 006D 0061; Additional folding */
+            "\x3384\x006B\x0061",      /* 3384; 006B 0061; Additional folding */
+            "\x3385\x006B\x0062",      /* 3385; 006B 0062; Additional folding */
+            "\x3386\x006D\x0062",      /* 3386; 006D 0062; Additional folding */
+            "\x3387\x0067\x0062",      /* 3387; 0067 0062; Additional folding */
+            "\x338A\x0070\x0066",      /* 338A; 0070 0066; Additional folding */
+            "\x338B\x006E\x0066",      /* 338B; 006E 0066; Additional folding */
+            "\x338C\x03BC\x0066",      /* 338C; 03BC 0066; Additional folding */
+            "\x3390\x0068\x007A",      /* 3390; 0068 007A; Additional folding */
+            "\x3391\x006B\x0068\x007A",  /* 3391; 006B 0068 007A; Additional folding */
+            "\x3392\x006D\x0068\x007A",  /* 3392; 006D 0068 007A; Additional folding */
+            "\x3393\x0067\x0068\x007A",  /* 3393; 0067 0068 007A; Additional folding */
+            "\x3394\x0074\x0068\x007A",  /* 3394; 0074 0068 007A; Additional folding */
+            "\x33A9\x0070\x0061",      /* 33A9; 0070 0061; Additional folding */
+            "\x33AA\x006B\x0070\x0061",  /* 33AA; 006B 0070 0061; Additional folding */
+            "\x33AB\x006D\x0070\x0061",  /* 33AB; 006D 0070 0061; Additional folding */
+            "\x33AC\x0067\x0070\x0061",  /* 33AC; 0067 0070 0061; Additional folding */
+            "\x33B4\x0070\x0076",      /* 33B4; 0070 0076; Additional folding */
+            "\x33B5\x006E\x0076",      /* 33B5; 006E 0076; Additional folding */
+            "\x33B6\x03BC\x0076",      /* 33B6; 03BC 0076; Additional folding */
+            "\x33B7\x006D\x0076",      /* 33B7; 006D 0076; Additional folding */
+            "\x33B8\x006B\x0076",      /* 33B8; 006B 0076; Additional folding */
+            "\x33B9\x006D\x0076",      /* 33B9; 006D 0076; Additional folding */
+            "\x33BA\x0070\x0077",      /* 33BA; 0070 0077; Additional folding */
+            "\x33BB\x006E\x0077",      /* 33BB; 006E 0077; Additional folding */
+            "\x33BC\x03BC\x0077",      /* 33BC; 03BC 0077; Additional folding */
+            "\x33BD\x006D\x0077",      /* 33BD; 006D 0077; Additional folding */
+            "\x33BE\x006B\x0077",      /* 33BE; 006B 0077; Additional folding */
+            "\x33BF\x006D\x0077",      /* 33BF; 006D 0077; Additional folding */
+            "\x33C0\x006B\x03C9",      /* 33C0; 006B 03C9; Additional folding */
+            "\x33C1\x006D\x03C9",      /* 33C1; 006D 03C9; Additional folding */
+            "\x33C3\x0062\x0071",      /* 33C3; 0062 0071; Additional folding */
+            "\x33C6\x0063\x2215\x006B\x0067",  /* 33C6; 0063 2215 006B 0067; Additional folding */
+            "\x33C7\x0063\x006F\x002E",  /* 33C7; 0063 006F 002E; Additional folding */
+            "\x33C8\x0064\x0062",      /* 33C8; 0064 0062; Additional folding */
+            "\x33C9\x0067\x0079",      /* 33C9; 0067 0079; Additional folding */
+            "\x33CB\x0068\x0070",      /* 33CB; 0068 0070; Additional folding */
+            "\x33CD\x006B\x006B",      /* 33CD; 006B 006B; Additional folding */
+            "\x33CE\x006B\x006D",      /* 33CE; 006B 006D; Additional folding */
+            "\x33D7\x0070\x0068",      /* 33D7; 0070 0068; Additional folding */
+            "\x33D9\x0070\x0070\x006D",  /* 33D9; 0070 0070 006D; Additional folding */
+            "\x33DA\x0070\x0072",      /* 33DA; 0070 0072; Additional folding */
+            "\x33DC\x0073\x0076",      /* 33DC; 0073 0076; Additional folding */
+            "\x33DD\x0077\x0062",      /* 33DD; 0077 0062; Additional folding */
+            "\xFB00\x0066\x0066",                /* FB00; 0066 0066; Case map */
+            "\xFB01\x0066\x0069",                /* FB01; 0066 0069; Case map */
+            "\xFB02\x0066\x006C",                /* FB02; 0066 006C; Case map */
+            "\xFB03\x0066\x0066\x0069",          /* FB03; 0066 0066 0069; Case map */
+            "\xFB04\x0066\x0066\x006C",          /* FB04; 0066 0066 006C; Case map */
+            "\xFB05\x0073\x0074",                /* FB05; 0073 0074; Case map */
+            "\xFB06\x0073\x0074",                /* FB06; 0073 0074; Case map */
+            "\xFB13\x0574\x0576",                /* FB13; 0574 0576; Case map */
+            "\xFB14\x0574\x0565",                /* FB14; 0574 0565; Case map */
+            "\xFB15\x0574\x056B",                /* FB15; 0574 056B; Case map */
+            "\xFB16\x057E\x0576",                /* FB16; 057E 0576; Case map */
+            "\xFB17\x0574\x056D",                /* FB17; 0574 056D; Case map */
+            "\xFF21\xFF41",                      /* FF21; FF41; Case map */
+            "\xFF22\xFF42",                      /* FF22; FF42; Case map */
+            "\xFF23\xFF43",                      /* FF23; FF43; Case map */
+            "\xFF24\xFF44",                      /* FF24; FF44; Case map */
+            "\xFF25\xFF45",                      /* FF25; FF45; Case map */
+            "\xFF26\xFF46",                      /* FF26; FF46; Case map */
+            "\xFF27\xFF47",                      /* FF27; FF47; Case map */
+            "\xFF28\xFF48",                      /* FF28; FF48; Case map */
+            "\xFF29\xFF49",                      /* FF29; FF49; Case map */
+            "\xFF2A\xFF4A",                      /* FF2A; FF4A; Case map */
+            "\xFF2B\xFF4B",                      /* FF2B; FF4B; Case map */
+            "\xFF2C\xFF4C",                      /* FF2C; FF4C; Case map */
+            "\xFF2D\xFF4D",                      /* FF2D; FF4D; Case map */
+            "\xFF2E\xFF4E",                      /* FF2E; FF4E; Case map */
+            "\xFF2F\xFF4F",                      /* FF2F; FF4F; Case map */
+            "\xFF30\xFF50",                      /* FF30; FF50; Case map */
+            "\xFF31\xFF51",                      /* FF31; FF51; Case map */
+            "\xFF32\xFF52",                      /* FF32; FF52; Case map */
+            "\xFF33\xFF53",                      /* FF33; FF53; Case map */
+            "\xFF34\xFF54",                      /* FF34; FF54; Case map */
+            "\xFF35\xFF55",                      /* FF35; FF55; Case map */
+            "\xFF36\xFF56",                      /* FF36; FF56; Case map */
+            "\xFF37\xFF57",                      /* FF37; FF57; Case map */
+            "\xFF38\xFF58",                      /* FF38; FF58; Case map */
+            "\xFF39\xFF59",                      /* FF39; FF59; Case map */
+            "\xFF3A\xFF5A",                      /* FF3A; FF5A; Case map */
+        };
+
+
+        /// <summary>
+        /// B.3 Mapping for case-folding used with no normalization
+        ///
+        /// </summary>
+        public static readonly string[] B_3 = new string[]
+        {
+            "\x0041\x0061",                      /* 0041; 0061; Case map */
+            "\x0042\x0062",                      /* 0042; 0062; Case map */
+            "\x0043\x0063",                      /* 0043; 0063; Case map */
+            "\x0044\x0064",                      /* 0044; 0064; Case map */
+            "\x0045\x0065",                      /* 0045; 0065; Case map */
+            "\x0046\x0066",                      /* 0046; 0066; Case map */
+            "\x0047\x0067",                      /* 0047; 0067; Case map */
+            "\x0048\x0068",                      /* 0048; 0068; Case map */
+            "\x0049\x0069",                      /* 0049; 0069; Case map */
+            "\x004A\x006A",                      /* 004A; 006A; Case map */
+            "\x004B\x006B",                      /* 004B; 006B; Case map */
+            "\x004C\x006C",                      /* 004C; 006C; Case map */
+            "\x004D\x006D",                      /* 004D; 006D; Case map */
+            "\x004E\x006E",                      /* 004E; 006E; Case map */
+            "\x004F\x006F",                      /* 004F; 006F; Case map */
+            "\x0050\x0070",                      /* 0050; 0070; Case map */
+            "\x0051\x0071",                      /* 0051; 0071; Case map */
+            "\x0052\x0072",                      /* 0052; 0072; Case map */
+            "\x0053\x0073",                      /* 0053; 0073; Case map */
+            "\x0054\x0074",                      /* 0054; 0074; Case map */
+            "\x0055\x0075",                      /* 0055; 0075; Case map */
+            "\x0056\x0076",                      /* 0056; 0076; Case map */
+            "\x0057\x0077",                      /* 0057; 0077; Case map */
+            "\x0058\x0078",                      /* 0058; 0078; Case map */
+            "\x0059\x0079",                      /* 0059; 0079; Case map */
+            "\x005A\x007A",                      /* 005A; 007A; Case map */
+            "\x00B5\x03BC",                      /* 00B5; 03BC; Case map */
+            "\x00C0\x00E0",                      /* 00C0; 00E0; Case map */
+            "\x00C1\x00E1",                      /* 00C1; 00E1; Case map */
+            "\x00C2\x00E2",                      /* 00C2; 00E2; Case map */
+            "\x00C3\x00E3",                      /* 00C3; 00E3; Case map */
+            "\x00C4\x00E4",                      /* 00C4; 00E4; Case map */
+            "\x00C5\x00E5",                      /* 00C5; 00E5; Case map */
+            "\x00C6\x00E6",                      /* 00C6; 00E6; Case map */
+            "\x00C7\x00E7",                      /* 00C7; 00E7; Case map */
+            "\x00C8\x00E8",                      /* 00C8; 00E8; Case map */
+            "\x00C9\x00E9",                      /* 00C9; 00E9; Case map */
+            "\x00CA\x00EA",                      /* 00CA; 00EA; Case map */
+            "\x00CB\x00EB",                      /* 00CB; 00EB; Case map */
+            "\x00CC\x00EC",                      /* 00CC; 00EC; Case map */
+            "\x00CD\x00ED",                      /* 00CD; 00ED; Case map */
+            "\x00CE\x00EE",                      /* 00CE; 00EE; Case map */
+            "\x00CF\x00EF",                      /* 00CF; 00EF; Case map */
+            "\x00D0\x00F0",                      /* 00D0; 00F0; Case map */
+            "\x00D1\x00F1",                      /* 00D1; 00F1; Case map */
+            "\x00D2\x00F2",                      /* 00D2; 00F2; Case map */
+            "\x00D3\x00F3",                      /* 00D3; 00F3; Case map */
+            "\x00D4\x00F4",                      /* 00D4; 00F4; Case map */
+            "\x00D5\x00F5",                      /* 00D5; 00F5; Case map */
+            "\x00D6\x00F6",                      /* 00D6; 00F6; Case map */
+            "\x00D8\x00F8",                      /* 00D8; 00F8; Case map */
+            "\x00D9\x00F9",                      /* 00D9; 00F9; Case map */
+            "\x00DA\x00FA",                      /* 00DA; 00FA; Case map */
+            "\x00DB\x00FB",                      /* 00DB; 00FB; Case map */
+            "\x00DC\x00FC",                      /* 00DC; 00FC; Case map */
+            "\x00DD\x00FD",                      /* 00DD; 00FD; Case map */
+            "\x00DE\x00FE",                      /* 00DE; 00FE; Case map */
+            "\x00DF\x0073\x0073",                /* 00DF; 0073 0073; Case map */
+            "\x0100\x0101",                      /* 0100; 0101; Case map */
+            "\x0102\x0103",                      /* 0102; 0103; Case map */
+            "\x0104\x0105",                      /* 0104; 0105; Case map */
+            "\x0106\x0107",                      /* 0106; 0107; Case map */
+            "\x0108\x0109",                      /* 0108; 0109; Case map */
+            "\x010A\x010B",                      /* 010A; 010B; Case map */
+            "\x010C\x010D",                      /* 010C; 010D; Case map */
+            "\x010E\x010F",                      /* 010E; 010F; Case map */
+            "\x0110\x0111",                      /* 0110; 0111; Case map */
+            "\x0112\x0113",                      /* 0112; 0113; Case map */
+            "\x0114\x0115",                      /* 0114; 0115; Case map */
+            "\x0116\x0117",                      /* 0116; 0117; Case map */
+            "\x0118\x0119",                      /* 0118; 0119; Case map */
+            "\x011A\x011B",                      /* 011A; 011B; Case map */
+            "\x011C\x011D",                      /* 011C; 011D; Case map */
+            "\x011E\x011F",                      /* 011E; 011F; Case map */
+            "\x0120\x0121",                      /* 0120; 0121; Case map */
+            "\x0122\x0123",                      /* 0122; 0123; Case map */
+            "\x0124\x0125",                      /* 0124; 0125; Case map */
+            "\x0126\x0127",                      /* 0126; 0127; Case map */
+            "\x0128\x0129",                      /* 0128; 0129; Case map */
+            "\x012A\x012B",                      /* 012A; 012B; Case map */
+            "\x012C\x012D",                      /* 012C; 012D; Case map */
+            "\x012E\x012F",                      /* 012E; 012F; Case map */
+            "\x0130\x0069\x0307",                /* 0130; 0069 0307; Case map */
+            "\x0132\x0133",                      /* 0132; 0133; Case map */
+            "\x0134\x0135",                      /* 0134; 0135; Case map */
+            "\x0136\x0137",                      /* 0136; 0137; Case map */
+            "\x0139\x013A",                      /* 0139; 013A; Case map */
+            "\x013B\x013C",                      /* 013B; 013C; Case map */
+            "\x013D\x013E",                      /* 013D; 013E; Case map */
+            "\x013F\x0140",                      /* 013F; 0140; Case map */
+            "\x0141\x0142",                      /* 0141; 0142; Case map */
+            "\x0143\x0144",                      /* 0143; 0144; Case map */
+            "\x0145\x0146",                      /* 0145; 0146; Case map */
+            "\x0147\x0148",                      /* 0147; 0148; Case map */
+            "\x0149\x02BC\x006E",                /* 0149; 02BC 006E; Case map */
+            "\x014A\x014B",                      /* 014A; 014B; Case map */
+            "\x014C\x014D",                      /* 014C; 014D; Case map */
+            "\x014E\x014F",                      /* 014E; 014F; Case map */
+            "\x0150\x0151",                      /* 0150; 0151; Case map */
+            "\x0152\x0153",                      /* 0152; 0153; Case map */
+            "\x0154\x0155",                      /* 0154; 0155; Case map */
+            "\x0156\x0157",                      /* 0156; 0157; Case map */
+            "\x0158\x0159",                      /* 0158; 0159; Case map */
+            "\x015A\x015B",                      /* 015A; 015B; Case map */
+            "\x015C\x015D",                      /* 015C; 015D; Case map */
+            "\x015E\x015F",                      /* 015E; 015F; Case map */
+            "\x0160\x0161",                      /* 0160; 0161; Case map */
+            "\x0162\x0163",                      /* 0162; 0163; Case map */
+            "\x0164\x0165",                      /* 0164; 0165; Case map */
+            "\x0166\x0167",                      /* 0166; 0167; Case map */
+            "\x0168\x0169",                      /* 0168; 0169; Case map */
+            "\x016A\x016B",                      /* 016A; 016B; Case map */
+            "\x016C\x016D",                      /* 016C; 016D; Case map */
+            "\x016E\x016F",                      /* 016E; 016F; Case map */
+            "\x0170\x0171",                      /* 0170; 0171; Case map */
+            "\x0172\x0173",                      /* 0172; 0173; Case map */
+            "\x0174\x0175",                      /* 0174; 0175; Case map */
+            "\x0176\x0177",                      /* 0176; 0177; Case map */
+            "\x0178\x00FF",                      /* 0178; 00FF; Case map */
+            "\x0179\x017A",                      /* 0179; 017A; Case map */
+            "\x017B\x017C",                      /* 017B; 017C; Case map */
+            "\x017D\x017E",                      /* 017D; 017E; Case map */
+            "\x017F\x0073",                      /* 017F; 0073; Case map */
+            "\x0181\x0253",                      /* 0181; 0253; Case map */
+            "\x0182\x0183",                      /* 0182; 0183; Case map */
+            "\x0184\x0185",                      /* 0184; 0185; Case map */
+            "\x0186\x0254",                      /* 0186; 0254; Case map */
+            "\x0187\x0188",                      /* 0187; 0188; Case map */
+            "\x0189\x0256",                      /* 0189; 0256; Case map */
+            "\x018A\x0257",                      /* 018A; 0257; Case map */
+            "\x018B\x018C",                      /* 018B; 018C; Case map */
+            "\x018E\x01DD",                      /* 018E; 01DD; Case map */
+            "\x018F\x0259",                      /* 018F; 0259; Case map */
+            "\x0190\x025B",                      /* 0190; 025B; Case map */
+            "\x0191\x0192",                      /* 0191; 0192; Case map */
+            "\x0193\x0260",                      /* 0193; 0260; Case map */
+            "\x0194\x0263",                      /* 0194; 0263; Case map */
+            "\x0196\x0269",                      /* 0196; 0269; Case map */
+            "\x0197\x0268",                      /* 0197; 0268; Case map */
+            "\x0198\x0199",                      /* 0198; 0199; Case map */
+            "\x019C\x026F",                      /* 019C; 026F; Case map */
+            "\x019D\x0272",                      /* 019D; 0272; Case map */
+            "\x019F\x0275",                      /* 019F; 0275; Case map */
+            "\x01A0\x01A1",                      /* 01A0; 01A1; Case map */
+            "\x01A2\x01A3",                      /* 01A2; 01A3; Case map */
+            "\x01A4\x01A5",                      /* 01A4; 01A5; Case map */
+            "\x01A6\x0280",                      /* 01A6; 0280; Case map */
+            "\x01A7\x01A8",                      /* 01A7; 01A8; Case map */
+            "\x01A9\x0283",                      /* 01A9; 0283; Case map */
+            "\x01AC\x01AD",                      /* 01AC; 01AD; Case map */
+            "\x01AE\x0288",                      /* 01AE; 0288; Case map */
+            "\x01AF\x01B0",                      /* 01AF; 01B0; Case map */
+            "\x01B1\x028A",                      /* 01B1; 028A; Case map */
+            "\x01B2\x028B",                      /* 01B2; 028B; Case map */
+            "\x01B3\x01B4",                      /* 01B3; 01B4; Case map */
+            "\x01B5\x01B6",                      /* 01B5; 01B6; Case map */
+            "\x01B7\x0292",                      /* 01B7; 0292; Case map */
+            "\x01B8\x01B9",                      /* 01B8; 01B9; Case map */
+            "\x01BC\x01BD",                      /* 01BC; 01BD; Case map */
+            "\x01C4\x01C6",                      /* 01C4; 01C6; Case map */
+            "\x01C5\x01C6",                      /* 01C5; 01C6; Case map */
+            "\x01C7\x01C9",                      /* 01C7; 01C9; Case map */
+            "\x01C8\x01C9",                      /* 01C8; 01C9; Case map */
+            "\x01CA\x01CC",                      /* 01CA; 01CC; Case map */
+            "\x01CB\x01CC",                      /* 01CB; 01CC; Case map */
+            "\x01CD\x01CE",                      /* 01CD; 01CE; Case map */
+            "\x01CF\x01D0",                      /* 01CF; 01D0; Case map */
+            "\x01D1\x01D2",                      /* 01D1; 01D2; Case map */
+            "\x01D3\x01D4",                      /* 01D3; 01D4; Case map */
+            "\x01D5\x01D6",                      /* 01D5; 01D6; Case map */
+            "\x01D7\x01D8",                      /* 01D7; 01D8; Case map */
+            "\x01D9\x01DA",                      /* 01D9; 01DA; Case map */
+            "\x01DB\x01DC",                      /* 01DB; 01DC; Case map */
+            "\x01DE\x01DF",                      /* 01DE; 01DF; Case map */
+            "\x01E0\x01E1",                      /* 01E0; 01E1; Case map */
+            "\x01E2\x01E3",                      /* 01E2; 01E3; Case map */
+            "\x01E4\x01E5",                      /* 01E4; 01E5; Case map */
+            "\x01E6\x01E7",                      /* 01E6; 01E7; Case map */
+            "\x01E8\x01E9",                      /* 01E8; 01E9; Case map */
+            "\x01EA\x01EB",                      /* 01EA; 01EB; Case map */
+            "\x01EC\x01ED",                      /* 01EC; 01ED; Case map */
+            "\x01EE\x01EF",                      /* 01EE; 01EF; Case map */
+            "\x01F0\x006A\x030C",                /* 01F0; 006A 030C; Case map */
+            "\x01F1\x01F3",                      /* 01F1; 01F3; Case map */
+            "\x01F2\x01F3",                      /* 01F2; 01F3; Case map */
+            "\x01F4\x01F5",                      /* 01F4; 01F5; Case map */
+            "\x01F6\x0195",                      /* 01F6; 0195; Case map */
+            "\x01F7\x01BF",                      /* 01F7; 01BF; Case map */
+            "\x01F8\x01F9",                      /* 01F8; 01F9; Case map */
+            "\x01FA\x01FB",                      /* 01FA; 01FB; Case map */
+            "\x01FC\x01FD",                      /* 01FC; 01FD; Case map */
+            "\x01FE\x01FF",                      /* 01FE; 01FF; Case map */
+            "\x0200\x0201",                      /* 0200; 0201; Case map */
+            "\x0202\x0203",                      /* 0202; 0203; Case map */
+            "\x0204\x0205",                      /* 0204; 0205; Case map */
+            "\x0206\x0207",                      /* 0206; 0207; Case map */
+            "\x0208\x0209",                      /* 0208; 0209; Case map */
+            "\x020A\x020B",                      /* 020A; 020B; Case map */
+            "\x020C\x020D",                      /* 020C; 020D; Case map */
+            "\x020E\x020F",                      /* 020E; 020F; Case map */
+            "\x0210\x0211",                      /* 0210; 0211; Case map */
+            "\x0212\x0213",                      /* 0212; 0213; Case map */
+            "\x0214\x0215",                      /* 0214; 0215; Case map */
+            "\x0216\x0217",                      /* 0216; 0217; Case map */
+            "\x0218\x0219",                      /* 0218; 0219; Case map */
+            "\x021A\x021B",                      /* 021A; 021B; Case map */
+            "\x021C\x021D",                      /* 021C; 021D; Case map */
+            "\x021E\x021F",                      /* 021E; 021F; Case map */
+            "\x0220\x019E",                      /* 0220; 019E; Case map */
+            "\x0222\x0223",                      /* 0222; 0223; Case map */
+            "\x0224\x0225",                      /* 0224; 0225; Case map */
+            "\x0226\x0227",                      /* 0226; 0227; Case map */
+            "\x0228\x0229",                      /* 0228; 0229; Case map */
+            "\x022A\x022B",                      /* 022A; 022B; Case map */
+            "\x022C\x022D",                      /* 022C; 022D; Case map */
+            "\x022E\x022F",                      /* 022E; 022F; Case map */
+            "\x0230\x0231",                      /* 0230; 0231; Case map */
+            "\x0232\x0233",                      /* 0232; 0233; Case map */
+            "\x0345\x03B9",                      /* 0345; 03B9; Case map */
+            "\x0386\x03AC",                      /* 0386; 03AC; Case map */
+            "\x0388\x03AD",                      /* 0388; 03AD; Case map */
+            "\x0389\x03AE",                      /* 0389; 03AE; Case map */
+            "\x038A\x03AF",                      /* 038A; 03AF; Case map */
+            "\x038C\x03CC",                      /* 038C; 03CC; Case map */
+            "\x038E\x03CD",                      /* 038E; 03CD; Case map */
+            "\x038F\x03CE",                      /* 038F; 03CE; Case map */
+            "\x0390\x03B9\x0308\x0301",          /* 0390; 03B9 0308 0301; Case map */
+            "\x0391\x03B1",                      /* 0391; 03B1; Case map */
+            "\x0392\x03B2",                      /* 0392; 03B2; Case map */
+            "\x0393\x03B3",                      /* 0393; 03B3; Case map */
+            "\x0394\x03B4",                      /* 0394; 03B4; Case map */
+            "\x0395\x03B5",                      /* 0395; 03B5; Case map */
+            "\x0396\x03B6",                      /* 0396; 03B6; Case map */
+            "\x0397\x03B7",                      /* 0397; 03B7; Case map */
+            "\x0398\x03B8",                      /* 0398; 03B8; Case map */
+            "\x0399\x03B9",                      /* 0399; 03B9; Case map */
+            "\x039A\x03BA",                      /* 039A; 03BA; Case map */
+            "\x039B\x03BB",                      /* 039B; 03BB; Case map */
+            "\x039C\x03BC",                      /* 039C; 03BC; Case map */
+            "\x039D\x03BD",                      /* 039D; 03BD; Case map */
+            "\x039E\x03BE",                      /* 039E; 03BE; Case map */
+            "\x039F\x03BF",                      /* 039F; 03BF; Case map */
+            "\x03A0\x03C0",                      /* 03A0; 03C0; Case map */
+            "\x03A1\x03C1",                      /* 03A1; 03C1; Case map */
+            "\x03A3\x03C3",                      /* 03A3; 03C3; Case map */
+            "\x03A4\x03C4",                      /* 03A4; 03C4; Case map */
+            "\x03A5\x03C5",                      /* 03A5; 03C5; Case map */
+            "\x03A6\x03C6",                      /* 03A6; 03C6; Case map */
+            "\x03A7\x03C7",                      /* 03A7; 03C7; Case map */
+            "\x03A8\x03C8",                      /* 03A8; 03C8; Case map */
+            "\x03A9\x03C9",                      /* 03A9; 03C9; Case map */
+            "\x03AA\x03CA",                      /* 03AA; 03CA; Case map */
+            "\x03AB\x03CB",                      /* 03AB; 03CB; Case map */
+            "\x03B0\x03C5\x0308\x0301",          /* 03B0; 03C5 0308 0301; Case map */
+            "\x03C2\x03C3",                      /* 03C2; 03C3; Case map */
+            "\x03D0\x03B2",                      /* 03D0; 03B2; Case map */
+            "\x03D1\x03B8",                      /* 03D1; 03B8; Case map */
+            "\x03D5\x03C6",                      /* 03D5; 03C6; Case map */
+            "\x03D6\x03C0",                      /* 03D6; 03C0; Case map */
+            "\x03D8\x03D9",                      /* 03D8; 03D9; Case map */
+            "\x03DA\x03DB",                      /* 03DA; 03DB; Case map */
+            "\x03DC\x03DD",                      /* 03DC; 03DD; Case map */
+            "\x03DE\x03DF",                      /* 03DE; 03DF; Case map */
+            "\x03E0\x03E1",                      /* 03E0; 03E1; Case map */
+            "\x03E2\x03E3",                      /* 03E2; 03E3; Case map */
+            "\x03E4\x03E5",                      /* 03E4; 03E5; Case map */
+            "\x03E6\x03E7",                      /* 03E6; 03E7; Case map */
+            "\x03E8\x03E9",                      /* 03E8; 03E9; Case map */
+            "\x03EA\x03EB",                      /* 03EA; 03EB; Case map */
+            "\x03EC\x03ED",                      /* 03EC; 03ED; Case map */
+            "\x03EE\x03EF",                      /* 03EE; 03EF; Case map */
+            "\x03F0\x03BA",                      /* 03F0; 03BA; Case map */
+            "\x03F1\x03C1",                      /* 03F1; 03C1; Case map */
+            "\x03F2\x03C3",                      /* 03F2; 03C3; Case map */
+            "\x03F4\x03B8",                      /* 03F4; 03B8; Case map */
+            "\x03F5\x03B5",                      /* 03F5; 03B5; Case map */
+            "\x0400\x0450",                      /* 0400; 0450; Case map */
+            "\x0401\x0451",                      /* 0401; 0451; Case map */
+            "\x0402\x0452",                      /* 0402; 0452; Case map */
+            "\x0403\x0453",                      /* 0403; 0453; Case map */
+            "\x0404\x0454",                      /* 0404; 0454; Case map */
+            "\x0405\x0455",                      /* 0405; 0455; Case map */
+            "\x0406\x0456",                      /* 0406; 0456; Case map */
+            "\x0407\x0457",                      /* 0407; 0457; Case map */
+            "\x0408\x0458",                      /* 0408; 0458; Case map */
+            "\x0409\x0459",                      /* 0409; 0459; Case map */
+            "\x040A\x045A",                      /* 040A; 045A; Case map */
+            "\x040B\x045B",                      /* 040B; 045B; Case map */
+            "\x040C\x045C",                      /* 040C; 045C; Case map */
+            "\x040D\x045D",                      /* 040D; 045D; Case map */
+            "\x040E\x045E",                      /* 040E; 045E; Case map */
+            "\x040F\x045F",                      /* 040F; 045F; Case map */
+            "\x0410\x0430",                      /* 0410; 0430; Case map */
+            "\x0411\x0431",                      /* 0411; 0431; Case map */
+            "\x0412\x0432",                      /* 0412; 0432; Case map */
+            "\x0413\x0433",                      /* 0413; 0433; Case map */
+            "\x0414\x0434",                      /* 0414; 0434; Case map */
+            "\x0415\x0435",                      /* 0415; 0435; Case map */
+            "\x0416\x0436",                      /* 0416; 0436; Case map */
+            "\x0417\x0437",                      /* 0417; 0437; Case map */
+            "\x0418\x0438",                      /* 0418; 0438; Case map */
+            "\x0419\x0439",                      /* 0419; 0439; Case map */
+            "\x041A\x043A",                      /* 041A; 043A; Case map */
+            "\x041B\x043B",                      /* 041B; 043B; Case map */
+            "\x041C\x043C",                      /* 041C; 043C; Case map */
+            "\x041D\x043D",                      /* 041D; 043D; Case map */
+            "\x041E\x043E",                      /* 041E; 043E; Case map */
+            "\x041F\x043F",                      /* 041F; 043F; Case map */
+            "\x0420\x0440",                      /* 0420; 0440; Case map */
+            "\x0421\x0441",                      /* 0421; 0441; Case map */
+            "\x0422\x0442",                      /* 0422; 0442; Case map */
+            "\x0423\x0443",                      /* 0423; 0443; Case map */
+            "\x0424\x0444",                      /* 0424; 0444; Case map */
+            "\x0425\x0445",                      /* 0425; 0445; Case map */
+            "\x0426\x0446",                      /* 0426; 0446; Case map */
+            "\x0427\x0447",                      /* 0427; 0447; Case map */
+            "\x0428\x0448",                      /* 0428; 0448; Case map */
+            "\x0429\x0449",                      /* 0429; 0449; Case map */
+            "\x042A\x044A",                      /* 042A; 044A; Case map */
+            "\x042B\x044B",                      /* 042B; 044B; Case map */
+            "\x042C\x044C",                      /* 042C; 044C; Case map */
+            "\x042D\x044D",                      /* 042D; 044D; Case map */
+            "\x042E\x044E",                      /* 042E; 044E; Case map */
+            "\x042F\x044F",                      /* 042F; 044F; Case map */
+            "\x0460\x0461",                      /* 0460; 0461; Case map */
+            "\x0462\x0463",                      /* 0462; 0463; Case map */
+            "\x0464\x0465",                      /* 0464; 0465; Case map */
+            "\x0466\x0467",                      /* 0466; 0467; Case map */
+            "\x0468\x0469",                      /* 0468; 0469; Case map */
+            "\x046A\x046B",                      /* 046A; 046B; Case map */
+            "\x046C\x046D",                      /* 046C; 046D; Case map */
+            "\x046E\x046F",                      /* 046E; 046F; Case map */
+            "\x0470\x0471",                      /* 0470; 0471; Case map */
+            "\x0472\x0473",                      /* 0472; 0473; Case map */
+            "\x0474\x0475",                      /* 0474; 0475; Case map */
+            "\x0476\x0477",                      /* 0476; 0477; Case map */
+            "\x0478\x0479",                      /* 0478; 0479; Case map */
+            "\x047A\x047B",                      /* 047A; 047B; Case map */
+            "\x047C\x047D",                      /* 047C; 047D; Case map */
+            "\x047E\x047F",                      /* 047E; 047F; Case map */
+            "\x0480\x0481",                      /* 0480; 0481; Case map */
+            "\x048A\x048B",                      /* 048A; 048B; Case map */
+            "\x048C\x048D",                      /* 048C; 048D; Case map */
+            "\x048E\x048F",                      /* 048E; 048F; Case map */
+            "\x0490\x0491",                      /* 0490; 0491; Case map */
+            "\x0492\x0493",                      /* 0492; 0493; Case map */
+            "\x0494\x0495",                      /* 0494; 0495; Case map */
+            "\x0496\x0497",                      /* 0496; 0497; Case map */
+            "\x0498\x0499",                      /* 0498; 0499; Case map */
+            "\x049A\x049B",                      /* 049A; 049B; Case map */
+            "\x049C\x049D",                      /* 049C; 049D; Case map */
+            "\x049E\x049F",                      /* 049E; 049F; Case map */
+            "\x04A0\x04A1",                      /* 04A0; 04A1; Case map */
+            "\x04A2\x04A3",                      /* 04A2; 04A3; Case map */
+            "\x04A4\x04A5",                      /* 04A4; 04A5; Case map */
+            "\x04A6\x04A7",                      /* 04A6; 04A7; Case map */
+            "\x04A8\x04A9",                      /* 04A8; 04A9; Case map */
+            "\x04AA\x04AB",                      /* 04AA; 04AB; Case map */
+            "\x04AC\x04AD",                      /* 04AC; 04AD; Case map */
+            "\x04AE\x04AF",                      /* 04AE; 04AF; Case map */
+            "\x04B0\x04B1",                      /* 04B0; 04B1; Case map */
+            "\x04B2\x04B3",                      /* 04B2; 04B3; Case map */
+            "\x04B4\x04B5",                      /* 04B4; 04B5; Case map */
+            "\x04B6\x04B7",                      /* 04B6; 04B7; Case map */
+            "\x04B8\x04B9",                      /* 04B8; 04B9; Case map */
+            "\x04BA\x04BB",                      /* 04BA; 04BB; Case map */
+            "\x04BC\x04BD",                      /* 04BC; 04BD; Case map */
+            "\x04BE\x04BF",                      /* 04BE; 04BF; Case map */
+            "\x04C1\x04C2",                      /* 04C1; 04C2; Case map */
+            "\x04C3\x04C4",                      /* 04C3; 04C4; Case map */
+            "\x04C5\x04C6",                      /* 04C5; 04C6; Case map */
+            "\x04C7\x04C8",                      /* 04C7; 04C8; Case map */
+            "\x04C9\x04CA",                      /* 04C9; 04CA; Case map */
+            "\x04CB\x04CC",                      /* 04CB; 04CC; Case map */
+            "\x04CD\x04CE",                      /* 04CD; 04CE; Case map */
+            "\x04D0\x04D1",                      /* 04D0; 04D1; Case map */
+            "\x04D2\x04D3",                      /* 04D2; 04D3; Case map */
+            "\x04D4\x04D5",                      /* 04D4; 04D5; Case map */
+            "\x04D6\x04D7",                      /* 04D6; 04D7; Case map */
+            "\x04D8\x04D9",                      /* 04D8; 04D9; Case map */
+            "\x04DA\x04DB",                      /* 04DA; 04DB; Case map */
+            "\x04DC\x04DD",                      /* 04DC; 04DD; Case map */
+            "\x04DE\x04DF",                      /* 04DE; 04DF; Case map */
+            "\x04E0\x04E1",                      /* 04E0; 04E1; Case map */
+            "\x04E2\x04E3",                      /* 04E2; 04E3; Case map */
+            "\x04E4\x04E5",                      /* 04E4; 04E5; Case map */
+            "\x04E6\x04E7",                      /* 04E6; 04E7; Case map */
+            "\x04E8\x04E9",                      /* 04E8; 04E9; Case map */
+            "\x04EA\x04EB",                      /* 04EA; 04EB; Case map */
+            "\x04EC\x04ED",                      /* 04EC; 04ED; Case map */
+            "\x04EE\x04EF",                      /* 04EE; 04EF; Case map */
+            "\x04F0\x04F1",                      /* 04F0; 04F1; Case map */
+            "\x04F2\x04F3",                      /* 04F2; 04F3; Case map */
+            "\x04F4\x04F5",                      /* 04F4; 04F5; Case map */
+            "\x04F8\x04F9",                      /* 04F8; 04F9; Case map */
+            "\x0500\x0501",                      /* 0500; 0501; Case map */
+            "\x0502\x0503",                      /* 0502; 0503; Case map */
+            "\x0504\x0505",                      /* 0504; 0505; Case map */
+            "\x0506\x0507",                      /* 0506; 0507; Case map */
+            "\x0508\x0509",                      /* 0508; 0509; Case map */
+            "\x050A\x050B",                      /* 050A; 050B; Case map */
+            "\x050C\x050D",                      /* 050C; 050D; Case map */
+            "\x050E\x050F",                      /* 050E; 050F; Case map */
+            "\x0531\x0561",                      /* 0531; 0561; Case map */
+            "\x0532\x0562",                      /* 0532; 0562; Case map */
+            "\x0533\x0563",                      /* 0533; 0563; Case map */
+            "\x0534\x0564",                      /* 0534; 0564; Case map */
+            "\x0535\x0565",                      /* 0535; 0565; Case map */
+            "\x0536\x0566",                      /* 0536; 0566; Case map */
+            "\x0537\x0567",                      /* 0537; 0567; Case map */
+            "\x0538\x0568",                      /* 0538; 0568; Case map */
+            "\x0539\x0569",                      /* 0539; 0569; Case map */
+            "\x053A\x056A",                      /* 053A; 056A; Case map */
+            "\x053B\x056B",                      /* 053B; 056B; Case map */
+            "\x053C\x056C",                      /* 053C; 056C; Case map */
+            "\x053D\x056D",                      /* 053D; 056D; Case map */
+            "\x053E\x056E",                      /* 053E; 056E; Case map */
+            "\x053F\x056F",                      /* 053F; 056F; Case map */
+            "\x0540\x0570",                      /* 0540; 0570; Case map */
+            "\x0541\x0571",                      /* 0541; 0571; Case map */
+            "\x0542\x0572",                      /* 0542; 0572; Case map */
+            "\x0543\x0573",                      /* 0543; 0573; Case map */
+            "\x0544\x0574",                      /* 0544; 0574; Case map */
+            "\x0545\x0575",                      /* 0545; 0575; Case map */
+            "\x0546\x0576",                      /* 0546; 0576; Case map */
+            "\x0547\x0577",                      /* 0547; 0577; Case map */
+            "\x0548\x0578",                      /* 0548; 0578; Case map */
+            "\x0549\x0579",                      /* 0549; 0579; Case map */
+            "\x054A\x057A",                      /* 054A; 057A; Case map */
+            "\x054B\x057B",                      /* 054B; 057B; Case map */
+            "\x054C\x057C",                      /* 054C; 057C; Case map */
+            "\x054D\x057D",                      /* 054D; 057D; Case map */
+            "\x054E\x057E",                      /* 054E; 057E; Case map */
+            "\x054F\x057F",                      /* 054F; 057F; Case map */
+            "\x0550\x0580",                      /* 0550; 0580; Case map */
+            "\x0551\x0581",                      /* 0551; 0581; Case map */
+            "\x0552\x0582",                      /* 0552; 0582; Case map */
+            "\x0553\x0583",                      /* 0553; 0583; Case map */
+            "\x0554\x0584",                      /* 0554; 0584; Case map */
+            "\x0555\x0585",                      /* 0555; 0585; Case map */
+            "\x0556\x0586",                      /* 0556; 0586; Case map */
+            "\x0587\x0565\x0582",                /* 0587; 0565 0582; Case map */
+            "\x1E00\x1E01",                      /* 1E00; 1E01; Case map */
+            "\x1E02\x1E03",                      /* 1E02; 1E03; Case map */
+            "\x1E04\x1E05",                      /* 1E04; 1E05; Case map */
+            "\x1E06\x1E07",                      /* 1E06; 1E07; Case map */
+            "\x1E08\x1E09",                      /* 1E08; 1E09; Case map */
+            "\x1E0A\x1E0B",                      /* 1E0A; 1E0B; Case map */
+            "\x1E0C\x1E0D",                      /* 1E0C; 1E0D; Case map */
+            "\x1E0E\x1E0F",                      /* 1E0E; 1E0F; Case map */
+            "\x1E10\x1E11",                      /* 1E10; 1E11; Case map */
+            "\x1E12\x1E13",                      /* 1E12; 1E13; Case map */
+            "\x1E14\x1E15",                      /* 1E14; 1E15; Case map */
+            "\x1E16\x1E17",                      /* 1E16; 1E17; Case map */
+            "\x1E18\x1E19",                      /* 1E18; 1E19; Case map */
+            "\x1E1A\x1E1B",                      /* 1E1A; 1E1B; Case map */
+            "\x1E1C\x1E1D",                      /* 1E1C; 1E1D; Case map */
+            "\x1E1E\x1E1F",                      /* 1E1E; 1E1F; Case map */
+            "\x1E20\x1E21",                      /* 1E20; 1E21; Case map */
+            "\x1E22\x1E23",                      /* 1E22; 1E23; Case map */
+            "\x1E24\x1E25",                      /* 1E24; 1E25; Case map */
+            "\x1E26\x1E27",                      /* 1E26; 1E27; Case map */
+            "\x1E28\x1E29",                      /* 1E28; 1E29; Case map */
+            "\x1E2A\x1E2B",                      /* 1E2A; 1E2B; Case map */
+            "\x1E2C\x1E2D",                      /* 1E2C; 1E2D; Case map */
+            "\x1E2E\x1E2F",                      /* 1E2E; 1E2F; Case map */
+            "\x1E30\x1E31",                      /* 1E30; 1E31; Case map */
+            "\x1E32\x1E33",                      /* 1E32; 1E33; Case map */
+            "\x1E34\x1E35",                      /* 1E34; 1E35; Case map */
+            "\x1E36\x1E37",                      /* 1E36; 1E37; Case map */
+            "\x1E38\x1E39",                      /* 1E38; 1E39; Case map */
+            "\x1E3A\x1E3B",                      /* 1E3A; 1E3B; Case map */
+            "\x1E3C\x1E3D",                      /* 1E3C; 1E3D; Case map */
+            "\x1E3E\x1E3F",                      /* 1E3E; 1E3F; Case map */
+            "\x1E40\x1E41",                      /* 1E40; 1E41; Case map */
+            "\x1E42\x1E43",                      /* 1E42; 1E43; Case map */
+            "\x1E44\x1E45",                      /* 1E44; 1E45; Case map */
+            "\x1E46\x1E47",                      /* 1E46; 1E47; Case map */
+            "\x1E48\x1E49",                      /* 1E48; 1E49; Case map */
+            "\x1E4A\x1E4B",                      /* 1E4A; 1E4B; Case map */
+            "\x1E4C\x1E4D",                      /* 1E4C; 1E4D; Case map */
+            "\x1E4E\x1E4F",                      /* 1E4E; 1E4F; Case map */
+            "\x1E50\x1E51",                      /* 1E50; 1E51; Case map */
+            "\x1E52\x1E53",                      /* 1E52; 1E53; Case map */
+            "\x1E54\x1E55",                      /* 1E54; 1E55; Case map */
+            "\x1E56\x1E57",                      /* 1E56; 1E57; Case map */
+            "\x1E58\x1E59",                      /* 1E58; 1E59; Case map */
+            "\x1E5A\x1E5B",                      /* 1E5A; 1E5B; Case map */
+            "\x1E5C\x1E5D",                      /* 1E5C; 1E5D; Case map */
+            "\x1E5E\x1E5F",                      /* 1E5E; 1E5F; Case map */
+            "\x1E60\x1E61",                      /* 1E60; 1E61; Case map */
+            "\x1E62\x1E63",                      /* 1E62; 1E63; Case map */
+            "\x1E64\x1E65",                      /* 1E64; 1E65; Case map */
+            "\x1E66\x1E67",                      /* 1E66; 1E67; Case map */
+            "\x1E68\x1E69",                      /* 1E68; 1E69; Case map */
+            "\x1E6A\x1E6B",                      /* 1E6A; 1E6B; Case map */
+            "\x1E6C\x1E6D",                      /* 1E6C; 1E6D; Case map */
+            "\x1E6E\x1E6F",                      /* 1E6E; 1E6F; Case map */
+            "\x1E70\x1E71",                      /* 1E70; 1E71; Case map */
+            "\x1E72\x1E73",                      /* 1E72; 1E73; Case map */
+            "\x1E74\x1E75",                      /* 1E74; 1E75; Case map */
+            "\x1E76\x1E77",                      /* 1E76; 1E77; Case map */
+            "\x1E78\x1E79",                      /* 1E78; 1E79; Case map */
+            "\x1E7A\x1E7B",                      /* 1E7A; 1E7B; Case map */
+            "\x1E7C\x1E7D",                      /* 1E7C; 1E7D; Case map */
+            "\x1E7E\x1E7F",                      /* 1E7E; 1E7F; Case map */
+            "\x1E80\x1E81",                      /* 1E80; 1E81; Case map */
+            "\x1E82\x1E83",                      /* 1E82; 1E83; Case map */
+            "\x1E84\x1E85",                      /* 1E84; 1E85; Case map */
+            "\x1E86\x1E87",                      /* 1E86; 1E87; Case map */
+            "\x1E88\x1E89",                      /* 1E88; 1E89; Case map */
+            "\x1E8A\x1E8B",                      /* 1E8A; 1E8B; Case map */
+            "\x1E8C\x1E8D",                      /* 1E8C; 1E8D; Case map */
+            "\x1E8E\x1E8F",                      /* 1E8E; 1E8F; Case map */
+            "\x1E90\x1E91",                      /* 1E90; 1E91; Case map */
+            "\x1E92\x1E93",                      /* 1E92; 1E93; Case map */
+            "\x1E94\x1E95",                      /* 1E94; 1E95; Case map */
+            "\x1E96\x0068\x0331",                /* 1E96; 0068 0331; Case map */
+            "\x1E97\x0074\x0308",                /* 1E97; 0074 0308; Case map */
+            "\x1E98\x0077\x030A",                /* 1E98; 0077 030A; Case map */
+            "\x1E99\x0079\x030A",                /* 1E99; 0079 030A; Case map */
+            "\x1E9A\x0061\x02BE",                /* 1E9A; 0061 02BE; Case map */
+            "\x1E9B\x1E61",                      /* 1E9B; 1E61; Case map */
+            "\x1EA0\x1EA1",                      /* 1EA0; 1EA1; Case map */
+            "\x1EA2\x1EA3",                      /* 1EA2; 1EA3; Case map */
+            "\x1EA4\x1EA5",                      /* 1EA4; 1EA5; Case map */
+            "\x1EA6\x1EA7",                      /* 1EA6; 1EA7; Case map */
+            "\x1EA8\x1EA9",                      /* 1EA8; 1EA9; Case map */
+            "\x1EAA\x1EAB",                      /* 1EAA; 1EAB; Case map */
+            "\x1EAC\x1EAD",                      /* 1EAC; 1EAD; Case map */
+            "\x1EAE\x1EAF",                      /* 1EAE; 1EAF; Case map */
+            "\x1EB0\x1EB1",                      /* 1EB0; 1EB1; Case map */
+            "\x1EB2\x1EB3",                      /* 1EB2; 1EB3; Case map */
+            "\x1EB4\x1EB5",                      /* 1EB4; 1EB5; Case map */
+            "\x1EB6\x1EB7",                      /* 1EB6; 1EB7; Case map */
+            "\x1EB8\x1EB9",                      /* 1EB8; 1EB9; Case map */
+            "\x1EBA\x1EBB",                      /* 1EBA; 1EBB; Case map */
+            "\x1EBC\x1EBD",                      /* 1EBC; 1EBD; Case map */
+            "\x1EBE\x1EBF",                      /* 1EBE; 1EBF; Case map */
+            "\x1EC0\x1EC1",                      /* 1EC0; 1EC1; Case map */
+            "\x1EC2\x1EC3",                      /* 1EC2; 1EC3; Case map */
+            "\x1EC4\x1EC5",                      /* 1EC4; 1EC5; Case map */
+            "\x1EC6\x1EC7",                      /* 1EC6; 1EC7; Case map */
+            "\x1EC8\x1EC9",                      /* 1EC8; 1EC9; Case map */
+            "\x1ECA\x1ECB",                      /* 1ECA; 1ECB; Case map */
+            "\x1ECC\x1ECD",                      /* 1ECC; 1ECD; Case map */
+            "\x1ECE\x1ECF",                      /* 1ECE; 1ECF; Case map */
+            "\x1ED0\x1ED1",                      /* 1ED0; 1ED1; Case map */
+            "\x1ED2\x1ED3",                      /* 1ED2; 1ED3; Case map */
+            "\x1ED4\x1ED5",                      /* 1ED4; 1ED5; Case map */
+            "\x1ED6\x1ED7",                      /* 1ED6; 1ED7; Case map */
+            "\x1ED8\x1ED9",                      /* 1ED8; 1ED9; Case map */
+            "\x1EDA\x1EDB",                      /* 1EDA; 1EDB; Case map */
+            "\x1EDC\x1EDD",                      /* 1EDC; 1EDD; Case map */
+            "\x1EDE\x1EDF",                      /* 1EDE; 1EDF; Case map */
+            "\x1EE0\x1EE1",                      /* 1EE0; 1EE1; Case map */
+            "\x1EE2\x1EE3",                      /* 1EE2; 1EE3; Case map */
+            "\x1EE4\x1EE5",                      /* 1EE4; 1EE5; Case map */
+            "\x1EE6\x1EE7",                      /* 1EE6; 1EE7; Case map */
+            "\x1EE8\x1EE9",                      /* 1EE8; 1EE9; Case map */
+            "\x1EEA\x1EEB",                      /* 1EEA; 1EEB; Case map */
+            "\x1EEC\x1EED",                      /* 1EEC; 1EED; Case map */
+            "\x1EEE\x1EEF",                      /* 1EEE; 1EEF; Case map */
+            "\x1EF0\x1EF1",                      /* 1EF0; 1EF1; Case map */
+            "\x1EF2\x1EF3",                      /* 1EF2; 1EF3; Case map */
+            "\x1EF4\x1EF5",                      /* 1EF4; 1EF5; Case map */
+            "\x1EF6\x1EF7",                      /* 1EF6; 1EF7; Case map */
+            "\x1EF8\x1EF9",                      /* 1EF8; 1EF9; Case map */
+            "\x1F08\x1F00",                      /* 1F08; 1F00; Case map */
+            "\x1F09\x1F01",                      /* 1F09; 1F01; Case map */
+            "\x1F0A\x1F02",                      /* 1F0A; 1F02; Case map */
+            "\x1F0B\x1F03",                      /* 1F0B; 1F03; Case map */
+            "\x1F0C\x1F04",                      /* 1F0C; 1F04; Case map */
+            "\x1F0D\x1F05",                      /* 1F0D; 1F05; Case map */
+            "\x1F0E\x1F06",                      /* 1F0E; 1F06; Case map */
+            "\x1F0F\x1F07",                      /* 1F0F; 1F07; Case map */
+            "\x1F18\x1F10",                      /* 1F18; 1F10; Case map */
+            "\x1F19\x1F11",                      /* 1F19; 1F11; Case map */
+            "\x1F1A\x1F12",                      /* 1F1A; 1F12; Case map */
+            "\x1F1B\x1F13",                      /* 1F1B; 1F13; Case map */
+            "\x1F1C\x1F14",                      /* 1F1C; 1F14; Case map */
+            "\x1F1D\x1F15",                      /* 1F1D; 1F15; Case map */
+            "\x1F28\x1F20",                      /* 1F28; 1F20; Case map */
+            "\x1F29\x1F21",                      /* 1F29; 1F21; Case map */
+            "\x1F2A\x1F22",                      /* 1F2A; 1F22; Case map */
+            "\x1F2B\x1F23",                      /* 1F2B; 1F23; Case map */
+            "\x1F2C\x1F24",                      /* 1F2C; 1F24; Case map */
+            "\x1F2D\x1F25",                      /* 1F2D; 1F25; Case map */
+            "\x1F2E\x1F26",                      /* 1F2E; 1F26; Case map */
+            "\x1F2F\x1F27",                      /* 1F2F; 1F27; Case map */
+            "\x1F38\x1F30",                      /* 1F38; 1F30; Case map */
+            "\x1F39\x1F31",                      /* 1F39; 1F31; Case map */
+            "\x1F3A\x1F32",                      /* 1F3A; 1F32; Case map */
+            "\x1F3B\x1F33",                      /* 1F3B; 1F33; Case map */
+            "\x1F3C\x1F34",                      /* 1F3C; 1F34; Case map */
+            "\x1F3D\x1F35",                      /* 1F3D; 1F35; Case map */
+            "\x1F3E\x1F36",                      /* 1F3E; 1F36; Case map */
+            "\x1F3F\x1F37",                      /* 1F3F; 1F37; Case map */
+            "\x1F48\x1F40",                      /* 1F48; 1F40; Case map */
+            "\x1F49\x1F41",                      /* 1F49; 1F41; Case map */
+            "\x1F4A\x1F42",                      /* 1F4A; 1F42; Case map */
+            "\x1F4B\x1F43",                      /* 1F4B; 1F43; Case map */
+            "\x1F4C\x1F44",                      /* 1F4C; 1F44; Case map */
+            "\x1F4D\x1F45",                      /* 1F4D; 1F45; Case map */
+            "\x1F50\x03C5\x0313",                /* 1F50; 03C5 0313; Case map */
+            "\x1F52\x03C5\x0313\x0300",          /* 1F52; 03C5 0313 0300; Case map */
+            "\x1F54\x03C5\x0313\x0301",          /* 1F54; 03C5 0313 0301; Case map */
+            "\x1F56\x03C5\x0313\x0342",          /* 1F56; 03C5 0313 0342; Case map */
+            "\x1F59\x1F51",                      /* 1F59; 1F51; Case map */
+            "\x1F5B\x1F53",                      /* 1F5B; 1F53; Case map */
+            "\x1F5D\x1F55",                      /* 1F5D; 1F55; Case map */
+            "\x1F5F\x1F57",                      /* 1F5F; 1F57; Case map */
+            "\x1F68\x1F60",                      /* 1F68; 1F60; Case map */
+            "\x1F69\x1F61",                      /* 1F69; 1F61; Case map */
+            "\x1F6A\x1F62",                      /* 1F6A; 1F62; Case map */
+            "\x1F6B\x1F63",                      /* 1F6B; 1F63; Case map */
+            "\x1F6C\x1F64",                      /* 1F6C; 1F64; Case map */
+            "\x1F6D\x1F65",                      /* 1F6D; 1F65; Case map */
+            "\x1F6E\x1F66",                      /* 1F6E; 1F66; Case map */
+            "\x1F6F\x1F67",                      /* 1F6F; 1F67; Case map */
+            "\x1F80\x1F00\x03B9",                /* 1F80; 1F00 03B9; Case map */
+            "\x1F81\x1F01\x03B9",                /* 1F81; 1F01 03B9; Case map */
+            "\x1F82\x1F02\x03B9",                /* 1F82; 1F02 03B9; Case map */
+            "\x1F83\x1F03\x03B9",                /* 1F83; 1F03 03B9; Case map */
+            "\x1F84\x1F04\x03B9",                /* 1F84; 1F04 03B9; Case map */
+            "\x1F85\x1F05\x03B9",                /* 1F85; 1F05 03B9; Case map */
+            "\x1F86\x1F06\x03B9",                /* 1F86; 1F06 03B9; Case map */
+            "\x1F87\x1F07\x03B9",                /* 1F87; 1F07 03B9; Case map */
+            "\x1F88\x1F00\x03B9",                /* 1F88; 1F00 03B9; Case map */
+            "\x1F89\x1F01\x03B9",                /* 1F89; 1F01 03B9; Case map */
+            "\x1F8A\x1F02\x03B9",                /* 1F8A; 1F02 03B9; Case map */
+            "\x1F8B\x1F03\x03B9",                /* 1F8B; 1F03 03B9; Case map */
+            "\x1F8C\x1F04\x03B9",                /* 1F8C; 1F04 03B9; Case map */
+            "\x1F8D\x1F05\x03B9",                /* 1F8D; 1F05 03B9; Case map */
+            "\x1F8E\x1F06\x03B9",                /* 1F8E; 1F06 03B9; Case map */
+            "\x1F8F\x1F07\x03B9",                /* 1F8F; 1F07 03B9; Case map */
+            "\x1F90\x1F20\x03B9",                /* 1F90; 1F20 03B9; Case map */
+            "\x1F91\x1F21\x03B9",                /* 1F91; 1F21 03B9; Case map */
+            "\x1F92\x1F22\x03B9",                /* 1F92; 1F22 03B9; Case map */
+            "\x1F93\x1F23\x03B9",                /* 1F93; 1F23 03B9; Case map */
+            "\x1F94\x1F24\x03B9",                /* 1F94; 1F24 03B9; Case map */
+            "\x1F95\x1F25\x03B9",                /* 1F95; 1F25 03B9; Case map */
+            "\x1F96\x1F26\x03B9",                /* 1F96; 1F26 03B9; Case map */
+            "\x1F97\x1F27\x03B9",                /* 1F97; 1F27 03B9; Case map */
+            "\x1F98\x1F20\x03B9",                /* 1F98; 1F20 03B9; Case map */
+            "\x1F99\x1F21\x03B9",                /* 1F99; 1F21 03B9; Case map */
+            "\x1F9A\x1F22\x03B9",                /* 1F9A; 1F22 03B9; Case map */
+            "\x1F9B\x1F23\x03B9",                /* 1F9B; 1F23 03B9; Case map */
+            "\x1F9C\x1F24\x03B9",                /* 1F9C; 1F24 03B9; Case map */
+            "\x1F9D\x1F25\x03B9",                /* 1F9D; 1F25 03B9; Case map */
+            "\x1F9E\x1F26\x03B9",                /* 1F9E; 1F26 03B9; Case map */
+            "\x1F9F\x1F27\x03B9",                /* 1F9F; 1F27 03B9; Case map */
+            "\x1FA0\x1F60\x03B9",                /* 1FA0; 1F60 03B9; Case map */
+            "\x1FA1\x1F61\x03B9",                /* 1FA1; 1F61 03B9; Case map */
+            "\x1FA2\x1F62\x03B9",                /* 1FA2; 1F62 03B9; Case map */
+            "\x1FA3\x1F63\x03B9",                /* 1FA3; 1F63 03B9; Case map */
+            "\x1FA4\x1F64\x03B9",                /* 1FA4; 1F64 03B9; Case map */
+            "\x1FA5\x1F65\x03B9",                /* 1FA5; 1F65 03B9; Case map */
+            "\x1FA6\x1F66\x03B9",                /* 1FA6; 1F66 03B9; Case map */
+            "\x1FA7\x1F67\x03B9",                /* 1FA7; 1F67 03B9; Case map */
+            "\x1FA8\x1F60\x03B9",                /* 1FA8; 1F60 03B9; Case map */
+            "\x1FA9\x1F61\x03B9",                /* 1FA9; 1F61 03B9; Case map */
+            "\x1FAA\x1F62\x03B9",                /* 1FAA; 1F62 03B9; Case map */
+            "\x1FAB\x1F63\x03B9",                /* 1FAB; 1F63 03B9; Case map */
+            "\x1FAC\x1F64\x03B9",                /* 1FAC; 1F64 03B9; Case map */
+            "\x1FAD\x1F65\x03B9",                /* 1FAD; 1F65 03B9; Case map */
+            "\x1FAE\x1F66\x03B9",                /* 1FAE; 1F66 03B9; Case map */
+            "\x1FAF\x1F67\x03B9",                /* 1FAF; 1F67 03B9; Case map */
+            "\x1FB2\x1F70\x03B9",                /* 1FB2; 1F70 03B9; Case map */
+            "\x1FB3\x03B1\x03B9",                /* 1FB3; 03B1 03B9; Case map */
+            "\x1FB4\x03AC\x03B9",                /* 1FB4; 03AC 03B9; Case map */
+            "\x1FB6\x03B1\x0342",                /* 1FB6; 03B1 0342; Case map */
+            "\x1FB7\x03B1\x0342\x03B9",          /* 1FB7; 03B1 0342 03B9; Case map */
+            "\x1FB8\x1FB0",                      /* 1FB8; 1FB0; Case map */
+            "\x1FB9\x1FB1",                      /* 1FB9; 1FB1; Case map */
+            "\x1FBA\x1F70",                      /* 1FBA; 1F70; Case map */
+            "\x1FBB\x1F71",                      /* 1FBB; 1F71; Case map */
+            "\x1FBC\x03B1\x03B9",                /* 1FBC; 03B1 03B9; Case map */
+            "\x1FBE\x03B9",                      /* 1FBE; 03B9; Case map */
+            "\x1FC2\x1F74\x03B9",                /* 1FC2; 1F74 03B9; Case map */
+            "\x1FC3\x03B7\x03B9",                /* 1FC3; 03B7 03B9; Case map */
+            "\x1FC4\x03AE\x03B9",                /* 1FC4; 03AE 03B9; Case map */
+            "\x1FC6\x03B7\x0342",                /* 1FC6; 03B7 0342; Case map */
+            "\x1FC7\x03B7\x0342\x03B9",          /* 1FC7; 03B7 0342 03B9; Case map */
+            "\x1FC8\x1F72",                      /* 1FC8; 1F72; Case map */
+            "\x1FC9\x1F73",                      /* 1FC9; 1F73; Case map */
+            "\x1FCA\x1F74",                      /* 1FCA; 1F74; Case map */
+            "\x1FCB\x1F75",                      /* 1FCB; 1F75; Case map */
+            "\x1FCC\x03B7\x03B9",                /* 1FCC; 03B7 03B9; Case map */
+            "\x1FD2\x03B9\x0308\x0300",          /* 1FD2; 03B9 0308 0300; Case map */
+            "\x1FD3\x03B9\x0308\x0301",          /* 1FD3; 03B9 0308 0301; Case map */
+            "\x1FD6\x03B9\x0342",                /* 1FD6; 03B9 0342; Case map */
+            "\x1FD7\x03B9\x0308\x0342",          /* 1FD7; 03B9 0308 0342; Case map */
+            "\x1FD8\x1FD0",                      /* 1FD8; 1FD0; Case map */
+            "\x1FD9\x1FD1",                      /* 1FD9; 1FD1; Case map */
+            "\x1FDA\x1F76",                      /* 1FDA; 1F76; Case map */
+            "\x1FDB\x1F77",                      /* 1FDB; 1F77; Case map */
+            "\x1FE2\x03C5\x0308\x0300",          /* 1FE2; 03C5 0308 0300; Case map */
+            "\x1FE3\x03C5\x0308\x0301",          /* 1FE3; 03C5 0308 0301; Case map */
+            "\x1FE4\x03C1\x0313",                /* 1FE4; 03C1 0313; Case map */
+            "\x1FE6\x03C5\x0342",                /* 1FE6; 03C5 0342; Case map */
+            "\x1FE7\x03C5\x0308\x0342",          /* 1FE7; 03C5 0308 0342; Case map */
+            "\x1FE8\x1FE0",                      /* 1FE8; 1FE0; Case map */
+            "\x1FE9\x1FE1",                      /* 1FE9; 1FE1; Case map */
+            "\x1FEA\x1F7A",                      /* 1FEA; 1F7A; Case map */
+            "\x1FEB\x1F7B",                      /* 1FEB; 1F7B; Case map */
+            "\x1FEC\x1FE5",                      /* 1FEC; 1FE5; Case map */
+            "\x1FF2\x1F7C\x03B9",                /* 1FF2; 1F7C 03B9; Case map */
+            "\x1FF3\x03C9\x03B9",                /* 1FF3; 03C9 03B9; Case map */
+            "\x1FF4\x03CE\x03B9",                /* 1FF4; 03CE 03B9; Case map */
+            "\x1FF6\x03C9\x0342",                /* 1FF6; 03C9 0342; Case map */
+            "\x1FF7\x03C9\x0342\x03B9",          /* 1FF7; 03C9 0342 03B9; Case map */
+            "\x1FF8\x1F78",                      /* 1FF8; 1F78; Case map */
+            "\x1FF9\x1F79",                      /* 1FF9; 1F79; Case map */
+            "\x1FFA\x1F7C",                      /* 1FFA; 1F7C; Case map */
+            "\x1FFB\x1F7D",                      /* 1FFB; 1F7D; Case map */
+            "\x1FFC\x03C9\x03B9",                /* 1FFC; 03C9 03B9; Case map */
+            "\x2126\x03C9",                      /* 2126; 03C9; Case map */
+            "\x212A\x006B",                      /* 212A; 006B; Case map */
+            "\x212B\x00E5",                      /* 212B; 00E5; Case map */
+            "\x2160\x2170",                      /* 2160; 2170; Case map */
+            "\x2161\x2171",                      /* 2161; 2171; Case map */
+            "\x2162\x2172",                      /* 2162; 2172; Case map */
+            "\x2163\x2173",                      /* 2163; 2173; Case map */
+            "\x2164\x2174",                      /* 2164; 2174; Case map */
+            "\x2165\x2175",                      /* 2165; 2175; Case map */
+            "\x2166\x2176",                      /* 2166; 2176; Case map */
+            "\x2167\x2177",                      /* 2167; 2177; Case map */
+            "\x2168\x2178",                      /* 2168; 2178; Case map */
+            "\x2169\x2179",                      /* 2169; 2179; Case map */
+            "\x216A\x217A",                      /* 216A; 217A; Case map */
+            "\x216B\x217B",                      /* 216B; 217B; Case map */
+            "\x216C\x217C",                      /* 216C; 217C; Case map */
+            "\x216D\x217D",                      /* 216D; 217D; Case map */
+            "\x216E\x217E",                      /* 216E; 217E; Case map */
+            "\x216F\x217F",                      /* 216F; 217F; Case map */
+            "\x24B6\x24D0",                      /* 24B6; 24D0; Case map */
+            "\x24B7\x24D1",                      /* 24B7; 24D1; Case map */
+            "\x24B8\x24D2",                      /* 24B8; 24D2; Case map */
+            "\x24B9\x24D3",                      /* 24B9; 24D3; Case map */
+            "\x24BA\x24D4",                      /* 24BA; 24D4; Case map */
+            "\x24BB\x24D5",                      /* 24BB; 24D5; Case map */
+            "\x24BC\x24D6",                      /* 24BC; 24D6; Case map */
+            "\x24BD\x24D7",                      /* 24BD; 24D7; Case map */
+            "\x24BE\x24D8",                      /* 24BE; 24D8; Case map */
+            "\x24BF\x24D9",                      /* 24BF; 24D9; Case map */
+            "\x24C0\x24DA",                      /* 24C0; 24DA; Case map */
+            "\x24C1\x24DB",                      /* 24C1; 24DB; Case map */
+            "\x24C2\x24DC",                      /* 24C2; 24DC; Case map */
+            "\x24C3\x24DD",                      /* 24C3; 24DD; Case map */
+            "\x24C4\x24DE",                      /* 24C4; 24DE; Case map */
+            "\x24C5\x24DF",                      /* 24C5; 24DF; Case map */
+            "\x24C6\x24E0",                      /* 24C6; 24E0; Case map */
+            "\x24C7\x24E1",                      /* 24C7; 24E1; Case map */
+            "\x24C8\x24E2",                      /* 24C8; 24E2; Case map */
+            "\x24C9\x24E3",                      /* 24C9; 24E3; Case map */
+            "\x24CA\x24E4",                      /* 24CA; 24E4; Case map */
+            "\x24CB\x24E5",                      /* 24CB; 24E5; Case map */
+            "\x24CC\x24E6",                      /* 24CC; 24E6; Case map */
+            "\x24CD\x24E7",                      /* 24CD; 24E7; Case map */
+            "\x24CE\x24E8",                      /* 24CE; 24E8; Case map */
+            "\x24CF\x24E9",                      /* 24CF; 24E9; Case map */
+            "\xFB00\x0066\x0066",                /* FB00; 0066 0066; Case map */
+            "\xFB01\x0066\x0069",                /* FB01; 0066 0069; Case map */
+            "\xFB02\x0066\x006C",                /* FB02; 0066 006C; Case map */
+            "\xFB03\x0066\x0066\x0069",          /* FB03; 0066 0066 0069; Case map */
+            "\xFB04\x0066\x0066\x006C",          /* FB04; 0066 0066 006C; Case map */
+            "\xFB05\x0073\x0074",                /* FB05; 0073 0074; Case map */
+            "\xFB06\x0073\x0074",                /* FB06; 0073 0074; Case map */
+            "\xFB13\x0574\x0576",                /* FB13; 0574 0576; Case map */
+            "\xFB14\x0574\x0565",                /* FB14; 0574 0565; Case map */
+            "\xFB15\x0574\x056B",                /* FB15; 0574 056B; Case map */
+            "\xFB16\x057E\x0576",                /* FB16; 057E 0576; Case map */
+            "\xFB17\x0574\x056D",                /* FB17; 0574 056D; Case map */
+            "\xFF21\xFF41",                      /* FF21; FF41; Case map */
+            "\xFF22\xFF42",                      /* FF22; FF42; Case map */
+            "\xFF23\xFF43",                      /* FF23; FF43; Case map */
+            "\xFF24\xFF44",                      /* FF24; FF44; Case map */
+            "\xFF25\xFF45",                      /* FF25; FF45; Case map */
+            "\xFF26\xFF46",                      /* FF26; FF46; Case map */
+            "\xFF27\xFF47",                      /* FF27; FF47; Case map */
+            "\xFF28\xFF48",                      /* FF28; FF48; Case map */
+            "\xFF29\xFF49",                      /* FF29; FF49; Case map */
+            "\xFF2A\xFF4A",                      /* FF2A; FF4A; Case map */
+            "\xFF2B\xFF4B",                      /* FF2B; FF4B; Case map */
+            "\xFF2C\xFF4C",                      /* FF2C; FF4C; Case map */
+            "\xFF2D\xFF4D",                      /* FF2D; FF4D; Case map */
+            "\xFF2E\xFF4E",                      /* FF2E; FF4E; Case map */
+            "\xFF2F\xFF4F",                      /* FF2F; FF4F; Case map */
+            "\xFF30\xFF50",                      /* FF30; FF50; Case map */
+            "\xFF31\xFF51",                      /* FF31; FF51; Case map */
+            "\xFF32\xFF52",                      /* FF32; FF52; Case map */
+            "\xFF33\xFF53",                      /* FF33; FF53; Case map */
+            "\xFF34\xFF54",                      /* FF34; FF54; Case map */
+            "\xFF35\xFF55",                      /* FF35; FF55; Case map */
+            "\xFF36\xFF56",                      /* FF36; FF56; Case map */
+            "\xFF37\xFF57",                      /* FF37; FF57; Case map */
+            "\xFF38\xFF58",                      /* FF38; FF58; Case map */
+            "\xFF39\xFF59",                      /* FF39; FF59; Case map */
+            "\xFF3A\xFF5A",                      /* FF3A; FF5A; Case map */
+        };
+
+
+        /// <summary>
+        /// C.1.1 ASCII space characters
+        ///
+        /// </summary>
+        public static readonly char[][] C_1_1 = new char[][]
+        {
+            new char[] {'\x0020', '\x0000'},   /* 0020; SPACE */
+        };
+
+
+        /// <summary>
+        /// C.1.2 Non-ASCII space characters
+        ///         /// </summary>
+        public static readonly char[][] C_1_2 = new char[][]
+        {
+            new char[] {'\x00A0', '\x0000'},            /* 00A0; NO-BREAK SPACE */
+            new char[] {'\x1680', '\x0000'},              /* 1680; OGHAM SPACE MARK */
+            new char[] {'\x2000', '\x0000'},     /* 2000; EN QUAD */
+            new char[] {'\x2001', '\x0000'},     /* 2001; EM QUAD */
+            new char[] {'\x2002', '\x0000'},      /* 2002; EN SPACE */
+            new char[] {'\x2003', '\x0000'},      /* 2003; EM SPACE */
+            new char[] {'\x2004', '\x0000'},                /* 2004; THREE-PER-EM SPACE */
+            new char[] {'\x2005', '\x0000'},               /* 2005; FOUR-PER-EM SPACE */
+            new char[] {'\x2006', '\x0000'},              /* 2006; SIX-PER-EM SPACE */
+            new char[] {'\x2007', '\x0000'},          /* 2007; FIGURE SPACE */
+            new char[] {'\x2008', '\x0000'},               /* 2008; PUNCTUATION SPACE */
+            new char[] {'\x2009', '\x0000'},        /* 2009; THIN SPACE */
+            new char[] {'\x200A', '\x0000'},        /* 200A; HAIR SPACE */
+            new char[] {'\x200B', '\x0000'},              /* 200B; ZERO WIDTH SPACE */
+            new char[] {'\x202F', '\x0000'},                   /* 202F; NARROW NO-BREAK SPACE */
+            new char[] {'\x205F', '\x0000'},                       /* 205F; MEDIUM MATHEMATICAL SPACE */
+            new char[] {'\x3000', '\x0000'},               /* 3000; IDEOGRAPHIC SPACE */
+        };
+
+
+        /// <summary>
+        /// C.2.1 ASCII control characters
+        ///
+        /// </summary>
+        public static readonly char[][] C_2_1 = new char[][]
+        {
+            new char[] {'\x0000', '\x001F'},                  /* 0000-001F; [CONTROL CHARACTERS] */
+            new char[] {'\x007F', '\x0000'},    /* 007F; DELETE */
+        };
+
+
+        /// <summary>
+        /// C.2.2 Non-ASCII control characters
+        ///
+        /// </summary>
+        public static readonly char[][] C_2_2 = new char[][]
+        {
+            new char[] {'\x0080', '\x009F'},                  /* 0080-009F; [CONTROL CHARACTERS] */
+            new char[] {'\x06DD', '\x0000'},                /* 06DD; ARABIC END OF AYAH */
+            new char[] {'\x070F', '\x0000'},                      /* 070F; SYRIAC ABBREVIATION MARK */
+            new char[] {'\x180E', '\x0000'},                       /* 180E; MONGOLIAN VOWEL SEPARATOR */
+            new char[] {'\x200C', '\x0000'},                   /* 200C; ZERO WIDTH NON-JOINER */
+            new char[] {'\x200D', '\x0000'},               /* 200D; ZERO WIDTH JOINER */
+            new char[] {'\x2028', '\x0000'},            /* 2028; LINE SEPARATOR */
+            new char[] {'\x2029', '\x0000'},                 /* 2029; PARAGRAPH SEPARATOR */
+            new char[] {'\x2060', '\x0000'},         /* 2060; WORD JOINER */
+            new char[] {'\x2061', '\x0000'},                  /* 2061; FUNCTION APPLICATION */
+            new char[] {'\x2062', '\x0000'},             /* 2062; INVISIBLE TIMES */
+            new char[] {'\x2063', '\x0000'},                 /* 2063; INVISIBLE SEPARATOR */
+            new char[] {'\x206A', '\x206F'},                  /* 206A-206F; [CONTROL CHARACTERS] */
+            new char[] {'\xFEFF', '\x0000'},                       /* FEFF; ZERO WIDTH NO-BREAK SPACE */
+            new char[] {'\xFFF9', '\xFFFC'},                  /* FFF9-FFFC; [CONTROL CHARACTERS] */
+        };
+
+
+        /// <summary>
+        /// C.3 Private use
+        ///
+        /// </summary>
+        public static readonly char[][] C_3 = new char[][]
+        {
+            new char[] {'\xE000', '\xF8FF'},                    /* E000-F8FF; [PRIVATE USE, PLANE 0] */
+        };
+
+
+        /// <summary>
+        /// C.4 Non-character code points
+        ///
+        /// </summary>
+        public static readonly char[][] C_4 = new char[][]
+        {
+            new char[] {'\xFDD0', '\xFDEF'},                        /* FDD0-FDEF; [NONCHARACTER CODE POINTS] */
+            new char[] {'\xFFFE', '\xFFFF'},                        /* FFFE-FFFF; [NONCHARACTER CODE POINTS] */
+        };
+
+
+        /// <summary>
+        /// C.5 Surrogate codes
+        ///
+        /// </summary>
+        public static readonly char[][] C_5 = new char[][]
+        {
+            new char[] {'\xD800', '\xDFFF'},               /* D800-DFFF; [SURROGATE CODES] */
+        };
+
+
+        /// <summary>
+        /// C.6 Inappropriate for plain text
+        ///
+        /// </summary>
+        public static readonly char[][] C_6 = new char[][]
+        {
+            new char[] {'\xFFF9', '\x0000'},                           /* FFF9; INTERLINEAR ANNOTATION ANCHOR */
+            new char[] {'\xFFFA', '\x0000'},                              /* FFFA; INTERLINEAR ANNOTATION SEPARATOR */
+            new char[] {'\xFFFB', '\x0000'},                               /* FFFB; INTERLINEAR ANNOTATION TERMINATOR */
+            new char[] {'\xFFFC', '\x0000'},                          /* FFFC; OBJECT REPLACEMENT CHARACTER */
+            new char[] {'\xFFFD', '\x0000'},                   /* FFFD; REPLACEMENT CHARACTER */
+        };
+
+
+        /// <summary>
+        /// C.7 Inappropriate for canonical representation
+        ///
+        /// </summary>
+        public static readonly char[][] C_7 = new char[][]
+        {
+            new char[] {'\x2FF0', '\x2FFB'},                                  /* 2FF0-2FFB; [IDEOGRAPHIC DESCRIPTION CHARACTERS] */
+        };
+
+
+        /// <summary>
+        /// C.8 Change display properties or are deprecated
+        ///
+        /// </summary>
+        public static readonly char[][] C_8 = new char[][]
+        {
+            new char[] {'\x0340', '\x0000'},                       /* 0340; COMBINING GRAVE TONE MARK */
+            new char[] {'\x0341', '\x0000'},                       /* 0341; COMBINING ACUTE TONE MARK */
+            new char[] {'\x200E', '\x0000'},                /* 200E; LEFT-TO-RIGHT MARK */
+            new char[] {'\x200F', '\x0000'},                /* 200F; RIGHT-TO-LEFT MARK */
+            new char[] {'\x202A', '\x0000'},                     /* 202A; LEFT-TO-RIGHT EMBEDDING */
+            new char[] {'\x202B', '\x0000'},                     /* 202B; RIGHT-TO-LEFT EMBEDDING */
+            new char[] {'\x202C', '\x0000'},                        /* 202C; POP DIRECTIONAL FORMATTING */
+            new char[] {'\x202D', '\x0000'},                    /* 202D; LEFT-TO-RIGHT OVERRIDE */
+            new char[] {'\x202E', '\x0000'},                    /* 202E; RIGHT-TO-LEFT OVERRIDE */
+            new char[] {'\x206A', '\x0000'},                        /* 206A; INHIBIT SYMMETRIC SWAPPING */
+            new char[] {'\x206B', '\x0000'},                         /* 206B; ACTIVATE SYMMETRIC SWAPPING */
+            new char[] {'\x206C', '\x0000'},                         /* 206C; INHIBIT ARABIC FORM SHAPING */
+            new char[] {'\x206D', '\x0000'},                          /* 206D; ACTIVATE ARABIC FORM SHAPING */
+            new char[] {'\x206E', '\x0000'},                   /* 206E; NATIONAL DIGIT SHAPES */
+            new char[] {'\x206F', '\x0000'},                  /* 206F; NOMINAL DIGIT SHAPES */
+        };
+
+
+        /// <summary>
+        /// C.9 Tagging characters
+        ///
+        /// </summary>
+        public static readonly char[][] C_9 = new char[][]
+        {
+        };
+
+
+        /// <summary>
+        /// D.1 Characters with bidirectional property "R" or "AL"
+        ///
+        /// </summary>
+        public static readonly char[][] D_1 = new char[][]
+        {
+            new char[] {'\x05BE', '\x0000'},    /* 05BE */
+            new char[] {'\x05C0', '\x0000'},    /* 05C0 */
+            new char[] {'\x05C3', '\x0000'},    /* 05C3 */
+            new char[] {'\x05D0', '\x05EA'},    /* 05D0-05EA */
+            new char[] {'\x05F0', '\x05F4'},    /* 05F0-05F4 */
+            new char[] {'\x061B', '\x0000'},    /* 061B */
+            new char[] {'\x061F', '\x0000'},    /* 061F */
+            new char[] {'\x0621', '\x063A'},    /* 0621-063A */
+            new char[] {'\x0640', '\x064A'},    /* 0640-064A */
+            new char[] {'\x066D', '\x066F'},    /* 066D-066F */
+            new char[] {'\x0671', '\x06D5'},    /* 0671-06D5 */
+            new char[] {'\x06DD', '\x0000'},    /* 06DD */
+            new char[] {'\x06E5', '\x06E6'},    /* 06E5-06E6 */
+            new char[] {'\x06FA', '\x06FE'},    /* 06FA-06FE */
+            new char[] {'\x0700', '\x070D'},    /* 0700-070D */
+            new char[] {'\x0710', '\x0000'},    /* 0710 */
+            new char[] {'\x0712', '\x072C'},    /* 0712-072C */
+            new char[] {'\x0780', '\x07A5'},    /* 0780-07A5 */
+            new char[] {'\x07B1', '\x0000'},    /* 07B1 */
+            new char[] {'\x200F', '\x0000'},    /* 200F */
+            new char[] {'\xFB1D', '\x0000'},    /* FB1D */
+            new char[] {'\xFB1F', '\xFB28'},    /* FB1F-FB28 */
+            new char[] {'\xFB2A', '\xFB36'},    /* FB2A-FB36 */
+            new char[] {'\xFB38', '\xFB3C'},    /* FB38-FB3C */
+            new char[] {'\xFB3E', '\x0000'},    /* FB3E */
+            new char[] {'\xFB40', '\xFB41'},    /* FB40-FB41 */
+            new char[] {'\xFB43', '\xFB44'},    /* FB43-FB44 */
+            new char[] {'\xFB46', '\xFBB1'},    /* FB46-FBB1 */
+            new char[] {'\xFBD3', '\xFD3D'},    /* FBD3-FD3D */
+            new char[] {'\xFD50', '\xFD8F'},    /* FD50-FD8F */
+            new char[] {'\xFD92', '\xFDC7'},    /* FD92-FDC7 */
+            new char[] {'\xFDF0', '\xFDFC'},    /* FDF0-FDFC */
+            new char[] {'\xFE70', '\xFE74'},    /* FE70-FE74 */
+            new char[] {'\xFE76', '\xFEFC'},    /* FE76-FEFC */
+        };
+
+
+        /// <summary>
+        /// D.2 Characters with bidirectional property "L"
+        ///
+        /// </summary>
+        public static readonly char[][] D_2 = new char[][]
+        {
+            new char[] {'\x0041', '\x005A'},    /* 0041-005A */
+            new char[] {'\x0061', '\x007A'},    /* 0061-007A */
+            new char[] {'\x00AA', '\x0000'},    /* 00AA */
+            new char[] {'\x00B5', '\x0000'},    /* 00B5 */
+            new char[] {'\x00BA', '\x0000'},    /* 00BA */
+            new char[] {'\x00C0', '\x00D6'},    /* 00C0-00D6 */
+            new char[] {'\x00D8', '\x00F6'},    /* 00D8-00F6 */
+            new char[] {'\x00F8', '\x0220'},    /* 00F8-0220 */
+            new char[] {'\x0222', '\x0233'},    /* 0222-0233 */
+            new char[] {'\x0250', '\x02AD'},    /* 0250-02AD */
+            new char[] {'\x02B0', '\x02B8'},    /* 02B0-02B8 */
+            new char[] {'\x02BB', '\x02C1'},    /* 02BB-02C1 */
+            new char[] {'\x02D0', '\x02D1'},    /* 02D0-02D1 */
+            new char[] {'\x02E0', '\x02E4'},    /* 02E0-02E4 */
+            new char[] {'\x02EE', '\x0000'},    /* 02EE */
+            new char[] {'\x037A', '\x0000'},    /* 037A */
+            new char[] {'\x0386', '\x0000'},    /* 0386 */
+            new char[] {'\x0388', '\x038A'},    /* 0388-038A */
+            new char[] {'\x038C', '\x0000'},    /* 038C */
+            new char[] {'\x038E', '\x03A1'},    /* 038E-03A1 */
+            new char[] {'\x03A3', '\x03CE'},    /* 03A3-03CE */
+            new char[] {'\x03D0', '\x03F5'},    /* 03D0-03F5 */
+            new char[] {'\x0400', '\x0482'},    /* 0400-0482 */
+            new char[] {'\x048A', '\x04CE'},    /* 048A-04CE */
+            new char[] {'\x04D0', '\x04F5'},    /* 04D0-04F5 */
+            new char[] {'\x04F8', '\x04F9'},    /* 04F8-04F9 */
+            new char[] {'\x0500', '\x050F'},    /* 0500-050F */
+            new char[] {'\x0531', '\x0556'},    /* 0531-0556 */
+            new char[] {'\x0559', '\x055F'},    /* 0559-055F */
+            new char[] {'\x0561', '\x0587'},    /* 0561-0587 */
+            new char[] {'\x0589', '\x0000'},    /* 0589 */
+            new char[] {'\x0903', '\x0000'},    /* 0903 */
+            new char[] {'\x0905', '\x0939'},    /* 0905-0939 */
+            new char[] {'\x093D', '\x0940'},    /* 093D-0940 */
+            new char[] {'\x0949', '\x094C'},    /* 0949-094C */
+            new char[] {'\x0950', '\x0000'},    /* 0950 */
+            new char[] {'\x0958', '\x0961'},    /* 0958-0961 */
+            new char[] {'\x0964', '\x0970'},    /* 0964-0970 */
+            new char[] {'\x0982', '\x0983'},    /* 0982-0983 */
+            new char[] {'\x0985', '\x098C'},    /* 0985-098C */
+            new char[] {'\x098F', '\x0990'},    /* 098F-0990 */
+            new char[] {'\x0993', '\x09A8'},    /* 0993-09A8 */
+            new char[] {'\x09AA', '\x09B0'},    /* 09AA-09B0 */
+            new char[] {'\x09B2', '\x0000'},    /* 09B2 */
+            new char[] {'\x09B6', '\x09B9'},    /* 09B6-09B9 */
+            new char[] {'\x09BE', '\x09C0'},    /* 09BE-09C0 */
+            new char[] {'\x09C7', '\x09C8'},    /* 09C7-09C8 */
+            new char[] {'\x09CB', '\x09CC'},    /* 09CB-09CC */
+            new char[] {'\x09D7', '\x0000'},    /* 09D7 */
+            new char[] {'\x09DC', '\x09DD'},    /* 09DC-09DD */
+            new char[] {'\x09DF', '\x09E1'},    /* 09DF-09E1 */
+            new char[] {'\x09E6', '\x09F1'},    /* 09E6-09F1 */
+            new char[] {'\x09F4', '\x09FA'},    /* 09F4-09FA */
+            new char[] {'\x0A05', '\x0A0A'},    /* 0A05-0A0A */
+            new char[] {'\x0A0F', '\x0A10'},    /* 0A0F-0A10 */
+            new char[] {'\x0A13', '\x0A28'},    /* 0A13-0A28 */
+            new char[] {'\x0A2A', '\x0A30'},    /* 0A2A-0A30 */
+            new char[] {'\x0A32', '\x0A33'},    /* 0A32-0A33 */
+            new char[] {'\x0A35', '\x0A36'},    /* 0A35-0A36 */
+            new char[] {'\x0A38', '\x0A39'},    /* 0A38-0A39 */
+            new char[] {'\x0A3E', '\x0A40'},    /* 0A3E-0A40 */
+            new char[] {'\x0A59', '\x0A5C'},    /* 0A59-0A5C */
+            new char[] {'\x0A5E', '\x0000'},    /* 0A5E */
+            new char[] {'\x0A66', '\x0A6F'},    /* 0A66-0A6F */
+            new char[] {'\x0A72', '\x0A74'},    /* 0A72-0A74 */
+            new char[] {'\x0A83', '\x0000'},    /* 0A83 */
+            new char[] {'\x0A85', '\x0A8B'},    /* 0A85-0A8B */
+            new char[] {'\x0A8D', '\x0000'},    /* 0A8D */
+            new char[] {'\x0A8F', '\x0A91'},    /* 0A8F-0A91 */
+            new char[] {'\x0A93', '\x0AA8'},    /* 0A93-0AA8 */
+            new char[] {'\x0AAA', '\x0AB0'},    /* 0AAA-0AB0 */
+            new char[] {'\x0AB2', '\x0AB3'},    /* 0AB2-0AB3 */
+            new char[] {'\x0AB5', '\x0AB9'},    /* 0AB5-0AB9 */
+            new char[] {'\x0ABD', '\x0AC0'},    /* 0ABD-0AC0 */
+            new char[] {'\x0AC9', '\x0000'},    /* 0AC9 */
+            new char[] {'\x0ACB', '\x0ACC'},    /* 0ACB-0ACC */
+            new char[] {'\x0AD0', '\x0000'},    /* 0AD0 */
+            new char[] {'\x0AE0', '\x0000'},    /* 0AE0 */
+            new char[] {'\x0AE6', '\x0AEF'},    /* 0AE6-0AEF */
+            new char[] {'\x0B02', '\x0B03'},    /* 0B02-0B03 */
+            new char[] {'\x0B05', '\x0B0C'},    /* 0B05-0B0C */
+            new char[] {'\x0B0F', '\x0B10'},    /* 0B0F-0B10 */
+            new char[] {'\x0B13', '\x0B28'},    /* 0B13-0B28 */
+            new char[] {'\x0B2A', '\x0B30'},    /* 0B2A-0B30 */
+            new char[] {'\x0B32', '\x0B33'},    /* 0B32-0B33 */
+            new char[] {'\x0B36', '\x0B39'},    /* 0B36-0B39 */
+            new char[] {'\x0B3D', '\x0B3E'},    /* 0B3D-0B3E */
+            new char[] {'\x0B40', '\x0000'},    /* 0B40 */
+            new char[] {'\x0B47', '\x0B48'},    /* 0B47-0B48 */
+            new char[] {'\x0B4B', '\x0B4C'},    /* 0B4B-0B4C */
+            new char[] {'\x0B57', '\x0000'},    /* 0B57 */
+            new char[] {'\x0B5C', '\x0B5D'},    /* 0B5C-0B5D */
+            new char[] {'\x0B5F', '\x0B61'},    /* 0B5F-0B61 */
+            new char[] {'\x0B66', '\x0B70'},    /* 0B66-0B70 */
+            new char[] {'\x0B83', '\x0000'},    /* 0B83 */
+            new char[] {'\x0B85', '\x0B8A'},    /* 0B85-0B8A */
+            new char[] {'\x0B8E', '\x0B90'},    /* 0B8E-0B90 */
+            new char[] {'\x0B92', '\x0B95'},    /* 0B92-0B95 */
+            new char[] {'\x0B99', '\x0B9A'},    /* 0B99-0B9A */
+            new char[] {'\x0B9C', '\x0000'},    /* 0B9C */
+            new char[] {'\x0B9E', '\x0B9F'},    /* 0B9E-0B9F */
+            new char[] {'\x0BA3', '\x0BA4'},    /* 0BA3-0BA4 */
+            new char[] {'\x0BA8', '\x0BAA'},    /* 0BA8-0BAA */
+            new char[] {'\x0BAE', '\x0BB5'},    /* 0BAE-0BB5 */
+            new char[] {'\x0BB7', '\x0BB9'},    /* 0BB7-0BB9 */
+            new char[] {'\x0BBE', '\x0BBF'},    /* 0BBE-0BBF */
+            new char[] {'\x0BC1', '\x0BC2'},    /* 0BC1-0BC2 */
+            new char[] {'\x0BC6', '\x0BC8'},    /* 0BC6-0BC8 */
+            new char[] {'\x0BCA', '\x0BCC'},    /* 0BCA-0BCC */
+            new char[] {'\x0BD7', '\x0000'},    /* 0BD7 */
+            new char[] {'\x0BE7', '\x0BF2'},    /* 0BE7-0BF2 */
+            new char[] {'\x0C01', '\x0C03'},    /* 0C01-0C03 */
+            new char[] {'\x0C05', '\x0C0C'},    /* 0C05-0C0C */
+            new char[] {'\x0C0E', '\x0C10'},    /* 0C0E-0C10 */
+            new char[] {'\x0C12', '\x0C28'},    /* 0C12-0C28 */
+            new char[] {'\x0C2A', '\x0C33'},    /* 0C2A-0C33 */
+            new char[] {'\x0C35', '\x0C39'},    /* 0C35-0C39 */
+            new char[] {'\x0C41', '\x0C44'},    /* 0C41-0C44 */
+            new char[] {'\x0C60', '\x0C61'},    /* 0C60-0C61 */
+            new char[] {'\x0C66', '\x0C6F'},    /* 0C66-0C6F */
+            new char[] {'\x0C82', '\x0C83'},    /* 0C82-0C83 */
+            new char[] {'\x0C85', '\x0C8C'},    /* 0C85-0C8C */
+            new char[] {'\x0C8E', '\x0C90'},    /* 0C8E-0C90 */
+            new char[] {'\x0C92', '\x0CA8'},    /* 0C92-0CA8 */
+            new char[] {'\x0CAA', '\x0CB3'},    /* 0CAA-0CB3 */
+            new char[] {'\x0CB5', '\x0CB9'},    /* 0CB5-0CB9 */
+            new char[] {'\x0CBE', '\x0000'},    /* 0CBE */
+            new char[] {'\x0CC0', '\x0CC4'},    /* 0CC0-0CC4 */
+            new char[] {'\x0CC7', '\x0CC8'},    /* 0CC7-0CC8 */
+            new char[] {'\x0CCA', '\x0CCB'},    /* 0CCA-0CCB */
+            new char[] {'\x0CD5', '\x0CD6'},    /* 0CD5-0CD6 */
+            new char[] {'\x0CDE', '\x0000'},    /* 0CDE */
+            new char[] {'\x0CE0', '\x0CE1'},    /* 0CE0-0CE1 */
+            new char[] {'\x0CE6', '\x0CEF'},    /* 0CE6-0CEF */
+            new char[] {'\x0D02', '\x0D03'},    /* 0D02-0D03 */
+            new char[] {'\x0D05', '\x0D0C'},    /* 0D05-0D0C */
+            new char[] {'\x0D0E', '\x0D10'},    /* 0D0E-0D10 */
+            new char[] {'\x0D12', '\x0D28'},    /* 0D12-0D28 */
+            new char[] {'\x0D2A', '\x0D39'},    /* 0D2A-0D39 */
+            new char[] {'\x0D3E', '\x0D40'},    /* 0D3E-0D40 */
+            new char[] {'\x0D46', '\x0D48'},    /* 0D46-0D48 */
+            new char[] {'\x0D4A', '\x0D4C'},    /* 0D4A-0D4C */
+            new char[] {'\x0D57', '\x0000'},    /* 0D57 */
+            new char[] {'\x0D60', '\x0D61'},    /* 0D60-0D61 */
+            new char[] {'\x0D66', '\x0D6F'},    /* 0D66-0D6F */
+            new char[] {'\x0D82', '\x0D83'},    /* 0D82-0D83 */
+            new char[] {'\x0D85', '\x0D96'},    /* 0D85-0D96 */
+            new char[] {'\x0D9A', '\x0DB1'},    /* 0D9A-0DB1 */
+            new char[] {'\x0DB3', '\x0DBB'},    /* 0DB3-0DBB */
+            new char[] {'\x0DBD', '\x0000'},    /* 0DBD */
+            new char[] {'\x0DC0', '\x0DC6'},    /* 0DC0-0DC6 */
+            new char[] {'\x0DCF', '\x0DD1'},    /* 0DCF-0DD1 */
+            new char[] {'\x0DD8', '\x0DDF'},    /* 0DD8-0DDF */
+            new char[] {'\x0DF2', '\x0DF4'},    /* 0DF2-0DF4 */
+            new char[] {'\x0E01', '\x0E30'},    /* 0E01-0E30 */
+            new char[] {'\x0E32', '\x0E33'},    /* 0E32-0E33 */
+            new char[] {'\x0E40', '\x0E46'},    /* 0E40-0E46 */
+            new char[] {'\x0E4F', '\x0E5B'},    /* 0E4F-0E5B */
+            new char[] {'\x0E81', '\x0E82'},    /* 0E81-0E82 */
+            new char[] {'\x0E84', '\x0000'},    /* 0E84 */
+            new char[] {'\x0E87', '\x0E88'},    /* 0E87-0E88 */
+            new char[] {'\x0E8A', '\x0000'},    /* 0E8A */
+            new char[] {'\x0E8D', '\x0000'},    /* 0E8D */
+            new char[] {'\x0E94', '\x0E97'},    /* 0E94-0E97 */
+            new char[] {'\x0E99', '\x0E9F'},    /* 0E99-0E9F */
+            new char[] {'\x0EA1', '\x0EA3'},    /* 0EA1-0EA3 */
+            new char[] {'\x0EA5', '\x0000'},    /* 0EA5 */
+            new char[] {'\x0EA7', '\x0000'},    /* 0EA7 */
+            new char[] {'\x0EAA', '\x0EAB'},    /* 0EAA-0EAB */
+            new char[] {'\x0EAD', '\x0EB0'},    /* 0EAD-0EB0 */
+            new char[] {'\x0EB2', '\x0EB3'},    /* 0EB2-0EB3 */
+            new char[] {'\x0EBD', '\x0000'},    /* 0EBD */
+            new char[] {'\x0EC0', '\x0EC4'},    /* 0EC0-0EC4 */
+            new char[] {'\x0EC6', '\x0000'},    /* 0EC6 */
+            new char[] {'\x0ED0', '\x0ED9'},    /* 0ED0-0ED9 */
+            new char[] {'\x0EDC', '\x0EDD'},    /* 0EDC-0EDD */
+            new char[] {'\x0F00', '\x0F17'},    /* 0F00-0F17 */
+            new char[] {'\x0F1A', '\x0F34'},    /* 0F1A-0F34 */
+            new char[] {'\x0F36', '\x0000'},    /* 0F36 */
+            new char[] {'\x0F38', '\x0000'},    /* 0F38 */
+            new char[] {'\x0F3E', '\x0F47'},    /* 0F3E-0F47 */
+            new char[] {'\x0F49', '\x0F6A'},    /* 0F49-0F6A */
+            new char[] {'\x0F7F', '\x0000'},    /* 0F7F */
+            new char[] {'\x0F85', '\x0000'},    /* 0F85 */
+            new char[] {'\x0F88', '\x0F8B'},    /* 0F88-0F8B */
+            new char[] {'\x0FBE', '\x0FC5'},    /* 0FBE-0FC5 */
+            new char[] {'\x0FC7', '\x0FCC'},    /* 0FC7-0FCC */
+            new char[] {'\x0FCF', '\x0000'},    /* 0FCF */
+            new char[] {'\x1000', '\x1021'},    /* 1000-1021 */
+            new char[] {'\x1023', '\x1027'},    /* 1023-1027 */
+            new char[] {'\x1029', '\x102A'},    /* 1029-102A */
+            new char[] {'\x102C', '\x0000'},    /* 102C */
+            new char[] {'\x1031', '\x0000'},    /* 1031 */
+            new char[] {'\x1038', '\x0000'},    /* 1038 */
+            new char[] {'\x1040', '\x1057'},    /* 1040-1057 */
+            new char[] {'\x10A0', '\x10C5'},    /* 10A0-10C5 */
+            new char[] {'\x10D0', '\x10F8'},    /* 10D0-10F8 */
+            new char[] {'\x10FB', '\x0000'},    /* 10FB */
+            new char[] {'\x1100', '\x1159'},    /* 1100-1159 */
+            new char[] {'\x115F', '\x11A2'},    /* 115F-11A2 */
+            new char[] {'\x11A8', '\x11F9'},    /* 11A8-11F9 */
+            new char[] {'\x1200', '\x1206'},    /* 1200-1206 */
+            new char[] {'\x1208', '\x1246'},    /* 1208-1246 */
+            new char[] {'\x1248', '\x0000'},    /* 1248 */
+            new char[] {'\x124A', '\x124D'},    /* 124A-124D */
+            new char[] {'\x1250', '\x1256'},    /* 1250-1256 */
+            new char[] {'\x1258', '\x0000'},    /* 1258 */
+            new char[] {'\x125A', '\x125D'},    /* 125A-125D */
+            new char[] {'\x1260', '\x1286'},    /* 1260-1286 */
+            new char[] {'\x1288', '\x0000'},    /* 1288 */
+            new char[] {'\x128A', '\x128D'},    /* 128A-128D */
+            new char[] {'\x1290', '\x12AE'},    /* 1290-12AE */
+            new char[] {'\x12B0', '\x0000'},    /* 12B0 */
+            new char[] {'\x12B2', '\x12B5'},    /* 12B2-12B5 */
+            new char[] {'\x12B8', '\x12BE'},    /* 12B8-12BE */
+            new char[] {'\x12C0', '\x0000'},    /* 12C0 */
+            new char[] {'\x12C2', '\x12C5'},    /* 12C2-12C5 */
+            new char[] {'\x12C8', '\x12CE'},    /* 12C8-12CE */
+            new char[] {'\x12D0', '\x12D6'},    /* 12D0-12D6 */
+            new char[] {'\x12D8', '\x12EE'},    /* 12D8-12EE */
+            new char[] {'\x12F0', '\x130E'},    /* 12F0-130E */
+            new char[] {'\x1310', '\x0000'},    /* 1310 */
+            new char[] {'\x1312', '\x1315'},    /* 1312-1315 */
+            new char[] {'\x1318', '\x131E'},    /* 1318-131E */
+            new char[] {'\x1320', '\x1346'},    /* 1320-1346 */
+            new char[] {'\x1348', '\x135A'},    /* 1348-135A */
+            new char[] {'\x1361', '\x137C'},    /* 1361-137C */
+            new char[] {'\x13A0', '\x13F4'},    /* 13A0-13F4 */
+            new char[] {'\x1401', '\x1676'},    /* 1401-1676 */
+            new char[] {'\x1681', '\x169A'},    /* 1681-169A */
+            new char[] {'\x16A0', '\x16F0'},    /* 16A0-16F0 */
+            new char[] {'\x1700', '\x170C'},    /* 1700-170C */
+            new char[] {'\x170E', '\x1711'},    /* 170E-1711 */
+            new char[] {'\x1720', '\x1731'},    /* 1720-1731 */
+            new char[] {'\x1735', '\x1736'},    /* 1735-1736 */
+            new char[] {'\x1740', '\x1751'},    /* 1740-1751 */
+            new char[] {'\x1760', '\x176C'},    /* 1760-176C */
+            new char[] {'\x176E', '\x1770'},    /* 176E-1770 */
+            new char[] {'\x1780', '\x17B6'},    /* 1780-17B6 */
+            new char[] {'\x17BE', '\x17C5'},    /* 17BE-17C5 */
+            new char[] {'\x17C7', '\x17C8'},    /* 17C7-17C8 */
+            new char[] {'\x17D4', '\x17DA'},    /* 17D4-17DA */
+            new char[] {'\x17DC', '\x0000'},    /* 17DC */
+            new char[] {'\x17E0', '\x17E9'},    /* 17E0-17E9 */
+            new char[] {'\x1810', '\x1819'},    /* 1810-1819 */
+            new char[] {'\x1820', '\x1877'},    /* 1820-1877 */
+            new char[] {'\x1880', '\x18A8'},    /* 1880-18A8 */
+            new char[] {'\x1E00', '\x1E9B'},    /* 1E00-1E9B */
+            new char[] {'\x1EA0', '\x1EF9'},    /* 1EA0-1EF9 */
+            new char[] {'\x1F00', '\x1F15'},    /* 1F00-1F15 */
+            new char[] {'\x1F18', '\x1F1D'},    /* 1F18-1F1D */
+            new char[] {'\x1F20', '\x1F45'},    /* 1F20-1F45 */
+            new char[] {'\x1F48', '\x1F4D'},    /* 1F48-1F4D */
+            new char[] {'\x1F50', '\x1F57'},    /* 1F50-1F57 */
+            new char[] {'\x1F59', '\x0000'},    /* 1F59 */
+            new char[] {'\x1F5B', '\x0000'},    /* 1F5B */
+            new char[] {'\x1F5D', '\x0000'},    /* 1F5D */
+            new char[] {'\x1F5F', '\x1F7D'},    /* 1F5F-1F7D */
+            new char[] {'\x1F80', '\x1FB4'},    /* 1F80-1FB4 */
+            new char[] {'\x1FB6', '\x1FBC'},    /* 1FB6-1FBC */
+            new char[] {'\x1FBE', '\x0000'},    /* 1FBE */
+            new char[] {'\x1FC2', '\x1FC4'},    /* 1FC2-1FC4 */
+            new char[] {'\x1FC6', '\x1FCC'},    /* 1FC6-1FCC */
+            new char[] {'\x1FD0', '\x1FD3'},    /* 1FD0-1FD3 */
+            new char[] {'\x1FD6', '\x1FDB'},    /* 1FD6-1FDB */
+            new char[] {'\x1FE0', '\x1FEC'},    /* 1FE0-1FEC */
+            new char[] {'\x1FF2', '\x1FF4'},    /* 1FF2-1FF4 */
+            new char[] {'\x1FF6', '\x1FFC'},    /* 1FF6-1FFC */
+            new char[] {'\x200E', '\x0000'},    /* 200E */
+            new char[] {'\x2071', '\x0000'},    /* 2071 */
+            new char[] {'\x207F', '\x0000'},    /* 207F */
+            new char[] {'\x2102', '\x0000'},    /* 2102 */
+            new char[] {'\x2107', '\x0000'},    /* 2107 */
+            new char[] {'\x210A', '\x2113'},    /* 210A-2113 */
+            new char[] {'\x2115', '\x0000'},    /* 2115 */
+            new char[] {'\x2119', '\x211D'},    /* 2119-211D */
+            new char[] {'\x2124', '\x0000'},    /* 2124 */
+            new char[] {'\x2126', '\x0000'},    /* 2126 */
+            new char[] {'\x2128', '\x0000'},    /* 2128 */
+            new char[] {'\x212A', '\x212D'},    /* 212A-212D */
+            new char[] {'\x212F', '\x2131'},    /* 212F-2131 */
+            new char[] {'\x2133', '\x2139'},    /* 2133-2139 */
+            new char[] {'\x213D', '\x213F'},    /* 213D-213F */
+            new char[] {'\x2145', '\x2149'},    /* 2145-2149 */
+            new char[] {'\x2160', '\x2183'},    /* 2160-2183 */
+            new char[] {'\x2336', '\x237A'},    /* 2336-237A */
+            new char[] {'\x2395', '\x0000'},    /* 2395 */
+            new char[] {'\x249C', '\x24E9'},    /* 249C-24E9 */
+            new char[] {'\x3005', '\x3007'},    /* 3005-3007 */
+            new char[] {'\x3021', '\x3029'},    /* 3021-3029 */
+            new char[] {'\x3031', '\x3035'},    /* 3031-3035 */
+            new char[] {'\x3038', '\x303C'},    /* 3038-303C */
+            new char[] {'\x3041', '\x3096'},    /* 3041-3096 */
+            new char[] {'\x309D', '\x309F'},    /* 309D-309F */
+            new char[] {'\x30A1', '\x30FA'},    /* 30A1-30FA */
+            new char[] {'\x30FC', '\x30FF'},    /* 30FC-30FF */
+            new char[] {'\x3105', '\x312C'},    /* 3105-312C */
+            new char[] {'\x3131', '\x318E'},    /* 3131-318E */
+            new char[] {'\x3190', '\x31B7'},    /* 3190-31B7 */
+            new char[] {'\x31F0', '\x321C'},    /* 31F0-321C */
+            new char[] {'\x3220', '\x3243'},    /* 3220-3243 */
+            new char[] {'\x3260', '\x327B'},    /* 3260-327B */
+            new char[] {'\x327F', '\x32B0'},    /* 327F-32B0 */
+            new char[] {'\x32C0', '\x32CB'},    /* 32C0-32CB */
+            new char[] {'\x32D0', '\x32FE'},    /* 32D0-32FE */
+            new char[] {'\x3300', '\x3376'},    /* 3300-3376 */
+            new char[] {'\x337B', '\x33DD'},    /* 337B-33DD */
+            new char[] {'\x33E0', '\x33FE'},    /* 33E0-33FE */
+            new char[] {'\x3400', '\x4DB5'},    /* 3400-4DB5 */
+            new char[] {'\x4E00', '\x9FA5'},    /* 4E00-9FA5 */
+            new char[] {'\xA000', '\xA48C'},    /* A000-A48C */
+            new char[] {'\xAC00', '\xD7A3'},    /* AC00-D7A3 */
+            new char[] {'\xD800', '\xFA2D'},    /* D800-FA2D */
+            new char[] {'\xFA30', '\xFA6A'},    /* FA30-FA6A */
+            new char[] {'\xFB00', '\xFB06'},    /* FB00-FB06 */
+            new char[] {'\xFB13', '\xFB17'},    /* FB13-FB17 */
+            new char[] {'\xFF21', '\xFF3A'},    /* FF21-FF3A */
+            new char[] {'\xFF41', '\xFF5A'},    /* FF41-FF5A */
+            new char[] {'\xFF66', '\xFFBE'},    /* FF66-FFBE */
+            new char[] {'\xFFC2', '\xFFC7'},    /* FFC2-FFC7 */
+            new char[] {'\xFFCA', '\xFFCF'},    /* FFCA-FFCF */
+            new char[] {'\xFFD2', '\xFFD7'},    /* FFD2-FFD7 */
+            new char[] {'\xFFDA', '\xFFDC'},    /* FFDA-FFDC */
+        };
+
+    }
+}
diff --git a/lib/jabber-net/stringprep/steps/ResourceLoader.cs b/lib/jabber-net/stringprep/steps/ResourceLoader.cs
new file mode 100644
index 0000000..6dbd8b3
--- /dev/null
+++ b/lib/jabber-net/stringprep/steps/ResourceLoader.cs
@@ -0,0 +1,47 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net can be used under either JOSL or the GPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Resources;
+using System.Reflection;
+
+namespace stringprep.steps
+{
+    class ResourceLoader
+    {
+        private const string RFC3454 = "stringprep.steps.rfc3454";
+        private static ResourceManager m_rfc_res = null;
+
+        private static ResourceManager Resources
+        {
+            get
+            {
+                if (m_rfc_res == null)
+                {
+                    lock (RFC3454)
+                    {
+                        if (m_rfc_res == null)
+                            m_rfc_res = new ResourceManager(RFC3454, Assembly.GetExecutingAssembly());
+                    }
+                }
+                return m_rfc_res;
+            }
+        }
+
+        public static object LoadRes(string name)
+        {
+            return Resources.GetObject(name);
+        }
+    }
+}
diff --git a/lib/jabber-net/stringprep/unicode/Combining.cs b/lib/jabber-net/stringprep/unicode/Combining.cs
new file mode 100644
index 0000000..971255d
--- /dev/null
+++ b/lib/jabber-net/stringprep/unicode/Combining.cs
@@ -0,0 +1,38 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+
+namespace stringprep.unicode
+{
+    /// <summary>
+    /// Combining classes for Unicode characters.
+    /// </summary>
+    public class Combining
+    {
+        /// <summary>
+        /// What is the combining class for the given character?
+        /// </summary>
+        /// <param name="c">Character to look up</param>
+        /// <returns>Combining class for this character</returns>
+        public static int Class(char c)
+        {
+            int page = c >> 8;
+            if (CombiningData.Pages[page] == 255)
+                return 0;
+            else
+                return CombiningData.Classes[CombiningData.Pages[page], c & 0xff];
+        }
+    }
+}
diff --git a/lib/jabber-net/stringprep/unicode/CombiningData.cs b/lib/jabber-net/stringprep/unicode/CombiningData.cs
new file mode 100644
index 0000000..3c89f5f
--- /dev/null
+++ b/lib/jabber-net/stringprep/unicode/CombiningData.cs
@@ -0,0 +1,550 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+/* This file is automatically generated.  DO NOT EDIT! */
+
+namespace stringprep.unicode
+{
+    /// <summary>
+    /// Combining class lookup tables.
+    /// </summary>
+    public class CombiningData
+    {
+        /// <summary>
+        /// Combining classes for different pages.  All pages
+        /// unspecified here will return combining class 0.
+        /// </summary>
+        public static readonly byte[,] Classes =  new byte[,]
+        {
+            { /* page 3, index 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
+            },
+            { /* page 4, index 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,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   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
+            },
+            { /* page 5, index 2 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   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
+            },
+            { /* page 6, index 3 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   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
+            },
+            { /* page 7, index 4 */
+                  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
+            },
+            { /* page 9, index 5 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   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
+            },
+            { /* page 10, index 6 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   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
+            },
+            { /* page 11, index 7 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   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
+            },
+            { /* page 12, index 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,   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
+            },
+            { /* page 13, index 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,   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
+            },
+            { /* page 14, index 10 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   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
+            },
+            { /* page 15, index 11 */
+                  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
+            },
+            { /* page 16, index 12 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   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
+            },
+            { /* page 23, index 13 */
+                  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
+            },
+            { /* page 24, index 14 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   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
+            },
+            { /* page 32, index 15 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   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
+            },
+            { /* page 48, index 16 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   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
+            },
+            { /* page 251, index 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,  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
+            },
+            { /* page 254, index 18 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   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
+            }
+        };
+
+        /// <summary>
+        /// Offset into the Classes array for each page, since Classes
+        /// is sparse.
+        /// 255 here means that all of the combining classes for that page
+        /// are 0.
+        /// </summary>
+        public static readonly byte[] Pages = new byte[]
+        {
+            255,
+            255,
+            255,
+            0 /* page 3 */,
+            1 /* page 4 */,
+            2 /* page 5 */,
+            3 /* page 6 */,
+            4 /* page 7 */,
+            255,
+            5 /* page 9 */,
+            6 /* page 10 */,
+            7 /* page 11 */,
+            8 /* page 12 */,
+            9 /* page 13 */,
+            10 /* page 14 */,
+            11 /* page 15 */,
+            12 /* page 16 */,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            13 /* page 23 */,
+            14 /* page 24 */,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            15 /* page 32 */,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            16 /* page 48 */,
+            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,
+            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,
+            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,
+            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,
+            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,
+            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,
+            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,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            17 /* page 251 */,
+            255,
+            255,
+            18 /* page 254 */,
+            255        };
+   }
+}
diff --git a/lib/jabber-net/stringprep/unicode/Compose.cs b/lib/jabber-net/stringprep/unicode/Compose.cs
new file mode 100644
index 0000000..0c45cf7
--- /dev/null
+++ b/lib/jabber-net/stringprep/unicode/Compose.cs
@@ -0,0 +1,107 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+
+namespace stringprep.unicode
+{
+    /// <summary>
+    /// Combine combining characters, where possible.
+    /// Note: this is still Black Magic, as far as I can tell.
+    /// </summary>
+    public class Compose
+    {
+        private static int Index(char c)
+        {
+            int p = c >> 8;
+            if (p >= ComposeData.Table.Length)
+                return 0;
+            if (ComposeData.Table[p] == 255)
+                return 0;
+            else
+                return ComposeData.Data[ComposeData.Table[p], c & 0xff];
+        }
+
+        private static bool Between(int x, int start, int end)
+        {
+            return (x >= start) && (x < end);
+        }
+
+        /// <summary>
+        /// Combine two characters together, if possible.
+        /// </summary>
+        /// <param name="a">First character to combine</param>
+        /// <param name="b">Second character to combine</param>
+        /// <param name="result">The combined character, if method returns true.  Otherwise, undefined.</param>
+        /// <returns>True if combination occurred</returns>
+        public static bool Combine(char a, char b, out char result)
+        {
+
+            // FIRST_START..FIRST_SINGLE_START:
+            // FIRST_SINGLE_START..SECOND_START: look up a to see if b matches
+            // SECOND_START..SECOND_SINGLE_START:
+            // SECOND_SINGLE_START..: look up b to see if a matches
+
+            int index_a = Index(a);
+            // for stuff in this range, there is only one possible combination for the character
+            // on the left
+            if (Between(index_a, ComposeData.FIRST_SINGLE_START, ComposeData.SECOND_START))
+            {
+                int offset = index_a - ComposeData.FIRST_SINGLE_START;
+                if (b == ComposeData.FirstSingle[offset, 0])
+                {
+                    result = ComposeData.FirstSingle[offset, 1];
+                    return true;
+                }
+                else
+                {
+                    result = '\x0';
+                    return false;
+                }
+            }
+
+            int index_b = Index(b);
+            // for this range, only one possible combination to the right.
+            if (index_b >= ComposeData.SECOND_SINGLE_START)
+            {
+                int offset = index_b - ComposeData.SECOND_SINGLE_START;
+                if (a == ComposeData.SecondSingle[offset,0])
+                {
+                    result = ComposeData.SecondSingle[offset, 1];
+                    return true;
+                }
+                else
+                {
+                    result = '\x0';
+                    return false;
+                }
+            }
+
+            if (Between(index_a, ComposeData.FIRST_START, ComposeData.FIRST_SINGLE_START) &&
+                Between(index_b, ComposeData.SECOND_START, ComposeData.SECOND_SINGLE_START))
+            {
+                char res = ComposeData.Array[index_a - ComposeData.FIRST_START, index_b - ComposeData.SECOND_START];
+
+                if (res != '\x0')
+                {
+                    result = res;
+                    return true;
+                }
+            }
+
+            result = '\x0';
+            return false;
+        }
+    }
+}
diff --git a/lib/jabber-net/stringprep/unicode/ComposeData.cs b/lib/jabber-net/stringprep/unicode/ComposeData.cs
new file mode 100644
index 0000000..2b6997d
--- /dev/null
+++ b/lib/jabber-net/stringprep/unicode/ComposeData.cs
@@ -0,0 +1,729 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+/* This file is automatically generated.  DO NOT EDIT! */
+
+namespace stringprep.unicode
+{
+    /// <summary>
+    /// Data for composition of characters.  The algorithms here are still black box to me.
+    /// </summary>
+    public class ComposeData
+    {
+
+        /// <summary>
+        /// Where the first range of offsets from Data starts.
+        /// These are used for checking the first character
+        /// in a pair with a second character in Array.
+        /// </summary>
+        public const short FIRST_START = 1;
+        /// <summary>
+        /// Where the offsets of the range of characters where there is
+        /// only one match for the second character, with a given first character.
+        /// </summary>
+        public const short FIRST_SINGLE_START = 147;
+        /// <summary>
+        /// Where the offsets of the range of second characters that match a given first
+        /// character starts.
+        /// </summary>
+        public const short SECOND_START = 357;
+        /// <summary>
+        /// When there is only a single match to the left for these characters on the
+        /// right, the offsets for that chunk of characters starts here.
+        /// </summary>
+        public const short SECOND_SINGLE_START = 388;
+
+        /// <summary>
+        /// The offset into Array for each character.  This array is compressed using
+        /// the Table table, which provides page offsets for the pages that are non-zero.
+        /// </summary>
+        public static readonly short[,] Data = new short[,]
+        {
+            { /* page 0, index 0 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 147, 148, 149,   0,   0,   1,   2,   3,   4,   5,
+                150,   6,   7,   8, 151,   9,  10,  11,  12,  13,  14,   0,  15,  16,  17,  18,  19,  20,  21,
+                 22,  23,   0,   0,   0,   0,   0,   0,  24,  25,  26,  27,  28, 152,  29,  30,  31,  32,  33,
+                 34,  35,  36,  37,  38,   0,  39,  40,  41,  42,  43,  44,  45,  46,  47,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  48,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  49,   0, 153, 154,
+                 50, 155,   0,   0,  51,   0,   0,   0,   0, 156,   0,   0,   0,   0,  52,  53, 157,   0, 158,   0,
+                  0,   0,  54,   0,   0,   0,   0,   0,  55,   0, 159, 160,  56, 161,   0,   0,  57,   0,   0,   0,   0,
+                162,   0,   0,   0,   0,  58,  59, 163,   0, 164,   0,   0,   0,  60,   0,   0,   0
+            },
+            { /* page 1, index 1 */
+                  0,   0,  61,  62,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  63,  64,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,  65,  66,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 165, 166,   0,
+                  0,   0,   0, 167, 168,   0,   0,   0,   0,   0,   0, 169, 170, 171, 172,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 173,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  67,
+                 68,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  69,  70,   0,   0,   0,   0,   0,   0, 174,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0, 175, 176,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0
+            },
+            { /* page 2, index 2 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 177, 178, 179, 180,   0,   0,   0,   0,
+                181, 182,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0, 183,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
+            },
+            { /* page 3, index 3 */
+                357, 358, 359, 360, 361,   0, 362, 363, 364, 365, 366, 367, 368,   0,   0, 369,
+                  0, 370,   0, 371, 372,   0,   0,   0,   0,   0,   0, 373,   0,   0,   0,   0,   0,   0,   0, 374,
+                375, 376, 377, 378, 379,   0,   0,   0,   0, 380, 381,   0, 382, 383,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 384,   0,   0, 385,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  71,   0,   0,   0,
+                 72,   0,  73,   0,  74,   0,   0,   0,   0,   0,  75,   0, 184,   0,   0,   0,  76,   0,   0,   0,  77,   0,
+                  0, 185,   0, 186,   0,   0,  78,   0,   0,   0,  79,   0,  80,   0,  81,   0,   0,   0,   0,   0,  82,
+                  0,  83,   0,   0,   0,  84,   0,   0,   0,  85,  86,  87,   0,   0, 187,   0,   0,   0,  88,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
+            },
+            { /* page 4, index 4 */
+                  0,   0,   0,   0,   0,   0, 188,   0,   0,   0,   0,   0,   0,   0,   0,   0,  89,   0,   0, 189,   0,  90,
+                 91, 190,  92,   0, 191,   0,   0,   0, 192,   0,   0,   0,   0,  93,   0,   0,   0, 193,   0,   0,   0,
+                194,   0, 195,   0,   0,  94,   0,   0, 196,   0,  95,  96, 197,  97,   0, 198,   0,   0,   0,
+                199,   0,   0,   0,   0,  98,   0,   0,   0, 200,   0,   0,   0, 201,   0, 202,   0,   0,   0,   0,   0,
+                  0,   0,   0, 203,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0, 204, 205,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 206, 207,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0, 208, 209,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0
+            },
+            { /* page 6, index 5 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  99,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                210,   0, 211,   0,   0,   0,   0,   0,   0,   0,   0, 388, 389, 390,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0, 212,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 213,   0,
+                  0, 214,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
+            },
+            { /* page 9, index 6 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 215,   0,   0,   0,   0,   0,   0,   0,
+                216,   0,   0, 217,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 391,
+                  0,   0,   0,   0,   0,   0,   0,   0, 100,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                392,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
+            },
+            { /* page 11, index 7 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 393,   0,   0,   0,   0,   0,   0,   0,   0,
+                101,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 394, 395,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   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,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0, 396,   0,   0,   0,   0,   0,   0,   0, 102, 219,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0, 397,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
+            },
+            { /* page 12, index 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, 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,   0,   0,   0,   0,   0,   0,   0,   0, 221,
+                  0,   0, 398,   0,   0,   0, 103,   0,   0,   0, 222,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 399,
+                400,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
+            },
+            { /* page 13, index 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, 401,   0,   0,   0,   0,   0,   0,   0, 104,
+                223,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 402,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 403,   0,   0,   0,   0, 404,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0, 105,   0,   0, 224,   0,   0, 405,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
+            },
+            { /* page 16, index 10 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 225,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
+            },
+            { /* page 30, index 11 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0, 226, 227,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   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, 229,   0,   0,
+                  0,   0,   0,   0, 230, 231,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 106, 107,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 232, 233,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 234, 235,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
+            },
+            { /* page 31, index 12 */
+                108, 109, 236, 237, 238, 239, 240, 241, 110, 111, 242, 243, 244, 245,
+                246, 247, 112, 113,   0,   0,   0,   0,   0,   0, 114, 115,   0,   0,   0,   0,   0,   0, 116,
+                117, 248, 249, 250, 251, 252, 253, 118, 119, 254, 255, 256, 257, 258,
+                259, 120, 121,   0,   0,   0,   0,   0,   0, 122, 123,   0,   0,   0,   0,   0,   0, 124, 125,   0,
+                  0,   0,   0,   0,   0, 126, 127,   0,   0,   0,   0,   0,   0, 128, 129,   0,   0,   0,   0,   0,   0,   0,
+                130,   0,   0,   0,   0,   0,   0, 131, 132, 260, 261, 262, 263, 264, 265, 133, 134,
+                266, 267, 268, 269, 270, 271, 272,   0,   0,   0, 273,   0,   0,   0,   0,   0,   0,   0,
+                274,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 275,   0,   0,   0,   0,   0,   0,   0,   0, 135,   0,   0,   0,
+                  0,   0,   0, 276,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0, 277,   0,   0,   0,   0,   0,   0,   0, 136,   0
+            },
+            { /* page 33, index 13 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                278,   0, 279,   0, 280,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 281,   0, 282,   0,
+                283,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
+            },
+            { /* page 34, index 14 */
+                  0,   0,   0, 284,   0,   0,   0,   0, 285,   0,   0, 286,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 287,   0, 288,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 289,   0,   0,   0,   0,   0,   0, 290,
+                  0, 291,   0,   0, 292,   0,   0,   0,   0, 293,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0, 294,   0,   0, 295, 296,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0, 297, 298,   0,   0, 299, 300,   0,   0, 301, 302, 303, 304,   0,   0,   0,   0,
+                305, 306,   0,   0, 307, 308,   0,   0,   0,   0,   0,   0,   0,   0,   0, 309, 310,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 311,   0,   0,   0,   0,   0, 312, 313,   0, 314,
+                  0,   0,   0,   0,   0,   0, 315, 316, 317, 318,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
+            },
+            { /* page 48, index 15 */
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 319,   0,
+                  0,   0,   0, 320,   0, 321,   0, 322,   0, 323,   0, 324,   0, 325,   0, 326,   0, 327,   0,
+                328,   0, 329,   0, 330,   0, 331,   0,   0, 332,   0, 333,   0, 334,   0,   0,   0,   0,   0,   0,
+                137,   0,   0, 138,   0,   0, 139,   0,   0, 140,   0,   0, 141,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 386, 387,
+                  0,   0, 335,   0,   0,   0,   0,   0,   0,   0,   0, 336,   0,   0,   0,   0, 337,   0, 338,   0, 339,
+                  0, 340,   0, 341,   0, 342,   0, 343,   0, 344,   0, 345,   0, 346,   0, 347,   0, 348,
+                  0,   0, 349,   0, 350,   0, 351,   0,   0,   0,   0,   0,   0, 142,   0,   0, 143,   0,   0, 144,
+                  0,   0, 145,   0,   0, 146,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+                  0,   0, 352, 353, 354, 355,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 356,   0,   0
+            }
+        };
+
+        /// <summary>
+        /// Page offsets into Data for each page of characters.
+        /// </summary>
+        public static readonly byte[] Table = new byte[]
+        {
+            0 /* page 0 */,
+            1 /* page 1 */,
+            2 /* page 2 */,
+            3 /* page 3 */,
+            4 /* page 4 */,
+            255,
+            5 /* page 6 */,
+            255,
+            255,
+            6 /* page 9 */,
+            255,
+            7 /* page 11 */,
+            8 /* page 12 */,
+            9 /* page 13 */,
+            255,
+            255,
+            10 /* page 16 */,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            11 /* page 30 */,
+            12 /* page 31 */,
+            255,
+            13 /* page 33 */,
+            14 /* page 34 */,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            15 /* page 48 */
+        };
+
+        /// <summary>
+        /// When the offset for the  first character is in the range
+        /// [FIRST_SINGLE_START, SECOND_START), look up the corresponding
+        /// character here with the offset from Data to see if it is
+        /// the second character.  If not, there is no combination.
+        /// </summary>
+        public static readonly char[,] FirstSingle = new char[,]
+        {
+            {'\x0338', '\x226e'},
+            {'\x0338', '\x2260'},
+            {'\x0338', '\x226f'},
+            {'\x0307', '\x1e1e'},
+            {'\x0302', '\x0134'},
+            {'\x0307', '\x1e1f'},
+            {'\x0304', '\x01de'},
+            {'\x0301', '\x01fa'},
+            {'\x0301', '\x1e08'},
+            {'\x0301', '\x1e2e'},
+            {'\x0304', '\x022a'},
+            {'\x0301', '\x01fe'},
+            {'\x0304', '\x01df'},
+            {'\x0301', '\x01fb'},
+            {'\x0301', '\x1e09'},
+            {'\x0301', '\x1e2f'},
+            {'\x0304', '\x022b'},
+            {'\x0301', '\x01ff'},
+            {'\x0307', '\x1e64'},
+            {'\x0307', '\x1e65'},
+            {'\x0307', '\x1e66'},
+            {'\x0307', '\x1e67'},
+            {'\x0301', '\x1e78'},
+            {'\x0301', '\x1e79'},
+            {'\x0308', '\x1e7a'},
+            {'\x0308', '\x1e7b'},
+            {'\x0307', '\x1e9b'},
+            {'\x030c', '\x01ee'},
+            {'\x0304', '\x01ec'},
+            {'\x0304', '\x01ed'},
+            {'\x0304', '\x01e0'},
+            {'\x0304', '\x01e1'},
+            {'\x0306', '\x1e1c'},
+            {'\x0306', '\x1e1d'},
+            {'\x0304', '\x0230'},
+            {'\x0304', '\x0231'},
+            {'\x030c', '\x01ef'},
+            {'\x0314', '\x1fec'},
+            {'\x0345', '\x1fb4'},
+            {'\x0345', '\x1fc4'},
+            {'\x0345', '\x1ff4'},
+            {'\x0308', '\x0407'},
+            {'\x0301', '\x0403'},
+            {'\x0308', '\x04de'},
+            {'\x0301', '\x040c'},
+            {'\x0308', '\x04e6'},
+            {'\x0308', '\x04f4'},
+            {'\x0308', '\x04f8'},
+            {'\x0308', '\x04ec'},
+            {'\x0301', '\x0453'},
+            {'\x0308', '\x04df'},
+            {'\x0301', '\x045c'},
+            {'\x0308', '\x04e7'},
+            {'\x0308', '\x04f5'},
+            {'\x0308', '\x04f9'},
+            {'\x0308', '\x04ed'},
+            {'\x0308', '\x0457'},
+            {'\x030f', '\x0476'},
+            {'\x030f', '\x0477'},
+            {'\x0308', '\x04da'},
+            {'\x0308', '\x04db'},
+            {'\x0308', '\x04ea'},
+            {'\x0308', '\x04eb'},
+            {'\x0654', '\x0624'},
+            {'\x0654', '\x0626'},
+            {'\x0654', '\x06c2'},
+            {'\x0654', '\x06d3'},
+            {'\x0654', '\x06c0'},
+            {'\x093c', '\x0929'},
+            {'\x093c', '\x0931'},
+            {'\x093c', '\x0934'},
+            {'\x0bd7', '\x0b94'},
+            {'\x0bbe', '\x0bcb'},
+            {'\x0c56', '\x0c48'},
+            {'\x0cd5', '\x0cc0'},
+            {'\x0cd5', '\x0ccb'},
+            {'\x0d3e', '\x0d4b'},
+            {'\x0dca', '\x0ddd'},
+            {'\x102e', '\x1026'},
+            {'\x0304', '\x1e38'},
+            {'\x0304', '\x1e39'},
+            {'\x0304', '\x1e5c'},
+            {'\x0304', '\x1e5d'},
+            {'\x0307', '\x1e68'},
+            {'\x0307', '\x1e69'},
+            {'\x0302', '\x1ec6'},
+            {'\x0302', '\x1ec7'},
+            {'\x0302', '\x1ed8'},
+            {'\x0302', '\x1ed9'},
+            {'\x0345', '\x1f82'},
+            {'\x0345', '\x1f83'},
+            {'\x0345', '\x1f84'},
+            {'\x0345', '\x1f85'},
+            {'\x0345', '\x1f86'},
+            {'\x0345', '\x1f87'},
+            {'\x0345', '\x1f8a'},
+            {'\x0345', '\x1f8b'},
+            {'\x0345', '\x1f8c'},
+            {'\x0345', '\x1f8d'},
+            {'\x0345', '\x1f8e'},
+            {'\x0345', '\x1f8f'},
+            {'\x0345', '\x1f92'},
+            {'\x0345', '\x1f93'},
+            {'\x0345', '\x1f94'},
+            {'\x0345', '\x1f95'},
+            {'\x0345', '\x1f96'},
+            {'\x0345', '\x1f97'},
+            {'\x0345', '\x1f9a'},
+            {'\x0345', '\x1f9b'},
+            {'\x0345', '\x1f9c'},
+            {'\x0345', '\x1f9d'},
+            {'\x0345', '\x1f9e'},
+            {'\x0345', '\x1f9f'},
+            {'\x0345', '\x1fa2'},
+            {'\x0345', '\x1fa3'},
+            {'\x0345', '\x1fa4'},
+            {'\x0345', '\x1fa5'},
+            {'\x0345', '\x1fa6'},
+            {'\x0345', '\x1fa7'},
+            {'\x0345', '\x1faa'},
+            {'\x0345', '\x1fab'},
+            {'\x0345', '\x1fac'},
+            {'\x0345', '\x1fad'},
+            {'\x0345', '\x1fae'},
+            {'\x0345', '\x1faf'},
+            {'\x0345', '\x1fb2'},
+            {'\x0345', '\x1fc2'},
+            {'\x0345', '\x1ff2'},
+            {'\x0345', '\x1fb7'},
+            {'\x0345', '\x1fc7'},
+            {'\x0345', '\x1ff7'},
+            {'\x0338', '\x219a'},
+            {'\x0338', '\x219b'},
+            {'\x0338', '\x21ae'},
+            {'\x0338', '\x21cd'},
+            {'\x0338', '\x21cf'},
+            {'\x0338', '\x21ce'},
+            {'\x0338', '\x2204'},
+            {'\x0338', '\x2209'},
+            {'\x0338', '\x220c'},
+            {'\x0338', '\x2224'},
+            {'\x0338', '\x2226'},
+            {'\x0338', '\x2241'},
+            {'\x0338', '\x2244'},
+            {'\x0338', '\x2247'},
+            {'\x0338', '\x2249'},
+            {'\x0338', '\x226d'},
+            {'\x0338', '\x2262'},
+            {'\x0338', '\x2270'},
+            {'\x0338', '\x2271'},
+            {'\x0338', '\x2274'},
+            {'\x0338', '\x2275'},
+            {'\x0338', '\x2278'},
+            {'\x0338', '\x2279'},
+            {'\x0338', '\x2280'},
+            {'\x0338', '\x2281'},
+            {'\x0338', '\x22e0'},
+            {'\x0338', '\x22e1'},
+            {'\x0338', '\x2284'},
+            {'\x0338', '\x2285'},
+            {'\x0338', '\x2288'},
+            {'\x0338', '\x2289'},
+            {'\x0338', '\x22e2'},
+            {'\x0338', '\x22e3'},
+            {'\x0338', '\x22ac'},
+            {'\x0338', '\x22ad'},
+            {'\x0338', '\x22ae'},
+            {'\x0338', '\x22af'},
+            {'\x0338', '\x22ea'},
+            {'\x0338', '\x22eb'},
+            {'\x0338', '\x22ec'},
+            {'\x0338', '\x22ed'},
+            {'\x3099', '\x3094'},
+            {'\x3099', '\x304c'},
+            {'\x3099', '\x304e'},
+            {'\x3099', '\x3050'},
+            {'\x3099', '\x3052'},
+            {'\x3099', '\x3054'},
+            {'\x3099', '\x3056'},
+            {'\x3099', '\x3058'},
+            {'\x3099', '\x305a'},
+            {'\x3099', '\x305c'},
+            {'\x3099', '\x305e'},
+            {'\x3099', '\x3060'},
+            {'\x3099', '\x3062'},
+            {'\x3099', '\x3065'},
+            {'\x3099', '\x3067'},
+            {'\x3099', '\x3069'},
+            {'\x3099', '\x309e'},
+            {'\x3099', '\x30f4'},
+            {'\x3099', '\x30ac'},
+            {'\x3099', '\x30ae'},
+            {'\x3099', '\x30b0'},
+            {'\x3099', '\x30b2'},
+            {'\x3099', '\x30b4'},
+            {'\x3099', '\x30b6'},
+            {'\x3099', '\x30b8'},
+            {'\x3099', '\x30ba'},
+            {'\x3099', '\x30bc'},
+            {'\x3099', '\x30be'},
+            {'\x3099', '\x30c0'},
+            {'\x3099', '\x30c2'},
+            {'\x3099', '\x30c5'},
+            {'\x3099', '\x30c7'},
+            {'\x3099', '\x30c9'},
+            {'\x3099', '\x30f7'},
+            {'\x3099', '\x30f8'},
+            {'\x3099', '\x30f9'},
+            {'\x3099', '\x30fa'},
+            {'\x3099', '\x30fe'}
+        };
+
+        /// <summary>
+        /// When the offset for the second character is in the range
+        /// [SECOND_SINGLE_START...), look up the corresponding
+        /// character here with the offset from Data to see if it is
+        /// the first character.  If not, there is no combination.
+        /// </summary>
+        public static readonly char[,] SecondSingle = new char[,]
+        {
+            {'\x0627', '\x0622'},
+            {'\x0627', '\x0623'},
+            {'\x0627', '\x0625'},
+            {'\x09c7', '\x09cb'},
+            {'\x09c7', '\x09cc'},
+            {'\x0b47', '\x0b4b'},
+            {'\x0b47', '\x0b48'},
+            {'\x0b47', '\x0b4c'},
+            {'\x0bc6', '\x0bca'},
+            {'\x0bc6', '\x0bcc'},
+            {'\x0cc6', '\x0cca'},
+            {'\x0cc6', '\x0cc7'},
+            {'\x0cc6', '\x0cc8'},
+            {'\x0d46', '\x0d4a'},
+            {'\x0d46', '\x0d4c'},
+            {'\x0dd9', '\x0dda'},
+            {'\x0dd9', '\x0ddc'},
+            {'\x0dd9', '\x0dde'}
+        };
+
+        /// <summary>
+        /// Array of composition pairs, indexed by offset (from Data) of first
+        /// character, and offset of second character.
+        /// </summary>
+        public static readonly char[,] Array = new char[,]
+        {
+            {'\x00c0', '\x00c1', '\x00c2', '\x00c3', '\x0100', '\x0102', '\x0226', '\x00c4', '\x1ea2', '\x00c5', '\x0000', '\x01cd', '\x0200', '\x0202', '\x0000', '\x0000', '\x0000', '\x1ea0', '\x0000', '\x1e00', '\x0000', '\x0000', '\x0104', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e02', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e04', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e06', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0106', '\x0108', '\x0000', '\x0000', '\x0000', '\x010a', '\x0000', '\x0000', '\x0000', '\x0000', '\x010c', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x00c7', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e0a', '\x0000', '\x0000', '\x0000', '\x0000', '\x010e', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e0c', '\x0000', '\x0000', '\x0000', '\x1e10', '\x0000', '\x1e12', '\x0000', '\x0000', '\x1e0e', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x00c8', '\x00c9', '\x00ca', '\x1ebc', '\x0112', '\x0114', '\x0116', '\x00cb', '\x1eba', '\x0000', '\x0000', '\x011a', '\x0204', '\x0206', '\x0000', '\x0000', '\x0000', '\x1eb8', '\x0000', '\x0000', '\x0000', '\x0228', '\x0118', '\x1e18', '\x0000', '\x1e1a', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x01f4', '\x011c', '\x0000', '\x1e20', '\x011e', '\x0120', '\x0000', '\x0000', '\x0000', '\x0000', '\x01e6', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0122', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0124', '\x0000', '\x0000', '\x0000', '\x1e22', '\x1e26', '\x0000', '\x0000', '\x0000', '\x021e', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e24', '\x0000', '\x0000', '\x0000', '\x1e28', '\x0000', '\x0000', '\x1e2a', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x00cc', '\x00cd', '\x00ce', '\x0128', '\x012a', '\x012c', '\x0130', '\x00cf', '\x1ec8', '\x0000', '\x0000', '\x01cf', '\x0208', '\x020a', '\x0000', '\x0000', '\x0000', '\x1eca', '\x0000', '\x0000', '\x0000', '\x0000', '\x012e', '\x0000', '\x0000', '\x1e2c', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x1e30', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x01e8', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e32', '\x0000', '\x0000', '\x0000', '\x0136', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e34', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0139', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x013d', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e36', '\x0000', '\x0000', '\x0000', '\x013b', '\x0000', '\x1e3c', '\x0000', '\x0000', '\x1e3a', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x1e3e', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e40', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e42', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x01f8', '\x0143', '\x0000', '\x00d1', '\x0000', '\x0000', '\x1e44', '\x0000', '\x0000', '\x0000', '\x0000', '\x0147', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e46', '\x0000', '\x0000', '\x0000', '\x0145', '\x0000', '\x1e4a', '\x0000', '\x0000', '\x1e48', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x00d2', '\x00d3', '\x00d4', '\x00d5', '\x014c', '\x014e', '\x022e', '\x00d6', '\x1ece', '\x0000', '\x0150', '\x01d1', '\x020c', '\x020e', '\x0000', '\x0000', '\x01a0', '\x1ecc', '\x0000', '\x0000', '\x0000', '\x0000', '\x01ea', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x1e54', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e56', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0154', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e58', '\x0000', '\x0000', '\x0000', '\x0000', '\x0158', '\x0210', '\x0212', '\x0000', '\x0000', '\x0000', '\x1e5a', '\x0000', '\x0000', '\x0000', '\x0156', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e5e', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x015a', '\x015c', '\x0000', '\x0000', '\x0000', '\x1e60', '\x0000', '\x0000', '\x0000', '\x0000', '\x0160', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e62', '\x0000', '\x0000', '\x0218', '\x015e', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e6a', '\x0000', '\x0000', '\x0000', '\x0000', '\x0164', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e6c', '\x0000', '\x0000', '\x021a', '\x0162', '\x0000', '\x1e70', '\x0000', '\x0000', '\x1e6e', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x00d9', '\x00da', '\x00db', '\x0168', '\x016a', '\x016c', '\x0000', '\x00dc', '\x1ee6', '\x016e', '\x0170', '\x01d3', '\x0214', '\x0216', '\x0000', '\x0000', '\x01af', '\x1ee4', '\x1e72', '\x0000', '\x0000', '\x0000', '\x0172', '\x1e76', '\x0000', '\x1e74', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x1e7c', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e7e', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1e80', '\x1e82', '\x0174', '\x0000', '\x0000', '\x0000', '\x1e86', '\x1e84', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e88', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e8a', '\x1e8c', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1ef2', '\x00dd', '\x0176', '\x1ef8', '\x0232', '\x0000', '\x1e8e', '\x0178', '\x1ef6', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1ef4', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0179', '\x1e90', '\x0000', '\x0000', '\x0000', '\x017b', '\x0000', '\x0000', '\x0000', '\x0000', '\x017d', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e92', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e94', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x00e0', '\x00e1', '\x00e2', '\x00e3', '\x0101', '\x0103', '\x0227', '\x00e4', '\x1ea3', '\x00e5', '\x0000', '\x01ce', '\x0201', '\x0203', '\x0000', '\x0000', '\x0000', '\x1ea1', '\x0000', '\x1e01', '\x0000', '\x0000', '\x0105', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e03', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e05', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e07', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0107', '\x0109', '\x0000', '\x0000', '\x0000', '\x010b', '\x0000', '\x0000', '\x0000', '\x0000', '\x010d', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x00e7', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e0b', '\x0000', '\x0000', '\x0000', '\x0000', '\x010f', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e0d', '\x0000', '\x0000', '\x0000', '\x1e11', '\x0000', '\x1e13', '\x0000', '\x0000', '\x1e0f', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x00e8', '\x00e9', '\x00ea', '\x1ebd', '\x0113', '\x0115', '\x0117', '\x00eb', '\x1ebb', '\x0000', '\x0000', '\x011b', '\x0205', '\x0207', '\x0000', '\x0000', '\x0000', '\x1eb9', '\x0000', '\x0000', '\x0000', '\x0229', '\x0119', '\x1e19', '\x0000', '\x1e1b', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x01f5', '\x011d', '\x0000', '\x1e21', '\x011f', '\x0121', '\x0000', '\x0000', '\x0000', '\x0000', '\x01e7', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0123', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0125', '\x0000', '\x0000', '\x0000', '\x1e23', '\x1e27', '\x0000', '\x0000', '\x0000', '\x021f', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e25', '\x0000', '\x0000', '\x0000', '\x1e29', '\x0000', '\x0000', '\x1e2b', '\x0000', '\x1e96', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x00ec', '\x00ed', '\x00ee', '\x0129', '\x012b', '\x012d', '\x0000', '\x00ef', '\x1ec9', '\x0000', '\x0000', '\x01d0', '\x0209', '\x020b', '\x0000', '\x0000', '\x0000', '\x1ecb', '\x0000', '\x0000', '\x0000', '\x0000', '\x012f', '\x0000', '\x0000', '\x1e2d', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0135', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x01f0', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x1e31', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x01e9', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e33', '\x0000', '\x0000', '\x0000', '\x0137', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e35', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x013a', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x013e', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e37', '\x0000', '\x0000', '\x0000', '\x013c', '\x0000', '\x1e3d', '\x0000', '\x0000', '\x1e3b', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x1e3f', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e41', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e43', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x01f9', '\x0144', '\x0000', '\x00f1', '\x0000', '\x0000', '\x1e45', '\x0000', '\x0000', '\x0000', '\x0000', '\x0148', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e47', '\x0000', '\x0000', '\x0000', '\x0146', '\x0000', '\x1e4b', '\x0000', '\x0000', '\x1e49', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x00f2', '\x00f3', '\x00f4', '\x00f5', '\x014d', '\x014f', '\x022f', '\x00f6', '\x1ecf', '\x0000', '\x0151', '\x01d2', '\x020d', '\x020f', '\x0000', '\x0000', '\x01a1', '\x1ecd', '\x0000', '\x0000', '\x0000', '\x0000', '\x01eb', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x1e55', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e57', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0155', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e59', '\x0000', '\x0000', '\x0000', '\x0000', '\x0159', '\x0211', '\x0213', '\x0000', '\x0000', '\x0000', '\x1e5b', '\x0000', '\x0000', '\x0000', '\x0157', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e5f', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x015b', '\x015d', '\x0000', '\x0000', '\x0000', '\x1e61', '\x0000', '\x0000', '\x0000', '\x0000', '\x0161', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e63', '\x0000', '\x0000', '\x0219', '\x015f', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e6b', '\x1e97', '\x0000', '\x0000', '\x0000', '\x0165', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e6d', '\x0000', '\x0000', '\x021b', '\x0163', '\x0000', '\x1e71', '\x0000', '\x0000', '\x1e6f', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x00f9', '\x00fa', '\x00fb', '\x0169', '\x016b', '\x016d', '\x0000', '\x00fc', '\x1ee7', '\x016f', '\x0171', '\x01d4', '\x0215', '\x0217', '\x0000', '\x0000', '\x01b0', '\x1ee5', '\x1e73', '\x0000', '\x0000', '\x0000', '\x0173', '\x1e77', '\x0000', '\x1e75', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x1e7d', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e7f', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1e81', '\x1e83', '\x0175', '\x0000', '\x0000', '\x0000', '\x1e87', '\x1e85', '\x0000', '\x1e98', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e89', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e8b', '\x1e8d', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1ef3', '\x00fd', '\x0177', '\x1ef9', '\x0233', '\x0000', '\x1e8f', '\x00ff', '\x1ef7', '\x1e99', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1ef5', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x017a', '\x1e91', '\x0000', '\x0000', '\x0000', '\x017c', '\x0000', '\x0000', '\x0000', '\x0000', '\x017e', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e93', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1e95', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1fed', '\x0385', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1fc1', '\x0000', '\x0000', '\x0000'},
+            {'\x1ea6', '\x1ea4', '\x0000', '\x1eaa', '\x0000', '\x0000', '\x0000', '\x0000', '\x1ea8', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x01fc', '\x0000', '\x0000', '\x01e2', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1ec0', '\x1ebe', '\x0000', '\x1ec4', '\x0000', '\x0000', '\x0000', '\x0000', '\x1ec2', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1ed2', '\x1ed0', '\x0000', '\x1ed6', '\x0000', '\x0000', '\x0000', '\x0000', '\x1ed4', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x1e4c', '\x0000', '\x0000', '\x022c', '\x0000', '\x0000', '\x1e4e', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x01db', '\x01d7', '\x0000', '\x0000', '\x01d5', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x01d9', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1ea7', '\x1ea5', '\x0000', '\x1eab', '\x0000', '\x0000', '\x0000', '\x0000', '\x1ea9', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x01fd', '\x0000', '\x0000', '\x01e3', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1ec1', '\x1ebf', '\x0000', '\x1ec5', '\x0000', '\x0000', '\x0000', '\x0000', '\x1ec3', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1ed3', '\x1ed1', '\x0000', '\x1ed7', '\x0000', '\x0000', '\x0000', '\x0000', '\x1ed5', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x1e4d', '\x0000', '\x0000', '\x022d', '\x0000', '\x0000', '\x1e4f', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x01dc', '\x01d8', '\x0000', '\x0000', '\x01d6', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x01da', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1eb0', '\x1eae', '\x0000', '\x1eb4', '\x0000', '\x0000', '\x0000', '\x0000', '\x1eb2', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1eb1', '\x1eaf', '\x0000', '\x1eb5', '\x0000', '\x0000', '\x0000', '\x0000', '\x1eb3', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1e14', '\x1e16', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1e15', '\x1e17', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1e50', '\x1e52', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1e51', '\x1e53', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1edc', '\x1eda', '\x0000', '\x1ee0', '\x0000', '\x0000', '\x0000', '\x0000', '\x1ede', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1ee2', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1edd', '\x1edb', '\x0000', '\x1ee1', '\x0000', '\x0000', '\x0000', '\x0000', '\x1edf', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1ee3', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1eea', '\x1ee8', '\x0000', '\x1eee', '\x0000', '\x0000', '\x0000', '\x0000', '\x1eec', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1ef0', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1eeb', '\x1ee9', '\x0000', '\x1eef', '\x0000', '\x0000', '\x0000', '\x0000', '\x1eed', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1ef1', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1fba', '\x0386', '\x0000', '\x0000', '\x1fb9', '\x1fb8', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f08', '\x1f09', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1fbc', '\x0000', '\x0000'},
+            {'\x1fc8', '\x0388', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f18', '\x1f19', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1fca', '\x0389', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f28', '\x1f29', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1fcc', '\x0000', '\x0000'},
+            {'\x1fda', '\x038a', '\x0000', '\x0000', '\x1fd9', '\x1fd8', '\x0000', '\x03aa', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f38', '\x1f39', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1ff8', '\x038c', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f48', '\x1f49', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1fea', '\x038e', '\x0000', '\x0000', '\x1fe9', '\x1fe8', '\x0000', '\x03ab', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f59', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1ffa', '\x038f', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f68', '\x1f69', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1ffc', '\x0000', '\x0000'},
+            {'\x1f70', '\x03ac', '\x0000', '\x0000', '\x1fb1', '\x1fb0', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f00', '\x1f01', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1fb6', '\x1fb3', '\x0000', '\x0000'},
+            {'\x1f72', '\x03ad', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f10', '\x1f11', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1f74', '\x03ae', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f20', '\x1f21', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1fc6', '\x1fc3', '\x0000', '\x0000'},
+            {'\x1f76', '\x03af', '\x0000', '\x0000', '\x1fd1', '\x1fd0', '\x0000', '\x03ca', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f30', '\x1f31', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1fd6', '\x0000', '\x0000', '\x0000'},
+            {'\x1f78', '\x03cc', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f40', '\x1f41', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1fe4', '\x1fe5', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1f7a', '\x03cd', '\x0000', '\x0000', '\x1fe1', '\x1fe0', '\x0000', '\x03cb', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f50', '\x1f51', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1fe6', '\x0000', '\x0000', '\x0000'},
+            {'\x1f7c', '\x03ce', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f60', '\x1f61', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1ff6', '\x1ff3', '\x0000', '\x0000'},
+            {'\x1fd2', '\x0390', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1fd7', '\x0000', '\x0000', '\x0000'},
+            {'\x1fe2', '\x03b0', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1fe7', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x03d3', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x03d4', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x04d0', '\x0000', '\x04d2', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0400', '\x0000', '\x0000', '\x0000', '\x0000', '\x04d6', '\x0000', '\x0401', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x04c1', '\x0000', '\x04dc', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x040d', '\x0000', '\x0000', '\x0000', '\x04e2', '\x0419', '\x0000', '\x04e4', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x04ee', '\x040e', '\x0000', '\x04f0', '\x0000', '\x0000', '\x04f2', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x04d1', '\x0000', '\x04d3', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0450', '\x0000', '\x0000', '\x0000', '\x0000', '\x04d7', '\x0000', '\x0451', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x04c2', '\x0000', '\x04dd', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x045d', '\x0000', '\x0000', '\x0000', '\x04e3', '\x0439', '\x0000', '\x04e5', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x04ef', '\x045e', '\x0000', '\x04f1', '\x0000', '\x0000', '\x04f3', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x1eac', '\x0000', '\x0000', '\x1eb6', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x1ead', '\x0000', '\x0000', '\x1eb7', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1f02', '\x1f04', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f06', '\x1f80', '\x0000', '\x0000'},
+            {'\x1f03', '\x1f05', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f07', '\x1f81', '\x0000', '\x0000'},
+            {'\x1f0a', '\x1f0c', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f0e', '\x1f88', '\x0000', '\x0000'},
+            {'\x1f0b', '\x1f0d', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f0f', '\x1f89', '\x0000', '\x0000'},
+            {'\x1f12', '\x1f14', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1f13', '\x1f15', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1f1a', '\x1f1c', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1f1b', '\x1f1d', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1f22', '\x1f24', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f26', '\x1f90', '\x0000', '\x0000'},
+            {'\x1f23', '\x1f25', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f27', '\x1f91', '\x0000', '\x0000'},
+            {'\x1f2a', '\x1f2c', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f2e', '\x1f98', '\x0000', '\x0000'},
+            {'\x1f2b', '\x1f2d', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f2f', '\x1f99', '\x0000', '\x0000'},
+            {'\x1f32', '\x1f34', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f36', '\x0000', '\x0000', '\x0000'},
+            {'\x1f33', '\x1f35', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f37', '\x0000', '\x0000', '\x0000'},
+            {'\x1f3a', '\x1f3c', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f3e', '\x0000', '\x0000', '\x0000'},
+            {'\x1f3b', '\x1f3d', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f3f', '\x0000', '\x0000', '\x0000'},
+            {'\x1f42', '\x1f44', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1f43', '\x1f45', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1f4a', '\x1f4c', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1f4b', '\x1f4d', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000'},
+            {'\x1f52', '\x1f54', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f56', '\x0000', '\x0000', '\x0000'},
+            {'\x1f53', '\x1f55', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f57', '\x0000', '\x0000', '\x0000'},
+            {'\x1f5b', '\x1f5d', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f5f', '\x0000', '\x0000', '\x0000'},
+            {'\x1f62', '\x1f64', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f66', '\x1fa0', '\x0000', '\x0000'},
+            {'\x1f63', '\x1f65', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f67', '\x1fa1', '\x0000', '\x0000'},
+            {'\x1f6a', '\x1f6c', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f6e', '\x1fa8', '\x0000', '\x0000'},
+            {'\x1f6b', '\x1f6d', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1f6f', '\x1fa9', '\x0000', '\x0000'},
+            {'\x1fcd', '\x1fce', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1fcf', '\x0000', '\x0000', '\x0000'},
+            {'\x1fdd', '\x1fde', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x1fdf', '\x0000', '\x0000', '\x0000'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x3070', '\x3071'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x3073', '\x3074'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x3076', '\x3077'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x3079', '\x307a'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x307c', '\x307d'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x30d0', '\x30d1'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x30d3', '\x30d4'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x30d6', '\x30d7'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x30d9', '\x30da'},
+            {'\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x0000', '\x30dc', '\x30dd'}
+        };
+    }
+}
+
diff --git a/lib/jabber-net/stringprep/unicode/Decompose.cs b/lib/jabber-net/stringprep/unicode/Decompose.cs
new file mode 100644
index 0000000..ee22fe5
--- /dev/null
+++ b/lib/jabber-net/stringprep/unicode/Decompose.cs
@@ -0,0 +1,51 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+
+namespace stringprep.unicode
+{
+    /// <summary>
+    /// Decomposition data for NFKC.
+    /// </summary>
+    public class Decompose
+    {
+        private static IComparer s_comparer = new CharArrayComparer();
+
+        /// <summary>
+        /// Look up the expansion, if any, for the given character.
+        /// </summary>
+        /// <param name="ch">The character to find</param>
+        /// <returns>the expansion, or null if none found.</returns>
+        public static string Find(char ch)
+        {
+            int offset = Array.BinarySearch(DecomposeData.Offsets, ch, s_comparer);
+            if (offset < 0)
+                return null;
+
+            return DecomposeData.Expansion[DecomposeData.Offsets[offset][1]];
+        }
+
+        private class CharArrayComparer : IComparer
+        {
+            #region IComparer Members
+            public int Compare(object x, object y)
+            {
+                return ((char[])x)[0].CompareTo(y);
+            }
+            #endregion
+        }
+    }
+}
diff --git a/lib/jabber-net/stringprep/unicode/DecomposeData.cs b/lib/jabber-net/stringprep/unicode/DecomposeData.cs
new file mode 100644
index 0000000..b48cb38
--- /dev/null
+++ b/lib/jabber-net/stringprep/unicode/DecomposeData.cs
@@ -0,0 +1,6470 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+/* This file is automatically generated.  DO NOT EDIT! */
+
+namespace stringprep.unicode
+{
+    /// <summary>
+    /// Decomposition data for NFKC.
+    /// </summary>
+    public class DecomposeData
+    {
+        /// <summary>
+        /// Offset into the Expansion string for each decomposable character.
+        /// One way to make this faster might be to have this not be sparse, so that the lookup
+        /// could be direct rather than a binary search.  That would add several hundred K to the
+        /// library size, though, or time at startup to initialize an array from this.
+        /// </summary>
+        public static readonly char[][] Offsets =  new char[][]
+        {
+            new char[] {'\x00A0', '\x0000'},
+            new char[] {'\x00A8', '\x0001'},
+            new char[] {'\x00AA', '\x0002'},
+            new char[] {'\x00AF', '\x0003'},
+            new char[] {'\x00B2', '\x0004'},
+            new char[] {'\x00B3', '\x0005'},
+            new char[] {'\x00B4', '\x0006'},
+            new char[] {'\x00B5', '\x0007'},
+            new char[] {'\x00B8', '\x0008'},
+            new char[] {'\x00B9', '\x0009'},
+            new char[] {'\x00BA', '\x000A'},
+            new char[] {'\x00BC', '\x000B'},
+            new char[] {'\x00BD', '\x000C'},
+            new char[] {'\x00BE', '\x000D'},
+            new char[] {'\x00C0', '\x000E'},
+            new char[] {'\x00C1', '\x000F'},
+            new char[] {'\x00C2', '\x0010'},
+            new char[] {'\x00C3', '\x0011'},
+            new char[] {'\x00C4', '\x0012'},
+            new char[] {'\x00C5', '\x0013'},
+            new char[] {'\x00C7', '\x0014'},
+            new char[] {'\x00C8', '\x0015'},
+            new char[] {'\x00C9', '\x0016'},
+            new char[] {'\x00CA', '\x0017'},
+            new char[] {'\x00CB', '\x0018'},
+            new char[] {'\x00CC', '\x0019'},
+            new char[] {'\x00CD', '\x001A'},
+            new char[] {'\x00CE', '\x001B'},
+            new char[] {'\x00CF', '\x001C'},
+            new char[] {'\x00D1', '\x001D'},
+            new char[] {'\x00D2', '\x001E'},
+            new char[] {'\x00D3', '\x001F'},
+            new char[] {'\x00D4', '\x0020'},
+            new char[] {'\x00D5', '\x0021'},
+            new char[] {'\x00D6', '\x0022'},
+            new char[] {'\x00D9', '\x0023'},
+            new char[] {'\x00DA', '\x0024'},
+            new char[] {'\x00DB', '\x0025'},
+            new char[] {'\x00DC', '\x0026'},
+            new char[] {'\x00DD', '\x0027'},
+            new char[] {'\x00E0', '\x0028'},
+            new char[] {'\x00E1', '\x0029'},
+            new char[] {'\x00E2', '\x002A'},
+            new char[] {'\x00E3', '\x002B'},
+            new char[] {'\x00E4', '\x002C'},
+            new char[] {'\x00E5', '\x002D'},
+            new char[] {'\x00E7', '\x002E'},
+            new char[] {'\x00E8', '\x002F'},
+            new char[] {'\x00E9', '\x0030'},
+            new char[] {'\x00EA', '\x0031'},
+            new char[] {'\x00EB', '\x0032'},
+            new char[] {'\x00EC', '\x0033'},
+            new char[] {'\x00ED', '\x0034'},
+            new char[] {'\x00EE', '\x0035'},
+            new char[] {'\x00EF', '\x0036'},
+            new char[] {'\x00F1', '\x0037'},
+            new char[] {'\x00F2', '\x0038'},
+            new char[] {'\x00F3', '\x0039'},
+            new char[] {'\x00F4', '\x003A'},
+            new char[] {'\x00F5', '\x003B'},
+            new char[] {'\x00F6', '\x003C'},
+            new char[] {'\x00F9', '\x003D'},
+            new char[] {'\x00FA', '\x003E'},
+            new char[] {'\x00FB', '\x003F'},
+            new char[] {'\x00FC', '\x0040'},
+            new char[] {'\x00FD', '\x0041'},
+            new char[] {'\x00FF', '\x0042'},
+            new char[] {'\x0100', '\x0043'},
+            new char[] {'\x0101', '\x0044'},
+            new char[] {'\x0102', '\x0045'},
+            new char[] {'\x0103', '\x0046'},
+            new char[] {'\x0104', '\x0047'},
+            new char[] {'\x0105', '\x0048'},
+            new char[] {'\x0106', '\x0049'},
+            new char[] {'\x0107', '\x004A'},
+            new char[] {'\x0108', '\x004B'},
+            new char[] {'\x0109', '\x004C'},
+            new char[] {'\x010A', '\x004D'},
+            new char[] {'\x010B', '\x004E'},
+            new char[] {'\x010C', '\x004F'},
+            new char[] {'\x010D', '\x0050'},
+            new char[] {'\x010E', '\x0051'},
+            new char[] {'\x010F', '\x0052'},
+            new char[] {'\x0112', '\x0053'},
+            new char[] {'\x0113', '\x0054'},
+            new char[] {'\x0114', '\x0055'},
+            new char[] {'\x0115', '\x0056'},
+            new char[] {'\x0116', '\x0057'},
+            new char[] {'\x0117', '\x0058'},
+            new char[] {'\x0118', '\x0059'},
+            new char[] {'\x0119', '\x005A'},
+            new char[] {'\x011A', '\x005B'},
+            new char[] {'\x011B', '\x005C'},
+            new char[] {'\x011C', '\x005D'},
+            new char[] {'\x011D', '\x005E'},
+            new char[] {'\x011E', '\x005F'},
+            new char[] {'\x011F', '\x0060'},
+            new char[] {'\x0120', '\x0061'},
+            new char[] {'\x0121', '\x0062'},
+            new char[] {'\x0122', '\x0063'},
+            new char[] {'\x0123', '\x0064'},
+            new char[] {'\x0124', '\x0065'},
+            new char[] {'\x0125', '\x0066'},
+            new char[] {'\x0128', '\x0067'},
+            new char[] {'\x0129', '\x0068'},
+            new char[] {'\x012A', '\x0069'},
+            new char[] {'\x012B', '\x006A'},
+            new char[] {'\x012C', '\x006B'},
+            new char[] {'\x012D', '\x006C'},
+            new char[] {'\x012E', '\x006D'},
+            new char[] {'\x012F', '\x006E'},
+            new char[] {'\x0130', '\x006F'},
+            new char[] {'\x0132', '\x0070'},
+            new char[] {'\x0133', '\x0071'},
+            new char[] {'\x0134', '\x0072'},
+            new char[] {'\x0135', '\x0073'},
+            new char[] {'\x0136', '\x0074'},
+            new char[] {'\x0137', '\x0075'},
+            new char[] {'\x0139', '\x0076'},
+            new char[] {'\x013A', '\x0077'},
+            new char[] {'\x013B', '\x0078'},
+            new char[] {'\x013C', '\x0079'},
+            new char[] {'\x013D', '\x007A'},
+            new char[] {'\x013E', '\x007B'},
+            new char[] {'\x013F', '\x007C'},
+            new char[] {'\x0140', '\x007D'},
+            new char[] {'\x0143', '\x007E'},
+            new char[] {'\x0144', '\x007F'},
+            new char[] {'\x0145', '\x0080'},
+            new char[] {'\x0146', '\x0081'},
+            new char[] {'\x0147', '\x0082'},
+            new char[] {'\x0148', '\x0083'},
+            new char[] {'\x0149', '\x0084'},
+            new char[] {'\x014C', '\x0085'},
+            new char[] {'\x014D', '\x0086'},
+            new char[] {'\x014E', '\x0087'},
+            new char[] {'\x014F', '\x0088'},
+            new char[] {'\x0150', '\x0089'},
+            new char[] {'\x0151', '\x008A'},
+            new char[] {'\x0154', '\x008B'},
+            new char[] {'\x0155', '\x008C'},
+            new char[] {'\x0156', '\x008D'},
+            new char[] {'\x0157', '\x008E'},
+            new char[] {'\x0158', '\x008F'},
+            new char[] {'\x0159', '\x0090'},
+            new char[] {'\x015A', '\x0091'},
+            new char[] {'\x015B', '\x0092'},
+            new char[] {'\x015C', '\x0093'},
+            new char[] {'\x015D', '\x0094'},
+            new char[] {'\x015E', '\x0095'},
+            new char[] {'\x015F', '\x0096'},
+            new char[] {'\x0160', '\x0097'},
+            new char[] {'\x0161', '\x0098'},
+            new char[] {'\x0162', '\x0099'},
+            new char[] {'\x0163', '\x009A'},
+            new char[] {'\x0164', '\x009B'},
+            new char[] {'\x0165', '\x009C'},
+            new char[] {'\x0168', '\x009D'},
+            new char[] {'\x0169', '\x009E'},
+            new char[] {'\x016A', '\x009F'},
+            new char[] {'\x016B', '\x00A0'},
+            new char[] {'\x016C', '\x00A1'},
+            new char[] {'\x016D', '\x00A2'},
+            new char[] {'\x016E', '\x00A3'},
+            new char[] {'\x016F', '\x00A4'},
+            new char[] {'\x0170', '\x00A5'},
+            new char[] {'\x0171', '\x00A6'},
+            new char[] {'\x0172', '\x00A7'},
+            new char[] {'\x0173', '\x00A8'},
+            new char[] {'\x0174', '\x00A9'},
+            new char[] {'\x0175', '\x00AA'},
+            new char[] {'\x0176', '\x00AB'},
+            new char[] {'\x0177', '\x00AC'},
+            new char[] {'\x0178', '\x00AD'},
+            new char[] {'\x0179', '\x00AE'},
+            new char[] {'\x017A', '\x00AF'},
+            new char[] {'\x017B', '\x00B0'},
+            new char[] {'\x017C', '\x00B1'},
+            new char[] {'\x017D', '\x00B2'},
+            new char[] {'\x017E', '\x00B3'},
+            new char[] {'\x017F', '\x00B4'},
+            new char[] {'\x01A0', '\x00B5'},
+            new char[] {'\x01A1', '\x00B6'},
+            new char[] {'\x01AF', '\x00B7'},
+            new char[] {'\x01B0', '\x00B8'},
+            new char[] {'\x01C4', '\x00B9'},
+            new char[] {'\x01C5', '\x00BA'},
+            new char[] {'\x01C6', '\x00BB'},
+            new char[] {'\x01C7', '\x00BC'},
+            new char[] {'\x01C8', '\x00BD'},
+            new char[] {'\x01C9', '\x00BE'},
+            new char[] {'\x01CA', '\x00BF'},
+            new char[] {'\x01CB', '\x00C0'},
+            new char[] {'\x01CC', '\x00C1'},
+            new char[] {'\x01CD', '\x00C2'},
+            new char[] {'\x01CE', '\x00C3'},
+            new char[] {'\x01CF', '\x00C4'},
+            new char[] {'\x01D0', '\x00C5'},
+            new char[] {'\x01D1', '\x00C6'},
+            new char[] {'\x01D2', '\x00C7'},
+            new char[] {'\x01D3', '\x00C8'},
+            new char[] {'\x01D4', '\x00C9'},
+            new char[] {'\x01D5', '\x00CA'},
+            new char[] {'\x01D6', '\x00CB'},
+            new char[] {'\x01D7', '\x00CC'},
+            new char[] {'\x01D8', '\x00CD'},
+            new char[] {'\x01D9', '\x00CE'},
+            new char[] {'\x01DA', '\x00CF'},
+            new char[] {'\x01DB', '\x00D0'},
+            new char[] {'\x01DC', '\x00D1'},
+            new char[] {'\x01DE', '\x00D2'},
+            new char[] {'\x01DF', '\x00D3'},
+            new char[] {'\x01E0', '\x00D4'},
+            new char[] {'\x01E1', '\x00D5'},
+            new char[] {'\x01E2', '\x00D6'},
+            new char[] {'\x01E3', '\x00D7'},
+            new char[] {'\x01E6', '\x00D8'},
+            new char[] {'\x01E7', '\x00D9'},
+            new char[] {'\x01E8', '\x00DA'},
+            new char[] {'\x01E9', '\x00DB'},
+            new char[] {'\x01EA', '\x00DC'},
+            new char[] {'\x01EB', '\x00DD'},
+            new char[] {'\x01EC', '\x00DE'},
+            new char[] {'\x01ED', '\x00DF'},
+            new char[] {'\x01EE', '\x00E0'},
+            new char[] {'\x01EF', '\x00E1'},
+            new char[] {'\x01F0', '\x00E2'},
+            new char[] {'\x01F1', '\x00E3'},
+            new char[] {'\x01F2', '\x00E4'},
+            new char[] {'\x01F3', '\x00E5'},
+            new char[] {'\x01F4', '\x00E6'},
+            new char[] {'\x01F5', '\x00E7'},
+            new char[] {'\x01F8', '\x00E8'},
+            new char[] {'\x01F9', '\x00E9'},
+            new char[] {'\x01FA', '\x00EA'},
+            new char[] {'\x01FB', '\x00EB'},
+            new char[] {'\x01FC', '\x00EC'},
+            new char[] {'\x01FD', '\x00ED'},
+            new char[] {'\x01FE', '\x00EE'},
+            new char[] {'\x01FF', '\x00EF'},
+            new char[] {'\x0200', '\x00F0'},
+            new char[] {'\x0201', '\x00F1'},
+            new char[] {'\x0202', '\x00F2'},
+            new char[] {'\x0203', '\x00F3'},
+            new char[] {'\x0204', '\x00F4'},
+            new char[] {'\x0205', '\x00F5'},
+            new char[] {'\x0206', '\x00F6'},
+            new char[] {'\x0207', '\x00F7'},
+            new char[] {'\x0208', '\x00F8'},
+            new char[] {'\x0209', '\x00F9'},
+            new char[] {'\x020A', '\x00FA'},
+            new char[] {'\x020B', '\x00FB'},
+            new char[] {'\x020C', '\x00FC'},
+            new char[] {'\x020D', '\x00FD'},
+            new char[] {'\x020E', '\x00FE'},
+            new char[] {'\x020F', '\x00FF'},
+            new char[] {'\x0210', '\x0100'},
+            new char[] {'\x0211', '\x0101'},
+            new char[] {'\x0212', '\x0102'},
+            new char[] {'\x0213', '\x0103'},
+            new char[] {'\x0214', '\x0104'},
+            new char[] {'\x0215', '\x0105'},
+            new char[] {'\x0216', '\x0106'},
+            new char[] {'\x0217', '\x0107'},
+            new char[] {'\x0218', '\x0108'},
+            new char[] {'\x0219', '\x0109'},
+            new char[] {'\x021A', '\x010A'},
+            new char[] {'\x021B', '\x010B'},
+            new char[] {'\x021E', '\x010C'},
+            new char[] {'\x021F', '\x010D'},
+            new char[] {'\x0226', '\x010E'},
+            new char[] {'\x0227', '\x010F'},
+            new char[] {'\x0228', '\x0110'},
+            new char[] {'\x0229', '\x0111'},
+            new char[] {'\x022A', '\x0112'},
+            new char[] {'\x022B', '\x0113'},
+            new char[] {'\x022C', '\x0114'},
+            new char[] {'\x022D', '\x0115'},
+            new char[] {'\x022E', '\x0116'},
+            new char[] {'\x022F', '\x0117'},
+            new char[] {'\x0230', '\x0118'},
+            new char[] {'\x0231', '\x0119'},
+            new char[] {'\x0232', '\x011A'},
+            new char[] {'\x0233', '\x011B'},
+            new char[] {'\x02B0', '\x011C'},
+            new char[] {'\x02B1', '\x011D'},
+            new char[] {'\x02B2', '\x011E'},
+            new char[] {'\x02B3', '\x011F'},
+            new char[] {'\x02B4', '\x0120'},
+            new char[] {'\x02B5', '\x0121'},
+            new char[] {'\x02B6', '\x0122'},
+            new char[] {'\x02B7', '\x0123'},
+            new char[] {'\x02B8', '\x0124'},
+            new char[] {'\x02D8', '\x0125'},
+            new char[] {'\x02D9', '\x0126'},
+            new char[] {'\x02DA', '\x0127'},
+            new char[] {'\x02DB', '\x0128'},
+            new char[] {'\x02DC', '\x0129'},
+            new char[] {'\x02DD', '\x012A'},
+            new char[] {'\x02E0', '\x012B'},
+            new char[] {'\x02E1', '\x012C'},
+            new char[] {'\x02E2', '\x00B4'},
+            new char[] {'\x02E3', '\x012D'},
+            new char[] {'\x02E4', '\x012E'},
+            new char[] {'\x0340', '\x012F'},
+            new char[] {'\x0341', '\x0130'},
+            new char[] {'\x0343', '\x0131'},
+            new char[] {'\x0344', '\x0132'},
+            new char[] {'\x0374', '\x0133'},
+            new char[] {'\x037A', '\x0134'},
+            new char[] {'\x037E', '\x0135'},
+            new char[] {'\x0384', '\x0006'},
+            new char[] {'\x0385', '\x0136'},
+            new char[] {'\x0386', '\x0137'},
+            new char[] {'\x0387', '\x0138'},
+            new char[] {'\x0388', '\x0139'},
+            new char[] {'\x0389', '\x013A'},
+            new char[] {'\x038A', '\x013B'},
+            new char[] {'\x038C', '\x013C'},
+            new char[] {'\x038E', '\x013D'},
+            new char[] {'\x038F', '\x013E'},
+            new char[] {'\x0390', '\x013F'},
+            new char[] {'\x03AA', '\x0140'},
+            new char[] {'\x03AB', '\x0141'},
+            new char[] {'\x03AC', '\x0142'},
+            new char[] {'\x03AD', '\x0143'},
+            new char[] {'\x03AE', '\x0144'},
+            new char[] {'\x03AF', '\x0145'},
+            new char[] {'\x03B0', '\x0146'},
+            new char[] {'\x03CA', '\x0147'},
+            new char[] {'\x03CB', '\x0148'},
+            new char[] {'\x03CC', '\x0149'},
+            new char[] {'\x03CD', '\x014A'},
+            new char[] {'\x03CE', '\x014B'},
+            new char[] {'\x03D0', '\x014C'},
+            new char[] {'\x03D1', '\x014D'},
+            new char[] {'\x03D2', '\x014E'},
+            new char[] {'\x03D3', '\x013D'},
+            new char[] {'\x03D4', '\x0141'},
+            new char[] {'\x03D5', '\x014F'},
+            new char[] {'\x03D6', '\x0150'},
+            new char[] {'\x03F0', '\x0151'},
+            new char[] {'\x03F1', '\x0152'},
+            new char[] {'\x03F2', '\x0153'},
+            new char[] {'\x03F4', '\x0154'},
+            new char[] {'\x03F5', '\x0155'},
+            new char[] {'\x0400', '\x0156'},
+            new char[] {'\x0401', '\x0157'},
+            new char[] {'\x0403', '\x0158'},
+            new char[] {'\x0407', '\x0159'},
+            new char[] {'\x040C', '\x015A'},
+            new char[] {'\x040D', '\x015B'},
+            new char[] {'\x040E', '\x015C'},
+            new char[] {'\x0419', '\x015D'},
+            new char[] {'\x0439', '\x015E'},
+            new char[] {'\x0450', '\x015F'},
+            new char[] {'\x0451', '\x0160'},
+            new char[] {'\x0453', '\x0161'},
+            new char[] {'\x0457', '\x0162'},
+            new char[] {'\x045C', '\x0163'},
+            new char[] {'\x045D', '\x0164'},
+            new char[] {'\x045E', '\x0165'},
+            new char[] {'\x0476', '\x0166'},
+            new char[] {'\x0477', '\x0167'},
+            new char[] {'\x04C1', '\x0168'},
+            new char[] {'\x04C2', '\x0169'},
+            new char[] {'\x04D0', '\x016A'},
+            new char[] {'\x04D1', '\x016B'},
+            new char[] {'\x04D2', '\x016C'},
+            new char[] {'\x04D3', '\x016D'},
+            new char[] {'\x04D6', '\x016E'},
+            new char[] {'\x04D7', '\x016F'},
+            new char[] {'\x04DA', '\x0170'},
+            new char[] {'\x04DB', '\x0171'},
+            new char[] {'\x04DC', '\x0172'},
+            new char[] {'\x04DD', '\x0173'},
+            new char[] {'\x04DE', '\x0174'},
+            new char[] {'\x04DF', '\x0175'},
+            new char[] {'\x04E2', '\x0176'},
+            new char[] {'\x04E3', '\x0177'},
+            new char[] {'\x04E4', '\x0178'},
+            new char[] {'\x04E5', '\x0179'},
+            new char[] {'\x04E6', '\x017A'},
+            new char[] {'\x04E7', '\x017B'},
+            new char[] {'\x04EA', '\x017C'},
+            new char[] {'\x04EB', '\x017D'},
+            new char[] {'\x04EC', '\x017E'},
+            new char[] {'\x04ED', '\x017F'},
+            new char[] {'\x04EE', '\x0180'},
+            new char[] {'\x04EF', '\x0181'},
+            new char[] {'\x04F0', '\x0182'},
+            new char[] {'\x04F1', '\x0183'},
+            new char[] {'\x04F2', '\x0184'},
+            new char[] {'\x04F3', '\x0185'},
+            new char[] {'\x04F4', '\x0186'},
+            new char[] {'\x04F5', '\x0187'},
+            new char[] {'\x04F8', '\x0188'},
+            new char[] {'\x04F9', '\x0189'},
+            new char[] {'\x0587', '\x018A'},
+            new char[] {'\x0622', '\x018B'},
+            new char[] {'\x0623', '\x018C'},
+            new char[] {'\x0624', '\x018D'},
+            new char[] {'\x0625', '\x018E'},
+            new char[] {'\x0626', '\x018F'},
+            new char[] {'\x0675', '\x0190'},
+            new char[] {'\x0676', '\x0191'},
+            new char[] {'\x0677', '\x0192'},
+            new char[] {'\x0678', '\x0193'},
+            new char[] {'\x06C0', '\x0194'},
+            new char[] {'\x06C2', '\x0195'},
+            new char[] {'\x06D3', '\x0196'},
+            new char[] {'\x0929', '\x0197'},
+            new char[] {'\x0931', '\x0198'},
+            new char[] {'\x0934', '\x0199'},
+            new char[] {'\x0958', '\x019A'},
+            new char[] {'\x0959', '\x019B'},
+            new char[] {'\x095A', '\x019C'},
+            new char[] {'\x095B', '\x019D'},
+            new char[] {'\x095C', '\x019E'},
+            new char[] {'\x095D', '\x019F'},
+            new char[] {'\x095E', '\x01A0'},
+            new char[] {'\x095F', '\x01A1'},
+            new char[] {'\x09CB', '\x01A2'},
+            new char[] {'\x09CC', '\x01A3'},
+            new char[] {'\x09DC', '\x01A4'},
+            new char[] {'\x09DD', '\x01A5'},
+            new char[] {'\x09DF', '\x01A6'},
+            new char[] {'\x0A33', '\x01A7'},
+            new char[] {'\x0A36', '\x01A8'},
+            new char[] {'\x0A59', '\x01A9'},
+            new char[] {'\x0A5A', '\x01AA'},
+            new char[] {'\x0A5B', '\x01AB'},
+            new char[] {'\x0A5E', '\x01AC'},
+            new char[] {'\x0B48', '\x01AD'},
+            new char[] {'\x0B4B', '\x01AE'},
+            new char[] {'\x0B4C', '\x01AF'},
+            new char[] {'\x0B5C', '\x01B0'},
+            new char[] {'\x0B5D', '\x01B1'},
+            new char[] {'\x0B94', '\x01B2'},
+            new char[] {'\x0BCA', '\x01B3'},
+            new char[] {'\x0BCB', '\x01B4'},
+            new char[] {'\x0BCC', '\x01B5'},
+            new char[] {'\x0C48', '\x01B6'},
+            new char[] {'\x0CC0', '\x01B7'},
+            new char[] {'\x0CC7', '\x01B8'},
+            new char[] {'\x0CC8', '\x01B9'},
+            new char[] {'\x0CCA', '\x01BA'},
+            new char[] {'\x0CCB', '\x01BB'},
+            new char[] {'\x0D4A', '\x01BC'},
+            new char[] {'\x0D4B', '\x01BD'},
+            new char[] {'\x0D4C', '\x01BE'},
+            new char[] {'\x0DDA', '\x01BF'},
+            new char[] {'\x0DDC', '\x01C0'},
+            new char[] {'\x0DDD', '\x01C1'},
+            new char[] {'\x0DDE', '\x01C2'},
+            new char[] {'\x0E33', '\x01C3'},
+            new char[] {'\x0EB3', '\x01C4'},
+            new char[] {'\x0EDC', '\x01C5'},
+            new char[] {'\x0EDD', '\x01C6'},
+            new char[] {'\x0F0C', '\x01C7'},
+            new char[] {'\x0F43', '\x01C8'},
+            new char[] {'\x0F4D', '\x01C9'},
+            new char[] {'\x0F52', '\x01CA'},
+            new char[] {'\x0F57', '\x01CB'},
+            new char[] {'\x0F5C', '\x01CC'},
+            new char[] {'\x0F69', '\x01CD'},
+            new char[] {'\x0F73', '\x01CE'},
+            new char[] {'\x0F75', '\x01CF'},
+            new char[] {'\x0F76', '\x01D0'},
+            new char[] {'\x0F77', '\x01D1'},
+            new char[] {'\x0F78', '\x01D2'},
+            new char[] {'\x0F79', '\x01D3'},
+            new char[] {'\x0F81', '\x01D4'},
+            new char[] {'\x0F93', '\x01D5'},
+            new char[] {'\x0F9D', '\x01D6'},
+            new char[] {'\x0FA2', '\x01D7'},
+            new char[] {'\x0FA7', '\x01D8'},
+            new char[] {'\x0FAC', '\x01D9'},
+            new char[] {'\x0FB9', '\x01DA'},
+            new char[] {'\x1026', '\x01DB'},
+            new char[] {'\x1E00', '\x01DC'},
+            new char[] {'\x1E01', '\x01DD'},
+            new char[] {'\x1E02', '\x01DE'},
+            new char[] {'\x1E03', '\x01DF'},
+            new char[] {'\x1E04', '\x01E0'},
+            new char[] {'\x1E05', '\x01E1'},
+            new char[] {'\x1E06', '\x01E2'},
+            new char[] {'\x1E07', '\x01E3'},
+            new char[] {'\x1E08', '\x01E4'},
+            new char[] {'\x1E09', '\x01E5'},
+            new char[] {'\x1E0A', '\x01E6'},
+            new char[] {'\x1E0B', '\x01E7'},
+            new char[] {'\x1E0C', '\x01E8'},
+            new char[] {'\x1E0D', '\x01E9'},
+            new char[] {'\x1E0E', '\x01EA'},
+            new char[] {'\x1E0F', '\x01EB'},
+            new char[] {'\x1E10', '\x01EC'},
+            new char[] {'\x1E11', '\x01ED'},
+            new char[] {'\x1E12', '\x01EE'},
+            new char[] {'\x1E13', '\x01EF'},
+            new char[] {'\x1E14', '\x01F0'},
+            new char[] {'\x1E15', '\x01F1'},
+            new char[] {'\x1E16', '\x01F2'},
+            new char[] {'\x1E17', '\x01F3'},
+            new char[] {'\x1E18', '\x01F4'},
+            new char[] {'\x1E19', '\x01F5'},
+            new char[] {'\x1E1A', '\x01F6'},
+            new char[] {'\x1E1B', '\x01F7'},
+            new char[] {'\x1E1C', '\x01F8'},
+            new char[] {'\x1E1D', '\x01F9'},
+            new char[] {'\x1E1E', '\x01FA'},
+            new char[] {'\x1E1F', '\x01FB'},
+            new char[] {'\x1E20', '\x01FC'},
+            new char[] {'\x1E21', '\x01FD'},
+            new char[] {'\x1E22', '\x01FE'},
+            new char[] {'\x1E23', '\x01FF'},
+            new char[] {'\x1E24', '\x0200'},
+            new char[] {'\x1E25', '\x0201'},
+            new char[] {'\x1E26', '\x0202'},
+            new char[] {'\x1E27', '\x0203'},
+            new char[] {'\x1E28', '\x0204'},
+            new char[] {'\x1E29', '\x0205'},
+            new char[] {'\x1E2A', '\x0206'},
+            new char[] {'\x1E2B', '\x0207'},
+            new char[] {'\x1E2C', '\x0208'},
+            new char[] {'\x1E2D', '\x0209'},
+            new char[] {'\x1E2E', '\x020A'},
+            new char[] {'\x1E2F', '\x020B'},
+            new char[] {'\x1E30', '\x020C'},
+            new char[] {'\x1E31', '\x020D'},
+            new char[] {'\x1E32', '\x020E'},
+            new char[] {'\x1E33', '\x020F'},
+            new char[] {'\x1E34', '\x0210'},
+            new char[] {'\x1E35', '\x0211'},
+            new char[] {'\x1E36', '\x0212'},
+            new char[] {'\x1E37', '\x0213'},
+            new char[] {'\x1E38', '\x0214'},
+            new char[] {'\x1E39', '\x0215'},
+            new char[] {'\x1E3A', '\x0216'},
+            new char[] {'\x1E3B', '\x0217'},
+            new char[] {'\x1E3C', '\x0218'},
+            new char[] {'\x1E3D', '\x0219'},
+            new char[] {'\x1E3E', '\x021A'},
+            new char[] {'\x1E3F', '\x021B'},
+            new char[] {'\x1E40', '\x021C'},
+            new char[] {'\x1E41', '\x021D'},
+            new char[] {'\x1E42', '\x021E'},
+            new char[] {'\x1E43', '\x021F'},
+            new char[] {'\x1E44', '\x0220'},
+            new char[] {'\x1E45', '\x0221'},
+            new char[] {'\x1E46', '\x0222'},
+            new char[] {'\x1E47', '\x0223'},
+            new char[] {'\x1E48', '\x0224'},
+            new char[] {'\x1E49', '\x0225'},
+            new char[] {'\x1E4A', '\x0226'},
+            new char[] {'\x1E4B', '\x0227'},
+            new char[] {'\x1E4C', '\x0228'},
+            new char[] {'\x1E4D', '\x0229'},
+            new char[] {'\x1E4E', '\x022A'},
+            new char[] {'\x1E4F', '\x022B'},
+            new char[] {'\x1E50', '\x022C'},
+            new char[] {'\x1E51', '\x022D'},
+            new char[] {'\x1E52', '\x022E'},
+            new char[] {'\x1E53', '\x022F'},
+            new char[] {'\x1E54', '\x0230'},
+            new char[] {'\x1E55', '\x0231'},
+            new char[] {'\x1E56', '\x0232'},
+            new char[] {'\x1E57', '\x0233'},
+            new char[] {'\x1E58', '\x0234'},
+            new char[] {'\x1E59', '\x0235'},
+            new char[] {'\x1E5A', '\x0236'},
+            new char[] {'\x1E5B', '\x0237'},
+            new char[] {'\x1E5C', '\x0238'},
+            new char[] {'\x1E5D', '\x0239'},
+            new char[] {'\x1E5E', '\x023A'},
+            new char[] {'\x1E5F', '\x023B'},
+            new char[] {'\x1E60', '\x023C'},
+            new char[] {'\x1E61', '\x023D'},
+            new char[] {'\x1E62', '\x023E'},
+            new char[] {'\x1E63', '\x023F'},
+            new char[] {'\x1E64', '\x0240'},
+            new char[] {'\x1E65', '\x0241'},
+            new char[] {'\x1E66', '\x0242'},
+            new char[] {'\x1E67', '\x0243'},
+            new char[] {'\x1E68', '\x0244'},
+            new char[] {'\x1E69', '\x0245'},
+            new char[] {'\x1E6A', '\x0246'},
+            new char[] {'\x1E6B', '\x0247'},
+            new char[] {'\x1E6C', '\x0248'},
+            new char[] {'\x1E6D', '\x0249'},
+            new char[] {'\x1E6E', '\x024A'},
+            new char[] {'\x1E6F', '\x024B'},
+            new char[] {'\x1E70', '\x024C'},
+            new char[] {'\x1E71', '\x024D'},
+            new char[] {'\x1E72', '\x024E'},
+            new char[] {'\x1E73', '\x024F'},
+            new char[] {'\x1E74', '\x0250'},
+            new char[] {'\x1E75', '\x0251'},
+            new char[] {'\x1E76', '\x0252'},
+            new char[] {'\x1E77', '\x0253'},
+            new char[] {'\x1E78', '\x0254'},
+            new char[] {'\x1E79', '\x0255'},
+            new char[] {'\x1E7A', '\x0256'},
+            new char[] {'\x1E7B', '\x0257'},
+            new char[] {'\x1E7C', '\x0258'},
+            new char[] {'\x1E7D', '\x0259'},
+            new char[] {'\x1E7E', '\x025A'},
+            new char[] {'\x1E7F', '\x025B'},
+            new char[] {'\x1E80', '\x025C'},
+            new char[] {'\x1E81', '\x025D'},
+            new char[] {'\x1E82', '\x025E'},
+            new char[] {'\x1E83', '\x025F'},
+            new char[] {'\x1E84', '\x0260'},
+            new char[] {'\x1E85', '\x0261'},
+            new char[] {'\x1E86', '\x0262'},
+            new char[] {'\x1E87', '\x0263'},
+            new char[] {'\x1E88', '\x0264'},
+            new char[] {'\x1E89', '\x0265'},
+            new char[] {'\x1E8A', '\x0266'},
+            new char[] {'\x1E8B', '\x0267'},
+            new char[] {'\x1E8C', '\x0268'},
+            new char[] {'\x1E8D', '\x0269'},
+            new char[] {'\x1E8E', '\x026A'},
+            new char[] {'\x1E8F', '\x026B'},
+            new char[] {'\x1E90', '\x026C'},
+            new char[] {'\x1E91', '\x026D'},
+            new char[] {'\x1E92', '\x026E'},
+            new char[] {'\x1E93', '\x026F'},
+            new char[] {'\x1E94', '\x0270'},
+            new char[] {'\x1E95', '\x0271'},
+            new char[] {'\x1E96', '\x0272'},
+            new char[] {'\x1E97', '\x0273'},
+            new char[] {'\x1E98', '\x0274'},
+            new char[] {'\x1E99', '\x0275'},
+            new char[] {'\x1E9A', '\x0276'},
+            new char[] {'\x1E9B', '\x023D'},
+            new char[] {'\x1EA0', '\x0277'},
+            new char[] {'\x1EA1', '\x0278'},
+            new char[] {'\x1EA2', '\x0279'},
+            new char[] {'\x1EA3', '\x027A'},
+            new char[] {'\x1EA4', '\x027B'},
+            new char[] {'\x1EA5', '\x027C'},
+            new char[] {'\x1EA6', '\x027D'},
+            new char[] {'\x1EA7', '\x027E'},
+            new char[] {'\x1EA8', '\x027F'},
+            new char[] {'\x1EA9', '\x0280'},
+            new char[] {'\x1EAA', '\x0281'},
+            new char[] {'\x1EAB', '\x0282'},
+            new char[] {'\x1EAC', '\x0283'},
+            new char[] {'\x1EAD', '\x0284'},
+            new char[] {'\x1EAE', '\x0285'},
+            new char[] {'\x1EAF', '\x0286'},
+            new char[] {'\x1EB0', '\x0287'},
+            new char[] {'\x1EB1', '\x0288'},
+            new char[] {'\x1EB2', '\x0289'},
+            new char[] {'\x1EB3', '\x028A'},
+            new char[] {'\x1EB4', '\x028B'},
+            new char[] {'\x1EB5', '\x028C'},
+            new char[] {'\x1EB6', '\x028D'},
+            new char[] {'\x1EB7', '\x028E'},
+            new char[] {'\x1EB8', '\x028F'},
+            new char[] {'\x1EB9', '\x0290'},
+            new char[] {'\x1EBA', '\x0291'},
+            new char[] {'\x1EBB', '\x0292'},
+            new char[] {'\x1EBC', '\x0293'},
+            new char[] {'\x1EBD', '\x0294'},
+            new char[] {'\x1EBE', '\x0295'},
+            new char[] {'\x1EBF', '\x0296'},
+            new char[] {'\x1EC0', '\x0297'},
+            new char[] {'\x1EC1', '\x0298'},
+            new char[] {'\x1EC2', '\x0299'},
+            new char[] {'\x1EC3', '\x029A'},
+            new char[] {'\x1EC4', '\x029B'},
+            new char[] {'\x1EC5', '\x029C'},
+            new char[] {'\x1EC6', '\x029D'},
+            new char[] {'\x1EC7', '\x029E'},
+            new char[] {'\x1EC8', '\x029F'},
+            new char[] {'\x1EC9', '\x02A0'},
+            new char[] {'\x1ECA', '\x02A1'},
+            new char[] {'\x1ECB', '\x02A2'},
+            new char[] {'\x1ECC', '\x02A3'},
+            new char[] {'\x1ECD', '\x02A4'},
+            new char[] {'\x1ECE', '\x02A5'},
+            new char[] {'\x1ECF', '\x02A6'},
+            new char[] {'\x1ED0', '\x02A7'},
+            new char[] {'\x1ED1', '\x02A8'},
+            new char[] {'\x1ED2', '\x02A9'},
+            new char[] {'\x1ED3', '\x02AA'},
+            new char[] {'\x1ED4', '\x02AB'},
+            new char[] {'\x1ED5', '\x02AC'},
+            new char[] {'\x1ED6', '\x02AD'},
+            new char[] {'\x1ED7', '\x02AE'},
+            new char[] {'\x1ED8', '\x02AF'},
+            new char[] {'\x1ED9', '\x02B0'},
+            new char[] {'\x1EDA', '\x02B1'},
+            new char[] {'\x1EDB', '\x02B2'},
+            new char[] {'\x1EDC', '\x02B3'},
+            new char[] {'\x1EDD', '\x02B4'},
+            new char[] {'\x1EDE', '\x02B5'},
+            new char[] {'\x1EDF', '\x02B6'},
+            new char[] {'\x1EE0', '\x02B7'},
+            new char[] {'\x1EE1', '\x02B8'},
+            new char[] {'\x1EE2', '\x02B9'},
+            new char[] {'\x1EE3', '\x02BA'},
+            new char[] {'\x1EE4', '\x02BB'},
+            new char[] {'\x1EE5', '\x02BC'},
+            new char[] {'\x1EE6', '\x02BD'},
+            new char[] {'\x1EE7', '\x02BE'},
+            new char[] {'\x1EE8', '\x02BF'},
+            new char[] {'\x1EE9', '\x02C0'},
+            new char[] {'\x1EEA', '\x02C1'},
+            new char[] {'\x1EEB', '\x02C2'},
+            new char[] {'\x1EEC', '\x02C3'},
+            new char[] {'\x1EED', '\x02C4'},
+            new char[] {'\x1EEE', '\x02C5'},
+            new char[] {'\x1EEF', '\x02C6'},
+            new char[] {'\x1EF0', '\x02C7'},
+            new char[] {'\x1EF1', '\x02C8'},
+            new char[] {'\x1EF2', '\x02C9'},
+            new char[] {'\x1EF3', '\x02CA'},
+            new char[] {'\x1EF4', '\x02CB'},
+            new char[] {'\x1EF5', '\x02CC'},
+            new char[] {'\x1EF6', '\x02CD'},
+            new char[] {'\x1EF7', '\x02CE'},
+            new char[] {'\x1EF8', '\x02CF'},
+            new char[] {'\x1EF9', '\x02D0'},
+            new char[] {'\x1F00', '\x02D1'},
+            new char[] {'\x1F01', '\x02D2'},
+            new char[] {'\x1F02', '\x02D3'},
+            new char[] {'\x1F03', '\x02D4'},
+            new char[] {'\x1F04', '\x02D5'},
+            new char[] {'\x1F05', '\x02D6'},
+            new char[] {'\x1F06', '\x02D7'},
+            new char[] {'\x1F07', '\x02D8'},
+            new char[] {'\x1F08', '\x02D9'},
+            new char[] {'\x1F09', '\x02DA'},
+            new char[] {'\x1F0A', '\x02DB'},
+            new char[] {'\x1F0B', '\x02DC'},
+            new char[] {'\x1F0C', '\x02DD'},
+            new char[] {'\x1F0D', '\x02DE'},
+            new char[] {'\x1F0E', '\x02DF'},
+            new char[] {'\x1F0F', '\x02E0'},
+            new char[] {'\x1F10', '\x02E1'},
+            new char[] {'\x1F11', '\x02E2'},
+            new char[] {'\x1F12', '\x02E3'},
+            new char[] {'\x1F13', '\x02E4'},
+            new char[] {'\x1F14', '\x02E5'},
+            new char[] {'\x1F15', '\x02E6'},
+            new char[] {'\x1F18', '\x02E7'},
+            new char[] {'\x1F19', '\x02E8'},
+            new char[] {'\x1F1A', '\x02E9'},
+            new char[] {'\x1F1B', '\x02EA'},
+            new char[] {'\x1F1C', '\x02EB'},
+            new char[] {'\x1F1D', '\x02EC'},
+            new char[] {'\x1F20', '\x02ED'},
+            new char[] {'\x1F21', '\x02EE'},
+            new char[] {'\x1F22', '\x02EF'},
+            new char[] {'\x1F23', '\x02F0'},
+            new char[] {'\x1F24', '\x02F1'},
+            new char[] {'\x1F25', '\x02F2'},
+            new char[] {'\x1F26', '\x02F3'},
+            new char[] {'\x1F27', '\x02F4'},
+            new char[] {'\x1F28', '\x02F5'},
+            new char[] {'\x1F29', '\x02F6'},
+            new char[] {'\x1F2A', '\x02F7'},
+            new char[] {'\x1F2B', '\x02F8'},
+            new char[] {'\x1F2C', '\x02F9'},
+            new char[] {'\x1F2D', '\x02FA'},
+            new char[] {'\x1F2E', '\x02FB'},
+            new char[] {'\x1F2F', '\x02FC'},
+            new char[] {'\x1F30', '\x02FD'},
+            new char[] {'\x1F31', '\x02FE'},
+            new char[] {'\x1F32', '\x02FF'},
+            new char[] {'\x1F33', '\x0300'},
+            new char[] {'\x1F34', '\x0301'},
+            new char[] {'\x1F35', '\x0302'},
+            new char[] {'\x1F36', '\x0303'},
+            new char[] {'\x1F37', '\x0304'},
+            new char[] {'\x1F38', '\x0305'},
+            new char[] {'\x1F39', '\x0306'},
+            new char[] {'\x1F3A', '\x0307'},
+            new char[] {'\x1F3B', '\x0308'},
+            new char[] {'\x1F3C', '\x0309'},
+            new char[] {'\x1F3D', '\x030A'},
+            new char[] {'\x1F3E', '\x030B'},
+            new char[] {'\x1F3F', '\x030C'},
+            new char[] {'\x1F40', '\x030D'},
+            new char[] {'\x1F41', '\x030E'},
+            new char[] {'\x1F42', '\x030F'},
+            new char[] {'\x1F43', '\x0310'},
+            new char[] {'\x1F44', '\x0311'},
+            new char[] {'\x1F45', '\x0312'},
+            new char[] {'\x1F48', '\x0313'},
+            new char[] {'\x1F49', '\x0314'},
+            new char[] {'\x1F4A', '\x0315'},
+            new char[] {'\x1F4B', '\x0316'},
+            new char[] {'\x1F4C', '\x0317'},
+            new char[] {'\x1F4D', '\x0318'},
+            new char[] {'\x1F50', '\x0319'},
+            new char[] {'\x1F51', '\x031A'},
+            new char[] {'\x1F52', '\x031B'},
+            new char[] {'\x1F53', '\x031C'},
+            new char[] {'\x1F54', '\x031D'},
+            new char[] {'\x1F55', '\x031E'},
+            new char[] {'\x1F56', '\x031F'},
+            new char[] {'\x1F57', '\x0320'},
+            new char[] {'\x1F59', '\x0321'},
+            new char[] {'\x1F5B', '\x0322'},
+            new char[] {'\x1F5D', '\x0323'},
+            new char[] {'\x1F5F', '\x0324'},
+            new char[] {'\x1F60', '\x0325'},
+            new char[] {'\x1F61', '\x0326'},
+            new char[] {'\x1F62', '\x0327'},
+            new char[] {'\x1F63', '\x0328'},
+            new char[] {'\x1F64', '\x0329'},
+            new char[] {'\x1F65', '\x032A'},
+            new char[] {'\x1F66', '\x032B'},
+            new char[] {'\x1F67', '\x032C'},
+            new char[] {'\x1F68', '\x032D'},
+            new char[] {'\x1F69', '\x032E'},
+            new char[] {'\x1F6A', '\x032F'},
+            new char[] {'\x1F6B', '\x0330'},
+            new char[] {'\x1F6C', '\x0331'},
+            new char[] {'\x1F6D', '\x0332'},
+            new char[] {'\x1F6E', '\x0333'},
+            new char[] {'\x1F6F', '\x0334'},
+            new char[] {'\x1F70', '\x0335'},
+            new char[] {'\x1F71', '\x0142'},
+            new char[] {'\x1F72', '\x0336'},
+            new char[] {'\x1F73', '\x0143'},
+            new char[] {'\x1F74', '\x0337'},
+            new char[] {'\x1F75', '\x0144'},
+            new char[] {'\x1F76', '\x0338'},
+            new char[] {'\x1F77', '\x0145'},
+            new char[] {'\x1F78', '\x0339'},
+            new char[] {'\x1F79', '\x0149'},
+            new char[] {'\x1F7A', '\x033A'},
+            new char[] {'\x1F7B', '\x014A'},
+            new char[] {'\x1F7C', '\x033B'},
+            new char[] {'\x1F7D', '\x014B'},
+            new char[] {'\x1F80', '\x033C'},
+            new char[] {'\x1F81', '\x033D'},
+            new char[] {'\x1F82', '\x033E'},
+            new char[] {'\x1F83', '\x033F'},
+            new char[] {'\x1F84', '\x0340'},
+            new char[] {'\x1F85', '\x0341'},
+            new char[] {'\x1F86', '\x0342'},
+            new char[] {'\x1F87', '\x0343'},
+            new char[] {'\x1F88', '\x0344'},
+            new char[] {'\x1F89', '\x0345'},
+            new char[] {'\x1F8A', '\x0346'},
+            new char[] {'\x1F8B', '\x0347'},
+            new char[] {'\x1F8C', '\x0348'},
+            new char[] {'\x1F8D', '\x0349'},
+            new char[] {'\x1F8E', '\x034A'},
+            new char[] {'\x1F8F', '\x034B'},
+            new char[] {'\x1F90', '\x034C'},
+            new char[] {'\x1F91', '\x034D'},
+            new char[] {'\x1F92', '\x034E'},
+            new char[] {'\x1F93', '\x034F'},
+            new char[] {'\x1F94', '\x0350'},
+            new char[] {'\x1F95', '\x0351'},
+            new char[] {'\x1F96', '\x0352'},
+            new char[] {'\x1F97', '\x0353'},
+            new char[] {'\x1F98', '\x0354'},
+            new char[] {'\x1F99', '\x0355'},
+            new char[] {'\x1F9A', '\x0356'},
+            new char[] {'\x1F9B', '\x0357'},
+            new char[] {'\x1F9C', '\x0358'},
+            new char[] {'\x1F9D', '\x0359'},
+            new char[] {'\x1F9E', '\x035A'},
+            new char[] {'\x1F9F', '\x035B'},
+            new char[] {'\x1FA0', '\x035C'},
+            new char[] {'\x1FA1', '\x035D'},
+            new char[] {'\x1FA2', '\x035E'},
+            new char[] {'\x1FA3', '\x035F'},
+            new char[] {'\x1FA4', '\x0360'},
+            new char[] {'\x1FA5', '\x0361'},
+            new char[] {'\x1FA6', '\x0362'},
+            new char[] {'\x1FA7', '\x0363'},
+            new char[] {'\x1FA8', '\x0364'},
+            new char[] {'\x1FA9', '\x0365'},
+            new char[] {'\x1FAA', '\x0366'},
+            new char[] {'\x1FAB', '\x0367'},
+            new char[] {'\x1FAC', '\x0368'},
+            new char[] {'\x1FAD', '\x0369'},
+            new char[] {'\x1FAE', '\x036A'},
+            new char[] {'\x1FAF', '\x036B'},
+            new char[] {'\x1FB0', '\x036C'},
+            new char[] {'\x1FB1', '\x036D'},
+            new char[] {'\x1FB2', '\x036E'},
+            new char[] {'\x1FB3', '\x036F'},
+            new char[] {'\x1FB4', '\x0370'},
+            new char[] {'\x1FB6', '\x0371'},
+            new char[] {'\x1FB7', '\x0372'},
+            new char[] {'\x1FB8', '\x0373'},
+            new char[] {'\x1FB9', '\x0374'},
+            new char[] {'\x1FBA', '\x0375'},
+            new char[] {'\x1FBB', '\x0137'},
+            new char[] {'\x1FBC', '\x0376'},
+            new char[] {'\x1FBD', '\x0377'},
+            new char[] {'\x1FBE', '\x0378'},
+            new char[] {'\x1FBF', '\x0377'},
+            new char[] {'\x1FC0', '\x0379'},
+            new char[] {'\x1FC1', '\x037A'},
+            new char[] {'\x1FC2', '\x037B'},
+            new char[] {'\x1FC3', '\x037C'},
+            new char[] {'\x1FC4', '\x037D'},
+            new char[] {'\x1FC6', '\x037E'},
+            new char[] {'\x1FC7', '\x037F'},
+            new char[] {'\x1FC8', '\x0380'},
+            new char[] {'\x1FC9', '\x0139'},
+            new char[] {'\x1FCA', '\x0381'},
+            new char[] {'\x1FCB', '\x013A'},
+            new char[] {'\x1FCC', '\x0382'},
+            new char[] {'\x1FCD', '\x0383'},
+            new char[] {'\x1FCE', '\x0384'},
+            new char[] {'\x1FCF', '\x0385'},
+            new char[] {'\x1FD0', '\x0386'},
+            new char[] {'\x1FD1', '\x0387'},
+            new char[] {'\x1FD2', '\x0388'},
+            new char[] {'\x1FD3', '\x013F'},
+            new char[] {'\x1FD6', '\x0389'},
+            new char[] {'\x1FD7', '\x038A'},
+            new char[] {'\x1FD8', '\x038B'},
+            new char[] {'\x1FD9', '\x038C'},
+            new char[] {'\x1FDA', '\x038D'},
+            new char[] {'\x1FDB', '\x013B'},
+            new char[] {'\x1FDD', '\x038E'},
+            new char[] {'\x1FDE', '\x038F'},
+            new char[] {'\x1FDF', '\x0390'},
+            new char[] {'\x1FE0', '\x0391'},
+            new char[] {'\x1FE1', '\x0392'},
+            new char[] {'\x1FE2', '\x0393'},
+            new char[] {'\x1FE3', '\x0146'},
+            new char[] {'\x1FE4', '\x0394'},
+            new char[] {'\x1FE5', '\x0395'},
+            new char[] {'\x1FE6', '\x0396'},
+            new char[] {'\x1FE7', '\x0397'},
+            new char[] {'\x1FE8', '\x0398'},
+            new char[] {'\x1FE9', '\x0399'},
+            new char[] {'\x1FEA', '\x039A'},
+            new char[] {'\x1FEB', '\x013D'},
+            new char[] {'\x1FEC', '\x039B'},
+            new char[] {'\x1FED', '\x039C'},
+            new char[] {'\x1FEE', '\x0136'},
+            new char[] {'\x1FEF', '\x039D'},
+            new char[] {'\x1FF2', '\x039E'},
+            new char[] {'\x1FF3', '\x039F'},
+            new char[] {'\x1FF4', '\x03A0'},
+            new char[] {'\x1FF6', '\x03A1'},
+            new char[] {'\x1FF7', '\x03A2'},
+            new char[] {'\x1FF8', '\x03A3'},
+            new char[] {'\x1FF9', '\x013C'},
+            new char[] {'\x1FFA', '\x03A4'},
+            new char[] {'\x1FFB', '\x013E'},
+            new char[] {'\x1FFC', '\x03A5'},
+            new char[] {'\x1FFD', '\x0006'},
+            new char[] {'\x1FFE', '\x03A6'},
+            new char[] {'\x2000', '\x0000'},
+            new char[] {'\x2001', '\x0000'},
+            new char[] {'\x2002', '\x0000'},
+            new char[] {'\x2003', '\x0000'},
+            new char[] {'\x2004', '\x0000'},
+            new char[] {'\x2005', '\x0000'},
+            new char[] {'\x2006', '\x0000'},
+            new char[] {'\x2007', '\x0000'},
+            new char[] {'\x2008', '\x0000'},
+            new char[] {'\x2009', '\x0000'},
+            new char[] {'\x200A', '\x0000'},
+            new char[] {'\x2011', '\x03A7'},
+            new char[] {'\x2017', '\x03A8'},
+            new char[] {'\x2024', '\x03A9'},
+            new char[] {'\x2025', '\x03AA'},
+            new char[] {'\x2026', '\x03AB'},
+            new char[] {'\x202F', '\x0000'},
+            new char[] {'\x2033', '\x03AC'},
+            new char[] {'\x2034', '\x03AD'},
+            new char[] {'\x2036', '\x03AE'},
+            new char[] {'\x2037', '\x03AF'},
+            new char[] {'\x203C', '\x03B0'},
+            new char[] {'\x203E', '\x03B1'},
+            new char[] {'\x2047', '\x03B2'},
+            new char[] {'\x2048', '\x03B3'},
+            new char[] {'\x2049', '\x03B4'},
+            new char[] {'\x2057', '\x03B5'},
+            new char[] {'\x205F', '\x0000'},
+            new char[] {'\x2070', '\x03B6'},
+            new char[] {'\x2071', '\x03B7'},
+            new char[] {'\x2074', '\x03B8'},
+            new char[] {'\x2075', '\x03B9'},
+            new char[] {'\x2076', '\x03BA'},
+            new char[] {'\x2077', '\x03BB'},
+            new char[] {'\x2078', '\x03BC'},
+            new char[] {'\x2079', '\x03BD'},
+            new char[] {'\x207A', '\x03BE'},
+            new char[] {'\x207B', '\x03BF'},
+            new char[] {'\x207C', '\x03C0'},
+            new char[] {'\x207D', '\x03C1'},
+            new char[] {'\x207E', '\x03C2'},
+            new char[] {'\x207F', '\x03C3'},
+            new char[] {'\x2080', '\x03B6'},
+            new char[] {'\x2081', '\x0009'},
+            new char[] {'\x2082', '\x0004'},
+            new char[] {'\x2083', '\x0005'},
+            new char[] {'\x2084', '\x03B8'},
+            new char[] {'\x2085', '\x03B9'},
+            new char[] {'\x2086', '\x03BA'},
+            new char[] {'\x2087', '\x03BB'},
+            new char[] {'\x2088', '\x03BC'},
+            new char[] {'\x2089', '\x03BD'},
+            new char[] {'\x208A', '\x03BE'},
+            new char[] {'\x208B', '\x03BF'},
+            new char[] {'\x208C', '\x03C0'},
+            new char[] {'\x208D', '\x03C1'},
+            new char[] {'\x208E', '\x03C2'},
+            new char[] {'\x20A8', '\x03C4'},
+            new char[] {'\x2100', '\x03C5'},
+            new char[] {'\x2101', '\x03C6'},
+            new char[] {'\x2102', '\x03C7'},
+            new char[] {'\x2103', '\x03C8'},
+            new char[] {'\x2105', '\x03C9'},
+            new char[] {'\x2106', '\x03CA'},
+            new char[] {'\x2107', '\x03CB'},
+            new char[] {'\x2109', '\x03CC'},
+            new char[] {'\x210A', '\x03CD'},
+            new char[] {'\x210B', '\x03CE'},
+            new char[] {'\x210C', '\x03CE'},
+            new char[] {'\x210D', '\x03CE'},
+            new char[] {'\x210E', '\x011C'},
+            new char[] {'\x210F', '\x03CF'},
+            new char[] {'\x2110', '\x03D0'},
+            new char[] {'\x2111', '\x03D0'},
+            new char[] {'\x2112', '\x03D1'},
+            new char[] {'\x2113', '\x012C'},
+            new char[] {'\x2115', '\x03D2'},
+            new char[] {'\x2116', '\x03D3'},
+            new char[] {'\x2119', '\x03D4'},
+            new char[] {'\x211A', '\x03D5'},
+            new char[] {'\x211B', '\x03D6'},
+            new char[] {'\x211C', '\x03D6'},
+            new char[] {'\x211D', '\x03D6'},
+            new char[] {'\x2120', '\x03D7'},
+            new char[] {'\x2121', '\x03D8'},
+            new char[] {'\x2122', '\x03D9'},
+            new char[] {'\x2124', '\x03DA'},
+            new char[] {'\x2126', '\x03DB'},
+            new char[] {'\x2128', '\x03DA'},
+            new char[] {'\x212A', '\x03DC'},
+            new char[] {'\x212B', '\x0013'},
+            new char[] {'\x212C', '\x03DD'},
+            new char[] {'\x212D', '\x03C7'},
+            new char[] {'\x212F', '\x03DE'},
+            new char[] {'\x2130', '\x03DF'},
+            new char[] {'\x2131', '\x03E0'},
+            new char[] {'\x2133', '\x03E1'},
+            new char[] {'\x2134', '\x000A'},
+            new char[] {'\x2135', '\x03E2'},
+            new char[] {'\x2136', '\x03E3'},
+            new char[] {'\x2137', '\x03E4'},
+            new char[] {'\x2138', '\x03E5'},
+            new char[] {'\x2139', '\x03B7'},
+            new char[] {'\x213D', '\x03E6'},
+            new char[] {'\x213E', '\x03E7'},
+            new char[] {'\x213F', '\x03E8'},
+            new char[] {'\x2140', '\x03E9'},
+            new char[] {'\x2145', '\x03EA'},
+            new char[] {'\x2146', '\x03EB'},
+            new char[] {'\x2147', '\x03DE'},
+            new char[] {'\x2148', '\x03B7'},
+            new char[] {'\x2149', '\x011E'},
+            new char[] {'\x2153', '\x03EC'},
+            new char[] {'\x2154', '\x03ED'},
+            new char[] {'\x2155', '\x03EE'},
+            new char[] {'\x2156', '\x03EF'},
+            new char[] {'\x2157', '\x03F0'},
+            new char[] {'\x2158', '\x03F1'},
+            new char[] {'\x2159', '\x03F2'},
+            new char[] {'\x215A', '\x03F3'},
+            new char[] {'\x215B', '\x03F4'},
+            new char[] {'\x215C', '\x03F5'},
+            new char[] {'\x215D', '\x03F6'},
+            new char[] {'\x215E', '\x03F7'},
+            new char[] {'\x215F', '\x03F8'},
+            new char[] {'\x2160', '\x03D0'},
+            new char[] {'\x2161', '\x03F9'},
+            new char[] {'\x2162', '\x03FA'},
+            new char[] {'\x2163', '\x03FB'},
+            new char[] {'\x2164', '\x03FC'},
+            new char[] {'\x2165', '\x03FD'},
+            new char[] {'\x2166', '\x03FE'},
+            new char[] {'\x2167', '\x03FF'},
+            new char[] {'\x2168', '\x0400'},
+            new char[] {'\x2169', '\x0401'},
+            new char[] {'\x216A', '\x0402'},
+            new char[] {'\x216B', '\x0403'},
+            new char[] {'\x216C', '\x03D1'},
+            new char[] {'\x216D', '\x03C7'},
+            new char[] {'\x216E', '\x03EA'},
+            new char[] {'\x216F', '\x03E1'},
+            new char[] {'\x2170', '\x03B7'},
+            new char[] {'\x2171', '\x0404'},
+            new char[] {'\x2172', '\x0405'},
+            new char[] {'\x2173', '\x0406'},
+            new char[] {'\x2174', '\x0407'},
+            new char[] {'\x2175', '\x0408'},
+            new char[] {'\x2176', '\x0409'},
+            new char[] {'\x2177', '\x040A'},
+            new char[] {'\x2178', '\x040B'},
+            new char[] {'\x2179', '\x012D'},
+            new char[] {'\x217A', '\x040C'},
+            new char[] {'\x217B', '\x040D'},
+            new char[] {'\x217C', '\x012C'},
+            new char[] {'\x217D', '\x040E'},
+            new char[] {'\x217E', '\x03EB'},
+            new char[] {'\x217F', '\x040F'},
+            new char[] {'\x219A', '\x0410'},
+            new char[] {'\x219B', '\x0411'},
+            new char[] {'\x21AE', '\x0412'},
+            new char[] {'\x21CD', '\x0413'},
+            new char[] {'\x21CE', '\x0414'},
+            new char[] {'\x21CF', '\x0415'},
+            new char[] {'\x2204', '\x0416'},
+            new char[] {'\x2209', '\x0417'},
+            new char[] {'\x220C', '\x0418'},
+            new char[] {'\x2224', '\x0419'},
+            new char[] {'\x2226', '\x041A'},
+            new char[] {'\x222C', '\x041B'},
+            new char[] {'\x222D', '\x041C'},
+            new char[] {'\x222F', '\x041D'},
+            new char[] {'\x2230', '\x041E'},
+            new char[] {'\x2241', '\x041F'},
+            new char[] {'\x2244', '\x0420'},
+            new char[] {'\x2247', '\x0421'},
+            new char[] {'\x2249', '\x0422'},
+            new char[] {'\x2260', '\x0423'},
+            new char[] {'\x2262', '\x0424'},
+            new char[] {'\x226D', '\x0425'},
+            new char[] {'\x226E', '\x0426'},
+            new char[] {'\x226F', '\x0427'},
+            new char[] {'\x2270', '\x0428'},
+            new char[] {'\x2271', '\x0429'},
+            new char[] {'\x2274', '\x042A'},
+            new char[] {'\x2275', '\x042B'},
+            new char[] {'\x2278', '\x042C'},
+            new char[] {'\x2279', '\x042D'},
+            new char[] {'\x2280', '\x042E'},
+            new char[] {'\x2281', '\x042F'},
+            new char[] {'\x2284', '\x0430'},
+            new char[] {'\x2285', '\x0431'},
+            new char[] {'\x2288', '\x0432'},
+            new char[] {'\x2289', '\x0433'},
+            new char[] {'\x22AC', '\x0434'},
+            new char[] {'\x22AD', '\x0435'},
+            new char[] {'\x22AE', '\x0436'},
+            new char[] {'\x22AF', '\x0437'},
+            new char[] {'\x22E0', '\x0438'},
+            new char[] {'\x22E1', '\x0439'},
+            new char[] {'\x22E2', '\x043A'},
+            new char[] {'\x22E3', '\x043B'},
+            new char[] {'\x22EA', '\x043C'},
+            new char[] {'\x22EB', '\x043D'},
+            new char[] {'\x22EC', '\x043E'},
+            new char[] {'\x22ED', '\x043F'},
+            new char[] {'\x2329', '\x0440'},
+            new char[] {'\x232A', '\x0441'},
+            new char[] {'\x2460', '\x0009'},
+            new char[] {'\x2461', '\x0004'},
+            new char[] {'\x2462', '\x0005'},
+            new char[] {'\x2463', '\x03B8'},
+            new char[] {'\x2464', '\x03B9'},
+            new char[] {'\x2465', '\x03BA'},
+            new char[] {'\x2466', '\x03BB'},
+            new char[] {'\x2467', '\x03BC'},
+            new char[] {'\x2468', '\x03BD'},
+            new char[] {'\x2469', '\x0442'},
+            new char[] {'\x246A', '\x0443'},
+            new char[] {'\x246B', '\x0444'},
+            new char[] {'\x246C', '\x0445'},
+            new char[] {'\x246D', '\x0446'},
+            new char[] {'\x246E', '\x0447'},
+            new char[] {'\x246F', '\x0448'},
+            new char[] {'\x2470', '\x0449'},
+            new char[] {'\x2471', '\x044A'},
+            new char[] {'\x2472', '\x044B'},
+            new char[] {'\x2473', '\x044C'},
+            new char[] {'\x2474', '\x044D'},
+            new char[] {'\x2475', '\x044E'},
+            new char[] {'\x2476', '\x044F'},
+            new char[] {'\x2477', '\x0450'},
+            new char[] {'\x2478', '\x0451'},
+            new char[] {'\x2479', '\x0452'},
+            new char[] {'\x247A', '\x0453'},
+            new char[] {'\x247B', '\x0454'},
+            new char[] {'\x247C', '\x0455'},
+            new char[] {'\x247D', '\x0456'},
+            new char[] {'\x247E', '\x0457'},
+            new char[] {'\x247F', '\x0458'},
+            new char[] {'\x2480', '\x0459'},
+            new char[] {'\x2481', '\x045A'},
+            new char[] {'\x2482', '\x045B'},
+            new char[] {'\x2483', '\x045C'},
+            new char[] {'\x2484', '\x045D'},
+            new char[] {'\x2485', '\x045E'},
+            new char[] {'\x2486', '\x045F'},
+            new char[] {'\x2487', '\x0460'},
+            new char[] {'\x2488', '\x0461'},
+            new char[] {'\x2489', '\x0462'},
+            new char[] {'\x248A', '\x0463'},
+            new char[] {'\x248B', '\x0464'},
+            new char[] {'\x248C', '\x0465'},
+            new char[] {'\x248D', '\x0466'},
+            new char[] {'\x248E', '\x0467'},
+            new char[] {'\x248F', '\x0468'},
+            new char[] {'\x2490', '\x0469'},
+            new char[] {'\x2491', '\x046A'},
+            new char[] {'\x2492', '\x046B'},
+            new char[] {'\x2493', '\x046C'},
+            new char[] {'\x2494', '\x046D'},
+            new char[] {'\x2495', '\x046E'},
+            new char[] {'\x2496', '\x046F'},
+            new char[] {'\x2497', '\x0470'},
+            new char[] {'\x2498', '\x0471'},
+            new char[] {'\x2499', '\x0472'},
+            new char[] {'\x249A', '\x0473'},
+            new char[] {'\x249B', '\x0474'},
+            new char[] {'\x249C', '\x0475'},
+            new char[] {'\x249D', '\x0476'},
+            new char[] {'\x249E', '\x0477'},
+            new char[] {'\x249F', '\x0478'},
+            new char[] {'\x24A0', '\x0479'},
+            new char[] {'\x24A1', '\x047A'},
+            new char[] {'\x24A2', '\x047B'},
+            new char[] {'\x24A3', '\x047C'},
+            new char[] {'\x24A4', '\x047D'},
+            new char[] {'\x24A5', '\x047E'},
+            new char[] {'\x24A6', '\x047F'},
+            new char[] {'\x24A7', '\x0480'},
+            new char[] {'\x24A8', '\x0481'},
+            new char[] {'\x24A9', '\x0482'},
+            new char[] {'\x24AA', '\x0483'},
+            new char[] {'\x24AB', '\x0484'},
+            new char[] {'\x24AC', '\x0485'},
+            new char[] {'\x24AD', '\x0486'},
+            new char[] {'\x24AE', '\x0487'},
+            new char[] {'\x24AF', '\x0488'},
+            new char[] {'\x24B0', '\x0489'},
+            new char[] {'\x24B1', '\x048A'},
+            new char[] {'\x24B2', '\x048B'},
+            new char[] {'\x24B3', '\x048C'},
+            new char[] {'\x24B4', '\x048D'},
+            new char[] {'\x24B5', '\x048E'},
+            new char[] {'\x24B6', '\x048F'},
+            new char[] {'\x24B7', '\x03DD'},
+            new char[] {'\x24B8', '\x03C7'},
+            new char[] {'\x24B9', '\x03EA'},
+            new char[] {'\x24BA', '\x03DF'},
+            new char[] {'\x24BB', '\x03E0'},
+            new char[] {'\x24BC', '\x0490'},
+            new char[] {'\x24BD', '\x03CE'},
+            new char[] {'\x24BE', '\x03D0'},
+            new char[] {'\x24BF', '\x0491'},
+            new char[] {'\x24C0', '\x03DC'},
+            new char[] {'\x24C1', '\x03D1'},
+            new char[] {'\x24C2', '\x03E1'},
+            new char[] {'\x24C3', '\x03D2'},
+            new char[] {'\x24C4', '\x0492'},
+            new char[] {'\x24C5', '\x03D4'},
+            new char[] {'\x24C6', '\x03D5'},
+            new char[] {'\x24C7', '\x03D6'},
+            new char[] {'\x24C8', '\x0493'},
+            new char[] {'\x24C9', '\x0494'},
+            new char[] {'\x24CA', '\x0495'},
+            new char[] {'\x24CB', '\x03FC'},
+            new char[] {'\x24CC', '\x0496'},
+            new char[] {'\x24CD', '\x0401'},
+            new char[] {'\x24CE', '\x0497'},
+            new char[] {'\x24CF', '\x03DA'},
+            new char[] {'\x24D0', '\x0002'},
+            new char[] {'\x24D1', '\x0498'},
+            new char[] {'\x24D2', '\x040E'},
+            new char[] {'\x24D3', '\x03EB'},
+            new char[] {'\x24D4', '\x03DE'},
+            new char[] {'\x24D5', '\x0499'},
+            new char[] {'\x24D6', '\x03CD'},
+            new char[] {'\x24D7', '\x011C'},
+            new char[] {'\x24D8', '\x03B7'},
+            new char[] {'\x24D9', '\x011E'},
+            new char[] {'\x24DA', '\x049A'},
+            new char[] {'\x24DB', '\x012C'},
+            new char[] {'\x24DC', '\x040F'},
+            new char[] {'\x24DD', '\x03C3'},
+            new char[] {'\x24DE', '\x000A'},
+            new char[] {'\x24DF', '\x049B'},
+            new char[] {'\x24E0', '\x049C'},
+            new char[] {'\x24E1', '\x011F'},
+            new char[] {'\x24E2', '\x00B4'},
+            new char[] {'\x24E3', '\x049D'},
+            new char[] {'\x24E4', '\x049E'},
+            new char[] {'\x24E5', '\x0407'},
+            new char[] {'\x24E6', '\x0123'},
+            new char[] {'\x24E7', '\x012D'},
+            new char[] {'\x24E8', '\x0124'},
+            new char[] {'\x24E9', '\x049F'},
+            new char[] {'\x24EA', '\x03B6'},
+            new char[] {'\x2A0C', '\x04A0'},
+            new char[] {'\x2A74', '\x04A1'},
+            new char[] {'\x2A75', '\x04A2'},
+            new char[] {'\x2A76', '\x04A3'},
+            new char[] {'\x2ADC', '\x04A4'},
+            new char[] {'\x2E9F', '\x04A5'},
+            new char[] {'\x2EF3', '\x04A6'},
+            new char[] {'\x2F00', '\x04A7'},
+            new char[] {'\x2F01', '\x04A8'},
+            new char[] {'\x2F02', '\x04A9'},
+            new char[] {'\x2F03', '\x04AA'},
+            new char[] {'\x2F04', '\x04AB'},
+            new char[] {'\x2F05', '\x04AC'},
+            new char[] {'\x2F06', '\x04AD'},
+            new char[] {'\x2F07', '\x04AE'},
+            new char[] {'\x2F08', '\x04AF'},
+            new char[] {'\x2F09', '\x04B0'},
+            new char[] {'\x2F0A', '\x04B1'},
+            new char[] {'\x2F0B', '\x04B2'},
+            new char[] {'\x2F0C', '\x04B3'},
+            new char[] {'\x2F0D', '\x04B4'},
+            new char[] {'\x2F0E', '\x04B5'},
+            new char[] {'\x2F0F', '\x04B6'},
+            new char[] {'\x2F10', '\x04B7'},
+            new char[] {'\x2F11', '\x04B8'},
+            new char[] {'\x2F12', '\x04B9'},
+            new char[] {'\x2F13', '\x04BA'},
+            new char[] {'\x2F14', '\x04BB'},
+            new char[] {'\x2F15', '\x04BC'},
+            new char[] {'\x2F16', '\x04BD'},
+            new char[] {'\x2F17', '\x04BE'},
+            new char[] {'\x2F18', '\x04BF'},
+            new char[] {'\x2F19', '\x04C0'},
+            new char[] {'\x2F1A', '\x04C1'},
+            new char[] {'\x2F1B', '\x04C2'},
+            new char[] {'\x2F1C', '\x04C3'},
+            new char[] {'\x2F1D', '\x04C4'},
+            new char[] {'\x2F1E', '\x04C5'},
+            new char[] {'\x2F1F', '\x04C6'},
+            new char[] {'\x2F20', '\x04C7'},
+            new char[] {'\x2F21', '\x04C8'},
+            new char[] {'\x2F22', '\x04C9'},
+            new char[] {'\x2F23', '\x04CA'},
+            new char[] {'\x2F24', '\x04CB'},
+            new char[] {'\x2F25', '\x04CC'},
+            new char[] {'\x2F26', '\x04CD'},
+            new char[] {'\x2F27', '\x04CE'},
+            new char[] {'\x2F28', '\x04CF'},
+            new char[] {'\x2F29', '\x04D0'},
+            new char[] {'\x2F2A', '\x04D1'},
+            new char[] {'\x2F2B', '\x04D2'},
+            new char[] {'\x2F2C', '\x04D3'},
+            new char[] {'\x2F2D', '\x04D4'},
+            new char[] {'\x2F2E', '\x04D5'},
+            new char[] {'\x2F2F', '\x04D6'},
+            new char[] {'\x2F30', '\x04D7'},
+            new char[] {'\x2F31', '\x04D8'},
+            new char[] {'\x2F32', '\x04D9'},
+            new char[] {'\x2F33', '\x04DA'},
+            new char[] {'\x2F34', '\x04DB'},
+            new char[] {'\x2F35', '\x04DC'},
+            new char[] {'\x2F36', '\x04DD'},
+            new char[] {'\x2F37', '\x04DE'},
+            new char[] {'\x2F38', '\x04DF'},
+            new char[] {'\x2F39', '\x04E0'},
+            new char[] {'\x2F3A', '\x04E1'},
+            new char[] {'\x2F3B', '\x04E2'},
+            new char[] {'\x2F3C', '\x04E3'},
+            new char[] {'\x2F3D', '\x04E4'},
+            new char[] {'\x2F3E', '\x04E5'},
+            new char[] {'\x2F3F', '\x04E6'},
+            new char[] {'\x2F40', '\x04E7'},
+            new char[] {'\x2F41', '\x04E8'},
+            new char[] {'\x2F42', '\x04E9'},
+            new char[] {'\x2F43', '\x04EA'},
+            new char[] {'\x2F44', '\x04EB'},
+            new char[] {'\x2F45', '\x04EC'},
+            new char[] {'\x2F46', '\x04ED'},
+            new char[] {'\x2F47', '\x04EE'},
+            new char[] {'\x2F48', '\x04EF'},
+            new char[] {'\x2F49', '\x04F0'},
+            new char[] {'\x2F4A', '\x04F1'},
+            new char[] {'\x2F4B', '\x04F2'},
+            new char[] {'\x2F4C', '\x04F3'},
+            new char[] {'\x2F4D', '\x04F4'},
+            new char[] {'\x2F4E', '\x04F5'},
+            new char[] {'\x2F4F', '\x04F6'},
+            new char[] {'\x2F50', '\x04F7'},
+            new char[] {'\x2F51', '\x04F8'},
+            new char[] {'\x2F52', '\x04F9'},
+            new char[] {'\x2F53', '\x04FA'},
+            new char[] {'\x2F54', '\x04FB'},
+            new char[] {'\x2F55', '\x04FC'},
+            new char[] {'\x2F56', '\x04FD'},
+            new char[] {'\x2F57', '\x04FE'},
+            new char[] {'\x2F58', '\x04FF'},
+            new char[] {'\x2F59', '\x0500'},
+            new char[] {'\x2F5A', '\x0501'},
+            new char[] {'\x2F5B', '\x0502'},
+            new char[] {'\x2F5C', '\x0503'},
+            new char[] {'\x2F5D', '\x0504'},
+            new char[] {'\x2F5E', '\x0505'},
+            new char[] {'\x2F5F', '\x0506'},
+            new char[] {'\x2F60', '\x0507'},
+            new char[] {'\x2F61', '\x0508'},
+            new char[] {'\x2F62', '\x0509'},
+            new char[] {'\x2F63', '\x050A'},
+            new char[] {'\x2F64', '\x050B'},
+            new char[] {'\x2F65', '\x050C'},
+            new char[] {'\x2F66', '\x050D'},
+            new char[] {'\x2F67', '\x050E'},
+            new char[] {'\x2F68', '\x050F'},
+            new char[] {'\x2F69', '\x0510'},
+            new char[] {'\x2F6A', '\x0511'},
+            new char[] {'\x2F6B', '\x0512'},
+            new char[] {'\x2F6C', '\x0513'},
+            new char[] {'\x2F6D', '\x0514'},
+            new char[] {'\x2F6E', '\x0515'},
+            new char[] {'\x2F6F', '\x0516'},
+            new char[] {'\x2F70', '\x0517'},
+            new char[] {'\x2F71', '\x0518'},
+            new char[] {'\x2F72', '\x0519'},
+            new char[] {'\x2F73', '\x051A'},
+            new char[] {'\x2F74', '\x051B'},
+            new char[] {'\x2F75', '\x051C'},
+            new char[] {'\x2F76', '\x051D'},
+            new char[] {'\x2F77', '\x051E'},
+            new char[] {'\x2F78', '\x051F'},
+            new char[] {'\x2F79', '\x0520'},
+            new char[] {'\x2F7A', '\x0521'},
+            new char[] {'\x2F7B', '\x0522'},
+            new char[] {'\x2F7C', '\x0523'},
+            new char[] {'\x2F7D', '\x0524'},
+            new char[] {'\x2F7E', '\x0525'},
+            new char[] {'\x2F7F', '\x0526'},
+            new char[] {'\x2F80', '\x0527'},
+            new char[] {'\x2F81', '\x0528'},
+            new char[] {'\x2F82', '\x0529'},
+            new char[] {'\x2F83', '\x052A'},
+            new char[] {'\x2F84', '\x052B'},
+            new char[] {'\x2F85', '\x052C'},
+            new char[] {'\x2F86', '\x052D'},
+            new char[] {'\x2F87', '\x052E'},
+            new char[] {'\x2F88', '\x052F'},
+            new char[] {'\x2F89', '\x0530'},
+            new char[] {'\x2F8A', '\x0531'},
+            new char[] {'\x2F8B', '\x0532'},
+            new char[] {'\x2F8C', '\x0533'},
+            new char[] {'\x2F8D', '\x0534'},
+            new char[] {'\x2F8E', '\x0535'},
+            new char[] {'\x2F8F', '\x0536'},
+            new char[] {'\x2F90', '\x0537'},
+            new char[] {'\x2F91', '\x0538'},
+            new char[] {'\x2F92', '\x0539'},
+            new char[] {'\x2F93', '\x053A'},
+            new char[] {'\x2F94', '\x053B'},
+            new char[] {'\x2F95', '\x053C'},
+            new char[] {'\x2F96', '\x053D'},
+            new char[] {'\x2F97', '\x053E'},
+            new char[] {'\x2F98', '\x053F'},
+            new char[] {'\x2F99', '\x0540'},
+            new char[] {'\x2F9A', '\x0541'},
+            new char[] {'\x2F9B', '\x0542'},
+            new char[] {'\x2F9C', '\x0543'},
+            new char[] {'\x2F9D', '\x0544'},
+            new char[] {'\x2F9E', '\x0545'},
+            new char[] {'\x2F9F', '\x0546'},
+            new char[] {'\x2FA0', '\x0547'},
+            new char[] {'\x2FA1', '\x0548'},
+            new char[] {'\x2FA2', '\x0549'},
+            new char[] {'\x2FA3', '\x054A'},
+            new char[] {'\x2FA4', '\x054B'},
+            new char[] {'\x2FA5', '\x054C'},
+            new char[] {'\x2FA6', '\x054D'},
+            new char[] {'\x2FA7', '\x054E'},
+            new char[] {'\x2FA8', '\x054F'},
+            new char[] {'\x2FA9', '\x0550'},
+            new char[] {'\x2FAA', '\x0551'},
+            new char[] {'\x2FAB', '\x0552'},
+            new char[] {'\x2FAC', '\x0553'},
+            new char[] {'\x2FAD', '\x0554'},
+            new char[] {'\x2FAE', '\x0555'},
+            new char[] {'\x2FAF', '\x0556'},
+            new char[] {'\x2FB0', '\x0557'},
+            new char[] {'\x2FB1', '\x0558'},
+            new char[] {'\x2FB2', '\x0559'},
+            new char[] {'\x2FB3', '\x055A'},
+            new char[] {'\x2FB4', '\x055B'},
+            new char[] {'\x2FB5', '\x055C'},
+            new char[] {'\x2FB6', '\x055D'},
+            new char[] {'\x2FB7', '\x055E'},
+            new char[] {'\x2FB8', '\x055F'},
+            new char[] {'\x2FB9', '\x0560'},
+            new char[] {'\x2FBA', '\x0561'},
+            new char[] {'\x2FBB', '\x0562'},
+            new char[] {'\x2FBC', '\x0563'},
+            new char[] {'\x2FBD', '\x0564'},
+            new char[] {'\x2FBE', '\x0565'},
+            new char[] {'\x2FBF', '\x0566'},
+            new char[] {'\x2FC0', '\x0567'},
+            new char[] {'\x2FC1', '\x0568'},
+            new char[] {'\x2FC2', '\x0569'},
+            new char[] {'\x2FC3', '\x056A'},
+            new char[] {'\x2FC4', '\x056B'},
+            new char[] {'\x2FC5', '\x056C'},
+            new char[] {'\x2FC6', '\x056D'},
+            new char[] {'\x2FC7', '\x056E'},
+            new char[] {'\x2FC8', '\x056F'},
+            new char[] {'\x2FC9', '\x0570'},
+            new char[] {'\x2FCA', '\x0571'},
+            new char[] {'\x2FCB', '\x0572'},
+            new char[] {'\x2FCC', '\x0573'},
+            new char[] {'\x2FCD', '\x0574'},
+            new char[] {'\x2FCE', '\x0575'},
+            new char[] {'\x2FCF', '\x0576'},
+            new char[] {'\x2FD0', '\x0577'},
+            new char[] {'\x2FD1', '\x0578'},
+            new char[] {'\x2FD2', '\x0579'},
+            new char[] {'\x2FD3', '\x057A'},
+            new char[] {'\x2FD4', '\x057B'},
+            new char[] {'\x2FD5', '\x057C'},
+            new char[] {'\x3000', '\x0000'},
+            new char[] {'\x3036', '\x057D'},
+            new char[] {'\x3038', '\x04BE'},
+            new char[] {'\x3039', '\x057E'},
+            new char[] {'\x303A', '\x057F'},
+            new char[] {'\x304C', '\x0580'},
+            new char[] {'\x304E', '\x0581'},
+            new char[] {'\x3050', '\x0582'},
+            new char[] {'\x3052', '\x0583'},
+            new char[] {'\x3054', '\x0584'},
+            new char[] {'\x3056', '\x0585'},
+            new char[] {'\x3058', '\x0586'},
+            new char[] {'\x305A', '\x0587'},
+            new char[] {'\x305C', '\x0588'},
+            new char[] {'\x305E', '\x0589'},
+            new char[] {'\x3060', '\x058A'},
+            new char[] {'\x3062', '\x058B'},
+            new char[] {'\x3065', '\x058C'},
+            new char[] {'\x3067', '\x058D'},
+            new char[] {'\x3069', '\x058E'},
+            new char[] {'\x3070', '\x058F'},
+            new char[] {'\x3071', '\x0590'},
+            new char[] {'\x3073', '\x0591'},
+            new char[] {'\x3074', '\x0592'},
+            new char[] {'\x3076', '\x0593'},
+            new char[] {'\x3077', '\x0594'},
+            new char[] {'\x3079', '\x0595'},
+            new char[] {'\x307A', '\x0596'},
+            new char[] {'\x307C', '\x0597'},
+            new char[] {'\x307D', '\x0598'},
+            new char[] {'\x3094', '\x0599'},
+            new char[] {'\x309B', '\x059A'},
+            new char[] {'\x309C', '\x059B'},
+            new char[] {'\x309E', '\x059C'},
+            new char[] {'\x309F', '\x059D'},
+            new char[] {'\x30AC', '\x059E'},
+            new char[] {'\x30AE', '\x059F'},
+            new char[] {'\x30B0', '\x05A0'},
+            new char[] {'\x30B2', '\x05A1'},
+            new char[] {'\x30B4', '\x05A2'},
+            new char[] {'\x30B6', '\x05A3'},
+            new char[] {'\x30B8', '\x05A4'},
+            new char[] {'\x30BA', '\x05A5'},
+            new char[] {'\x30BC', '\x05A6'},
+            new char[] {'\x30BE', '\x05A7'},
+            new char[] {'\x30C0', '\x05A8'},
+            new char[] {'\x30C2', '\x05A9'},
+            new char[] {'\x30C5', '\x05AA'},
+            new char[] {'\x30C7', '\x05AB'},
+            new char[] {'\x30C9', '\x05AC'},
+            new char[] {'\x30D0', '\x05AD'},
+            new char[] {'\x30D1', '\x05AE'},
+            new char[] {'\x30D3', '\x05AF'},
+            new char[] {'\x30D4', '\x05B0'},
+            new char[] {'\x30D6', '\x05B1'},
+            new char[] {'\x30D7', '\x05B2'},
+            new char[] {'\x30D9', '\x05B3'},
+            new char[] {'\x30DA', '\x05B4'},
+            new char[] {'\x30DC', '\x05B5'},
+            new char[] {'\x30DD', '\x05B6'},
+            new char[] {'\x30F4', '\x05B7'},
+            new char[] {'\x30F7', '\x05B8'},
+            new char[] {'\x30F8', '\x05B9'},
+            new char[] {'\x30F9', '\x05BA'},
+            new char[] {'\x30FA', '\x05BB'},
+            new char[] {'\x30FE', '\x05BC'},
+            new char[] {'\x30FF', '\x05BD'},
+            new char[] {'\x3131', '\x05BE'},
+            new char[] {'\x3132', '\x05BF'},
+            new char[] {'\x3133', '\x05C0'},
+            new char[] {'\x3134', '\x05C1'},
+            new char[] {'\x3135', '\x05C2'},
+            new char[] {'\x3136', '\x05C3'},
+            new char[] {'\x3137', '\x05C4'},
+            new char[] {'\x3138', '\x05C5'},
+            new char[] {'\x3139', '\x05C6'},
+            new char[] {'\x313A', '\x05C7'},
+            new char[] {'\x313B', '\x05C8'},
+            new char[] {'\x313C', '\x05C9'},
+            new char[] {'\x313D', '\x05CA'},
+            new char[] {'\x313E', '\x05CB'},
+            new char[] {'\x313F', '\x05CC'},
+            new char[] {'\x3140', '\x05CD'},
+            new char[] {'\x3141', '\x05CE'},
+            new char[] {'\x3142', '\x05CF'},
+            new char[] {'\x3143', '\x05D0'},
+            new char[] {'\x3144', '\x05D1'},
+            new char[] {'\x3145', '\x05D2'},
+            new char[] {'\x3146', '\x05D3'},
+            new char[] {'\x3147', '\x05D4'},
+            new char[] {'\x3148', '\x05D5'},
+            new char[] {'\x3149', '\x05D6'},
+            new char[] {'\x314A', '\x05D7'},
+            new char[] {'\x314B', '\x05D8'},
+            new char[] {'\x314C', '\x05D9'},
+            new char[] {'\x314D', '\x05DA'},
+            new char[] {'\x314E', '\x05DB'},
+            new char[] {'\x314F', '\x05DC'},
+            new char[] {'\x3150', '\x05DD'},
+            new char[] {'\x3151', '\x05DE'},
+            new char[] {'\x3152', '\x05DF'},
+            new char[] {'\x3153', '\x05E0'},
+            new char[] {'\x3154', '\x05E1'},
+            new char[] {'\x3155', '\x05E2'},
+            new char[] {'\x3156', '\x05E3'},
+            new char[] {'\x3157', '\x05E4'},
+            new char[] {'\x3158', '\x05E5'},
+            new char[] {'\x3159', '\x05E6'},
+            new char[] {'\x315A', '\x05E7'},
+            new char[] {'\x315B', '\x05E8'},
+            new char[] {'\x315C', '\x05E9'},
+            new char[] {'\x315D', '\x05EA'},
+            new char[] {'\x315E', '\x05EB'},
+            new char[] {'\x315F', '\x05EC'},
+            new char[] {'\x3160', '\x05ED'},
+            new char[] {'\x3161', '\x05EE'},
+            new char[] {'\x3162', '\x05EF'},
+            new char[] {'\x3163', '\x05F0'},
+            new char[] {'\x3164', '\x05F1'},
+            new char[] {'\x3165', '\x05F2'},
+            new char[] {'\x3166', '\x05F3'},
+            new char[] {'\x3167', '\x05F4'},
+            new char[] {'\x3168', '\x05F5'},
+            new char[] {'\x3169', '\x05F6'},
+            new char[] {'\x316A', '\x05F7'},
+            new char[] {'\x316B', '\x05F8'},
+            new char[] {'\x316C', '\x05F9'},
+            new char[] {'\x316D', '\x05FA'},
+            new char[] {'\x316E', '\x05FB'},
+            new char[] {'\x316F', '\x05FC'},
+            new char[] {'\x3170', '\x05FD'},
+            new char[] {'\x3171', '\x05FE'},
+            new char[] {'\x3172', '\x05FF'},
+            new char[] {'\x3173', '\x0600'},
+            new char[] {'\x3174', '\x0601'},
+            new char[] {'\x3175', '\x0602'},
+            new char[] {'\x3176', '\x0603'},
+            new char[] {'\x3177', '\x0604'},
+            new char[] {'\x3178', '\x0605'},
+            new char[] {'\x3179', '\x0606'},
+            new char[] {'\x317A', '\x0607'},
+            new char[] {'\x317B', '\x0608'},
+            new char[] {'\x317C', '\x0609'},
+            new char[] {'\x317D', '\x060A'},
+            new char[] {'\x317E', '\x060B'},
+            new char[] {'\x317F', '\x060C'},
+            new char[] {'\x3180', '\x060D'},
+            new char[] {'\x3181', '\x060E'},
+            new char[] {'\x3182', '\x060F'},
+            new char[] {'\x3183', '\x0610'},
+            new char[] {'\x3184', '\x0611'},
+            new char[] {'\x3185', '\x0612'},
+            new char[] {'\x3186', '\x0613'},
+            new char[] {'\x3187', '\x0614'},
+            new char[] {'\x3188', '\x0615'},
+            new char[] {'\x3189', '\x0616'},
+            new char[] {'\x318A', '\x0617'},
+            new char[] {'\x318B', '\x0618'},
+            new char[] {'\x318C', '\x0619'},
+            new char[] {'\x318D', '\x061A'},
+            new char[] {'\x318E', '\x061B'},
+            new char[] {'\x3192', '\x04A7'},
+            new char[] {'\x3193', '\x04AD'},
+            new char[] {'\x3194', '\x061C'},
+            new char[] {'\x3195', '\x061D'},
+            new char[] {'\x3196', '\x061E'},
+            new char[] {'\x3197', '\x061F'},
+            new char[] {'\x3198', '\x0620'},
+            new char[] {'\x3199', '\x0621'},
+            new char[] {'\x319A', '\x04AB'},
+            new char[] {'\x319B', '\x0622'},
+            new char[] {'\x319C', '\x0623'},
+            new char[] {'\x319D', '\x0624'},
+            new char[] {'\x319E', '\x0625'},
+            new char[] {'\x319F', '\x04AF'},
+            new char[] {'\x3200', '\x0626'},
+            new char[] {'\x3201', '\x0627'},
+            new char[] {'\x3202', '\x0628'},
+            new char[] {'\x3203', '\x0629'},
+            new char[] {'\x3204', '\x062A'},
+            new char[] {'\x3205', '\x062B'},
+            new char[] {'\x3206', '\x062C'},
+            new char[] {'\x3207', '\x062D'},
+            new char[] {'\x3208', '\x062E'},
+            new char[] {'\x3209', '\x062F'},
+            new char[] {'\x320A', '\x0630'},
+            new char[] {'\x320B', '\x0631'},
+            new char[] {'\x320C', '\x0632'},
+            new char[] {'\x320D', '\x0633'},
+            new char[] {'\x320E', '\x0634'},
+            new char[] {'\x320F', '\x0635'},
+            new char[] {'\x3210', '\x0636'},
+            new char[] {'\x3211', '\x0637'},
+            new char[] {'\x3212', '\x0638'},
+            new char[] {'\x3213', '\x0639'},
+            new char[] {'\x3214', '\x063A'},
+            new char[] {'\x3215', '\x063B'},
+            new char[] {'\x3216', '\x063C'},
+            new char[] {'\x3217', '\x063D'},
+            new char[] {'\x3218', '\x063E'},
+            new char[] {'\x3219', '\x063F'},
+            new char[] {'\x321A', '\x0640'},
+            new char[] {'\x321B', '\x0641'},
+            new char[] {'\x321C', '\x0642'},
+            new char[] {'\x3220', '\x0643'},
+            new char[] {'\x3221', '\x0644'},
+            new char[] {'\x3222', '\x0645'},
+            new char[] {'\x3223', '\x0646'},
+            new char[] {'\x3224', '\x0647'},
+            new char[] {'\x3225', '\x0648'},
+            new char[] {'\x3226', '\x0649'},
+            new char[] {'\x3227', '\x064A'},
+            new char[] {'\x3228', '\x064B'},
+            new char[] {'\x3229', '\x064C'},
+            new char[] {'\x322A', '\x064D'},
+            new char[] {'\x322B', '\x064E'},
+            new char[] {'\x322C', '\x064F'},
+            new char[] {'\x322D', '\x0650'},
+            new char[] {'\x322E', '\x0651'},
+            new char[] {'\x322F', '\x0652'},
+            new char[] {'\x3230', '\x0653'},
+            new char[] {'\x3231', '\x0654'},
+            new char[] {'\x3232', '\x0655'},
+            new char[] {'\x3233', '\x0656'},
+            new char[] {'\x3234', '\x0657'},
+            new char[] {'\x3235', '\x0658'},
+            new char[] {'\x3236', '\x0659'},
+            new char[] {'\x3237', '\x065A'},
+            new char[] {'\x3238', '\x065B'},
+            new char[] {'\x3239', '\x065C'},
+            new char[] {'\x323A', '\x065D'},
+            new char[] {'\x323B', '\x065E'},
+            new char[] {'\x323C', '\x065F'},
+            new char[] {'\x323D', '\x0660'},
+            new char[] {'\x323E', '\x0661'},
+            new char[] {'\x323F', '\x0662'},
+            new char[] {'\x3240', '\x0663'},
+            new char[] {'\x3241', '\x0664'},
+            new char[] {'\x3242', '\x0665'},
+            new char[] {'\x3243', '\x0666'},
+            new char[] {'\x3251', '\x0667'},
+            new char[] {'\x3252', '\x0668'},
+            new char[] {'\x3253', '\x0669'},
+            new char[] {'\x3254', '\x066A'},
+            new char[] {'\x3255', '\x066B'},
+            new char[] {'\x3256', '\x066C'},
+            new char[] {'\x3257', '\x066D'},
+            new char[] {'\x3258', '\x066E'},
+            new char[] {'\x3259', '\x066F'},
+            new char[] {'\x325A', '\x0670'},
+            new char[] {'\x325B', '\x0671'},
+            new char[] {'\x325C', '\x0672'},
+            new char[] {'\x325D', '\x0673'},
+            new char[] {'\x325E', '\x0674'},
+            new char[] {'\x325F', '\x0675'},
+            new char[] {'\x3260', '\x05BE'},
+            new char[] {'\x3261', '\x05C1'},
+            new char[] {'\x3262', '\x05C4'},
+            new char[] {'\x3263', '\x05C6'},
+            new char[] {'\x3264', '\x05CE'},
+            new char[] {'\x3265', '\x05CF'},
+            new char[] {'\x3266', '\x05D2'},
+            new char[] {'\x3267', '\x05D4'},
+            new char[] {'\x3268', '\x05D5'},
+            new char[] {'\x3269', '\x05D7'},
+            new char[] {'\x326A', '\x05D8'},
+            new char[] {'\x326B', '\x05D9'},
+            new char[] {'\x326C', '\x05DA'},
+            new char[] {'\x326D', '\x05DB'},
+            new char[] {'\x326E', '\x0676'},
+            new char[] {'\x326F', '\x0677'},
+            new char[] {'\x3270', '\x0678'},
+            new char[] {'\x3271', '\x0679'},
+            new char[] {'\x3272', '\x067A'},
+            new char[] {'\x3273', '\x067B'},
+            new char[] {'\x3274', '\x067C'},
+            new char[] {'\x3275', '\x067D'},
+            new char[] {'\x3276', '\x067E'},
+            new char[] {'\x3277', '\x067F'},
+            new char[] {'\x3278', '\x0680'},
+            new char[] {'\x3279', '\x0681'},
+            new char[] {'\x327A', '\x0682'},
+            new char[] {'\x327B', '\x0683'},
+            new char[] {'\x3280', '\x04A7'},
+            new char[] {'\x3281', '\x04AD'},
+            new char[] {'\x3282', '\x061C'},
+            new char[] {'\x3283', '\x061D'},
+            new char[] {'\x3284', '\x0684'},
+            new char[] {'\x3285', '\x0685'},
+            new char[] {'\x3286', '\x0686'},
+            new char[] {'\x3287', '\x04B2'},
+            new char[] {'\x3288', '\x0687'},
+            new char[] {'\x3289', '\x04BE'},
+            new char[] {'\x328A', '\x04F0'},
+            new char[] {'\x328B', '\x04FC'},
+            new char[] {'\x328C', '\x04FB'},
+            new char[] {'\x328D', '\x04F1'},
+            new char[] {'\x328E', '\x054D'},
+            new char[] {'\x328F', '\x04C6'},
+            new char[] {'\x3290', '\x04EE'},
+            new char[] {'\x3291', '\x0688'},
+            new char[] {'\x3292', '\x0689'},
+            new char[] {'\x3293', '\x068A'},
+            new char[] {'\x3294', '\x068B'},
+            new char[] {'\x3295', '\x068C'},
+            new char[] {'\x3296', '\x068D'},
+            new char[] {'\x3297', '\x068E'},
+            new char[] {'\x3298', '\x068F'},
+            new char[] {'\x3299', '\x0690'},
+            new char[] {'\x329A', '\x0691'},
+            new char[] {'\x329B', '\x04CC'},
+            new char[] {'\x329C', '\x0692'},
+            new char[] {'\x329D', '\x0693'},
+            new char[] {'\x329E', '\x0694'},
+            new char[] {'\x329F', '\x0695'},
+            new char[] {'\x32A0', '\x0696'},
+            new char[] {'\x32A1', '\x0697'},
+            new char[] {'\x32A2', '\x0698'},
+            new char[] {'\x32A3', '\x0699'},
+            new char[] {'\x32A4', '\x061E'},
+            new char[] {'\x32A5', '\x061F'},
+            new char[] {'\x32A6', '\x0620'},
+            new char[] {'\x32A7', '\x069A'},
+            new char[] {'\x32A8', '\x069B'},
+            new char[] {'\x32A9', '\x069C'},
+            new char[] {'\x32AA', '\x069D'},
+            new char[] {'\x32AB', '\x069E'},
+            new char[] {'\x32AC', '\x069F'},
+            new char[] {'\x32AD', '\x06A0'},
+            new char[] {'\x32AE', '\x06A1'},
+            new char[] {'\x32AF', '\x06A2'},
+            new char[] {'\x32B0', '\x06A3'},
+            new char[] {'\x32B1', '\x06A4'},
+            new char[] {'\x32B2', '\x06A5'},
+            new char[] {'\x32B3', '\x06A6'},
+            new char[] {'\x32B4', '\x06A7'},
+            new char[] {'\x32B5', '\x06A8'},
+            new char[] {'\x32B6', '\x06A9'},
+            new char[] {'\x32B7', '\x06AA'},
+            new char[] {'\x32B8', '\x06AB'},
+            new char[] {'\x32B9', '\x06AC'},
+            new char[] {'\x32BA', '\x06AD'},
+            new char[] {'\x32BB', '\x06AE'},
+            new char[] {'\x32BC', '\x06AF'},
+            new char[] {'\x32BD', '\x06B0'},
+            new char[] {'\x32BE', '\x06B1'},
+            new char[] {'\x32BF', '\x06B2'},
+            new char[] {'\x32C0', '\x06B3'},
+            new char[] {'\x32C1', '\x06B4'},
+            new char[] {'\x32C2', '\x06B5'},
+            new char[] {'\x32C3', '\x06B6'},
+            new char[] {'\x32C4', '\x06B7'},
+            new char[] {'\x32C5', '\x06B8'},
+            new char[] {'\x32C6', '\x06B9'},
+            new char[] {'\x32C7', '\x06BA'},
+            new char[] {'\x32C8', '\x06BB'},
+            new char[] {'\x32C9', '\x06BC'},
+            new char[] {'\x32CA', '\x06BD'},
+            new char[] {'\x32CB', '\x06BE'},
+            new char[] {'\x32D0', '\x06BF'},
+            new char[] {'\x32D1', '\x06C0'},
+            new char[] {'\x32D2', '\x06C1'},
+            new char[] {'\x32D3', '\x06C2'},
+            new char[] {'\x32D4', '\x06C3'},
+            new char[] {'\x32D5', '\x06C4'},
+            new char[] {'\x32D6', '\x06C5'},
+            new char[] {'\x32D7', '\x06C6'},
+            new char[] {'\x32D8', '\x06C7'},
+            new char[] {'\x32D9', '\x06C8'},
+            new char[] {'\x32DA', '\x06C9'},
+            new char[] {'\x32DB', '\x06CA'},
+            new char[] {'\x32DC', '\x06CB'},
+            new char[] {'\x32DD', '\x06CC'},
+            new char[] {'\x32DE', '\x06CD'},
+            new char[] {'\x32DF', '\x06CE'},
+            new char[] {'\x32E0', '\x06CF'},
+            new char[] {'\x32E1', '\x06D0'},
+            new char[] {'\x32E2', '\x06D1'},
+            new char[] {'\x32E3', '\x06D2'},
+            new char[] {'\x32E4', '\x06D3'},
+            new char[] {'\x32E5', '\x06D4'},
+            new char[] {'\x32E6', '\x06D5'},
+            new char[] {'\x32E7', '\x06D6'},
+            new char[] {'\x32E8', '\x06D7'},
+            new char[] {'\x32E9', '\x06D8'},
+            new char[] {'\x32EA', '\x06D9'},
+            new char[] {'\x32EB', '\x06DA'},
+            new char[] {'\x32EC', '\x06DB'},
+            new char[] {'\x32ED', '\x06DC'},
+            new char[] {'\x32EE', '\x06DD'},
+            new char[] {'\x32EF', '\x06DE'},
+            new char[] {'\x32F0', '\x06DF'},
+            new char[] {'\x32F1', '\x06E0'},
+            new char[] {'\x32F2', '\x06E1'},
+            new char[] {'\x32F3', '\x06E2'},
+            new char[] {'\x32F4', '\x06E3'},
+            new char[] {'\x32F5', '\x06E4'},
+            new char[] {'\x32F6', '\x06E5'},
+            new char[] {'\x32F7', '\x06E6'},
+            new char[] {'\x32F8', '\x06E7'},
+            new char[] {'\x32F9', '\x06E8'},
+            new char[] {'\x32FA', '\x06E9'},
+            new char[] {'\x32FB', '\x06EA'},
+            new char[] {'\x32FC', '\x06EB'},
+            new char[] {'\x32FD', '\x06EC'},
+            new char[] {'\x32FE', '\x06ED'},
+            new char[] {'\x3300', '\x06EE'},
+            new char[] {'\x3301', '\x06EF'},
+            new char[] {'\x3302', '\x06F0'},
+            new char[] {'\x3303', '\x06F1'},
+            new char[] {'\x3304', '\x06F2'},
+            new char[] {'\x3305', '\x06F3'},
+            new char[] {'\x3306', '\x06F4'},
+            new char[] {'\x3307', '\x06F5'},
+            new char[] {'\x3308', '\x06F6'},
+            new char[] {'\x3309', '\x06F7'},
+            new char[] {'\x330A', '\x06F8'},
+            new char[] {'\x330B', '\x06F9'},
+            new char[] {'\x330C', '\x06FA'},
+            new char[] {'\x330D', '\x06FB'},
+            new char[] {'\x330E', '\x06FC'},
+            new char[] {'\x330F', '\x06FD'},
+            new char[] {'\x3310', '\x06FE'},
+            new char[] {'\x3311', '\x06FF'},
+            new char[] {'\x3312', '\x0700'},
+            new char[] {'\x3313', '\x0701'},
+            new char[] {'\x3314', '\x0702'},
+            new char[] {'\x3315', '\x0703'},
+            new char[] {'\x3316', '\x0704'},
+            new char[] {'\x3317', '\x0705'},
+            new char[] {'\x3318', '\x0706'},
+            new char[] {'\x3319', '\x0707'},
+            new char[] {'\x331A', '\x0708'},
+            new char[] {'\x331B', '\x0709'},
+            new char[] {'\x331C', '\x070A'},
+            new char[] {'\x331D', '\x070B'},
+            new char[] {'\x331E', '\x070C'},
+            new char[] {'\x331F', '\x070D'},
+            new char[] {'\x3320', '\x070E'},
+            new char[] {'\x3321', '\x070F'},
+            new char[] {'\x3322', '\x0710'},
+            new char[] {'\x3323', '\x0711'},
+            new char[] {'\x3324', '\x0712'},
+            new char[] {'\x3325', '\x0713'},
+            new char[] {'\x3326', '\x0714'},
+            new char[] {'\x3327', '\x0715'},
+            new char[] {'\x3328', '\x0716'},
+            new char[] {'\x3329', '\x0717'},
+            new char[] {'\x332A', '\x0718'},
+            new char[] {'\x332B', '\x0719'},
+            new char[] {'\x332C', '\x071A'},
+            new char[] {'\x332D', '\x071B'},
+            new char[] {'\x332E', '\x071C'},
+            new char[] {'\x332F', '\x071D'},
+            new char[] {'\x3330', '\x071E'},
+            new char[] {'\x3331', '\x071F'},
+            new char[] {'\x3332', '\x0720'},
+            new char[] {'\x3333', '\x0721'},
+            new char[] {'\x3334', '\x0722'},
+            new char[] {'\x3335', '\x0723'},
+            new char[] {'\x3336', '\x0724'},
+            new char[] {'\x3337', '\x0725'},
+            new char[] {'\x3338', '\x0726'},
+            new char[] {'\x3339', '\x0727'},
+            new char[] {'\x333A', '\x0728'},
+            new char[] {'\x333B', '\x0729'},
+            new char[] {'\x333C', '\x072A'},
+            new char[] {'\x333D', '\x072B'},
+            new char[] {'\x333E', '\x072C'},
+            new char[] {'\x333F', '\x072D'},
+            new char[] {'\x3340', '\x072E'},
+            new char[] {'\x3341', '\x072F'},
+            new char[] {'\x3342', '\x0730'},
+            new char[] {'\x3343', '\x0731'},
+            new char[] {'\x3344', '\x0732'},
+            new char[] {'\x3345', '\x0733'},
+            new char[] {'\x3346', '\x0734'},
+            new char[] {'\x3347', '\x0735'},
+            new char[] {'\x3348', '\x0736'},
+            new char[] {'\x3349', '\x0737'},
+            new char[] {'\x334A', '\x0738'},
+            new char[] {'\x334B', '\x0739'},
+            new char[] {'\x334C', '\x073A'},
+            new char[] {'\x334D', '\x073B'},
+            new char[] {'\x334E', '\x073C'},
+            new char[] {'\x334F', '\x073D'},
+            new char[] {'\x3350', '\x073E'},
+            new char[] {'\x3351', '\x073F'},
+            new char[] {'\x3352', '\x0740'},
+            new char[] {'\x3353', '\x0741'},
+            new char[] {'\x3354', '\x0742'},
+            new char[] {'\x3355', '\x0743'},
+            new char[] {'\x3356', '\x0744'},
+            new char[] {'\x3357', '\x0745'},
+            new char[] {'\x3358', '\x0746'},
+            new char[] {'\x3359', '\x0747'},
+            new char[] {'\x335A', '\x0748'},
+            new char[] {'\x335B', '\x0749'},
+            new char[] {'\x335C', '\x074A'},
+            new char[] {'\x335D', '\x074B'},
+            new char[] {'\x335E', '\x074C'},
+            new char[] {'\x335F', '\x074D'},
+            new char[] {'\x3360', '\x074E'},
+            new char[] {'\x3361', '\x074F'},
+            new char[] {'\x3362', '\x0750'},
+            new char[] {'\x3363', '\x0751'},
+            new char[] {'\x3364', '\x0752'},
+            new char[] {'\x3365', '\x0753'},
+            new char[] {'\x3366', '\x0754'},
+            new char[] {'\x3367', '\x0755'},
+            new char[] {'\x3368', '\x0756'},
+            new char[] {'\x3369', '\x0757'},
+            new char[] {'\x336A', '\x0758'},
+            new char[] {'\x336B', '\x0759'},
+            new char[] {'\x336C', '\x075A'},
+            new char[] {'\x336D', '\x075B'},
+            new char[] {'\x336E', '\x075C'},
+            new char[] {'\x336F', '\x075D'},
+            new char[] {'\x3370', '\x075E'},
+            new char[] {'\x3371', '\x075F'},
+            new char[] {'\x3372', '\x0760'},
+            new char[] {'\x3373', '\x0761'},
+            new char[] {'\x3374', '\x0762'},
+            new char[] {'\x3375', '\x0763'},
+            new char[] {'\x3376', '\x0764'},
+            new char[] {'\x337B', '\x0765'},
+            new char[] {'\x337C', '\x0766'},
+            new char[] {'\x337D', '\x0767'},
+            new char[] {'\x337E', '\x0768'},
+            new char[] {'\x337F', '\x0769'},
+            new char[] {'\x3380', '\x076A'},
+            new char[] {'\x3381', '\x076B'},
+            new char[] {'\x3382', '\x076C'},
+            new char[] {'\x3383', '\x076D'},
+            new char[] {'\x3384', '\x076E'},
+            new char[] {'\x3385', '\x076F'},
+            new char[] {'\x3386', '\x0770'},
+            new char[] {'\x3387', '\x0771'},
+            new char[] {'\x3388', '\x0772'},
+            new char[] {'\x3389', '\x0773'},
+            new char[] {'\x338A', '\x0774'},
+            new char[] {'\x338B', '\x0775'},
+            new char[] {'\x338C', '\x0776'},
+            new char[] {'\x338D', '\x0777'},
+            new char[] {'\x338E', '\x0778'},
+            new char[] {'\x338F', '\x0779'},
+            new char[] {'\x3390', '\x077A'},
+            new char[] {'\x3391', '\x077B'},
+            new char[] {'\x3392', '\x077C'},
+            new char[] {'\x3393', '\x077D'},
+            new char[] {'\x3394', '\x077E'},
+            new char[] {'\x3395', '\x077F'},
+            new char[] {'\x3396', '\x0780'},
+            new char[] {'\x3397', '\x0781'},
+            new char[] {'\x3398', '\x0782'},
+            new char[] {'\x3399', '\x0783'},
+            new char[] {'\x339A', '\x0784'},
+            new char[] {'\x339B', '\x0785'},
+            new char[] {'\x339C', '\x0786'},
+            new char[] {'\x339D', '\x0787'},
+            new char[] {'\x339E', '\x0788'},
+            new char[] {'\x339F', '\x0789'},
+            new char[] {'\x33A0', '\x078A'},
+            new char[] {'\x33A1', '\x078B'},
+            new char[] {'\x33A2', '\x078C'},
+            new char[] {'\x33A3', '\x078D'},
+            new char[] {'\x33A4', '\x078E'},
+            new char[] {'\x33A5', '\x078F'},
+            new char[] {'\x33A6', '\x0790'},
+            new char[] {'\x33A7', '\x0791'},
+            new char[] {'\x33A8', '\x0792'},
+            new char[] {'\x33A9', '\x0793'},
+            new char[] {'\x33AA', '\x0794'},
+            new char[] {'\x33AB', '\x0795'},
+            new char[] {'\x33AC', '\x0796'},
+            new char[] {'\x33AD', '\x0797'},
+            new char[] {'\x33AE', '\x0798'},
+            new char[] {'\x33AF', '\x0799'},
+            new char[] {'\x33B0', '\x079A'},
+            new char[] {'\x33B1', '\x079B'},
+            new char[] {'\x33B2', '\x079C'},
+            new char[] {'\x33B3', '\x079D'},
+            new char[] {'\x33B4', '\x079E'},
+            new char[] {'\x33B5', '\x079F'},
+            new char[] {'\x33B6', '\x07A0'},
+            new char[] {'\x33B7', '\x07A1'},
+            new char[] {'\x33B8', '\x07A2'},
+            new char[] {'\x33B9', '\x07A3'},
+            new char[] {'\x33BA', '\x07A4'},
+            new char[] {'\x33BB', '\x07A5'},
+            new char[] {'\x33BC', '\x07A6'},
+            new char[] {'\x33BD', '\x07A7'},
+            new char[] {'\x33BE', '\x07A8'},
+            new char[] {'\x33BF', '\x07A9'},
+            new char[] {'\x33C0', '\x07AA'},
+            new char[] {'\x33C1', '\x07AB'},
+            new char[] {'\x33C2', '\x07AC'},
+            new char[] {'\x33C3', '\x07AD'},
+            new char[] {'\x33C4', '\x07AE'},
+            new char[] {'\x33C5', '\x07AF'},
+            new char[] {'\x33C6', '\x07B0'},
+            new char[] {'\x33C7', '\x07B1'},
+            new char[] {'\x33C8', '\x07B2'},
+            new char[] {'\x33C9', '\x07B3'},
+            new char[] {'\x33CA', '\x07B4'},
+            new char[] {'\x33CB', '\x07B5'},
+            new char[] {'\x33CC', '\x07B6'},
+            new char[] {'\x33CD', '\x07B7'},
+            new char[] {'\x33CE', '\x07B8'},
+            new char[] {'\x33CF', '\x07B9'},
+            new char[] {'\x33D0', '\x07BA'},
+            new char[] {'\x33D1', '\x07BB'},
+            new char[] {'\x33D2', '\x07BC'},
+            new char[] {'\x33D3', '\x07BD'},
+            new char[] {'\x33D4', '\x07BE'},
+            new char[] {'\x33D5', '\x07BF'},
+            new char[] {'\x33D6', '\x07C0'},
+            new char[] {'\x33D7', '\x07C1'},
+            new char[] {'\x33D8', '\x07C2'},
+            new char[] {'\x33D9', '\x07C3'},
+            new char[] {'\x33DA', '\x07C4'},
+            new char[] {'\x33DB', '\x07C5'},
+            new char[] {'\x33DC', '\x07C6'},
+            new char[] {'\x33DD', '\x07C7'},
+            new char[] {'\x33E0', '\x07C8'},
+            new char[] {'\x33E1', '\x07C9'},
+            new char[] {'\x33E2', '\x07CA'},
+            new char[] {'\x33E3', '\x07CB'},
+            new char[] {'\x33E4', '\x07CC'},
+            new char[] {'\x33E5', '\x07CD'},
+            new char[] {'\x33E6', '\x07CE'},
+            new char[] {'\x33E7', '\x07CF'},
+            new char[] {'\x33E8', '\x07D0'},
+            new char[] {'\x33E9', '\x07D1'},
+            new char[] {'\x33EA', '\x07D2'},
+            new char[] {'\x33EB', '\x07D3'},
+            new char[] {'\x33EC', '\x07D4'},
+            new char[] {'\x33ED', '\x07D5'},
+            new char[] {'\x33EE', '\x07D6'},
+            new char[] {'\x33EF', '\x07D7'},
+            new char[] {'\x33F0', '\x07D8'},
+            new char[] {'\x33F1', '\x07D9'},
+            new char[] {'\x33F2', '\x07DA'},
+            new char[] {'\x33F3', '\x07DB'},
+            new char[] {'\x33F4', '\x07DC'},
+            new char[] {'\x33F5', '\x07DD'},
+            new char[] {'\x33F6', '\x07DE'},
+            new char[] {'\x33F7', '\x07DF'},
+            new char[] {'\x33F8', '\x07E0'},
+            new char[] {'\x33F9', '\x07E1'},
+            new char[] {'\x33FA', '\x07E2'},
+            new char[] {'\x33FB', '\x07E3'},
+            new char[] {'\x33FC', '\x07E4'},
+            new char[] {'\x33FD', '\x07E5'},
+            new char[] {'\x33FE', '\x07E6'},
+            new char[] {'\xF900', '\x07E7'},
+            new char[] {'\xF901', '\x07E8'},
+            new char[] {'\xF902', '\x0545'},
+            new char[] {'\xF903', '\x07E9'},
+            new char[] {'\xF904', '\x07EA'},
+            new char[] {'\xF905', '\x07EB'},
+            new char[] {'\xF906', '\x07EC'},
+            new char[] {'\xF907', '\x057B'},
+            new char[] {'\xF908', '\x057B'},
+            new char[] {'\xF909', '\x07ED'},
+            new char[] {'\xF90A', '\x054D'},
+            new char[] {'\xF90B', '\x07EE'},
+            new char[] {'\xF90C', '\x07EF'},
+            new char[] {'\xF90D', '\x07F0'},
+            new char[] {'\xF90E', '\x07F1'},
+            new char[] {'\xF90F', '\x07F2'},
+            new char[] {'\xF910', '\x07F3'},
+            new char[] {'\xF911', '\x07F4'},
+            new char[] {'\xF912', '\x07F5'},
+            new char[] {'\xF913', '\x07F6'},
+            new char[] {'\xF914', '\x07F7'},
+            new char[] {'\xF915', '\x07F8'},
+            new char[] {'\xF916', '\x07F9'},
+            new char[] {'\xF917', '\x07FA'},
+            new char[] {'\xF918', '\x07FB'},
+            new char[] {'\xF919', '\x07FC'},
+            new char[] {'\xF91A', '\x07FD'},
+            new char[] {'\xF91B', '\x07FE'},
+            new char[] {'\xF91C', '\x07FF'},
+            new char[] {'\xF91D', '\x0800'},
+            new char[] {'\xF91E', '\x0801'},
+            new char[] {'\xF91F', '\x0802'},
+            new char[] {'\xF920', '\x0803'},
+            new char[] {'\xF921', '\x0804'},
+            new char[] {'\xF922', '\x0805'},
+            new char[] {'\xF923', '\x0806'},
+            new char[] {'\xF924', '\x0807'},
+            new char[] {'\xF925', '\x0808'},
+            new char[] {'\xF926', '\x0809'},
+            new char[] {'\xF927', '\x080A'},
+            new char[] {'\xF928', '\x080B'},
+            new char[] {'\xF929', '\x080C'},
+            new char[] {'\xF92A', '\x080D'},
+            new char[] {'\xF92B', '\x080E'},
+            new char[] {'\xF92C', '\x080F'},
+            new char[] {'\xF92D', '\x0810'},
+            new char[] {'\xF92E', '\x0811'},
+            new char[] {'\xF92F', '\x0812'},
+            new char[] {'\xF930', '\x0813'},
+            new char[] {'\xF931', '\x0814'},
+            new char[] {'\xF932', '\x0815'},
+            new char[] {'\xF933', '\x0816'},
+            new char[] {'\xF934', '\x0523'},
+            new char[] {'\xF935', '\x0817'},
+            new char[] {'\xF936', '\x0818'},
+            new char[] {'\xF937', '\x0819'},
+            new char[] {'\xF938', '\x081A'},
+            new char[] {'\xF939', '\x081B'},
+            new char[] {'\xF93A', '\x081C'},
+            new char[] {'\xF93B', '\x081D'},
+            new char[] {'\xF93C', '\x081E'},
+            new char[] {'\xF93D', '\x081F'},
+            new char[] {'\xF93E', '\x0820'},
+            new char[] {'\xF93F', '\x0821'},
+            new char[] {'\xF940', '\x056C'},
+            new char[] {'\xF941', '\x0822'},
+            new char[] {'\xF942', '\x0823'},
+            new char[] {'\xF943', '\x0824'},
+            new char[] {'\xF944', '\x0825'},
+            new char[] {'\xF945', '\x0826'},
+            new char[] {'\xF946', '\x0827'},
+            new char[] {'\xF947', '\x0828'},
+            new char[] {'\xF948', '\x0829'},
+            new char[] {'\xF949', '\x082A'},
+            new char[] {'\xF94A', '\x082B'},
+            new char[] {'\xF94B', '\x082C'},
+            new char[] {'\xF94C', '\x082D'},
+            new char[] {'\xF94D', '\x082E'},
+            new char[] {'\xF94E', '\x082F'},
+            new char[] {'\xF94F', '\x0830'},
+            new char[] {'\xF950', '\x0831'},
+            new char[] {'\xF951', '\x0832'},
+            new char[] {'\xF952', '\x0833'},
+            new char[] {'\xF953', '\x0834'},
+            new char[] {'\xF954', '\x0835'},
+            new char[] {'\xF955', '\x0836'},
+            new char[] {'\xF956', '\x0837'},
+            new char[] {'\xF957', '\x0838'},
+            new char[] {'\xF958', '\x0839'},
+            new char[] {'\xF959', '\x083A'},
+            new char[] {'\xF95A', '\x083B'},
+            new char[] {'\xF95B', '\x083C'},
+            new char[] {'\xF95C', '\x07F7'},
+            new char[] {'\xF95D', '\x083D'},
+            new char[] {'\xF95E', '\x083E'},
+            new char[] {'\xF95F', '\x083F'},
+            new char[] {'\xF960', '\x0840'},
+            new char[] {'\xF961', '\x0841'},
+            new char[] {'\xF962', '\x0842'},
+            new char[] {'\xF963', '\x0843'},
+            new char[] {'\xF964', '\x0844'},
+            new char[] {'\xF965', '\x0845'},
+            new char[] {'\xF966', '\x0846'},
+            new char[] {'\xF967', '\x0847'},
+            new char[] {'\xF968', '\x0848'},
+            new char[] {'\xF969', '\x0849'},
+            new char[] {'\xF96A', '\x084A'},
+            new char[] {'\xF96B', '\x084B'},
+            new char[] {'\xF96C', '\x084C'},
+            new char[] {'\xF96D', '\x084D'},
+            new char[] {'\xF96E', '\x084E'},
+            new char[] {'\xF96F', '\x084F'},
+            new char[] {'\xF970', '\x0850'},
+            new char[] {'\xF971', '\x0547'},
+            new char[] {'\xF972', '\x0851'},
+            new char[] {'\xF973', '\x0852'},
+            new char[] {'\xF974', '\x0853'},
+            new char[] {'\xF975', '\x0854'},
+            new char[] {'\xF976', '\x0855'},
+            new char[] {'\xF977', '\x0856'},
+            new char[] {'\xF978', '\x0857'},
+            new char[] {'\xF979', '\x0858'},
+            new char[] {'\xF97A', '\x0859'},
+            new char[] {'\xF97B', '\x085A'},
+            new char[] {'\xF97C', '\x085B'},
+            new char[] {'\xF97D', '\x085C'},
+            new char[] {'\xF97E', '\x085D'},
+            new char[] {'\xF97F', '\x085E'},
+            new char[] {'\xF980', '\x085F'},
+            new char[] {'\xF981', '\x04CC'},
+            new char[] {'\xF982', '\x0860'},
+            new char[] {'\xF983', '\x0861'},
+            new char[] {'\xF984', '\x0862'},
+            new char[] {'\xF985', '\x0863'},
+            new char[] {'\xF986', '\x0864'},
+            new char[] {'\xF987', '\x0865'},
+            new char[] {'\xF988', '\x0866'},
+            new char[] {'\xF989', '\x0867'},
+            new char[] {'\xF98A', '\x04B9'},
+            new char[] {'\xF98B', '\x0868'},
+            new char[] {'\xF98C', '\x0869'},
+            new char[] {'\xF98D', '\x086A'},
+            new char[] {'\xF98E', '\x086B'},
+            new char[] {'\xF98F', '\x086C'},
+            new char[] {'\xF990', '\x086D'},
+            new char[] {'\xF991', '\x086E'},
+            new char[] {'\xF992', '\x086F'},
+            new char[] {'\xF993', '\x0870'},
+            new char[] {'\xF994', '\x0871'},
+            new char[] {'\xF995', '\x0872'},
+            new char[] {'\xF996', '\x0873'},
+            new char[] {'\xF997', '\x0874'},
+            new char[] {'\xF998', '\x0875'},
+            new char[] {'\xF999', '\x0876'},
+            new char[] {'\xF99A', '\x0877'},
+            new char[] {'\xF99B', '\x0878'},
+            new char[] {'\xF99C', '\x0879'},
+            new char[] {'\xF99D', '\x087A'},
+            new char[] {'\xF99E', '\x087B'},
+            new char[] {'\xF99F', '\x087C'},
+            new char[] {'\xF9A0', '\x087D'},
+            new char[] {'\xF9A1', '\x084F'},
+            new char[] {'\xF9A2', '\x087E'},
+            new char[] {'\xF9A3', '\x087F'},
+            new char[] {'\xF9A4', '\x0880'},
+            new char[] {'\xF9A5', '\x0881'},
+            new char[] {'\xF9A6', '\x0882'},
+            new char[] {'\xF9A7', '\x0883'},
+            new char[] {'\xF9A8', '\x0884'},
+            new char[] {'\xF9A9', '\x0885'},
+            new char[] {'\xF9AA', '\x083F'},
+            new char[] {'\xF9AB', '\x0886'},
+            new char[] {'\xF9AC', '\x0887'},
+            new char[] {'\xF9AD', '\x0888'},
+            new char[] {'\xF9AE', '\x0889'},
+            new char[] {'\xF9AF', '\x088A'},
+            new char[] {'\xF9B0', '\x088B'},
+            new char[] {'\xF9B1', '\x088C'},
+            new char[] {'\xF9B2', '\x088D'},
+            new char[] {'\xF9B3', '\x088E'},
+            new char[] {'\xF9B4', '\x088F'},
+            new char[] {'\xF9B5', '\x0890'},
+            new char[] {'\xF9B6', '\x0891'},
+            new char[] {'\xF9B7', '\x0892'},
+            new char[] {'\xF9B8', '\x0893'},
+            new char[] {'\xF9B9', '\x0894'},
+            new char[] {'\xF9BA', '\x0895'},
+            new char[] {'\xF9BB', '\x0896'},
+            new char[] {'\xF9BC', '\x0897'},
+            new char[] {'\xF9BD', '\x0898'},
+            new char[] {'\xF9BE', '\x0899'},
+            new char[] {'\xF9BF', '\x07F7'},
+            new char[] {'\xF9C0', '\x089A'},
+            new char[] {'\xF9C1', '\x089B'},
+            new char[] {'\xF9C2', '\x089C'},
+            new char[] {'\xF9C3', '\x089D'},
+            new char[] {'\xF9C4', '\x057A'},
+            new char[] {'\xF9C5', '\x089E'},
+            new char[] {'\xF9C6', '\x089F'},
+            new char[] {'\xF9C7', '\x08A0'},
+            new char[] {'\xF9C8', '\x08A1'},
+            new char[] {'\xF9C9', '\x08A2'},
+            new char[] {'\xF9CA', '\x08A3'},
+            new char[] {'\xF9CB', '\x08A4'},
+            new char[] {'\xF9CC', '\x08A5'},
+            new char[] {'\xF9CD', '\x08A6'},
+            new char[] {'\xF9CE', '\x08A7'},
+            new char[] {'\xF9CF', '\x08A8'},
+            new char[] {'\xF9D0', '\x08A9'},
+            new char[] {'\xF9D1', '\x0685'},
+            new char[] {'\xF9D2', '\x08AA'},
+            new char[] {'\xF9D3', '\x08AB'},
+            new char[] {'\xF9D4', '\x08AC'},
+            new char[] {'\xF9D5', '\x08AD'},
+            new char[] {'\xF9D6', '\x08AE'},
+            new char[] {'\xF9D7', '\x08AF'},
+            new char[] {'\xF9D8', '\x08B0'},
+            new char[] {'\xF9D9', '\x08B1'},
+            new char[] {'\xF9DA', '\x08B2'},
+            new char[] {'\xF9DB', '\x0841'},
+            new char[] {'\xF9DC', '\x08B3'},
+            new char[] {'\xF9DD', '\x08B4'},
+            new char[] {'\xF9DE', '\x08B5'},
+            new char[] {'\xF9DF', '\x08B6'},
+            new char[] {'\xF9E0', '\x08B7'},
+            new char[] {'\xF9E1', '\x08B8'},
+            new char[] {'\xF9E2', '\x08B9'},
+            new char[] {'\xF9E3', '\x08BA'},
+            new char[] {'\xF9E4', '\x08BB'},
+            new char[] {'\xF9E5', '\x08BC'},
+            new char[] {'\xF9E6', '\x08BD'},
+            new char[] {'\xF9E7', '\x08BE'},
+            new char[] {'\xF9E8', '\x08BF'},
+            new char[] {'\xF9E9', '\x054C'},
+            new char[] {'\xF9EA', '\x08C0'},
+            new char[] {'\xF9EB', '\x08C1'},
+            new char[] {'\xF9EC', '\x08C2'},
+            new char[] {'\xF9ED', '\x08C3'},
+            new char[] {'\xF9EE', '\x08C4'},
+            new char[] {'\xF9EF', '\x08C5'},
+            new char[] {'\xF9F0', '\x08C6'},
+            new char[] {'\xF9F1', '\x08C7'},
+            new char[] {'\xF9F2', '\x08C8'},
+            new char[] {'\xF9F3', '\x08C9'},
+            new char[] {'\xF9F4', '\x08CA'},
+            new char[] {'\xF9F5', '\x08CB'},
+            new char[] {'\xF9F6', '\x08CC'},
+            new char[] {'\xF9F7', '\x051B'},
+            new char[] {'\xF9F8', '\x08CD'},
+            new char[] {'\xF9F9', '\x08CE'},
+            new char[] {'\xF9FA', '\x08CF'},
+            new char[] {'\xF9FB', '\x08D0'},
+            new char[] {'\xF9FC', '\x08D1'},
+            new char[] {'\xF9FD', '\x08D2'},
+            new char[] {'\xF9FE', '\x08D3'},
+            new char[] {'\xF9FF', '\x08D4'},
+            new char[] {'\xFA00', '\x08D5'},
+            new char[] {'\xFA01', '\x08D6'},
+            new char[] {'\xFA02', '\x08D7'},
+            new char[] {'\xFA03', '\x08D8'},
+            new char[] {'\xFA04', '\x08D9'},
+            new char[] {'\xFA05', '\x08DA'},
+            new char[] {'\xFA06', '\x08DB'},
+            new char[] {'\xFA07', '\x08DC'},
+            new char[] {'\xFA08', '\x0536'},
+            new char[] {'\xFA09', '\x08DD'},
+            new char[] {'\xFA0A', '\x0539'},
+            new char[] {'\xFA0B', '\x08DE'},
+            new char[] {'\xFA0C', '\x08DF'},
+            new char[] {'\xFA0D', '\x08E0'},
+            new char[] {'\xFA10', '\x08E1'},
+            new char[] {'\xFA12', '\x08E2'},
+            new char[] {'\xFA15', '\x08E3'},
+            new char[] {'\xFA16', '\x08E4'},
+            new char[] {'\xFA17', '\x08E5'},
+            new char[] {'\xFA18', '\x08E6'},
+            new char[] {'\xFA19', '\x08E7'},
+            new char[] {'\xFA1A', '\x08E8'},
+            new char[] {'\xFA1B', '\x08E9'},
+            new char[] {'\xFA1C', '\x08EA'},
+            new char[] {'\xFA1D', '\x08EB'},
+            new char[] {'\xFA1E', '\x0522'},
+            new char[] {'\xFA20', '\x08EC'},
+            new char[] {'\xFA22', '\x08ED'},
+            new char[] {'\xFA25', '\x08EE'},
+            new char[] {'\xFA26', '\x08EF'},
+            new char[] {'\xFA2A', '\x08F0'},
+            new char[] {'\xFA2B', '\x08F1'},
+            new char[] {'\xFA2C', '\x08F2'},
+            new char[] {'\xFA2D', '\x08F3'},
+            new char[] {'\xFA30', '\x08F4'},
+            new char[] {'\xFA31', '\x08F5'},
+            new char[] {'\xFA32', '\x08F6'},
+            new char[] {'\xFA33', '\x08F7'},
+            new char[] {'\xFA34', '\x08F8'},
+            new char[] {'\xFA35', '\x08F9'},
+            new char[] {'\xFA36', '\x08FA'},
+            new char[] {'\xFA37', '\x08FB'},
+            new char[] {'\xFA38', '\x08FC'},
+            new char[] {'\xFA39', '\x08FD'},
+            new char[] {'\xFA3A', '\x08FE'},
+            new char[] {'\xFA3B', '\x08FF'},
+            new char[] {'\xFA3C', '\x04D3'},
+            new char[] {'\xFA3D', '\x0900'},
+            new char[] {'\xFA3E', '\x0901'},
+            new char[] {'\xFA3F', '\x0902'},
+            new char[] {'\xFA40', '\x0903'},
+            new char[] {'\xFA41', '\x0904'},
+            new char[] {'\xFA42', '\x0905'},
+            new char[] {'\xFA43', '\x0906'},
+            new char[] {'\xFA44', '\x0907'},
+            new char[] {'\xFA45', '\x0908'},
+            new char[] {'\xFA46', '\x0909'},
+            new char[] {'\xFA47', '\x090A'},
+            new char[] {'\xFA48', '\x090B'},
+            new char[] {'\xFA49', '\x090C'},
+            new char[] {'\xFA4A', '\x090D'},
+            new char[] {'\xFA4B', '\x090E'},
+            new char[] {'\xFA4C', '\x068A'},
+            new char[] {'\xFA4D', '\x090F'},
+            new char[] {'\xFA4E', '\x0910'},
+            new char[] {'\xFA4F', '\x0911'},
+            new char[] {'\xFA50', '\x0912'},
+            new char[] {'\xFA51', '\x068E'},
+            new char[] {'\xFA52', '\x0913'},
+            new char[] {'\xFA53', '\x0914'},
+            new char[] {'\xFA54', '\x0915'},
+            new char[] {'\xFA55', '\x0916'},
+            new char[] {'\xFA56', '\x0917'},
+            new char[] {'\xFA57', '\x0873'},
+            new char[] {'\xFA58', '\x0918'},
+            new char[] {'\xFA59', '\x0919'},
+            new char[] {'\xFA5A', '\x091A'},
+            new char[] {'\xFA5B', '\x091B'},
+            new char[] {'\xFA5C', '\x091C'},
+            new char[] {'\xFA5D', '\x091D'},
+            new char[] {'\xFA5E', '\x091D'},
+            new char[] {'\xFA5F', '\x091E'},
+            new char[] {'\xFA60', '\x091F'},
+            new char[] {'\xFA61', '\x0920'},
+            new char[] {'\xFA62', '\x0921'},
+            new char[] {'\xFA63', '\x0922'},
+            new char[] {'\xFA64', '\x0923'},
+            new char[] {'\xFA65', '\x0924'},
+            new char[] {'\xFA66', '\x0925'},
+            new char[] {'\xFA67', '\x08EE'},
+            new char[] {'\xFA68', '\x0926'},
+            new char[] {'\xFA69', '\x0927'},
+            new char[] {'\xFA6A', '\x0928'},
+            new char[] {'\xFB00', '\x0929'},
+            new char[] {'\xFB01', '\x092A'},
+            new char[] {'\xFB02', '\x092B'},
+            new char[] {'\xFB03', '\x092C'},
+            new char[] {'\xFB04', '\x092D'},
+            new char[] {'\xFB05', '\x092E'},
+            new char[] {'\xFB06', '\x092E'},
+            new char[] {'\xFB13', '\x092F'},
+            new char[] {'\xFB14', '\x0930'},
+            new char[] {'\xFB15', '\x0931'},
+            new char[] {'\xFB16', '\x0932'},
+            new char[] {'\xFB17', '\x0933'},
+            new char[] {'\xFB1D', '\x0934'},
+            new char[] {'\xFB1F', '\x0935'},
+            new char[] {'\xFB20', '\x0936'},
+            new char[] {'\xFB21', '\x03E2'},
+            new char[] {'\xFB22', '\x03E5'},
+            new char[] {'\xFB23', '\x0937'},
+            new char[] {'\xFB24', '\x0938'},
+            new char[] {'\xFB25', '\x0939'},
+            new char[] {'\xFB26', '\x093A'},
+            new char[] {'\xFB27', '\x093B'},
+            new char[] {'\xFB28', '\x093C'},
+            new char[] {'\xFB29', '\x03BE'},
+            new char[] {'\xFB2A', '\x093D'},
+            new char[] {'\xFB2B', '\x093E'},
+            new char[] {'\xFB2C', '\x093F'},
+            new char[] {'\xFB2D', '\x0940'},
+            new char[] {'\xFB2E', '\x0941'},
+            new char[] {'\xFB2F', '\x0942'},
+            new char[] {'\xFB30', '\x0943'},
+            new char[] {'\xFB31', '\x0944'},
+            new char[] {'\xFB32', '\x0945'},
+            new char[] {'\xFB33', '\x0946'},
+            new char[] {'\xFB34', '\x0947'},
+            new char[] {'\xFB35', '\x0948'},
+            new char[] {'\xFB36', '\x0949'},
+            new char[] {'\xFB38', '\x094A'},
+            new char[] {'\xFB39', '\x094B'},
+            new char[] {'\xFB3A', '\x094C'},
+            new char[] {'\xFB3B', '\x094D'},
+            new char[] {'\xFB3C', '\x094E'},
+            new char[] {'\xFB3E', '\x094F'},
+            new char[] {'\xFB40', '\x0950'},
+            new char[] {'\xFB41', '\x0951'},
+            new char[] {'\xFB43', '\x0952'},
+            new char[] {'\xFB44', '\x0953'},
+            new char[] {'\xFB46', '\x0954'},
+            new char[] {'\xFB47', '\x0955'},
+            new char[] {'\xFB48', '\x0956'},
+            new char[] {'\xFB49', '\x0957'},
+            new char[] {'\xFB4A', '\x0958'},
+            new char[] {'\xFB4B', '\x0959'},
+            new char[] {'\xFB4C', '\x095A'},
+            new char[] {'\xFB4D', '\x095B'},
+            new char[] {'\xFB4E', '\x095C'},
+            new char[] {'\xFB4F', '\x095D'},
+            new char[] {'\xFB50', '\x095E'},
+            new char[] {'\xFB51', '\x095E'},
+            new char[] {'\xFB52', '\x095F'},
+            new char[] {'\xFB53', '\x095F'},
+            new char[] {'\xFB54', '\x095F'},
+            new char[] {'\xFB55', '\x095F'},
+            new char[] {'\xFB56', '\x0960'},
+            new char[] {'\xFB57', '\x0960'},
+            new char[] {'\xFB58', '\x0960'},
+            new char[] {'\xFB59', '\x0960'},
+            new char[] {'\xFB5A', '\x0961'},
+            new char[] {'\xFB5B', '\x0961'},
+            new char[] {'\xFB5C', '\x0961'},
+            new char[] {'\xFB5D', '\x0961'},
+            new char[] {'\xFB5E', '\x0962'},
+            new char[] {'\xFB5F', '\x0962'},
+            new char[] {'\xFB60', '\x0962'},
+            new char[] {'\xFB61', '\x0962'},
+            new char[] {'\xFB62', '\x0963'},
+            new char[] {'\xFB63', '\x0963'},
+            new char[] {'\xFB64', '\x0963'},
+            new char[] {'\xFB65', '\x0963'},
+            new char[] {'\xFB66', '\x0964'},
+            new char[] {'\xFB67', '\x0964'},
+            new char[] {'\xFB68', '\x0964'},
+            new char[] {'\xFB69', '\x0964'},
+            new char[] {'\xFB6A', '\x0965'},
+            new char[] {'\xFB6B', '\x0965'},
+            new char[] {'\xFB6C', '\x0965'},
+            new char[] {'\xFB6D', '\x0965'},
+            new char[] {'\xFB6E', '\x0966'},
+            new char[] {'\xFB6F', '\x0966'},
+            new char[] {'\xFB70', '\x0966'},
+            new char[] {'\xFB71', '\x0966'},
+            new char[] {'\xFB72', '\x0967'},
+            new char[] {'\xFB73', '\x0967'},
+            new char[] {'\xFB74', '\x0967'},
+            new char[] {'\xFB75', '\x0967'},
+            new char[] {'\xFB76', '\x0968'},
+            new char[] {'\xFB77', '\x0968'},
+            new char[] {'\xFB78', '\x0968'},
+            new char[] {'\xFB79', '\x0968'},
+            new char[] {'\xFB7A', '\x0969'},
+            new char[] {'\xFB7B', '\x0969'},
+            new char[] {'\xFB7C', '\x0969'},
+            new char[] {'\xFB7D', '\x0969'},
+            new char[] {'\xFB7E', '\x096A'},
+            new char[] {'\xFB7F', '\x096A'},
+            new char[] {'\xFB80', '\x096A'},
+            new char[] {'\xFB81', '\x096A'},
+            new char[] {'\xFB82', '\x096B'},
+            new char[] {'\xFB83', '\x096B'},
+            new char[] {'\xFB84', '\x096C'},
+            new char[] {'\xFB85', '\x096C'},
+            new char[] {'\xFB86', '\x096D'},
+            new char[] {'\xFB87', '\x096D'},
+            new char[] {'\xFB88', '\x096E'},
+            new char[] {'\xFB89', '\x096E'},
+            new char[] {'\xFB8A', '\x096F'},
+            new char[] {'\xFB8B', '\x096F'},
+            new char[] {'\xFB8C', '\x0970'},
+            new char[] {'\xFB8D', '\x0970'},
+            new char[] {'\xFB8E', '\x0971'},
+            new char[] {'\xFB8F', '\x0971'},
+            new char[] {'\xFB90', '\x0971'},
+            new char[] {'\xFB91', '\x0971'},
+            new char[] {'\xFB92', '\x0972'},
+            new char[] {'\xFB93', '\x0972'},
+            new char[] {'\xFB94', '\x0972'},
+            new char[] {'\xFB95', '\x0972'},
+            new char[] {'\xFB96', '\x0973'},
+            new char[] {'\xFB97', '\x0973'},
+            new char[] {'\xFB98', '\x0973'},
+            new char[] {'\xFB99', '\x0973'},
+            new char[] {'\xFB9A', '\x0974'},
+            new char[] {'\xFB9B', '\x0974'},
+            new char[] {'\xFB9C', '\x0974'},
+            new char[] {'\xFB9D', '\x0974'},
+            new char[] {'\xFB9E', '\x0975'},
+            new char[] {'\xFB9F', '\x0975'},
+            new char[] {'\xFBA0', '\x0976'},
+            new char[] {'\xFBA1', '\x0976'},
+            new char[] {'\xFBA2', '\x0976'},
+            new char[] {'\xFBA3', '\x0976'},
+            new char[] {'\xFBA4', '\x0194'},
+            new char[] {'\xFBA5', '\x0194'},
+            new char[] {'\xFBA6', '\x0977'},
+            new char[] {'\xFBA7', '\x0977'},
+            new char[] {'\xFBA8', '\x0977'},
+            new char[] {'\xFBA9', '\x0977'},
+            new char[] {'\xFBAA', '\x0978'},
+            new char[] {'\xFBAB', '\x0978'},
+            new char[] {'\xFBAC', '\x0978'},
+            new char[] {'\xFBAD', '\x0978'},
+            new char[] {'\xFBAE', '\x0979'},
+            new char[] {'\xFBAF', '\x0979'},
+            new char[] {'\xFBB0', '\x0196'},
+            new char[] {'\xFBB1', '\x0196'},
+            new char[] {'\xFBD3', '\x097A'},
+            new char[] {'\xFBD4', '\x097A'},
+            new char[] {'\xFBD5', '\x097A'},
+            new char[] {'\xFBD6', '\x097A'},
+            new char[] {'\xFBD7', '\x097B'},
+            new char[] {'\xFBD8', '\x097B'},
+            new char[] {'\xFBD9', '\x097C'},
+            new char[] {'\xFBDA', '\x097C'},
+            new char[] {'\xFBDB', '\x097D'},
+            new char[] {'\xFBDC', '\x097D'},
+            new char[] {'\xFBDD', '\x0192'},
+            new char[] {'\xFBDE', '\x097E'},
+            new char[] {'\xFBDF', '\x097E'},
+            new char[] {'\xFBE0', '\x097F'},
+            new char[] {'\xFBE1', '\x097F'},
+            new char[] {'\xFBE2', '\x0980'},
+            new char[] {'\xFBE3', '\x0980'},
+            new char[] {'\xFBE4', '\x0981'},
+            new char[] {'\xFBE5', '\x0981'},
+            new char[] {'\xFBE6', '\x0981'},
+            new char[] {'\xFBE7', '\x0981'},
+            new char[] {'\xFBE8', '\x0982'},
+            new char[] {'\xFBE9', '\x0982'},
+            new char[] {'\xFBEA', '\x0983'},
+            new char[] {'\xFBEB', '\x0983'},
+            new char[] {'\xFBEC', '\x0984'},
+            new char[] {'\xFBED', '\x0984'},
+            new char[] {'\xFBEE', '\x0985'},
+            new char[] {'\xFBEF', '\x0985'},
+            new char[] {'\xFBF0', '\x0986'},
+            new char[] {'\xFBF1', '\x0986'},
+            new char[] {'\xFBF2', '\x0987'},
+            new char[] {'\xFBF3', '\x0987'},
+            new char[] {'\xFBF4', '\x0988'},
+            new char[] {'\xFBF5', '\x0988'},
+            new char[] {'\xFBF6', '\x0989'},
+            new char[] {'\xFBF7', '\x0989'},
+            new char[] {'\xFBF8', '\x0989'},
+            new char[] {'\xFBF9', '\x098A'},
+            new char[] {'\xFBFA', '\x098A'},
+            new char[] {'\xFBFB', '\x098A'},
+            new char[] {'\xFBFC', '\x098B'},
+            new char[] {'\xFBFD', '\x098B'},
+            new char[] {'\xFBFE', '\x098B'},
+            new char[] {'\xFBFF', '\x098B'},
+            new char[] {'\xFC00', '\x098C'},
+            new char[] {'\xFC01', '\x098D'},
+            new char[] {'\xFC02', '\x098E'},
+            new char[] {'\xFC03', '\x098A'},
+            new char[] {'\xFC04', '\x098F'},
+            new char[] {'\xFC05', '\x0990'},
+            new char[] {'\xFC06', '\x0991'},
+            new char[] {'\xFC07', '\x0992'},
+            new char[] {'\xFC08', '\x0993'},
+            new char[] {'\xFC09', '\x0994'},
+            new char[] {'\xFC0A', '\x0995'},
+            new char[] {'\xFC0B', '\x0996'},
+            new char[] {'\xFC0C', '\x0997'},
+            new char[] {'\xFC0D', '\x0998'},
+            new char[] {'\xFC0E', '\x0999'},
+            new char[] {'\xFC0F', '\x099A'},
+            new char[] {'\xFC10', '\x099B'},
+            new char[] {'\xFC11', '\x099C'},
+            new char[] {'\xFC12', '\x099D'},
+            new char[] {'\xFC13', '\x099E'},
+            new char[] {'\xFC14', '\x099F'},
+            new char[] {'\xFC15', '\x09A0'},
+            new char[] {'\xFC16', '\x09A1'},
+            new char[] {'\xFC17', '\x09A2'},
+            new char[] {'\xFC18', '\x09A3'},
+            new char[] {'\xFC19', '\x09A4'},
+            new char[] {'\xFC1A', '\x09A5'},
+            new char[] {'\xFC1B', '\x09A6'},
+            new char[] {'\xFC1C', '\x09A7'},
+            new char[] {'\xFC1D', '\x09A8'},
+            new char[] {'\xFC1E', '\x09A9'},
+            new char[] {'\xFC1F', '\x09AA'},
+            new char[] {'\xFC20', '\x09AB'},
+            new char[] {'\xFC21', '\x09AC'},
+            new char[] {'\xFC22', '\x09AD'},
+            new char[] {'\xFC23', '\x09AE'},
+            new char[] {'\xFC24', '\x09AF'},
+            new char[] {'\xFC25', '\x09B0'},
+            new char[] {'\xFC26', '\x09B1'},
+            new char[] {'\xFC27', '\x09B2'},
+            new char[] {'\xFC28', '\x09B3'},
+            new char[] {'\xFC29', '\x09B4'},
+            new char[] {'\xFC2A', '\x09B5'},
+            new char[] {'\xFC2B', '\x09B6'},
+            new char[] {'\xFC2C', '\x09B7'},
+            new char[] {'\xFC2D', '\x09B8'},
+            new char[] {'\xFC2E', '\x09B9'},
+            new char[] {'\xFC2F', '\x09BA'},
+            new char[] {'\xFC30', '\x09BB'},
+            new char[] {'\xFC31', '\x09BC'},
+            new char[] {'\xFC32', '\x09BD'},
+            new char[] {'\xFC33', '\x09BE'},
+            new char[] {'\xFC34', '\x09BF'},
+            new char[] {'\xFC35', '\x09C0'},
+            new char[] {'\xFC36', '\x09C1'},
+            new char[] {'\xFC37', '\x09C2'},
+            new char[] {'\xFC38', '\x09C3'},
+            new char[] {'\xFC39', '\x09C4'},
+            new char[] {'\xFC3A', '\x09C5'},
+            new char[] {'\xFC3B', '\x09C6'},
+            new char[] {'\xFC3C', '\x09C7'},
+            new char[] {'\xFC3D', '\x09C8'},
+            new char[] {'\xFC3E', '\x09C9'},
+            new char[] {'\xFC3F', '\x09CA'},
+            new char[] {'\xFC40', '\x09CB'},
+            new char[] {'\xFC41', '\x09CC'},
+            new char[] {'\xFC42', '\x09CD'},
+            new char[] {'\xFC43', '\x09CE'},
+            new char[] {'\xFC44', '\x09CF'},
+            new char[] {'\xFC45', '\x09D0'},
+            new char[] {'\xFC46', '\x09D1'},
+            new char[] {'\xFC47', '\x09D2'},
+            new char[] {'\xFC48', '\x09D3'},
+            new char[] {'\xFC49', '\x09D4'},
+            new char[] {'\xFC4A', '\x09D5'},
+            new char[] {'\xFC4B', '\x09D6'},
+            new char[] {'\xFC4C', '\x09D7'},
+            new char[] {'\xFC4D', '\x09D8'},
+            new char[] {'\xFC4E', '\x09D9'},
+            new char[] {'\xFC4F', '\x09DA'},
+            new char[] {'\xFC50', '\x09DB'},
+            new char[] {'\xFC51', '\x09DC'},
+            new char[] {'\xFC52', '\x09DD'},
+            new char[] {'\xFC53', '\x09DE'},
+            new char[] {'\xFC54', '\x09DF'},
+            new char[] {'\xFC55', '\x09E0'},
+            new char[] {'\xFC56', '\x09E1'},
+            new char[] {'\xFC57', '\x09E2'},
+            new char[] {'\xFC58', '\x09E3'},
+            new char[] {'\xFC59', '\x09E4'},
+            new char[] {'\xFC5A', '\x09E5'},
+            new char[] {'\xFC5B', '\x09E6'},
+            new char[] {'\xFC5C', '\x09E7'},
+            new char[] {'\xFC5D', '\x09E8'},
+            new char[] {'\xFC5E', '\x09E9'},
+            new char[] {'\xFC5F', '\x09EA'},
+            new char[] {'\xFC60', '\x09EB'},
+            new char[] {'\xFC61', '\x09EC'},
+            new char[] {'\xFC62', '\x09ED'},
+            new char[] {'\xFC63', '\x09EE'},
+            new char[] {'\xFC64', '\x09EF'},
+            new char[] {'\xFC65', '\x09F0'},
+            new char[] {'\xFC66', '\x098E'},
+            new char[] {'\xFC67', '\x09F1'},
+            new char[] {'\xFC68', '\x098A'},
+            new char[] {'\xFC69', '\x098F'},
+            new char[] {'\xFC6A', '\x09F2'},
+            new char[] {'\xFC6B', '\x09F3'},
+            new char[] {'\xFC6C', '\x0993'},
+            new char[] {'\xFC6D', '\x09F4'},
+            new char[] {'\xFC6E', '\x0994'},
+            new char[] {'\xFC6F', '\x0995'},
+            new char[] {'\xFC70', '\x09F5'},
+            new char[] {'\xFC71', '\x09F6'},
+            new char[] {'\xFC72', '\x0999'},
+            new char[] {'\xFC73', '\x09F7'},
+            new char[] {'\xFC74', '\x099A'},
+            new char[] {'\xFC75', '\x099B'},
+            new char[] {'\xFC76', '\x09F8'},
+            new char[] {'\xFC77', '\x09F9'},
+            new char[] {'\xFC78', '\x099D'},
+            new char[] {'\xFC79', '\x09FA'},
+            new char[] {'\xFC7A', '\x099E'},
+            new char[] {'\xFC7B', '\x099F'},
+            new char[] {'\xFC7C', '\x09BC'},
+            new char[] {'\xFC7D', '\x09BD'},
+            new char[] {'\xFC7E', '\x09C0'},
+            new char[] {'\xFC7F', '\x09C1'},
+            new char[] {'\xFC80', '\x09C2'},
+            new char[] {'\xFC81', '\x09C6'},
+            new char[] {'\xFC82', '\x09C7'},
+            new char[] {'\xFC83', '\x09C8'},
+            new char[] {'\xFC84', '\x09C9'},
+            new char[] {'\xFC85', '\x09CD'},
+            new char[] {'\xFC86', '\x09CE'},
+            new char[] {'\xFC87', '\x09CF'},
+            new char[] {'\xFC88', '\x09FB'},
+            new char[] {'\xFC89', '\x09D3'},
+            new char[] {'\xFC8A', '\x09FC'},
+            new char[] {'\xFC8B', '\x09FD'},
+            new char[] {'\xFC8C', '\x09D9'},
+            new char[] {'\xFC8D', '\x09FE'},
+            new char[] {'\xFC8E', '\x09DA'},
+            new char[] {'\xFC8F', '\x09DB'},
+            new char[] {'\xFC90', '\x09E8'},
+            new char[] {'\xFC91', '\x09FF'},
+            new char[] {'\xFC92', '\x0A00'},
+            new char[] {'\xFC93', '\x09E3'},
+            new char[] {'\xFC94', '\x0A01'},
+            new char[] {'\xFC95', '\x09E4'},
+            new char[] {'\xFC96', '\x09E5'},
+            new char[] {'\xFC97', '\x098C'},
+            new char[] {'\xFC98', '\x098D'},
+            new char[] {'\xFC99', '\x0A02'},
+            new char[] {'\xFC9A', '\x098E'},
+            new char[] {'\xFC9B', '\x0A03'},
+            new char[] {'\xFC9C', '\x0990'},
+            new char[] {'\xFC9D', '\x0991'},
+            new char[] {'\xFC9E', '\x0992'},
+            new char[] {'\xFC9F', '\x0993'},
+            new char[] {'\xFCA0', '\x0A04'},
+            new char[] {'\xFCA1', '\x0996'},
+            new char[] {'\xFCA2', '\x0997'},
+            new char[] {'\xFCA3', '\x0998'},
+            new char[] {'\xFCA4', '\x0999'},
+            new char[] {'\xFCA5', '\x0A05'},
+            new char[] {'\xFCA6', '\x099D'},
+            new char[] {'\xFCA7', '\x09A0'},
+            new char[] {'\xFCA8', '\x09A1'},
+            new char[] {'\xFCA9', '\x09A2'},
+            new char[] {'\xFCAA', '\x09A3'},
+            new char[] {'\xFCAB', '\x09A4'},
+            new char[] {'\xFCAC', '\x09A6'},
+            new char[] {'\xFCAD', '\x09A7'},
+            new char[] {'\xFCAE', '\x09A8'},
+            new char[] {'\xFCAF', '\x09A9'},
+            new char[] {'\xFCB0', '\x09AA'},
+            new char[] {'\xFCB1', '\x09AB'},
+            new char[] {'\xFCB2', '\x0A06'},
+            new char[] {'\xFCB3', '\x09AC'},
+            new char[] {'\xFCB4', '\x09AD'},
+            new char[] {'\xFCB5', '\x09AE'},
+            new char[] {'\xFCB6', '\x09AF'},
+            new char[] {'\xFCB7', '\x09B0'},
+            new char[] {'\xFCB8', '\x09B1'},
+            new char[] {'\xFCB9', '\x09B3'},
+            new char[] {'\xFCBA', '\x09B4'},
+            new char[] {'\xFCBB', '\x09B5'},
+            new char[] {'\xFCBC', '\x09B6'},
+            new char[] {'\xFCBD', '\x09B7'},
+            new char[] {'\xFCBE', '\x09B8'},
+            new char[] {'\xFCBF', '\x09B9'},
+            new char[] {'\xFCC0', '\x09BA'},
+            new char[] {'\xFCC1', '\x09BB'},
+            new char[] {'\xFCC2', '\x09BE'},
+            new char[] {'\xFCC3', '\x09BF'},
+            new char[] {'\xFCC4', '\x09C3'},
+            new char[] {'\xFCC5', '\x09C4'},
+            new char[] {'\xFCC6', '\x09C5'},
+            new char[] {'\xFCC7', '\x09C6'},
+            new char[] {'\xFCC8', '\x09C7'},
+            new char[] {'\xFCC9', '\x09CA'},
+            new char[] {'\xFCCA', '\x09CB'},
+            new char[] {'\xFCCB', '\x09CC'},
+            new char[] {'\xFCCC', '\x09CD'},
+            new char[] {'\xFCCD', '\x0A07'},
+            new char[] {'\xFCCE', '\x09D0'},
+            new char[] {'\xFCCF', '\x09D1'},
+            new char[] {'\xFCD0', '\x09D2'},
+            new char[] {'\xFCD1', '\x09D3'},
+            new char[] {'\xFCD2', '\x09D6'},
+            new char[] {'\xFCD3', '\x09D7'},
+            new char[] {'\xFCD4', '\x09D8'},
+            new char[] {'\xFCD5', '\x09D9'},
+            new char[] {'\xFCD6', '\x0A08'},
+            new char[] {'\xFCD7', '\x09DC'},
+            new char[] {'\xFCD8', '\x09DD'},
+            new char[] {'\xFCD9', '\x0A09'},
+            new char[] {'\xFCDA', '\x09E0'},
+            new char[] {'\xFCDB', '\x09E1'},
+            new char[] {'\xFCDC', '\x09E2'},
+            new char[] {'\xFCDD', '\x09E3'},
+            new char[] {'\xFCDE', '\x0A0A'},
+            new char[] {'\xFCDF', '\x098E'},
+            new char[] {'\xFCE0', '\x0A03'},
+            new char[] {'\xFCE1', '\x0993'},
+            new char[] {'\xFCE2', '\x0A04'},
+            new char[] {'\xFCE3', '\x0999'},
+            new char[] {'\xFCE4', '\x0A05'},
+            new char[] {'\xFCE5', '\x099D'},
+            new char[] {'\xFCE6', '\x0A0B'},
+            new char[] {'\xFCE7', '\x09AA'},
+            new char[] {'\xFCE8', '\x0A0C'},
+            new char[] {'\xFCE9', '\x0A0D'},
+            new char[] {'\xFCEA', '\x0A0E'},
+            new char[] {'\xFCEB', '\x09C6'},
+            new char[] {'\xFCEC', '\x09C7'},
+            new char[] {'\xFCED', '\x09CD'},
+            new char[] {'\xFCEE', '\x09D9'},
+            new char[] {'\xFCEF', '\x0A08'},
+            new char[] {'\xFCF0', '\x09E3'},
+            new char[] {'\xFCF1', '\x0A0A'},
+            new char[] {'\xFCF2', '\x0A0F'},
+            new char[] {'\xFCF3', '\x0A10'},
+            new char[] {'\xFCF4', '\x0A11'},
+            new char[] {'\xFCF5', '\x0A12'},
+            new char[] {'\xFCF6', '\x0A13'},
+            new char[] {'\xFCF7', '\x0A14'},
+            new char[] {'\xFCF8', '\x0A15'},
+            new char[] {'\xFCF9', '\x0A16'},
+            new char[] {'\xFCFA', '\x0A17'},
+            new char[] {'\xFCFB', '\x0A18'},
+            new char[] {'\xFCFC', '\x0A19'},
+            new char[] {'\xFCFD', '\x0A1A'},
+            new char[] {'\xFCFE', '\x0A1B'},
+            new char[] {'\xFCFF', '\x0A1C'},
+            new char[] {'\xFD00', '\x0A1D'},
+            new char[] {'\xFD01', '\x0A1E'},
+            new char[] {'\xFD02', '\x0A1F'},
+            new char[] {'\xFD03', '\x0A20'},
+            new char[] {'\xFD04', '\x0A21'},
+            new char[] {'\xFD05', '\x0A22'},
+            new char[] {'\xFD06', '\x0A23'},
+            new char[] {'\xFD07', '\x0A24'},
+            new char[] {'\xFD08', '\x0A25'},
+            new char[] {'\xFD09', '\x0A26'},
+            new char[] {'\xFD0A', '\x0A27'},
+            new char[] {'\xFD0B', '\x0A28'},
+            new char[] {'\xFD0C', '\x0A0D'},
+            new char[] {'\xFD0D', '\x0A29'},
+            new char[] {'\xFD0E', '\x0A2A'},
+            new char[] {'\xFD0F', '\x0A2B'},
+            new char[] {'\xFD10', '\x0A2C'},
+            new char[] {'\xFD11', '\x0A12'},
+            new char[] {'\xFD12', '\x0A13'},
+            new char[] {'\xFD13', '\x0A14'},
+            new char[] {'\xFD14', '\x0A15'},
+            new char[] {'\xFD15', '\x0A16'},
+            new char[] {'\xFD16', '\x0A17'},
+            new char[] {'\xFD17', '\x0A18'},
+            new char[] {'\xFD18', '\x0A19'},
+            new char[] {'\xFD19', '\x0A1A'},
+            new char[] {'\xFD1A', '\x0A1B'},
+            new char[] {'\xFD1B', '\x0A1C'},
+            new char[] {'\xFD1C', '\x0A1D'},
+            new char[] {'\xFD1D', '\x0A1E'},
+            new char[] {'\xFD1E', '\x0A1F'},
+            new char[] {'\xFD1F', '\x0A20'},
+            new char[] {'\xFD20', '\x0A21'},
+            new char[] {'\xFD21', '\x0A22'},
+            new char[] {'\xFD22', '\x0A23'},
+            new char[] {'\xFD23', '\x0A24'},
+            new char[] {'\xFD24', '\x0A25'},
+            new char[] {'\xFD25', '\x0A26'},
+            new char[] {'\xFD26', '\x0A27'},
+            new char[] {'\xFD27', '\x0A28'},
+            new char[] {'\xFD28', '\x0A0D'},
+            new char[] {'\xFD29', '\x0A29'},
+            new char[] {'\xFD2A', '\x0A2A'},
+            new char[] {'\xFD2B', '\x0A2B'},
+            new char[] {'\xFD2C', '\x0A2C'},
+            new char[] {'\xFD2D', '\x0A26'},
+            new char[] {'\xFD2E', '\x0A27'},
+            new char[] {'\xFD2F', '\x0A28'},
+            new char[] {'\xFD30', '\x0A0D'},
+            new char[] {'\xFD31', '\x0A0C'},
+            new char[] {'\xFD32', '\x0A0E'},
+            new char[] {'\xFD33', '\x09B2'},
+            new char[] {'\xFD34', '\x09A7'},
+            new char[] {'\xFD35', '\x09A8'},
+            new char[] {'\xFD36', '\x09A9'},
+            new char[] {'\xFD37', '\x0A26'},
+            new char[] {'\xFD38', '\x0A27'},
+            new char[] {'\xFD39', '\x0A28'},
+            new char[] {'\xFD3A', '\x09B2'},
+            new char[] {'\xFD3B', '\x09B3'},
+            new char[] {'\xFD3C', '\x0A2D'},
+            new char[] {'\xFD3D', '\x0A2D'},
+            new char[] {'\xFD50', '\x0A2E'},
+            new char[] {'\xFD51', '\x0A2F'},
+            new char[] {'\xFD52', '\x0A2F'},
+            new char[] {'\xFD53', '\x0A30'},
+            new char[] {'\xFD54', '\x0A31'},
+            new char[] {'\xFD55', '\x0A32'},
+            new char[] {'\xFD56', '\x0A33'},
+            new char[] {'\xFD57', '\x0A34'},
+            new char[] {'\xFD58', '\x0A35'},
+            new char[] {'\xFD59', '\x0A35'},
+            new char[] {'\xFD5A', '\x0A36'},
+            new char[] {'\xFD5B', '\x0A37'},
+            new char[] {'\xFD5C', '\x0A38'},
+            new char[] {'\xFD5D', '\x0A39'},
+            new char[] {'\xFD5E', '\x0A3A'},
+            new char[] {'\xFD5F', '\x0A3B'},
+            new char[] {'\xFD60', '\x0A3B'},
+            new char[] {'\xFD61', '\x0A3C'},
+            new char[] {'\xFD62', '\x0A3D'},
+            new char[] {'\xFD63', '\x0A3D'},
+            new char[] {'\xFD64', '\x0A3E'},
+            new char[] {'\xFD65', '\x0A3E'},
+            new char[] {'\xFD66', '\x0A3F'},
+            new char[] {'\xFD67', '\x0A40'},
+            new char[] {'\xFD68', '\x0A40'},
+            new char[] {'\xFD69', '\x0A41'},
+            new char[] {'\xFD6A', '\x0A42'},
+            new char[] {'\xFD6B', '\x0A42'},
+            new char[] {'\xFD6C', '\x0A43'},
+            new char[] {'\xFD6D', '\x0A43'},
+            new char[] {'\xFD6E', '\x0A44'},
+            new char[] {'\xFD6F', '\x0A45'},
+            new char[] {'\xFD70', '\x0A45'},
+            new char[] {'\xFD71', '\x0A46'},
+            new char[] {'\xFD72', '\x0A46'},
+            new char[] {'\xFD73', '\x0A47'},
+            new char[] {'\xFD74', '\x0A48'},
+            new char[] {'\xFD75', '\x0A49'},
+            new char[] {'\xFD76', '\x0A4A'},
+            new char[] {'\xFD77', '\x0A4A'},
+            new char[] {'\xFD78', '\x0A4B'},
+            new char[] {'\xFD79', '\x0A4C'},
+            new char[] {'\xFD7A', '\x0A4D'},
+            new char[] {'\xFD7B', '\x0A4E'},
+            new char[] {'\xFD7C', '\x0A4F'},
+            new char[] {'\xFD7D', '\x0A4F'},
+            new char[] {'\xFD7E', '\x0A50'},
+            new char[] {'\xFD7F', '\x0A51'},
+            new char[] {'\xFD80', '\x0A52'},
+            new char[] {'\xFD81', '\x0A53'},
+            new char[] {'\xFD82', '\x0A54'},
+            new char[] {'\xFD83', '\x0A55'},
+            new char[] {'\xFD84', '\x0A55'},
+            new char[] {'\xFD85', '\x0A56'},
+            new char[] {'\xFD86', '\x0A56'},
+            new char[] {'\xFD87', '\x0A57'},
+            new char[] {'\xFD88', '\x0A57'},
+            new char[] {'\xFD89', '\x0A58'},
+            new char[] {'\xFD8A', '\x0A59'},
+            new char[] {'\xFD8B', '\x0A5A'},
+            new char[] {'\xFD8C', '\x0A5B'},
+            new char[] {'\xFD8D', '\x0A5C'},
+            new char[] {'\xFD8E', '\x0A5D'},
+            new char[] {'\xFD8F', '\x0A5E'},
+            new char[] {'\xFD92', '\x0A5F'},
+            new char[] {'\xFD93', '\x0A60'},
+            new char[] {'\xFD94', '\x0A61'},
+            new char[] {'\xFD95', '\x0A62'},
+            new char[] {'\xFD96', '\x0A63'},
+            new char[] {'\xFD97', '\x0A64'},
+            new char[] {'\xFD98', '\x0A64'},
+            new char[] {'\xFD99', '\x0A65'},
+            new char[] {'\xFD9A', '\x0A66'},
+            new char[] {'\xFD9B', '\x0A67'},
+            new char[] {'\xFD9C', '\x0A68'},
+            new char[] {'\xFD9D', '\x0A68'},
+            new char[] {'\xFD9E', '\x0A69'},
+            new char[] {'\xFD9F', '\x0A6A'},
+            new char[] {'\xFDA0', '\x0A6B'},
+            new char[] {'\xFDA1', '\x0A6C'},
+            new char[] {'\xFDA2', '\x0A6D'},
+            new char[] {'\xFDA3', '\x0A6E'},
+            new char[] {'\xFDA4', '\x0A6F'},
+            new char[] {'\xFDA5', '\x0A70'},
+            new char[] {'\xFDA6', '\x0A71'},
+            new char[] {'\xFDA7', '\x0A72'},
+            new char[] {'\xFDA8', '\x0A73'},
+            new char[] {'\xFDA9', '\x0A74'},
+            new char[] {'\xFDAA', '\x0A75'},
+            new char[] {'\xFDAB', '\x0A76'},
+            new char[] {'\xFDAC', '\x0A77'},
+            new char[] {'\xFDAD', '\x0A78'},
+            new char[] {'\xFDAE', '\x0A79'},
+            new char[] {'\xFDAF', '\x0A7A'},
+            new char[] {'\xFDB0', '\x0A7B'},
+            new char[] {'\xFDB1', '\x0A7C'},
+            new char[] {'\xFDB2', '\x0A7D'},
+            new char[] {'\xFDB3', '\x0A7E'},
+            new char[] {'\xFDB4', '\x0A50'},
+            new char[] {'\xFDB5', '\x0A52'},
+            new char[] {'\xFDB6', '\x0A7F'},
+            new char[] {'\xFDB7', '\x0A80'},
+            new char[] {'\xFDB8', '\x0A81'},
+            new char[] {'\xFDB9', '\x0A82'},
+            new char[] {'\xFDBA', '\x0A83'},
+            new char[] {'\xFDBB', '\x0A84'},
+            new char[] {'\xFDBC', '\x0A83'},
+            new char[] {'\xFDBD', '\x0A81'},
+            new char[] {'\xFDBE', '\x0A85'},
+            new char[] {'\xFDBF', '\x0A86'},
+            new char[] {'\xFDC0', '\x0A87'},
+            new char[] {'\xFDC1', '\x0A88'},
+            new char[] {'\xFDC2', '\x0A89'},
+            new char[] {'\xFDC3', '\x0A84'},
+            new char[] {'\xFDC4', '\x0A49'},
+            new char[] {'\xFDC5', '\x0A3F'},
+            new char[] {'\xFDC6', '\x0A8A'},
+            new char[] {'\xFDC7', '\x0A8B'},
+            new char[] {'\xFDF0', '\x0A8C'},
+            new char[] {'\xFDF1', '\x0A8D'},
+            new char[] {'\xFDF2', '\x0A8E'},
+            new char[] {'\xFDF3', '\x0A8F'},
+            new char[] {'\xFDF4', '\x0A90'},
+            new char[] {'\xFDF5', '\x0A91'},
+            new char[] {'\xFDF6', '\x0A92'},
+            new char[] {'\xFDF7', '\x0A93'},
+            new char[] {'\xFDF8', '\x0A94'},
+            new char[] {'\xFDF9', '\x0A95'},
+            new char[] {'\xFDFA', '\x0A96'},
+            new char[] {'\xFDFB', '\x0A97'},
+            new char[] {'\xFDFC', '\x0A98'},
+            new char[] {'\xFE30', '\x03AA'},
+            new char[] {'\xFE31', '\x0A99'},
+            new char[] {'\xFE32', '\x0A9A'},
+            new char[] {'\xFE33', '\x0A9B'},
+            new char[] {'\xFE34', '\x0A9B'},
+            new char[] {'\xFE35', '\x03C1'},
+            new char[] {'\xFE36', '\x03C2'},
+            new char[] {'\xFE37', '\x0A9C'},
+            new char[] {'\xFE38', '\x0A9D'},
+            new char[] {'\xFE39', '\x0A9E'},
+            new char[] {'\xFE3A', '\x0A9F'},
+            new char[] {'\xFE3B', '\x0AA0'},
+            new char[] {'\xFE3C', '\x0AA1'},
+            new char[] {'\xFE3D', '\x0AA2'},
+            new char[] {'\xFE3E', '\x0AA3'},
+            new char[] {'\xFE3F', '\x0440'},
+            new char[] {'\xFE40', '\x0441'},
+            new char[] {'\xFE41', '\x0AA4'},
+            new char[] {'\xFE42', '\x0AA5'},
+            new char[] {'\xFE43', '\x0AA6'},
+            new char[] {'\xFE44', '\x0AA7'},
+            new char[] {'\xFE49', '\x03B1'},
+            new char[] {'\xFE4A', '\x03B1'},
+            new char[] {'\xFE4B', '\x03B1'},
+            new char[] {'\xFE4C', '\x03B1'},
+            new char[] {'\xFE4D', '\x0A9B'},
+            new char[] {'\xFE4E', '\x0A9B'},
+            new char[] {'\xFE4F', '\x0A9B'},
+            new char[] {'\xFE50', '\x0AA8'},
+            new char[] {'\xFE51', '\x0AA9'},
+            new char[] {'\xFE52', '\x03A9'},
+            new char[] {'\xFE54', '\x0135'},
+            new char[] {'\xFE55', '\x0AAA'},
+            new char[] {'\xFE56', '\x0AAB'},
+            new char[] {'\xFE57', '\x0AAC'},
+            new char[] {'\xFE58', '\x0A99'},
+            new char[] {'\xFE59', '\x03C1'},
+            new char[] {'\xFE5A', '\x03C2'},
+            new char[] {'\xFE5B', '\x0A9C'},
+            new char[] {'\xFE5C', '\x0A9D'},
+            new char[] {'\xFE5D', '\x0A9E'},
+            new char[] {'\xFE5E', '\x0A9F'},
+            new char[] {'\xFE5F', '\x0AAD'},
+            new char[] {'\xFE60', '\x0AAE'},
+            new char[] {'\xFE61', '\x0AAF'},
+            new char[] {'\xFE62', '\x03BE'},
+            new char[] {'\xFE63', '\x0AB0'},
+            new char[] {'\xFE64', '\x0AB1'},
+            new char[] {'\xFE65', '\x0AB2'},
+            new char[] {'\xFE66', '\x03C0'},
+            new char[] {'\xFE68', '\x0AB3'},
+            new char[] {'\xFE69', '\x0AB4'},
+            new char[] {'\xFE6A', '\x0AB5'},
+            new char[] {'\xFE6B', '\x0AB6'},
+            new char[] {'\xFE70', '\x0AB7'},
+            new char[] {'\xFE71', '\x0AB8'},
+            new char[] {'\xFE72', '\x0AB9'},
+            new char[] {'\xFE74', '\x0ABA'},
+            new char[] {'\xFE76', '\x0ABB'},
+            new char[] {'\xFE77', '\x0ABC'},
+            new char[] {'\xFE78', '\x0ABD'},
+            new char[] {'\xFE79', '\x0ABE'},
+            new char[] {'\xFE7A', '\x0ABF'},
+            new char[] {'\xFE7B', '\x0AC0'},
+            new char[] {'\xFE7C', '\x0AC1'},
+            new char[] {'\xFE7D', '\x0AC2'},
+            new char[] {'\xFE7E', '\x0AC3'},
+            new char[] {'\xFE7F', '\x0AC4'},
+            new char[] {'\xFE80', '\x0AC5'},
+            new char[] {'\xFE81', '\x018B'},
+            new char[] {'\xFE82', '\x018B'},
+            new char[] {'\xFE83', '\x018C'},
+            new char[] {'\xFE84', '\x018C'},
+            new char[] {'\xFE85', '\x018D'},
+            new char[] {'\xFE86', '\x018D'},
+            new char[] {'\xFE87', '\x018E'},
+            new char[] {'\xFE88', '\x018E'},
+            new char[] {'\xFE89', '\x018F'},
+            new char[] {'\xFE8A', '\x018F'},
+            new char[] {'\xFE8B', '\x018F'},
+            new char[] {'\xFE8C', '\x018F'},
+            new char[] {'\xFE8D', '\x0AC6'},
+            new char[] {'\xFE8E', '\x0AC6'},
+            new char[] {'\xFE8F', '\x0AC7'},
+            new char[] {'\xFE90', '\x0AC7'},
+            new char[] {'\xFE91', '\x0AC7'},
+            new char[] {'\xFE92', '\x0AC7'},
+            new char[] {'\xFE93', '\x0AC8'},
+            new char[] {'\xFE94', '\x0AC8'},
+            new char[] {'\xFE95', '\x0AC9'},
+            new char[] {'\xFE96', '\x0AC9'},
+            new char[] {'\xFE97', '\x0AC9'},
+            new char[] {'\xFE98', '\x0AC9'},
+            new char[] {'\xFE99', '\x0ACA'},
+            new char[] {'\xFE9A', '\x0ACA'},
+            new char[] {'\xFE9B', '\x0ACA'},
+            new char[] {'\xFE9C', '\x0ACA'},
+            new char[] {'\xFE9D', '\x0ACB'},
+            new char[] {'\xFE9E', '\x0ACB'},
+            new char[] {'\xFE9F', '\x0ACB'},
+            new char[] {'\xFEA0', '\x0ACB'},
+            new char[] {'\xFEA1', '\x0ACC'},
+            new char[] {'\xFEA2', '\x0ACC'},
+            new char[] {'\xFEA3', '\x0ACC'},
+            new char[] {'\xFEA4', '\x0ACC'},
+            new char[] {'\xFEA5', '\x0ACD'},
+            new char[] {'\xFEA6', '\x0ACD'},
+            new char[] {'\xFEA7', '\x0ACD'},
+            new char[] {'\xFEA8', '\x0ACD'},
+            new char[] {'\xFEA9', '\x0ACE'},
+            new char[] {'\xFEAA', '\x0ACE'},
+            new char[] {'\xFEAB', '\x0ACF'},
+            new char[] {'\xFEAC', '\x0ACF'},
+            new char[] {'\xFEAD', '\x0AD0'},
+            new char[] {'\xFEAE', '\x0AD0'},
+            new char[] {'\xFEAF', '\x0AD1'},
+            new char[] {'\xFEB0', '\x0AD1'},
+            new char[] {'\xFEB1', '\x0AD2'},
+            new char[] {'\xFEB2', '\x0AD2'},
+            new char[] {'\xFEB3', '\x0AD2'},
+            new char[] {'\xFEB4', '\x0AD2'},
+            new char[] {'\xFEB5', '\x0AD3'},
+            new char[] {'\xFEB6', '\x0AD3'},
+            new char[] {'\xFEB7', '\x0AD3'},
+            new char[] {'\xFEB8', '\x0AD3'},
+            new char[] {'\xFEB9', '\x0AD4'},
+            new char[] {'\xFEBA', '\x0AD4'},
+            new char[] {'\xFEBB', '\x0AD4'},
+            new char[] {'\xFEBC', '\x0AD4'},
+            new char[] {'\xFEBD', '\x0AD5'},
+            new char[] {'\xFEBE', '\x0AD5'},
+            new char[] {'\xFEBF', '\x0AD5'},
+            new char[] {'\xFEC0', '\x0AD5'},
+            new char[] {'\xFEC1', '\x0AD6'},
+            new char[] {'\xFEC2', '\x0AD6'},
+            new char[] {'\xFEC3', '\x0AD6'},
+            new char[] {'\xFEC4', '\x0AD6'},
+            new char[] {'\xFEC5', '\x0AD7'},
+            new char[] {'\xFEC6', '\x0AD7'},
+            new char[] {'\xFEC7', '\x0AD7'},
+            new char[] {'\xFEC8', '\x0AD7'},
+            new char[] {'\xFEC9', '\x0AD8'},
+            new char[] {'\xFECA', '\x0AD8'},
+            new char[] {'\xFECB', '\x0AD8'},
+            new char[] {'\xFECC', '\x0AD8'},
+            new char[] {'\xFECD', '\x0AD9'},
+            new char[] {'\xFECE', '\x0AD9'},
+            new char[] {'\xFECF', '\x0AD9'},
+            new char[] {'\xFED0', '\x0AD9'},
+            new char[] {'\xFED1', '\x0ADA'},
+            new char[] {'\xFED2', '\x0ADA'},
+            new char[] {'\xFED3', '\x0ADA'},
+            new char[] {'\xFED4', '\x0ADA'},
+            new char[] {'\xFED5', '\x0ADB'},
+            new char[] {'\xFED6', '\x0ADB'},
+            new char[] {'\xFED7', '\x0ADB'},
+            new char[] {'\xFED8', '\x0ADB'},
+            new char[] {'\xFED9', '\x0ADC'},
+            new char[] {'\xFEDA', '\x0ADC'},
+            new char[] {'\xFEDB', '\x0ADC'},
+            new char[] {'\xFEDC', '\x0ADC'},
+            new char[] {'\xFEDD', '\x0ADD'},
+            new char[] {'\xFEDE', '\x0ADD'},
+            new char[] {'\xFEDF', '\x0ADD'},
+            new char[] {'\xFEE0', '\x0ADD'},
+            new char[] {'\xFEE1', '\x0ADE'},
+            new char[] {'\xFEE2', '\x0ADE'},
+            new char[] {'\xFEE3', '\x0ADE'},
+            new char[] {'\xFEE4', '\x0ADE'},
+            new char[] {'\xFEE5', '\x0ADF'},
+            new char[] {'\xFEE6', '\x0ADF'},
+            new char[] {'\xFEE7', '\x0ADF'},
+            new char[] {'\xFEE8', '\x0ADF'},
+            new char[] {'\xFEE9', '\x0AE0'},
+            new char[] {'\xFEEA', '\x0AE0'},
+            new char[] {'\xFEEB', '\x0AE0'},
+            new char[] {'\xFEEC', '\x0AE0'},
+            new char[] {'\xFEED', '\x0AE1'},
+            new char[] {'\xFEEE', '\x0AE1'},
+            new char[] {'\xFEEF', '\x0982'},
+            new char[] {'\xFEF0', '\x0982'},
+            new char[] {'\xFEF1', '\x0AE2'},
+            new char[] {'\xFEF2', '\x0AE2'},
+            new char[] {'\xFEF3', '\x0AE2'},
+            new char[] {'\xFEF4', '\x0AE2'},
+            new char[] {'\xFEF5', '\x0AE3'},
+            new char[] {'\xFEF6', '\x0AE3'},
+            new char[] {'\xFEF7', '\x0AE4'},
+            new char[] {'\xFEF8', '\x0AE4'},
+            new char[] {'\xFEF9', '\x0AE5'},
+            new char[] {'\xFEFA', '\x0AE5'},
+            new char[] {'\xFEFB', '\x0AE6'},
+            new char[] {'\xFEFC', '\x0AE6'},
+            new char[] {'\xFF01', '\x0AAC'},
+            new char[] {'\xFF02', '\x0AE7'},
+            new char[] {'\xFF03', '\x0AAD'},
+            new char[] {'\xFF04', '\x0AB4'},
+            new char[] {'\xFF05', '\x0AB5'},
+            new char[] {'\xFF06', '\x0AAE'},
+            new char[] {'\xFF07', '\x0AE8'},
+            new char[] {'\xFF08', '\x03C1'},
+            new char[] {'\xFF09', '\x03C2'},
+            new char[] {'\xFF0A', '\x0AAF'},
+            new char[] {'\xFF0B', '\x03BE'},
+            new char[] {'\xFF0C', '\x0AA8'},
+            new char[] {'\xFF0D', '\x0AB0'},
+            new char[] {'\xFF0E', '\x03A9'},
+            new char[] {'\xFF0F', '\x0AE9'},
+            new char[] {'\xFF10', '\x03B6'},
+            new char[] {'\xFF11', '\x0009'},
+            new char[] {'\xFF12', '\x0004'},
+            new char[] {'\xFF13', '\x0005'},
+            new char[] {'\xFF14', '\x03B8'},
+            new char[] {'\xFF15', '\x03B9'},
+            new char[] {'\xFF16', '\x03BA'},
+            new char[] {'\xFF17', '\x03BB'},
+            new char[] {'\xFF18', '\x03BC'},
+            new char[] {'\xFF19', '\x03BD'},
+            new char[] {'\xFF1A', '\x0AAA'},
+            new char[] {'\xFF1B', '\x0135'},
+            new char[] {'\xFF1C', '\x0AB1'},
+            new char[] {'\xFF1D', '\x03C0'},
+            new char[] {'\xFF1E', '\x0AB2'},
+            new char[] {'\xFF1F', '\x0AAB'},
+            new char[] {'\xFF20', '\x0AB6'},
+            new char[] {'\xFF21', '\x048F'},
+            new char[] {'\xFF22', '\x03DD'},
+            new char[] {'\xFF23', '\x03C7'},
+            new char[] {'\xFF24', '\x03EA'},
+            new char[] {'\xFF25', '\x03DF'},
+            new char[] {'\xFF26', '\x03E0'},
+            new char[] {'\xFF27', '\x0490'},
+            new char[] {'\xFF28', '\x03CE'},
+            new char[] {'\xFF29', '\x03D0'},
+            new char[] {'\xFF2A', '\x0491'},
+            new char[] {'\xFF2B', '\x03DC'},
+            new char[] {'\xFF2C', '\x03D1'},
+            new char[] {'\xFF2D', '\x03E1'},
+            new char[] {'\xFF2E', '\x03D2'},
+            new char[] {'\xFF2F', '\x0492'},
+            new char[] {'\xFF30', '\x03D4'},
+            new char[] {'\xFF31', '\x03D5'},
+            new char[] {'\xFF32', '\x03D6'},
+            new char[] {'\xFF33', '\x0493'},
+            new char[] {'\xFF34', '\x0494'},
+            new char[] {'\xFF35', '\x0495'},
+            new char[] {'\xFF36', '\x03FC'},
+            new char[] {'\xFF37', '\x0496'},
+            new char[] {'\xFF38', '\x0401'},
+            new char[] {'\xFF39', '\x0497'},
+            new char[] {'\xFF3A', '\x03DA'},
+            new char[] {'\xFF3B', '\x0AEA'},
+            new char[] {'\xFF3C', '\x0AB3'},
+            new char[] {'\xFF3D', '\x0AEB'},
+            new char[] {'\xFF3E', '\x0AEC'},
+            new char[] {'\xFF3F', '\x0A9B'},
+            new char[] {'\xFF40', '\x039D'},
+            new char[] {'\xFF41', '\x0002'},
+            new char[] {'\xFF42', '\x0498'},
+            new char[] {'\xFF43', '\x040E'},
+            new char[] {'\xFF44', '\x03EB'},
+            new char[] {'\xFF45', '\x03DE'},
+            new char[] {'\xFF46', '\x0499'},
+            new char[] {'\xFF47', '\x03CD'},
+            new char[] {'\xFF48', '\x011C'},
+            new char[] {'\xFF49', '\x03B7'},
+            new char[] {'\xFF4A', '\x011E'},
+            new char[] {'\xFF4B', '\x049A'},
+            new char[] {'\xFF4C', '\x012C'},
+            new char[] {'\xFF4D', '\x040F'},
+            new char[] {'\xFF4E', '\x03C3'},
+            new char[] {'\xFF4F', '\x000A'},
+            new char[] {'\xFF50', '\x049B'},
+            new char[] {'\xFF51', '\x049C'},
+            new char[] {'\xFF52', '\x011F'},
+            new char[] {'\xFF53', '\x00B4'},
+            new char[] {'\xFF54', '\x049D'},
+            new char[] {'\xFF55', '\x049E'},
+            new char[] {'\xFF56', '\x0407'},
+            new char[] {'\xFF57', '\x0123'},
+            new char[] {'\xFF58', '\x012D'},
+            new char[] {'\xFF59', '\x0124'},
+            new char[] {'\xFF5A', '\x049F'},
+            new char[] {'\xFF5B', '\x0A9C'},
+            new char[] {'\xFF5C', '\x0AED'},
+            new char[] {'\xFF5D', '\x0A9D'},
+            new char[] {'\xFF5E', '\x0AEE'},
+            new char[] {'\xFF5F', '\x0AEF'},
+            new char[] {'\xFF60', '\x0AF0'},
+            new char[] {'\xFF61', '\x0AF1'},
+            new char[] {'\xFF62', '\x0AA4'},
+            new char[] {'\xFF63', '\x0AA5'},
+            new char[] {'\xFF64', '\x0AA9'},
+            new char[] {'\xFF65', '\x0AF2'},
+            new char[] {'\xFF66', '\x06ED'},
+            new char[] {'\xFF67', '\x0AF3'},
+            new char[] {'\xFF68', '\x0AF4'},
+            new char[] {'\xFF69', '\x0AF5'},
+            new char[] {'\xFF6A', '\x0AF6'},
+            new char[] {'\xFF6B', '\x0AF7'},
+            new char[] {'\xFF6C', '\x0AF8'},
+            new char[] {'\xFF6D', '\x0AF9'},
+            new char[] {'\xFF6E', '\x0AFA'},
+            new char[] {'\xFF6F', '\x0AFB'},
+            new char[] {'\xFF70', '\x0AFC'},
+            new char[] {'\xFF71', '\x06BF'},
+            new char[] {'\xFF72', '\x06C0'},
+            new char[] {'\xFF73', '\x06C1'},
+            new char[] {'\xFF74', '\x06C2'},
+            new char[] {'\xFF75', '\x06C3'},
+            new char[] {'\xFF76', '\x06C4'},
+            new char[] {'\xFF77', '\x06C5'},
+            new char[] {'\xFF78', '\x06C6'},
+            new char[] {'\xFF79', '\x06C7'},
+            new char[] {'\xFF7A', '\x06C8'},
+            new char[] {'\xFF7B', '\x06C9'},
+            new char[] {'\xFF7C', '\x06CA'},
+            new char[] {'\xFF7D', '\x06CB'},
+            new char[] {'\xFF7E', '\x06CC'},
+            new char[] {'\xFF7F', '\x06CD'},
+            new char[] {'\xFF80', '\x06CE'},
+            new char[] {'\xFF81', '\x06CF'},
+            new char[] {'\xFF82', '\x06D0'},
+            new char[] {'\xFF83', '\x06D1'},
+            new char[] {'\xFF84', '\x06D2'},
+            new char[] {'\xFF85', '\x06D3'},
+            new char[] {'\xFF86', '\x06D4'},
+            new char[] {'\xFF87', '\x06D5'},
+            new char[] {'\xFF88', '\x06D6'},
+            new char[] {'\xFF89', '\x06D7'},
+            new char[] {'\xFF8A', '\x06D8'},
+            new char[] {'\xFF8B', '\x06D9'},
+            new char[] {'\xFF8C', '\x06DA'},
+            new char[] {'\xFF8D', '\x06DB'},
+            new char[] {'\xFF8E', '\x06DC'},
+            new char[] {'\xFF8F', '\x06DD'},
+            new char[] {'\xFF90', '\x06DE'},
+            new char[] {'\xFF91', '\x06DF'},
+            new char[] {'\xFF92', '\x06E0'},
+            new char[] {'\xFF93', '\x06E1'},
+            new char[] {'\xFF94', '\x06E2'},
+            new char[] {'\xFF95', '\x06E3'},
+            new char[] {'\xFF96', '\x06E4'},
+            new char[] {'\xFF97', '\x06E5'},
+            new char[] {'\xFF98', '\x06E6'},
+            new char[] {'\xFF99', '\x06E7'},
+            new char[] {'\xFF9A', '\x06E8'},
+            new char[] {'\xFF9B', '\x06E9'},
+            new char[] {'\xFF9C', '\x06EA'},
+            new char[] {'\xFF9D', '\x0AFD'},
+            new char[] {'\xFF9E', '\x0AFE'},
+            new char[] {'\xFF9F', '\x0AFF'},
+            new char[] {'\xFFA0', '\x05F1'},
+            new char[] {'\xFFA1', '\x05BE'},
+            new char[] {'\xFFA2', '\x05BF'},
+            new char[] {'\xFFA3', '\x05C0'},
+            new char[] {'\xFFA4', '\x05C1'},
+            new char[] {'\xFFA5', '\x05C2'},
+            new char[] {'\xFFA6', '\x05C3'},
+            new char[] {'\xFFA7', '\x05C4'},
+            new char[] {'\xFFA8', '\x05C5'},
+            new char[] {'\xFFA9', '\x05C6'},
+            new char[] {'\xFFAA', '\x05C7'},
+            new char[] {'\xFFAB', '\x05C8'},
+            new char[] {'\xFFAC', '\x05C9'},
+            new char[] {'\xFFAD', '\x05CA'},
+            new char[] {'\xFFAE', '\x05CB'},
+            new char[] {'\xFFAF', '\x05CC'},
+            new char[] {'\xFFB0', '\x05CD'},
+            new char[] {'\xFFB1', '\x05CE'},
+            new char[] {'\xFFB2', '\x05CF'},
+            new char[] {'\xFFB3', '\x05D0'},
+            new char[] {'\xFFB4', '\x05D1'},
+            new char[] {'\xFFB5', '\x05D2'},
+            new char[] {'\xFFB6', '\x05D3'},
+            new char[] {'\xFFB7', '\x05D4'},
+            new char[] {'\xFFB8', '\x05D5'},
+            new char[] {'\xFFB9', '\x05D6'},
+            new char[] {'\xFFBA', '\x05D7'},
+            new char[] {'\xFFBB', '\x05D8'},
+            new char[] {'\xFFBC', '\x05D9'},
+            new char[] {'\xFFBD', '\x05DA'},
+            new char[] {'\xFFBE', '\x05DB'},
+            new char[] {'\xFFC2', '\x05DC'},
+            new char[] {'\xFFC3', '\x05DD'},
+            new char[] {'\xFFC4', '\x05DE'},
+            new char[] {'\xFFC5', '\x05DF'},
+            new char[] {'\xFFC6', '\x05E0'},
+            new char[] {'\xFFC7', '\x05E1'},
+            new char[] {'\xFFCA', '\x05E2'},
+            new char[] {'\xFFCB', '\x05E3'},
+            new char[] {'\xFFCC', '\x05E4'},
+            new char[] {'\xFFCD', '\x05E5'},
+            new char[] {'\xFFCE', '\x05E6'},
+            new char[] {'\xFFCF', '\x05E7'},
+            new char[] {'\xFFD2', '\x05E8'},
+            new char[] {'\xFFD3', '\x05E9'},
+            new char[] {'\xFFD4', '\x05EA'},
+            new char[] {'\xFFD5', '\x05EB'},
+            new char[] {'\xFFD6', '\x05EC'},
+            new char[] {'\xFFD7', '\x05ED'},
+            new char[] {'\xFFDA', '\x05EE'},
+            new char[] {'\xFFDB', '\x05EF'},
+            new char[] {'\xFFDC', '\x05F0'},
+            new char[] {'\xFFE0', '\x0B00'},
+            new char[] {'\xFFE1', '\x0B01'},
+            new char[] {'\xFFE2', '\x0B02'},
+            new char[] {'\xFFE3', '\x0003'},
+            new char[] {'\xFFE4', '\x0B03'},
+            new char[] {'\xFFE5', '\x0B04'},
+            new char[] {'\xFFE6', '\x0B05'},
+            new char[] {'\xFFE8', '\x0B06'},
+            new char[] {'\xFFE9', '\x0B07'},
+            new char[] {'\xFFEA', '\x0B08'},
+            new char[] {'\xFFEB', '\x0B09'},
+            new char[] {'\xFFEC', '\x0B0A'},
+            new char[] {'\xFFED', '\x0B0B'},
+            new char[] {'\xFFEE', '\x0B0C'}
+        };
+
+        /// <summary>
+        /// How to expand characters.  Since multiple input characters
+        /// output the same string, this table is compressed to only
+        /// have one copy of each, and the Offsets table
+        /// gives offsets into this for each input.
+        /// </summary>
+        public static readonly string[] Expansion =
+        {
+            "\x0020", /* offset 0x0000 */
+            "\x0020\x0308", /* offset 0x0001 */
+            "\x0061", /* offset 0x0002 */
+            "\x0020\x0304", /* offset 0x0003 */
+            "\x0032", /* offset 0x0004 */
+            "\x0033", /* offset 0x0005 */
+            "\x0020\x0301", /* offset 0x0006 */
+            "\x03BC", /* offset 0x0007 */
+            "\x0020\x0327", /* offset 0x0008 */
+            "\x0031", /* offset 0x0009 */
+            "\x006F", /* offset 0x000A */
+            "\x0031\x2044\x0034", /* offset 0x000B */
+            "\x0031\x2044\x0032", /* offset 0x000C */
+            "\x0033\x2044\x0034", /* offset 0x000D */
+            "\x0041\x0300", /* offset 0x000E */
+            "\x0041\x0301", /* offset 0x000F */
+            "\x0041\x0302", /* offset 0x0010 */
+            "\x0041\x0303", /* offset 0x0011 */
+            "\x0041\x0308", /* offset 0x0012 */
+            "\x0041\x030A", /* offset 0x0013 */
+            "\x0043\x0327", /* offset 0x0014 */
+            "\x0045\x0300", /* offset 0x0015 */
+            "\x0045\x0301", /* offset 0x0016 */
+            "\x0045\x0302", /* offset 0x0017 */
+            "\x0045\x0308", /* offset 0x0018 */
+            "\x0049\x0300", /* offset 0x0019 */
+            "\x0049\x0301", /* offset 0x001A */
+            "\x0049\x0302", /* offset 0x001B */
+            "\x0049\x0308", /* offset 0x001C */
+            "\x004E\x0303", /* offset 0x001D */
+            "\x004F\x0300", /* offset 0x001E */
+            "\x004F\x0301", /* offset 0x001F */
+            "\x004F\x0302", /* offset 0x0020 */
+            "\x004F\x0303", /* offset 0x0021 */
+            "\x004F\x0308", /* offset 0x0022 */
+            "\x0055\x0300", /* offset 0x0023 */
+            "\x0055\x0301", /* offset 0x0024 */
+            "\x0055\x0302", /* offset 0x0025 */
+            "\x0055\x0308", /* offset 0x0026 */
+            "\x0059\x0301", /* offset 0x0027 */
+            "\x0061\x0300", /* offset 0x0028 */
+            "\x0061\x0301", /* offset 0x0029 */
+            "\x0061\x0302", /* offset 0x002A */
+            "\x0061\x0303", /* offset 0x002B */
+            "\x0061\x0308", /* offset 0x002C */
+            "\x0061\x030A", /* offset 0x002D */
+            "\x0063\x0327", /* offset 0x002E */
+            "\x0065\x0300", /* offset 0x002F */
+            "\x0065\x0301", /* offset 0x0030 */
+            "\x0065\x0302", /* offset 0x0031 */
+            "\x0065\x0308", /* offset 0x0032 */
+            "\x0069\x0300", /* offset 0x0033 */
+            "\x0069\x0301", /* offset 0x0034 */
+            "\x0069\x0302", /* offset 0x0035 */
+            "\x0069\x0308", /* offset 0x0036 */
+            "\x006E\x0303", /* offset 0x0037 */
+            "\x006F\x0300", /* offset 0x0038 */
+            "\x006F\x0301", /* offset 0x0039 */
+            "\x006F\x0302", /* offset 0x003A */
+            "\x006F\x0303", /* offset 0x003B */
+            "\x006F\x0308", /* offset 0x003C */
+            "\x0075\x0300", /* offset 0x003D */
+            "\x0075\x0301", /* offset 0x003E */
+            "\x0075\x0302", /* offset 0x003F */
+            "\x0075\x0308", /* offset 0x0040 */
+            "\x0079\x0301", /* offset 0x0041 */
+            "\x0079\x0308", /* offset 0x0042 */
+            "\x0041\x0304", /* offset 0x0043 */
+            "\x0061\x0304", /* offset 0x0044 */
+            "\x0041\x0306", /* offset 0x0045 */
+            "\x0061\x0306", /* offset 0x0046 */
+            "\x0041\x0328", /* offset 0x0047 */
+            "\x0061\x0328", /* offset 0x0048 */
+            "\x0043\x0301", /* offset 0x0049 */
+            "\x0063\x0301", /* offset 0x004A */
+            "\x0043\x0302", /* offset 0x004B */
+            "\x0063\x0302", /* offset 0x004C */
+            "\x0043\x0307", /* offset 0x004D */
+            "\x0063\x0307", /* offset 0x004E */
+            "\x0043\x030C", /* offset 0x004F */
+            "\x0063\x030C", /* offset 0x0050 */
+            "\x0044\x030C", /* offset 0x0051 */
+            "\x0064\x030C", /* offset 0x0052 */
+            "\x0045\x0304", /* offset 0x0053 */
+            "\x0065\x0304", /* offset 0x0054 */
+            "\x0045\x0306", /* offset 0x0055 */
+            "\x0065\x0306", /* offset 0x0056 */
+            "\x0045\x0307", /* offset 0x0057 */
+            "\x0065\x0307", /* offset 0x0058 */
+            "\x0045\x0328", /* offset 0x0059 */
+            "\x0065\x0328", /* offset 0x005A */
+            "\x0045\x030C", /* offset 0x005B */
+            "\x0065\x030C", /* offset 0x005C */
+            "\x0047\x0302", /* offset 0x005D */
+            "\x0067\x0302", /* offset 0x005E */
+            "\x0047\x0306", /* offset 0x005F */
+            "\x0067\x0306", /* offset 0x0060 */
+            "\x0047\x0307", /* offset 0x0061 */
+            "\x0067\x0307", /* offset 0x0062 */
+            "\x0047\x0327", /* offset 0x0063 */
+            "\x0067\x0327", /* offset 0x0064 */
+            "\x0048\x0302", /* offset 0x0065 */
+            "\x0068\x0302", /* offset 0x0066 */
+            "\x0049\x0303", /* offset 0x0067 */
+            "\x0069\x0303", /* offset 0x0068 */
+            "\x0049\x0304", /* offset 0x0069 */
+            "\x0069\x0304", /* offset 0x006A */
+            "\x0049\x0306", /* offset 0x006B */
+            "\x0069\x0306", /* offset 0x006C */
+            "\x0049\x0328", /* offset 0x006D */
+            "\x0069\x0328", /* offset 0x006E */
+            "\x0049\x0307", /* offset 0x006F */
+            "\x0049\x004A", /* offset 0x0070 */
+            "\x0069\x006A", /* offset 0x0071 */
+            "\x004A\x0302", /* offset 0x0072 */
+            "\x006A\x0302", /* offset 0x0073 */
+            "\x004B\x0327", /* offset 0x0074 */
+            "\x006B\x0327", /* offset 0x0075 */
+            "\x004C\x0301", /* offset 0x0076 */
+            "\x006C\x0301", /* offset 0x0077 */
+            "\x004C\x0327", /* offset 0x0078 */
+            "\x006C\x0327", /* offset 0x0079 */
+            "\x004C\x030C", /* offset 0x007A */
+            "\x006C\x030C", /* offset 0x007B */
+            "\x004C\x00B7", /* offset 0x007C */
+            "\x006C\x00B7", /* offset 0x007D */
+            "\x004E\x0301", /* offset 0x007E */
+            "\x006E\x0301", /* offset 0x007F */
+            "\x004E\x0327", /* offset 0x0080 */
+            "\x006E\x0327", /* offset 0x0081 */
+            "\x004E\x030C", /* offset 0x0082 */
+            "\x006E\x030C", /* offset 0x0083 */
+            "\x02BC\x006E", /* offset 0x0084 */
+            "\x004F\x0304", /* offset 0x0085 */
+            "\x006F\x0304", /* offset 0x0086 */
+            "\x004F\x0306", /* offset 0x0087 */
+            "\x006F\x0306", /* offset 0x0088 */
+            "\x004F\x030B", /* offset 0x0089 */
+            "\x006F\x030B", /* offset 0x008A */
+            "\x0052\x0301", /* offset 0x008B */
+            "\x0072\x0301", /* offset 0x008C */
+            "\x0052\x0327", /* offset 0x008D */
+            "\x0072\x0327", /* offset 0x008E */
+            "\x0052\x030C", /* offset 0x008F */
+            "\x0072\x030C", /* offset 0x0090 */
+            "\x0053\x0301", /* offset 0x0091 */
+            "\x0073\x0301", /* offset 0x0092 */
+            "\x0053\x0302", /* offset 0x0093 */
+            "\x0073\x0302", /* offset 0x0094 */
+            "\x0053\x0327", /* offset 0x0095 */
+            "\x0073\x0327", /* offset 0x0096 */
+            "\x0053\x030C", /* offset 0x0097 */
+            "\x0073\x030C", /* offset 0x0098 */
+            "\x0054\x0327", /* offset 0x0099 */
+            "\x0074\x0327", /* offset 0x009A */
+            "\x0054\x030C", /* offset 0x009B */
+            "\x0074\x030C", /* offset 0x009C */
+            "\x0055\x0303", /* offset 0x009D */
+            "\x0075\x0303", /* offset 0x009E */
+            "\x0055\x0304", /* offset 0x009F */
+            "\x0075\x0304", /* offset 0x00A0 */
+            "\x0055\x0306", /* offset 0x00A1 */
+            "\x0075\x0306", /* offset 0x00A2 */
+            "\x0055\x030A", /* offset 0x00A3 */
+            "\x0075\x030A", /* offset 0x00A4 */
+            "\x0055\x030B", /* offset 0x00A5 */
+            "\x0075\x030B", /* offset 0x00A6 */
+            "\x0055\x0328", /* offset 0x00A7 */
+            "\x0075\x0328", /* offset 0x00A8 */
+            "\x0057\x0302", /* offset 0x00A9 */
+            "\x0077\x0302", /* offset 0x00AA */
+            "\x0059\x0302", /* offset 0x00AB */
+            "\x0079\x0302", /* offset 0x00AC */
+            "\x0059\x0308", /* offset 0x00AD */
+            "\x005A\x0301", /* offset 0x00AE */
+            "\x007A\x0301", /* offset 0x00AF */
+            "\x005A\x0307", /* offset 0x00B0 */
+            "\x007A\x0307", /* offset 0x00B1 */
+            "\x005A\x030C", /* offset 0x00B2 */
+            "\x007A\x030C", /* offset 0x00B3 */
+            "\x0073", /* offset 0x00B4 */
+            "\x004F\x031B", /* offset 0x00B5 */
+            "\x006F\x031B", /* offset 0x00B6 */
+            "\x0055\x031B", /* offset 0x00B7 */
+            "\x0075\x031B", /* offset 0x00B8 */
+            "\x0044\x005A\x030C", /* offset 0x00B9 */
+            "\x0044\x007A\x030C", /* offset 0x00BA */
+            "\x0064\x007A\x030C", /* offset 0x00BB */
+            "\x004C\x004A", /* offset 0x00BC */
+            "\x004C\x006A", /* offset 0x00BD */
+            "\x006C\x006A", /* offset 0x00BE */
+            "\x004E\x004A", /* offset 0x00BF */
+            "\x004E\x006A", /* offset 0x00C0 */
+            "\x006E\x006A", /* offset 0x00C1 */
+            "\x0041\x030C", /* offset 0x00C2 */
+            "\x0061\x030C", /* offset 0x00C3 */
+            "\x0049\x030C", /* offset 0x00C4 */
+            "\x0069\x030C", /* offset 0x00C5 */
+            "\x004F\x030C", /* offset 0x00C6 */
+            "\x006F\x030C", /* offset 0x00C7 */
+            "\x0055\x030C", /* offset 0x00C8 */
+            "\x0075\x030C", /* offset 0x00C9 */
+            "\x0055\x0308\x0304", /* offset 0x00CA */
+            "\x0075\x0308\x0304", /* offset 0x00CB */
+            "\x0055\x0308\x0301", /* offset 0x00CC */
+            "\x0075\x0308\x0301", /* offset 0x00CD */
+            "\x0055\x0308\x030C", /* offset 0x00CE */
+            "\x0075\x0308\x030C", /* offset 0x00CF */
+            "\x0055\x0308\x0300", /* offset 0x00D0 */
+            "\x0075\x0308\x0300", /* offset 0x00D1 */
+            "\x0041\x0308\x0304", /* offset 0x00D2 */
+            "\x0061\x0308\x0304", /* offset 0x00D3 */
+            "\x0041\x0307\x0304", /* offset 0x00D4 */
+            "\x0061\x0307\x0304", /* offset 0x00D5 */
+            "\x00C6\x0304", /* offset 0x00D6 */
+            "\x00E6\x0304", /* offset 0x00D7 */
+            "\x0047\x030C", /* offset 0x00D8 */
+            "\x0067\x030C", /* offset 0x00D9 */
+            "\x004B\x030C", /* offset 0x00DA */
+            "\x006B\x030C", /* offset 0x00DB */
+            "\x004F\x0328", /* offset 0x00DC */
+            "\x006F\x0328", /* offset 0x00DD */
+            "\x004F\x0328\x0304", /* offset 0x00DE */
+            "\x006F\x0328\x0304", /* offset 0x00DF */
+            "\x01B7\x030C", /* offset 0x00E0 */
+            "\x0292\x030C", /* offset 0x00E1 */
+            "\x006A\x030C", /* offset 0x00E2 */
+            "\x0044\x005A", /* offset 0x00E3 */
+            "\x0044\x007A", /* offset 0x00E4 */
+            "\x0064\x007A", /* offset 0x00E5 */
+            "\x0047\x0301", /* offset 0x00E6 */
+            "\x0067\x0301", /* offset 0x00E7 */
+            "\x004E\x0300", /* offset 0x00E8 */
+            "\x006E\x0300", /* offset 0x00E9 */
+            "\x0041\x030A\x0301", /* offset 0x00EA */
+            "\x0061\x030A\x0301", /* offset 0x00EB */
+            "\x00C6\x0301", /* offset 0x00EC */
+            "\x00E6\x0301", /* offset 0x00ED */
+            "\x00D8\x0301", /* offset 0x00EE */
+            "\x00F8\x0301", /* offset 0x00EF */
+            "\x0041\x030F", /* offset 0x00F0 */
+            "\x0061\x030F", /* offset 0x00F1 */
+            "\x0041\x0311", /* offset 0x00F2 */
+            "\x0061\x0311", /* offset 0x00F3 */
+            "\x0045\x030F", /* offset 0x00F4 */
+            "\x0065\x030F", /* offset 0x00F5 */
+            "\x0045\x0311", /* offset 0x00F6 */
+            "\x0065\x0311", /* offset 0x00F7 */
+            "\x0049\x030F", /* offset 0x00F8 */
+            "\x0069\x030F", /* offset 0x00F9 */
+            "\x0049\x0311", /* offset 0x00FA */
+            "\x0069\x0311", /* offset 0x00FB */
+            "\x004F\x030F", /* offset 0x00FC */
+            "\x006F\x030F", /* offset 0x00FD */
+            "\x004F\x0311", /* offset 0x00FE */
+            "\x006F\x0311", /* offset 0x00FF */
+            "\x0052\x030F", /* offset 0x0100 */
+            "\x0072\x030F", /* offset 0x0101 */
+            "\x0052\x0311", /* offset 0x0102 */
+            "\x0072\x0311", /* offset 0x0103 */
+            "\x0055\x030F", /* offset 0x0104 */
+            "\x0075\x030F", /* offset 0x0105 */
+            "\x0055\x0311", /* offset 0x0106 */
+            "\x0075\x0311", /* offset 0x0107 */
+            "\x0053\x0326", /* offset 0x0108 */
+            "\x0073\x0326", /* offset 0x0109 */
+            "\x0054\x0326", /* offset 0x010A */
+            "\x0074\x0326", /* offset 0x010B */
+            "\x0048\x030C", /* offset 0x010C */
+            "\x0068\x030C", /* offset 0x010D */
+            "\x0041\x0307", /* offset 0x010E */
+            "\x0061\x0307", /* offset 0x010F */
+            "\x0045\x0327", /* offset 0x0110 */
+            "\x0065\x0327", /* offset 0x0111 */
+            "\x004F\x0308\x0304", /* offset 0x0112 */
+            "\x006F\x0308\x0304", /* offset 0x0113 */
+            "\x004F\x0303\x0304", /* offset 0x0114 */
+            "\x006F\x0303\x0304", /* offset 0x0115 */
+            "\x004F\x0307", /* offset 0x0116 */
+            "\x006F\x0307", /* offset 0x0117 */
+            "\x004F\x0307\x0304", /* offset 0x0118 */
+            "\x006F\x0307\x0304", /* offset 0x0119 */
+            "\x0059\x0304", /* offset 0x011A */
+            "\x0079\x0304", /* offset 0x011B */
+            "\x0068", /* offset 0x011C */
+            "\x0266", /* offset 0x011D */
+            "\x006A", /* offset 0x011E */
+            "\x0072", /* offset 0x011F */
+            "\x0279", /* offset 0x0120 */
+            "\x027B", /* offset 0x0121 */
+            "\x0281", /* offset 0x0122 */
+            "\x0077", /* offset 0x0123 */
+            "\x0079", /* offset 0x0124 */
+            "\x0020\x0306", /* offset 0x0125 */
+            "\x0020\x0307", /* offset 0x0126 */
+            "\x0020\x030A", /* offset 0x0127 */
+            "\x0020\x0328", /* offset 0x0128 */
+            "\x0020\x0303", /* offset 0x0129 */
+            "\x0020\x030B", /* offset 0x012A */
+            "\x0263", /* offset 0x012B */
+            "\x006C", /* offset 0x012C */
+            "\x0078", /* offset 0x012D */
+            "\x0295", /* offset 0x012E */
+            "\x0300", /* offset 0x012F */
+            "\x0301", /* offset 0x0130 */
+            "\x0313", /* offset 0x0131 */
+            "\x0308\x0301", /* offset 0x0132 */
+            "\x02B9", /* offset 0x0133 */
+            "\x0020\x0345", /* offset 0x0134 */
+            "\x003B", /* offset 0x0135 */
+            "\x0020\x0308\x0301", /* offset 0x0136 */
+            "\x0391\x0301", /* offset 0x0137 */
+            "\x00B7", /* offset 0x0138 */
+            "\x0395\x0301", /* offset 0x0139 */
+            "\x0397\x0301", /* offset 0x013A */
+            "\x0399\x0301", /* offset 0x013B */
+            "\x039F\x0301", /* offset 0x013C */
+            "\x03A5\x0301", /* offset 0x013D */
+            "\x03A9\x0301", /* offset 0x013E */
+            "\x03B9\x0308\x0301", /* offset 0x013F */
+            "\x0399\x0308", /* offset 0x0140 */
+            "\x03A5\x0308", /* offset 0x0141 */
+            "\x03B1\x0301", /* offset 0x0142 */
+            "\x03B5\x0301", /* offset 0x0143 */
+            "\x03B7\x0301", /* offset 0x0144 */
+            "\x03B9\x0301", /* offset 0x0145 */
+            "\x03C5\x0308\x0301", /* offset 0x0146 */
+            "\x03B9\x0308", /* offset 0x0147 */
+            "\x03C5\x0308", /* offset 0x0148 */
+            "\x03BF\x0301", /* offset 0x0149 */
+            "\x03C5\x0301", /* offset 0x014A */
+            "\x03C9\x0301", /* offset 0x014B */
+            "\x03B2", /* offset 0x014C */
+            "\x03B8", /* offset 0x014D */
+            "\x03A5", /* offset 0x014E */
+            "\x03C6", /* offset 0x014F */
+            "\x03C0", /* offset 0x0150 */
+            "\x03BA", /* offset 0x0151 */
+            "\x03C1", /* offset 0x0152 */
+            "\x03C2", /* offset 0x0153 */
+            "\x0398", /* offset 0x0154 */
+            "\x03B5", /* offset 0x0155 */
+            "\x0415\x0300", /* offset 0x0156 */
+            "\x0415\x0308", /* offset 0x0157 */
+            "\x0413\x0301", /* offset 0x0158 */
+            "\x0406\x0308", /* offset 0x0159 */
+            "\x041A\x0301", /* offset 0x015A */
+            "\x0418\x0300", /* offset 0x015B */
+            "\x0423\x0306", /* offset 0x015C */
+            "\x0418\x0306", /* offset 0x015D */
+            "\x0438\x0306", /* offset 0x015E */
+            "\x0435\x0300", /* offset 0x015F */
+            "\x0435\x0308", /* offset 0x0160 */
+            "\x0433\x0301", /* offset 0x0161 */
+            "\x0456\x0308", /* offset 0x0162 */
+            "\x043A\x0301", /* offset 0x0163 */
+            "\x0438\x0300", /* offset 0x0164 */
+            "\x0443\x0306", /* offset 0x0165 */
+            "\x0474\x030F", /* offset 0x0166 */
+            "\x0475\x030F", /* offset 0x0167 */
+            "\x0416\x0306", /* offset 0x0168 */
+            "\x0436\x0306", /* offset 0x0169 */
+            "\x0410\x0306", /* offset 0x016A */
+            "\x0430\x0306", /* offset 0x016B */
+            "\x0410\x0308", /* offset 0x016C */
+            "\x0430\x0308", /* offset 0x016D */
+            "\x0415\x0306", /* offset 0x016E */
+            "\x0435\x0306", /* offset 0x016F */
+            "\x04D8\x0308", /* offset 0x0170 */
+            "\x04D9\x0308", /* offset 0x0171 */
+            "\x0416\x0308", /* offset 0x0172 */
+            "\x0436\x0308", /* offset 0x0173 */
+            "\x0417\x0308", /* offset 0x0174 */
+            "\x0437\x0308", /* offset 0x0175 */
+            "\x0418\x0304", /* offset 0x0176 */
+            "\x0438\x0304", /* offset 0x0177 */
+            "\x0418\x0308", /* offset 0x0178 */
+            "\x0438\x0308", /* offset 0x0179 */
+            "\x041E\x0308", /* offset 0x017A */
+            "\x043E\x0308", /* offset 0x017B */
+            "\x04E8\x0308", /* offset 0x017C */
+            "\x04E9\x0308", /* offset 0x017D */
+            "\x042D\x0308", /* offset 0x017E */
+            "\x044D\x0308", /* offset 0x017F */
+            "\x0423\x0304", /* offset 0x0180 */
+            "\x0443\x0304", /* offset 0x0181 */
+            "\x0423\x0308", /* offset 0x0182 */
+            "\x0443\x0308", /* offset 0x0183 */
+            "\x0423\x030B", /* offset 0x0184 */
+            "\x0443\x030B", /* offset 0x0185 */
+            "\x0427\x0308", /* offset 0x0186 */
+            "\x0447\x0308", /* offset 0x0187 */
+            "\x042B\x0308", /* offset 0x0188 */
+            "\x044B\x0308", /* offset 0x0189 */
+            "\x0565\x0582", /* offset 0x018A */
+            "\x0627\x0653", /* offset 0x018B */
+            "\x0627\x0654", /* offset 0x018C */
+            "\x0648\x0654", /* offset 0x018D */
+            "\x0627\x0655", /* offset 0x018E */
+            "\x064A\x0654", /* offset 0x018F */
+            "\x0627\x0674", /* offset 0x0190 */
+            "\x0648\x0674", /* offset 0x0191 */
+            "\x06C7\x0674", /* offset 0x0192 */
+            "\x064A\x0674", /* offset 0x0193 */
+            "\x06D5\x0654", /* offset 0x0194 */
+            "\x06C1\x0654", /* offset 0x0195 */
+            "\x06D2\x0654", /* offset 0x0196 */
+            "\x0928\x093C", /* offset 0x0197 */
+            "\x0930\x093C", /* offset 0x0198 */
+            "\x0933\x093C", /* offset 0x0199 */
+            "\x0915\x093C", /* offset 0x019A */
+            "\x0916\x093C", /* offset 0x019B */
+            "\x0917\x093C", /* offset 0x019C */
+            "\x091C\x093C", /* offset 0x019D */
+            "\x0921\x093C", /* offset 0x019E */
+            "\x0922\x093C", /* offset 0x019F */
+            "\x092B\x093C", /* offset 0x01A0 */
+            "\x092F\x093C", /* offset 0x01A1 */
+            "\x09C7\x09BE", /* offset 0x01A2 */
+            "\x09C7\x09D7", /* offset 0x01A3 */
+            "\x09A1\x09BC", /* offset 0x01A4 */
+            "\x09A2\x09BC", /* offset 0x01A5 */
+            "\x09AF\x09BC", /* offset 0x01A6 */
+            "\x0A32\x0A3C", /* offset 0x01A7 */
+            "\x0A38\x0A3C", /* offset 0x01A8 */
+            "\x0A16\x0A3C", /* offset 0x01A9 */
+            "\x0A17\x0A3C", /* offset 0x01AA */
+            "\x0A1C\x0A3C", /* offset 0x01AB */
+            "\x0A2B\x0A3C", /* offset 0x01AC */
+            "\x0B47\x0B56", /* offset 0x01AD */
+            "\x0B47\x0B3E", /* offset 0x01AE */
+            "\x0B47\x0B57", /* offset 0x01AF */
+            "\x0B21\x0B3C", /* offset 0x01B0 */
+            "\x0B22\x0B3C", /* offset 0x01B1 */
+            "\x0B92\x0BD7", /* offset 0x01B2 */
+            "\x0BC6\x0BBE", /* offset 0x01B3 */
+            "\x0BC7\x0BBE", /* offset 0x01B4 */
+            "\x0BC6\x0BD7", /* offset 0x01B5 */
+            "\x0C46\x0C56", /* offset 0x01B6 */
+            "\x0CBF\x0CD5", /* offset 0x01B7 */
+            "\x0CC6\x0CD5", /* offset 0x01B8 */
+            "\x0CC6\x0CD6", /* offset 0x01B9 */
+            "\x0CC6\x0CC2", /* offset 0x01BA */
+            "\x0CC6\x0CC2\x0CD5", /* offset 0x01BB */
+            "\x0D46\x0D3E", /* offset 0x01BC */
+            "\x0D47\x0D3E", /* offset 0x01BD */
+            "\x0D46\x0D57", /* offset 0x01BE */
+            "\x0DD9\x0DCA", /* offset 0x01BF */
+            "\x0DD9\x0DCF", /* offset 0x01C0 */
+            "\x0DD9\x0DCF\x0DCA", /* offset 0x01C1 */
+            "\x0DD9\x0DDF", /* offset 0x01C2 */
+            "\x0E4D\x0E32", /* offset 0x01C3 */
+            "\x0ECD\x0EB2", /* offset 0x01C4 */
+            "\x0EAB\x0E99", /* offset 0x01C5 */
+            "\x0EAB\x0EA1", /* offset 0x01C6 */
+            "\x0F0B", /* offset 0x01C7 */
+            "\x0F42\x0FB7", /* offset 0x01C8 */
+            "\x0F4C\x0FB7", /* offset 0x01C9 */
+            "\x0F51\x0FB7", /* offset 0x01CA */
+            "\x0F56\x0FB7", /* offset 0x01CB */
+            "\x0F5B\x0FB7", /* offset 0x01CC */
+            "\x0F40\x0FB5", /* offset 0x01CD */
+            "\x0F71\x0F72", /* offset 0x01CE */
+            "\x0F71\x0F74", /* offset 0x01CF */
+            "\x0FB2\x0F80", /* offset 0x01D0 */
+            "\x0FB2\x0F71\x0F80", /* offset 0x01D1 */
+            "\x0FB3\x0F80", /* offset 0x01D2 */
+            "\x0FB3\x0F71\x0F80", /* offset 0x01D3 */
+            "\x0F71\x0F80", /* offset 0x01D4 */
+            "\x0F92\x0FB7", /* offset 0x01D5 */
+            "\x0F9C\x0FB7", /* offset 0x01D6 */
+            "\x0FA1\x0FB7", /* offset 0x01D7 */
+            "\x0FA6\x0FB7", /* offset 0x01D8 */
+            "\x0FAB\x0FB7", /* offset 0x01D9 */
+            "\x0F90\x0FB5", /* offset 0x01DA */
+            "\x1025\x102E", /* offset 0x01DB */
+            "\x0041\x0325", /* offset 0x01DC */
+            "\x0061\x0325", /* offset 0x01DD */
+            "\x0042\x0307", /* offset 0x01DE */
+            "\x0062\x0307", /* offset 0x01DF */
+            "\x0042\x0323", /* offset 0x01E0 */
+            "\x0062\x0323", /* offset 0x01E1 */
+            "\x0042\x0331", /* offset 0x01E2 */
+            "\x0062\x0331", /* offset 0x01E3 */
+            "\x0043\x0327\x0301", /* offset 0x01E4 */
+            "\x0063\x0327\x0301", /* offset 0x01E5 */
+            "\x0044\x0307", /* offset 0x01E6 */
+            "\x0064\x0307", /* offset 0x01E7 */
+            "\x0044\x0323", /* offset 0x01E8 */
+            "\x0064\x0323", /* offset 0x01E9 */
+            "\x0044\x0331", /* offset 0x01EA */
+            "\x0064\x0331", /* offset 0x01EB */
+            "\x0044\x0327", /* offset 0x01EC */
+            "\x0064\x0327", /* offset 0x01ED */
+            "\x0044\x032D", /* offset 0x01EE */
+            "\x0064\x032D", /* offset 0x01EF */
+            "\x0045\x0304\x0300", /* offset 0x01F0 */
+            "\x0065\x0304\x0300", /* offset 0x01F1 */
+            "\x0045\x0304\x0301", /* offset 0x01F2 */
+            "\x0065\x0304\x0301", /* offset 0x01F3 */
+            "\x0045\x032D", /* offset 0x01F4 */
+            "\x0065\x032D", /* offset 0x01F5 */
+            "\x0045\x0330", /* offset 0x01F6 */
+            "\x0065\x0330", /* offset 0x01F7 */
+            "\x0045\x0327\x0306", /* offset 0x01F8 */
+            "\x0065\x0327\x0306", /* offset 0x01F9 */
+            "\x0046\x0307", /* offset 0x01FA */
+            "\x0066\x0307", /* offset 0x01FB */
+            "\x0047\x0304", /* offset 0x01FC */
+            "\x0067\x0304", /* offset 0x01FD */
+            "\x0048\x0307", /* offset 0x01FE */
+            "\x0068\x0307", /* offset 0x01FF */
+            "\x0048\x0323", /* offset 0x0200 */
+            "\x0068\x0323", /* offset 0x0201 */
+            "\x0048\x0308", /* offset 0x0202 */
+            "\x0068\x0308", /* offset 0x0203 */
+            "\x0048\x0327", /* offset 0x0204 */
+            "\x0068\x0327", /* offset 0x0205 */
+            "\x0048\x032E", /* offset 0x0206 */
+            "\x0068\x032E", /* offset 0x0207 */
+            "\x0049\x0330", /* offset 0x0208 */
+            "\x0069\x0330", /* offset 0x0209 */
+            "\x0049\x0308\x0301", /* offset 0x020A */
+            "\x0069\x0308\x0301", /* offset 0x020B */
+            "\x004B\x0301", /* offset 0x020C */
+            "\x006B\x0301", /* offset 0x020D */
+            "\x004B\x0323", /* offset 0x020E */
+            "\x006B\x0323", /* offset 0x020F */
+            "\x004B\x0331", /* offset 0x0210 */
+            "\x006B\x0331", /* offset 0x0211 */
+            "\x004C\x0323", /* offset 0x0212 */
+            "\x006C\x0323", /* offset 0x0213 */
+            "\x004C\x0323\x0304", /* offset 0x0214 */
+            "\x006C\x0323\x0304", /* offset 0x0215 */
+            "\x004C\x0331", /* offset 0x0216 */
+            "\x006C\x0331", /* offset 0x0217 */
+            "\x004C\x032D", /* offset 0x0218 */
+            "\x006C\x032D", /* offset 0x0219 */
+            "\x004D\x0301", /* offset 0x021A */
+            "\x006D\x0301", /* offset 0x021B */
+            "\x004D\x0307", /* offset 0x021C */
+            "\x006D\x0307", /* offset 0x021D */
+            "\x004D\x0323", /* offset 0x021E */
+            "\x006D\x0323", /* offset 0x021F */
+            "\x004E\x0307", /* offset 0x0220 */
+            "\x006E\x0307", /* offset 0x0221 */
+            "\x004E\x0323", /* offset 0x0222 */
+            "\x006E\x0323", /* offset 0x0223 */
+            "\x004E\x0331", /* offset 0x0224 */
+            "\x006E\x0331", /* offset 0x0225 */
+            "\x004E\x032D", /* offset 0x0226 */
+            "\x006E\x032D", /* offset 0x0227 */
+            "\x004F\x0303\x0301", /* offset 0x0228 */
+            "\x006F\x0303\x0301", /* offset 0x0229 */
+            "\x004F\x0303\x0308", /* offset 0x022A */
+            "\x006F\x0303\x0308", /* offset 0x022B */
+            "\x004F\x0304\x0300", /* offset 0x022C */
+            "\x006F\x0304\x0300", /* offset 0x022D */
+            "\x004F\x0304\x0301", /* offset 0x022E */
+            "\x006F\x0304\x0301", /* offset 0x022F */
+            "\x0050\x0301", /* offset 0x0230 */
+            "\x0070\x0301", /* offset 0x0231 */
+            "\x0050\x0307", /* offset 0x0232 */
+            "\x0070\x0307", /* offset 0x0233 */
+            "\x0052\x0307", /* offset 0x0234 */
+            "\x0072\x0307", /* offset 0x0235 */
+            "\x0052\x0323", /* offset 0x0236 */
+            "\x0072\x0323", /* offset 0x0237 */
+            "\x0052\x0323\x0304", /* offset 0x0238 */
+            "\x0072\x0323\x0304", /* offset 0x0239 */
+            "\x0052\x0331", /* offset 0x023A */
+            "\x0072\x0331", /* offset 0x023B */
+            "\x0053\x0307", /* offset 0x023C */
+            "\x0073\x0307", /* offset 0x023D */
+            "\x0053\x0323", /* offset 0x023E */
+            "\x0073\x0323", /* offset 0x023F */
+            "\x0053\x0301\x0307", /* offset 0x0240 */
+            "\x0073\x0301\x0307", /* offset 0x0241 */
+            "\x0053\x030C\x0307", /* offset 0x0242 */
+            "\x0073\x030C\x0307", /* offset 0x0243 */
+            "\x0053\x0323\x0307", /* offset 0x0244 */
+            "\x0073\x0323\x0307", /* offset 0x0245 */
+            "\x0054\x0307", /* offset 0x0246 */
+            "\x0074\x0307", /* offset 0x0247 */
+            "\x0054\x0323", /* offset 0x0248 */
+            "\x0074\x0323", /* offset 0x0249 */
+            "\x0054\x0331", /* offset 0x024A */
+            "\x0074\x0331", /* offset 0x024B */
+            "\x0054\x032D", /* offset 0x024C */
+            "\x0074\x032D", /* offset 0x024D */
+            "\x0055\x0324", /* offset 0x024E */
+            "\x0075\x0324", /* offset 0x024F */
+            "\x0055\x0330", /* offset 0x0250 */
+            "\x0075\x0330", /* offset 0x0251 */
+            "\x0055\x032D", /* offset 0x0252 */
+            "\x0075\x032D", /* offset 0x0253 */
+            "\x0055\x0303\x0301", /* offset 0x0254 */
+            "\x0075\x0303\x0301", /* offset 0x0255 */
+            "\x0055\x0304\x0308", /* offset 0x0256 */
+            "\x0075\x0304\x0308", /* offset 0x0257 */
+            "\x0056\x0303", /* offset 0x0258 */
+            "\x0076\x0303", /* offset 0x0259 */
+            "\x0056\x0323", /* offset 0x025A */
+            "\x0076\x0323", /* offset 0x025B */
+            "\x0057\x0300", /* offset 0x025C */
+            "\x0077\x0300", /* offset 0x025D */
+            "\x0057\x0301", /* offset 0x025E */
+            "\x0077\x0301", /* offset 0x025F */
+            "\x0057\x0308", /* offset 0x0260 */
+            "\x0077\x0308", /* offset 0x0261 */
+            "\x0057\x0307", /* offset 0x0262 */
+            "\x0077\x0307", /* offset 0x0263 */
+            "\x0057\x0323", /* offset 0x0264 */
+            "\x0077\x0323", /* offset 0x0265 */
+            "\x0058\x0307", /* offset 0x0266 */
+            "\x0078\x0307", /* offset 0x0267 */
+            "\x0058\x0308", /* offset 0x0268 */
+            "\x0078\x0308", /* offset 0x0269 */
+            "\x0059\x0307", /* offset 0x026A */
+            "\x0079\x0307", /* offset 0x026B */
+            "\x005A\x0302", /* offset 0x026C */
+            "\x007A\x0302", /* offset 0x026D */
+            "\x005A\x0323", /* offset 0x026E */
+            "\x007A\x0323", /* offset 0x026F */
+            "\x005A\x0331", /* offset 0x0270 */
+            "\x007A\x0331", /* offset 0x0271 */
+            "\x0068\x0331", /* offset 0x0272 */
+            "\x0074\x0308", /* offset 0x0273 */
+            "\x0077\x030A", /* offset 0x0274 */
+            "\x0079\x030A", /* offset 0x0275 */
+            "\x0061\x02BE", /* offset 0x0276 */
+            "\x0041\x0323", /* offset 0x0277 */
+            "\x0061\x0323", /* offset 0x0278 */
+            "\x0041\x0309", /* offset 0x0279 */
+            "\x0061\x0309", /* offset 0x027A */
+            "\x0041\x0302\x0301", /* offset 0x027B */
+            "\x0061\x0302\x0301", /* offset 0x027C */
+            "\x0041\x0302\x0300", /* offset 0x027D */
+            "\x0061\x0302\x0300", /* offset 0x027E */
+            "\x0041\x0302\x0309", /* offset 0x027F */
+            "\x0061\x0302\x0309", /* offset 0x0280 */
+            "\x0041\x0302\x0303", /* offset 0x0281 */
+            "\x0061\x0302\x0303", /* offset 0x0282 */
+            "\x0041\x0323\x0302", /* offset 0x0283 */
+            "\x0061\x0323\x0302", /* offset 0x0284 */
+            "\x0041\x0306\x0301", /* offset 0x0285 */
+            "\x0061\x0306\x0301", /* offset 0x0286 */
+            "\x0041\x0306\x0300", /* offset 0x0287 */
+            "\x0061\x0306\x0300", /* offset 0x0288 */
+            "\x0041\x0306\x0309", /* offset 0x0289 */
+            "\x0061\x0306\x0309", /* offset 0x028A */
+            "\x0041\x0306\x0303", /* offset 0x028B */
+            "\x0061\x0306\x0303", /* offset 0x028C */
+            "\x0041\x0323\x0306", /* offset 0x028D */
+            "\x0061\x0323\x0306", /* offset 0x028E */
+            "\x0045\x0323", /* offset 0x028F */
+            "\x0065\x0323", /* offset 0x0290 */
+            "\x0045\x0309", /* offset 0x0291 */
+            "\x0065\x0309", /* offset 0x0292 */
+            "\x0045\x0303", /* offset 0x0293 */
+            "\x0065\x0303", /* offset 0x0294 */
+            "\x0045\x0302\x0301", /* offset 0x0295 */
+            "\x0065\x0302\x0301", /* offset 0x0296 */
+            "\x0045\x0302\x0300", /* offset 0x0297 */
+            "\x0065\x0302\x0300", /* offset 0x0298 */
+            "\x0045\x0302\x0309", /* offset 0x0299 */
+            "\x0065\x0302\x0309", /* offset 0x029A */
+            "\x0045\x0302\x0303", /* offset 0x029B */
+            "\x0065\x0302\x0303", /* offset 0x029C */
+            "\x0045\x0323\x0302", /* offset 0x029D */
+            "\x0065\x0323\x0302", /* offset 0x029E */
+            "\x0049\x0309", /* offset 0x029F */
+            "\x0069\x0309", /* offset 0x02A0 */
+            "\x0049\x0323", /* offset 0x02A1 */
+            "\x0069\x0323", /* offset 0x02A2 */
+            "\x004F\x0323", /* offset 0x02A3 */
+            "\x006F\x0323", /* offset 0x02A4 */
+            "\x004F\x0309", /* offset 0x02A5 */
+            "\x006F\x0309", /* offset 0x02A6 */
+            "\x004F\x0302\x0301", /* offset 0x02A7 */
+            "\x006F\x0302\x0301", /* offset 0x02A8 */
+            "\x004F\x0302\x0300", /* offset 0x02A9 */
+            "\x006F\x0302\x0300", /* offset 0x02AA */
+            "\x004F\x0302\x0309", /* offset 0x02AB */
+            "\x006F\x0302\x0309", /* offset 0x02AC */
+            "\x004F\x0302\x0303", /* offset 0x02AD */
+            "\x006F\x0302\x0303", /* offset 0x02AE */
+            "\x004F\x0323\x0302", /* offset 0x02AF */
+            "\x006F\x0323\x0302", /* offset 0x02B0 */
+            "\x004F\x031B\x0301", /* offset 0x02B1 */
+            "\x006F\x031B\x0301", /* offset 0x02B2 */
+            "\x004F\x031B\x0300", /* offset 0x02B3 */
+            "\x006F\x031B\x0300", /* offset 0x02B4 */
+            "\x004F\x031B\x0309", /* offset 0x02B5 */
+            "\x006F\x031B\x0309", /* offset 0x02B6 */
+            "\x004F\x031B\x0303", /* offset 0x02B7 */
+            "\x006F\x031B\x0303", /* offset 0x02B8 */
+            "\x004F\x031B\x0323", /* offset 0x02B9 */
+            "\x006F\x031B\x0323", /* offset 0x02BA */
+            "\x0055\x0323", /* offset 0x02BB */
+            "\x0075\x0323", /* offset 0x02BC */
+            "\x0055\x0309", /* offset 0x02BD */
+            "\x0075\x0309", /* offset 0x02BE */
+            "\x0055\x031B\x0301", /* offset 0x02BF */
+            "\x0075\x031B\x0301", /* offset 0x02C0 */
+            "\x0055\x031B\x0300", /* offset 0x02C1 */
+            "\x0075\x031B\x0300", /* offset 0x02C2 */
+            "\x0055\x031B\x0309", /* offset 0x02C3 */
+            "\x0075\x031B\x0309", /* offset 0x02C4 */
+            "\x0055\x031B\x0303", /* offset 0x02C5 */
+            "\x0075\x031B\x0303", /* offset 0x02C6 */
+            "\x0055\x031B\x0323", /* offset 0x02C7 */
+            "\x0075\x031B\x0323", /* offset 0x02C8 */
+            "\x0059\x0300", /* offset 0x02C9 */
+            "\x0079\x0300", /* offset 0x02CA */
+            "\x0059\x0323", /* offset 0x02CB */
+            "\x0079\x0323", /* offset 0x02CC */
+            "\x0059\x0309", /* offset 0x02CD */
+            "\x0079\x0309", /* offset 0x02CE */
+            "\x0059\x0303", /* offset 0x02CF */
+            "\x0079\x0303", /* offset 0x02D0 */
+            "\x03B1\x0313", /* offset 0x02D1 */
+            "\x03B1\x0314", /* offset 0x02D2 */
+            "\x03B1\x0313\x0300", /* offset 0x02D3 */
+            "\x03B1\x0314\x0300", /* offset 0x02D4 */
+            "\x03B1\x0313\x0301", /* offset 0x02D5 */
+            "\x03B1\x0314\x0301", /* offset 0x02D6 */
+            "\x03B1\x0313\x0342", /* offset 0x02D7 */
+            "\x03B1\x0314\x0342", /* offset 0x02D8 */
+            "\x0391\x0313", /* offset 0x02D9 */
+            "\x0391\x0314", /* offset 0x02DA */
+            "\x0391\x0313\x0300", /* offset 0x02DB */
+            "\x0391\x0314\x0300", /* offset 0x02DC */
+            "\x0391\x0313\x0301", /* offset 0x02DD */
+            "\x0391\x0314\x0301", /* offset 0x02DE */
+            "\x0391\x0313\x0342", /* offset 0x02DF */
+            "\x0391\x0314\x0342", /* offset 0x02E0 */
+            "\x03B5\x0313", /* offset 0x02E1 */
+            "\x03B5\x0314", /* offset 0x02E2 */
+            "\x03B5\x0313\x0300", /* offset 0x02E3 */
+            "\x03B5\x0314\x0300", /* offset 0x02E4 */
+            "\x03B5\x0313\x0301", /* offset 0x02E5 */
+            "\x03B5\x0314\x0301", /* offset 0x02E6 */
+            "\x0395\x0313", /* offset 0x02E7 */
+            "\x0395\x0314", /* offset 0x02E8 */
+            "\x0395\x0313\x0300", /* offset 0x02E9 */
+            "\x0395\x0314\x0300", /* offset 0x02EA */
+            "\x0395\x0313\x0301", /* offset 0x02EB */
+            "\x0395\x0314\x0301", /* offset 0x02EC */
+            "\x03B7\x0313", /* offset 0x02ED */
+            "\x03B7\x0314", /* offset 0x02EE */
+            "\x03B7\x0313\x0300", /* offset 0x02EF */
+            "\x03B7\x0314\x0300", /* offset 0x02F0 */
+            "\x03B7\x0313\x0301", /* offset 0x02F1 */
+            "\x03B7\x0314\x0301", /* offset 0x02F2 */
+            "\x03B7\x0313\x0342", /* offset 0x02F3 */
+            "\x03B7\x0314\x0342", /* offset 0x02F4 */
+            "\x0397\x0313", /* offset 0x02F5 */
+            "\x0397\x0314", /* offset 0x02F6 */
+            "\x0397\x0313\x0300", /* offset 0x02F7 */
+            "\x0397\x0314\x0300", /* offset 0x02F8 */
+            "\x0397\x0313\x0301", /* offset 0x02F9 */
+            "\x0397\x0314\x0301", /* offset 0x02FA */
+            "\x0397\x0313\x0342", /* offset 0x02FB */
+            "\x0397\x0314\x0342", /* offset 0x02FC */
+            "\x03B9\x0313", /* offset 0x02FD */
+            "\x03B9\x0314", /* offset 0x02FE */
+            "\x03B9\x0313\x0300", /* offset 0x02FF */
+            "\x03B9\x0314\x0300", /* offset 0x0300 */
+            "\x03B9\x0313\x0301", /* offset 0x0301 */
+            "\x03B9\x0314\x0301", /* offset 0x0302 */
+            "\x03B9\x0313\x0342", /* offset 0x0303 */
+            "\x03B9\x0314\x0342", /* offset 0x0304 */
+            "\x0399\x0313", /* offset 0x0305 */
+            "\x0399\x0314", /* offset 0x0306 */
+            "\x0399\x0313\x0300", /* offset 0x0307 */
+            "\x0399\x0314\x0300", /* offset 0x0308 */
+            "\x0399\x0313\x0301", /* offset 0x0309 */
+            "\x0399\x0314\x0301", /* offset 0x030A */
+            "\x0399\x0313\x0342", /* offset 0x030B */
+            "\x0399\x0314\x0342", /* offset 0x030C */
+            "\x03BF\x0313", /* offset 0x030D */
+            "\x03BF\x0314", /* offset 0x030E */
+            "\x03BF\x0313\x0300", /* offset 0x030F */
+            "\x03BF\x0314\x0300", /* offset 0x0310 */
+            "\x03BF\x0313\x0301", /* offset 0x0311 */
+            "\x03BF\x0314\x0301", /* offset 0x0312 */
+            "\x039F\x0313", /* offset 0x0313 */
+            "\x039F\x0314", /* offset 0x0314 */
+            "\x039F\x0313\x0300", /* offset 0x0315 */
+            "\x039F\x0314\x0300", /* offset 0x0316 */
+            "\x039F\x0313\x0301", /* offset 0x0317 */
+            "\x039F\x0314\x0301", /* offset 0x0318 */
+            "\x03C5\x0313", /* offset 0x0319 */
+            "\x03C5\x0314", /* offset 0x031A */
+            "\x03C5\x0313\x0300", /* offset 0x031B */
+            "\x03C5\x0314\x0300", /* offset 0x031C */
+            "\x03C5\x0313\x0301", /* offset 0x031D */
+            "\x03C5\x0314\x0301", /* offset 0x031E */
+            "\x03C5\x0313\x0342", /* offset 0x031F */
+            "\x03C5\x0314\x0342", /* offset 0x0320 */
+            "\x03A5\x0314", /* offset 0x0321 */
+            "\x03A5\x0314\x0300", /* offset 0x0322 */
+            "\x03A5\x0314\x0301", /* offset 0x0323 */
+            "\x03A5\x0314\x0342", /* offset 0x0324 */
+            "\x03C9\x0313", /* offset 0x0325 */
+            "\x03C9\x0314", /* offset 0x0326 */
+            "\x03C9\x0313\x0300", /* offset 0x0327 */
+            "\x03C9\x0314\x0300", /* offset 0x0328 */
+            "\x03C9\x0313\x0301", /* offset 0x0329 */
+            "\x03C9\x0314\x0301", /* offset 0x032A */
+            "\x03C9\x0313\x0342", /* offset 0x032B */
+            "\x03C9\x0314\x0342", /* offset 0x032C */
+            "\x03A9\x0313", /* offset 0x032D */
+            "\x03A9\x0314", /* offset 0x032E */
+            "\x03A9\x0313\x0300", /* offset 0x032F */
+            "\x03A9\x0314\x0300", /* offset 0x0330 */
+            "\x03A9\x0313\x0301", /* offset 0x0331 */
+            "\x03A9\x0314\x0301", /* offset 0x0332 */
+            "\x03A9\x0313\x0342", /* offset 0x0333 */
+            "\x03A9\x0314\x0342", /* offset 0x0334 */
+            "\x03B1\x0300", /* offset 0x0335 */
+            "\x03B5\x0300", /* offset 0x0336 */
+            "\x03B7\x0300", /* offset 0x0337 */
+            "\x03B9\x0300", /* offset 0x0338 */
+            "\x03BF\x0300", /* offset 0x0339 */
+            "\x03C5\x0300", /* offset 0x033A */
+            "\x03C9\x0300", /* offset 0x033B */
+            "\x03B1\x0313\x0345", /* offset 0x033C */
+            "\x03B1\x0314\x0345", /* offset 0x033D */
+            "\x03B1\x0313\x0300\x0345", /* offset 0x033E */
+            "\x03B1\x0314\x0300\x0345", /* offset 0x033F */
+            "\x03B1\x0313\x0301\x0345", /* offset 0x0340 */
+            "\x03B1\x0314\x0301\x0345", /* offset 0x0341 */
+            "\x03B1\x0313\x0342\x0345", /* offset 0x0342 */
+            "\x03B1\x0314\x0342\x0345", /* offset 0x0343 */
+            "\x0391\x0313\x0345", /* offset 0x0344 */
+            "\x0391\x0314\x0345", /* offset 0x0345 */
+            "\x0391\x0313\x0300\x0345", /* offset 0x0346 */
+            "\x0391\x0314\x0300\x0345", /* offset 0x0347 */
+            "\x0391\x0313\x0301\x0345", /* offset 0x0348 */
+            "\x0391\x0314\x0301\x0345", /* offset 0x0349 */
+            "\x0391\x0313\x0342\x0345", /* offset 0x034A */
+            "\x0391\x0314\x0342\x0345", /* offset 0x034B */
+            "\x03B7\x0313\x0345", /* offset 0x034C */
+            "\x03B7\x0314\x0345", /* offset 0x034D */
+            "\x03B7\x0313\x0300\x0345", /* offset 0x034E */
+            "\x03B7\x0314\x0300\x0345", /* offset 0x034F */
+            "\x03B7\x0313\x0301\x0345", /* offset 0x0350 */
+            "\x03B7\x0314\x0301\x0345", /* offset 0x0351 */
+            "\x03B7\x0313\x0342\x0345", /* offset 0x0352 */
+            "\x03B7\x0314\x0342\x0345", /* offset 0x0353 */
+            "\x0397\x0313\x0345", /* offset 0x0354 */
+            "\x0397\x0314\x0345", /* offset 0x0355 */
+            "\x0397\x0313\x0300\x0345", /* offset 0x0356 */
+            "\x0397\x0314\x0300\x0345", /* offset 0x0357 */
+            "\x0397\x0313\x0301\x0345", /* offset 0x0358 */
+            "\x0397\x0314\x0301\x0345", /* offset 0x0359 */
+            "\x0397\x0313\x0342\x0345", /* offset 0x035A */
+            "\x0397\x0314\x0342\x0345", /* offset 0x035B */
+            "\x03C9\x0313\x0345", /* offset 0x035C */
+            "\x03C9\x0314\x0345", /* offset 0x035D */
+            "\x03C9\x0313\x0300\x0345", /* offset 0x035E */
+            "\x03C9\x0314\x0300\x0345", /* offset 0x035F */
+            "\x03C9\x0313\x0301\x0345", /* offset 0x0360 */
+            "\x03C9\x0314\x0301\x0345", /* offset 0x0361 */
+            "\x03C9\x0313\x0342\x0345", /* offset 0x0362 */
+            "\x03C9\x0314\x0342\x0345", /* offset 0x0363 */
+            "\x03A9\x0313\x0345", /* offset 0x0364 */
+            "\x03A9\x0314\x0345", /* offset 0x0365 */
+            "\x03A9\x0313\x0300\x0345", /* offset 0x0366 */
+            "\x03A9\x0314\x0300\x0345", /* offset 0x0367 */
+            "\x03A9\x0313\x0301\x0345", /* offset 0x0368 */
+            "\x03A9\x0314\x0301\x0345", /* offset 0x0369 */
+            "\x03A9\x0313\x0342\x0345", /* offset 0x036A */
+            "\x03A9\x0314\x0342\x0345", /* offset 0x036B */
+            "\x03B1\x0306", /* offset 0x036C */
+            "\x03B1\x0304", /* offset 0x036D */
+            "\x03B1\x0300\x0345", /* offset 0x036E */
+            "\x03B1\x0345", /* offset 0x036F */
+            "\x03B1\x0301\x0345", /* offset 0x0370 */
+            "\x03B1\x0342", /* offset 0x0371 */
+            "\x03B1\x0342\x0345", /* offset 0x0372 */
+            "\x0391\x0306", /* offset 0x0373 */
+            "\x0391\x0304", /* offset 0x0374 */
+            "\x0391\x0300", /* offset 0x0375 */
+            "\x0391\x0345", /* offset 0x0376 */
+            "\x0020\x0313", /* offset 0x0377 */
+            "\x03B9", /* offset 0x0378 */
+            "\x0020\x0342", /* offset 0x0379 */
+            "\x0020\x0308\x0342", /* offset 0x037A */
+            "\x03B7\x0300\x0345", /* offset 0x037B */
+            "\x03B7\x0345", /* offset 0x037C */
+            "\x03B7\x0301\x0345", /* offset 0x037D */
+            "\x03B7\x0342", /* offset 0x037E */
+            "\x03B7\x0342\x0345", /* offset 0x037F */
+            "\x0395\x0300", /* offset 0x0380 */
+            "\x0397\x0300", /* offset 0x0381 */
+            "\x0397\x0345", /* offset 0x0382 */
+            "\x0020\x0313\x0300", /* offset 0x0383 */
+            "\x0020\x0313\x0301", /* offset 0x0384 */
+            "\x0020\x0313\x0342", /* offset 0x0385 */
+            "\x03B9\x0306", /* offset 0x0386 */
+            "\x03B9\x0304", /* offset 0x0387 */
+            "\x03B9\x0308\x0300", /* offset 0x0388 */
+            "\x03B9\x0342", /* offset 0x0389 */
+            "\x03B9\x0308\x0342", /* offset 0x038A */
+            "\x0399\x0306", /* offset 0x038B */
+            "\x0399\x0304", /* offset 0x038C */
+            "\x0399\x0300", /* offset 0x038D */
+            "\x0020\x0314\x0300", /* offset 0x038E */
+            "\x0020\x0314\x0301", /* offset 0x038F */
+            "\x0020\x0314\x0342", /* offset 0x0390 */
+            "\x03C5\x0306", /* offset 0x0391 */
+            "\x03C5\x0304", /* offset 0x0392 */
+            "\x03C5\x0308\x0300", /* offset 0x0393 */
+            "\x03C1\x0313", /* offset 0x0394 */
+            "\x03C1\x0314", /* offset 0x0395 */
+            "\x03C5\x0342", /* offset 0x0396 */
+            "\x03C5\x0308\x0342", /* offset 0x0397 */
+            "\x03A5\x0306", /* offset 0x0398 */
+            "\x03A5\x0304", /* offset 0x0399 */
+            "\x03A5\x0300", /* offset 0x039A */
+            "\x03A1\x0314", /* offset 0x039B */
+            "\x0020\x0308\x0300", /* offset 0x039C */
+            "\x0060", /* offset 0x039D */
+            "\x03C9\x0300\x0345", /* offset 0x039E */
+            "\x03C9\x0345", /* offset 0x039F */
+            "\x03C9\x0301\x0345", /* offset 0x03A0 */
+            "\x03C9\x0342", /* offset 0x03A1 */
+            "\x03C9\x0342\x0345", /* offset 0x03A2 */
+            "\x039F\x0300", /* offset 0x03A3 */
+            "\x03A9\x0300", /* offset 0x03A4 */
+            "\x03A9\x0345", /* offset 0x03A5 */
+            "\x0020\x0314", /* offset 0x03A6 */
+            "\x2010", /* offset 0x03A7 */
+            "\x0020\x0333", /* offset 0x03A8 */
+            "\x002E", /* offset 0x03A9 */
+            "\x002E\x002E", /* offset 0x03AA */
+            "\x002E\x002E\x002E", /* offset 0x03AB */
+            "\x2032\x2032", /* offset 0x03AC */
+            "\x2032\x2032\x2032", /* offset 0x03AD */
+            "\x2035\x2035", /* offset 0x03AE */
+            "\x2035\x2035\x2035", /* offset 0x03AF */
+            "\x0021\x0021", /* offset 0x03B0 */
+            "\x0020\x0305", /* offset 0x03B1 */
+            "\x003F\x003F", /* offset 0x03B2 */
+            "\x003F\x0021", /* offset 0x03B3 */
+            "\x0021\x003F", /* offset 0x03B4 */
+            "\x2032\x2032\x2032\x2032", /* offset 0x03B5 */
+            "\x0030", /* offset 0x03B6 */
+            "\x0069", /* offset 0x03B7 */
+            "\x0034", /* offset 0x03B8 */
+            "\x0035", /* offset 0x03B9 */
+            "\x0036", /* offset 0x03BA */
+            "\x0037", /* offset 0x03BB */
+            "\x0038", /* offset 0x03BC */
+            "\x0039", /* offset 0x03BD */
+            "\x002B", /* offset 0x03BE */
+            "\x2212", /* offset 0x03BF */
+            "\x003D", /* offset 0x03C0 */
+            "\x0028", /* offset 0x03C1 */
+            "\x0029", /* offset 0x03C2 */
+            "\x006E", /* offset 0x03C3 */
+            "\x0052\x0073", /* offset 0x03C4 */
+            "\x0061\x002F\x0063", /* offset 0x03C5 */
+            "\x0061\x002F\x0073", /* offset 0x03C6 */
+            "\x0043", /* offset 0x03C7 */
+            "\x00B0\x0043", /* offset 0x03C8 */
+            "\x0063\x002F\x006F", /* offset 0x03C9 */
+            "\x0063\x002F\x0075", /* offset 0x03CA */
+            "\x0190", /* offset 0x03CB */
+            "\x00B0\x0046", /* offset 0x03CC */
+            "\x0067", /* offset 0x03CD */
+            "\x0048", /* offset 0x03CE */
+            "\x0127", /* offset 0x03CF */
+            "\x0049", /* offset 0x03D0 */
+            "\x004C", /* offset 0x03D1 */
+            "\x004E", /* offset 0x03D2 */
+            "\x004E\x006F", /* offset 0x03D3 */
+            "\x0050", /* offset 0x03D4 */
+            "\x0051", /* offset 0x03D5 */
+            "\x0052", /* offset 0x03D6 */
+            "\x0053\x004D", /* offset 0x03D7 */
+            "\x0054\x0045\x004C", /* offset 0x03D8 */
+            "\x0054\x004D", /* offset 0x03D9 */
+            "\x005A", /* offset 0x03DA */
+            "\x03A9", /* offset 0x03DB */
+            "\x004B", /* offset 0x03DC */
+            "\x0042", /* offset 0x03DD */
+            "\x0065", /* offset 0x03DE */
+            "\x0045", /* offset 0x03DF */
+            "\x0046", /* offset 0x03E0 */
+            "\x004D", /* offset 0x03E1 */
+            "\x05D0", /* offset 0x03E2 */
+            "\x05D1", /* offset 0x03E3 */
+            "\x05D2", /* offset 0x03E4 */
+            "\x05D3", /* offset 0x03E5 */
+            "\x03B3", /* offset 0x03E6 */
+            "\x0393", /* offset 0x03E7 */
+            "\x03A0", /* offset 0x03E8 */
+            "\x2211", /* offset 0x03E9 */
+            "\x0044", /* offset 0x03EA */
+            "\x0064", /* offset 0x03EB */
+            "\x0031\x2044\x0033", /* offset 0x03EC */
+            "\x0032\x2044\x0033", /* offset 0x03ED */
+            "\x0031\x2044\x0035", /* offset 0x03EE */
+            "\x0032\x2044\x0035", /* offset 0x03EF */
+            "\x0033\x2044\x0035", /* offset 0x03F0 */
+            "\x0034\x2044\x0035", /* offset 0x03F1 */
+            "\x0031\x2044\x0036", /* offset 0x03F2 */
+            "\x0035\x2044\x0036", /* offset 0x03F3 */
+            "\x0031\x2044\x0038", /* offset 0x03F4 */
+            "\x0033\x2044\x0038", /* offset 0x03F5 */
+            "\x0035\x2044\x0038", /* offset 0x03F6 */
+            "\x0037\x2044\x0038", /* offset 0x03F7 */
+            "\x0031\x2044", /* offset 0x03F8 */
+            "\x0049\x0049", /* offset 0x03F9 */
+            "\x0049\x0049\x0049", /* offset 0x03FA */
+            "\x0049\x0056", /* offset 0x03FB */
+            "\x0056", /* offset 0x03FC */
+            "\x0056\x0049", /* offset 0x03FD */
+            "\x0056\x0049\x0049", /* offset 0x03FE */
+            "\x0056\x0049\x0049\x0049", /* offset 0x03FF */
+            "\x0049\x0058", /* offset 0x0400 */
+            "\x0058", /* offset 0x0401 */
+            "\x0058\x0049", /* offset 0x0402 */
+            "\x0058\x0049\x0049", /* offset 0x0403 */
+            "\x0069\x0069", /* offset 0x0404 */
+            "\x0069\x0069\x0069", /* offset 0x0405 */
+            "\x0069\x0076", /* offset 0x0406 */
+            "\x0076", /* offset 0x0407 */
+            "\x0076\x0069", /* offset 0x0408 */
+            "\x0076\x0069\x0069", /* offset 0x0409 */
+            "\x0076\x0069\x0069\x0069", /* offset 0x040A */
+            "\x0069\x0078", /* offset 0x040B */
+            "\x0078\x0069", /* offset 0x040C */
+            "\x0078\x0069\x0069", /* offset 0x040D */
+            "\x0063", /* offset 0x040E */
+            "\x006D", /* offset 0x040F */
+            "\x2190\x0338", /* offset 0x0410 */
+            "\x2192\x0338", /* offset 0x0411 */
+            "\x2194\x0338", /* offset 0x0412 */
+            "\x21D0\x0338", /* offset 0x0413 */
+            "\x21D4\x0338", /* offset 0x0414 */
+            "\x21D2\x0338", /* offset 0x0415 */
+            "\x2203\x0338", /* offset 0x0416 */
+            "\x2208\x0338", /* offset 0x0417 */
+            "\x220B\x0338", /* offset 0x0418 */
+            "\x2223\x0338", /* offset 0x0419 */
+            "\x2225\x0338", /* offset 0x041A */
+            "\x222B\x222B", /* offset 0x041B */
+            "\x222B\x222B\x222B", /* offset 0x041C */
+            "\x222E\x222E", /* offset 0x041D */
+            "\x222E\x222E\x222E", /* offset 0x041E */
+            "\x223C\x0338", /* offset 0x041F */
+            "\x2243\x0338", /* offset 0x0420 */
+            "\x2245\x0338", /* offset 0x0421 */
+            "\x2248\x0338", /* offset 0x0422 */
+            "\x003D\x0338", /* offset 0x0423 */
+            "\x2261\x0338", /* offset 0x0424 */
+            "\x224D\x0338", /* offset 0x0425 */
+            "\x003C\x0338", /* offset 0x0426 */
+            "\x003E\x0338", /* offset 0x0427 */
+            "\x2264\x0338", /* offset 0x0428 */
+            "\x2265\x0338", /* offset 0x0429 */
+            "\x2272\x0338", /* offset 0x042A */
+            "\x2273\x0338", /* offset 0x042B */
+            "\x2276\x0338", /* offset 0x042C */
+            "\x2277\x0338", /* offset 0x042D */
+            "\x227A\x0338", /* offset 0x042E */
+            "\x227B\x0338", /* offset 0x042F */
+            "\x2282\x0338", /* offset 0x0430 */
+            "\x2283\x0338", /* offset 0x0431 */
+            "\x2286\x0338", /* offset 0x0432 */
+            "\x2287\x0338", /* offset 0x0433 */
+            "\x22A2\x0338", /* offset 0x0434 */
+            "\x22A8\x0338", /* offset 0x0435 */
+            "\x22A9\x0338", /* offset 0x0436 */
+            "\x22AB\x0338", /* offset 0x0437 */
+            "\x227C\x0338", /* offset 0x0438 */
+            "\x227D\x0338", /* offset 0x0439 */
+            "\x2291\x0338", /* offset 0x043A */
+            "\x2292\x0338", /* offset 0x043B */
+            "\x22B2\x0338", /* offset 0x043C */
+            "\x22B3\x0338", /* offset 0x043D */
+            "\x22B4\x0338", /* offset 0x043E */
+            "\x22B5\x0338", /* offset 0x043F */
+            "\x3008", /* offset 0x0440 */
+            "\x3009", /* offset 0x0441 */
+            "\x0031\x0030", /* offset 0x0442 */
+            "\x0031\x0031", /* offset 0x0443 */
+            "\x0031\x0032", /* offset 0x0444 */
+            "\x0031\x0033", /* offset 0x0445 */
+            "\x0031\x0034", /* offset 0x0446 */
+            "\x0031\x0035", /* offset 0x0447 */
+            "\x0031\x0036", /* offset 0x0448 */
+            "\x0031\x0037", /* offset 0x0449 */
+            "\x0031\x0038", /* offset 0x044A */
+            "\x0031\x0039", /* offset 0x044B */
+            "\x0032\x0030", /* offset 0x044C */
+            "\x0028\x0031\x0029", /* offset 0x044D */
+            "\x0028\x0032\x0029", /* offset 0x044E */
+            "\x0028\x0033\x0029", /* offset 0x044F */
+            "\x0028\x0034\x0029", /* offset 0x0450 */
+            "\x0028\x0035\x0029", /* offset 0x0451 */
+            "\x0028\x0036\x0029", /* offset 0x0452 */
+            "\x0028\x0037\x0029", /* offset 0x0453 */
+            "\x0028\x0038\x0029", /* offset 0x0454 */
+            "\x0028\x0039\x0029", /* offset 0x0455 */
+            "\x0028\x0031\x0030\x0029", /* offset 0x0456 */
+            "\x0028\x0031\x0031\x0029", /* offset 0x0457 */
+            "\x0028\x0031\x0032\x0029", /* offset 0x0458 */
+            "\x0028\x0031\x0033\x0029", /* offset 0x0459 */
+            "\x0028\x0031\x0034\x0029", /* offset 0x045A */
+            "\x0028\x0031\x0035\x0029", /* offset 0x045B */
+            "\x0028\x0031\x0036\x0029", /* offset 0x045C */
+            "\x0028\x0031\x0037\x0029", /* offset 0x045D */
+            "\x0028\x0031\x0038\x0029", /* offset 0x045E */
+            "\x0028\x0031\x0039\x0029", /* offset 0x045F */
+            "\x0028\x0032\x0030\x0029", /* offset 0x0460 */
+            "\x0031\x002E", /* offset 0x0461 */
+            "\x0032\x002E", /* offset 0x0462 */
+            "\x0033\x002E", /* offset 0x0463 */
+            "\x0034\x002E", /* offset 0x0464 */
+            "\x0035\x002E", /* offset 0x0465 */
+            "\x0036\x002E", /* offset 0x0466 */
+            "\x0037\x002E", /* offset 0x0467 */
+            "\x0038\x002E", /* offset 0x0468 */
+            "\x0039\x002E", /* offset 0x0469 */
+            "\x0031\x0030\x002E", /* offset 0x046A */
+            "\x0031\x0031\x002E", /* offset 0x046B */
+            "\x0031\x0032\x002E", /* offset 0x046C */
+            "\x0031\x0033\x002E", /* offset 0x046D */
+            "\x0031\x0034\x002E", /* offset 0x046E */
+            "\x0031\x0035\x002E", /* offset 0x046F */
+            "\x0031\x0036\x002E", /* offset 0x0470 */
+            "\x0031\x0037\x002E", /* offset 0x0471 */
+            "\x0031\x0038\x002E", /* offset 0x0472 */
+            "\x0031\x0039\x002E", /* offset 0x0473 */
+            "\x0032\x0030\x002E", /* offset 0x0474 */
+            "\x0028\x0061\x0029", /* offset 0x0475 */
+            "\x0028\x0062\x0029", /* offset 0x0476 */
+            "\x0028\x0063\x0029", /* offset 0x0477 */
+            "\x0028\x0064\x0029", /* offset 0x0478 */
+            "\x0028\x0065\x0029", /* offset 0x0479 */
+            "\x0028\x0066\x0029", /* offset 0x047A */
+            "\x0028\x0067\x0029", /* offset 0x047B */
+            "\x0028\x0068\x0029", /* offset 0x047C */
+            "\x0028\x0069\x0029", /* offset 0x047D */
+            "\x0028\x006A\x0029", /* offset 0x047E */
+            "\x0028\x006B\x0029", /* offset 0x047F */
+            "\x0028\x006C\x0029", /* offset 0x0480 */
+            "\x0028\x006D\x0029", /* offset 0x0481 */
+            "\x0028\x006E\x0029", /* offset 0x0482 */
+            "\x0028\x006F\x0029", /* offset 0x0483 */
+            "\x0028\x0070\x0029", /* offset 0x0484 */
+            "\x0028\x0071\x0029", /* offset 0x0485 */
+            "\x0028\x0072\x0029", /* offset 0x0486 */
+            "\x0028\x0073\x0029", /* offset 0x0487 */
+            "\x0028\x0074\x0029", /* offset 0x0488 */
+            "\x0028\x0075\x0029", /* offset 0x0489 */
+            "\x0028\x0076\x0029", /* offset 0x048A */
+            "\x0028\x0077\x0029", /* offset 0x048B */
+            "\x0028\x0078\x0029", /* offset 0x048C */
+            "\x0028\x0079\x0029", /* offset 0x048D */
+            "\x0028\x007A\x0029", /* offset 0x048E */
+            "\x0041", /* offset 0x048F */
+            "\x0047", /* offset 0x0490 */
+            "\x004A", /* offset 0x0491 */
+            "\x004F", /* offset 0x0492 */
+            "\x0053", /* offset 0x0493 */
+            "\x0054", /* offset 0x0494 */
+            "\x0055", /* offset 0x0495 */
+            "\x0057", /* offset 0x0496 */
+            "\x0059", /* offset 0x0497 */
+            "\x0062", /* offset 0x0498 */
+            "\x0066", /* offset 0x0499 */
+            "\x006B", /* offset 0x049A */
+            "\x0070", /* offset 0x049B */
+            "\x0071", /* offset 0x049C */
+            "\x0074", /* offset 0x049D */
+            "\x0075", /* offset 0x049E */
+            "\x007A", /* offset 0x049F */
+            "\x222B\x222B\x222B\x222B", /* offset 0x04A0 */
+            "\x003A\x003A\x003D", /* offset 0x04A1 */
+            "\x003D\x003D", /* offset 0x04A2 */
+            "\x003D\x003D\x003D", /* offset 0x04A3 */
+            "\x2ADD\x0338", /* offset 0x04A4 */
+            "\x6BCD", /* offset 0x04A5 */
+            "\x9F9F", /* offset 0x04A6 */
+            "\x4E00", /* offset 0x04A7 */
+            "\x4E28", /* offset 0x04A8 */
+            "\x4E36", /* offset 0x04A9 */
+            "\x4E3F", /* offset 0x04AA */
+            "\x4E59", /* offset 0x04AB */
+            "\x4E85", /* offset 0x04AC */
+            "\x4E8C", /* offset 0x04AD */
+            "\x4EA0", /* offset 0x04AE */
+            "\x4EBA", /* offset 0x04AF */
+            "\x513F", /* offset 0x04B0 */
+            "\x5165", /* offset 0x04B1 */
+            "\x516B", /* offset 0x04B2 */
+            "\x5182", /* offset 0x04B3 */
+            "\x5196", /* offset 0x04B4 */
+            "\x51AB", /* offset 0x04B5 */
+            "\x51E0", /* offset 0x04B6 */
+            "\x51F5", /* offset 0x04B7 */
+            "\x5200", /* offset 0x04B8 */
+            "\x529B", /* offset 0x04B9 */
+            "\x52F9", /* offset 0x04BA */
+            "\x5315", /* offset 0x04BB */
+            "\x531A", /* offset 0x04BC */
+            "\x5338", /* offset 0x04BD */
+            "\x5341", /* offset 0x04BE */
+            "\x535C", /* offset 0x04BF */
+            "\x5369", /* offset 0x04C0 */
+            "\x5382", /* offset 0x04C1 */
+            "\x53B6", /* offset 0x04C2 */
+            "\x53C8", /* offset 0x04C3 */
+            "\x53E3", /* offset 0x04C4 */
+            "\x56D7", /* offset 0x04C5 */
+            "\x571F", /* offset 0x04C6 */
+            "\x58EB", /* offset 0x04C7 */
+            "\x5902", /* offset 0x04C8 */
+            "\x590A", /* offset 0x04C9 */
+            "\x5915", /* offset 0x04CA */
+            "\x5927", /* offset 0x04CB */
+            "\x5973", /* offset 0x04CC */
+            "\x5B50", /* offset 0x04CD */
+            "\x5B80", /* offset 0x04CE */
+            "\x5BF8", /* offset 0x04CF */
+            "\x5C0F", /* offset 0x04D0 */
+            "\x5C22", /* offset 0x04D1 */
+            "\x5C38", /* offset 0x04D2 */
+            "\x5C6E", /* offset 0x04D3 */
+            "\x5C71", /* offset 0x04D4 */
+            "\x5DDB", /* offset 0x04D5 */
+            "\x5DE5", /* offset 0x04D6 */
+            "\x5DF1", /* offset 0x04D7 */
+            "\x5DFE", /* offset 0x04D8 */
+            "\x5E72", /* offset 0x04D9 */
+            "\x5E7A", /* offset 0x04DA */
+            "\x5E7F", /* offset 0x04DB */
+            "\x5EF4", /* offset 0x04DC */
+            "\x5EFE", /* offset 0x04DD */
+            "\x5F0B", /* offset 0x04DE */
+            "\x5F13", /* offset 0x04DF */
+            "\x5F50", /* offset 0x04E0 */
+            "\x5F61", /* offset 0x04E1 */
+            "\x5F73", /* offset 0x04E2 */
+            "\x5FC3", /* offset 0x04E3 */
+            "\x6208", /* offset 0x04E4 */
+            "\x6236", /* offset 0x04E5 */
+            "\x624B", /* offset 0x04E6 */
+            "\x652F", /* offset 0x04E7 */
+            "\x6534", /* offset 0x04E8 */
+            "\x6587", /* offset 0x04E9 */
+            "\x6597", /* offset 0x04EA */
+            "\x65A4", /* offset 0x04EB */
+            "\x65B9", /* offset 0x04EC */
+            "\x65E0", /* offset 0x04ED */
+            "\x65E5", /* offset 0x04EE */
+            "\x66F0", /* offset 0x04EF */
+            "\x6708", /* offset 0x04F0 */
+            "\x6728", /* offset 0x04F1 */
+            "\x6B20", /* offset 0x04F2 */
+            "\x6B62", /* offset 0x04F3 */
+            "\x6B79", /* offset 0x04F4 */
+            "\x6BB3", /* offset 0x04F5 */
+            "\x6BCB", /* offset 0x04F6 */
+            "\x6BD4", /* offset 0x04F7 */
+            "\x6BDB", /* offset 0x04F8 */
+            "\x6C0F", /* offset 0x04F9 */
+            "\x6C14", /* offset 0x04FA */
+            "\x6C34", /* offset 0x04FB */
+            "\x706B", /* offset 0x04FC */
+            "\x722A", /* offset 0x04FD */
+            "\x7236", /* offset 0x04FE */
+            "\x723B", /* offset 0x04FF */
+            "\x723F", /* offset 0x0500 */
+            "\x7247", /* offset 0x0501 */
+            "\x7259", /* offset 0x0502 */
+            "\x725B", /* offset 0x0503 */
+            "\x72AC", /* offset 0x0504 */
+            "\x7384", /* offset 0x0505 */
+            "\x7389", /* offset 0x0506 */
+            "\x74DC", /* offset 0x0507 */
+            "\x74E6", /* offset 0x0508 */
+            "\x7518", /* offset 0x0509 */
+            "\x751F", /* offset 0x050A */
+            "\x7528", /* offset 0x050B */
+            "\x7530", /* offset 0x050C */
+            "\x758B", /* offset 0x050D */
+            "\x7592", /* offset 0x050E */
+            "\x7676", /* offset 0x050F */
+            "\x767D", /* offset 0x0510 */
+            "\x76AE", /* offset 0x0511 */
+            "\x76BF", /* offset 0x0512 */
+            "\x76EE", /* offset 0x0513 */
+            "\x77DB", /* offset 0x0514 */
+            "\x77E2", /* offset 0x0515 */
+            "\x77F3", /* offset 0x0516 */
+            "\x793A", /* offset 0x0517 */
+            "\x79B8", /* offset 0x0518 */
+            "\x79BE", /* offset 0x0519 */
+            "\x7A74", /* offset 0x051A */
+            "\x7ACB", /* offset 0x051B */
+            "\x7AF9", /* offset 0x051C */
+            "\x7C73", /* offset 0x051D */
+            "\x7CF8", /* offset 0x051E */
+            "\x7F36", /* offset 0x051F */
+            "\x7F51", /* offset 0x0520 */
+            "\x7F8A", /* offset 0x0521 */
+            "\x7FBD", /* offset 0x0522 */
+            "\x8001", /* offset 0x0523 */
+            "\x800C", /* offset 0x0524 */
+            "\x8012", /* offset 0x0525 */
+            "\x8033", /* offset 0x0526 */
+            "\x807F", /* offset 0x0527 */
+            "\x8089", /* offset 0x0528 */
+            "\x81E3", /* offset 0x0529 */
+            "\x81EA", /* offset 0x052A */
+            "\x81F3", /* offset 0x052B */
+            "\x81FC", /* offset 0x052C */
+            "\x820C", /* offset 0x052D */
+            "\x821B", /* offset 0x052E */
+            "\x821F", /* offset 0x052F */
+            "\x826E", /* offset 0x0530 */
+            "\x8272", /* offset 0x0531 */
+            "\x8278", /* offset 0x0532 */
+            "\x864D", /* offset 0x0533 */
+            "\x866B", /* offset 0x0534 */
+            "\x8840", /* offset 0x0535 */
+            "\x884C", /* offset 0x0536 */
+            "\x8863", /* offset 0x0537 */
+            "\x897E", /* offset 0x0538 */
+            "\x898B", /* offset 0x0539 */
+            "\x89D2", /* offset 0x053A */
+            "\x8A00", /* offset 0x053B */
+            "\x8C37", /* offset 0x053C */
+            "\x8C46", /* offset 0x053D */
+            "\x8C55", /* offset 0x053E */
+            "\x8C78", /* offset 0x053F */
+            "\x8C9D", /* offset 0x0540 */
+            "\x8D64", /* offset 0x0541 */
+            "\x8D70", /* offset 0x0542 */
+            "\x8DB3", /* offset 0x0543 */
+            "\x8EAB", /* offset 0x0544 */
+            "\x8ECA", /* offset 0x0545 */
+            "\x8F9B", /* offset 0x0546 */
+            "\x8FB0", /* offset 0x0547 */
+            "\x8FB5", /* offset 0x0548 */
+            "\x9091", /* offset 0x0549 */
+            "\x9149", /* offset 0x054A */
+            "\x91C6", /* offset 0x054B */
+            "\x91CC", /* offset 0x054C */
+            "\x91D1", /* offset 0x054D */
+            "\x9577", /* offset 0x054E */
+            "\x9580", /* offset 0x054F */
+            "\x961C", /* offset 0x0550 */
+            "\x96B6", /* offset 0x0551 */
+            "\x96B9", /* offset 0x0552 */
+            "\x96E8", /* offset 0x0553 */
+            "\x9751", /* offset 0x0554 */
+            "\x975E", /* offset 0x0555 */
+            "\x9762", /* offset 0x0556 */
+            "\x9769", /* offset 0x0557 */
+            "\x97CB", /* offset 0x0558 */
+            "\x97ED", /* offset 0x0559 */
+            "\x97F3", /* offset 0x055A */
+            "\x9801", /* offset 0x055B */
+            "\x98A8", /* offset 0x055C */
+            "\x98DB", /* offset 0x055D */
+            "\x98DF", /* offset 0x055E */
+            "\x9996", /* offset 0x055F */
+            "\x9999", /* offset 0x0560 */
+            "\x99AC", /* offset 0x0561 */
+            "\x9AA8", /* offset 0x0562 */
+            "\x9AD8", /* offset 0x0563 */
+            "\x9ADF", /* offset 0x0564 */
+            "\x9B25", /* offset 0x0565 */
+            "\x9B2F", /* offset 0x0566 */
+            "\x9B32", /* offset 0x0567 */
+            "\x9B3C", /* offset 0x0568 */
+            "\x9B5A", /* offset 0x0569 */
+            "\x9CE5", /* offset 0x056A */
+            "\x9E75", /* offset 0x056B */
+            "\x9E7F", /* offset 0x056C */
+            "\x9EA5", /* offset 0x056D */
+            "\x9EBB", /* offset 0x056E */
+            "\x9EC3", /* offset 0x056F */
+            "\x9ECD", /* offset 0x0570 */
+            "\x9ED1", /* offset 0x0571 */
+            "\x9EF9", /* offset 0x0572 */
+            "\x9EFD", /* offset 0x0573 */
+            "\x9F0E", /* offset 0x0574 */
+            "\x9F13", /* offset 0x0575 */
+            "\x9F20", /* offset 0x0576 */
+            "\x9F3B", /* offset 0x0577 */
+            "\x9F4A", /* offset 0x0578 */
+            "\x9F52", /* offset 0x0579 */
+            "\x9F8D", /* offset 0x057A */
+            "\x9F9C", /* offset 0x057B */
+            "\x9FA0", /* offset 0x057C */
+            "\x3012", /* offset 0x057D */
+            "\x5344", /* offset 0x057E */
+            "\x5345", /* offset 0x057F */
+            "\x304B\x3099", /* offset 0x0580 */
+            "\x304D\x3099", /* offset 0x0581 */
+            "\x304F\x3099", /* offset 0x0582 */
+            "\x3051\x3099", /* offset 0x0583 */
+            "\x3053\x3099", /* offset 0x0584 */
+            "\x3055\x3099", /* offset 0x0585 */
+            "\x3057\x3099", /* offset 0x0586 */
+            "\x3059\x3099", /* offset 0x0587 */
+            "\x305B\x3099", /* offset 0x0588 */
+            "\x305D\x3099", /* offset 0x0589 */
+            "\x305F\x3099", /* offset 0x058A */
+            "\x3061\x3099", /* offset 0x058B */
+            "\x3064\x3099", /* offset 0x058C */
+            "\x3066\x3099", /* offset 0x058D */
+            "\x3068\x3099", /* offset 0x058E */
+            "\x306F\x3099", /* offset 0x058F */
+            "\x306F\x309A", /* offset 0x0590 */
+            "\x3072\x3099", /* offset 0x0591 */
+            "\x3072\x309A", /* offset 0x0592 */
+            "\x3075\x3099", /* offset 0x0593 */
+            "\x3075\x309A", /* offset 0x0594 */
+            "\x3078\x3099", /* offset 0x0595 */
+            "\x3078\x309A", /* offset 0x0596 */
+            "\x307B\x3099", /* offset 0x0597 */
+            "\x307B\x309A", /* offset 0x0598 */
+            "\x3046\x3099", /* offset 0x0599 */
+            "\x0020\x3099", /* offset 0x059A */
+            "\x0020\x309A", /* offset 0x059B */
+            "\x309D\x3099", /* offset 0x059C */
+            "\x3088\x308A", /* offset 0x059D */
+            "\x30AB\x3099", /* offset 0x059E */
+            "\x30AD\x3099", /* offset 0x059F */
+            "\x30AF\x3099", /* offset 0x05A0 */
+            "\x30B1\x3099", /* offset 0x05A1 */
+            "\x30B3\x3099", /* offset 0x05A2 */
+            "\x30B5\x3099", /* offset 0x05A3 */
+            "\x30B7\x3099", /* offset 0x05A4 */
+            "\x30B9\x3099", /* offset 0x05A5 */
+            "\x30BB\x3099", /* offset 0x05A6 */
+            "\x30BD\x3099", /* offset 0x05A7 */
+            "\x30BF\x3099", /* offset 0x05A8 */
+            "\x30C1\x3099", /* offset 0x05A9 */
+            "\x30C4\x3099", /* offset 0x05AA */
+            "\x30C6\x3099", /* offset 0x05AB */
+            "\x30C8\x3099", /* offset 0x05AC */
+            "\x30CF\x3099", /* offset 0x05AD */
+            "\x30CF\x309A", /* offset 0x05AE */
+            "\x30D2\x3099", /* offset 0x05AF */
+            "\x30D2\x309A", /* offset 0x05B0 */
+            "\x30D5\x3099", /* offset 0x05B1 */
+            "\x30D5\x309A", /* offset 0x05B2 */
+            "\x30D8\x3099", /* offset 0x05B3 */
+            "\x30D8\x309A", /* offset 0x05B4 */
+            "\x30DB\x3099", /* offset 0x05B5 */
+            "\x30DB\x309A", /* offset 0x05B6 */
+            "\x30A6\x3099", /* offset 0x05B7 */
+            "\x30EF\x3099", /* offset 0x05B8 */
+            "\x30F0\x3099", /* offset 0x05B9 */
+            "\x30F1\x3099", /* offset 0x05BA */
+            "\x30F2\x3099", /* offset 0x05BB */
+            "\x30FD\x3099", /* offset 0x05BC */
+            "\x30B3\x30C8", /* offset 0x05BD */
+            "\x1100", /* offset 0x05BE */
+            "\x1101", /* offset 0x05BF */
+            "\x11AA", /* offset 0x05C0 */
+            "\x1102", /* offset 0x05C1 */
+            "\x11AC", /* offset 0x05C2 */
+            "\x11AD", /* offset 0x05C3 */
+            "\x1103", /* offset 0x05C4 */
+            "\x1104", /* offset 0x05C5 */
+            "\x1105", /* offset 0x05C6 */
+            "\x11B0", /* offset 0x05C7 */
+            "\x11B1", /* offset 0x05C8 */
+            "\x11B2", /* offset 0x05C9 */
+            "\x11B3", /* offset 0x05CA */
+            "\x11B4", /* offset 0x05CB */
+            "\x11B5", /* offset 0x05CC */
+            "\x111A", /* offset 0x05CD */
+            "\x1106", /* offset 0x05CE */
+            "\x1107", /* offset 0x05CF */
+            "\x1108", /* offset 0x05D0 */
+            "\x1121", /* offset 0x05D1 */
+            "\x1109", /* offset 0x05D2 */
+            "\x110A", /* offset 0x05D3 */
+            "\x110B", /* offset 0x05D4 */
+            "\x110C", /* offset 0x05D5 */
+            "\x110D", /* offset 0x05D6 */
+            "\x110E", /* offset 0x05D7 */
+            "\x110F", /* offset 0x05D8 */
+            "\x1110", /* offset 0x05D9 */
+            "\x1111", /* offset 0x05DA */
+            "\x1112", /* offset 0x05DB */
+            "\x1161", /* offset 0x05DC */
+            "\x1162", /* offset 0x05DD */
+            "\x1163", /* offset 0x05DE */
+            "\x1164", /* offset 0x05DF */
+            "\x1165", /* offset 0x05E0 */
+            "\x1166", /* offset 0x05E1 */
+            "\x1167", /* offset 0x05E2 */
+            "\x1168", /* offset 0x05E3 */
+            "\x1169", /* offset 0x05E4 */
+            "\x116A", /* offset 0x05E5 */
+            "\x116B", /* offset 0x05E6 */
+            "\x116C", /* offset 0x05E7 */
+            "\x116D", /* offset 0x05E8 */
+            "\x116E", /* offset 0x05E9 */
+            "\x116F", /* offset 0x05EA */
+            "\x1170", /* offset 0x05EB */
+            "\x1171", /* offset 0x05EC */
+            "\x1172", /* offset 0x05ED */
+            "\x1173", /* offset 0x05EE */
+            "\x1174", /* offset 0x05EF */
+            "\x1175", /* offset 0x05F0 */
+            "\x1160", /* offset 0x05F1 */
+            "\x1114", /* offset 0x05F2 */
+            "\x1115", /* offset 0x05F3 */
+            "\x11C7", /* offset 0x05F4 */
+            "\x11C8", /* offset 0x05F5 */
+            "\x11CC", /* offset 0x05F6 */
+            "\x11CE", /* offset 0x05F7 */
+            "\x11D3", /* offset 0x05F8 */
+            "\x11D7", /* offset 0x05F9 */
+            "\x11D9", /* offset 0x05FA */
+            "\x111C", /* offset 0x05FB */
+            "\x11DD", /* offset 0x05FC */
+            "\x11DF", /* offset 0x05FD */
+            "\x111D", /* offset 0x05FE */
+            "\x111E", /* offset 0x05FF */
+            "\x1120", /* offset 0x0600 */
+            "\x1122", /* offset 0x0601 */
+            "\x1123", /* offset 0x0602 */
+            "\x1127", /* offset 0x0603 */
+            "\x1129", /* offset 0x0604 */
+            "\x112B", /* offset 0x0605 */
+            "\x112C", /* offset 0x0606 */
+            "\x112D", /* offset 0x0607 */
+            "\x112E", /* offset 0x0608 */
+            "\x112F", /* offset 0x0609 */
+            "\x1132", /* offset 0x060A */
+            "\x1136", /* offset 0x060B */
+            "\x1140", /* offset 0x060C */
+            "\x1147", /* offset 0x060D */
+            "\x114C", /* offset 0x060E */
+            "\x11F1", /* offset 0x060F */
+            "\x11F2", /* offset 0x0610 */
+            "\x1157", /* offset 0x0611 */
+            "\x1158", /* offset 0x0612 */
+            "\x1159", /* offset 0x0613 */
+            "\x1184", /* offset 0x0614 */
+            "\x1185", /* offset 0x0615 */
+            "\x1188", /* offset 0x0616 */
+            "\x1191", /* offset 0x0617 */
+            "\x1192", /* offset 0x0618 */
+            "\x1194", /* offset 0x0619 */
+            "\x119E", /* offset 0x061A */
+            "\x11A1", /* offset 0x061B */
+            "\x4E09", /* offset 0x061C */
+            "\x56DB", /* offset 0x061D */
+            "\x4E0A", /* offset 0x061E */
+            "\x4E2D", /* offset 0x061F */
+            "\x4E0B", /* offset 0x0620 */
+            "\x7532", /* offset 0x0621 */
+            "\x4E19", /* offset 0x0622 */
+            "\x4E01", /* offset 0x0623 */
+            "\x5929", /* offset 0x0624 */
+            "\x5730", /* offset 0x0625 */
+            "\x0028\x1100\x0029", /* offset 0x0626 */
+            "\x0028\x1102\x0029", /* offset 0x0627 */
+            "\x0028\x1103\x0029", /* offset 0x0628 */
+            "\x0028\x1105\x0029", /* offset 0x0629 */
+            "\x0028\x1106\x0029", /* offset 0x062A */
+            "\x0028\x1107\x0029", /* offset 0x062B */
+            "\x0028\x1109\x0029", /* offset 0x062C */
+            "\x0028\x110B\x0029", /* offset 0x062D */
+            "\x0028\x110C\x0029", /* offset 0x062E */
+            "\x0028\x110E\x0029", /* offset 0x062F */
+            "\x0028\x110F\x0029", /* offset 0x0630 */
+            "\x0028\x1110\x0029", /* offset 0x0631 */
+            "\x0028\x1111\x0029", /* offset 0x0632 */
+            "\x0028\x1112\x0029", /* offset 0x0633 */
+            "\x0028\x1100\x1161\x0029", /* offset 0x0634 */
+            "\x0028\x1102\x1161\x0029", /* offset 0x0635 */
+            "\x0028\x1103\x1161\x0029", /* offset 0x0636 */
+            "\x0028\x1105\x1161\x0029", /* offset 0x0637 */
+            "\x0028\x1106\x1161\x0029", /* offset 0x0638 */
+            "\x0028\x1107\x1161\x0029", /* offset 0x0639 */
+            "\x0028\x1109\x1161\x0029", /* offset 0x063A */
+            "\x0028\x110B\x1161\x0029", /* offset 0x063B */
+            "\x0028\x110C\x1161\x0029", /* offset 0x063C */
+            "\x0028\x110E\x1161\x0029", /* offset 0x063D */
+            "\x0028\x110F\x1161\x0029", /* offset 0x063E */
+            "\x0028\x1110\x1161\x0029", /* offset 0x063F */
+            "\x0028\x1111\x1161\x0029", /* offset 0x0640 */
+            "\x0028\x1112\x1161\x0029", /* offset 0x0641 */
+            "\x0028\x110C\x116E\x0029", /* offset 0x0642 */
+            "\x0028\x4E00\x0029", /* offset 0x0643 */
+            "\x0028\x4E8C\x0029", /* offset 0x0644 */
+            "\x0028\x4E09\x0029", /* offset 0x0645 */
+            "\x0028\x56DB\x0029", /* offset 0x0646 */
+            "\x0028\x4E94\x0029", /* offset 0x0647 */
+            "\x0028\x516D\x0029", /* offset 0x0648 */
+            "\x0028\x4E03\x0029", /* offset 0x0649 */
+            "\x0028\x516B\x0029", /* offset 0x064A */
+            "\x0028\x4E5D\x0029", /* offset 0x064B */
+            "\x0028\x5341\x0029", /* offset 0x064C */
+            "\x0028\x6708\x0029", /* offset 0x064D */
+            "\x0028\x706B\x0029", /* offset 0x064E */
+            "\x0028\x6C34\x0029", /* offset 0x064F */
+            "\x0028\x6728\x0029", /* offset 0x0650 */
+            "\x0028\x91D1\x0029", /* offset 0x0651 */
+            "\x0028\x571F\x0029", /* offset 0x0652 */
+            "\x0028\x65E5\x0029", /* offset 0x0653 */
+            "\x0028\x682A\x0029", /* offset 0x0654 */
+            "\x0028\x6709\x0029", /* offset 0x0655 */
+            "\x0028\x793E\x0029", /* offset 0x0656 */
+            "\x0028\x540D\x0029", /* offset 0x0657 */
+            "\x0028\x7279\x0029", /* offset 0x0658 */
+            "\x0028\x8CA1\x0029", /* offset 0x0659 */
+            "\x0028\x795D\x0029", /* offset 0x065A */
+            "\x0028\x52B4\x0029", /* offset 0x065B */
+            "\x0028\x4EE3\x0029", /* offset 0x065C */
+            "\x0028\x547C\x0029", /* offset 0x065D */
+            "\x0028\x5B66\x0029", /* offset 0x065E */
+            "\x0028\x76E3\x0029", /* offset 0x065F */
+            "\x0028\x4F01\x0029", /* offset 0x0660 */
+            "\x0028\x8CC7\x0029", /* offset 0x0661 */
+            "\x0028\x5354\x0029", /* offset 0x0662 */
+            "\x0028\x796D\x0029", /* offset 0x0663 */
+            "\x0028\x4F11\x0029", /* offset 0x0664 */
+            "\x0028\x81EA\x0029", /* offset 0x0665 */
+            "\x0028\x81F3\x0029", /* offset 0x0666 */
+            "\x0032\x0031", /* offset 0x0667 */
+            "\x0032\x0032", /* offset 0x0668 */
+            "\x0032\x0033", /* offset 0x0669 */
+            "\x0032\x0034", /* offset 0x066A */
+            "\x0032\x0035", /* offset 0x066B */
+            "\x0032\x0036", /* offset 0x066C */
+            "\x0032\x0037", /* offset 0x066D */
+            "\x0032\x0038", /* offset 0x066E */
+            "\x0032\x0039", /* offset 0x066F */
+            "\x0033\x0030", /* offset 0x0670 */
+            "\x0033\x0031", /* offset 0x0671 */
+            "\x0033\x0032", /* offset 0x0672 */
+            "\x0033\x0033", /* offset 0x0673 */
+            "\x0033\x0034", /* offset 0x0674 */
+            "\x0033\x0035", /* offset 0x0675 */
+            "\x1100\x1161", /* offset 0x0676 */
+            "\x1102\x1161", /* offset 0x0677 */
+            "\x1103\x1161", /* offset 0x0678 */
+            "\x1105\x1161", /* offset 0x0679 */
+            "\x1106\x1161", /* offset 0x067A */
+            "\x1107\x1161", /* offset 0x067B */
+            "\x1109\x1161", /* offset 0x067C */
+            "\x110B\x1161", /* offset 0x067D */
+            "\x110C\x1161", /* offset 0x067E */
+            "\x110E\x1161", /* offset 0x067F */
+            "\x110F\x1161", /* offset 0x0680 */
+            "\x1110\x1161", /* offset 0x0681 */
+            "\x1111\x1161", /* offset 0x0682 */
+            "\x1112\x1161", /* offset 0x0683 */
+            "\x4E94", /* offset 0x0684 */
+            "\x516D", /* offset 0x0685 */
+            "\x4E03", /* offset 0x0686 */
+            "\x4E5D", /* offset 0x0687 */
+            "\x682A", /* offset 0x0688 */
+            "\x6709", /* offset 0x0689 */
+            "\x793E", /* offset 0x068A */
+            "\x540D", /* offset 0x068B */
+            "\x7279", /* offset 0x068C */
+            "\x8CA1", /* offset 0x068D */
+            "\x795D", /* offset 0x068E */
+            "\x52B4", /* offset 0x068F */
+            "\x79D8", /* offset 0x0690 */
+            "\x7537", /* offset 0x0691 */
+            "\x9069", /* offset 0x0692 */
+            "\x512A", /* offset 0x0693 */
+            "\x5370", /* offset 0x0694 */
+            "\x6CE8", /* offset 0x0695 */
+            "\x9805", /* offset 0x0696 */
+            "\x4F11", /* offset 0x0697 */
+            "\x5199", /* offset 0x0698 */
+            "\x6B63", /* offset 0x0699 */
+            "\x5DE6", /* offset 0x069A */
+            "\x53F3", /* offset 0x069B */
+            "\x533B", /* offset 0x069C */
+            "\x5B97", /* offset 0x069D */
+            "\x5B66", /* offset 0x069E */
+            "\x76E3", /* offset 0x069F */
+            "\x4F01", /* offset 0x06A0 */
+            "\x8CC7", /* offset 0x06A1 */
+            "\x5354", /* offset 0x06A2 */
+            "\x591C", /* offset 0x06A3 */
+            "\x0033\x0036", /* offset 0x06A4 */
+            "\x0033\x0037", /* offset 0x06A5 */
+            "\x0033\x0038", /* offset 0x06A6 */
+            "\x0033\x0039", /* offset 0x06A7 */
+            "\x0034\x0030", /* offset 0x06A8 */
+            "\x0034\x0031", /* offset 0x06A9 */
+            "\x0034\x0032", /* offset 0x06AA */
+            "\x0034\x0033", /* offset 0x06AB */
+            "\x0034\x0034", /* offset 0x06AC */
+            "\x0034\x0035", /* offset 0x06AD */
+            "\x0034\x0036", /* offset 0x06AE */
+            "\x0034\x0037", /* offset 0x06AF */
+            "\x0034\x0038", /* offset 0x06B0 */
+            "\x0034\x0039", /* offset 0x06B1 */
+            "\x0035\x0030", /* offset 0x06B2 */
+            "\x0031\x6708", /* offset 0x06B3 */
+            "\x0032\x6708", /* offset 0x06B4 */
+            "\x0033\x6708", /* offset 0x06B5 */
+            "\x0034\x6708", /* offset 0x06B6 */
+            "\x0035\x6708", /* offset 0x06B7 */
+            "\x0036\x6708", /* offset 0x06B8 */
+            "\x0037\x6708", /* offset 0x06B9 */
+            "\x0038\x6708", /* offset 0x06BA */
+            "\x0039\x6708", /* offset 0x06BB */
+            "\x0031\x0030\x6708", /* offset 0x06BC */
+            "\x0031\x0031\x6708", /* offset 0x06BD */
+            "\x0031\x0032\x6708", /* offset 0x06BE */
+            "\x30A2", /* offset 0x06BF */
+            "\x30A4", /* offset 0x06C0 */
+            "\x30A6", /* offset 0x06C1 */
+            "\x30A8", /* offset 0x06C2 */
+            "\x30AA", /* offset 0x06C3 */
+            "\x30AB", /* offset 0x06C4 */
+            "\x30AD", /* offset 0x06C5 */
+            "\x30AF", /* offset 0x06C6 */
+            "\x30B1", /* offset 0x06C7 */
+            "\x30B3", /* offset 0x06C8 */
+            "\x30B5", /* offset 0x06C9 */
+            "\x30B7", /* offset 0x06CA */
+            "\x30B9", /* offset 0x06CB */
+            "\x30BB", /* offset 0x06CC */
+            "\x30BD", /* offset 0x06CD */
+            "\x30BF", /* offset 0x06CE */
+            "\x30C1", /* offset 0x06CF */
+            "\x30C4", /* offset 0x06D0 */
+            "\x30C6", /* offset 0x06D1 */
+            "\x30C8", /* offset 0x06D2 */
+            "\x30CA", /* offset 0x06D3 */
+            "\x30CB", /* offset 0x06D4 */
+            "\x30CC", /* offset 0x06D5 */
+            "\x30CD", /* offset 0x06D6 */
+            "\x30CE", /* offset 0x06D7 */
+            "\x30CF", /* offset 0x06D8 */
+            "\x30D2", /* offset 0x06D9 */
+            "\x30D5", /* offset 0x06DA */
+            "\x30D8", /* offset 0x06DB */
+            "\x30DB", /* offset 0x06DC */
+            "\x30DE", /* offset 0x06DD */
+            "\x30DF", /* offset 0x06DE */
+            "\x30E0", /* offset 0x06DF */
+            "\x30E1", /* offset 0x06E0 */
+            "\x30E2", /* offset 0x06E1 */
+            "\x30E4", /* offset 0x06E2 */
+            "\x30E6", /* offset 0x06E3 */
+            "\x30E8", /* offset 0x06E4 */
+            "\x30E9", /* offset 0x06E5 */
+            "\x30EA", /* offset 0x06E6 */
+            "\x30EB", /* offset 0x06E7 */
+            "\x30EC", /* offset 0x06E8 */
+            "\x30ED", /* offset 0x06E9 */
+            "\x30EF", /* offset 0x06EA */
+            "\x30F0", /* offset 0x06EB */
+            "\x30F1", /* offset 0x06EC */
+            "\x30F2", /* offset 0x06ED */
+            "\x30A2\x30CF\x309A\x30FC\x30C8", /* offset 0x06EE */
+            "\x30A2\x30EB\x30D5\x30A1", /* offset 0x06EF */
+            "\x30A2\x30F3\x30D8\x309A\x30A2", /* offset 0x06F0 */
+            "\x30A2\x30FC\x30EB", /* offset 0x06F1 */
+            "\x30A4\x30CB\x30F3\x30AF\x3099", /* offset 0x06F2 */
+            "\x30A4\x30F3\x30C1", /* offset 0x06F3 */
+            "\x30A6\x30A9\x30F3", /* offset 0x06F4 */
+            "\x30A8\x30B9\x30AF\x30FC\x30C8\x3099", /* offset 0x06F5 */
+            "\x30A8\x30FC\x30AB\x30FC", /* offset 0x06F6 */
+            "\x30AA\x30F3\x30B9", /* offset 0x06F7 */
+            "\x30AA\x30FC\x30E0", /* offset 0x06F8 */
+            "\x30AB\x30A4\x30EA", /* offset 0x06F9 */
+            "\x30AB\x30E9\x30C3\x30C8", /* offset 0x06FA */
+            "\x30AB\x30ED\x30EA\x30FC", /* offset 0x06FB */
+            "\x30AB\x3099\x30ED\x30F3", /* offset 0x06FC */
+            "\x30AB\x3099\x30F3\x30DE", /* offset 0x06FD */
+            "\x30AD\x3099\x30AB\x3099", /* offset 0x06FE */
+            "\x30AD\x3099\x30CB\x30FC", /* offset 0x06FF */
+            "\x30AD\x30E5\x30EA\x30FC", /* offset 0x0700 */
+            "\x30AD\x3099\x30EB\x30BF\x3099\x30FC", /* offset 0x0701 */
+            "\x30AD\x30ED", /* offset 0x0702 */
+            "\x30AD\x30ED\x30AF\x3099\x30E9\x30E0", /* offset 0x0703 */
+            "\x30AD\x30ED\x30E1\x30FC\x30C8\x30EB", /* offset 0x0704 */
+            "\x30AD\x30ED\x30EF\x30C3\x30C8", /* offset 0x0705 */
+            "\x30AF\x3099\x30E9\x30E0", /* offset 0x0706 */
+            "\x30AF\x3099\x30E9\x30E0\x30C8\x30F3", /* offset 0x0707 */
+            "\x30AF\x30EB\x30BB\x3099\x30A4\x30ED", /* offset 0x0708 */
+            "\x30AF\x30ED\x30FC\x30CD", /* offset 0x0709 */
+            "\x30B1\x30FC\x30B9", /* offset 0x070A */
+            "\x30B3\x30EB\x30CA", /* offset 0x070B */
+            "\x30B3\x30FC\x30DB\x309A", /* offset 0x070C */
+            "\x30B5\x30A4\x30AF\x30EB", /* offset 0x070D */
+            "\x30B5\x30F3\x30C1\x30FC\x30E0", /* offset 0x070E */
+            "\x30B7\x30EA\x30F3\x30AF\x3099", /* offset 0x070F */
+            "\x30BB\x30F3\x30C1", /* offset 0x0710 */
+            "\x30BB\x30F3\x30C8", /* offset 0x0711 */
+            "\x30BF\x3099\x30FC\x30B9", /* offset 0x0712 */
+            "\x30C6\x3099\x30B7", /* offset 0x0713 */
+            "\x30C8\x3099\x30EB", /* offset 0x0714 */
+            "\x30C8\x30F3", /* offset 0x0715 */
+            "\x30CA\x30CE", /* offset 0x0716 */
+            "\x30CE\x30C3\x30C8", /* offset 0x0717 */
+            "\x30CF\x30A4\x30C4", /* offset 0x0718 */
+            "\x30CF\x309A\x30FC\x30BB\x30F3\x30C8", /* offset 0x0719 */
+            "\x30CF\x309A\x30FC\x30C4", /* offset 0x071A */
+            "\x30CF\x3099\x30FC\x30EC\x30EB", /* offset 0x071B */
+            "\x30D2\x309A\x30A2\x30B9\x30C8\x30EB", /* offset 0x071C */
+            "\x30D2\x309A\x30AF\x30EB", /* offset 0x071D */
+            "\x30D2\x309A\x30B3", /* offset 0x071E */
+            "\x30D2\x3099\x30EB", /* offset 0x071F */
+            "\x30D5\x30A1\x30E9\x30C3\x30C8\x3099", /* offset 0x0720 */
+            "\x30D5\x30A3\x30FC\x30C8", /* offset 0x0721 */
+            "\x30D5\x3099\x30C3\x30B7\x30A7\x30EB", /* offset 0x0722 */
+            "\x30D5\x30E9\x30F3", /* offset 0x0723 */
+            "\x30D8\x30AF\x30BF\x30FC\x30EB", /* offset 0x0724 */
+            "\x30D8\x309A\x30BD", /* offset 0x0725 */
+            "\x30D8\x309A\x30CB\x30D2", /* offset 0x0726 */
+            "\x30D8\x30EB\x30C4", /* offset 0x0727 */
+            "\x30D8\x309A\x30F3\x30B9", /* offset 0x0728 */
+            "\x30D8\x309A\x30FC\x30B7\x3099", /* offset 0x0729 */
+            "\x30D8\x3099\x30FC\x30BF", /* offset 0x072A */
+            "\x30DB\x309A\x30A4\x30F3\x30C8", /* offset 0x072B */
+            "\x30DB\x3099\x30EB\x30C8", /* offset 0x072C */
+            "\x30DB\x30F3", /* offset 0x072D */
+            "\x30DB\x309A\x30F3\x30C8\x3099", /* offset 0x072E */
+            "\x30DB\x30FC\x30EB", /* offset 0x072F */
+            "\x30DB\x30FC\x30F3", /* offset 0x0730 */
+            "\x30DE\x30A4\x30AF\x30ED", /* offset 0x0731 */
+            "\x30DE\x30A4\x30EB", /* offset 0x0732 */
+            "\x30DE\x30C3\x30CF", /* offset 0x0733 */
+            "\x30DE\x30EB\x30AF", /* offset 0x0734 */
+            "\x30DE\x30F3\x30B7\x30E7\x30F3", /* offset 0x0735 */
+            "\x30DF\x30AF\x30ED\x30F3", /* offset 0x0736 */
+            "\x30DF\x30EA", /* offset 0x0737 */
+            "\x30DF\x30EA\x30CF\x3099\x30FC\x30EB", /* offset 0x0738 */
+            "\x30E1\x30AB\x3099", /* offset 0x0739 */
+            "\x30E1\x30AB\x3099\x30C8\x30F3", /* offset 0x073A */
+            "\x30E1\x30FC\x30C8\x30EB", /* offset 0x073B */
+            "\x30E4\x30FC\x30C8\x3099", /* offset 0x073C */
+            "\x30E4\x30FC\x30EB", /* offset 0x073D */
+            "\x30E6\x30A2\x30F3", /* offset 0x073E */
+            "\x30EA\x30C3\x30C8\x30EB", /* offset 0x073F */
+            "\x30EA\x30E9", /* offset 0x0740 */
+            "\x30EB\x30D2\x309A\x30FC", /* offset 0x0741 */
+            "\x30EB\x30FC\x30D5\x3099\x30EB", /* offset 0x0742 */
+            "\x30EC\x30E0", /* offset 0x0743 */
+            "\x30EC\x30F3\x30C8\x30B1\x3099\x30F3", /* offset 0x0744 */
+            "\x30EF\x30C3\x30C8", /* offset 0x0745 */
+            "\x0030\x70B9", /* offset 0x0746 */
+            "\x0031\x70B9", /* offset 0x0747 */
+            "\x0032\x70B9", /* offset 0x0748 */
+            "\x0033\x70B9", /* offset 0x0749 */
+            "\x0034\x70B9", /* offset 0x074A */
+            "\x0035\x70B9", /* offset 0x074B */
+            "\x0036\x70B9", /* offset 0x074C */
+            "\x0037\x70B9", /* offset 0x074D */
+            "\x0038\x70B9", /* offset 0x074E */
+            "\x0039\x70B9", /* offset 0x074F */
+            "\x0031\x0030\x70B9", /* offset 0x0750 */
+            "\x0031\x0031\x70B9", /* offset 0x0751 */
+            "\x0031\x0032\x70B9", /* offset 0x0752 */
+            "\x0031\x0033\x70B9", /* offset 0x0753 */
+            "\x0031\x0034\x70B9", /* offset 0x0754 */
+            "\x0031\x0035\x70B9", /* offset 0x0755 */
+            "\x0031\x0036\x70B9", /* offset 0x0756 */
+            "\x0031\x0037\x70B9", /* offset 0x0757 */
+            "\x0031\x0038\x70B9", /* offset 0x0758 */
+            "\x0031\x0039\x70B9", /* offset 0x0759 */
+            "\x0032\x0030\x70B9", /* offset 0x075A */
+            "\x0032\x0031\x70B9", /* offset 0x075B */
+            "\x0032\x0032\x70B9", /* offset 0x075C */
+            "\x0032\x0033\x70B9", /* offset 0x075D */
+            "\x0032\x0034\x70B9", /* offset 0x075E */
+            "\x0068\x0050\x0061", /* offset 0x075F */
+            "\x0064\x0061", /* offset 0x0760 */
+            "\x0041\x0055", /* offset 0x0761 */
+            "\x0062\x0061\x0072", /* offset 0x0762 */
+            "\x006F\x0056", /* offset 0x0763 */
+            "\x0070\x0063", /* offset 0x0764 */
+            "\x5E73\x6210", /* offset 0x0765 */
+            "\x662D\x548C", /* offset 0x0766 */
+            "\x5927\x6B63", /* offset 0x0767 */
+            "\x660E\x6CBB", /* offset 0x0768 */
+            "\x682A\x5F0F\x4F1A\x793E", /* offset 0x0769 */
+            "\x0070\x0041", /* offset 0x076A */
+            "\x006E\x0041", /* offset 0x076B */
+            "\x03BC\x0041", /* offset 0x076C */
+            "\x006D\x0041", /* offset 0x076D */
+            "\x006B\x0041", /* offset 0x076E */
+            "\x004B\x0042", /* offset 0x076F */
+            "\x004D\x0042", /* offset 0x0770 */
+            "\x0047\x0042", /* offset 0x0771 */
+            "\x0063\x0061\x006C", /* offset 0x0772 */
+            "\x006B\x0063\x0061\x006C", /* offset 0x0773 */
+            "\x0070\x0046", /* offset 0x0774 */
+            "\x006E\x0046", /* offset 0x0775 */
+            "\x03BC\x0046", /* offset 0x0776 */
+            "\x03BC\x0067", /* offset 0x0777 */
+            "\x006D\x0067", /* offset 0x0778 */
+            "\x006B\x0067", /* offset 0x0779 */
+            "\x0048\x007A", /* offset 0x077A */
+            "\x006B\x0048\x007A", /* offset 0x077B */
+            "\x004D\x0048\x007A", /* offset 0x077C */
+            "\x0047\x0048\x007A", /* offset 0x077D */
+            "\x0054\x0048\x007A", /* offset 0x077E */
+            "\x03BC\x006C", /* offset 0x077F */
+            "\x006D\x006C", /* offset 0x0780 */
+            "\x0064\x006C", /* offset 0x0781 */
+            "\x006B\x006C", /* offset 0x0782 */
+            "\x0066\x006D", /* offset 0x0783 */
+            "\x006E\x006D", /* offset 0x0784 */
+            "\x03BC\x006D", /* offset 0x0785 */
+            "\x006D\x006D", /* offset 0x0786 */
+            "\x0063\x006D", /* offset 0x0787 */
+            "\x006B\x006D", /* offset 0x0788 */
+            "\x006D\x006D\x0032", /* offset 0x0789 */
+            "\x0063\x006D\x0032", /* offset 0x078A */
+            "\x006D\x0032", /* offset 0x078B */
+            "\x006B\x006D\x0032", /* offset 0x078C */
+            "\x006D\x006D\x0033", /* offset 0x078D */
+            "\x0063\x006D\x0033", /* offset 0x078E */
+            "\x006D\x0033", /* offset 0x078F */
+            "\x006B\x006D\x0033", /* offset 0x0790 */
+            "\x006D\x2215\x0073", /* offset 0x0791 */
+            "\x006D\x2215\x0073\x0032", /* offset 0x0792 */
+            "\x0050\x0061", /* offset 0x0793 */
+            "\x006B\x0050\x0061", /* offset 0x0794 */
+            "\x004D\x0050\x0061", /* offset 0x0795 */
+            "\x0047\x0050\x0061", /* offset 0x0796 */
+            "\x0072\x0061\x0064", /* offset 0x0797 */
+            "\x0072\x0061\x0064\x2215\x0073", /* offset 0x0798 */
+            "\x0072\x0061\x0064\x2215\x0073\x0032", /* offset 0x0799 */
+            "\x0070\x0073", /* offset 0x079A */
+            "\x006E\x0073", /* offset 0x079B */
+            "\x03BC\x0073", /* offset 0x079C */
+            "\x006D\x0073", /* offset 0x079D */
+            "\x0070\x0056", /* offset 0x079E */
+            "\x006E\x0056", /* offset 0x079F */
+            "\x03BC\x0056", /* offset 0x07A0 */
+            "\x006D\x0056", /* offset 0x07A1 */
+            "\x006B\x0056", /* offset 0x07A2 */
+            "\x004D\x0056", /* offset 0x07A3 */
+            "\x0070\x0057", /* offset 0x07A4 */
+            "\x006E\x0057", /* offset 0x07A5 */
+            "\x03BC\x0057", /* offset 0x07A6 */
+            "\x006D\x0057", /* offset 0x07A7 */
+            "\x006B\x0057", /* offset 0x07A8 */
+            "\x004D\x0057", /* offset 0x07A9 */
+            "\x006B\x03A9", /* offset 0x07AA */
+            "\x004D\x03A9", /* offset 0x07AB */
+            "\x0061\x002E\x006D\x002E", /* offset 0x07AC */
+            "\x0042\x0071", /* offset 0x07AD */
+            "\x0063\x0063", /* offset 0x07AE */
+            "\x0063\x0064", /* offset 0x07AF */
+            "\x0043\x2215\x006B\x0067", /* offset 0x07B0 */
+            "\x0043\x006F\x002E", /* offset 0x07B1 */
+            "\x0064\x0042", /* offset 0x07B2 */
+            "\x0047\x0079", /* offset 0x07B3 */
+            "\x0068\x0061", /* offset 0x07B4 */
+            "\x0048\x0050", /* offset 0x07B5 */
+            "\x0069\x006E", /* offset 0x07B6 */
+            "\x004B\x004B", /* offset 0x07B7 */
+            "\x004B\x004D", /* offset 0x07B8 */
+            "\x006B\x0074", /* offset 0x07B9 */
+            "\x006C\x006D", /* offset 0x07BA */
+            "\x006C\x006E", /* offset 0x07BB */
+            "\x006C\x006F\x0067", /* offset 0x07BC */
+            "\x006C\x0078", /* offset 0x07BD */
+            "\x006D\x0062", /* offset 0x07BE */
+            "\x006D\x0069\x006C", /* offset 0x07BF */
+            "\x006D\x006F\x006C", /* offset 0x07C0 */
+            "\x0050\x0048", /* offset 0x07C1 */
+            "\x0070\x002E\x006D\x002E", /* offset 0x07C2 */
+            "\x0050\x0050\x004D", /* offset 0x07C3 */
+            "\x0050\x0052", /* offset 0x07C4 */
+            "\x0073\x0072", /* offset 0x07C5 */
+            "\x0053\x0076", /* offset 0x07C6 */
+            "\x0057\x0062", /* offset 0x07C7 */
+            "\x0031\x65E5", /* offset 0x07C8 */
+            "\x0032\x65E5", /* offset 0x07C9 */
+            "\x0033\x65E5", /* offset 0x07CA */
+            "\x0034\x65E5", /* offset 0x07CB */
+            "\x0035\x65E5", /* offset 0x07CC */
+            "\x0036\x65E5", /* offset 0x07CD */
+            "\x0037\x65E5", /* offset 0x07CE */
+            "\x0038\x65E5", /* offset 0x07CF */
+            "\x0039\x65E5", /* offset 0x07D0 */
+            "\x0031\x0030\x65E5", /* offset 0x07D1 */
+            "\x0031\x0031\x65E5", /* offset 0x07D2 */
+            "\x0031\x0032\x65E5", /* offset 0x07D3 */
+            "\x0031\x0033\x65E5", /* offset 0x07D4 */
+            "\x0031\x0034\x65E5", /* offset 0x07D5 */
+            "\x0031\x0035\x65E5", /* offset 0x07D6 */
+            "\x0031\x0036\x65E5", /* offset 0x07D7 */
+            "\x0031\x0037\x65E5", /* offset 0x07D8 */
+            "\x0031\x0038\x65E5", /* offset 0x07D9 */
+            "\x0031\x0039\x65E5", /* offset 0x07DA */
+            "\x0032\x0030\x65E5", /* offset 0x07DB */
+            "\x0032\x0031\x65E5", /* offset 0x07DC */
+            "\x0032\x0032\x65E5", /* offset 0x07DD */
+            "\x0032\x0033\x65E5", /* offset 0x07DE */
+            "\x0032\x0034\x65E5", /* offset 0x07DF */
+            "\x0032\x0035\x65E5", /* offset 0x07E0 */
+            "\x0032\x0036\x65E5", /* offset 0x07E1 */
+            "\x0032\x0037\x65E5", /* offset 0x07E2 */
+            "\x0032\x0038\x65E5", /* offset 0x07E3 */
+            "\x0032\x0039\x65E5", /* offset 0x07E4 */
+            "\x0033\x0030\x65E5", /* offset 0x07E5 */
+            "\x0033\x0031\x65E5", /* offset 0x07E6 */
+            "\x8C48", /* offset 0x07E7 */
+            "\x66F4", /* offset 0x07E8 */
+            "\x8CC8", /* offset 0x07E9 */
+            "\x6ED1", /* offset 0x07EA */
+            "\x4E32", /* offset 0x07EB */
+            "\x53E5", /* offset 0x07EC */
+            "\x5951", /* offset 0x07ED */
+            "\x5587", /* offset 0x07EE */
+            "\x5948", /* offset 0x07EF */
+            "\x61F6", /* offset 0x07F0 */
+            "\x7669", /* offset 0x07F1 */
+            "\x7F85", /* offset 0x07F2 */
+            "\x863F", /* offset 0x07F3 */
+            "\x87BA", /* offset 0x07F4 */
+            "\x88F8", /* offset 0x07F5 */
+            "\x908F", /* offset 0x07F6 */
+            "\x6A02", /* offset 0x07F7 */
+            "\x6D1B", /* offset 0x07F8 */
+            "\x70D9", /* offset 0x07F9 */
+            "\x73DE", /* offset 0x07FA */
+            "\x843D", /* offset 0x07FB */
+            "\x916A", /* offset 0x07FC */
+            "\x99F1", /* offset 0x07FD */
+            "\x4E82", /* offset 0x07FE */
+            "\x5375", /* offset 0x07FF */
+            "\x6B04", /* offset 0x0800 */
+            "\x721B", /* offset 0x0801 */
+            "\x862D", /* offset 0x0802 */
+            "\x9E1E", /* offset 0x0803 */
+            "\x5D50", /* offset 0x0804 */
+            "\x6FEB", /* offset 0x0805 */
+            "\x85CD", /* offset 0x0806 */
+            "\x8964", /* offset 0x0807 */
+            "\x62C9", /* offset 0x0808 */
+            "\x81D8", /* offset 0x0809 */
+            "\x881F", /* offset 0x080A */
+            "\x5ECA", /* offset 0x080B */
+            "\x6717", /* offset 0x080C */
+            "\x6D6A", /* offset 0x080D */
+            "\x72FC", /* offset 0x080E */
+            "\x90CE", /* offset 0x080F */
+            "\x4F86", /* offset 0x0810 */
+            "\x51B7", /* offset 0x0811 */
+            "\x52DE", /* offset 0x0812 */
+            "\x64C4", /* offset 0x0813 */
+            "\x6AD3", /* offset 0x0814 */
+            "\x7210", /* offset 0x0815 */
+            "\x76E7", /* offset 0x0816 */
+            "\x8606", /* offset 0x0817 */
+            "\x865C", /* offset 0x0818 */
+            "\x8DEF", /* offset 0x0819 */
+            "\x9732", /* offset 0x081A */
+            "\x9B6F", /* offset 0x081B */
+            "\x9DFA", /* offset 0x081C */
+            "\x788C", /* offset 0x081D */
+            "\x797F", /* offset 0x081E */
+            "\x7DA0", /* offset 0x081F */
+            "\x83C9", /* offset 0x0820 */
+            "\x9304", /* offset 0x0821 */
+            "\x8AD6", /* offset 0x0822 */
+            "\x58DF", /* offset 0x0823 */
+            "\x5F04", /* offset 0x0824 */
+            "\x7C60", /* offset 0x0825 */
+            "\x807E", /* offset 0x0826 */
+            "\x7262", /* offset 0x0827 */
+            "\x78CA", /* offset 0x0828 */
+            "\x8CC2", /* offset 0x0829 */
+            "\x96F7", /* offset 0x082A */
+            "\x58D8", /* offset 0x082B */
+            "\x5C62", /* offset 0x082C */
+            "\x6A13", /* offset 0x082D */
+            "\x6DDA", /* offset 0x082E */
+            "\x6F0F", /* offset 0x082F */
+            "\x7D2F", /* offset 0x0830 */
+            "\x7E37", /* offset 0x0831 */
+            "\x964B", /* offset 0x0832 */
+            "\x52D2", /* offset 0x0833 */
+            "\x808B", /* offset 0x0834 */
+            "\x51DC", /* offset 0x0835 */
+            "\x51CC", /* offset 0x0836 */
+            "\x7A1C", /* offset 0x0837 */
+            "\x7DBE", /* offset 0x0838 */
+            "\x83F1", /* offset 0x0839 */
+            "\x9675", /* offset 0x083A */
+            "\x8B80", /* offset 0x083B */
+            "\x62CF", /* offset 0x083C */
+            "\x8AFE", /* offset 0x083D */
+            "\x4E39", /* offset 0x083E */
+            "\x5BE7", /* offset 0x083F */
+            "\x6012", /* offset 0x0840 */
+            "\x7387", /* offset 0x0841 */
+            "\x7570", /* offset 0x0842 */
+            "\x5317", /* offset 0x0843 */
+            "\x78FB", /* offset 0x0844 */
+            "\x4FBF", /* offset 0x0845 */
+            "\x5FA9", /* offset 0x0846 */
+            "\x4E0D", /* offset 0x0847 */
+            "\x6CCC", /* offset 0x0848 */
+            "\x6578", /* offset 0x0849 */
+            "\x7D22", /* offset 0x084A */
+            "\x53C3", /* offset 0x084B */
+            "\x585E", /* offset 0x084C */
+            "\x7701", /* offset 0x084D */
+            "\x8449", /* offset 0x084E */
+            "\x8AAA", /* offset 0x084F */
+            "\x6BBA", /* offset 0x0850 */
+            "\x6C88", /* offset 0x0851 */
+            "\x62FE", /* offset 0x0852 */
+            "\x82E5", /* offset 0x0853 */
+            "\x63A0", /* offset 0x0854 */
+            "\x7565", /* offset 0x0855 */
+            "\x4EAE", /* offset 0x0856 */
+            "\x5169", /* offset 0x0857 */
+            "\x51C9", /* offset 0x0858 */
+            "\x6881", /* offset 0x0859 */
+            "\x7CE7", /* offset 0x085A */
+            "\x826F", /* offset 0x085B */
+            "\x8AD2", /* offset 0x085C */
+            "\x91CF", /* offset 0x085D */
+            "\x52F5", /* offset 0x085E */
+            "\x5442", /* offset 0x085F */
+            "\x5EEC", /* offset 0x0860 */
+            "\x65C5", /* offset 0x0861 */
+            "\x6FFE", /* offset 0x0862 */
+            "\x792A", /* offset 0x0863 */
+            "\x95AD", /* offset 0x0864 */
+            "\x9A6A", /* offset 0x0865 */
+            "\x9E97", /* offset 0x0866 */
+            "\x9ECE", /* offset 0x0867 */
+            "\x66C6", /* offset 0x0868 */
+            "\x6B77", /* offset 0x0869 */
+            "\x8F62", /* offset 0x086A */
+            "\x5E74", /* offset 0x086B */
+            "\x6190", /* offset 0x086C */
+            "\x6200", /* offset 0x086D */
+            "\x649A", /* offset 0x086E */
+            "\x6F23", /* offset 0x086F */
+            "\x7149", /* offset 0x0870 */
+            "\x7489", /* offset 0x0871 */
+            "\x79CA", /* offset 0x0872 */
+            "\x7DF4", /* offset 0x0873 */
+            "\x806F", /* offset 0x0874 */
+            "\x8F26", /* offset 0x0875 */
+            "\x84EE", /* offset 0x0876 */
+            "\x9023", /* offset 0x0877 */
+            "\x934A", /* offset 0x0878 */
+            "\x5217", /* offset 0x0879 */
+            "\x52A3", /* offset 0x087A */
+            "\x54BD", /* offset 0x087B */
+            "\x70C8", /* offset 0x087C */
+            "\x88C2", /* offset 0x087D */
+            "\x5EC9", /* offset 0x087E */
+            "\x5FF5", /* offset 0x087F */
+            "\x637B", /* offset 0x0880 */
+            "\x6BAE", /* offset 0x0881 */
+            "\x7C3E", /* offset 0x0882 */
+            "\x7375", /* offset 0x0883 */
+            "\x4EE4", /* offset 0x0884 */
+            "\x56F9", /* offset 0x0885 */
+            "\x5DBA", /* offset 0x0886 */
+            "\x601C", /* offset 0x0887 */
+            "\x73B2", /* offset 0x0888 */
+            "\x7469", /* offset 0x0889 */
+            "\x7F9A", /* offset 0x088A */
+            "\x8046", /* offset 0x088B */
+            "\x9234", /* offset 0x088C */
+            "\x96F6", /* offset 0x088D */
+            "\x9748", /* offset 0x088E */
+            "\x9818", /* offset 0x088F */
+            "\x4F8B", /* offset 0x0890 */
+            "\x79AE", /* offset 0x0891 */
+            "\x91B4", /* offset 0x0892 */
+            "\x96B8", /* offset 0x0893 */
+            "\x60E1", /* offset 0x0894 */
+            "\x4E86", /* offset 0x0895 */
+            "\x50DA", /* offset 0x0896 */
+            "\x5BEE", /* offset 0x0897 */
+            "\x5C3F", /* offset 0x0898 */
+            "\x6599", /* offset 0x0899 */
+            "\x71CE", /* offset 0x089A */
+            "\x7642", /* offset 0x089B */
+            "\x84FC", /* offset 0x089C */
+            "\x907C", /* offset 0x089D */
+            "\x6688", /* offset 0x089E */
+            "\x962E", /* offset 0x089F */
+            "\x5289", /* offset 0x08A0 */
+            "\x677B", /* offset 0x08A1 */
+            "\x67F3", /* offset 0x08A2 */
+            "\x6D41", /* offset 0x08A3 */
+            "\x6E9C", /* offset 0x08A4 */
+            "\x7409", /* offset 0x08A5 */
+            "\x7559", /* offset 0x08A6 */
+            "\x786B", /* offset 0x08A7 */
+            "\x7D10", /* offset 0x08A8 */
+            "\x985E", /* offset 0x08A9 */
+            "\x622E", /* offset 0x08AA */
+            "\x9678", /* offset 0x08AB */
+            "\x502B", /* offset 0x08AC */
+            "\x5D19", /* offset 0x08AD */
+            "\x6DEA", /* offset 0x08AE */
+            "\x8F2A", /* offset 0x08AF */
+            "\x5F8B", /* offset 0x08B0 */
+            "\x6144", /* offset 0x08B1 */
+            "\x6817", /* offset 0x08B2 */
+            "\x9686", /* offset 0x08B3 */
+            "\x5229", /* offset 0x08B4 */
+            "\x540F", /* offset 0x08B5 */
+            "\x5C65", /* offset 0x08B6 */
+            "\x6613", /* offset 0x08B7 */
+            "\x674E", /* offset 0x08B8 */
+            "\x68A8", /* offset 0x08B9 */
+            "\x6CE5", /* offset 0x08BA */
+            "\x7406", /* offset 0x08BB */
+            "\x75E2", /* offset 0x08BC */
+            "\x7F79", /* offset 0x08BD */
+            "\x88CF", /* offset 0x08BE */
+            "\x88E1", /* offset 0x08BF */
+            "\x96E2", /* offset 0x08C0 */
+            "\x533F", /* offset 0x08C1 */
+            "\x6EBA", /* offset 0x08C2 */
+            "\x541D", /* offset 0x08C3 */
+            "\x71D0", /* offset 0x08C4 */
+            "\x7498", /* offset 0x08C5 */
+            "\x85FA", /* offset 0x08C6 */
+            "\x96A3", /* offset 0x08C7 */
+            "\x9C57", /* offset 0x08C8 */
+            "\x9E9F", /* offset 0x08C9 */
+            "\x6797", /* offset 0x08CA */
+            "\x6DCB", /* offset 0x08CB */
+            "\x81E8", /* offset 0x08CC */
+            "\x7B20", /* offset 0x08CD */
+            "\x7C92", /* offset 0x08CE */
+            "\x72C0", /* offset 0x08CF */
+            "\x7099", /* offset 0x08D0 */
+            "\x8B58", /* offset 0x08D1 */
+            "\x4EC0", /* offset 0x08D2 */
+            "\x8336", /* offset 0x08D3 */
+            "\x523A", /* offset 0x08D4 */
+            "\x5207", /* offset 0x08D5 */
+            "\x5EA6", /* offset 0x08D6 */
+            "\x62D3", /* offset 0x08D7 */
+            "\x7CD6", /* offset 0x08D8 */
+            "\x5B85", /* offset 0x08D9 */
+            "\x6D1E", /* offset 0x08DA */
+            "\x66B4", /* offset 0x08DB */
+            "\x8F3B", /* offset 0x08DC */
+            "\x964D", /* offset 0x08DD */
+            "\x5ED3", /* offset 0x08DE */
+            "\x5140", /* offset 0x08DF */
+            "\x55C0", /* offset 0x08E0 */
+            "\x585A", /* offset 0x08E1 */
+            "\x6674", /* offset 0x08E2 */
+            "\x51DE", /* offset 0x08E3 */
+            "\x732A", /* offset 0x08E4 */
+            "\x76CA", /* offset 0x08E5 */
+            "\x793C", /* offset 0x08E6 */
+            "\x795E", /* offset 0x08E7 */
+            "\x7965", /* offset 0x08E8 */
+            "\x798F", /* offset 0x08E9 */
+            "\x9756", /* offset 0x08EA */
+            "\x7CBE", /* offset 0x08EB */
+            "\x8612", /* offset 0x08EC */
+            "\x8AF8", /* offset 0x08ED */
+            "\x9038", /* offset 0x08EE */
+            "\x90FD", /* offset 0x08EF */
+            "\x98EF", /* offset 0x08F0 */
+            "\x98FC", /* offset 0x08F1 */
+            "\x9928", /* offset 0x08F2 */
+            "\x9DB4", /* offset 0x08F3 */
+            "\x4FAE", /* offset 0x08F4 */
+            "\x50E7", /* offset 0x08F5 */
+            "\x514D", /* offset 0x08F6 */
+            "\x52C9", /* offset 0x08F7 */
+            "\x52E4", /* offset 0x08F8 */
+            "\x5351", /* offset 0x08F9 */
+            "\x559D", /* offset 0x08FA */
+            "\x5606", /* offset 0x08FB */
+            "\x5668", /* offset 0x08FC */
+            "\x5840", /* offset 0x08FD */
+            "\x58A8", /* offset 0x08FE */
+            "\x5C64", /* offset 0x08FF */
+            "\x6094", /* offset 0x0900 */
+            "\x6168", /* offset 0x0901 */
+            "\x618E", /* offset 0x0902 */
+            "\x61F2", /* offset 0x0903 */
+            "\x654F", /* offset 0x0904 */
+            "\x65E2", /* offset 0x0905 */
+            "\x6691", /* offset 0x0906 */
+            "\x6885", /* offset 0x0907 */
+            "\x6D77", /* offset 0x0908 */
+            "\x6E1A", /* offset 0x0909 */
+            "\x6F22", /* offset 0x090A */
+            "\x716E", /* offset 0x090B */
+            "\x722B", /* offset 0x090C */
+            "\x7422", /* offset 0x090D */
+            "\x7891", /* offset 0x090E */
+            "\x7949", /* offset 0x090F */
+            "\x7948", /* offset 0x0910 */
+            "\x7950", /* offset 0x0911 */
+            "\x7956", /* offset 0x0912 */
+            "\x798D", /* offset 0x0913 */
+            "\x798E", /* offset 0x0914 */
+            "\x7A40", /* offset 0x0915 */
+            "\x7A81", /* offset 0x0916 */
+            "\x7BC0", /* offset 0x0917 */
+            "\x7E09", /* offset 0x0918 */
+            "\x7E41", /* offset 0x0919 */
+            "\x7F72", /* offset 0x091A */
+            "\x8005", /* offset 0x091B */
+            "\x81ED", /* offset 0x091C */
+            "\x8279", /* offset 0x091D */
+            "\x8457", /* offset 0x091E */
+            "\x8910", /* offset 0x091F */
+            "\x8996", /* offset 0x0920 */
+            "\x8B01", /* offset 0x0921 */
+            "\x8B39", /* offset 0x0922 */
+            "\x8CD3", /* offset 0x0923 */
+            "\x8D08", /* offset 0x0924 */
+            "\x8FB6", /* offset 0x0925 */
+            "\x96E3", /* offset 0x0926 */
+            "\x97FF", /* offset 0x0927 */
+            "\x983B", /* offset 0x0928 */
+            "\x0066\x0066", /* offset 0x0929 */
+            "\x0066\x0069", /* offset 0x092A */
+            "\x0066\x006C", /* offset 0x092B */
+            "\x0066\x0066\x0069", /* offset 0x092C */
+            "\x0066\x0066\x006C", /* offset 0x092D */
+            "\x0073\x0074", /* offset 0x092E */
+            "\x0574\x0576", /* offset 0x092F */
+            "\x0574\x0565", /* offset 0x0930 */
+            "\x0574\x056B", /* offset 0x0931 */
+            "\x057E\x0576", /* offset 0x0932 */
+            "\x0574\x056D", /* offset 0x0933 */
+            "\x05D9\x05B4", /* offset 0x0934 */
+            "\x05F2\x05B7", /* offset 0x0935 */
+            "\x05E2", /* offset 0x0936 */
+            "\x05D4", /* offset 0x0937 */
+            "\x05DB", /* offset 0x0938 */
+            "\x05DC", /* offset 0x0939 */
+            "\x05DD", /* offset 0x093A */
+            "\x05E8", /* offset 0x093B */
+            "\x05EA", /* offset 0x093C */
+            "\x05E9\x05C1", /* offset 0x093D */
+            "\x05E9\x05C2", /* offset 0x093E */
+            "\x05E9\x05BC\x05C1", /* offset 0x093F */
+            "\x05E9\x05BC\x05C2", /* offset 0x0940 */
+            "\x05D0\x05B7", /* offset 0x0941 */
+            "\x05D0\x05B8", /* offset 0x0942 */
+            "\x05D0\x05BC", /* offset 0x0943 */
+            "\x05D1\x05BC", /* offset 0x0944 */
+            "\x05D2\x05BC", /* offset 0x0945 */
+            "\x05D3\x05BC", /* offset 0x0946 */
+            "\x05D4\x05BC", /* offset 0x0947 */
+            "\x05D5\x05BC", /* offset 0x0948 */
+            "\x05D6\x05BC", /* offset 0x0949 */
+            "\x05D8\x05BC", /* offset 0x094A */
+            "\x05D9\x05BC", /* offset 0x094B */
+            "\x05DA\x05BC", /* offset 0x094C */
+            "\x05DB\x05BC", /* offset 0x094D */
+            "\x05DC\x05BC", /* offset 0x094E */
+            "\x05DE\x05BC", /* offset 0x094F */
+            "\x05E0\x05BC", /* offset 0x0950 */
+            "\x05E1\x05BC", /* offset 0x0951 */
+            "\x05E3\x05BC", /* offset 0x0952 */
+            "\x05E4\x05BC", /* offset 0x0953 */
+            "\x05E6\x05BC", /* offset 0x0954 */
+            "\x05E7\x05BC", /* offset 0x0955 */
+            "\x05E8\x05BC", /* offset 0x0956 */
+            "\x05E9\x05BC", /* offset 0x0957 */
+            "\x05EA\x05BC", /* offset 0x0958 */
+            "\x05D5\x05B9", /* offset 0x0959 */
+            "\x05D1\x05BF", /* offset 0x095A */
+            "\x05DB\x05BF", /* offset 0x095B */
+            "\x05E4\x05BF", /* offset 0x095C */
+            "\x05D0\x05DC", /* offset 0x095D */
+            "\x0671", /* offset 0x095E */
+            "\x067B", /* offset 0x095F */
+            "\x067E", /* offset 0x0960 */
+            "\x0680", /* offset 0x0961 */
+            "\x067A", /* offset 0x0962 */
+            "\x067F", /* offset 0x0963 */
+            "\x0679", /* offset 0x0964 */
+            "\x06A4", /* offset 0x0965 */
+            "\x06A6", /* offset 0x0966 */
+            "\x0684", /* offset 0x0967 */
+            "\x0683", /* offset 0x0968 */
+            "\x0686", /* offset 0x0969 */
+            "\x0687", /* offset 0x096A */
+            "\x068D", /* offset 0x096B */
+            "\x068C", /* offset 0x096C */
+            "\x068E", /* offset 0x096D */
+            "\x0688", /* offset 0x096E */
+            "\x0698", /* offset 0x096F */
+            "\x0691", /* offset 0x0970 */
+            "\x06A9", /* offset 0x0971 */
+            "\x06AF", /* offset 0x0972 */
+            "\x06B3", /* offset 0x0973 */
+            "\x06B1", /* offset 0x0974 */
+            "\x06BA", /* offset 0x0975 */
+            "\x06BB", /* offset 0x0976 */
+            "\x06C1", /* offset 0x0977 */
+            "\x06BE", /* offset 0x0978 */
+            "\x06D2", /* offset 0x0979 */
+            "\x06AD", /* offset 0x097A */
+            "\x06C7", /* offset 0x097B */
+            "\x06C6", /* offset 0x097C */
+            "\x06C8", /* offset 0x097D */
+            "\x06CB", /* offset 0x097E */
+            "\x06C5", /* offset 0x097F */
+            "\x06C9", /* offset 0x0980 */
+            "\x06D0", /* offset 0x0981 */
+            "\x0649", /* offset 0x0982 */
+            "\x064A\x0654\x0627", /* offset 0x0983 */
+            "\x064A\x0654\x06D5", /* offset 0x0984 */
+            "\x064A\x0654\x0648", /* offset 0x0985 */
+            "\x064A\x0654\x06C7", /* offset 0x0986 */
+            "\x064A\x0654\x06C6", /* offset 0x0987 */
+            "\x064A\x0654\x06C8", /* offset 0x0988 */
+            "\x064A\x0654\x06D0", /* offset 0x0989 */
+            "\x064A\x0654\x0649", /* offset 0x098A */
+            "\x06CC", /* offset 0x098B */
+            "\x064A\x0654\x062C", /* offset 0x098C */
+            "\x064A\x0654\x062D", /* offset 0x098D */
+            "\x064A\x0654\x0645", /* offset 0x098E */
+            "\x064A\x0654\x064A", /* offset 0x098F */
+            "\x0628\x062C", /* offset 0x0990 */
+            "\x0628\x062D", /* offset 0x0991 */
+            "\x0628\x062E", /* offset 0x0992 */
+            "\x0628\x0645", /* offset 0x0993 */
+            "\x0628\x0649", /* offset 0x0994 */
+            "\x0628\x064A", /* offset 0x0995 */
+            "\x062A\x062C", /* offset 0x0996 */
+            "\x062A\x062D", /* offset 0x0997 */
+            "\x062A\x062E", /* offset 0x0998 */
+            "\x062A\x0645", /* offset 0x0999 */
+            "\x062A\x0649", /* offset 0x099A */
+            "\x062A\x064A", /* offset 0x099B */
+            "\x062B\x062C", /* offset 0x099C */
+            "\x062B\x0645", /* offset 0x099D */
+            "\x062B\x0649", /* offset 0x099E */
+            "\x062B\x064A", /* offset 0x099F */
+            "\x062C\x062D", /* offset 0x09A0 */
+            "\x062C\x0645", /* offset 0x09A1 */
+            "\x062D\x062C", /* offset 0x09A2 */
+            "\x062D\x0645", /* offset 0x09A3 */
+            "\x062E\x062C", /* offset 0x09A4 */
+            "\x062E\x062D", /* offset 0x09A5 */
+            "\x062E\x0645", /* offset 0x09A6 */
+            "\x0633\x062C", /* offset 0x09A7 */
+            "\x0633\x062D", /* offset 0x09A8 */
+            "\x0633\x062E", /* offset 0x09A9 */
+            "\x0633\x0645", /* offset 0x09AA */
+            "\x0635\x062D", /* offset 0x09AB */
+            "\x0635\x0645", /* offset 0x09AC */
+            "\x0636\x062C", /* offset 0x09AD */
+            "\x0636\x062D", /* offset 0x09AE */
+            "\x0636\x062E", /* offset 0x09AF */
+            "\x0636\x0645", /* offset 0x09B0 */
+            "\x0637\x062D", /* offset 0x09B1 */
+            "\x0637\x0645", /* offset 0x09B2 */
+            "\x0638\x0645", /* offset 0x09B3 */
+            "\x0639\x062C", /* offset 0x09B4 */
+            "\x0639\x0645", /* offset 0x09B5 */
+            "\x063A\x062C", /* offset 0x09B6 */
+            "\x063A\x0645", /* offset 0x09B7 */
+            "\x0641\x062C", /* offset 0x09B8 */
+            "\x0641\x062D", /* offset 0x09B9 */
+            "\x0641\x062E", /* offset 0x09BA */
+            "\x0641\x0645", /* offset 0x09BB */
+            "\x0641\x0649", /* offset 0x09BC */
+            "\x0641\x064A", /* offset 0x09BD */
+            "\x0642\x062D", /* offset 0x09BE */
+            "\x0642\x0645", /* offset 0x09BF */
+            "\x0642\x0649", /* offset 0x09C0 */
+            "\x0642\x064A", /* offset 0x09C1 */
+            "\x0643\x0627", /* offset 0x09C2 */
+            "\x0643\x062C", /* offset 0x09C3 */
+            "\x0643\x062D", /* offset 0x09C4 */
+            "\x0643\x062E", /* offset 0x09C5 */
+            "\x0643\x0644", /* offset 0x09C6 */
+            "\x0643\x0645", /* offset 0x09C7 */
+            "\x0643\x0649", /* offset 0x09C8 */
+            "\x0643\x064A", /* offset 0x09C9 */
+            "\x0644\x062C", /* offset 0x09CA */
+            "\x0644\x062D", /* offset 0x09CB */
+            "\x0644\x062E", /* offset 0x09CC */
+            "\x0644\x0645", /* offset 0x09CD */
+            "\x0644\x0649", /* offset 0x09CE */
+            "\x0644\x064A", /* offset 0x09CF */
+            "\x0645\x062C", /* offset 0x09D0 */
+            "\x0645\x062D", /* offset 0x09D1 */
+            "\x0645\x062E", /* offset 0x09D2 */
+            "\x0645\x0645", /* offset 0x09D3 */
+            "\x0645\x0649", /* offset 0x09D4 */
+            "\x0645\x064A", /* offset 0x09D5 */
+            "\x0646\x062C", /* offset 0x09D6 */
+            "\x0646\x062D", /* offset 0x09D7 */
+            "\x0646\x062E", /* offset 0x09D8 */
+            "\x0646\x0645", /* offset 0x09D9 */
+            "\x0646\x0649", /* offset 0x09DA */
+            "\x0646\x064A", /* offset 0x09DB */
+            "\x0647\x062C", /* offset 0x09DC */
+            "\x0647\x0645", /* offset 0x09DD */
+            "\x0647\x0649", /* offset 0x09DE */
+            "\x0647\x064A", /* offset 0x09DF */
+            "\x064A\x062C", /* offset 0x09E0 */
+            "\x064A\x062D", /* offset 0x09E1 */
+            "\x064A\x062E", /* offset 0x09E2 */
+            "\x064A\x0645", /* offset 0x09E3 */
+            "\x064A\x0649", /* offset 0x09E4 */
+            "\x064A\x064A", /* offset 0x09E5 */
+            "\x0630\x0670", /* offset 0x09E6 */
+            "\x0631\x0670", /* offset 0x09E7 */
+            "\x0649\x0670", /* offset 0x09E8 */
+            "\x0020\x064C\x0651", /* offset 0x09E9 */
+            "\x0020\x064D\x0651", /* offset 0x09EA */
+            "\x0020\x064E\x0651", /* offset 0x09EB */
+            "\x0020\x064F\x0651", /* offset 0x09EC */
+            "\x0020\x0650\x0651", /* offset 0x09ED */
+            "\x0020\x0651\x0670", /* offset 0x09EE */
+            "\x064A\x0654\x0631", /* offset 0x09EF */
+            "\x064A\x0654\x0632", /* offset 0x09F0 */
+            "\x064A\x0654\x0646", /* offset 0x09F1 */
+            "\x0628\x0631", /* offset 0x09F2 */
+            "\x0628\x0632", /* offset 0x09F3 */
+            "\x0628\x0646", /* offset 0x09F4 */
+            "\x062A\x0631", /* offset 0x09F5 */
+            "\x062A\x0632", /* offset 0x09F6 */
+            "\x062A\x0646", /* offset 0x09F7 */
+            "\x062B\x0631", /* offset 0x09F8 */
+            "\x062B\x0632", /* offset 0x09F9 */
+            "\x062B\x0646", /* offset 0x09FA */
+            "\x0645\x0627", /* offset 0x09FB */
+            "\x0646\x0631", /* offset 0x09FC */
+            "\x0646\x0632", /* offset 0x09FD */
+            "\x0646\x0646", /* offset 0x09FE */
+            "\x064A\x0631", /* offset 0x09FF */
+            "\x064A\x0632", /* offset 0x0A00 */
+            "\x064A\x0646", /* offset 0x0A01 */
+            "\x064A\x0654\x062E", /* offset 0x0A02 */
+            "\x064A\x0654\x0647", /* offset 0x0A03 */
+            "\x0628\x0647", /* offset 0x0A04 */
+            "\x062A\x0647", /* offset 0x0A05 */
+            "\x0635\x062E", /* offset 0x0A06 */
+            "\x0644\x0647", /* offset 0x0A07 */
+            "\x0646\x0647", /* offset 0x0A08 */
+            "\x0647\x0670", /* offset 0x0A09 */
+            "\x064A\x0647", /* offset 0x0A0A */
+            "\x062B\x0647", /* offset 0x0A0B */
+            "\x0633\x0647", /* offset 0x0A0C */
+            "\x0634\x0645", /* offset 0x0A0D */
+            "\x0634\x0647", /* offset 0x0A0E */
+            "\x0640\x064E\x0651", /* offset 0x0A0F */
+            "\x0640\x064F\x0651", /* offset 0x0A10 */
+            "\x0640\x0650\x0651", /* offset 0x0A11 */
+            "\x0637\x0649", /* offset 0x0A12 */
+            "\x0637\x064A", /* offset 0x0A13 */
+            "\x0639\x0649", /* offset 0x0A14 */
+            "\x0639\x064A", /* offset 0x0A15 */
+            "\x063A\x0649", /* offset 0x0A16 */
+            "\x063A\x064A", /* offset 0x0A17 */
+            "\x0633\x0649", /* offset 0x0A18 */
+            "\x0633\x064A", /* offset 0x0A19 */
+            "\x0634\x0649", /* offset 0x0A1A */
+            "\x0634\x064A", /* offset 0x0A1B */
+            "\x062D\x0649", /* offset 0x0A1C */
+            "\x062D\x064A", /* offset 0x0A1D */
+            "\x062C\x0649", /* offset 0x0A1E */
+            "\x062C\x064A", /* offset 0x0A1F */
+            "\x062E\x0649", /* offset 0x0A20 */
+            "\x062E\x064A", /* offset 0x0A21 */
+            "\x0635\x0649", /* offset 0x0A22 */
+            "\x0635\x064A", /* offset 0x0A23 */
+            "\x0636\x0649", /* offset 0x0A24 */
+            "\x0636\x064A", /* offset 0x0A25 */
+            "\x0634\x062C", /* offset 0x0A26 */
+            "\x0634\x062D", /* offset 0x0A27 */
+            "\x0634\x062E", /* offset 0x0A28 */
+            "\x0634\x0631", /* offset 0x0A29 */
+            "\x0633\x0631", /* offset 0x0A2A */
+            "\x0635\x0631", /* offset 0x0A2B */
+            "\x0636\x0631", /* offset 0x0A2C */
+            "\x0627\x064B", /* offset 0x0A2D */
+            "\x062A\x062C\x0645", /* offset 0x0A2E */
+            "\x062A\x062D\x062C", /* offset 0x0A2F */
+            "\x062A\x062D\x0645", /* offset 0x0A30 */
+            "\x062A\x062E\x0645", /* offset 0x0A31 */
+            "\x062A\x0645\x062C", /* offset 0x0A32 */
+            "\x062A\x0645\x062D", /* offset 0x0A33 */
+            "\x062A\x0645\x062E", /* offset 0x0A34 */
+            "\x062C\x0645\x062D", /* offset 0x0A35 */
+            "\x062D\x0645\x064A", /* offset 0x0A36 */
+            "\x062D\x0645\x0649", /* offset 0x0A37 */
+            "\x0633\x062D\x062C", /* offset 0x0A38 */
+            "\x0633\x062C\x062D", /* offset 0x0A39 */
+            "\x0633\x062C\x0649", /* offset 0x0A3A */
+            "\x0633\x0645\x062D", /* offset 0x0A3B */
+            "\x0633\x0645\x062C", /* offset 0x0A3C */
+            "\x0633\x0645\x0645", /* offset 0x0A3D */
+            "\x0635\x062D\x062D", /* offset 0x0A3E */
+            "\x0635\x0645\x0645", /* offset 0x0A3F */
+            "\x0634\x062D\x0645", /* offset 0x0A40 */
+            "\x0634\x062C\x064A", /* offset 0x0A41 */
+            "\x0634\x0645\x062E", /* offset 0x0A42 */
+            "\x0634\x0645\x0645", /* offset 0x0A43 */
+            "\x0636\x062D\x0649", /* offset 0x0A44 */
+            "\x0636\x062E\x0645", /* offset 0x0A45 */
+            "\x0637\x0645\x062D", /* offset 0x0A46 */
+            "\x0637\x0645\x0645", /* offset 0x0A47 */
+            "\x0637\x0645\x064A", /* offset 0x0A48 */
+            "\x0639\x062C\x0645", /* offset 0x0A49 */
+            "\x0639\x0645\x0645", /* offset 0x0A4A */
+            "\x0639\x0645\x0649", /* offset 0x0A4B */
+            "\x063A\x0645\x0645", /* offset 0x0A4C */
+            "\x063A\x0645\x064A", /* offset 0x0A4D */
+            "\x063A\x0645\x0649", /* offset 0x0A4E */
+            "\x0641\x062E\x0645", /* offset 0x0A4F */
+            "\x0642\x0645\x062D", /* offset 0x0A50 */
+            "\x0642\x0645\x0645", /* offset 0x0A51 */
+            "\x0644\x062D\x0645", /* offset 0x0A52 */
+            "\x0644\x062D\x064A", /* offset 0x0A53 */
+            "\x0644\x062D\x0649", /* offset 0x0A54 */
+            "\x0644\x062C\x062C", /* offset 0x0A55 */
+            "\x0644\x062E\x0645", /* offset 0x0A56 */
+            "\x0644\x0645\x062D", /* offset 0x0A57 */
+            "\x0645\x062D\x062C", /* offset 0x0A58 */
+            "\x0645\x062D\x0645", /* offset 0x0A59 */
+            "\x0645\x062D\x064A", /* offset 0x0A5A */
+            "\x0645\x062C\x062D", /* offset 0x0A5B */
+            "\x0645\x062C\x0645", /* offset 0x0A5C */
+            "\x0645\x062E\x062C", /* offset 0x0A5D */
+            "\x0645\x062E\x0645", /* offset 0x0A5E */
+            "\x0645\x062C\x062E", /* offset 0x0A5F */
+            "\x0647\x0645\x062C", /* offset 0x0A60 */
+            "\x0647\x0645\x0645", /* offset 0x0A61 */
+            "\x0646\x062D\x0645", /* offset 0x0A62 */
+            "\x0646\x062D\x0649", /* offset 0x0A63 */
+            "\x0646\x062C\x0645", /* offset 0x0A64 */
+            "\x0646\x062C\x0649", /* offset 0x0A65 */
+            "\x0646\x0645\x064A", /* offset 0x0A66 */
+            "\x0646\x0645\x0649", /* offset 0x0A67 */
+            "\x064A\x0645\x0645", /* offset 0x0A68 */
+            "\x0628\x062E\x064A", /* offset 0x0A69 */
+            "\x062A\x062C\x064A", /* offset 0x0A6A */
+            "\x062A\x062C\x0649", /* offset 0x0A6B */
+            "\x062A\x062E\x064A", /* offset 0x0A6C */
+            "\x062A\x062E\x0649", /* offset 0x0A6D */
+            "\x062A\x0645\x064A", /* offset 0x0A6E */
+            "\x062A\x0645\x0649", /* offset 0x0A6F */
+            "\x062C\x0645\x064A", /* offset 0x0A70 */
+            "\x062C\x062D\x0649", /* offset 0x0A71 */
+            "\x062C\x0645\x0649", /* offset 0x0A72 */
+            "\x0633\x062E\x0649", /* offset 0x0A73 */
+            "\x0635\x062D\x064A", /* offset 0x0A74 */
+            "\x0634\x062D\x064A", /* offset 0x0A75 */
+            "\x0636\x062D\x064A", /* offset 0x0A76 */
+            "\x0644\x062C\x064A", /* offset 0x0A77 */
+            "\x0644\x0645\x064A", /* offset 0x0A78 */
+            "\x064A\x062D\x064A", /* offset 0x0A79 */
+            "\x064A\x062C\x064A", /* offset 0x0A7A */
+            "\x064A\x0645\x064A", /* offset 0x0A7B */
+            "\x0645\x0645\x064A", /* offset 0x0A7C */
+            "\x0642\x0645\x064A", /* offset 0x0A7D */
+            "\x0646\x062D\x064A", /* offset 0x0A7E */
+            "\x0639\x0645\x064A", /* offset 0x0A7F */
+            "\x0643\x0645\x064A", /* offset 0x0A80 */
+            "\x0646\x062C\x062D", /* offset 0x0A81 */
+            "\x0645\x062E\x064A", /* offset 0x0A82 */
+            "\x0644\x062C\x0645", /* offset 0x0A83 */
+            "\x0643\x0645\x0645", /* offset 0x0A84 */
+            "\x062C\x062D\x064A", /* offset 0x0A85 */
+            "\x062D\x062C\x064A", /* offset 0x0A86 */
+            "\x0645\x062C\x064A", /* offset 0x0A87 */
+            "\x0641\x0645\x064A", /* offset 0x0A88 */
+            "\x0628\x062D\x064A", /* offset 0x0A89 */
+            "\x0633\x062E\x064A", /* offset 0x0A8A */
+            "\x0646\x062C\x064A", /* offset 0x0A8B */
+            "\x0635\x0644\x06D2", /* offset 0x0A8C */
+            "\x0642\x0644\x06D2", /* offset 0x0A8D */
+            "\x0627\x0644\x0644\x0647", /* offset 0x0A8E */
+            "\x0627\x0643\x0628\x0631", /* offset 0x0A8F */
+            "\x0645\x062D\x0645\x062F", /* offset 0x0A90 */
+            "\x0635\x0644\x0639\x0645", /* offset 0x0A91 */
+            "\x0631\x0633\x0648\x0644", /* offset 0x0A92 */
+            "\x0639\x0644\x064A\x0647", /* offset 0x0A93 */
+            "\x0648\x0633\x0644\x0645", /* offset 0x0A94 */
+            "\x0635\x0644\x0649", /* offset 0x0A95 */
+            "\x0635\x0644\x0649\x0020\x0627\x0644\x0644\x0647\x0020\x0639\x0644\x064A\x0647\x0020\x0648\x0633\x0644\x0645", /* offset 0x0A96 */
+            "\x062C\x0644\x0020\x062C\x0644\x0627\x0644\x0647", /* offset 0x0A97 */
+            "\x0631\x06CC\x0627\x0644", /* offset 0x0A98 */
+            "\x2014", /* offset 0x0A99 */
+            "\x2013", /* offset 0x0A9A */
+            "\x005F", /* offset 0x0A9B */
+            "\x007B", /* offset 0x0A9C */
+            "\x007D", /* offset 0x0A9D */
+            "\x3014", /* offset 0x0A9E */
+            "\x3015", /* offset 0x0A9F */
+            "\x3010", /* offset 0x0AA0 */
+            "\x3011", /* offset 0x0AA1 */
+            "\x300A", /* offset 0x0AA2 */
+            "\x300B", /* offset 0x0AA3 */
+            "\x300C", /* offset 0x0AA4 */
+            "\x300D", /* offset 0x0AA5 */
+            "\x300E", /* offset 0x0AA6 */
+            "\x300F", /* offset 0x0AA7 */
+            "\x002C", /* offset 0x0AA8 */
+            "\x3001", /* offset 0x0AA9 */
+            "\x003A", /* offset 0x0AAA */
+            "\x003F", /* offset 0x0AAB */
+            "\x0021", /* offset 0x0AAC */
+            "\x0023", /* offset 0x0AAD */
+            "\x0026", /* offset 0x0AAE */
+            "\x002A", /* offset 0x0AAF */
+            "\x002D", /* offset 0x0AB0 */
+            "\x003C", /* offset 0x0AB1 */
+            "\x003E", /* offset 0x0AB2 */
+            "\x005C", /* offset 0x0AB3 */
+            "\x0024", /* offset 0x0AB4 */
+            "\x0025", /* offset 0x0AB5 */
+            "\x0040", /* offset 0x0AB6 */
+            "\x0020\x064B", /* offset 0x0AB7 */
+            "\x0640\x064B", /* offset 0x0AB8 */
+            "\x0020\x064C", /* offset 0x0AB9 */
+            "\x0020\x064D", /* offset 0x0ABA */
+            "\x0020\x064E", /* offset 0x0ABB */
+            "\x0640\x064E", /* offset 0x0ABC */
+            "\x0020\x064F", /* offset 0x0ABD */
+            "\x0640\x064F", /* offset 0x0ABE */
+            "\x0020\x0650", /* offset 0x0ABF */
+            "\x0640\x0650", /* offset 0x0AC0 */
+            "\x0020\x0651", /* offset 0x0AC1 */
+            "\x0640\x0651", /* offset 0x0AC2 */
+            "\x0020\x0652", /* offset 0x0AC3 */
+            "\x0640\x0652", /* offset 0x0AC4 */
+            "\x0621", /* offset 0x0AC5 */
+            "\x0627", /* offset 0x0AC6 */
+            "\x0628", /* offset 0x0AC7 */
+            "\x0629", /* offset 0x0AC8 */
+            "\x062A", /* offset 0x0AC9 */
+            "\x062B", /* offset 0x0ACA */
+            "\x062C", /* offset 0x0ACB */
+            "\x062D", /* offset 0x0ACC */
+            "\x062E", /* offset 0x0ACD */
+            "\x062F", /* offset 0x0ACE */
+            "\x0630", /* offset 0x0ACF */
+            "\x0631", /* offset 0x0AD0 */
+            "\x0632", /* offset 0x0AD1 */
+            "\x0633", /* offset 0x0AD2 */
+            "\x0634", /* offset 0x0AD3 */
+            "\x0635", /* offset 0x0AD4 */
+            "\x0636", /* offset 0x0AD5 */
+            "\x0637", /* offset 0x0AD6 */
+            "\x0638", /* offset 0x0AD7 */
+            "\x0639", /* offset 0x0AD8 */
+            "\x063A", /* offset 0x0AD9 */
+            "\x0641", /* offset 0x0ADA */
+            "\x0642", /* offset 0x0ADB */
+            "\x0643", /* offset 0x0ADC */
+            "\x0644", /* offset 0x0ADD */
+            "\x0645", /* offset 0x0ADE */
+            "\x0646", /* offset 0x0ADF */
+            "\x0647", /* offset 0x0AE0 */
+            "\x0648", /* offset 0x0AE1 */
+            "\x064A", /* offset 0x0AE2 */
+            "\x0644\x0627\x0653", /* offset 0x0AE3 */
+            "\x0644\x0627\x0654", /* offset 0x0AE4 */
+            "\x0644\x0627\x0655", /* offset 0x0AE5 */
+            "\x0644\x0627", /* offset 0x0AE6 */
+            "\x0022", /* offset 0x0AE7 */
+            "\x0027", /* offset 0x0AE8 */
+            "\x002F", /* offset 0x0AE9 */
+            "\x005B", /* offset 0x0AEA */
+            "\x005D", /* offset 0x0AEB */
+            "\x005E", /* offset 0x0AEC */
+            "\x007C", /* offset 0x0AED */
+            "\x007E", /* offset 0x0AEE */
+            "\x2985", /* offset 0x0AEF */
+            "\x2986", /* offset 0x0AF0 */
+            "\x3002", /* offset 0x0AF1 */
+            "\x30FB", /* offset 0x0AF2 */
+            "\x30A1", /* offset 0x0AF3 */
+            "\x30A3", /* offset 0x0AF4 */
+            "\x30A5", /* offset 0x0AF5 */
+            "\x30A7", /* offset 0x0AF6 */
+            "\x30A9", /* offset 0x0AF7 */
+            "\x30E3", /* offset 0x0AF8 */
+            "\x30E5", /* offset 0x0AF9 */
+            "\x30E7", /* offset 0x0AFA */
+            "\x30C3", /* offset 0x0AFB */
+            "\x30FC", /* offset 0x0AFC */
+            "\x30F3", /* offset 0x0AFD */
+            "\x3099", /* offset 0x0AFE */
+            "\x309A", /* offset 0x0AFF */
+            "\x00A2", /* offset 0x0B00 */
+            "\x00A3", /* offset 0x0B01 */
+            "\x00AC", /* offset 0x0B02 */
+            "\x00A6", /* offset 0x0B03 */
+            "\x00A5", /* offset 0x0B04 */
+            "\x20A9", /* offset 0x0B05 */
+            "\x2502", /* offset 0x0B06 */
+            "\x2190", /* offset 0x0B07 */
+            "\x2191", /* offset 0x0B08 */
+            "\x2192", /* offset 0x0B09 */
+            "\x2193", /* offset 0x0B0A */
+            "\x25A0", /* offset 0x0B0B */
+            "\x25CB", /* offset 0x0B0C */
+        };
+    }
+}
+
diff --git a/lib/jabber-net/stringprep/unicode/ResourceLoader.cs b/lib/jabber-net/stringprep/unicode/ResourceLoader.cs
new file mode 100644
index 0000000..2c8c7a6
--- /dev/null
+++ b/lib/jabber-net/stringprep/unicode/ResourceLoader.cs
@@ -0,0 +1,47 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net can be used under either JOSL or the GPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Resources;
+using System.Reflection;
+
+namespace stringprep.unicode
+{
+    class ResourceLoader
+    {
+        private const string UNICODE = "stringprep.unicode.Unicode";
+        private static ResourceManager m_uni_res = null;
+
+        private static ResourceManager Resources
+        {
+            get
+            {
+                if (m_uni_res == null)
+                {
+                    lock (UNICODE)
+                    {
+                        if (m_uni_res == null)
+                            m_uni_res = new ResourceManager(UNICODE, Assembly.GetExecutingAssembly());
+                    }
+                }
+                return m_uni_res;
+            }
+        }
+
+        public static object LoadRes(string name)
+        {
+            return Resources.GetObject(name);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/AssemblyInfo.cs b/lib/jabber-net/test/AssemblyInfo.cs
new file mode 100644
index 0000000..f214fcc
--- /dev/null
+++ b/lib/jabber-net/test/AssemblyInfo.cs
@@ -0,0 +1,74 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System.Reflection;
+
+using System.Runtime.CompilerServices;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly: AssemblyTitle("")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+//
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly: AssemblyVersion("1.0.*")]
+
+//
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly signing.
+//
+// Use the attributes below to control which key is used for signing.
+//
+// Notes:
+//   (*) If no key is specified, the assembly is not signed.
+//   (*) KeyName refers to a key that has been installed in the Crypto Service
+//       Provider (CSP) on your machine. KeyFile refers to a file which contains
+//       a key.
+//   (*) If the KeyFile and the KeyName values are both specified, the
+//       following processing occurs:
+//       (1) If the KeyName can be found in the CSP, that key is used.
+//       (2) If the KeyName does not exist and the KeyFile does exist, the key
+//           in the KeyFile is installed into the CSP and used.
+//   (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
+//       When specifying the KeyFile, the location of the KeyFile should be
+//       relative to the project output directory which is
+//       %Project Directory%\obj\<configuration>. For example, if your KeyFile is
+//       located in the project directory, you would specify the AssemblyKeyFile
+//       attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
+//   (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
+//       documentation for more information on this.
+//
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyKeyName("")]
+
+[assembly: System.CLSCompliant(true)]
diff --git a/lib/jabber-net/test/bedrock/collections/ByteStackTest.cs b/lib/jabber-net/test/bedrock/collections/ByteStackTest.cs
new file mode 100644
index 0000000..0ce3afc
--- /dev/null
+++ b/lib/jabber-net/test/bedrock/collections/ByteStackTest.cs
@@ -0,0 +1,89 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+
+using NUnit.Framework;
+using bedrock.collections;
+using bedrock.util;
+
+namespace test.bedrock.collections
+{
+    /// <summary>
+    ///    Summary description for TemplateTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class ByteStackTest
+    {
+        private System.Text.Encoding ENC = System.Text.Encoding.Default;
+
+        [Test] public void Test_Main()
+        {
+            ByteStack bs = new ByteStack();
+            Assert.AreEqual(0, bs.Count);
+            bs.Push((byte) 'a');
+            Assert.AreEqual(1, bs.Count);
+            byte b = bs.Pop();
+            Assert.AreEqual(b, (byte)'a');
+            Assert.AreEqual(0, bs.Count);
+        }
+        [Test] public void Test_Empty()
+        {
+            ByteStack bs = new ByteStack();
+            byte[] buf = bs;
+            Assert.AreEqual(0, buf.Length);
+        }
+        [Test] public void Test_Init()
+        {
+            ByteStack bs = new ByteStack(ENC.GetBytes("foo"));
+            Assert.AreEqual("foo", bs.ToString());
+            bs.Push((byte) 't');
+            Assert.AreEqual("foot", bs.ToString());
+            bs = new ByteStack(ENC.GetBytes("f"));
+            bs.Push((byte) 't');
+            Assert.AreEqual("ft", bs.ToString());
+        }
+        [Test] public void Test_Growth()
+        {
+            ByteStack bs = new ByteStack(4);
+
+            bs.Push((byte) 'b');
+            Assert.AreEqual("b", bs.ToString());
+            bs.Push((byte) 'c');
+            Assert.AreEqual("bc", bs.ToString());
+            bs.Push((byte) 'd');
+            Assert.AreEqual("bcd", bs.ToString());
+            bs.Push((byte) 'e');
+            Assert.AreEqual("bcde", bs.ToString());
+            bs.Push((byte) 'b');
+            Assert.AreEqual("bcdeb", bs.ToString());
+            bs.Push((byte) 'c');
+            Assert.AreEqual("bcdebc", bs.ToString());
+            bs.Push((byte) 'd');
+            Assert.AreEqual("bcdebcd", bs.ToString());
+            bs.Push((byte) 'e');
+            Assert.AreEqual("bcdebcde", bs.ToString());
+            bs.Push((byte) 'b');
+            bs.Push((byte) 'c');
+            bs.Push((byte) 'd');
+            bs.Push((byte) 'e');
+            bs.Push((byte) 'b');
+            bs.Push((byte) 'c');
+            bs.Push((byte) 'd');
+            bs.Push((byte) 'e');
+            Assert.AreEqual("bcdebcdebcdebcde", bs.ToString());
+        }
+    }
+}
diff --git a/lib/jabber-net/test/bedrock/collections/SetTest.cs b/lib/jabber-net/test/bedrock/collections/SetTest.cs
new file mode 100644
index 0000000..2b79038
--- /dev/null
+++ b/lib/jabber-net/test/bedrock/collections/SetTest.cs
@@ -0,0 +1,114 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using NUnit.Framework;
+using bedrock.collections;
+using bedrock.util;
+
+namespace test.bedrock.collections
+{
+    /// <summary>
+    /// Summary description for SetTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class SetTest
+    {
+        //[ExpectedException(typeof(ArgumentException))]
+        [Test] public void Test_Hashtable_Double_Add()
+        {
+            Set s = new Set(SetImplementation.Hashtable);
+            Assert.AreEqual(0, s.Count);
+            s.Add("one");
+            Assert.AreEqual(1, s.Count);
+            s.Add("one");
+        }
+        //[ExpectedException(typeof(ArgumentException))]
+        [Test] public void Test_SkipList_Double_Add()
+        {
+            Set s = new Set(SetImplementation.SkipList);
+            Assert.AreEqual(0, s.Count);
+            s.Add("one");
+            Assert.AreEqual(1, s.Count);
+            s.Add("one");
+        }
+        //[ExpectedException(typeof(ArgumentException))]
+        [Test] public void Test_Tree_Double_Add()
+        {
+            Set s = new Set(SetImplementation.Tree);
+            Assert.AreEqual(0, s.Count);
+            s.Add("one");
+            Assert.AreEqual(1, s.Count);
+            s.Add("one");
+        }
+
+        private void all(SetImplementation i)
+        {
+            Set s = new Set(i);
+            Assert.AreEqual(0, s.Count);
+
+            s.Add("one");
+            Assert.AreEqual(1, s.Count);
+            Assert.IsTrue(s.Contains("one"));
+            Assert.IsTrue(!s.Contains("two"));
+            Assert.IsTrue(!s.Contains("three"));
+
+            s.Add("two");
+            Assert.AreEqual(2, s.Count);
+            Assert.IsTrue(s.Contains("one"));
+            Assert.IsTrue(s.Contains("two"));
+            Assert.IsTrue(!s.Contains("three"));
+
+            s.Remove("one");
+            Assert.AreEqual(1, s.Count);
+            Assert.IsTrue(!s.Contains("one"));
+            Assert.IsTrue(s.Contains("two"));
+            Assert.IsTrue(!s.Contains("three"));
+
+            s.Add("one");
+            Assert.AreEqual(2, s.Count);
+            Assert.IsTrue(s.Contains("one"));
+            Assert.IsTrue(s.Contains("two"));
+            Assert.IsTrue(!s.Contains("three"));
+
+            s.Add("one");
+            Assert.AreEqual(2, s.Count);
+            Assert.IsTrue(s.Contains("one"));
+            Assert.IsTrue(s.Contains("two"));
+            Assert.IsTrue(!s.Contains("three"));
+
+            int count = 0;
+            foreach (string str in s)
+            {
+                count++;
+                Assert.AreEqual(3, str.Length);
+            }
+            Assert.AreEqual(2, count);
+        }
+
+        [Test] public void Test_Hashtable()
+        {
+            all(SetImplementation.Hashtable);
+        }
+        [Test] public void Test_Skiplist()
+        {
+            all(SetImplementation.SkipList);
+        }
+        [Test] public void Test_Tree()
+        {
+            all(SetImplementation.Tree);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/bedrock/collections/SkipListTest.cs b/lib/jabber-net/test/bedrock/collections/SkipListTest.cs
new file mode 100644
index 0000000..db82b70
--- /dev/null
+++ b/lib/jabber-net/test/bedrock/collections/SkipListTest.cs
@@ -0,0 +1,152 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using NUnit.Framework;
+using bedrock.collections;
+using bedrock.util;
+using System.Collections;
+
+namespace test.bedrock.collections
+{
+    /// <summary>
+    /// Summary description for SkipListTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class SkipListTest
+    {
+        [ExpectedException(typeof(ArgumentNullException))]
+        [Test] public void Test_Null_Key()
+        {
+            SkipList sl = new SkipList();
+            sl.Add(null, "one");
+        }
+
+        [ExpectedException(typeof(ArgumentException))]
+        [Test] public void Test_Key_Twice()
+        {
+            SkipList sl = new SkipList();
+            sl.Add("one", "one");
+            sl.Add("one", "one");
+        }
+
+        [Test] public void Test_Add()
+        {
+            SkipList sl = new SkipList();
+            Assert.AreEqual(0, sl.Count);
+            sl.Add("1", "bar");
+            Assert.AreEqual(1, sl.Count);
+            sl.Add("2", "baz");
+            Assert.AreEqual(2, sl.Count);
+        }
+        [Test] public void Test_Get()
+        {
+            SkipList sl = new SkipList();
+            sl.Add("1", "bar");
+            Assert.AreEqual("bar", sl["1"]);
+        }
+        [Test] public void Test_Lots_InOrder()
+        {
+            SkipList sl = new SkipList();
+            for (int i=0; i<4096; i++)
+            {
+                sl[i] = i.ToString();
+            }
+            Assert.AreEqual(4096, sl.Count);
+            for (int i=0; i<4096; i++)
+            {
+                Assert.AreEqual(i.ToString(), sl[i]);
+            }
+        }
+        [Test] public void Test_Lots_Random()
+        {
+            SkipList sl = new SkipList();
+            Random r = new Random();
+            int[] nums = new int[4096];
+
+            for (int i=0; i<4096; i++)
+            {
+                nums[i] = r.Next(10000);
+                while (sl.Contains(nums[i]))
+                {
+                    nums[i] = r.Next(10000);
+                }
+                sl[nums[i]] = i.ToString();
+            }
+            Assert.AreEqual(4096, sl.Count);
+            for (int i=0; i<4096; i++)
+            {
+                Assert.AreEqual(i.ToString(), sl[nums[i]]);
+            }
+        }
+        [Test] public void Test_Iteration()
+        {
+            SkipList sl = new SkipList();
+            for (int i=0; i<4096; i++)
+            {
+                sl[i] = i.ToString();
+            }
+            Assert.AreEqual(4096, sl.Count);
+            int count = 0;
+            foreach (DictionaryEntry de in sl)
+            {
+                Assert.AreEqual(count, de.Key);
+                Assert.AreEqual(count.ToString(), de.Value);
+                count++;
+            }
+            Assert.AreEqual(4096, count);
+        }
+
+        [Test] public void Test_DictIteration()
+        {
+            SkipList sl = new SkipList();
+            for (int i=0; i<4096; i++)
+            {
+                sl[i] = i.ToString();
+            }
+            Assert.AreEqual(4096, sl.Count);
+            int count = 0;
+            IDictionaryEnumerator e = sl.GetEnumerator();
+            while (e.MoveNext())
+            {
+                Assert.AreEqual(count, e.Key);
+                Assert.AreEqual(count.ToString(), e.Value);
+                count++;
+            }
+            Assert.AreEqual(4096, count);
+        }
+
+        [Test] public void Test_Remove()
+        {
+            SkipList sl = new SkipList();
+            sl[0] = 0;
+            Assert.AreEqual(1, sl.Count);
+            sl.Remove(0);
+            Assert.AreEqual(0, sl.Count);
+        }
+
+        [Test] public void Test_Clear()
+        {
+            SkipList sl = new SkipList();
+            for (int i=0; i<4096; i++)
+            {
+                sl[i] = i.ToString();
+            }
+            Assert.AreEqual(4096, sl.Count);
+            sl.Clear();
+            Assert.AreEqual(0, sl.Count);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/bedrock/collections/StringSet.cs b/lib/jabber-net/test/bedrock/collections/StringSet.cs
new file mode 100644
index 0000000..48e8640
--- /dev/null
+++ b/lib/jabber-net/test/bedrock/collections/StringSet.cs
@@ -0,0 +1,145 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using NUnit.Framework;
+using bedrock.collections;
+using bedrock.util;
+
+namespace test.bedrock.collections
+{
+    [TestFixture]
+    [SVN(@"$Id$")]
+    public class StringSetTest
+    {
+        [Test]
+        public void Create()
+        {
+            StringSet ss = new StringSet();
+            Assert.AreEqual(0, ss.Count);
+            Assert.AreEqual("", ss.ToString());
+        }
+
+        [Test]
+        public void Add()
+        {
+            StringSet ss = new StringSet();
+            ss.Add("foo");
+            ss.Add("foo");
+            ss.Add("bar");
+            Assert.IsTrue(ss["foo"]);
+            Assert.AreEqual(2, ss.Count);
+            Assert.AreEqual("foo\r\nbar\r\n", ss.ToString());
+            ss.Remove("bar");
+            Assert.AreEqual(1, ss.Count);
+            Assert.IsFalse(ss["fool"]);
+
+            ss = new StringSet(new string[] { "foo", "bar"});
+            ss.Add(new StringSet("baz"));
+            Assert.AreEqual(3, ss.Count);
+        }
+
+        [Test]
+        public void Merge()
+        {
+            StringSet ss = new StringSet();
+            ss.Add("foo");
+            StringSet so = new StringSet();
+            so.Add("bar");
+            so.Add("baz");
+            ss.Add(so);
+            Assert.AreEqual(3, ss.Count);
+
+            so = new StringSet();
+            so.Add("boo");
+            so.Add("baz");
+            ss.Add(so);
+            Assert.AreEqual(4, ss.Count);
+
+            ss.Remove(so);
+            Assert.AreEqual(2, ss.Count);
+            Assert.IsTrue(ss["foo"]);
+            Assert.IsTrue(ss["bar"]);
+            Assert.IsFalse(ss["boo"]);
+            Assert.IsFalse(ss["baz"]);
+            Assert.IsFalse(ss["bloo"]);
+        }
+
+        [Test]
+        public void Enumerate()
+        {
+            StringSet ss = new StringSet();
+
+            int i = 0;
+            foreach (string s in ss)
+            {
+                i++;
+                Console.WriteLine(s);
+            }
+            Assert.AreEqual(0, i);
+
+            ss.Add("bloo");
+            ss.Add("foo");
+            ss.Add("bar");
+            foreach (string s in ss)
+            {
+                i++;
+                Console.WriteLine(s);
+            }
+            Assert.AreEqual(3, i);
+            string[] arr = ss.GetStrings();
+            Array.Sort(arr);
+            Assert.AreEqual("bar", arr[0]);
+            Assert.AreEqual("bloo", arr[1]);
+            Assert.AreEqual("foo", arr[2]);
+            Assert.AreEqual(3, arr.Length);
+        }
+
+        [Test]
+        public void Operators()
+        {
+            StringSet ss = new StringSet();
+            ss = ss + "bloo" + "bar";
+            Assert.AreEqual(2, ss.Count);
+            StringSet so = ss;
+            Assert.AreEqual(ss, so);
+            Assert.AreEqual(ss.GetHashCode(), so.GetHashCode());
+            so = new StringSet(so);
+            Assert.AreEqual(ss, so);
+            Assert.AreEqual(ss.GetHashCode(), so.GetHashCode());
+            so = ss - "bar";
+            Assert.AreEqual(1, so.Count);
+            Assert.AreNotEqual(ss, so);
+            Assert.IsTrue(ss != so);
+            Assert.AreNotEqual(ss.GetHashCode(), so.GetHashCode());
+        }
+
+        [Test]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void Null()
+        {
+            StringSet ss = new StringSet();
+            ss.Add((string)null);
+        }
+        
+        [Test]
+        public void Empty()
+        {
+            StringSet ss = new StringSet(new string[] { "" });
+            Assert.AreEqual(1, ss.Count);
+            ss = new StringSet((string[])null);
+            Assert.AreEqual(0, ss.Count);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/bedrock/collections/TreeTest.cs b/lib/jabber-net/test/bedrock/collections/TreeTest.cs
new file mode 100644
index 0000000..941b345
--- /dev/null
+++ b/lib/jabber-net/test/bedrock/collections/TreeTest.cs
@@ -0,0 +1,179 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using NUnit.Framework;
+using bedrock.collections;
+using bedrock.util;
+
+namespace test.bedrock.collections
+{
+    /// <summary>
+    /// Summary description for TreeTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class TreeTest
+    {
+        private Tree data()
+        {
+            Tree t = new Tree();
+            t.Add("one", "one");
+            t["2"]  = "12";
+            t["~"]  = "2~";
+            t["a~"] = "3a~";
+            t["~a"] = "4~a";
+            t[" "]  = "5 ";
+            t["  "] = "6  ";
+            Assert.AreEqual(t.Count, 7);
+            Assert.IsTrue(t.Contains("~"));
+            Assert.IsTrue(!t.Contains("~~"));
+            return t;
+        }
+        [Test] public void Test_Type()
+        {
+            Tree t = new Tree();
+            Assert.AreEqual("bedrock.collections.Tree", t.GetType().FullName);
+        }
+        [Test] public void Test_Main()
+        {
+            Tree t = new Tree();
+            t["one"] = "two";
+            Assert.AreEqual("two", t["one"]);
+            Assert.AreEqual(t.Count, 1);
+            t.Remove("one");
+            Assert.AreEqual(t.Count, 0);
+            Assert.AreEqual(null, t["one"]);
+        }
+        [Test] public void Test_Enum()
+        {
+            Tree t = data();
+            int i = 0;
+            string s;
+            foreach (DictionaryEntry o in t)
+            {
+                s = "s|" + o.Key + "|=|" + o.Value + "|";
+                Console.WriteLine(s);
+                i++;
+            }
+            Assert.AreEqual(7, i);
+        }
+        [Test] public void Test_Clear()
+        {
+            Tree t = new Tree();
+            Assert.AreEqual(t.Count, 0);
+            t.Clear();
+            Assert.AreEqual(t.Count, 0);
+            t.Add("one", "one");
+            Assert.AreEqual(t.Count, 1);
+            t.Clear();
+            Assert.AreEqual(t.Count, 0);
+        }
+        [Test] public void Test_Values()
+        {
+            Tree t = data();
+            ICollection ic = t.Values;
+            Assert.AreEqual(ic.Count, 7);
+            object[] o = (object[]) ic;
+            Assert.AreEqual("5 ", o[0]);
+        }
+        [Test] public void Test_Keys()
+        {
+            Tree t = data();
+            ICollection ic = t.Keys;
+            Assert.AreEqual(7, ic.Count);
+            object[] o = (object[]) ic;
+            Assert.AreEqual(" ", o[0]);
+        }
+
+        [Test] public void Test_Lots_InOrder()
+        {
+            Tree sl = new Tree();
+            for (int i=0; i<4096; i++)
+            {
+                sl[i] = i.ToString();
+            }
+            Assert.AreEqual(4096, sl.Count);
+            for (int i=0; i<4096; i++)
+            {
+                Assert.AreEqual(i.ToString(), sl[i]);
+            }
+        }
+        [Test] public void Test_Lots_Random()
+        {
+            Tree sl = new Tree();
+            Random r = new Random();
+            int[] nums = new int[4096];
+
+            for (int i=0; i<4096; i++)
+            {
+                nums[i] = r.Next(10000);
+                while (sl.Contains(nums[i]))
+                {
+                    nums[i] = r.Next(10000);
+                }
+                sl[nums[i]] = i.ToString();
+            }
+            Assert.AreEqual(4096, sl.Count);
+            for (int i=0; i<4096; i++)
+            {
+                Assert.AreEqual(i.ToString(), sl[nums[i]]);
+            }
+        }
+        [Test] public void Test_Iteration()
+        {
+            Tree sl = new Tree();
+            for (int i=0; i<4096; i++)
+            {
+                sl[i] = i.ToString();
+            }
+            Assert.AreEqual(4096, sl.Count);
+            int count = 0;
+            foreach (DictionaryEntry de in sl)
+            {
+                Assert.AreEqual(count, de.Key);
+                Assert.AreEqual(count.ToString(), de.Value);
+                count++;
+            }
+            Assert.AreEqual(4096, count);
+        }
+
+        [Test] public void Test_DictIteration()
+        {
+            Tree sl = new Tree();
+            for (int i=0; i<4096; i++)
+            {
+                sl[i] = i.ToString();
+            }
+            Assert.AreEqual(4096, sl.Count);
+            int count = 0;
+            IDictionaryEnumerator e = sl.GetEnumerator();
+            while (e.MoveNext())
+            {
+                Assert.AreEqual(count, e.Key);
+                Assert.AreEqual(count.ToString(), e.Value);
+                count++;
+            }
+            Assert.AreEqual(4096, count);
+        }
+
+        [ExpectedException(typeof(ArgumentNullException))]
+        [Test] public void Test_Null()
+        {
+            Tree sl = new Tree();
+            sl[null] = "n";
+        }
+    }
+}
diff --git a/lib/jabber-net/test/bedrock/collections/TrieNodeTest.cs b/lib/jabber-net/test/bedrock/collections/TrieNodeTest.cs
new file mode 100644
index 0000000..bc97fb8
--- /dev/null
+++ b/lib/jabber-net/test/bedrock/collections/TrieNodeTest.cs
@@ -0,0 +1,43 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using NUnit.Framework;
+using bedrock.collections;
+using bedrock.util;
+namespace test.bedrock.collections
+{
+    /// <summary>
+    ///    Summary description for TemplateTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class TrieNodeTest
+    {
+        [Test] public void Test_Main()
+        {
+            System.Text.Encoding ENC = System.Text.Encoding.Default;
+            TrieNode n = new TrieNode(null, 0);
+            byte[] key = ENC.GetBytes("test");
+            TrieNode current = n;
+            for (int i=0; i<key.Length; i++)
+            {
+                byte b = key[i];
+                current = current[b, true];
+            }
+            current.Value = "foo";
+            Assert.AreEqual(ENC.GetString(key), ENC.GetString(current.Key));
+        }
+    }
+}
diff --git a/lib/jabber-net/test/bedrock/collections/TrieTest.cs b/lib/jabber-net/test/bedrock/collections/TrieTest.cs
new file mode 100644
index 0000000..794221f
--- /dev/null
+++ b/lib/jabber-net/test/bedrock/collections/TrieTest.cs
@@ -0,0 +1,103 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Collections;
+using NUnit.Framework;
+using bedrock.collections;
+using bedrock.util;
+
+namespace test.bedrock.collections
+{
+    /// <summary>
+    ///    Summary description for TemplateTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class TrieTest
+    {
+        private Trie data()
+        {
+            Trie t = new Trie();
+            t.Add("one", "one");
+            t[2]    = "2";
+            t["~"]  = "~";
+            t["a~"] = "a~";
+            t["~a"] = "~a";
+            t[' ']  = " ";
+            t["  "] = "  ";
+            Assert.AreEqual(t.Count, 7);
+            Assert.IsTrue(t.Contains("~"));
+            Assert.IsTrue(!t.Contains("~~"));
+            return t;
+        }
+        [Test] public void Test_Type()
+        {
+            Trie t = new Trie();
+            Assert.AreEqual("bedrock.collections.Trie", t.GetType().FullName);
+        }
+        [Test] public void Test_Main()
+        {
+            Trie t = new Trie();
+            t["one"] = "two";
+            Assert.AreEqual("two", t["one"]);
+            Assert.AreEqual(t.Count, 1);
+            t.Remove("one");
+            Assert.AreEqual(t.Count, 0);
+            Assert.AreEqual(null, t["one"]);
+        }
+        [Test] public void Test_Enum()
+        {
+            Trie t = data();
+            int i = 0;
+            string s;
+            foreach (DictionaryEntry o in t)
+            {
+                s = "s|" + System.Text.Encoding.UTF8.GetString((byte[])o.Key) +
+                    "|=|" + o.Value + "|";
+                Console.WriteLine(s);
+                i++;
+            }
+            Assert.AreEqual(7, i);
+        }
+        [Test] public void Test_Clear()
+        {
+            Trie t = new Trie();
+            Assert.AreEqual(t.Count, 0);
+            t.Clear();
+            Assert.AreEqual(t.Count, 0);
+            t.Add("one", "one");
+            Assert.AreEqual(t.Count, 1);
+            t.Clear();
+            Assert.AreEqual(t.Count, 0);
+        }
+        [Test] public void Test_Values()
+        {
+            Trie t = data();
+            ICollection ic = t.Values;
+            Assert.AreEqual(ic.Count, 7);
+        }
+        [Test] public void Test_Keys()
+        {
+            Trie t = data();
+            ICollection ic = t.Keys;
+            Assert.AreEqual(7, ic.Count);
+        }
+        [Test] public void Test_Dictionary()
+        {
+            Trie t = data();
+            // TODO: test dictionary enumerator.
+        }
+    }
+}
diff --git a/lib/jabber-net/test/bedrock/io/ZlibStream.cs b/lib/jabber-net/test/bedrock/io/ZlibStream.cs
new file mode 100644
index 0000000..f2745df
--- /dev/null
+++ b/lib/jabber-net/test/bedrock/io/ZlibStream.cs
@@ -0,0 +1,73 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.IO;
+
+using NUnit.Framework;
+using bedrock.io;
+using bedrock.util;
+
+namespace test.bedrock.io
+{
+    /// <summary>
+    /// Test the ZlibStream class.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class ZlibStreamTest
+    {
+        private static readonly System.Text.Encoding ENC = System.Text.Encoding.UTF8;
+
+        // python:
+        // [ord(x) for x in zlib.compress("Hello, world")]
+        private const string HELLO_STR = "Hello, world";
+        private static readonly byte[] HELLO_BYTES = new byte[]
+        {
+            120, 156, 243,  72, 205, 201, 201, 215,
+             81,  40, 207,  47, 202,  73,   1,   0,
+             27, 212,   4, 105
+        };
+
+        [Test]
+        public void Read()
+        {
+            MemoryStream ms = new MemoryStream();
+            ms.Write(HELLO_BYTES, 0, HELLO_BYTES.Length);
+            ms.Seek(0, SeekOrigin.Begin);
+            ZlibStream z = new ZlibStream(ms);
+            byte[] buf = new byte[1024];
+            int len = z.Read(buf, 0, buf.Length);
+            Assert.Greater(len, 0);
+            string str = ENC.GetString(buf, 0, len);
+            Assert.AreEqual(HELLO_STR, str);
+        }
+
+        [Test]
+        public void Write()
+        {
+            byte[] buf = ENC.GetBytes(HELLO_STR);
+            MemoryStream ms = new MemoryStream();
+            ZlibStream z = new ZlibStream(ms, 4);
+            z.Write(buf, 0, buf.Length);
+            ms.Seek(0, SeekOrigin.Begin);
+            byte[] res = ms.ToArray();
+            Assert.AreEqual(HELLO_BYTES.Length, res.Length);
+            int count = 0;
+            foreach (byte b in res)
+            {
+                Assert.AreEqual(HELLO_BYTES[count++], b);
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/test/bedrock/net/AsyncSocketTest.cs b/lib/jabber-net/test/bedrock/net/AsyncSocketTest.cs
new file mode 100644
index 0000000..818da66
--- /dev/null
+++ b/lib/jabber-net/test/bedrock/net/AsyncSocketTest.cs
@@ -0,0 +1,188 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Threading;
+using NUnit.Framework;
+using bedrock.net;
+using bedrock.util;
+namespace test.bedrock.net
+{
+    /// <summary>
+    ///    Summary description for AsyncSocketTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class AsyncSocketTest : ISocketEventListener
+    {
+        private static readonly System.Text.Encoding ENC = System.Text.Encoding.ASCII;
+
+        private static readonly byte[] sbuf = ENC.GetBytes("01234567890123456789012345678901234567890123456789012345678901234567890123456789");
+        private readonly object done = new object();
+        private string success = null;
+
+        private bool succeeded = true;
+        private string errorMessage;
+
+        [Test] public void Test_Write()
+        {
+            SocketWatcher w = new SocketWatcher(20);
+            Address a = new Address("127.0.0.1", 7001);
+            a.Resolve();
+
+            AsyncSocket listen = w.CreateListenSocket(this, a);
+            listen.RequestAccept();
+
+            AsyncSocket connect;
+            lock (done)
+            {
+                connect = w.CreateConnectSocket(this, a);
+                bool NoTimeout = Monitor.Wait(done, new TimeSpan(0, 0, 30));
+
+                Assert.IsTrue(NoTimeout, "The read command didn't complete in time.");
+                Assert.IsTrue(succeeded, errorMessage);
+            }
+
+            Assert.AreEqual("5678901234", success);
+            connect.Close();
+            listen.Close();
+        }
+
+// %$@! can't use #pragma in VS.Net 2003.  Just live with these warnings.
+// #pragma warning disable 1718
+        [Test]
+        public void Test_Ops()
+        {
+            SocketWatcher w = new SocketWatcher(20);
+            Address a = new Address("127.0.0.1", 7002);
+            a.Resolve();
+            AsyncSocket one = w.CreateListenSocket(this, a);
+            AsyncSocket two = null;
+            AsyncSocket three = one;
+            AsyncSocket four = two;
+            Assert.IsTrue(one == three);
+            Assert.IsTrue(two == four);
+            Assert.IsTrue(one >= three);
+            Assert.IsTrue(two >= four);
+            Assert.IsTrue(one <= three);
+            Assert.IsTrue(two <= four);
+            Assert.IsTrue(one != two);
+            Assert.IsTrue(two != one);
+            Assert.IsTrue(one > two);
+            Assert.IsTrue(one >= two);
+            Assert.IsTrue(two < one);
+            Assert.IsTrue(two <= one);
+
+            two = w.CreateListenSocket(this, a);
+            four = two;
+            Assert.IsTrue(one == three);
+            Assert.IsTrue(two == four);
+            Assert.IsTrue(one >= three);
+            Assert.IsTrue(two >= four);
+            Assert.IsTrue(one <= three);
+            Assert.IsTrue(two <= four);
+            Assert.IsTrue(one != two);
+            Assert.IsTrue(two != one);
+
+            int c = ((IComparable)one).CompareTo(two);
+            Assert.IsTrue(c != 0);
+            if (c == -1)
+            {
+                // one less than two
+                Assert.IsTrue(one < two);
+                Assert.IsTrue(one <= two);
+                Assert.IsTrue(two > one);
+                Assert.IsTrue(two >= one);
+            }
+            else if (c == 1)
+            {
+                // one greater than two
+                Assert.IsTrue(one > two);
+                Assert.IsTrue(one >= two);
+                Assert.IsTrue(two < one);
+                Assert.IsTrue(two <= one);
+            }
+            else
+            {
+                Assert.IsTrue(false);
+            }
+            one.Close();
+            two.Close();
+        }
+// #pragma warning restore
+        #region Implementation of ISocketEventListener
+        public bool OnAccept(BaseSocket newsocket)
+        {
+            newsocket.RequestRead();
+            return false;
+        }
+
+        public bool OnRead(BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            success = ENC.GetString(buf, offset, length);
+            sock.Close();
+            lock(done)
+            {
+                Monitor.Pulse(done);
+            }
+            return false;
+        }
+
+        public void OnWrite(BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            System.Diagnostics.Debug.WriteLine(ENC.GetString(buf, offset, length));
+            sock.Close();
+        }
+
+        public void OnError(BaseSocket sock, Exception ex)
+        {
+            lock (done)
+            {
+                succeeded = false;
+                errorMessage = ex.Message;
+                Monitor.Pulse(done);
+            }
+        }
+
+        public void OnConnect(BaseSocket sock)
+        {
+            sock.Write(sbuf, 5, 10);
+        }
+
+        public void OnClose(BaseSocket sock)
+        {
+
+        }
+
+        public void OnInit(BaseSocket new_sock)
+        {
+
+        }
+
+        public ISocketEventListener GetListener(BaseSocket new_sock)
+        {
+            return this;
+        }
+
+        public bool OnInvalidCertificate(BaseSocket sock,
+            System.Security.Cryptography.X509Certificates.X509Certificate certificate,
+            System.Security.Cryptography.X509Certificates.X509Chain chain,
+            System.Net.Security.SslPolicyErrors sslPolicyErrors)
+        {
+            return false;
+        }
+
+        #endregion
+    }
+}
diff --git a/lib/jabber-net/test/bedrock/net/HttpSocketTest.cs b/lib/jabber-net/test/bedrock/net/HttpSocketTest.cs
new file mode 100644
index 0000000..7ca7d70
--- /dev/null
+++ b/lib/jabber-net/test/bedrock/net/HttpSocketTest.cs
@@ -0,0 +1,197 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using NUnit.Framework;
+
+using bedrock.net;
+using bedrock.util;
+using System.Threading;
+
+
+namespace test.bedrock.net
+{
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class HttpSocketTest
+    {
+        private static readonly Encoding ENC = Encoding.UTF8;
+
+        private class ServerListener: ISocketEventListener
+        {
+            #region ISocketEventListener Members
+
+            public void OnInit(BaseSocket newSock)
+            {
+            }
+
+            public ISocketEventListener GetListener(BaseSocket newSock)
+            {
+                return this;
+            }
+
+            public bool OnAccept(BaseSocket newsocket)
+            {
+                AsyncSocket s = (AsyncSocket)newsocket;
+                newsocket.RequestRead();
+                return true;
+            }
+
+            public void OnConnect(BaseSocket sock)
+            {
+                throw new NotImplementedException("The method or operation is not implemented.");
+            }
+
+            public void OnClose(BaseSocket sock)
+            {
+                
+            }
+
+            public void OnError(BaseSocket sock, Exception ex)
+            {
+                throw ex;
+            }
+
+            public bool OnRead(BaseSocket sock, byte[] buf, int offset, int length)
+            {
+                string str = ENC.GetString(buf, offset, length);
+                Console.WriteLine("SR: " + str);
+                if (str.Contains("11111"))
+                {
+                sock.Write(ENC.GetBytes(@"HTTP/1.1 200 OK
+Content-Length: 10
+Content-Type: text/plain
+
+1234567890"));
+                }
+                else if (str.Contains("22222"))
+                {
+                    sock.Write(ENC.GetBytes(@"HTTP/1.1 200 OK
+Content-Length: 10
+Content-Type: text/plain
+
+12345"));
+                    sock.Write(ENC.GetBytes("67890"));
+                }
+                else if (str.Contains("33333"))
+                {
+                    sock.Write(ENC.GetBytes(@"HTTP/1.1 200 OK
+Content-Length: 20
+Content-Type: text/plain
+
+12345"));
+                    // Turning off Nagle didn't fix this.  Mrmph.
+                    Thread.Sleep(300);
+                    sock.Write(ENC.GetBytes("67890"));
+                    Thread.Sleep(300);
+                    sock.Write(ENC.GetBytes("12345"));
+                    Thread.Sleep(300);
+                    sock.Write(ENC.GetBytes("67890"));
+                }
+                return true;
+            }
+
+            public void OnWrite(BaseSocket sock, byte[] buf, int offset, int length)
+            {
+                Console.WriteLine("SW: " + ENC.GetString(buf, offset, length));
+            }
+
+            public bool OnInvalidCertificate(BaseSocket sock, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
+            {
+                throw new NotImplementedException("The method or operation is not implemented.");
+            }
+
+            #endregion
+        }
+
+        private class ResponseListener: ISocketEventListener
+        {
+            public string Last = null;
+            public AutoResetEvent Event = new AutoResetEvent(false);
+
+
+            #region ISocketEventListener Members
+
+            public void OnInit(BaseSocket newSock)
+            {
+            }
+
+            public ISocketEventListener GetListener(BaseSocket newSock)
+            {
+                throw new NotImplementedException("The method or operation is not implemented.");
+            }
+
+            public bool OnAccept(BaseSocket newsocket)
+            {
+                throw new NotImplementedException("The method or operation is not implemented.");
+            }
+
+            public void OnConnect(BaseSocket sock)
+            {
+            }
+
+            public void OnClose(BaseSocket sock)
+            {
+            }
+
+            public void OnError(BaseSocket sock, Exception ex)
+            {
+                throw ex;
+            }
+
+            public bool OnRead(BaseSocket sock, byte[] buf, int offset, int length)
+            {
+                Last = ENC.GetString(buf, offset, length);
+                Console.WriteLine("RR: " + Last);
+                Event.Set();
+                return true;
+            }
+
+            public void OnWrite(BaseSocket sock, byte[] buf, int offset, int length)
+            {
+                Console.WriteLine("RW: " + ENC.GetString(buf, offset, length));
+            }
+
+            public bool OnInvalidCertificate(BaseSocket sock, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
+            {
+                throw new NotImplementedException("The method or operation is not implemented.");
+            }
+
+            #endregion
+        }
+
+        [Test]
+        public void Test_Full_Response()
+        {
+            SocketWatcher watcher = new SocketWatcher();
+            Address a = new Address("127.0.0.1", 7002);
+            a.Resolve();
+
+            ServerListener server = new ServerListener();
+            AsyncSocket server_sock = watcher.CreateListenSocket(server, a);
+            server_sock.RequestAccept();
+
+            ResponseListener resp = new ResponseListener();
+            HttpSocket sock = new HttpSocket(resp);
+
+            Uri u = new Uri("http://localhost:7002/");
+            byte[] buf = ENC.GetBytes("11111");
+            HttpSocket s = (HttpSocket)sock;
+            s.Execute("GET", u, buf, 0, buf.Length, "text/plain");
+            resp.Event.WaitOne();
+            Assert.AreEqual("1234567890", resp.Last);
+
+            resp.Last = null;
+            buf = ENC.GetBytes("22222");
+            s.Execute("GET", u, buf, 0, buf.Length, "text/plain");
+            resp.Event.WaitOne();
+            Assert.AreEqual("1234567890", resp.Last);
+
+            resp.Last = null;
+            buf = ENC.GetBytes("33333");
+            s.Execute("GET", u, buf, 0, buf.Length, "text/plain");
+            resp.Event.WaitOne();
+            Assert.AreEqual("12345678901234567890", resp.Last);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/bedrock/net/HttpUploadTest.cs b/lib/jabber-net/test/bedrock/net/HttpUploadTest.cs
new file mode 100644
index 0000000..e902853
--- /dev/null
+++ b/lib/jabber-net/test/bedrock/net/HttpUploadTest.cs
@@ -0,0 +1,58 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Text;
+using System.IO;
+using System.Threading;
+
+using NUnit.Framework;
+using bedrock.util;
+using jabber.connection;
+
+namespace test.bedrock.net
+{
+    /// <summary>
+    /// TODO: This test is known to not work.  Add one that does, please.
+    /// </summary>
+    [TestFixture]
+    [SVN(@"$Id$")]
+    public class HttpUploadTest
+    {
+        private object m_lock = new object();
+
+        private void uploader_OnUpload(object sender)
+        {
+            lock(m_lock)
+            {
+                Monitor.Pulse(m_lock);
+            }
+        }
+
+        [Test]
+        public void UploadFile()
+        {
+            /*
+            m_lock = new object();
+
+            HttpUploader uploader = new HttpUploader();
+            uploader.OnUpload += new global::bedrock.ObjectHandler(uploader_OnUpload);
+            uploader.Upload("http://opodsadny.kiev.luxoft.com:7335/webclient", "les at primus.com/Bass", "upload.txt");
+            lock (m_lock)
+            {
+                Monitor.Wait(m_lock);
+            }
+             */
+        }
+    }
+}
diff --git a/lib/jabber-net/test/bedrock/net/SSLAsyncSocketTest.cs b/lib/jabber-net/test/bedrock/net/SSLAsyncSocketTest.cs
new file mode 100644
index 0000000..411cf92
--- /dev/null
+++ b/lib/jabber-net/test/bedrock/net/SSLAsyncSocketTest.cs
@@ -0,0 +1,218 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Threading;
+using NUnit.Framework;
+using bedrock.net;
+using bedrock.util;
+using System.Security.Cryptography.X509Certificates;
+
+namespace test.bedrock.net
+{
+    /// <summary>
+    ///  Not really async.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [Ignore("Fails due to certificate.")]
+    [TestFixture]
+    public class SSLAsyncSocketTest : ISocketEventListener
+    {
+        private static readonly System.Text.Encoding ENC = System.Text.Encoding.ASCII;
+
+        private static readonly byte[] sbuf = ENC.GetBytes("01234567890123456789012345678901234567890123456789012345678901234567890123456789");
+        private readonly object done = new object();
+        private readonly object start = new object();
+        private string success = null;
+        private AsyncSocket m_listen;
+        readonly Address a = new Address("localhost", 7003);
+
+        private bool succeeded = true;
+        private string errorMessage;
+
+        [Test] public void Test_Write()
+        {
+            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
+            a.Resolve();
+
+            lock(start)
+            {
+                new Thread(Server).Start();
+                Monitor.Wait(start);
+            }
+
+            try
+            {
+                lock (done)
+                {
+                    new Thread(Client).Start();
+                    Monitor.Wait(done);
+
+                    Assert.IsTrue(succeeded, errorMessage);
+                }
+            }
+            finally
+            {
+                m_listen.Close();
+            }
+
+            Assert.AreEqual("5678901234", success);
+        }
+
+        private void Client()
+        {
+
+            SocketWatcher c_w = new SocketWatcher(20);
+            c_w.Synchronous = true;
+
+            // Note: must have a client cert in your IE cert store.
+            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
+            store.Open(OpenFlags.ReadOnly);
+
+            if (store.Certificates.Count > 0)
+            {
+                c_w.LocalCertificate = store.Certificates[0];
+            }
+            else
+            {
+                lock (done)
+                {
+                    errorMessage = "There were no certificates in the Windows Certificate Store.";
+                    succeeded = false;
+                    Monitor.Pulse(done);
+                }
+
+                return;
+            }
+            c_w.CreateConnectSocket(this, a, true, "localhost");
+        }
+
+        private void Server()
+        {
+            SocketWatcher s_w = new SocketWatcher(20);
+
+            //s_w.RequireClientCert = true;
+
+            X509Certificate2 c2;
+            X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
+            store.Open(OpenFlags.ReadWrite);
+            X509Certificate2Collection cert = store.Certificates.Find(X509FindType.FindBySubjectName, "localhost", true);
+            if (cert.Count == 0)
+            {
+                c2 = new X509Certificate2("../../localhost-cert.p12", "test");
+                store.Add(c2);
+            }
+            else
+            {
+                c2 = cert[0];
+            }
+            Assert.IsTrue(c2.HasPrivateKey);
+            Assert.IsNotNull(c2.PrivateKey);
+            Assert.AreEqual(typeof(X509Certificate2), c2.GetType());
+
+            cert = store.Certificates.Find(X509FindType.FindByThumbprint, c2.GetCertHashString(), false);
+            c2 = cert[0];
+            Assert.AreEqual(typeof(X509Certificate2), c2.GetType());
+            Assert.IsTrue(c2.HasPrivateKey);
+            Assert.IsNotNull(c2.PrivateKey);
+            store.Close();
+            s_w.LocalCertificate = c2;
+            s_w.Synchronous = true;
+
+            m_listen = s_w.CreateListenSocket(this, a, true);
+            lock(start)
+            {
+                Monitor.Pulse(start);
+            }
+
+            try
+            {
+                m_listen.RequestAccept();
+            }
+            catch (Exception ex)
+            {
+                lock (done)
+                {
+                    succeeded = false;
+                    errorMessage = ex.Message;
+                    Monitor.Pulse(done);
+                }
+            }
+        }
+
+        #region Implementation of ISocketEventListener
+        public bool OnAccept(BaseSocket newsocket)
+        {
+            Assert.IsTrue(((AsyncSocket)newsocket).IsMutuallyAuthenticated);
+            newsocket.RequestRead();
+            return false;
+        }
+
+        public bool OnRead(BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            success = ENC.GetString(buf, offset, length);
+            lock(done)
+            {
+                Monitor.Pulse(done);
+            }
+            return false;
+        }
+
+        public void OnWrite(BaseSocket sock, byte[] buf, int offset, int length)
+        {
+            System.Diagnostics.Debug.WriteLine(ENC.GetString(buf, offset, length));
+            sock.Close();
+        }
+
+        public void OnError(BaseSocket sock, Exception ex)
+        {
+
+        }
+
+        public void OnConnect(BaseSocket sock)
+        {
+            sock.Write(sbuf, 5, 10);
+        }
+
+        public void OnClose(BaseSocket sock)
+        {
+
+        }
+
+        public void OnInit(BaseSocket new_sock)
+        {
+
+        }
+
+        public ISocketEventListener GetListener(BaseSocket new_sock)
+        {
+            return this;
+        }
+
+        public bool OnInvalidCertificate(BaseSocket sock,
+            System.Security.Cryptography.X509Certificates.X509Certificate certificate,
+            System.Security.Cryptography.X509Certificates.X509Chain chain,
+            System.Net.Security.SslPolicyErrors sslPolicyErrors)
+        {
+            return true;
+        }
+
+        #endregion
+
+        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
+        {
+            System.Diagnostics.Debug.WriteLine(e.ExceptionObject.ToString());
+        }
+    }
+}
diff --git a/lib/jabber-net/test/bedrock/util/GetOptBaseTest.cs b/lib/jabber-net/test/bedrock/util/GetOptBaseTest.cs
new file mode 100644
index 0000000..8891d71
--- /dev/null
+++ b/lib/jabber-net/test/bedrock/util/GetOptBaseTest.cs
@@ -0,0 +1,323 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using NUnit.Framework;
+using bedrock.util;
+namespace test.bedrock.util
+{
+    /// <summary>
+    ///    Summary description for GetOptBaseTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class GetOptTest
+    {
+        [Test] public void Test_Construct()
+        {
+            TestGetOpt t = new TestGetOpt(new string[] {"/f", "/bar", "baz"});
+            Assert.AreEqual(true, t.foo);
+            Assert.AreEqual("baz", t.bar);
+        }
+        [Test] public void Test_Usage()
+        {
+            TestGetOpt t = new TestGetOpt();
+            Console.WriteLine(t.Usage);
+        }
+        [Test] public void Test_Int()
+        {
+            TestGetOpt t = new TestGetOpt(new string[] {"/some", "1", "/other", "2", "blah"});
+            Assert.AreEqual(1, t.iSome);
+            Assert.AreEqual(2, t.other);
+            Assert.AreEqual("one", t.bar);
+        }
+        [Test] public void Test_Private()
+        {
+            // hrmph.  This should probably throw an error, if I don't have the right permissions.
+            TestGetOpt t = new TestGetOpt(new string[] {"/private", "one"});
+            Assert.AreEqual("one", t.baz);
+        }
+        [Test] public void Test_Args()
+        {
+            TestGetOpt t = new TestGetOpt(new string[] {"/some", "1", "/other", "2", "blah", "bloo", "boo"});
+            Assert.AreEqual(3, t.Args.Length);
+            Assert.AreEqual("blah", t.Args[0]);
+            Assert.AreEqual("bloo", t.Args[1]);
+            Assert.AreEqual("boo", t.Args[2]);
+        }
+        [Test] public void Test_Colon()
+        {
+            TestGetOpt t = new TestGetOpt(new string[] {"/some:1", "/other:2", "blah", "bloo", "boo"});
+            Assert.AreEqual(1, t.iSome);
+            Assert.AreEqual(2, t.other);
+            Assert.AreEqual(3, t.Args.Length);
+        }
+        [Test] public void Test_Bool()
+        {
+            TestGetOpt go = new TestGetOpt(new string[] {"/a", "/b", "four", "one", "more"});
+            Assert.AreEqual(true,   go.a);
+            Assert.AreEqual(false,  go.b);
+            Assert.AreEqual(false,  go.c);
+            Assert.AreEqual(true,   go.d);
+            Assert.AreEqual(3,      go.Args.Length);
+            Assert.AreEqual("four", go.Args[0]);
+            Assert.AreEqual("one",  go.Args[1]);
+            Assert.AreEqual("more", go.Args[2]);
+        }
+        [Test] public void Test_DashBool()
+        {
+            TestGetOpt go = new TestGetOpt(new string[] {"-a", "-b", "four", "one", "more"});
+            Assert.AreEqual(true,   go.a);
+            Assert.AreEqual(false,  go.b);
+            Assert.AreEqual(false,  go.c);
+            Assert.AreEqual(true,   go.d);
+            Assert.AreEqual(3,      go.Args.Length);
+            Assert.AreEqual("four", go.Args[0]);
+            Assert.AreEqual("one",  go.Args[1]);
+            Assert.AreEqual("more", go.Args[2]);
+        }
+
+        [Test] public void Test_DashArgs()
+        {
+            TestGetOpt go = new TestGetOpt(new string[] {"-bar", "four", "-baz:one", "more"});
+            Assert.AreEqual("four", go.bar);
+            Assert.AreEqual("one",  go.baz);
+            Assert.AreEqual(null,   go.e);
+            Assert.AreEqual(1,      go.Args.Length);
+            Assert.AreEqual("more", go.Args[0]);
+        }
+
+        [Test] public void Test_Env()
+        {
+            TestGetOpt go = new TestGetOpt(null);
+
+            Assert.IsTrue(go.Args[0].StartsWith("test"));
+        }
+        [Test] public void Test_CaseInsensitive()
+        {
+            TestGetOpt go = new TestGetOpt(new string[] {"-BaZ:boo"});
+            Assert.AreEqual("boo", go.baz);
+        }
+        [Test] public void Test_Equals()
+        {
+            TestGetOpt go = new TestGetOpt(new string[] {"-baz=boo"});
+            Assert.AreEqual("boo", go.baz);
+        }
+        [Test] public void Test_DoubleColon()
+        {
+            TestGetOpt go = new TestGetOpt(new string[] {"/baz:boo:bar"});
+            Assert.AreEqual("boo:bar", go.baz);
+        }
+        [Test] public void Test_DoubleSlash()
+        {
+            TestGetOpt go = new TestGetOpt(new string[] {"/baz:boo/bar"});
+            Assert.AreEqual("boo/bar", go.baz);
+        }
+        [Test] public void Test_NunitProblem()
+        {
+            TestGetOpt go = new TestGetOpt(new string[] {@"/assembly:test.dll"});
+            Assert.AreEqual(@"test.dll", go.assembly);
+        }
+        [Test] public void Test_Enum()
+        {
+            TestGetOpt go = new TestGetOpt(new string[] {"-fb:bar"});
+            Assert.AreEqual(TestOptEnum.BAR, go.fb);
+        }
+        [Test] public void Test_Method()
+        {
+            TestGetOpt go = new TestGetOpt(new string[] {"-method"});
+            Assert.AreEqual("after", go.m);
+        }
+        [Test] public void Test_MethodParam()
+        {
+            TestGetOpt go = new TestGetOpt(new string[] {"-methodparam", "2"});
+            Assert.AreEqual(2, go.mp);
+            go = new TestGetOpt(new string[] {"-methodparams", "2", "after"});
+            Assert.AreEqual(2, go.m2);
+            Assert.AreEqual("after", go.mp2);
+        }
+        [Test] public void Test_NonChild()
+        {
+            NonChild nc = new NonChild();
+            GetOpt go = new GetOpt(nc);
+            go.Process(new string[] {"-test", "foo"});
+            Assert.AreEqual("foo", nc.test);
+        }
+        [Test] public void Test_Indexer()
+        {
+            NonChild nc = new NonChild();
+            GetOpt go = new GetOpt(nc);
+            go["test"] = "foo";
+            Assert.AreEqual("foo", nc.test);
+        }
+        [ExpectedException(typeof(FormatException))]
+        [Test] public void Test_BadInt()
+        {
+            TestGetOpt t = new TestGetOpt(new string[] {"/some", "one"});
+        }
+        [ExpectedException(typeof(ArgumentException))]
+        [Test] public void Test_Error()
+        {
+            TestGetOpt go = new TestGetOpt(new string[] {"/broncos"});
+        }
+        [ExpectedException(typeof(ArgumentException))]
+        [Test] public void Test_DashError()
+        {
+            TestGetOpt go = new TestGetOpt(new string[] {"-broncos"});
+        }
+        [ExpectedException(typeof(IndexOutOfRangeException))]
+        [Test] public void Test_InsufficientError()
+        {
+            TestGetOpt go = new TestGetOpt(new string[] {"/some"});
+        }
+        [ExpectedException(typeof(IndexOutOfRangeException))]
+        [Test] public void Test_DashInsufficientError()
+        {
+            TestGetOpt go = new TestGetOpt(new string[] {"-some"});
+        }
+        [ExpectedException(typeof(ArgumentException))]
+        [Test] public void Test_BadRequired()
+        {
+            BadOpt bo = new BadOpt();
+            bo.Process(new string[] {});
+        }
+        [Test] public void Test_Required()
+        {
+            ReqOpt bo = new ReqOpt(new string[] {"/req:here"});
+            Assert.AreEqual("here", bo.Req);
+        }
+        [ExpectedException(typeof(ArgumentException))]
+        [Test] public void Test_RequiredNotPassed()
+        {
+            ReqOpt bo = new ReqOpt(new string[] {});
+        }
+        [ExpectedException(typeof(IndexOutOfRangeException))]
+        [Test] public void Test_MethodNotEnoughParams()
+        {
+            TestGetOpt go = new TestGetOpt(new string[] {"-methodparams", "2"});
+        }
+    }
+    public enum TestOptEnum
+    {
+        FOO,
+        BAR
+    }
+
+    [SVN(@"$Id$")]
+    public class TestGetOpt : GetOpt
+    {
+        [CommandLine("nologo", Description="Command line argument for NUnit.")]
+        public bool nologo = false;
+        [CommandLine("f", Description = "Foo or not")]
+        public bool foo = false;
+        [CommandLine(Description = "What's in a bar?")]
+        public string bar = "one";
+        [CommandLine("private")]
+        private string m_baz = "default";
+        [CommandLine("baz", "A property test")]
+        public string baz
+        {
+            get
+            {
+                return m_baz;
+            }
+            set
+            {
+                m_baz = value;
+            }
+        }
+        public int iNone;
+        [CommandLine("some", Description = "Integer param")]
+        public int iSome = 0;
+        private int m_other = 3;
+        [CommandLine]
+        public int other
+        {
+            get
+            {
+                return m_other;
+            }
+            set
+            {
+                m_other = value;
+            }
+        }
+        [CommandLine]
+        public bool a = false;
+        [CommandLine]
+        public bool b = true;
+        [CommandLine]
+        public bool c = false;
+        [CommandLine]
+        public bool d = true;
+        [CommandLine]
+        public string e = null;
+
+        [CommandLine]
+        public TestOptEnum fb = TestOptEnum.FOO;
+
+        [CommandLine]
+        public string assembly;
+
+        public string m = "before";
+        public int mp = -1;
+
+        public int m2 = -1;
+        public string mp2 = "before";
+
+        [CommandLine]
+        public void method()
+        {
+            m = "after";
+        }
+        [CommandLine]
+        public void methodparam(int one)
+        {
+            mp = one;
+        }
+        [CommandLine]
+        public void methodparams(int one, string two)
+        {
+            m2 = one;
+            mp2 = two;
+        }
+        public TestGetOpt() : base() {}
+        public TestGetOpt(string[] args) : base(args) {}
+    }
+    public class  BadOpt : GetOpt
+    {
+        [CommandLine("bad", "A required parameter", true)]
+        public string Bad = "Bad";
+        public BadOpt() : base() {}
+        public BadOpt(string[] args) : base(args) {}
+    }
+    public class  ReqOpt : GetOpt
+    {
+        [CommandLine(Required = true)]
+        public string Req = null;
+        public ReqOpt() : base() {}
+        public ReqOpt(string[] args) : base(args) {}
+    }
+    public class NonChild
+    {
+        [CommandLine]
+        public string test = null;
+    }
+    public class TooManyParams : GetOpt
+    {
+        public int mp = -1;
+        public TooManyParams() : base() {}
+        public TooManyParams(string[] args) : base(args) {}
+    }
+}
diff --git a/lib/jabber-net/test/bedrock/util/VersionTest.cs b/lib/jabber-net/test/bedrock/util/VersionTest.cs
new file mode 100644
index 0000000..e454c37
--- /dev/null
+++ b/lib/jabber-net/test/bedrock/util/VersionTest.cs
@@ -0,0 +1,161 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using NUnit.Framework;
+using bedrock.util;
+namespace test.bedrock.util
+{
+    /// <summary>
+    ///    Summary description for AssemblyXMLTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class VersionTest
+    {
+        [StarTeam("$" + "Header" + "$")]
+            private class vFoo
+        {
+
+        }
+        [StarTeam(Archive="$" + @"Header: C:\Prj\Dognapper\Microsoft\Common\src\com.ilg.Util\Test\VersionTest.cs" + "$",
+             Author="$" + "Author: Joe Hildebrand" + "$",
+             DateString="02/12/2001 6:25:04 PM",
+             Revision="1")]
+            private class vInd
+        {
+
+        }
+        [StarTeam("$" + @"Header: C:\Prj\Dognapper\Microsoft\Common\src\com.ilg.Util\Test\VersionTest.cs, 1.11, 02/12/2001 6:25:04 PM, Joe Hildebrand" + "$")]
+            private class vBar
+        {
+
+        }
+        [StarTeam("$" + @"Header: C:\Prj\Dognapper\Microsoft\Common\src\com.ilg.Util\Test\VersionTest.cs, 11, 02/12/2001 6:25:04 PM, Joe Hildebrand" + "$")]
+            private class vBaz
+        {
+
+        }
+        [RCS("$" + @"Header: /u1/html/cvsroot/www.cyclic.com/RCS-html/info-ref.html,v 1.1 2001/02/12 18:25:04 kingdon Exp " + "$")]
+            private class RCSVer
+        {
+
+        }
+        [SourceSafe("$" + @"Header: /t.cs 1     2/12/01 6:25p Hildebzj " + "$")]
+            private class VssVer
+        {
+
+        }
+
+        [SVN("$" + @"Id: calc.c 148 2002-07-28 21:30:43Z sally " + "$")]
+        private class SvnVer
+        {
+
+        }
+
+
+        [Test] public void Test_Empty()
+        {
+            SourceVersionAttribute foo = SourceVersionAttribute.GetVersion(typeof(vFoo));
+            Assert.AreEqual(null,               foo.Revision, "Revision");
+            Assert.AreEqual(DateTime.MinValue,  foo.Date,     "Date");
+            Assert.AreEqual(null,               foo.Author,   "Date");
+            Assert.AreEqual(null,               foo.Version,  "Version");
+            Assert.AreEqual(null,               foo.Archive,  "Archive");
+        }
+        [Test] public void Test_Full()
+        {
+            SourceVersionAttribute bar = SourceVersionAttribute.GetVersion(typeof(vBar));
+            Assert.AreEqual("1.11",             bar.Revision);
+            Assert.AreEqual(
+                new DateTime(2001, 2, 12, 18, 25, 4),
+                bar.Date);
+            Assert.AreEqual("Joe Hildebrand",   bar.Author);
+            Assert.AreEqual(new Version(1, 11), bar.Version);
+            Assert.AreEqual(@"C:\Prj\Dognapper\Microsoft\Common\src\com.ilg.Util\Test\VersionTest.cs", bar.Archive);
+        }
+        [Test] public void Test_Ind()
+        {
+            SourceVersionAttribute ind = SourceVersionAttribute.GetVersion(typeof(vInd));
+            Assert.AreEqual(
+                "$" + @"Header: C:\Prj\Dognapper\Microsoft\Common\src\com.ilg.Util\Test\VersionTest.cs, 1, 02/12/2001 6:25:04 PM, Joe Hildebrand" + "$",
+                ind.ToString());
+        }
+        [Test] public void Test_PlainRev()
+        {
+            SourceVersionAttribute baz = SourceVersionAttribute.GetVersion(typeof(vBaz));
+            Assert.AreEqual("11",               baz.Revision);
+            Assert.AreEqual(
+                new DateTime(2001, 2, 12, 18, 25, 4),
+                baz.Date);
+            Assert.AreEqual("Joe Hildebrand",   baz.Author);
+            Assert.AreEqual(new Version(1, 11), baz.Version);
+            Assert.AreEqual(@"C:\Prj\Dognapper\Microsoft\Common\src\com.ilg.Util\Test\VersionTest.cs", baz.Archive);
+        }
+        [Test] public void Test_RCS()
+        {
+            RCSAttribute c = (RCSAttribute) SourceVersionAttribute.GetVersion(typeof(RCSVer));
+            Assert.AreEqual("1.1",               c.Revision);
+            Assert.AreEqual(
+                new DateTime(2001, 2, 12, 18, 25, 4),
+                c.Date);
+            Assert.AreEqual("kingdon",           c.Author);
+            Assert.AreEqual(new Version(1, 1),   c.Version);
+            Assert.AreEqual(@"/u1/html/cvsroot/www.cyclic.com/RCS-html/info-ref.html,v", c.Archive);
+            Assert.AreEqual("Exp",               c.State);
+        }
+        [Test] public void Test_VSS()
+        {
+            SourceSafeAttribute c = (SourceSafeAttribute) SourceVersionAttribute.GetVersion(typeof(VssVer));
+            Assert.AreEqual("1",                 c.Revision);
+            Assert.AreEqual(
+                new DateTime(2001, 2, 12, 18, 25, 0),
+                c.Date);
+            Assert.AreEqual("Hildebzj",          c.Author);
+            Assert.AreEqual(new Version(1, 1),   c.Version);
+            Assert.AreEqual(@"/t.cs",            c.Archive);
+        }
+
+        [Test] public void Test_GetAll()
+        {
+            SourceVersionCollection tv = SourceVersionAttribute.GetVersion();
+            Assert.IsTrue(tv["test.bedrock.util.VersionTest+vFoo"]   != null);
+            Assert.IsTrue(tv[typeof(vBar).FullName]   != null);
+            Assert.IsTrue(tv[typeof(vBaz)]   != null);
+            Assert.IsTrue(tv["test.bedrock.util.VersionTest+RCSVer"] != null);
+            Assert.IsTrue(tv["test.bedrock.util.VersionTest+VssVer"] != null);
+            Assert.IsTrue(tv["test.bedrock.util.VersionTest+SvnVer"] != null);
+            Assert.IsTrue(tv["test.bedrock.util.VersionTest+vBax"]   == null);
+            foreach (string c in tv)
+            {
+                //Console.WriteLine("<{0}>", c);
+                Assert.IsTrue(tv[c] != null);
+            }
+        }
+
+        [Test]
+        public void Test_SVN()
+        {
+            SVNAttribute c = (SVNAttribute)SourceVersionAttribute.GetVersion(typeof(SvnVer));
+            Assert.AreEqual("148", c.Revision);
+            Assert.AreEqual(
+                new DateTime(2002, 7, 28, 21, 30, 43),
+                c.Date);
+            Assert.AreEqual("sally", c.Author);
+            Assert.AreEqual(new Version(1, 148), c.Version);
+            Assert.AreEqual(@"calc.c", c.Archive);
+        }
+
+    }
+}
diff --git a/lib/jabber-net/test/jabber/JIDTest.cs b/lib/jabber-net/test/jabber/JIDTest.cs
new file mode 100644
index 0000000..fb186b0
--- /dev/null
+++ b/lib/jabber-net/test/jabber/JIDTest.cs
@@ -0,0 +1,367 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using bedrock.util;
+using NUnit.Framework;
+using je = jabber.JIDFormatException;
+using jabber;
+
+namespace test.jabber
+{
+    /// <summary>
+    /// Summary description for JIDTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class JIDTest
+    {
+        [Test] public void Test_Create()
+        {
+            JID j = new JID("foo", "jabber.com", "there");
+            Assert.AreEqual("foo at jabber.com/there", j.ToString());
+            j = new JID(null, "jabber.com", null);
+            Assert.AreEqual("jabber.com", j.ToString());
+            j = new JID("foo", "jabber.com", null);
+            Assert.AreEqual("foo at jabber.com", j.ToString());
+            j = new JID(null, "jabber.com", "there");
+            Assert.AreEqual("jabber.com/there", j.ToString());
+        }
+        [Test] public void Test_Parse_1()
+        {
+            JID j = new JID("foo");
+            Assert.AreEqual(null, j.User);
+            Assert.AreEqual("foo", j.Server);
+            Assert.AreEqual(null, j.Resource);
+        }
+        [Test] public void Test_Parse_2()
+        {
+            JID j = new JID("foo/bar");
+            Assert.AreEqual(null, j.User);
+            Assert.AreEqual("foo", j.Server);
+            Assert.AreEqual("bar", j.Resource);
+        }
+        [Test] public void Test_Parse_3()
+        {
+            JID j = new JID("boo at foo");
+            Assert.AreEqual("boo", j.User);
+            Assert.AreEqual("foo", j.Server);
+            Assert.AreEqual(null, j.Resource);
+        }
+        [Test] public void Test_Parse_4()
+        {
+            JID j = new JID("boo at foo/bar");
+            Assert.AreEqual("boo", j.User);
+            Assert.AreEqual("foo", j.Server);
+            Assert.AreEqual("bar", j.Resource);
+        }
+        [Test] public void Test_Parse_5()
+        {
+            JID j = new JID("foo/bar at baz");
+            Assert.AreEqual(null, j.User);
+            Assert.AreEqual("foo", j.Server);
+            Assert.AreEqual("bar at baz", j.Resource);
+        }
+        [Test] public void Test_Parse_6()
+        {
+            JID j = new JID("boo at foo/bar at baz");
+            Assert.AreEqual("boo", j.User);
+            Assert.AreEqual("foo", j.Server);
+            Assert.AreEqual("bar at baz", j.Resource);
+        }
+        [Test] public void Test_Parse_7()
+        {
+            JID j = new JID("boo at foo/bar/baz");
+            Assert.AreEqual("boo", j.User);
+            Assert.AreEqual("foo", j.Server);
+            Assert.AreEqual("bar/baz", j.Resource);
+        }
+        [Test] public void Test_Parse_8()
+        {
+            JID j = new JID("boo/foo at bar@baz");
+            Assert.AreEqual(null, j.User);
+            Assert.AreEqual("boo", j.Server);
+            Assert.AreEqual("foo at bar@baz", j.Resource);
+        }
+        [Test] public void Test_Parse_9()
+        {
+            JID j = new JID("boo/foo at bar");
+            Assert.AreEqual(null, j.User);
+            Assert.AreEqual("boo", j.Server);
+            Assert.AreEqual("foo at bar", j.Resource);
+        }
+        [Test] public void Test_Parse_10()
+        {
+            JID j = new JID("boo/foo/bar");
+            Assert.AreEqual(null, j.User);
+            Assert.AreEqual("boo", j.Server);
+            Assert.AreEqual("foo/bar", j.Resource);
+        }
+        [Test] public void Test_Parse_11()
+        {
+            JID j = new JID("boo//foo");
+            Assert.AreEqual(null, j.User);
+            Assert.AreEqual("boo", j.Server);
+            Assert.AreEqual("/foo", j.Resource);
+        }
+        [Test] public void Test_EmptyResource()
+        {
+            try
+            {
+                JID j = new JID("boo/");
+                string u = j.User;
+                Assert.IsTrue(false);
+            }
+            catch (JIDFormatException)
+            {
+                Assert.IsTrue(true);
+            }
+            catch (Exception)
+            {
+                Assert.IsTrue(false);
+            }
+        }
+        [Test] public void Test_EmptyResourceUser()
+        {
+            try
+            {
+                JID j = new JID("boo at foo/");
+                string u = j.User;
+                Assert.IsTrue(false);
+            }
+            catch (JIDFormatException)
+            {
+                Assert.IsTrue(true);
+            }
+            catch (Exception)
+            {
+                Assert.IsTrue(false);
+            }
+        }
+
+        [Test] public void Test_NoHost()
+        {
+            try
+            {
+                JID j = new JID("foo@");
+                string u = j.User;
+                Assert.IsTrue(false);
+            }
+            catch (JIDFormatException)
+            {
+                Assert.IsTrue(true);
+            }
+            catch (Exception)
+            {
+                Assert.IsTrue(false);
+            }
+        }
+        [Test] public void Test_AtAt()
+        {
+            try
+            {
+                JID j = new JID("boo@@foo");
+                string u = j.User;
+                Assert.IsTrue(false);
+            }
+            catch (JIDFormatException)
+            {
+                Assert.IsTrue(true);
+            }
+            catch (Exception)
+            {
+                Assert.IsTrue(false);
+            }
+        }
+        [Test] public void Test_TwoAt()
+        {
+            try
+            {
+                JID j = new JID("boo at foo@bar");
+                string u = j.User;
+                Assert.IsTrue(false);
+            }
+            catch (JIDFormatException)
+            {
+                Assert.IsTrue(true);
+            }
+            catch (Exception)
+            {
+                Assert.IsTrue(false);
+            }
+        }
+        [Test] public void Test_Compare_Equal()
+        {
+            JID j = new JID("foo at bar/baz");
+            Assert.AreEqual(0, j.CompareTo(j));
+            Assert.AreEqual(0, j.CompareTo(new JID("foo at bar/baz")));
+            j = new JID("foo at bar");
+            Assert.AreEqual(0, j.CompareTo(j));
+            Assert.AreEqual(0, j.CompareTo(new JID("foo at bar")));
+            Assert.IsTrue(j == new JID("foo at bar"));
+            Assert.IsTrue(j == new JID("foo at BAR"));
+            Assert.IsTrue(j == new JID("FOO at BAR"));
+            Assert.IsTrue(j == new JID("FOO at bar"));
+            Assert.AreEqual(new JID("FOO at bar").GetHashCode(), j.GetHashCode());
+            j = new JID("bar");
+            Assert.AreEqual(0, j.CompareTo(j));
+            Assert.AreEqual(0, j.CompareTo(new JID("bar")));
+            j = new JID("foo/bar");
+            Assert.AreEqual(0, j.CompareTo(j));
+            Assert.AreEqual(0, j.CompareTo(new JID("foo/bar")));
+            Assert.AreEqual(true, j >= new JID("foo/bar"));
+            Assert.AreEqual(true, j <= new JID("foo/bar"));
+        }
+        [Test] public void Test_Compare_Less()
+        {
+            JID j = new JID("foo at bar/baz");
+            Assert.AreEqual(-1, j.CompareTo(new JID("foo at bas/baz")));
+            Assert.AreEqual(-1, j.CompareTo(new JID("fop at bar/baz")));
+            Assert.AreEqual(-1, j.CompareTo(new JID("foo at bar/bazz")));
+            j = new JID("foo at bar");
+            Assert.AreEqual(-1, j.CompareTo(new JID("foo at bas/baz")));
+            Assert.AreEqual(-1, j.CompareTo(new JID("foo at bas")));
+            Assert.AreEqual(-1, j.CompareTo(new JID("fop at bar/baz")));
+            Assert.AreEqual(-1, j.CompareTo(new JID("fop at bar")));
+            Assert.AreEqual(-1, j.CompareTo(new JID("foo at bar/baz")));
+            j = new JID("bar");
+            Assert.AreEqual(-1, j.CompareTo(new JID("foo at bar/baz")));
+            Assert.AreEqual(-1, j.CompareTo(new JID("foo at bar")));
+            Assert.AreEqual(-1, j.CompareTo(new JID("bas")));
+            Assert.AreEqual(-1, j.CompareTo(new JID("bas/baz")));
+            Assert.AreEqual(-1, j.CompareTo(new JID("bar/baz")));
+            Assert.AreEqual(true, j < new JID("foo at bar/baz"));
+            Assert.AreEqual(true, j <= new JID("foo at bar/baz"));
+        }
+        [Test] public void Test_Compare_Greater()
+        {
+            JID j = new JID("foo at bar/baz");
+            Assert.AreEqual(1, j.CompareTo(new JID("foo at bap/baz")));
+            Assert.AreEqual(1, j.CompareTo(new JID("fon at bar/baz")));
+            Assert.AreEqual(1, j.CompareTo(new JID("foo at bar/bay")));
+            Assert.AreEqual(1, j.CompareTo(new JID("foo at bar")));
+            Assert.AreEqual(1, j.CompareTo(new JID("bar")));
+            Assert.AreEqual(1, j.CompareTo(new JID("bar/baz")));
+            j = new JID("foo at bar");
+            Assert.AreEqual(1, j.CompareTo(new JID("foo at bap/baz")));
+            Assert.AreEqual(1, j.CompareTo(new JID("fon at bar/baz")));
+            Assert.AreEqual(1, j.CompareTo(new JID("bar")));
+            Assert.AreEqual(1, j.CompareTo(new JID("bar/baz")));
+            Assert.AreEqual(true, j > new JID("foo at bap/baz"));
+            Assert.AreEqual(true, j >= new JID("foo at bap/baz"));
+            // /me runs out of interest.
+        }
+        [Test] public void Test_BadCompare()
+        {
+            try
+            {
+                JID j = new JID("foo at boo/bar");
+                j.CompareTo("foo at boo/bar");
+                Assert.IsTrue(false);
+            }
+            catch (ArgumentException)
+            {
+                Assert.IsTrue(true);
+            }
+            catch (Exception)
+            {
+                Assert.IsTrue(false);
+            }
+        }
+        [Test] public void Test_Insensitive()
+        {
+            JID j = new JID("foo at boo/bar");
+            Assert.AreEqual(0, j.CompareTo(new JID("foo at BOO/bar")));
+            Assert.AreEqual(0, j.CompareTo(new JID("FOO at boo/bar")));
+            Assert.AreEqual(0, j.CompareTo(new JID("FOO at BOO/bar")));
+            Assert.AreEqual(-1, j.CompareTo(new JID("FOO at BOO/BAR")));
+        }
+
+        [Test] public void Test_Config()
+        {
+            JID j = new JID("config at -internal");
+            Assert.AreEqual("config", j.User);
+            Assert.AreEqual("-internal", j.Server);
+            Assert.AreEqual(null, j.Resource);
+        }
+
+        [Test] public void Test_Numeric()
+        {
+            JID j = new JID("support", "conference.192.168.32.109", "bob");
+            Assert.AreEqual("conference.192.168.32.109", j.Server);
+        }
+
+        [Test]
+        public void Test_Escape()
+        {
+            JID j = JID.Escape("d'artagnan", "gascon.fr", "elder");
+            Assert.AreEqual(@"d\27artagnan at gascon.fr/elder", j.ToString());
+            j = JID.Escape("space cadet", "example.com", null);
+            Assert.AreEqual(@"space\20cadet at example.com", j.ToString());
+            j = JID.Escape("call me \"ishmael\"", "example.com", null);
+            Assert.AreEqual(@"call\20me\20\22ishmael\22 at example.com", j.ToString());
+            j = JID.Escape("at&t guy", "example.com", null);
+            Assert.AreEqual(@"at\26t\20guy at example.com", j.ToString());
+            j = JID.Escape("/.fanboy", "example.com", null);
+            Assert.AreEqual(@"\2f.fanboy at example.com", j.ToString());
+            j = JID.Escape("::foo::", "example.com", null);
+            Assert.AreEqual(@"\3a\3afoo\3a\3a at example.com", j.ToString());
+            j = JID.Escape("<foo>", "example.com", null);
+            Assert.AreEqual(@"\3cfoo\3e at example.com", j.ToString());
+            j = JID.Escape("user at host", "example.com", null);
+            Assert.AreEqual(@"user\40host at example.com", j.ToString());
+            j = JID.Escape(@"c:\net", "example.com", null);
+            Assert.AreEqual(@"c\3a\5cnet at example.com", j.ToString());
+            j = JID.Escape(@"c:\\net", "example.com", null);
+            Assert.AreEqual(@"c\3a\5c\5cnet at example.com", j.ToString());
+            j = JID.Escape(@"c:\cool stuff", "example.com", null);
+            Assert.AreEqual(@"c\3a\5ccool\20stuff at example.com", j.ToString());
+            j = JID.Escape(@"c:\5commas", "example.com", null);
+            Assert.AreEqual(@"c\3a\5c5commas at example.com", j.ToString());
+        }
+
+        [Test]
+        public void Test_Unescape()
+        {
+            string u = new JID(@"d\27artagnan at gascon.fr/elder").Unescape();
+            Assert.AreEqual("d'artagnan", u);
+            u = new JID(@"space\20cadet at example.com").Unescape();
+            Assert.AreEqual("space cadet", u);
+            u = new JID(@"call\20me\20\22ishmael\22 at example.com").Unescape();
+            Assert.AreEqual("call me \"ishmael\"", u);
+            u = new JID(@"at\26t\20guy at example.com").Unescape();
+            Assert.AreEqual("at&t guy", u);
+            u = new JID(@"\2f.fanboy at example.com").Unescape();
+            Assert.AreEqual("/.fanboy", u);
+            u = new JID(@"\3a\3afoo\3a\3a at example.com").Unescape();
+            Assert.AreEqual("::foo::", u);
+            u = new JID(@"\3cfoo\3e at example.com").Unescape();
+            Assert.AreEqual("<foo>", u);
+            u = new JID(@"user\40host at example.com").Unescape();
+            Assert.AreEqual("user at host", u);
+            u = new JID(@"c\3a\5cnet at example.com").Unescape();
+            Assert.AreEqual(@"c:\net", u);
+            u = new JID(@"c\3a\5c\5cnet at example.com").Unescape();
+            Assert.AreEqual(@"c:\\net", u);
+            u = new JID(@"c\3a\5ccool\20stuff at example.com").Unescape();
+            Assert.AreEqual(@"c:\cool stuff", u);
+            u = new JID(@"c\3a\5c5commas at example.com").Unescape();
+            Assert.AreEqual(@"c:\5commas", u);
+            u = new JID(@"\c0 at example.com").Unescape();
+            Assert.AreEqual(@"\c0", u);
+            u = new JID(@"\30 at example.com").Unescape();
+            Assert.AreEqual(@"\30", u);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/client/PresenceManagerTest.cs b/lib/jabber-net/test/jabber/client/PresenceManagerTest.cs
new file mode 100644
index 0000000..ecff110
--- /dev/null
+++ b/lib/jabber-net/test/jabber/client/PresenceManagerTest.cs
@@ -0,0 +1,295 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber;
+using jabber.client;
+using jabber.protocol.client;
+using jabber.protocol.x;
+using jabber.connection;
+using jabber.protocol;
+using bedrock.collections;
+using jabber.protocol.iq;
+
+namespace test.jabber.client1 // TODO: Client1 due to a bug in NUnit.
+{
+    /// <summary>
+    /// Summary description for PPDP.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class PresenceManagerTest
+    {
+        XmlDocument doc = new XmlDocument();
+
+        JID bare = "foo at bar";
+        JID baz  = "foo at bar/baz";
+        JID boo  = "foo at bar/boo";
+
+
+        [Test]
+        public void Test_Create()
+        {
+            PresenceManager pp = new PresenceManager();
+            Assert.AreEqual("jabber.client.PresenceManager", pp.GetType().FullName);
+        }
+        [Test]
+        public void TestAdd()
+        {
+            PresenceManager pp = new PresenceManager();
+            Presence pres = new Presence(doc);
+            JID f = new JID("foo", "bar", "baz");
+            pres.From = f;
+            pp.AddPresence(pres);
+            Assert.AreEqual("foo at bar/baz", pp[f].From.ToString());
+            f.Resource = null;
+            Assert.AreEqual("foo at bar/baz", pp[f].From.ToString());
+
+            pres = new Presence(doc);
+            pres.Status = "wandering";
+            pres.From = new JID("foo", "bar", "baz");
+            pp.AddPresence(pres);
+            Assert.AreEqual("wandering", pp[f].Status);
+        }
+        [Test]
+        public void TestRetrieve()
+        {
+            PresenceManager pp = new PresenceManager();
+            Presence pres = new Presence(doc);
+            JID f = new JID("foo", "bar", "baz");
+            pres.From = f;
+            pres.Priority = "0";
+            pp.AddPresence(pres);
+            Assert.AreEqual("foo at bar/baz", pp[f.Bare].From.ToString());
+
+            pres = new Presence(doc);
+            f = new JID("foo", "bar", "bay");
+            pres.From = f;
+            pres.Priority = "1";
+            pp.AddPresence(pres);
+            Assert.AreEqual("foo at bar/bay", pp[f.Bare].From.ToString());
+
+            pres = new Presence(doc);
+            pres.From = f;
+            pres.Type = PresenceType.unavailable;
+            pp.AddPresence(pres);
+            Assert.AreEqual("foo at bar/baz", pp[f.Bare].From.ToString());
+        }
+        [Test]
+        public void TestUserHost()
+        {
+            PresenceManager pp = new PresenceManager();
+            Presence pres = new Presence(doc);
+            JID f = new JID("foo", "bar", null);
+            pres.From = f;
+            pp.AddPresence(pres);
+            Assert.AreEqual("foo at bar", pp[f.Bare].From.ToString());
+        }
+        [Test]
+        public void TestHost()
+        {
+            PresenceManager pp = new PresenceManager();
+            Presence pres = new Presence(doc);
+            JID f = new JID("bar");
+            pres.From = f;
+            pp.AddPresence(pres);
+            Assert.AreEqual("bar", pp[f.Bare].From.ToString());
+        }
+        [Test]
+        public void TestHostResource()
+        {
+            PresenceManager pp = new PresenceManager();
+            Presence pres = new Presence(doc);
+            JID f = new JID(null, "bar", "baz");
+            pres.From = f;
+            pp.AddPresence(pres);
+            Assert.AreEqual("bar/baz", pp[f.Bare].From.ToString());
+        }
+        [Test]
+        public void TestRemove()
+        {
+            PresenceManager pp = new PresenceManager();
+            Presence pres = new Presence(doc);
+            JID f = new JID("foo", "bar", "baz");
+            pres.From = f;
+            pres.Status = "Working";
+            pres.Priority = "1";
+            pp.AddPresence(pres);
+            Assert.AreEqual("foo at bar/baz", pp[f].From.ToString());
+            f.Resource = null;
+            Assert.AreEqual("foo at bar/baz", pp[f].From.ToString());
+
+            pres = new Presence(doc);
+            pres.Status = "wandering";
+            pres.From = new JID("foo", "bar", "boo");
+            pp.AddPresence(pres);
+            Assert.AreEqual("Working", pp[f].Status);
+            pres.Priority = "2";
+            pp.AddPresence(pres);
+            Assert.AreEqual("wandering", pp[f].Status);
+            pres.Type = PresenceType.unavailable;
+            pp.AddPresence(pres);
+            Assert.AreEqual("Working", pp[f].Status);
+        }
+        [Test]
+        public void TestNumeric()
+        {
+            PresenceManager pp = new PresenceManager();
+            Presence pres = new Presence(doc);
+            JID f = new JID("support", "conference.192.168.32.109", "bob");
+            pres.From = f;
+            pres.Status = "Working";
+            pp.AddPresence(pres);
+            Assert.AreEqual("support at conference.192.168.32.109/bob", pp[f].From.ToString());
+            f.Resource = null;
+            Assert.AreEqual("support at conference.192.168.32.109/bob", pp[f].From.ToString());
+        }
+
+        [Test]
+        public void TestGetAll()
+        {
+            PresenceManager pp = new PresenceManager();
+
+            Presence pres = new Presence(doc);
+            pres.From = baz;
+            pp.AddPresence(pres);
+
+            pres = new Presence(doc);
+            pres.From = boo;
+            pp.AddPresence(pres);
+
+            Presence[] pa = pp.GetAll(bare);
+            Assert.AreEqual(2, pa.Length);
+            Assert.AreEqual(pa[0].GetType(), typeof(Presence));
+        }
+
+        [Test]
+        public void TestNewPrimaryAlgorithm()
+        {
+            PresenceManager pp = new PresenceManager();
+
+            Presence pres = new Presence(doc);
+            pres.From = baz;
+            pres.IntPriority = 1;
+            pp.AddPresence(pres);
+            Assert.AreEqual(1, pp[bare].IntPriority);
+            Assert.AreEqual(baz, pp[bare].From);
+
+            pres = new Presence(doc);
+            pres.From = boo;
+            pres.IntPriority = 2;
+            pp.AddPresence(pres);
+            // duh.
+            Assert.AreEqual(2, pp[bare].IntPriority);
+            Assert.AreEqual(boo, pp[bare].From);
+
+            pres = new Presence(doc);
+            pres.From = boo;
+            pres.IntPriority = 0;
+            pp.AddPresence(pres);
+            Assert.AreEqual(1, pp[bare].IntPriority);
+            Assert.AreEqual(baz, pp[bare].From); // ooo
+
+            pres = new Presence(doc);
+            pres.From = boo;
+            pres.Type = PresenceType.unavailable;
+            pp.AddPresence(pres);
+            Assert.AreEqual(1, pp[bare].IntPriority);
+            Assert.AreEqual(baz, pp[bare].From);
+
+            pres = new Presence(doc);
+            pres.From = baz;
+            pres.IntPriority = -1;
+            pp.AddPresence(pres);
+            Assert.AreEqual(null, pp[bare]);
+
+            pres = new Presence(doc);
+            pres.From = baz;
+            pres.Type = PresenceType.unavailable;
+            pp.AddPresence(pres);
+            Assert.AreEqual(0, pp.GetAll(bare).Length);
+        }
+
+        [Test]
+        public void TestComparisons()
+        {
+            PresenceManager pp = new PresenceManager();
+
+            Presence pres = new Presence(doc);
+            pres.From = baz;
+            pres.IntPriority = -1;
+            pp.AddPresence(pres);
+            Assert.AreEqual(null, pp[bare]);
+
+            pres = new Presence(doc);
+            pres.From = boo;
+            pres.IntPriority = 0;
+            pres.Show = "away";
+            pp.AddPresence(pres);
+            Assert.AreEqual(boo, pp[bare].From);
+
+            pres = new Presence(doc);
+            pres.From = baz;
+            pres.IntPriority = 0;
+            pres.Show = "xa";
+            pp.AddPresence(pres);
+            Assert.AreEqual(boo, pp[bare].From);
+
+            pres = new Presence(doc);
+            pres.From = boo;
+            pres.IntPriority = 1;
+            pp.AddPresence(pres);
+            Assert.AreEqual(boo, pp[bare].From);
+        }
+
+        [Test]
+        public void TestCaps()
+        {
+            PresenceManager pp = new PresenceManager();
+            Presence pres = new Presence(doc);
+            pres.From = baz;
+
+            CapsManager cm = new CapsManager();
+            pp.CapsManager = cm;
+
+            cm.FileName = "caps.xml";
+            cm.Node = "http://cursive.net/clients/PresenceManagerTest";
+            cm.AddFeature(URI.DISCO_INFO);
+            cm.AddFeature(URI.DELAY);
+            cm.AddIdentity("client", "pc", null, "Presence Manager Test");
+
+            DiscoInfo info = new DiscoInfo(doc);
+            cm.FillInInfo(info);
+            cm[cm.Ver] = info;
+
+            pres.AddChild(cm.GetCaps(pres.OwnerDocument));
+            pp.AddPresence(pres);
+
+            JID dij = pp.GetFeatureJID(bare, URI.DISCO_INFO);
+            Assert.AreEqual(baz, dij);
+            dij = pp.GetFeatureJID(bare, URI.DISCO_ITEMS);
+            Assert.IsNull(dij);
+            dij = pp.GetFeatureJID(baz, URI.DISCO_INFO);
+            Assert.AreEqual(baz, dij);
+
+            StringSet fs = pp.GetFeatures(bare);
+            Assert.IsTrue(fs[URI.DISCO_INFO]);
+            Assert.IsFalse(fs[URI.DISCO_ITEMS]);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/client/RosterManagerTest.cs b/lib/jabber-net/test/jabber/client/RosterManagerTest.cs
new file mode 100644
index 0000000..2f63e46
--- /dev/null
+++ b/lib/jabber-net/test/jabber/client/RosterManagerTest.cs
@@ -0,0 +1,85 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber;
+using jabber.client;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+
+namespace test.jabber.client1 // TODO: Client1 due to a bug in NUnit.
+{
+    /// <summary>
+    /// Summary description for PPDP.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class RosterManagerTest
+    {
+        XmlDocument doc = new XmlDocument();
+
+        [Test] public void Test_Create()
+        {
+            RosterManager rm = new RosterManager();
+            Assert.AreEqual("jabber.client.RosterManager", rm.GetType().FullName);
+        }
+        public void TestAdd()
+        {
+            RosterManager rm = new RosterManager();
+
+            RosterIQ riq = new RosterIQ(doc);
+            riq.Type = IQType.set;
+            Roster r = riq.Instruction;
+            Item i = r.AddItem();
+            i.JID = new JID("foo", "bar", null);
+            i.Nickname = "FOO";
+            i.Subscription = Subscription.both;
+
+            rm.AddRoster(riq);
+            Assert.AreEqual(Subscription.both, rm["foo at bar"].Subscription);
+            Assert.AreEqual("FOO", rm["foo at bar"].Nickname);
+
+            riq = new RosterIQ(doc);
+            riq.Type = IQType.set;
+            r = riq.Instruction;
+            i = r.AddItem();
+            i.JID = new JID("foo", "bar", null);
+            i.Nickname = "BAR";
+            i.Subscription = Subscription.to;
+            rm.AddRoster(riq);
+            Assert.AreEqual(Subscription.to, rm["foo at bar"].Subscription);
+            Assert.AreEqual("BAR", rm["foo at bar"].Nickname);
+        }
+        public void TestNumeric()
+        {
+            RosterManager rm = new RosterManager();
+
+            RosterIQ riq = new RosterIQ(doc);
+            riq.Type = IQType.set;
+            Roster r = riq.Instruction;
+            Item i = r.AddItem();
+            i.JID = new JID("support", "conference.192.168.32.109", null);
+            i.Nickname = "FOO";
+            i.Subscription = Subscription.both;
+
+            rm.AddRoster(riq);
+            Assert.AreEqual(Subscription.both, rm["support at conference.192.168.32.109"].Subscription);
+            Assert.AreEqual("FOO", rm["support at conference.192.168.32.109"].Nickname);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/connection/CapsManagerTest.cs b/lib/jabber-net/test/jabber/connection/CapsManagerTest.cs
new file mode 100644
index 0000000..37470f3
--- /dev/null
+++ b/lib/jabber-net/test/jabber/connection/CapsManagerTest.cs
@@ -0,0 +1,223 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System.Xml;
+
+using bedrock.util;
+
+using jabber;
+using jabber.client;
+using jabber.connection;
+using jabber.protocol;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+using jabber.protocol.x;
+
+using NUnit.Framework;
+using Rhino.Mocks;
+using Rhino.Mocks.Interfaces;
+
+namespace test.jabber.connection
+{
+    [TestFixture]
+    [SVN(@"$Id$")]
+    public class CapsManagerTest
+    {
+        private MockRepository mocks;
+
+        private JabberClient stream;
+        private XmlDocument doc;
+
+        private readonly JID TO_JID = new JID("user1 at test.com");
+        private readonly JID FROM_JID = new JID("user2 at test.com");
+        
+        private const string TEST_ID = "TEST_ID";
+        
+        private const string NODE = "http://jm.jabber.com/caps";
+        private const int PRIORITY = 2;
+        private const string STATUS = "Ready to Chat";
+
+        [SetUp]
+        public void Setup()
+        {
+            mocks = new MockRepository();
+
+            stream = mocks.DynamicMock<JabberClient>();
+
+            doc = new XmlDocument();
+        }
+
+        [Test]
+        public void OnBeforePresenceOutTest()
+        {
+            IEventRaiser presHandler;
+            using (mocks.Record())
+            {
+                stream.OnBeforePresenceOut += null;
+                presHandler = LastCall.IgnoreArguments().GetEventRaiser();
+            }
+
+            using (mocks.Playback())
+            {
+                CapsManager cm = new CapsManager();
+                cm.Stream = stream;
+                cm.Node = NODE;
+
+                Presence packet = CreatePresencePacket();
+                presHandler.Raise(new object[] { null, packet });
+
+                string original = packet.OuterXml.Replace(" ", "");
+                string comparison = GetPresenceWithCaps(cm.Ver).Replace(" ", "");
+                Assert.IsTrue(original == comparison);
+            }
+        }
+
+        private delegate T Func<A0, T>(A0 arg0);
+
+        [Test]
+        public void IqRequestTest()
+        {
+            string nodever = "";
+
+            IEventRaiser iqEvent;
+            using (mocks.Record())
+            {
+                stream.OnIQ += null;
+                iqEvent = LastCall.IgnoreArguments().GetEventRaiser();
+
+                Expect.Call(stream.Document).Return(doc);
+                stream.Write((XmlElement)null);
+                LastCall.Callback((Func<XmlElement, bool>)
+                    delegate(XmlElement arg0)
+                        {
+                            string original = arg0.OuterXml.Replace(" ", "");
+                            string comparison = GetIQResponse(nodever).Replace(" ", "");
+                            return original == comparison;
+                        });
+            }
+
+            using (mocks.Playback())
+            {
+                CapsManager cm = new CapsManager();
+                cm.Stream = stream;
+                cm.Node = NODE;
+
+                nodever = cm.NodeVer;
+
+                iqEvent.Raise(new object[] { null, CreateIqRequest() });
+            }
+        }
+
+        private string GetIQResponse(string nodever)
+        {
+            return
+                string.Format(
+                    "<iq id=\"{0}\" type=\"result\" from=\"{1}\" to=\"{2}\">" +
+                      "<query xmlns=\"{3}\" node=\"{4}\"/>" +
+                    "</iq>",
+                    TEST_ID, TO_JID, FROM_JID, URI.DISCO_INFO, nodever);
+        }
+
+        private IQ CreateIqRequest()
+        {
+            IQ iq = new IQ(doc);
+            iq.To = TO_JID;
+            iq.From = FROM_JID;
+            iq.Type = IQType.get;
+            iq.ID = TEST_ID;
+
+            DiscoInfo info = new DiscoInfo(doc);
+            info.SetAttribute("xmlns", URI.DISCO_INFO);
+            iq.Query = info;
+
+            return iq;
+        }
+
+        private static string GetPresenceWithCaps(string ver)
+        {
+            return
+                string.Format(
+                    "<presence>" +
+                      "<priority>{0}</priority>" +
+                      "<status>{1}</status>" +
+                      "<c ver=\"{2}\"" +
+                         "node=\"{3}\"" +
+                         "hash=\"sha-1\"" +
+                         "xmlns=\"{4}\"/>" +
+                    "</presence>",
+                    PRIORITY, STATUS, ver, NODE, URI.CAPS, URI.CLIENT);
+        }
+
+        private Presence CreatePresencePacket()
+        {
+            /*
+            <presence>
+              <priority>2</priority>
+              <status>Ready to Chat</status>
+            </presence>"
+            */
+
+            Presence packet = new Presence(doc);
+            packet.IntPriority = PRIORITY;
+            packet.Status = STATUS;
+
+            return packet;
+        }
+
+        [Test]
+        public void SimpleGenerationExample()
+        {
+            CapsManager cm = new CapsManager();
+            cm.AddIdentity("client", "pc", null, "Exodus 0.9.1");
+            cm.AddFeature("http://jabber.org/protocol/muc");
+            cm.AddFeature("http://jabber.org/protocol/disco#info");
+            cm.AddFeature("http://jabber.org/protocol/disco#items");
+            Assert.AreEqual("SrFo9ar2CCk2EnOH4q4QANeuxLQ=", cm.Ver);
+        }
+
+        [Test]
+        public void ComplexGenerationExample()
+        {
+
+            XmlDocument doc = new XmlDocument();
+            doc.LoadXml("<book xml:lang='en'/>");
+            XmlElement book = doc.DocumentElement;
+            foreach (XmlAttribute attr in book.Attributes)
+            {
+                System.Console.WriteLine(attr.Name);
+            }
+
+            XmlElement root = doc.DocumentElement;
+
+            DiscoInfo info = new DiscoInfo(doc);
+            info.AddFeature("http://jabber.org/protocol/muc");
+            info.AddFeature("http://jabber.org/protocol/disco#info");
+            info.AddFeature("http://jabber.org/protocol/disco#items");
+            info.AddIdentity("client", "pc", "Psi 0.9.1", "en");
+            info.AddIdentity("client", "pc", "\u03a8 0.9.1", "el");
+            Data x = info.CreateExtension();
+            x.FormType = "urn:xmpp:dataforms:softwareinfo";
+            x.AddField("ip_version").Vals = new string[] { "ipv4", "ipv6" };
+            x.AddField("os").Val = "Mac";
+            x.AddField("os_version").Val = "10.5.1";
+            x.AddField("software").Val = "Psi";
+            x.AddField("software_version").Val = "0.11";
+
+            DiscoNode dn = new DiscoNode(new JID(null, "placeholder", null), null);
+            dn.AddInfo(info);
+
+            CapsManager cm = new CapsManager(dn);
+            Assert.AreEqual("8lu+88MRxmKM7yO3MEzY7YmTsWs=", cm.Ver);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/connection/ConferenceManagerTest.cs b/lib/jabber-net/test/jabber/connection/ConferenceManagerTest.cs
new file mode 100644
index 0000000..20b08cf
--- /dev/null
+++ b/lib/jabber-net/test/jabber/connection/ConferenceManagerTest.cs
@@ -0,0 +1,438 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Xml;
+using bedrock.util;
+
+using jabber;
+using jabber.connection;
+using jabber.protocol;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+
+using NUnit.Framework;
+using Rhino.Mocks;
+using Rhino.Mocks.Interfaces;
+
+
+namespace test.jabber.connection
+{
+    [TestFixture]
+    [SVN(@"$Id$")]
+    public class ConferenceManagerTest
+    {
+        private MockRepository mocks;
+        private ConferenceManager cm;
+        private XmppStream stream;
+        private IIQTracker tracker;
+
+        private XmlDocument doc;
+
+        private readonly JID jid = new JID("room", "conference.test.com", "nick");
+
+        [SetUp]
+        public void setup()
+        {
+            mocks = new MockRepository();
+            stream = mocks.DynamicMock<XmppStream>();
+            tracker = mocks.DynamicMock<IIQTracker>();
+            cm = null;
+
+            doc = new XmlDocument();
+        }
+
+        [Test]
+        public void GetRoomTest()
+        {
+            Room test = CreateRoomPlayback(false, delegate { return null; });
+            Assert.IsNotNull(test);
+        }
+
+        [Test]
+        public void HasRoomTest()
+        {
+            cm = new ConferenceManager();
+            cm.Stream = stream;
+
+            bool roomExists = cm.HasRoom(jid);
+            Assert.IsFalse(roomExists);
+
+            cm.GetRoom(jid);
+            roomExists = cm.HasRoom(jid);
+            Assert.IsTrue(roomExists);
+        }
+
+        [Test]
+        public void RemoveRoomTest()
+        {
+            cm = new ConferenceManager();
+            cm.Stream = stream;
+
+            cm.GetRoom(jid);
+            bool roomExists = cm.HasRoom(jid);
+            Assert.IsTrue(roomExists);
+
+            cm.RemoveRoom(jid);
+            roomExists = cm.HasRoom(jid);
+            Assert.IsFalse(roomExists);
+        }
+
+        private delegate T Func<A0, T>(A0 arg0);
+
+        [Test]
+        //[Ignore("TODO: deal with cm calling OnProtocol +=.")]
+        public void RoomJoinTest()
+        {
+            using (mocks.Record())
+            {
+                CreateJoinExpected(CreateJoinResponsePacket);
+            }
+
+            using (mocks.Playback())
+            {
+                CreateRoomPlayback(true, delegate { return null; });
+            }
+        }
+
+        [Test]
+        //[Ignore("TODO: deal with cm calling OnProtocol +=.")]
+        public void RoomJoinDefaultConfigTest()
+        {
+            RoomConfigTest(true);
+        }
+
+        [Test]
+        //[Ignore("TODO: deal with cm calling OnProtocol +=.")]
+        public void RoomJoinGetConfigTest()
+        {
+            RoomConfigTest(false);
+        }
+
+        private void RoomConfigTest(bool defaultConfig)
+        {
+            using (mocks.Record())
+            {
+                CreateJoinExpected(CreateJoinNeedConfigResponsePacket);
+
+                Expect.Call(stream.Document).Return(doc);
+                SetupTrackerBeginIq(delegate(IQ iq, IqCB cb, object cbArg)
+                    {
+                        string id = iq.GetAttribute("id");
+                        string config = defaultConfig ? GetDefaultConfigPacket(id) :
+                            GetRetrieveConfigPacket(id);
+                        return iq.OuterXml.Replace(" ", "") == config.Replace(" ", "");
+                    });
+            }
+
+            using (mocks.Playback())
+            {
+                CreateRoomPlayback(
+                    true, delegate(Room arg0)
+                              {
+                                  arg0.DefaultConfig = defaultConfig;
+                                  arg0.OnRoomConfig += delegate { return null; };
+                                  return arg0;
+                              });
+            }
+        }
+
+        private string GetRetrieveConfigPacket(string id)
+        {
+            return
+                string.Format(
+                    "<iq id=\"{0}\" type=\"get\" to=\"{1}\">" +
+                        "<query xmlns=\"{2}\"/>" +
+                    "</iq>",
+                    id, jid.Bare, URI.MUC_OWNER);
+        }
+
+        private string GetDefaultConfigPacket(string id)
+        {
+            return
+                string.Format(
+                    "<iq id=\"{0}\" type=\"set\" to=\"{1}\">" +
+                        "<query xmlns=\"{2}\">" +
+                            "<x type=\"submit\" xmlns=\"{3}\"/>" +
+                        "</query>" +
+                    "</iq>",
+                    id, jid.Bare, URI.MUC_OWNER, URI.XDATA);
+        }
+
+        private delegate T Func<A0, A1, A2, T>(A0 arg0, A1 arg1, A2 arg2);
+
+        private void SetupTrackerBeginIq(Func<IQ, IqCB, object, bool> func)
+        {
+            Expect.Call(stream.Tracker).Return(tracker);
+            tracker.BeginIQ(null, null, null);
+            LastCall.Callback(func);
+        }
+
+        private XmlElement CreateJoinNeedConfigResponsePacket(XmlElement elem)
+        {
+            RoomStatus[] statuses = new RoomStatus[] { RoomStatus.CREATED, RoomStatus.SELF };
+
+            return CreateJoinPresence(elem, statuses);
+        }
+
+        private XmlElement CreateJoinResponsePacket(XmlElement elem)
+        {
+            return CreateJoinPresence(elem, new RoomStatus[] { RoomStatus.SELF });
+        }
+
+        private XmlElement CreateJoinPresence(XmlElement elem, RoomStatus[] statuses)
+        {
+            XmlDocument myDoc = new XmlDocument();
+
+            RoomPresence presence = new RoomPresence(myDoc, jid);
+            presence.RemoveAll();
+            presence.From = elem.GetAttribute("to");
+
+            UserX xElem = new UserX(myDoc);
+            presence.AppendChild(xElem);
+
+            xElem.Status = statuses;
+
+            return presence;
+        }
+
+        private const string MESSAGE = "TestMessage";
+
+        [Test]
+        //[Ignore("TODO: deal with cm calling OnProtocol +=.")]
+        public void RoomMessageTest()
+        {
+            SendMessage(true);
+        }
+
+        [Test]
+        [ExpectedException(typeof(InvalidOperationException))]
+        public void RoomMessageNoJoinTest()
+        {
+            SendMessage(false);
+        }
+
+        private void SendMessage(bool shouldJoinRoom)
+        {
+            using (mocks.Record())
+            {
+                CreateJoinExpected(CreateJoinResponsePacket);
+
+                Expect.Call(stream.Document).Return(doc);
+                stream.Write((XmlElement)null);
+                LastCall.Callback((Func<XmlElement, bool>)
+                                  delegate(XmlElement elem)
+                                  {
+                                      string id = elem.GetAttribute("id");
+                                      string original = elem.OuterXml;
+                                      return original.Replace(" ", "") == GetRoomMessage(id).Replace(" ", "");
+                                  });
+            }
+
+            using (mocks.Playback())
+            {
+                Room testRoom = CreateRoomPlayback(shouldJoinRoom, delegate { return null; });
+                testRoom.PublicMessage(MESSAGE);
+            }
+        }
+
+        private Room CreateRoomPlayback(bool joinRoom, Func<Room, Room> alterRoom)
+        {
+            cm = new ConferenceManager();
+            cm.Stream = stream;
+
+            Room testRoom = cm.GetRoom(jid);
+            alterRoom(testRoom);
+            if (joinRoom)
+            {
+                testRoom.Join();
+            }
+
+            return testRoom;
+        }
+
+        private void CreateJoinExpected(Func<XmlElement, XmlElement> sendPresence)
+        {
+            Expect.Call(stream.Document).Return(doc);
+
+            stream.OnProtocol += null;
+            IEventRaiser onProtocol = LastCall.IgnoreArguments().GetEventRaiser();
+
+            stream.Write((XmlElement)null);
+            LastCall.Callback((Func<XmlElement, bool>)
+                              delegate(XmlElement elem)
+                              {
+                                  onProtocol.Raise(new object[] { null, sendPresence(elem) });
+
+                                  string original = elem.OuterXml;
+                                  return original.Replace(" ", "") ==
+                                         GetJoinPresence().Replace(" ", "");
+                              });
+        }
+
+        private const string TO_NICK = "TestNick";
+
+        [Test]
+        //[Ignore("TODO: deal with cm calling OnProtocol +=.")]
+        public void RoomPrivateMessageTest()
+        {
+            SendPrivateMessage(true);
+        }
+
+        [Test]
+        [ExpectedException(typeof(InvalidOperationException))]
+        public void RoomPrivateMessageNoJoinTest()
+        {
+            SendPrivateMessage(false);
+        }
+
+        private void SendPrivateMessage(bool shouldJoin)
+        {
+            using (mocks.Record())
+            {
+                CreateJoinExpected(CreateJoinResponsePacket);
+
+                Expect.Call(stream.Document).Return(doc);
+                stream.Write((XmlElement)null);
+                LastCall.Callback((Func<XmlElement, bool>)
+                                  delegate(XmlElement elem)
+                                  {
+                                      string id = elem.GetAttribute("id");
+                                      string original = elem.OuterXml;
+                                      return original.Replace(" ", "") ==
+                                             GetRoomPrivateMessage(id).Replace(" ", "");
+                                  });
+            }
+
+            using (mocks.Playback())
+            {
+                Room testRoom = CreateRoomPlayback(shouldJoin, delegate { return null; });
+                testRoom.PrivateMessage(TO_NICK, MESSAGE);
+            }
+        }
+
+        private const string REASON = "TestReason";
+
+        [Test]
+        //[Ignore("TODO: deal with cm calling OnProtocol +=.")]
+        public void RoomLeaveTest()
+        {
+            using (mocks.Record())
+            {
+                Expect.Call(stream.Document).Return(doc);
+                stream.Write((XmlElement)null);
+                LastCall.Callback((Func<XmlElement, bool>)
+                    delegate(XmlElement elem)
+                    {
+                        string original = elem.OuterXml;
+                        return original.Replace(" ", "") ==
+                            GetLeavePresence().Replace(" ", "");
+                    });
+                stream.OnProtocol += null;
+                LastCall.IgnoreArguments();
+            }
+
+            using (mocks.Playback())
+            {
+                Room testRoom = CreateRoomPlayback(false, delegate { return null; });
+                testRoom.Leave(REASON);
+            }
+        }
+
+        [Test]
+        //[Ignore("TODO: deal with cm calling OnProtocol +=.")]
+        public void RoomFinishLeaveTest()
+        {
+            using (mocks.Record())
+            {
+                Expect.Call(stream.Document).Return(doc);
+
+                stream.OnProtocol += null;
+                IEventRaiser onProtocol = LastCall.IgnoreArguments().GetEventRaiser();
+
+                stream.Write((XmlElement)null);
+                LastCall.Callback((Func<XmlElement, bool>)
+                    delegate(XmlElement elem)
+                    {
+                        onProtocol.Raise(new object[] { null, CreateUnavailPacket(elem) });
+                        return true;
+                    });
+            }
+
+            using (mocks.Playback())
+            {
+                Room testRoom = CreateRoomPlayback(false, delegate { return null; });
+                testRoom.Leave(REASON);
+            }
+
+            Assert.IsFalse(cm.HasRoom(jid));
+        }
+
+        private XmlElement CreateUnavailPacket(XmlElement elem)
+        {
+            XmlDocument myDoc = new XmlDocument();
+
+            RoomPresence presence = new RoomPresence(myDoc, jid);
+            presence.RemoveAll();
+            presence.Type = PresenceType.unavailable;
+            presence.From = elem.GetAttribute("to");
+
+            UserX xElem = new UserX(myDoc);
+            presence.AppendChild(xElem);
+
+            xElem.Status = new RoomStatus[] { RoomStatus.SELF };
+
+            return presence;
+        }
+
+        private string GetLeavePresence()
+        {
+            return
+                string.Format(
+                    "<presence to=\"{0}\" type=\"unavailable\">" +
+                        "<status>{1}</status>" +
+                    "</presence>",
+                    jid, REASON);
+        }
+
+        private string GetJoinPresence()
+        {
+            return
+                string.Format(
+                    "<presence to=\"{0}\">" +
+                        "<x xmlns=\"{1}\"/>" +
+                    "</presence>",
+                    jid, URI.MUC);
+        }
+
+        private string GetRoomMessage(string id)
+        {
+            return
+                string.Format(
+                    "<message id=\"{0}\" to=\"{1}\" type=\"groupchat\">" +
+                        "<body>{2}</body>" +
+                    "</message>",
+                    id, jid.Bare, MESSAGE);
+        }
+
+        private string GetRoomPrivateMessage(string id)
+        {
+            return
+                string.Format(
+                    "<message id=\"{0}\" to=\"{1}/{2}\" type=\"chat\">" +
+                        "<body>{3}</body>" +
+                    "</message>",
+                    id, jid.Bare, TO_NICK, MESSAGE);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/connection/DiscoManagerTest.cs b/lib/jabber-net/test/jabber/connection/DiscoManagerTest.cs
new file mode 100644
index 0000000..c2f5278
--- /dev/null
+++ b/lib/jabber-net/test/jabber/connection/DiscoManagerTest.cs
@@ -0,0 +1,268 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System.Xml;
+
+using bedrock.util;
+
+using jabber;
+using jabber.connection;
+using jabber.protocol;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+
+using NUnit.Framework;
+using Rhino.Mocks;
+using Rhino.Mocks.Interfaces;
+
+namespace test.jabber.connection
+{
+    [TestFixture]
+    [SVN(@"$Id$")]
+    public class DiscoManagerTest
+    {
+        private MockRepository mocks;
+        private DiscoManager dm;
+        private XmppStream stream;
+        private IIQTracker tracker;
+        private XmlDocument doc;
+
+        [SetUp]
+        public void setup()
+        {
+            mocks = new MockRepository();
+            dm = new DiscoManager();
+
+            stream = mocks.DynamicMock<XmppStream>();
+            tracker = mocks.DynamicMock<IIQTracker>();
+            dm.Stream = stream;
+
+            doc = new XmlDocument();
+        }
+
+        [TearDown]
+        public void cleanUp()
+        {
+            dm.Clear();
+        }
+
+        private readonly JID jid = new JID("test.com");
+        private readonly string NODE = "TEST_NODE";
+        private readonly string FEATURE = "TEST_FEATURE";
+
+        [Test]
+        public void IntialDiscoTest()
+        {
+            IEventRaiser onAuth;
+
+            IQ sentIq = null;
+            IqCB sentCallback = null;
+
+            mocks.BackToRecordAll();
+            using (mocks.Record())
+            {
+                Expect.Call(stream.Server).Return(jid);
+                stream.OnAuthenticate += null;
+                onAuth = LastCall.IgnoreArguments().GetEventRaiser();
+
+                Expect.Call(stream.Document).Return(doc);
+                SetupTrackerBeginIq(
+                    delegate(IQ arg0, IqCB arg1, object arg2)
+                    {
+                        // Grab the iq and callback so this part of
+                        // the code can finish. Call the callback later.
+                        sentIq = arg0;
+                        sentCallback = arg1;
+
+                        string id = arg0.GetAttribute("id");
+                        string original = arg0.OuterXml.Replace(" ", "");
+                        string comparison = GetInfoXml(id).Replace(" ", "");
+                        return original == comparison;
+                    });
+
+                Expect.Call(stream.Document).Return(doc);
+                SetupTrackerBeginIq(
+                    delegate(IQ arg0, IqCB arg1, object arg2)
+                    {
+                        string id = arg0.GetAttribute("id");
+                        string original = arg0.OuterXml;
+                        return original.Replace(" ", "") ==
+                               GetItemsForServiceXml(id).Replace(" ", "");
+                    });
+            }
+
+            using (mocks.Playback())
+            {
+                DiscoManager newDm = new DiscoManager();
+                newDm.Stream = stream;
+
+                onAuth.Raise(new object[] { null });
+
+                if (sentIq != null)
+                {
+                    string id = sentIq.GetAttribute("id");
+                    if (sentCallback != null)
+                        sentCallback(null, CreateDiscoInfoResponse(id), newDm.Root);
+                }
+            }
+        }
+
+        [Test]
+        public void BeginGetItemsTest()
+        {
+            mocks.BackToRecordAll();
+            using (mocks.Record())
+            {
+                Expect.Call(stream.Document).Return(doc);
+                SetupTrackerBeginIq(
+                    delegate(IQ arg0, IqCB arg1, object arg2)
+                    {
+                        string id = arg0.GetAttribute("id");
+                        string original = arg0.OuterXml.Replace(" ", "");
+                        string comparison = GetItemsXml(id).Replace(" ", "");
+                        return original == comparison;
+                    });
+            }
+
+            using (mocks.Playback())
+            {
+                dm.BeginGetItems(jid, NODE, delegate { }, null);
+            }
+        }
+
+        [Test]
+        public void BeginGetFeaturesTest()
+        {
+            mocks.BackToRecordAll();
+            using (mocks.Record())
+            {
+                Expect.Call(stream.Document).Return(doc);
+                SetupTrackerBeginIq(
+                    delegate(IQ arg0, IqCB arg1, object arg2)
+                    {
+                        string id = arg0.GetAttribute("id");
+                        string original = arg0.OuterXml.Replace(" ", "");
+                        string comparison = GetFeaturesXml(id).Replace(" ", "");
+                        return original == comparison;
+                    });
+            }
+
+            using (mocks.Playback())
+            {
+                dm.BeginGetFeatures(jid, NODE, delegate { }, null);
+            }
+        }
+
+        [Test]
+        public void BeginGetServiceTest()
+        {
+            mocks.BackToRecordAll();
+            using (mocks.Record())
+            {
+                Expect.Call(stream.Server).Return(jid);
+                Expect.Call(stream.Document).Return(doc);
+                SetupTrackerBeginIq(
+                    delegate(IQ arg0, IqCB arg1, object arg2)
+                    {
+                        string id = arg0.GetAttribute("id");
+                        string original = arg0.OuterXml.Replace(" ", "");
+                        string comparison = GetItemsForServiceXml(id).Replace(" ", "");
+                        return original == comparison;
+                    });
+            }
+
+            using (mocks.Playback())
+            {
+                dm.BeginFindServiceWithFeature(FEATURE, delegate { }, null);
+            }
+        }
+
+        private IQ CreateDiscoInfoResponse(string id)
+        {
+            IQ returnIq = new IQ(doc);
+            returnIq.SetAttribute("id", id);
+            returnIq.SetAttribute("from", jid);
+            returnIq.SetAttribute("type", "result");
+
+            DiscoInfo info = new DiscoInfo(doc);
+            info.AddIdentity("server", "im", "jabber2 4.2.16.6", null);
+            info.AddFeature(URI.DISCO_ITEMS);
+            info.AddFeature(URI.DISCO_INFO);
+
+            returnIq.Query = info;
+
+            return returnIq;
+        }
+
+        private string GetInfoXml(string id)
+        {
+            return
+                string.Format(
+                    "<iq id=\"{0}\" type=\"get\" to=\"{1}\">" +
+                      "<query xmlns=\"{2}\"/>" +
+                    "</iq>",
+                    id, jid, URI.DISCO_INFO);
+        }
+
+        private string GetItemsForServiceXml(string id)
+        {
+            return
+                string.Format(
+                    "<iq id=\"{0}\" type=\"get\" to=\"{1}\">" +
+                      "<query xmlns=\"{2}\"/>" +
+                    "</iq>",
+                    id, jid, URI.DISCO_ITEMS);
+        }
+
+        private string GetFeaturesXml(string id)
+        {
+            return
+                string.Format(
+                    "<iq id=\"{0}\" type=\"get\" to=\"{1}\">" +
+                      "<query node=\"{2}\" xmlns=\"{3}\" />" +
+                    "</iq>",
+                    id, jid, NODE, URI.DISCO_INFO);
+        }
+
+        private string GetItemsXml(string id)
+        {
+            return
+                string.Format(
+                    "<iq id=\"{0}\" type=\"get\" to=\"{1}\">" +
+                      "<query node=\"{2}\" xmlns=\"{3}\"/>" +
+                    "</iq>",
+                    id, jid, NODE, URI.DISCO_ITEMS);
+        }
+
+        private delegate T Func<A0, A1, A2, T>(A0 arg0, A1 arg1, A2 arg2);
+        private void SetupTrackerBeginIq(Func<IQ, IqCB, object, bool> func)
+        {
+            Expect.Call(stream.Tracker).Return(tracker);
+            tracker.BeginIQ(null, null, null);
+            LastCall.Callback(func);
+        }
+
+        [Test]
+        public void IdentityLang()
+        {
+            DiscoIdentity id = new DiscoIdentity(doc);
+            Assert.IsNull(id.Lang);
+            id.Lang = "en";
+            Assert.AreEqual("en", id.Lang);
+            id.Lang = "el";
+            Assert.AreEqual("el", id.Lang);
+            id.Lang = null;
+            Assert.IsNull(id.Lang);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/connection/FileMap.cs b/lib/jabber-net/test/jabber/connection/FileMap.cs
new file mode 100644
index 0000000..7599f03
--- /dev/null
+++ b/lib/jabber-net/test/jabber/connection/FileMap.cs
@@ -0,0 +1,83 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using NUnit.Framework;
+using bedrock.io;
+using bedrock.util;
+using System.Xml;
+
+using jabber.connection;
+using jabber.protocol;
+using jabber.protocol.iq;
+
+namespace test.jabber.connection
+{
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class FileMapTest
+    {
+        XmlDocument doc = new XmlDocument();
+
+        DiscoInfo Element
+        {
+            get
+            {
+                XmlDocument doc = new XmlDocument();
+                global::jabber.protocol.iq.DiscoInfo di = new global::jabber.protocol.iq.DiscoInfo(doc);
+                di.AddFeature(global::jabber.protocol.URI.DISCO_INFO);
+                di.AddFeature(global::jabber.protocol.URI.DISCO_ITEMS);
+                return di;
+            }
+        }
+
+        [Test]
+        [ExpectedException(typeof(ArgumentException))]
+        public void TestNull()
+        {
+            FileMap<Element> fm = new FileMap<Element>("test.xml", null);
+            Assert.IsNotNull(fm);
+            FileMap<DiscoInfo> fm2 = new FileMap<DiscoInfo>("test.xml", null);
+        }
+
+        [Test]
+        public void TestCreate()
+        {
+            ElementFactory ef = new ElementFactory();
+            ef.AddType(new global::jabber.protocol.iq.Factory());
+
+            string g = new Guid().ToString();
+            FileMap<DiscoInfo> fm = new FileMap<DiscoInfo>("test.xml", ef);
+            fm.Clear();
+            Assert.AreEqual(0, fm.Count);
+
+            fm[g] = Element;
+            Assert.IsTrue(fm.Contains(g));
+            Assert.IsFalse(fm.Contains("foo"));
+            Assert.IsInstanceOfType(typeof(DiscoInfo), fm[g]);
+            Assert.AreEqual(1, fm.Count);
+
+            // re-read, to reparse
+            fm = new FileMap<DiscoInfo>("test.xml", ef);
+            Assert.IsTrue(fm.Contains(g));
+            Assert.IsInstanceOfType(typeof(DiscoInfo), fm[g]);
+
+            fm[g] = null;
+            Assert.AreEqual(1, fm.Count);
+
+            fm.Remove(g);
+            Assert.AreEqual(0, fm.Count);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/connection/PubSubManagerTest.cs b/lib/jabber-net/test/jabber/connection/PubSubManagerTest.cs
new file mode 100644
index 0000000..2e337f4
--- /dev/null
+++ b/lib/jabber-net/test/jabber/connection/PubSubManagerTest.cs
@@ -0,0 +1,285 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System.Collections;
+using System.Reflection;
+using System.Xml;
+
+using bedrock.util;
+
+using jabber;
+using jabber.connection;
+using jabber.protocol;
+using jabber.protocol.client;
+
+using NUnit.Framework;
+using Rhino.Mocks;
+
+namespace test.jabber.connection
+{
+    [TestFixture]
+    [SVN(@"$Id$")]
+    public class PubSubManagerTest
+    {
+        private const string PUB_SUB_XMLNS = "http://jabber.org/protocol/pubsub";
+
+        private XmppStream stream;
+
+        private MockRepository mocks;
+        private IIQTracker tracker;
+        private XmlDocument doc;
+
+        private JID jid;
+        private static readonly string NODE = "test";
+
+        [SetUp]
+        public void Setup()
+        {
+            mocks = new MockRepository();
+            stream = mocks.DynamicMock<XmppStream>();
+            tracker = mocks.DynamicMock<IIQTracker>();
+            doc = new XmlDocument();
+
+            jid = new JID("test.example.com");
+        }
+
+        [Test]
+        public void GetNodeTest()
+        {
+            PubSubManager mgr = GetPubSubMgr();
+
+            PubSubNode node = mgr.GetNode(jid, NODE, 0);
+            Assert.AreNotEqual(node, null);
+        }
+
+        private delegate T Func<A0, A1, A2, T>(A0 arg0, A1 arg1, A2 arg2);
+
+        [Test]
+        public void CreateNodeTest()
+        {
+            using (mocks.Record())
+            {
+                Expect.Call(stream.Document).Return(doc);
+                SetupTrackerBeginIq(delegate(IQ iq, IqCB cb, object cbArg)
+                    {
+                        string id = iq.GetAttribute("id");
+                        string original = iq.OuterXml.Replace(" ", "");
+                        string comparison = GetCreateNodeIQ(id).Replace(" ", "");
+                        return original == comparison;
+                    });
+            }
+
+            using (mocks.Playback())
+            {
+                PubSubManager mgr = GetPubSubMgr();
+                PubSubNode node = mgr.GetNode(jid, NODE, 0);
+                node.Create();
+            }
+        }
+
+        [Test]
+        public void RemoveNodeTest()
+        {
+            using (mocks.Record())
+            {
+                Expect.Call(stream.Document).Return(doc);
+                SetupTrackerBeginIq(delegate(IQ iq, IqCB cb, object cbArg)
+                    {
+                        string id = iq.GetAttribute("id");
+                        string original = iq.OuterXml.Replace(" ", "");
+                        string comparison = GetRemoveNodeIq(id).Replace(" ", "");
+                        return original == comparison;
+                    });
+            }
+
+            using (mocks.Playback())
+            {
+                PubSubManager mgr = GetPubSubMgr();
+                mgr.RemoveNode(jid, NODE, null);
+            }
+        }
+
+        [Test]
+        public void AddRemoveNodeTest()
+        {
+            using (mocks.Record())
+            {
+                Expect.Call(stream.Document).Return(doc);
+                SetupTrackerBeginIq(delegate
+                {
+                    return true;
+                });
+            }
+
+            using (mocks.Playback())
+            {
+                PubSubManager mgr = GetPubSubMgr();
+                mgr.GetNode(jid, NODE, 0);
+
+                FieldInfo fieldInfo = mgr.GetType().GetField("m_nodes",
+                    BindingFlags.Instance | BindingFlags.NonPublic);
+                IDictionary nodes = (IDictionary)fieldInfo.GetValue(mgr);
+                if (nodes == null || nodes.Count != 1)
+                    Assert.Fail("The GetNode function failed");
+
+                mgr.RemoveNode(jid, NODE, null);
+                Assert.IsTrue(nodes[new JIDNode(jid, NODE)] == null);
+            }
+        }
+
+        [Test]
+        public void DeleteNodeTest()
+        {
+            using (mocks.Record())
+            {
+                Expect.Call(stream.Document).Return(doc);
+                SetupTrackerBeginIq(delegate(IQ iq, IqCB cb, object cbArg)
+                    {
+                        string id = iq.GetAttribute("id");
+                        string original = iq.OuterXml;
+                        return original.Replace(" ", "") == GetRemoveNodeIq(id).Replace(" ", "");
+                    });
+            }
+
+            using (mocks.Playback())
+            {
+                PubSubManager mgr = GetPubSubMgr();
+                mgr.GetNode(jid, NODE, 0).Delete();
+            }
+        }
+
+        private const string PUB_SUB_ITEM = "TestItem";
+        private const string PUB_SUB_ITEM_XMLNS = "TestUri";
+
+        [Test]
+        public void PublishItemTest()
+        {
+            XmlElement pubItem = CreateTestItem();
+
+            using (mocks.Record())
+            {
+                Expect.Call(stream.Document).Return(doc);
+                Expect.Call(stream.Document).Return(doc);
+                SetupTrackerBeginIq(delegate(IQ iq, IqCB cb, object cbArg)
+                    {
+                        string id = iq.GetAttribute("id");
+                        string original = iq.OuterXml.Replace(" ", "");
+                        string comparison = GetPublishItemIq(id).Replace(" ", "");
+                        return original == comparison;
+                    });
+            }
+
+            using (mocks.Playback())
+            {
+                PubSubManager mgr = GetPubSubMgr();
+                mgr.GetNode(jid, NODE, 0).PublishItem(null, pubItem);
+            }
+        }
+
+        private static XmlElement CreateTestItem()
+        {
+            XmlDocument myDoc = new XmlDocument();
+            return myDoc.CreateElement(PUB_SUB_ITEM, PUB_SUB_ITEM_XMLNS);
+        }
+
+        private const string PUB_SUB_ID = "TestId";
+
+        [Test]
+        public void DeleteItemTest()
+        {
+            using (mocks.Record())
+            {
+                Expect.Call(stream.Document).Return(doc);
+                SetupTrackerBeginIq(delegate(IQ iq, IqCB cb, object cbArg)
+                    {
+                        string id = iq.GetAttribute("id");
+                        string original = iq.OuterXml.Replace(" ", "");
+                        string comparison = GetDeleteItemString(id).Replace(" ", "");
+                        return original == comparison;
+                    });
+            }
+
+            using (mocks.Playback())
+            {
+                PubSubManager mgr = GetPubSubMgr();
+                mgr.GetNode(jid, NODE, 0).DeleteItem(PUB_SUB_ID);
+            }
+        }
+
+        private string GetDeleteItemString(string id)
+        {
+            return string.Format(
+                "<iq id=\"{0}\" type=\"set\" to=\"{1}\">"+
+                    "<pubsub xmlns=\"{2}\">"+
+                        "<retract node=\"{3}\">"+
+                            "<item id=\"{4}\"/>"+
+                        "</retract>"+
+                    "</pubsub>"+
+                "</iq>",
+                id, jid, PUB_SUB_XMLNS, NODE, PUB_SUB_ID);
+        }
+
+        private string GetPublishItemIq(string id)
+        {
+            return string.Format(
+                "<iq id=\"{0}\" type=\"set\" to=\"{1}\">" +
+                    "<pubsub xmlns=\"{2}\">"+
+                        "<publish node=\"{3}\">"+
+                            "<item>"+
+                                "<{4} xmlns=\"{5}\"/>"+
+                            "</item>"+
+                        "</publish>"+
+                    "</pubsub>"+
+                "</iq>",
+                id, jid, PUB_SUB_XMLNS, NODE, PUB_SUB_ITEM, PUB_SUB_ITEM_XMLNS);
+        }
+
+        private void SetupTrackerBeginIq(Func<IQ, IqCB, object, bool> func)
+        {
+            Expect.Call(stream.Tracker).Return(tracker);
+            tracker.BeginIQ(null, null, null);
+            LastCall.Callback(func);
+        }
+
+        private string GetRemoveNodeIq(string id)
+        {
+            return string.Format(
+                "<iq id=\"{0}\" type=\"set\" to=\"{1}\">"+
+                    "<pubsub xmlns=\"{2}\">"+
+                        "<delete node=\"{3}\"/>"+
+                    "</pubsub>"+
+                "</iq>",
+                id, jid, URI.PUBSUB_OWNER, NODE);
+        }
+
+        private string GetCreateNodeIQ(string id)
+        {
+            return
+                string.Format(
+                    "<iq id=\"{0}\" type=\"set\" to=\"{1}\">"+
+                        "<pubsub xmlns=\"{2}\">"+
+                            "<create node=\"{3}\"/>"+
+                            "<configure/>"+
+                        "</pubsub>"+
+                    "</iq>",
+                    id, jid, PUB_SUB_XMLNS, NODE);
+        }
+
+        private PubSubManager GetPubSubMgr()
+        {
+            PubSubManager mgr = new PubSubManager();
+            mgr.Stream = stream;
+            return mgr;
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/connection/sasl/MD5Processor.cs b/lib/jabber-net/test/jabber/connection/sasl/MD5Processor.cs
new file mode 100644
index 0000000..eb26223
--- /dev/null
+++ b/lib/jabber-net/test/jabber/connection/sasl/MD5Processor.cs
@@ -0,0 +1,48 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using bedrock.util;
+
+using jabber.connection;
+using jabber.connection.sasl;
+using jabber.protocol.stream;
+
+using NUnit.Framework;
+using System.Xml;
+
+namespace test.jabber.connection.sasl
+{
+    [TestFixture]
+    [SVN(@"$Id$")]
+    public class MD5ProcessorTest
+    {
+        [Test]
+        public void TestChallenge()
+        {
+
+            XmlDocument doc = new XmlDocument();
+            Challenge c = new Challenge(doc);
+            c.InnerText = "cmVhbG09IndlYjIwMDMiLCBub25jZT0iWWE0anVNYzU0SG9UWDBPa1VPRDFvQT09IiwgcW9wPSJhdXRoLCBhdXRoLWludCIsIGNoYXJzZXQ9dXRmLTgsIGFsZ29yaXRobT1tZDUtc2Vzcw==";
+
+            MD5Processor m = new MD5Processor();
+            m["username"] = "test";
+            m["password"] = "test";
+            Step s = m.step(c, doc);
+            Assert.IsNotNull(s);
+            Assert.AreEqual("Ya4juMc54HoTX0OkUOD1oA==", m["nonce"]);
+            Assert.AreEqual("auth, auth-int", m["qop"]);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/ElementListTest.cs b/lib/jabber-net/test/jabber/protocol/ElementListTest.cs
new file mode 100644
index 0000000..abe9a0c
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/ElementListTest.cs
@@ -0,0 +1,84 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Text;
+using System.Xml;
+using NUnit.Framework;
+
+using bedrock;
+using bedrock.util;
+using jabber.protocol;
+
+namespace test.jabber.protocol
+{
+    /// <summary>
+    /// Summary description for ElementListTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class ElementListTest
+    {
+        private XmlDocument doc = new XmlDocument();
+
+        private Element Parent()
+        {
+            Element parent = new Element("rent", "f", doc);
+            Element child;
+            for (int i=0; i<10; i++)
+            {
+                child = new Element("foo", "f", doc);
+                child.InnerText = i.ToString();
+                parent.AppendChild(child);
+                child = new Element("bar", "f", doc);
+                child.InnerText = i.ToString();
+                parent.AppendChild(child);
+            }
+            return parent;
+        }
+
+        [Test] public void Test_Count()
+        {
+            Element parent = Parent();
+            Assert.AreEqual(10,  parent.GetElementsByTagName("foo").Count);
+            Assert.AreEqual(10,  parent.GetElementsByTagName("bar").Count);
+            Assert.AreEqual(10,  parent.GetElementsByTagName("foo", "f").Count);
+            Assert.AreEqual(10,  parent.GetElementsByTagName("bar", "f").Count);
+            Assert.AreEqual(0,  parent.GetElementsByTagName("bar", "g").Count);
+        }
+        [Test] public void Test_Enum()
+        {
+            Element parent = Parent();
+            int c = 0;
+            foreach (XmlElement e in parent.GetElementsByTagName("foo"))
+            {
+                Assert.AreEqual(c.ToString(), e.InnerText);
+                c++;
+            }
+            Assert.AreEqual(10, c);
+        }
+
+        [Test] public void Test_Grandkids()
+        {
+            Element parent = Parent();
+            Element g = new Element("foo", "f", doc);
+            g.InnerText = "one";
+            parent.FirstChild.AppendChild(g);
+            foreach (XmlElement e in parent.GetElementsByTagName("foo"))
+            {
+                Assert.IsTrue(e.InnerText != "one");
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/ElementStreamTest.cs b/lib/jabber-net/test/jabber/protocol/ElementStreamTest.cs
new file mode 100644
index 0000000..de656e3
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/ElementStreamTest.cs
@@ -0,0 +1,153 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System.IO;
+using System.Text;
+using System.Threading;
+using System.Xml;
+using System;
+using NUnit.Framework;
+
+using bedrock;
+using bedrock.util;
+using jabber.protocol;
+
+namespace test.jabber.protocol
+{
+    /// <summary>
+    /// Summary description for ElementStreamTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class ElementStreamTest
+    {
+        private bool fail = false;
+        private System.Text.Encoding ENC = System.Text.Encoding.UTF8;
+        private AutoResetEvent are = new AutoResetEvent(false);
+        private int count = 0;
+
+        /*
+         * Try several ways to generate PartialTokenException.
+         */
+        [Test] public void Test_Partial()
+        {
+            fail = false;
+            AsynchElementStream es = new AsynchElementStream();
+            es.OnDocumentEnd += new ObjectHandler(jabOnEnd);
+
+            es.Push(ENC.GetBytes("<stream>"));
+            es.OnElement += new ProtocolHandler(jabOnElement);
+            es.Push(ENC.GetBytes("<te"));
+
+            are.WaitOne(100, true);
+            Assert.IsTrue(! fail);
+
+            es.Push(ENC.GetBytes("st/>"));
+            es.Push(ENC.GetBytes("<test>"));
+            es.Push(ENC.GetBytes("</"));
+            es.Push(ENC.GetBytes("test>"));
+            es.Push(ENC.GetBytes("<test>&#1"));
+            es.Push(ENC.GetBytes("16;est</test>"));
+            es.Push(ENC.GetBytes("<test>"));
+            es.Push(new byte[] {0xC5});
+            es.Push(new byte[] {0x81});
+            es.Push(ENC.GetBytes("</test>"));
+            es.Push(ENC.GetBytes("<test f"));
+            es.Push(ENC.GetBytes("oo='bar'/>"));
+            es.Push(ENC.GetBytes("<test foo="));
+            es.Push(ENC.GetBytes("'bar'/>"));
+            es.Push(ENC.GetBytes("<test foo='"));
+            es.Push(ENC.GetBytes("bar'/>"));
+            es.Push(new byte[] {} );
+        }
+
+        /*
+         * What happens if we try to parse more than 4k of data at once?
+         */
+        [Test] public void Test_Large()
+        {
+            AsynchElementStream es = new AsynchElementStream();
+            // es.OnElement += new ProtocolHandler(jabOnElement);
+
+            es.Push(ENC.GetBytes("<stream>"));
+            byte[] buf = ENC.GetBytes("<test/>");
+            MemoryStream ms = new MemoryStream();
+            for (int i=0; i<1024; i++)
+            {
+                ms.Write(buf, 0, buf.Length);
+            }
+            es.Push(ms.ToArray());
+        }
+
+        [Test]
+        public void Test_Large_Partial()
+        {
+            count = 0;
+            AsynchElementStream es = new AsynchElementStream();
+            es.OnElement += new ProtocolHandler(es_OnElement);
+            es.Push(ENC.GetBytes("<stream>"));
+            string test = "<presence from='xxxxxxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxxxxxxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxxxxxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxxxxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxx at myjabber.net' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxxx at myjabber.net' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxxxxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxxx at jabber.org/Home' to='xxxxxx at jabber.org/Test'><priority>1</priority><c xmlns='http://jabber.org/protocol/caps' node='http://pidgin.im/caps' ver='2.3.1' ext='moodn nickn tunen avatar'/><x xmlns='vcard-temp:x:update'><photo>d206b82e4c1478ab033dacc55eacb1cfda7706c8</photo></x></presence><presence from='xxxxxxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxxxxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxxxxxxxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxxxxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxxxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxxxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cancel'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence><presence from='xxxxxxxxx at aim.ijabber.com' to='xxxxxx at jabber.org/Test' type='error'><error code='404' type='cance";
+            es.Push(ENC.GetBytes(test));
+            test = "l'><remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></presence>";
+            es.Push(ENC.GetBytes(test));
+            Assert.AreEqual(count, 20);
+        }
+
+        private void es_OnElement(object sender, XmlElement rp)
+        {
+            count++;
+        }
+
+        /*
+        [Test] public void Test_NullBody()
+        {
+            fail = false;
+            AsynchElementStream es = new AsynchElementStream();
+            es.OnDocumentEnd += new ObjectHandler(jabOnEnd);
+
+            es.Push(ENC.GetBytes("<str"));
+            es.Push(ENC.GetBytes("eam/>"));
+
+            System.Threading.Thread.Sleep(500);
+            Assert.IsTrue(! fail);
+        }
+*/
+
+        /* The server should protect from these.  Good thing, since
+         * it doesn't work.  :|
+        [Test] public void Test_Comment()
+        {
+            fail = false;
+            ElementStream es = new ElementStream();
+            es.OnDocumentEnd += new ObjectHandler(jabOnEnd);
+
+            es.Push(ENC.GetBytes("<stream><!-- <foo/>"));
+            es.Push(ENC.GetBytes(" --></stream>"));
+
+            System.Threading.Thread.Sleep(500);
+            Assert.IsTrue(! fail);
+        }
+*/
+        void jabOnEnd(object s)
+        {
+            fail = true;
+            are.Set();
+        }
+
+        void jabOnElement(Object sender, System.Xml.XmlElement elem)
+        {
+            Console.WriteLine(elem.OuterXml);
+            Assert.AreEqual("test", elem.Name);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/EnumParserTest.cs b/lib/jabber-net/test/jabber/protocol/EnumParserTest.cs
new file mode 100644
index 0000000..815f3b4
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/EnumParserTest.cs
@@ -0,0 +1,115 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber.protocol;
+
+namespace test.jabber.protocol
+{
+    /// <summary>
+    /// Test the EnumParser
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class EnumParserTest
+    {
+        enum foo
+        {
+            NONE = -1,
+            bar,
+            baz
+        }
+
+        enum bar
+        {
+            NONE = -1,
+            [XML("moo")]
+            bloo,
+            [XML("")]
+            goo
+        }
+
+        [Dash]
+        enum doo
+        {
+            moo_vie,
+        }
+
+        [Test]
+        public void ParsePlain()
+        {
+            foo f = EnumParser.Parse<foo>("bar");
+            Assert.AreEqual(foo.bar, f);
+            f = EnumParser.Parse<foo>("blah");
+            Assert.AreEqual(foo.NONE, f);
+        }
+
+        [Test]
+        public void ParseAttr()
+        {
+            bar b = EnumParser.Parse<bar>("moo");
+            Assert.AreEqual(bar.bloo, b);
+            b = EnumParser.Parse<bar>("bloo");
+            Assert.AreEqual(bar.bloo, b);
+        }
+
+        [Test]
+        public void Strings()
+        {
+            string s = EnumParser.ToString(foo.bar);
+            Assert.AreEqual("bar", s);
+
+            s = EnumParser.ToString(bar.bloo);
+            Assert.AreEqual("moo", s);
+        }
+
+        [Test]
+        public void XML()
+        {
+            XmlDocument doc = new XmlDocument();
+            Element e = new Element("test", doc);
+            e.SetAttribute("bloo", EnumParser.ToString(bar.NONE));
+            Assert.AreEqual("", e.GetAttribute("bloo"));
+            e.SetAttribute("bloo", EnumParser.ToString(bar.bloo));
+            Assert.AreEqual("moo", e.GetAttribute("bloo"));
+            e.SetAttribute("bloo", EnumParser.ToString(bar.NONE));
+            Assert.AreEqual("", e.GetAttribute("bloo"));
+        }
+
+        [Test]
+        public void Dashes()
+        {
+            doo d = doo.moo_vie;
+            string s = EnumParser.ToString(d);
+            Assert.AreEqual("moo-vie", s);
+            d = EnumParser.Parse<doo>(s);
+            Assert.AreEqual(doo.moo_vie, d);
+        }
+
+        [Test]
+        public void Null()
+        {
+            string s = EnumParser.ToString(foo.NONE);
+            Assert.IsNull(s);
+            foo f = EnumParser.Parse<foo>("");
+            Assert.AreEqual(foo.NONE, f);
+            bar b = EnumParser.Parse<bar>("");
+            Assert.AreEqual(bar.goo, b);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/PacketTest.cs b/lib/jabber-net/test/jabber/protocol/PacketTest.cs
new file mode 100644
index 0000000..c6604e6
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/PacketTest.cs
@@ -0,0 +1,70 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber.protocol;
+
+namespace test.jabber.protocol
+{
+    /// <summary>
+    /// Summary description for PacketTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class PacketTest
+    {
+        XmlDocument doc = new XmlDocument();
+
+        [Test] public void Test_Create()
+        {
+            Packet p = new Packet("foo", doc);
+            Assert.AreEqual("<foo />", p.ToString());
+            p.To = "one";
+            Assert.AreEqual("<foo to=\"one\" />", p.ToString());
+            p.From = "two";
+            Assert.AreEqual("<foo to=\"one\" from=\"two\" />", p.ToString());
+            p.Swap();
+            Assert.AreEqual("<foo to=\"two\" from=\"one\" />", p.ToString());
+        }
+
+        [Test] public void Test_JabberDate()
+        {
+            string sdt = "20020504T20:39:42";
+            DateTime dt = Element.JabberDate(sdt);
+            Assert.AreEqual(2002, dt.Year);
+            Assert.AreEqual(5, dt.Month);
+            Assert.AreEqual(4, dt.Day);
+            Assert.AreEqual(20, dt.Hour);
+            Assert.AreEqual(39, dt.Minute);
+            Assert.AreEqual(42, dt.Second);
+            Assert.AreEqual(sdt, Element.JabberDate(dt));
+        }
+        [Test] public void Test_DateTimeProfile()
+        {
+            string sdt = "2002-05-04T20:39:42.050Z";
+            DateTime dt = Element.DateTimeProfile(sdt);
+            Assert.AreEqual(2002, dt.Year);
+            Assert.AreEqual(5, dt.Month);
+            Assert.AreEqual(4, dt.Day);
+            Assert.AreEqual(20, dt.Hour);
+            Assert.AreEqual(39, dt.Minute);
+            Assert.AreEqual(42, dt.Second);
+            Assert.AreEqual(sdt, Element.DateTimeProfile(dt));
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/accept/RouteTest.cs b/lib/jabber-net/test/jabber/protocol/accept/RouteTest.cs
new file mode 100644
index 0000000..5bb2c55
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/accept/RouteTest.cs
@@ -0,0 +1,41 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber.protocol.accept;
+
+namespace test.jabber.protocol.accept
+{
+    /// <summary>
+    /// Summary description for IQTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class RouteTest
+    {
+        XmlDocument doc = new XmlDocument();
+        [Test] public void Test_Create()
+        {
+            Route r = new Route(doc);
+            r.Contents = doc.CreateElement("foo");
+            Assert.AreEqual("<route><foo /></route>", r.OuterXml);
+            XmlElement foo = r.Contents;
+            Assert.AreEqual("<foo />", foo.OuterXml);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/client/IQTest.cs b/lib/jabber-net/test/jabber/protocol/client/IQTest.cs
new file mode 100644
index 0000000..628ebb7
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/client/IQTest.cs
@@ -0,0 +1,48 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber.protocol;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+
+namespace test.jabber.protocol.client
+{
+    /// <summary>
+    /// Summary description for IQTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class IQTest
+    {
+        XmlDocument doc = new XmlDocument();
+
+        [Test]
+        public void Create()
+        {
+            Element.ResetID();
+
+            IQ iq = new IQ(doc);
+            Assert.AreEqual("<iq id=\"JN_1\" type=\"get\" />", iq.ToString());
+            iq = new IQ(doc);
+            Assert.AreEqual("<iq id=\"JN_2\" type=\"get\" />", iq.ToString());
+            iq.Query = new Auth(doc);
+            Assert.AreEqual("<iq id=\"JN_2\" type=\"get\"><query xmlns=\"jabber:iq:auth\" /></iq>", iq.ToString());
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/client/MessageTest.cs b/lib/jabber-net/test/jabber/protocol/client/MessageTest.cs
new file mode 100644
index 0000000..e27a776
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/client/MessageTest.cs
@@ -0,0 +1,87 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber.protocol;
+using jabber.protocol.client;
+
+namespace test.jabber.protocol.client
+{
+    /// <summary>
+    /// Summary description for MessageTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class MessageTest
+    {
+        XmlDocument doc = new XmlDocument();
+        [SetUp]
+        public void SetUp()
+        {
+            Element.ResetID();
+        }
+        [Test] public void Test_Create()
+        {
+            Message msg = new Message(doc);
+            msg.Html = "foo";
+            Assert.AreEqual("<message id=\""+msg.ID+"\"><html xmlns=\"http://jabber.org/protocol/xhtml-im\"><body xmlns=\"http://www.w3.org/1999/xhtml\">foo</body></html><body>foo</body></message>", msg.ToString());
+            // TODO: deal with the namespace problem here
+            msg.Html = "f<a href=\"http://www.jabber.org\">o</a>o";
+            Assert.AreEqual("<message id=\""+msg.ID+"\"><html xmlns=\"http://jabber.org/protocol/xhtml-im\"><body xmlns=\"http://www.w3.org/1999/xhtml\">f<a href=\"http://www.jabber.org\">o</a>o</body></html><body>foo</body></message>", msg.ToString());
+            Assert.AreEqual("f<a href=\"http://www.jabber.org\">o</a>o", msg.Html);
+        }
+        [Test] public void Test_NullBody()
+        {
+            Message msg = new Message(doc);
+            Assert.AreEqual(null, msg.Body);
+            msg.Body = "foo";
+            Assert.AreEqual("foo", msg.Body);
+            msg.Body = null;
+            Assert.AreEqual(null, msg.Body);
+        }
+        [Test] public void Test_Normal()
+        {
+            Message msg = new Message(doc);
+            Assert.AreEqual(MessageType.normal, msg.Type);
+            Assert.AreEqual("", msg.GetAttribute("type"));
+            msg.Type = MessageType.chat;
+            Assert.AreEqual(MessageType.chat, msg.Type);
+            Assert.AreEqual("chat", msg.GetAttribute("type"));
+            msg.Type = MessageType.normal;
+            Assert.AreEqual(MessageType.normal, msg.Type);
+            Assert.AreEqual("", msg.GetAttribute("type"));
+        }
+        [Test] public void Test_Escape()
+        {
+            Message msg = new Message(doc);
+            msg.Body = "&";
+            Assert.AreEqual("<message id=\""+msg.ID+"\"><body>&</body></message>", msg.ToString());
+            msg.RemoveChild(msg["body"]);
+            Assert.AreEqual("<message id=\""+msg.ID+"\"></message>", msg.ToString());
+            try
+            {
+                msg.Html = "&";
+                Assert.Fail("should have thrown an exception");
+            }
+            catch
+            {
+                Assert.IsTrue(true, "Threw exception, as expected");
+            }
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/client/PresenceTest.cs b/lib/jabber-net/test/jabber/protocol/client/PresenceTest.cs
new file mode 100644
index 0000000..be228d8
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/client/PresenceTest.cs
@@ -0,0 +1,79 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber.protocol.client;
+
+namespace test.jabber.protocol.client
+{
+    /// <summary>
+    /// Summary description for PresenceTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class PresenceTest
+    {
+        XmlDocument doc = new XmlDocument();
+        [Test] public void Test_Create()
+        {
+            Presence p = new Presence(doc);
+            p.Type   = PresenceType.available;
+            p.Status = "foo";
+            Assert.AreEqual("<presence><status>foo</status></presence>", p.ToString());
+        }
+
+        [Test] public void Test_Available()
+        {
+            Presence p = new Presence(doc);
+            Assert.AreEqual(PresenceType.available, p.Type);
+            Assert.AreEqual("", p.GetAttribute("type"));
+            p.Type = PresenceType.unavailable;
+            Assert.AreEqual(PresenceType.unavailable, p.Type);
+            Assert.AreEqual("unavailable", p.GetAttribute("type"));
+            p.Type = PresenceType.available;
+            Assert.AreEqual(PresenceType.available, p.Type);
+            Assert.AreEqual("", p.GetAttribute("type"));
+        }
+
+        [Test]
+        public void Test_Order()
+        {
+            Presence small = new Presence(doc);
+            DateTime d = DateTime.Now;
+            small.IntPriority = 0;
+            small.Stamp = d;
+
+            Presence big = new Presence(doc);
+            big.IntPriority = 10;
+            big.Stamp = d.AddSeconds(1);
+
+            Assert.IsTrue(small < big);
+            Assert.IsTrue(big > small);
+
+            small.IntPriority = 10;
+            small.Show = "dnd";
+            Assert.IsTrue(small < big);
+
+            big.Show = "chat";
+            Assert.IsTrue(small < big);
+
+            small.Show = "chat";
+            Assert.IsTrue(small < big);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/iq/AgentTest.cs b/lib/jabber-net/test/jabber/protocol/iq/AgentTest.cs
new file mode 100644
index 0000000..031a1db
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/iq/AgentTest.cs
@@ -0,0 +1,90 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber;
+using jabber.protocol;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+
+namespace test.jabber.protocol.iq
+{
+    /// <summary>
+    /// Test Agents
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class AgentTest
+    {
+        XmlDocument doc = new XmlDocument();
+        [SetUp]
+        public void SetUp()
+        {
+            Element.ResetID();
+        }
+        [Test] public void Test_Create()
+        {
+            AgentsQuery r = new AgentsQuery(doc);
+            Assert.AreEqual("<query xmlns=\"jabber:iq:agents\" />", r.ToString());
+        }
+
+        [Test] public void Test_Item()
+        {
+            AgentsIQ aiq = new AgentsIQ(doc);
+            AgentsQuery q = (AgentsQuery) aiq.Query;
+            Agent a = q.AddAgent();
+            a.JID = new JID("hildjj at jabber.com");
+            Assert.AreEqual("<iq id=\""+aiq.ID+"\" type=\"get\"><query xmlns=\"jabber:iq:agents\">" +
+                "<agent jid=\"hildjj at jabber.com\" /></query></iq>",
+                aiq.ToString());
+        }
+        [Test] public void Test_GetItems()
+        {
+            AgentsIQ aiq = new AgentsIQ(doc);
+            AgentsQuery r = (AgentsQuery) aiq.Query;
+            Agent a = r.AddAgent();
+            a.JID = new JID("hildjj at jabber.com");
+            a = r.AddAgent();
+            a.JID = new JID("hildjj at jabber.org");
+            Agent[] agents = r.GetAgents();
+            Assert.AreEqual(agents.Length, 2);
+            Assert.AreEqual(agents[0].JID, "hildjj at jabber.com");
+            Assert.AreEqual(agents[1].JID, "hildjj at jabber.org");
+        }
+        [Test] public void Test_Transport()
+        {
+            AgentsIQ aiq = new AgentsIQ(doc);
+            aiq.Type = IQType.result;
+            AgentsQuery r = (AgentsQuery) aiq.Query;
+            Agent a = r.AddAgent();
+            a.JID = new JID("hildjj at jabber.com");
+            a.Transport = true;
+            Assert.AreEqual(a.Transport, true);
+            Assert.AreEqual("<iq id=\""+aiq.ID+"\" type=\"result\"><query xmlns=\"jabber:iq:agents\">" +
+                "<agent jid=\"hildjj at jabber.com\"><transport /></agent></query></iq>",
+                aiq.ToString());
+            a.Transport = false;
+            Assert.AreEqual(a.Transport, false);
+            a.Groupchat = true;
+            Assert.AreEqual(a.Groupchat, true);
+            Assert.AreEqual("<iq id=\""+aiq.ID+"\" type=\"result\"><query xmlns=\"jabber:iq:agents\">" +
+                "<agent jid=\"hildjj at jabber.com\"><groupchat /></agent></query></iq>",
+                aiq.ToString());
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/iq/AuthTest.cs b/lib/jabber-net/test/jabber/protocol/iq/AuthTest.cs
new file mode 100644
index 0000000..9866f08
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/iq/AuthTest.cs
@@ -0,0 +1,78 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber.protocol;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+
+namespace test.jabber.protocol.iq
+{
+    /// <summary>
+    /// Summary description for AuthTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class AuthTest
+    {
+        XmlDocument doc = new XmlDocument();
+        [SetUp]
+        public void SetUp()
+        {
+            Element.ResetID();
+        }
+        [Test] public void Test_Create()
+        {
+            IQ iq = new AuthIQ(doc);
+            Assert.AreEqual("<iq id=\""+iq.ID+"\" type=\"get\"><query xmlns=\"jabber:iq:auth\" /></iq>", iq.ToString());
+        }
+        [Test] public void Test_Hash()
+        {
+            IQ iq = new AuthIQ(doc);
+            iq.Type = IQType.set;
+            Auth a = (Auth) iq.Query;
+            a.SetDigest("foo", "bar", "3B513636");
+            a.Resource = "Home";
+            Assert.AreEqual("<iq id=\""+iq.ID+"\" type=\"set\"><query xmlns=\"jabber:iq:auth\">" +
+                "<username>foo</username>" +
+                "<digest>37d9c887967a35d53b81f07916a309a5b8d7e8cc</digest>" +
+                "<resource>Home</resource>" +
+                "</query></iq>",
+                iq.ToString());
+        }
+        /*
+        SENT: <iq type="get" id="JCOM_14"><query xmlns="jabber:iq:auth"><username>zeroktest</username></query></iq>
+        RECV: <iq id='JCOM_14' type='result'><query xmlns='jabber:iq:auth'><username>zeroktest</username><password/><digest/><sequence>499</sequence><token>3C7A6B0A</token><resource/></query></iq>
+        SENT: <iq type="set" id="JCOM_15"><query xmlns="jabber:iq:auth"><username>zeroktest</username><hash>e00c83748492a3bc7e4831c9e973d117082c3abe</hash><resource>Winjab</resource></query></iq>
+        */
+        [Test] public void Test_ZeroK()
+        {
+            IQ iq = new AuthIQ(doc);
+            iq.Type = IQType.set;
+            Auth a = (Auth) iq.Query;
+            a.SetZeroK("zeroktest", "test", "3C7A6B0A", 499);
+            a.Resource = "Winjab";
+            Assert.AreEqual("<iq id=\""+iq.ID+"\" type=\"set\"><query xmlns=\"jabber:iq:auth\">" +
+                "<username>zeroktest</username>" +
+                "<hash>e00c83748492a3bc7e4831c9e973d117082c3abe</hash>" +
+                "<resource>Winjab</resource>" +
+                "</query></iq>",
+                iq.ToString());
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/iq/PubSubTest.cs b/lib/jabber-net/test/jabber/protocol/iq/PubSubTest.cs
new file mode 100644
index 0000000..2effc62
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/iq/PubSubTest.cs
@@ -0,0 +1,57 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System.Xml;
+using bedrock.util;
+using jabber.protocol.iq;
+using NUnit.Framework;
+
+namespace test.jabber.protocol.iq
+{
+    [TestFixture]
+    [SVN(@"$Id$")]
+    public class PubSubTest
+    {
+        private const string NODE = "TestNode";
+
+        private XmlDocument doc;
+
+        [SetUp]
+        public void Setup()
+        {
+            doc = new XmlDocument();
+        }
+
+        [Test]
+        public void AffiliationsTest()
+        {
+            PubSubIQ iq = new PubSubIQ(doc, PubSubCommandType.affiliations, NODE);
+            Affiliations test = iq.Command as Affiliations;
+            Assert.IsNotNull(test);
+        }
+
+        [Test]
+        public void PubSubCreateTest()
+        {
+            PubSubIQ iq = new PubSubIQ(doc, PubSubCommandType.create, NODE);
+            Assert.IsFalse(((Create)iq.Command).HasConfigure);
+
+            Create create = (Create)iq.Command;
+
+            create.HasConfigure = true;
+            Assert.IsTrue(create.HasConfigure);
+            Assert.IsNotNull(create.GetConfiguration());
+        }
+
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/iq/RegisterTest.cs b/lib/jabber-net/test/jabber/protocol/iq/RegisterTest.cs
new file mode 100644
index 0000000..7aa7727
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/iq/RegisterTest.cs
@@ -0,0 +1,52 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber;
+using jabber.protocol;
+using jabber.protocol.iq;
+
+namespace test.jabber.protocol.iq
+{
+    /// <summary>
+    /// Summary description for RosterTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class RegisterTest
+    {
+        XmlDocument doc = new XmlDocument();
+        [SetUp]
+        public void SetUp()
+        {
+            Element.ResetID();
+        }
+        [Test] public void Test_Create()
+        {
+            Register r = new Register(doc);
+            Assert.AreEqual("<query xmlns=\"jabber:iq:register\" />", r.ToString());
+        }
+        [Test] public void Test_Registered()
+        {
+            Register r = new Register(doc);
+            r.Registered = true;
+            Assert.AreEqual("<query xmlns=\"jabber:iq:register\"><registered /></query>", r.ToString());
+            Assert.IsTrue(r.Registered);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/iq/RosterTest.cs b/lib/jabber-net/test/jabber/protocol/iq/RosterTest.cs
new file mode 100644
index 0000000..7cfdc47
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/iq/RosterTest.cs
@@ -0,0 +1,110 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber;
+using jabber.protocol;
+using jabber.protocol.iq;
+
+namespace test.jabber.protocol.iq
+{
+    /// <summary>
+    /// Summary description for RosterTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class RosterTest
+    {
+        XmlDocument doc = new XmlDocument();
+        [SetUp]
+        public void SetUp()
+        {
+            Element.ResetID();
+        }
+        [Test] public void Test_Create()
+        {
+            Roster r = new Roster(doc);
+            Assert.AreEqual("<query xmlns=\"jabber:iq:roster\" />", r.ToString());
+        }
+
+        [Test] public void Test_Item()
+        {
+            RosterIQ riq = new RosterIQ(doc);
+            Roster r = riq.Instruction;
+            Item i = r.AddItem();
+            i.JID = new JID("hildjj at jabber.com");
+            Assert.AreEqual("<iq id=\""+riq.ID+"\" type=\"get\"><query xmlns=\"jabber:iq:roster\">" +
+                "<item jid=\"hildjj at jabber.com\" /></query></iq>",
+                riq.ToString());
+        }
+        [Test] public void Test_GetItems()
+        {
+            RosterIQ riq = new RosterIQ(doc);
+            Roster r = riq.Instruction;
+            Item i = r.AddItem();
+            i.JID = new JID("hildjj at jabber.com");
+            i = r.AddItem();
+            i.Subscription = Subscription.from;
+            i.JID = new JID("hildjj at jabber.org");
+            i.Subscription = Subscription.both;
+            Item[] items = r.GetItems();
+            Assert.AreEqual(items.Length, 2);
+            Assert.AreEqual(items[0].JID, "hildjj at jabber.com");
+            Assert.AreEqual(items[1].JID, "hildjj at jabber.org");
+        }
+        [Test] public void Test_Groups()
+        {
+            RosterIQ riq = new RosterIQ(doc);
+            Roster r = riq.Instruction;
+            Item i = r.AddItem();
+            i.JID = new JID("hildjj at jabber.com");
+            Group g = i.AddGroup("foo");
+            Assert.AreEqual("<iq id=\""+riq.ID+"\" type=\"get\"><query xmlns=\"jabber:iq:roster\">" +
+                "<item jid=\"hildjj at jabber.com\"><group>foo</group></item></query></iq>",
+                riq.ToString());
+            g = i.AddGroup("foo");
+            Assert.AreEqual("<iq id=\""+riq.ID+"\" type=\"get\"><query xmlns=\"jabber:iq:roster\">" +
+                "<item jid=\"hildjj at jabber.com\"><group>foo</group></item></query></iq>",
+                riq.ToString());
+            g = i.AddGroup("bar");
+            Assert.AreEqual("<iq id=\""+riq.ID+"\" type=\"get\"><query xmlns=\"jabber:iq:roster\">" +
+                "<item jid=\"hildjj at jabber.com\"><group>foo</group><group>bar</group></item></query></iq>",
+                riq.ToString());
+            Assert.AreEqual(2, i.GetGroups().Length);
+            Assert.AreEqual("foo", i.GetGroup("foo").GroupName);
+            Assert.AreEqual("bar", i.GetGroup("bar").GroupName);
+            i.RemoveGroup("foo");
+            Assert.AreEqual(1, i.GetGroups().Length);
+            Assert.AreEqual(null, i.GetGroup("foo"));
+        }
+        [Test] public void Test_Ask()
+        {
+            RosterIQ riq = new RosterIQ(doc);
+            Roster r = riq.Instruction;
+            Item i = r.AddItem();
+            Assert.AreEqual("", i.GetAttribute("ask"));
+            Assert.AreEqual(Ask.NONE, i.Ask);
+            i.Ask = Ask.subscribe;
+            Assert.AreEqual("subscribe", i.GetAttribute("ask"));
+            Assert.AreEqual(Ask.subscribe, i.Ask);
+            i.Ask = Ask.NONE;
+            Assert.AreEqual("", i.GetAttribute("ask"));
+            Assert.AreEqual(Ask.NONE, i.Ask);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/iq/TimeTest.cs b/lib/jabber-net/test/jabber/protocol/iq/TimeTest.cs
new file mode 100644
index 0000000..1772473
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/iq/TimeTest.cs
@@ -0,0 +1,48 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber;
+using jabber.protocol;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+
+namespace test.jabber.protocol.iq
+{
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class TimeTest
+    {
+        [Test]
+        public void UTC()
+        {
+            XmlDocument doc = new XmlDocument();
+            TimeIQ iq = new TimeIQ(doc);
+            Time t = iq.Instruction;
+            t.AddChild(doc.CreateElement("utc", t.NamespaceURI));
+            Assert.AreEqual(DateTime.MinValue, t.UTC);
+            DateTime start = DateTime.UtcNow;
+            t.SetCurrentTime();
+
+            // SetCurrentTime only stores seconds portion, whereas UtcNow has all 
+            // kinds of precision.  Are we within a second of being correct?
+            TimeSpan ts = t.UTC - start;
+            Assert.IsTrue(Math.Abs(ts.TotalSeconds) < 1.0);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/stream/FactoryTest.cs b/lib/jabber-net/test/jabber/protocol/stream/FactoryTest.cs
new file mode 100644
index 0000000..d9a4d54
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/stream/FactoryTest.cs
@@ -0,0 +1,37 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber.protocol;
+using fact = jabber.protocol.stream.Factory;
+
+namespace test.jabber.protocol.stream
+{
+    /// <summary>
+    /// Summary description for StreamFactoryTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class StreamFactoryTest
+    {
+        [Test] public void Test_Create()
+        {
+            ElementFactory pf = new ElementFactory();
+            pf.AddType(new fact());
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/stream/StreamTest.cs b/lib/jabber-net/test/jabber/protocol/stream/StreamTest.cs
new file mode 100644
index 0000000..8b27875
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/stream/StreamTest.cs
@@ -0,0 +1,64 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+using System.Text.RegularExpressions;
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber.protocol;
+using jabber.protocol.stream;
+using fact = jabber.protocol.stream.Factory;
+
+namespace test.jabber.protocol.stream
+{
+    /// <summary>
+    /// Summary description for StreamTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class StreamTest
+    {
+        XmlDocument doc = new XmlDocument();
+        [Test] public void Test_Create()
+        {
+            Stream s = new Stream(doc, "jabber:client");
+            Assert.IsTrue(
+                Regex.IsMatch(s.ToString(),
+                "<stream:stream id=\"[a-z0-9]+\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx\\.jabber\\.org/streams\" />",
+                RegexOptions.IgnoreCase), s.ToString());
+        }
+        [Test] public void Test_Error()
+        {
+            Error err = new Error(doc);
+            err.Message = "foo";
+            Assert.AreEqual("<stream:error " +
+                "xmlns:stream=\"http://etherx.jabber.org/streams\">foo</stream:error>", err.ToString());
+            ElementFactory sf = new ElementFactory();
+            sf.AddType(new fact());
+            XmlQualifiedName qname = new XmlQualifiedName(err.LocalName, err.NamespaceURI);
+            Element p = (Element) sf.GetElement(err.Prefix, qname, doc);
+            Assert.AreEqual(typeof(Error), p.GetType());
+        }
+        [Test] public void Test_StartTag()
+        {
+            Stream s = new Stream(doc, "jabber:client");
+            Assert.IsTrue(
+                Regex.IsMatch(s.StartTag(),
+                "<stream:stream xmlns:stream=\"http://etherx\\.jabber\\.org/streams\" id=\"[a-z0-9]+\" xmlns=\"jabber:client\">",
+                RegexOptions.IgnoreCase), s.StartTag());
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/x/DataTest.cs b/lib/jabber-net/test/jabber/protocol/x/DataTest.cs
new file mode 100644
index 0000000..c1e1223
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/x/DataTest.cs
@@ -0,0 +1,130 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.IO;
+using System.Xml;
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber.protocol;
+using jabber.protocol.x;
+
+namespace test.jabber.protocol.x
+{
+    /// <summary>
+    /// Summary description for DataTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class DataTest
+    {
+        private bool gotElement = false;
+
+        private const string tstring = @"<stream><x xmlns='jabber:x:data'>
+      <instructions>
+        Welcome to the BloodBank-Service!  We thank you for registering with
+        us and helping to save lives.  Please fill out the following form.
+      </instructions>
+      <field type='hidden' var='form_number'>
+        <value>113452</value>
+      </field>
+      <field type='fixed'>
+        <value>We need your contact information.</value>
+      </field>
+      <field type='text-single' label='First Name' var='first'>
+        <required/>
+      </field>
+      <field type='text-single' label='Last Name' var='last'>
+        <required/>
+      </field>
+      <field type='list-single' label='Gender' var='gender'>
+        <value>male</value>
+        <option label='Male'><value>male</value></option>
+        <option label='Female'><value>female</value></option>
+      </field>
+      <field type='fixed'>
+        <value>We need your blood information.</value>
+      </field>
+      <field type='list-single' label='Blood Type' var='blood_type'>
+        <required/>
+        <value>a+</value>
+        <option label='A-Positive'><value>a+</value></option>
+        <option label='B-Negative'><value>b-</value></option>
+        etc...
+      </field>
+      <field type='list-single' label='Pints to give' var='pints'>
+        <required/>
+        <value>2</value>
+        <option label='Zero'><value>0</value></option>
+        <option label='One'><value>1</value></option>
+        <option label='Two'><value>2</value></option>
+        <option label='Three'><value>3</value></option>
+      </field>
+      <field type='boolean' label='Willing to donate' var='willing'>
+        <required/>
+        <value>1</value>
+      </field>
+    </x></stream>";
+
+        [Test] public void Test_Parse()
+        {
+            AsynchElementStream es = new AsynchElementStream();
+            es.AddFactory(new global::jabber.protocol.x.Factory());
+            es.OnElement += new ProtocolHandler(es_OnElement);
+            es.Push(System.Text.Encoding.UTF8.GetBytes(tstring));
+
+            Assert.IsTrue(gotElement);
+        }
+
+        void es_OnElement(object sender, XmlElement n)
+        {
+            Assert.IsInstanceOfType(typeof(global::jabber.protocol.x.Data), n);
+            Data d = (Data)n;
+            Assert.AreEqual(@"
+        Welcome to the BloodBank-Service!  We thank you for registering with
+        us and helping to save lives.  Please fill out the following form.
+      ", d.Instructions);
+            Field[] fields = d.GetFields();
+            Assert.AreEqual(9, fields.Length);
+            Assert.AreEqual("2", fields[7].Val);
+            Assert.AreEqual(true, fields[7].IsRequired);
+            Assert.AreEqual(false, fields[4].IsRequired);
+            Assert.AreEqual("Pints to give", fields[7].Label);
+            Assert.AreEqual("pints", fields[7].Var);
+            Assert.AreEqual(FieldType.list_single, fields[7].Type);
+            Assert.AreEqual(d.GetField("pints").Label, "Pints to give");
+
+            Option[] options = fields[7].GetOptions();
+            Assert.AreEqual(4, options.Length);
+            Assert.AreEqual("Two", options[2].Label);
+            Assert.AreEqual("2", options[2].Val);
+            gotElement = true;
+        }
+
+        [Test]
+        public void Test_Convert()
+        {
+            XmlDocument doc = new XmlDocument();
+            doc.LoadXml(tstring);
+
+            ElementFactory f = new ElementFactory();
+            f.AddType(new global::jabber.protocol.x.Factory());
+
+            Element stream = Element.AddTypes(doc.DocumentElement, f);
+            Data d = stream.GetChildElement<global::jabber.protocol.x.Data>();
+            Assert.IsNotNull(d);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/jabber/protocol/x/EventTest.cs b/lib/jabber-net/test/jabber/protocol/x/EventTest.cs
new file mode 100644
index 0000000..31b4016
--- /dev/null
+++ b/lib/jabber-net/test/jabber/protocol/x/EventTest.cs
@@ -0,0 +1,58 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+
+using System.Xml;
+using NUnit.Framework;
+
+using bedrock.util;
+using jabber.protocol;
+using jabber.protocol.x;
+
+namespace test.jabber.protocol.x
+{
+    /// <summary>
+    /// Summary description for AuthTest.
+    /// </summary>
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class EventTest
+    {
+        XmlDocument doc = new XmlDocument();
+        [SetUp]
+        public void SetUp()
+        {
+            Element.ResetID();
+        }
+        [Test] public void Test_Create()
+        {
+            Event e = new Event(doc);
+            Assert.AreEqual("<x xmlns=\"jabber:x:event\" />", e.ToString());
+            e.ID = "foo";
+            Assert.AreEqual("<x xmlns=\"jabber:x:event\"><id>foo</id></x>", e.ToString());
+            Assert.AreEqual("foo", e.ID);
+            Assert.AreEqual(EventType.NONE, e.Type);
+            e.Type = EventType.composing;
+            Assert.AreEqual(EventType.composing, e.Type);
+            e.Type = EventType.delivered;
+            Assert.AreEqual(EventType.delivered, e.Type);
+            Assert.AreEqual("<x xmlns=\"jabber:x:event\"><id>foo</id><delivered /></x>", e.ToString());
+            Assert.AreEqual(true, e.IsDelivered);
+            Assert.AreEqual(false, e.IsComposing);
+            e.IsComposing = true;
+            Assert.AreEqual("<x xmlns=\"jabber:x:event\"><id>foo</id><delivered /><composing /></x>", e.ToString());
+            Assert.AreEqual(EventType.composing | EventType.delivered, e.Type);
+        }
+    }
+}
diff --git a/lib/jabber-net/test/stringprep/TestDecompose.cs b/lib/jabber-net/test/stringprep/TestDecompose.cs
new file mode 100644
index 0000000..9685364
--- /dev/null
+++ b/lib/jabber-net/test/stringprep/TestDecompose.cs
@@ -0,0 +1,37 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net can be used under either JOSL or the GPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+#if !NO_STRINGPREP
+
+using System;
+using NUnit.Framework;
+using stringprep.unicode;
+
+namespace test.stringprep
+{
+    /// <summary>
+    /// Summary description for TestGeneric.
+    /// </summary>
+    [TestFixture]
+    public class TestDecompose
+    {
+        public void Test_Decomp()
+        {
+            char[] d = Decompose.Find('\x2000');
+            Assertion.AssertNotNull(d);
+            Assertion.AssertEquals(1, d.Length);
+            Assertion.AssertEquals('\x0020', d[0]);
+        }
+    }
+}
+#endif
diff --git a/lib/jabber-net/test/stringprep/TestDraft.cs b/lib/jabber-net/test/stringprep/TestDraft.cs
new file mode 100644
index 0000000..6571b30
--- /dev/null
+++ b/lib/jabber-net/test/stringprep/TestDraft.cs
@@ -0,0 +1,669 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+#if !NO_STRINGPREP
+
+
+using System;
+using NUnit.Framework;
+using stringprep;
+using stringprep.steps;
+using bedrock.util;
+
+namespace test.stringprep
+{
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class TestDraft
+    {
+        private Profile nameprep = new Nameprep();
+
+        // 4.1 Map to nothing
+        [Test] public void Test_4_01()
+        {
+            string input = "\x0066\x006f\x006f\x00ad\x034f\x1806\x180b\x0062\x0061\x0072\x200b\x2060\x0062\x0061\x007a\xfe00\xfe08\xfe0f\xfeff";
+            string expected = "\x0066\x006f\x006f\x0062\x0061\x0072\x0062\x0061\x007a";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.2 Case folding ASCII U+0043 U+0041 U+0046 U+0045
+        [Test] public void Test_4_02()
+        {
+            string input = "\x0043\x0041\x0046\x0045";
+            string expected = "\x0063\x0061\x0066\x0065";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.3 Case folding 8bit U+00DF (german sharp s)
+        [Test] public void Test_4_03()
+        {
+            string input = "\x00df";
+            string expected = "\x0073\x0073";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.4 Case folding U+0130 (turkish capital I with dot)
+        [Test] public void Test_4_04()
+        {
+            string input = "\x0130";
+            string expected = "\x0069\x0307";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.5 Case folding multibyte U+0143 U+037A
+        [Test] public void Test_4_05()
+        {
+            string input = "\x0143\x037a";
+            string expected = "\x0144\x0020\x03b9";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        [Ignore("fails, due to lack of UTF-16 in .Net")]
+        // 4.6 Case folding U+2121 U+33C6 U+1D7BB
+        [Test] public void Test_4_06()
+        {
+            string input = "\x2121\x33c6\xd835\xdfbb";
+            string expected = "\x0074\x0065\x006c\x0063\x2215\x006b\x0067\x03c3";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.7 Normalization of U+006a U+030c U+00A0 U+00AA
+        [Test] public void Test_4_07()
+        {
+            string input = "\x006a\x030c\x00a0\x00aa";
+            string expected = "\x01f0\x0020\x0061";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.8 Case folding U+1FB7 and normalization
+        [Test] public void Test_4_08()
+        {
+            string input = "\x1fb7";
+            string expected = "\x1fb6\x03b9";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.9 Self-reverting case folding U+01F0 and normalization
+        [Test] public void Test_4_09()
+        {
+            string input = "\x01f0";
+            string expected = "\x01f0";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.10 Self-reverting case folding U+0390 and normalization
+        [Test] public void Test_4_10()
+        {
+            string input = "\x0390";
+            string expected = "\x0390";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.11 Self-reverting case folding U+03B0 and normalization
+        [Test] public void Test_4_11()
+        {
+            string input = "\x03b0";
+            string expected = "\x03b0";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.12 Self-reverting case folding U+1E96 and normalization
+        [Test] public void Test_4_12()
+        {
+            string input = "\x1e96";
+            string expected = "\x1e96";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.13 Self-reverting case folding U+1F56 and normalization
+        [Test] public void Test_4_13()
+        {
+            string input = "\x1f56";
+            string expected = "\x1f56";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.14 ASCII space character U+0020
+        [Test] public void Test_4_14()
+        {
+            string input = "\x0020";
+            string expected = "\x0020";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.15 Non-ASCII 8bit space character U+00A0
+        [Test] public void Test_4_15()
+        {
+            string input = "\x00a0";
+            string expected = "\x0020";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.16 Non-ASCII multibyte space character U+1680
+        [Test] public void Test_4_16()
+        {
+            string input = "\x1680";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.17 Non-ASCII multibyte space character U+2000
+        [Test] public void Test_4_17()
+        {
+            string input = "\x2000";
+            string expected = "\x0020";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.18 Zero Width Space U+200b
+        [Test] public void Test_4_18()
+        {
+            string input = "\x200b";
+            string expected = "";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.19 Non-ASCII multibyte space character U+3000
+        [Test] public void Test_4_19()
+        {
+            string input = "\x3000";
+            string expected = "\x0020";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.20 ASCII control characters U+0010 U+007F
+        [Test] public void Test_4_20()
+        {
+            string input = "\x0010\x007f";
+            string expected = "\x0010\x007f";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.21 Non-ASCII 8bit control character U+0085
+        [Test] public void Test_4_21()
+        {
+            string input = "\x0085";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.22 Non-ASCII multibyte control character U+180E
+        [Test] public void Test_4_22()
+        {
+            string input = "\x180e";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.23 Zero Width No-Break Space U+FEFF
+        [Test] public void Test_4_23()
+        {
+            string input = "\xfeff";
+            string expected = "";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.24 Non-ASCII control character U+1D175
+        [Test] public void Test_4_24()
+        {
+            string input = "\xd834\xdd75";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.25 Plane 0 private use character U+F123
+        [Test] public void Test_4_25()
+        {
+            string input = "\xf123";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.26 Plane 15 private use character U+F1234
+        [Test] public void Test_4_26()
+        {
+            string input = "\xdb84\xde34";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.27 Plane 16 private use character U+10F234
+        [Test] public void Test_4_27()
+        {
+            string input = "\xdbfc\xde34";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.28 Non-character code point U+8FFFE
+        [Test] public void Test_4_28()
+        {
+            string input = "\xd9ff\xdffe";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.29 Non-character code point U+10FFFF
+        [Test] public void Test_4_29()
+        {
+            string input = "\xdbff\xdfff";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.30 Surrogate code U+DF42
+        [Test] public void Test_4_30()
+        {
+            string input = "\xdf42";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.31 Non-plain text character U+FFFD
+        [Test] public void Test_4_31()
+        {
+            string input = "\xfffd";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.32 Ideographic description character U+2FF5
+        [Test] public void Test_4_32()
+        {
+            string input = "\x2ff5";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.33 Display property character U+0341
+        [Test] public void Test_4_33()
+        {
+            string input = "\x0341";
+            string expected = "\x0301";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.34 Left-to-right mark U+200E
+        [Test] public void Test_4_34()
+        {
+            string input = "\x200e";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.35 Deprecated U+202A
+        [Test] public void Test_4_35()
+        {
+            string input = "\x202a";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.36 Language tagging character U+E0001
+        [Test] public void Test_4_36()
+        {
+            string input = "\xdb40\xdc01";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.37 Language tagging character U+E0042
+        [Test] public void Test_4_37()
+        {
+            string input = "\xdb40\xdc42";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.38 Bidi: RandALCat character U+05BE and LCat characters
+        [Test] public void Test_4_38()
+        {
+            string input = "\x0066\x006f\x006f\x05be\x0062\x0061\x0072";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected BidiException");
+            }
+            catch (BidiException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected BidiException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.39 Bidi: RandALCat character U+FD50 and LCat characters
+        [Test] public void Test_4_39()
+        {
+            string input = "\x0066\x006f\x006f\xfd50\x0062\x0061\x0072";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected BidiException");
+            }
+            catch (BidiException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected BidiException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.40 Bidi: RandALCat character U+FB38 and LCat characters
+        [Test] public void Test_4_40()
+        {
+            string input = "\x0066\x006f\x006f\xfe76\x0062\x0061\x0072";
+            string expected = "\x0066\x006f\x006f\x0020\x064e\x0062\x0061\x0072";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.41 Bidi: RandALCat without trailing RandALCat U+0627 U+0031
+        [Test] public void Test_4_41()
+        {
+            string input = "\x0627\x0031";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected BidiException");
+            }
+            catch (BidiException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected BidiException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.42 Bidi: RandALCat character U+0627 U+0031 U+0628
+        [Test] public void Test_4_42()
+        {
+            string input = "\x0627\x0031\x0628";
+            string expected = "\x0627\x0031\x0628";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.43 Unassigned code point U+E0002
+        [Test] public void Test_4_43()
+        {
+            string input = "\xdb40\xdc02";
+            string expected = "";
+            try
+            {
+                expected = nameprep.Prepare(input);
+                Assert.Fail("Expected ProhibitedCharacterException");
+            }
+            catch (ProhibitedCharacterException)
+            {
+            }
+            catch (AssertionException)
+            {
+                throw;
+            }
+            catch (Exception e)
+            {
+               Assert.Fail("Expected ProhibitedCharacterException, got " + e.GetType().ToString());
+            }
+        }
+
+        // 4.44 Larger test (shrinking)
+        [Test] public void Test_4_44()
+        {
+            string input = "\x0058\x00ad\x00df\x0130\x2121\x006a\x030c\x00a0\x00aa\x03b0\x2000";
+            string expected = "\x0078\x0073\x0073\x0069\x0307\x0074\x0065\x006c\x01f0\x0020\x0061\x03b0\x0020";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+        // 4.45 Larger test (expanding)
+        [Test] public void Test_4_45()
+        {
+            string input = "\x0058\x00df\x3316\x0130\x2121\x249f\x3300";
+            string expected = "\x0078\x0073\x0073\x30ad\x30ed\x30e1\x30fc\x30c8\x30eb\x0069\x0307\x0074\x0065\x006c\x0028\x0064\x0029\x30a2\x30d1\x30fc\x30c8";
+            Assert.AreEqual(expected, nameprep.Prepare(input));
+        }
+    }
+}
+#endif
diff --git a/lib/jabber-net/test/stringprep/TestNFKC.cs b/lib/jabber-net/test/stringprep/TestNFKC.cs
new file mode 100644
index 0000000..c785180
--- /dev/null
+++ b/lib/jabber-net/test/stringprep/TestNFKC.cs
@@ -0,0 +1,146 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+#if !NO_STRINGPREP
+
+using System;
+using System.Text;
+using NUnit.Framework;
+using stringprep;
+using stringprep.steps;
+using bedrock.util;
+
+namespace test.stringprep
+{
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class TestNFKC
+    {
+        System.Text.Encoding UTF8 = System.Text.Encoding.UTF8;
+        NFKCStep step = new NFKCStep();
+
+        private void TryOne(string input, string expected)
+        {
+            StringBuilder i = new StringBuilder(input);
+            step.Prepare(i);
+            Assert.AreEqual(expected, i.ToString());
+        }
+
+        [Test] public void Test_1()
+        {
+            TryOne(UTF8.GetString(new byte[] {0xC2, 0xB5}), UTF8.GetString(new byte[] {0xCE, 0xBC}));
+        }
+
+        [Test] public void Test_2()
+        {
+            TryOne(UTF8.GetString(new byte[] {0xC2, 0xAA}), UTF8.GetString(new byte[] {0x61}));
+        }
+
+        [Test] public void Test_Normalization()
+        {
+            // http://www.unicode.org/unicode/faq/normalization.html
+            TryOne("\x03D3", "\x038E");
+        }
+
+        [Test] public void Test_Gurmukhi()
+        {
+            // http://www.unicode.org/charts/normalization/
+            TryOne("\x0a59", "\x0a16\x0a3c");
+            TryOne("\x0a5a", "\x0a17\x0a3c");
+            TryOne("\x0a5b", "\x0a1c\x0A3C");
+            TryOne("\x0A5E", "\x0A2B\x0A3C");
+            TryOne("\x0A33", "\x0A32\x0A3C");
+            TryOne("\x0A36", "\x0A38\x0A3C");
+        }
+
+        [Test] public void Test_Unchanged()
+        {
+            TryOne("\x0144\x0020\x03b9", "\x0144\x0020\x03b9");
+        }
+
+        [Test] public void Test_Navajo()
+        {
+            // a + ogonek + acute ==> a-ogonek + acute
+            TryOne("\x0061\x0328\x0301", "\x0105\x0301");
+            // i + ogonek + acute ==> i-ogonek + acute
+            TryOne("i\x0328\x0301", "\x012F\x0301");
+        }
+
+        [Test] public void Test_CannonicalOrdering()
+        {
+            // From Unicode 3.2, section 3.10
+
+            // The NFKC stuff does a Compose after these are specified, though.
+
+            // a-diaeresis + underdot => a + underdot + diaeresis
+            TryOne("\x00e4\x0323", "\x1ea1\x0308");
+            TryOne("\x00e4\x0323\x00e4\x0323\x00e4\x0323", "\x1ea1\x0308\x1ea1\x0308\x1ea1\x0308");
+
+            // a + diaeresis + underdot => a + underdot + diaeresis
+            TryOne("a\x0308\x0323", "\x1ea1\x0308");
+
+            // a + underdot + diaeresis => a + underdot + diaeresis
+            TryOne("a\x0323\x0308", "\x1ea1\x0308");
+
+            // a-underdot + diaeresis => a + underdot + diaeresis
+            TryOne("\x1ea1\x0308", "\x1ea1\x0308");
+
+
+            // a-diaeresis + breve => a + diaeresis + breve
+            TryOne("\x00e4\x0306", "\x00e4\x0306");
+
+            // a + diaeresis + breve => a + diaeresis + breve
+            TryOne("a\x0308\x0306", "\x00e4\x0306");
+
+            // a + breve + diaeresis => a + breve + diaeresis
+            TryOne("a\x0306\x0308", "\x0103\x0308");
+
+            // a-breve + diaeresis => a + breve + diaeresis
+            TryOne("\x0103\x0308", "\x0103\x0308");
+        }
+
+        [Test] public void Test_TR15_Annex_1()
+        {
+            TryOne("\x1E0A", "\x1E0A"); //a
+            TryOne("D\x0307", "\x1E0A"); //b
+            TryOne("\x1E0C\x0307", "\x1E0C\x0307"); //c
+            TryOne("\x1E0A\x0323", "\x1E0C\x0307"); //d
+            TryOne("D\x0307\x0323", "\x1E0C\x0307"); //e
+            TryOne("D\x0307\x031B\x0323", "\x1E0C\x031B\x0307"); //f
+            TryOne("\x1E14", "\x1E14"); //g
+            TryOne("\x0112\x0300", "\x1E14"); //h
+            TryOne("\x00C8\x0304", "\x00C8\x0304"); //i
+            TryOne("\x212B", "\x00C5"); //j
+            TryOne("\x00C5", "\x00C5"); //k
+
+            TryOne("Äffin", "Äffin"); //l'
+            TryOne("Ä\xFB03n", "Äffin"); //m'
+            TryOne("Henry IV", "Henry IV"); //n'
+            TryOne("Henry \x2163", "Henry IV"); //o'
+            TryOne("\x30AC", "\x30AC"); //p' ga
+            TryOne("\x30AB\x3099", "\x30AC"); //q' ka + ten
+            TryOne("\xFF76\xFF9E", "\x30AC"); //r' hw_ka + hw_ten
+            TryOne("\x30AB\xFF9E", "\x30AC"); //s' ka + hw_ten
+            TryOne("\xFF76\x3099", "\x30AC"); //t' hw_ka + ten
+            // TryOne("", ""); // can't find "kaks": I think it's Hangul.
+        }
+
+        // http://www.unicode.org/review/pr-29.html
+        [Test] public void Test_PR29()
+        {
+            //TODO: Try again with NFC, rather than NFKC.
+            TryOne("\x1100\x0300\x1161", "\x1100\x0300\x1161");
+        }
+    }
+}
+#endif
diff --git a/lib/jabber-net/test/stringprep/TestNameprep.cs b/lib/jabber-net/test/stringprep/TestNameprep.cs
new file mode 100644
index 0000000..35d2e76
--- /dev/null
+++ b/lib/jabber-net/test/stringprep/TestNameprep.cs
@@ -0,0 +1,359 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+#if !NO_STRINGPREP
+
+using System;
+using NUnit.Framework;
+using stringprep;
+using stringprep.steps;
+using bedrock.util;
+
+namespace test.stringprep
+{
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class TestNameprep
+    {
+        private static System.Text.Encoding ENC = System.Text.Encoding.UTF8;
+
+        private Profile nameprep = new Nameprep();
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="p"></param>
+        /// <param name="input">string with one UTF-8 byte per char, to enable easy cut-n-paste from the libidn tests.</param>
+        /// <param name="expected"></param>
+        private void TryOne(string input, string expected)
+        {
+            byte[] buf = new byte[input.Length];
+            for (int i=0; i<input.Length; i++)
+            {
+                buf[i] = (byte) input[i];
+            }
+            string in_enc = ENC.GetString(buf);
+            string output = nameprep.Prepare(in_enc);
+
+            buf = new byte[expected.Length];
+            for (int i=0; i<expected.Length; i++)
+            {
+                buf[i] = (byte) expected[i];
+            }
+            string ex = ENC.GetString(buf);
+
+            Assert.AreEqual(ex, output);
+        }
+
+        [Test] public void Test_NFKC_CaseFold()
+        {
+            string result = nameprep.Prepare("Henry \x2163");
+            Assert.AreEqual("henry iv", result);
+        }
+
+        [Test] public void Test_MapToNothing()
+        {
+            TryOne(
+                "foo\xC2\xAD\xCD\x8F\xE1\xA0\x86\xE1\xA0\x8B" +
+                "bar" + "\xE2\x80\x8B\xE2\x81\xA0" + "baz\xEF\xB8\x80\xEF\xB8\x88" +
+                "\xEF\xB8\x8F\xEF\xBB\xBF", "foobarbaz");
+        }
+
+        [Test] public void Test_CaseFolding_01()
+        {
+            // Case folding ASCII U+0043 U+0041 U+0046 U+0045
+            TryOne("CAFE", "cafe");
+        }
+
+        [Test] public void Test_CaseFolding_02()
+        {
+            // Case folding 8bit U+00DF (german sharp s)
+            TryOne("\xC3\x9F", "ss");
+        }
+
+        [Test] public void Test_CaseFolding_03()
+        {
+            // Case folding U+0130 (turkish capital I with dot)
+            TryOne("\xC4\xB0", "i\xcc\x87");
+        }
+
+        [Test] public void Test_CaseFolding_04()
+        {
+            // Case folding multibyte U+0143 U+037A
+            TryOne("\xC5\x83\xCD\xBA", "\xC5\x84 \xCE\xB9");
+        }
+
+        [Ignore("fails, due to lack of UTF-16 in .Net")]
+        [Test] public void Test_CaseFolding_05()
+        {
+            // Case folding U+2121 U+33C6 U+1D7BB
+            TryOne("\xE2\x84\xA1\xE3\x8F\x86\xF0\x9D\x9E\xBB",
+                "telc\xE2\x88\x95" + "kg\xCF\x83");
+        }
+
+        [Test] public void Test_CaseFolding_06()
+        {
+            // Normalization of U+006a U+030c U+00A0 U+00AA
+            TryOne("\x6A\xCC\x8C\xC2\xA0\xC2\xAA", "\xC7\xB0 a");
+        }
+
+        [Test] public void Test_CaseFolding_07()
+        {
+            // Case folding U+1FB7 and normalization
+            TryOne("\xE1\xBE\xB7", "\xE1\xBE\xB6\xCE\xB9");
+        }
+
+        [Test] public void Test_CaseFolding_08()
+        {
+            // Self-reverting case folding U+01F0 and normalization
+            TryOne("\xC7\xB0", "\xC7\xB0");
+        }
+
+        [Test] public void Test_CaseFolding_09()
+        {
+            // Self-reverting case folding U+0390 and normalization
+            TryOne("\xCE\x90", "\xCE\x90");
+        }
+
+        [Test] public void Test_CaseFolding_10()
+        {
+            // Self-reverting case folding U+03B0 and normalization
+            TryOne("\xCE\xB0", "\xCE\xB0");
+        }
+
+        [Test] public void Test_CaseFolding_11()
+        {
+            // Self-reverting case folding U+1E96 and normalization
+            TryOne("\xE1\xBA\x96", "\xE1\xBA\x96");
+        }
+
+        [Test] public void Test_CaseFolding_12()
+        {
+            // Self-reverting case folding U+1F56 and normalization
+            TryOne("\xE1\xBD\x96", "\xE1\xBD\x96");
+        }
+
+        [Test] public void Test_Space_01()
+        {
+            // ASCII space character U+0020
+            TryOne("\x20", "\x20");
+        }
+
+        [Test] public void Test_Space_02()
+        {
+            // Non-ASCII 8bit space character U+00A0
+            TryOne("\xC2\xA0", "\x20");
+        }
+
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Space_03()
+        {
+            // Non-ASCII multibyte space character U+1680",
+            TryOne("\xE1\x9A\x80", null);
+        }
+
+        [Test] public void Test_Space_04()
+        {
+            // Non-ASCII multibyte space character U+2000",
+            TryOne("\xE2\x80\x80", "\x20");
+        }
+
+        [Test] public void Test_Space_05()
+        {
+            // Zero Width Space U+200b",
+            TryOne("\xE2\x80\x8b", "");
+        }
+
+        [Test] public void Test_Space_06()
+        {
+            // Non-ASCII multibyte space character U+3000",
+            TryOne("\xE3\x80\x80", "\x20");
+        }
+
+        [Test] public void Test_Control_01()
+        {
+            // ASCII control characters U+0010 U+007F",
+            TryOne("\x10\x7F", "\x10\x7F");
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Control_02()
+        {
+            // Non-ASCII 8bit control character U+0085",
+            TryOne("\xC2\x85", null);
+        }
+
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Control_03()
+        {
+            // Non-ASCII multibyte control character U+180E",
+            TryOne("\xE1\xA0\x8E", null);
+        }
+        [Test] public void Test_Control_04()
+        {
+            // Zero Width No-Break Space U+FEFF",
+            TryOne("\xEF\xBB\xBF", "");
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Control_05()
+        {
+            // Non-ASCII control character U+1D175",
+            TryOne("\xF0\x9D\x85\xB5", null);
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Plane_0_Private()
+        {
+            // Plane 0 private use character U+F123",
+            TryOne("\xEF\x84\xA3", null);
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Plane_15_Private()
+        {
+            // Plane 15 private use character U+F1234",
+            TryOne("\xF3\xB1\x88\xB4", null);
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Plane_16_Private()
+        {
+            // Plane 16 private use character U+10F234",
+            TryOne("\xF4\x8F\x88\xB4", null);
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_NonCharacter_01()
+        {
+            // Non-character code point U+8FFFE",
+            TryOne("\xF2\x8F\xBF\xBE", null);
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_NonCharacter_02 ()
+        {
+            // Non-character code point U+10FFFF",
+            TryOne("\xF4\x8F\xBF\xBF", null);
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Surrogate()
+        {
+            // Surrogate code U+DF42",
+            //TryOne("\xED\xBD\x82", null);
+            string input = "\uDF42";
+            string output = nameprep.Prepare(input);
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_NonPlaintext()
+        {
+            // Non-plain text character U+FFFD",
+            TryOne("\xEF\xBF\xBD", null);
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_IdeographicDescription()
+        {
+            // Ideographic description character U+2FF5",
+            TryOne("\xE2\xBF\xB5", null);
+        }
+        [Test] public void Test_Property()
+        {
+            // Display property character U+0341",
+            TryOne("\xCD\x81", "\xCC\x81");
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_LTR ()
+        {
+            // Left-to-right mark U+200E",
+            TryOne("\xE2\x80\x8E", "\xCC\x81");
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Deprecated()
+        {
+            // Deprecated U+202A",
+            TryOne("\xE2\x80\xAA", "\xCC\x81");
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Tagging_01()
+        {
+            // Language tagging character U+E0001",
+            TryOne("\xF3\xA0\x80\x81", "\xCC\x81");
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Tagging_02()
+        {
+            // Language tagging character U+E0042",
+            TryOne("\xF3\xA0\x81\x82", null);
+        }
+        [ExpectedException(typeof(BidiException))]
+        [Test] public void Test_Bidi_01()
+        {
+            // Bidi: RandALCat character U+05BE and LCat characters",
+            TryOne("foo\xD6\xBE" + "bar", null);
+        }
+        [ExpectedException(typeof(BidiException))]
+        [Test] public void Test_Bidi_02()
+        {
+            // Bidi: RandALCat character U+FD50 and LCat characters",
+            TryOne("foo\xEF\xB5\x90" + "bar", null);
+        }
+        [Test] public void Test_Bidi_03()
+        {
+            // Bidi: RandALCat character U+FB38 and LCat characters",
+            TryOne("foo\xEF\xB9\xB6" + "bar", "foo \xd9\x8e" + "bar");
+        }
+        [ExpectedException(typeof(BidiException))]
+        [Test] public void Test_Bidi_04()
+        {
+            // Bidi: RandALCat without trailing RandALCat U+0627 U+0031",
+            TryOne("\xD8\xA7\x31", null);
+        }
+
+        [Test] public void Test_Bidi_05()
+        {
+            // Bidi: RandALCat character U+0627 U+0031 U+0628",
+            TryOne("\xD8\xA7\x31\xD8\xA8", "\xD8\xA7\x31\xD8\xA8");
+        }
+
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Unassigned()
+        {
+            // Unassigned code point U+E0002",
+            TryOne("\xF3\xA0\x80\x82", null);
+        }
+
+        [Test] public void Test_LargerShrinking()
+        {
+            // Larger test (shrinking)",
+            //  TryOne("X\xC2\xAD\xC3\xDF\xC4\xB0\xE2\x84\xA1\x6a\xcc\x8c\xc2\xa0\xc2" + "\xaa\xce\xb0\xe2\x80\x80",
+            //         "xssi\xcc\x87" + "tel\xc7\xb0 a\xce\xb0 ");
+            TryOne("X\xC2\xAD\xC3\x9F\xC4\xB0\xE2\x84\xA1\x6a\xcc\x8c\xc2\xa0\xc2" + "\xaa\xce\xb0\xe2\x80\x80",
+                "xssi\xcc\x87" + "tel\xc7\xb0 a\xce\xb0 ");
+
+        }
+        [Test] public void Test_LargerExpanding()
+        {
+            // Larger test (expanding)",
+            TryOne("X\xC3\x9F\xe3\x8c\x96\xC4\xB0\xE2\x84\xA1\xE2\x92\x9F\xE3\x8c\x80",
+                "xss\xe3\x82\xad\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\x88" +
+                "\xe3\x83\xab" + "i\xcc\x87" + "tel\x28" + "d\x29\xe3\x82\xa2\xe3\x83\x91" +
+                "\xe3\x83\xbc\xe3\x83\x88");
+        }
+
+        [Test] public void Test_OldBug()
+        {
+            // nameprep, exposed a bug in libstringprep 0.0.5",
+            TryOne("\xC2\xAA\x0A", "\x61\x0A");
+        }
+
+        [Test] public void Test_DomainName()
+        {
+            TryOne("ExAmPle.COM", "example.com");
+        }
+    }
+
+}
+#endif
diff --git a/lib/jabber-net/test/stringprep/TestNodeprep.cs b/lib/jabber-net/test/stringprep/TestNodeprep.cs
new file mode 100644
index 0000000..e296cff
--- /dev/null
+++ b/lib/jabber-net/test/stringprep/TestNodeprep.cs
@@ -0,0 +1,100 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+#if !NO_STRINGPREP
+
+using System;
+using NUnit.Framework;
+using stringprep;
+using stringprep.steps;
+using bedrock.util;
+
+namespace test.stringprep
+{
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class TestNodeprep
+    {
+        private static System.Text.Encoding ENC = System.Text.Encoding.UTF8;
+
+        private Profile nodeprep = new XmppNode();
+
+        private void TryOne(string input, string expected)
+        {
+            string output = nodeprep.Prepare(input);
+            Assert.AreEqual(expected, output);
+        }
+
+        [Test] public void Test_Good()
+        {
+            TryOne("HILDJJ", "hildjj");
+            TryOne("hildjj", "hildjj");
+            TryOne("\x226f", "\x226f"); // not greater than
+        }
+
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Dquote()
+        {
+            TryOne("\"", null);
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Amp()
+        {
+            TryOne("&", null);
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Squote()
+        {
+            TryOne("'", null);
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Slash()
+        {
+            TryOne("/", null);
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Colon()
+        {
+            TryOne(":", null);
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Less()
+        {
+            TryOne("<", null);
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Greater()
+        {
+            TryOne(">", null);
+        }
+#if !NO_STRINGPREP
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_SmallGreater()
+        {
+            TryOne("\xfe65", null); // small greater than
+        }
+#endif
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_At()
+        {
+            TryOne("@", null);
+        }
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Prep_Less()
+        {
+            // U+FE68: small commercial at
+            TryOne("\xFE6b", null);
+        }
+    }
+}
+#endif
diff --git a/lib/jabber-net/test/stringprep/TestResourceprep.cs b/lib/jabber-net/test/stringprep/TestResourceprep.cs
new file mode 100644
index 0000000..334c50d
--- /dev/null
+++ b/lib/jabber-net/test/stringprep/TestResourceprep.cs
@@ -0,0 +1,51 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+#if !NO_STRINGPREP
+
+using System;
+using NUnit.Framework;
+using stringprep;
+using stringprep.steps;
+using bedrock.util;
+
+namespace test.stringprep
+{
+    [SVN(@"$Id$")]
+    [TestFixture]
+    public class TestResourceprep
+    {
+        private static System.Text.Encoding ENC = System.Text.Encoding.UTF8;
+
+        private Profile resourceprep = new XmppResource();
+
+        private void TryOne(string input, string expected)
+        {
+            string output = resourceprep.Prepare(input);
+            Assert.AreEqual(expected, output);
+        }
+
+        [Test] public void Test_Good()
+        {
+            TryOne("Test", "Test");
+            TryOne("test", "test");
+        }
+
+        [ExpectedException(typeof(ProhibitedCharacterException))]
+        [Test] public void Test_Bad()
+        {
+            TryOne("Test\x180E", null);
+        }
+    }
+}
+#endif
diff --git a/lib/jabber-net/xpnet/ContentToken.cs b/lib/jabber-net/xpnet/ContentToken.cs
new file mode 100644
index 0000000..2f1e4d8
--- /dev/null
+++ b/lib/jabber-net/xpnet/ContentToken.cs
@@ -0,0 +1,191 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ *
+ * xpnet is a deriviative of James Clark's XP.  See copying.txt for more info.
+ * --------------------------------------------------------------------------*/
+namespace xpnet
+{
+    using bedrock.util;
+
+    /// <summary>
+    /// Represents information returned by <code>Encoding.tokenizeContent</code>.
+    /// @see Encoding#tokenizeContent
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class ContentToken : Token
+    {
+        private const int INIT_ATT_COUNT = 8;
+
+        private int attCount = 0;
+        private int[] attNameStart = new int[INIT_ATT_COUNT];
+        private int[] attNameEnd = new int[INIT_ATT_COUNT];
+        private int[] attValueStart = new int[INIT_ATT_COUNT];
+        private int[] attValueEnd = new int[INIT_ATT_COUNT];
+        private bool[] attNormalized = new bool[INIT_ATT_COUNT];
+
+
+        /// <summary>
+        /// Returns the number of attributes specified in the start-tag or empty element tag.
+        /// </summary>
+        /// <returns></returns>
+        public int getAttributeSpecifiedCount()
+        {
+            return attCount;
+        }
+
+        /// <summary>
+        /// Returns the index of the first character of the name of the
+        /// attribute index.
+        /// </summary>
+        /// <param name="i">Attribute index</param>
+        /// <returns>Index of the first character</returns>
+        public int getAttributeNameStart(int i)
+        {
+            if (i >= attCount)
+                throw new System.IndexOutOfRangeException();
+            return attNameStart[i];
+        }
+
+        /**
+                 * Returns the index following the last character of the name of the
+                 * attribute index <code>i</code>.
+                 */
+        public int getAttributeNameEnd(int i)
+        {
+            if (i >= attCount)
+                throw new System.IndexOutOfRangeException();
+            return attNameEnd[i];
+        }
+
+        /**
+         * Returns the index of the character following the opening quote of
+         * attribute index <code>i</code>.
+         */
+        public int getAttributeValueStart(int i)
+        {
+            if (i >= attCount)
+                throw new System.IndexOutOfRangeException();
+            return attValueStart[i];
+        }
+
+        /**
+         * Returns the index of the closing quote attribute index <code>i</code>.
+         */
+        public int getAttributeValueEnd(int i)
+        {
+            if (i >= attCount)
+                throw new System.IndexOutOfRangeException();
+            return attValueEnd[i];
+        }
+
+        /**
+                 * Returns true if attribute index <code>i</code> does not need to
+                 * be normalized.  This is an optimization that allows further processing
+                 * of the attribute to be avoided when it is known that normalization
+                 * cannot change the value of the attribute.
+                 */
+        public bool isAttributeNormalized(int i)
+        {
+            if (i >= attCount)
+                throw new System.IndexOutOfRangeException();
+            return attNormalized[i];
+        }
+
+
+        /// <summary>
+        /// Clear out all of the current attributes
+        /// </summary>
+        public void clearAttributes()
+        {
+            attCount = 0;
+        }
+
+        /// <summary>
+        /// Add a new attribute
+        /// </summary>
+        /// <param name="nameStart"></param>
+        /// <param name="nameEnd"></param>
+        /// <param name="valueStart"></param>
+        /// <param name="valueEnd"></param>
+        /// <param name="normalized"></param>
+        public void appendAttribute(int nameStart, int nameEnd,
+            int valueStart, int valueEnd,
+            bool normalized)
+        {
+
+            if (attCount == attNameStart.Length)
+            {
+                attNameStart = grow(attNameStart);
+                attNameEnd = grow(attNameEnd);
+                attValueStart = grow(attValueStart);
+                attValueEnd = grow(attValueEnd);
+                attNormalized = grow(attNormalized);
+            }
+            attNameStart[attCount] = nameStart;
+            attNameEnd[attCount] = nameEnd;
+            attValueStart[attCount] = valueStart;
+            attValueEnd[attCount] = valueEnd;
+            attNormalized[attCount] = normalized;
+            ++attCount;
+        }
+
+        /// <summary>
+        /// Is the current attribute unique?
+        /// </summary>
+        /// <param name="buf"></param>
+        public void checkAttributeUniqueness(byte[] buf)
+        {
+            for (int i = 1; i < attCount; i++)
+            {
+                int len = attNameEnd[i] - attNameStart[i];
+
+                for (int j = 0; j < i; j++)
+                {
+                    if (attNameEnd[j] - attNameStart[j] == len)
+                    {
+                        int n = len;
+                        int s1 = attNameStart[i];
+                        int s2 = attNameStart[j];
+                        do
+                        {
+                            if (--n < 0)
+                                throw new InvalidTokenException(attNameStart[i],
+                                    InvalidTokenException.DUPLICATE_ATTRIBUTE);
+                        } while (buf[s1++] == buf[s2++]);
+                    }
+                }
+            }
+        }
+
+        private static int[] grow(int[] v)
+        {
+            int[] tem = v;
+            v = new int[tem.Length << 1];
+
+            System.Buffer.BlockCopy(tem, 0, v, 0, System.Buffer.ByteLength(tem));
+
+            return v;
+        }
+
+        private static bool[] grow(bool[] v)
+        {
+            bool[] tem = v;
+            v = new bool[tem.Length << 1];
+
+            System.Buffer.BlockCopy(tem, 0, v, 0, System.Buffer.ByteLength(tem));
+
+            return v;
+        }
+
+    }
+}
diff --git a/lib/jabber-net/xpnet/Encoding.cs b/lib/jabber-net/xpnet/Encoding.cs
new file mode 100644
index 0000000..ab56b7e
--- /dev/null
+++ b/lib/jabber-net/xpnet/Encoding.cs
@@ -0,0 +1,3177 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ *
+ * xpnet is a deriviative of James Clark's XP.  See copying.txt for more info.
+ * --------------------------------------------------------------------------*/
+namespace xpnet
+{
+    using bedrock.util;
+
+    /// <summary>
+    /// Tokens that might have been found
+    /// </summary>
+    [SVN(@"$Id$")]
+    public enum TOK
+    {
+        /**
+         * Represents one or more characters of data.
+         */
+        DATA_CHARS,
+
+        /**
+         * Represents a newline (CR, LF or CR followed by LF) in data.
+         */
+        DATA_NEWLINE,
+
+        /**
+         * Represents a complete start-tag <code><name></code>,
+         * that doesn't have any attribute specifications.
+         */
+        START_TAG_NO_ATTS,
+
+        /**
+         * Represents a complete start-tag <code><name
+         * att="val"></code>, that contains one or more
+         * attribute specifications.
+         */
+        START_TAG_WITH_ATTS,
+
+        /**
+         * Represents an empty element tag <code><name/></code>,
+         * that doesn't have any attribute specifications.
+         */
+        EMPTY_ELEMENT_NO_ATTS,
+
+        /**
+         * Represents an empty element tag <code><name
+         * att="val"/></code>, that contains one or more
+         * attribute specifications.
+         */
+        EMPTY_ELEMENT_WITH_ATTS,
+
+        /**
+         * Represents a complete end-tag <code></name></code>.
+         */
+        END_TAG,
+
+        /**
+         * Represents the start of a CDATA section
+         * <code><![CDATA[</code>.
+         */
+        CDATA_SECT_OPEN,
+
+        /**
+         * Represents the end of a CDATA section <code>]]></code>.
+         */
+        CDATA_SECT_CLOSE,
+
+        /**
+         * Represents a general entity reference.
+         */
+        ENTITY_REF,
+
+        /**
+         * Represents a general entity reference to a one of the 5
+         * predefined entities <code>amp</code>, <code>lt</code>,
+         * <code>gt</code>, <code>quot</code>, <code>apos</code>.
+         */
+        MAGIC_ENTITY_REF,
+
+        /**
+         * Represents a numeric character reference (decimal or
+         * hexadecimal), when the referenced character is less
+         * than or equal to 0xFFFF and so is represented by a
+         * single char.
+         */
+        CHAR_REF,
+
+        /**
+         * Represents a numeric character reference (decimal or
+         * hexadecimal), when the referenced character is greater
+         * than 0xFFFF and so is represented by a pair of chars.
+         */
+        CHAR_PAIR_REF,
+
+        /**
+         * Represents a processing instruction.
+         */
+        PI,
+
+        /**
+         * Represents an XML declaration or text declaration (a
+         * processing instruction whose target is
+         * <code>xml</code>).
+         */
+        XML_DECL,
+
+        /**
+         * Represents a comment <code><!-- comment --></code>.
+         * This can occur both in the prolog and in content.
+         */
+        COMMENT,
+
+        /**
+         * Represents a white space character in an attribute
+         * value, excluding white space characters that are part
+         * of line boundaries.
+         */
+        ATTRIBUTE_VALUE_S,
+
+        /**
+         * Represents a parameter entity reference in the prolog.
+         */
+        PARAM_ENTITY_REF,
+
+        /**
+         * Represents whitespace in the prolog.
+         * The token contains one or more whitespace characters.
+         */
+        PROLOG_S,
+
+        /**
+         * Represents <code><!NAME</code> in the prolog.
+         */
+        DECL_OPEN,
+
+        /**
+         * Represents <code>></code> in the prolog.
+         */
+        DECL_CLOSE,
+
+        /**
+         * Represents a name in the prolog.
+         */
+        NAME,
+
+        /**
+         * Represents a name token in the prolog that is not a name.
+         */
+        NMTOKEN,
+
+        /**
+         * Represents <code>#NAME</code> in the prolog.
+         */
+        POUND_NAME,
+
+        /**
+         * Represents <code>|</code> in the prolog.
+         */
+        OR,
+
+        /**
+         * Represents a <code>%</code> in the prolog that does not start
+         * a parameter entity reference.
+         * This can occur in an entity declaration.
+         */
+        PERCENT,
+
+        /**
+         * Represents a <code>(</code> in the prolog.
+         */
+        OPEN_PAREN,
+
+        /**
+         * Represents a <code>)</code> in the prolog that is not
+         * followed immediately by any of
+         *  <code>*</code>, <code>+</code> or <code>?</code>.
+         */
+        CLOSE_PAREN,
+
+        /**
+         * Represents <code>[</code> in the prolog.
+         */
+        OPEN_BRACKET,
+
+        /**
+         * Represents <code>]</code> in the prolog.
+         */
+        CLOSE_BRACKET,
+
+        /**
+         * Represents a literal (EntityValue, AttValue, SystemLiteral or
+         * PubidLiteral).
+         */
+        LITERAL,
+
+        /**
+         * Represents a name followed immediately by <code>?</code>.
+         */
+        NAME_QUESTION,
+
+        /**
+         * Represents a name followed immediately by <code>*</code>.
+         */
+        NAME_ASTERISK,
+
+        /**
+         * Represents a name followed immediately by <code>+</code>.
+         */
+        NAME_PLUS,
+
+        /**
+         * Represents <code><![</code> in the prolog.
+         */
+        COND_SECT_OPEN,
+
+        /**
+         * Represents <code>]]></code> in the prolog.
+         */
+        COND_SECT_CLOSE,
+
+        /**
+         * Represents <code>)?</code> in the prolog.
+         */
+        CLOSE_PAREN_QUESTION,
+
+        /**
+         * Represents <code>)*</code> in the prolog.
+         */
+        CLOSE_PAREN_ASTERISK,
+
+        /**
+         * Represents <code>)+</code> in the prolog.
+         */
+        CLOSE_PAREN_PLUS,
+
+        /**
+         * Represents <code>,</code> in the prolog.
+         */
+        COMMA,
+    };
+
+    /// <summary>
+    /// Base tokenizer class
+    /// </summary>
+    [SVN(@"$Id$")]
+    public abstract class Encoding
+    {
+        // Bytes with type < 0 may not be data in content.
+        // The negation of the lead byte type gives the total number of bytes.
+
+        /// <summary>
+        /// Need more bytes
+        /// </summary>
+        protected const int BT_LEAD2 = -2;
+        /// <summary>
+        /// Need more bytes
+        /// </summary>
+        protected const int BT_LEAD3 = -3;
+        /// <summary>
+        /// Need more bytes
+        /// </summary>
+        protected const int BT_LEAD4 = -4;
+        /// <summary>
+        /// Not XML
+        /// </summary>
+        protected const int BT_NONXML = BT_LEAD4 - 1;
+        /// <summary>
+        /// Malformed XML
+        /// </summary>
+        protected const int BT_MALFORM = BT_NONXML - 1;
+        /// <summary>
+        /// Less than
+        /// </summary>
+        protected const int BT_LT = BT_MALFORM - 1;
+        /// <summary>
+        /// Ampersand
+        /// </summary>
+        protected const int BT_AMP = BT_LT - 1;
+        /// <summary>
+        /// right square bracket
+        /// </summary>
+        protected const int BT_RSQB = BT_AMP - 1;
+        /// <summary>
+        /// carriage return
+        /// </summary>
+        protected const int BT_CR = BT_RSQB - 1;
+        /// <summary>
+        /// line feed
+        /// </summary>
+        protected const int BT_LF = BT_CR - 1;
+
+        // Bytes with type >= 0 are treated as data in content.
+
+        /// <summary>
+        /// greater than
+        /// </summary>
+        protected const int BT_GT = 0;
+        /// <summary>
+        /// Quote
+        /// </summary>
+        protected const int BT_QUOT = BT_GT + 1;
+        /// <summary>
+        /// Apostrophe
+        /// </summary>
+        protected const int BT_APOS = BT_QUOT + 1;
+        /// <summary>
+        /// Equal sign
+        /// </summary>
+        protected const int BT_EQUALS = BT_APOS + 1;
+        /// <summary>
+        /// Question mark
+        /// </summary>
+        protected const int BT_QUEST = BT_EQUALS + 1;
+        /// <summary>
+        /// Exclamation point
+        /// </summary>
+        protected const int BT_EXCL = BT_QUEST + 1;
+        /// <summary>
+        /// Solidus (/)
+        /// </summary>
+        protected const int BT_SOL = BT_EXCL + 1;
+        /// <summary>
+        /// Semicolon
+        /// </summary>
+        protected const int BT_SEMI = BT_SOL + 1;
+        /// <summary>
+        /// Hash
+        /// </summary>
+        protected const int BT_NUM = BT_SEMI + 1;
+        /// <summary>
+        /// Left square bracket
+        /// </summary>
+        protected const int BT_LSQB = BT_NUM + 1;
+        /// <summary>
+        /// space
+        /// </summary>
+        protected const int BT_S = BT_LSQB + 1;
+        /// <summary>
+        ///
+        /// </summary>
+        protected const int BT_NMSTRT = BT_S + 1;
+        /// <summary>
+        ///
+        /// </summary>
+        protected const int BT_NAME = BT_NMSTRT + 1;
+        /// <summary>
+        /// Minus
+        /// </summary>
+        protected const int BT_MINUS = BT_NAME + 1;
+        /// <summary>
+        /// Other
+        /// </summary>
+        protected const int BT_OTHER = BT_MINUS + 1;
+        /// <summary>
+        /// Percent
+        /// </summary>
+        protected const int BT_PERCNT = BT_OTHER + 1;
+        /// <summary>
+        /// Left paren
+        /// </summary>
+        protected const int BT_LPAR = BT_PERCNT + 1;
+        /// <summary>
+        /// Right paren
+        /// </summary>
+        protected const int BT_RPAR = BT_LPAR + 1;
+        /// <summary>
+        ///
+        /// </summary>
+        protected const int BT_AST = BT_RPAR + 1;
+        /// <summary>
+        /// +
+        /// </summary>
+        protected const int BT_PLUS = BT_AST + 1;
+        /// <summary>
+        /// ,
+        /// </summary>
+        protected const int BT_COMMA = BT_PLUS + 1;
+        /// <summary>
+        /// Pipe
+        /// </summary>
+        protected const int BT_VERBAR = BT_COMMA + 1;
+
+        /// <summary>
+        /// What syntax do each of the ASCII7 characters have?
+        /// </summary>
+        protected static readonly int [] asciiTypeTable = new int[]
+        {
+            /* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+            /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+            /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+            /* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
+            /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+            /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+            /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+            /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+            /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+            /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+            /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+            /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+            /* 0x30 */ BT_NAME, BT_NAME, BT_NAME, BT_NAME,
+            /* 0x34 */ BT_NAME, BT_NAME, BT_NAME, BT_NAME,
+            /* 0x38 */ BT_NAME, BT_NAME, BT_NMSTRT, BT_SEMI,
+            /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+            /* 0x40 */ BT_OTHER, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+            /* 0x44 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+            /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+            /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+            /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+            /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+            /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+            /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+            /* 0x60 */ BT_OTHER, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+            /* 0x64 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+            /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+            /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+            /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+            /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+            /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+            /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
+        };
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="sourceBuf"></param>
+        /// <param name="sourceStart"></param>
+        /// <param name="sourceEnd"></param>
+        /// <param name="targetBuf"></param>
+        /// <param name="targetStart"></param>
+        /// <returns></returns>
+        protected abstract int convert(byte[] sourceBuf,
+            int sourceStart, int sourceEnd,
+            char[] targetBuf, int targetStart);
+
+
+        private static Encoding utf8Encoding;
+
+        private const byte UTF8_ENCODING = 0;
+        private const byte UTF16_LITTLE_ENDIAN_ENCODING = 1;
+        private const byte UTF16_BIG_ENDIAN_ENCODING = 2;
+        private const byte INTERNAL_ENCODING = 3;
+        private const byte ISO8859_1_ENCODING = 4;
+        private const byte ASCII_ENCODING = 5;
+
+        private static Encoding getEncoding(byte enc)
+        {
+            switch (enc)
+            {
+                case UTF8_ENCODING:
+                    if (utf8Encoding == null)
+                        utf8Encoding = new UTF8Encoding();
+                    return utf8Encoding;
+                    /*
+                case UTF16_LITTLE_ENDIAN_ENCODING:
+                    if (utf16LittleEndianEncoding == null)
+                        utf16LittleEndianEncoding = new UTF16LittleEndianEncoding();
+                    return utf16LittleEndianEncoding;
+                case UTF16_BIG_ENDIAN_ENCODING:
+                    if (utf16BigEndianEncoding == null)
+                        utf16BigEndianEncoding = new UTF16BigEndianEncoding();
+                    return utf16BigEndianEncoding;
+                case INTERNAL_ENCODING:
+                    if (internalEncoding == null)
+                        internalEncoding = new InternalEncoding();
+                    return internalEncoding;
+                case ISO8859_1_ENCODING:
+                    if (iso8859_1Encoding == null)
+                        iso8859_1Encoding = new ISO8859_1Encoding();
+                    return iso8859_1Encoding;
+                case ASCII_ENCODING:
+                    if (asciiEncoding == null)
+                        asciiEncoding = new ASCIIEncoding();
+                    return asciiEncoding;
+                    */
+            }
+            return null;
+        }
+
+        private int minBPC;
+
+        /// <summary>
+        /// Constructor called by subclasses to set the minimum bytes per character
+        /// </summary>
+        /// <param name="minBPC"></param>
+        protected Encoding(int minBPC)
+        {
+            this.minBPC = minBPC;
+        }
+
+        /// <summary>
+        /// Get the byte type of the next byte.  There are guaranteed to be minBPC available bytes starting at off.
+        /// </summary>
+        /// <param name="buf"></param>
+        /// <param name="off"></param>
+        /// <returns></returns>
+        protected abstract int byteType(byte[] buf, int off);
+
+        /// <summary>
+        /// Really only works for ASCII7.
+        /// </summary>
+        /// <param name="buf"></param>
+        /// <param name="off"></param>
+        /// <returns></returns>
+        protected abstract char byteToAscii(byte[] buf, int off);
+
+        /// <summary>
+        /// This must only be called when c is an (XML significant)
+        /// ASCII character.
+        /// </summary>
+        /// <param name="buf"></param>
+        /// <param name="off"></param>
+        /// <param name="c"></param>
+        /// <returns></returns>
+        protected abstract bool charMatches(byte[] buf, int off, char c);
+
+        /// <summary>
+        /// Called only when byteType(buf, off) == BT_LEAD2
+        /// </summary>
+        /// <param name="buf"></param>
+        /// <param name="off"></param>
+        /// <returns></returns>
+        protected virtual int byteType2(byte[] buf, int off)
+        {
+            return BT_OTHER;
+        }
+
+        /// <summary>
+        /// Called only when byteType(buf, off) == BT_LEAD3
+        /// </summary>
+        /// <param name="buf"></param>
+        /// <param name="off"></param>
+        /// <returns></returns>
+        int byteType3(byte[] buf, int off)
+        {
+            return BT_OTHER;
+        }
+
+        /// <summary>
+        /// Called only when byteType(buf, off) == BT_LEAD4
+        /// </summary>
+        /// <param name="buf"></param>
+        /// <param name="off"></param>
+        /// <returns></returns>
+        int byteType4(byte[] buf, int off)
+        {
+            return BT_OTHER;
+        }
+
+        void check2(byte[] buf, int off) { }
+        void check3(byte[] buf, int off) { }
+        void check4(byte[] buf, int off) { }
+
+        /**
+         * Moves a position forward.  On entry, <code>pos</code> gives
+         * the position of the byte at index <code>off</code> in
+         * <code>buf</code>.  On exit, it <code>pos</code> will give
+         * the position of the byte at index <code>end</code>, which
+         * must be greater than or equal to <code>off</code>.  The
+         * bytes between <code>off</code> and <code>end</code> must
+         * encode one or more complete characters.  A carriage return
+         * followed by a line feed will be treated as a single line
+         * delimiter provided that they are given to
+         * <code>movePosition</code> together.
+         */
+        protected abstract void movePosition(byte[] buf, int off, int end, Position pos);
+
+        private void checkCharMatches(byte[] buf, int off, char c)
+        {
+            if (!charMatches(buf, off, c))
+                throw new InvalidTokenException(off);
+        }
+
+        /* off points to character following "<!-" */
+        private TOK scanComment(byte[] buf, int off, int end, Token token)
+        {
+            if (off != end)
+            {
+                checkCharMatches(buf, off, '-');
+                off += minBPC;
+                while (off != end)
+                {
+                    switch (byteType(buf, off))
+                    {
+                        case BT_LEAD2:
+                            if (end - off < 2)
+                                throw new PartialCharException(off);
+                            check2(buf, off);
+                            off += 2;
+                            break;
+                        case BT_LEAD3:
+                            if (end - off < 3)
+                                throw new PartialCharException(off);
+                            check3(buf, off);
+                            off += 3;
+                            break;
+                        case BT_LEAD4:
+                            if (end - off < 4)
+                                throw new PartialCharException(off);
+                            check4(buf, off);
+                            off += 4;
+                            break;
+                        case BT_NONXML:
+                        case BT_MALFORM:
+                            throw new InvalidTokenException(off);
+                        case BT_MINUS:
+                            if ((off += minBPC) == end)
+                                throw new PartialTokenException();
+                            if (charMatches(buf, off, '-'))
+                            {
+                                if ((off += minBPC) == end)
+                                    throw new PartialTokenException();
+                                checkCharMatches(buf, off, '>');
+                                token.TokenEnd = off + minBPC;
+                                return TOK.COMMENT;
+                            }
+                            break;
+                        default:
+                            off += minBPC;
+                            break;
+                    }
+                }
+            }
+            throw new PartialTokenException();
+        }
+
+        /* off points to character following "<!" */
+        private TOK scanDecl(byte[] buf, int off, int end, Token token)
+        {
+            if (off == end)
+                throw new PartialTokenException();
+            switch (byteType(buf, off))
+            {
+                case BT_MINUS:
+                    return scanComment(buf, off + minBPC, end, token);
+                case BT_LSQB:
+                    token.TokenEnd = off + minBPC;
+                    return TOK.COND_SECT_OPEN;
+                case BT_NMSTRT:
+                    off += minBPC;
+                    break;
+                default:
+                    throw new InvalidTokenException(off);
+            }
+            while (off != end)
+            {
+                switch (byteType(buf, off))
+                {
+                    case BT_PERCNT:
+                        if (off + minBPC == end)
+                            throw new PartialTokenException();
+                        /* don't allow <!ENTITY% foo "whatever"> */
+                    switch (byteType(buf, off + minBPC))
+                    {
+                        case BT_S:
+                        case BT_CR:
+                        case BT_LF:
+                        case BT_PERCNT:
+                            throw new InvalidTokenException(off);
+                    }
+                        /* fall through */
+                        goto case BT_S;
+                    case BT_S:
+                    case BT_CR:
+                    case BT_LF:
+                        token.TokenEnd = off;
+                        return TOK.DECL_OPEN;
+                    case BT_NMSTRT:
+                        off += minBPC;
+                        break;
+                    default:
+                        throw new InvalidTokenException(off);
+                }
+            }
+            throw new PartialTokenException();
+        }
+
+        private bool targetIsXml(byte[] buf, int off, int end)
+        {
+            bool upper = false;
+            if (end - off != minBPC*3)
+                return false;
+            switch (byteToAscii(buf, off))
+            {
+                case 'x':
+                    break;
+                case 'X':
+                    upper = true;
+                    break;
+                default:
+                    return false;
+            }
+            off += minBPC;
+            switch (byteToAscii(buf, off))
+            {
+                case 'm':
+                    break;
+                case 'M':
+                    upper = true;
+                    break;
+                default:
+                    return false;
+            }
+            off += minBPC;
+            switch (byteToAscii(buf, off))
+            {
+                case 'l':
+                    break;
+                case 'L':
+                    upper = true;
+                    break;
+                default:
+                    return false;
+            }
+            if (upper)
+                throw new InvalidTokenException(off, InvalidTokenException.XML_TARGET);
+            return true;
+        }
+
+        /* off points to character following "<?" */
+
+        private TOK scanPi(byte[] buf, int off, int end, Token token)
+        {
+            int target = off;
+            if (off == end)
+                throw new PartialTokenException();
+            switch (byteType(buf, off))
+            {
+                case BT_NMSTRT:
+                    off += minBPC;
+                    break;
+                case BT_LEAD2:
+                    if (end - off < 2)
+                        throw new PartialCharException(off);
+                    if (byteType2(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 2;
+                    break;
+                case BT_LEAD3:
+                    if (end - off < 3)
+                        throw new PartialCharException(off);
+                    if (byteType3(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 3;
+                    break;
+                case BT_LEAD4:
+                    if (end - off < 4)
+                        throw new PartialCharException(off);
+                    if (byteType4(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 4;
+                    break;
+                default:
+                    throw new InvalidTokenException(off);
+            }
+            while (off != end)
+            {
+                switch (byteType(buf, off))
+                {
+                    case BT_NMSTRT:
+                    case BT_NAME:
+                    case BT_MINUS:
+                        off += minBPC;
+                        break;
+                    case BT_LEAD2:
+                        if (end - off < 2)
+                            throw new PartialCharException(off);
+                        if (!isNameChar2(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 2;
+                        break;
+                    case BT_LEAD3:
+                        if (end - off < 3)
+                            throw new PartialCharException(off);
+                        if (!isNameChar3(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 3;
+                        break;
+                    case BT_LEAD4:
+                        if (end - off < 4)
+                            throw new PartialCharException(off);
+                        if (!isNameChar4(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 4;
+                        break;
+                    case BT_S:
+                    case BT_CR:
+                    case BT_LF:
+                        bool isXml = targetIsXml(buf, target, off);
+                        token.NameEnd = off;
+                        off += minBPC;
+                        while (off != end)
+                        {
+                            switch (byteType(buf, off))
+                            {
+                                case BT_LEAD2:
+                                    if (end - off < 2)
+                                        throw new PartialCharException(off);
+                                    check2(buf, off);
+                                    off += 2;
+                                    break;
+                                case BT_LEAD3:
+                                    if (end - off < 3)
+                                        throw new PartialCharException(off);
+                                    check3(buf, off);
+                                    off += 3;
+                                    break;
+                                case BT_LEAD4:
+                                    if (end - off < 4)
+                                        throw new PartialCharException(off);
+                                    check4(buf, off);
+                                    off += 4;
+                                    break;
+                                case BT_NONXML:
+                                case BT_MALFORM:
+                                    throw new InvalidTokenException(off);
+                                case BT_QUEST:
+                                    off += minBPC;
+                                    if (off == end)
+                                        throw new PartialTokenException();
+                                    if (charMatches(buf, off, '>'))
+                                    {
+                                        token.TokenEnd = off + minBPC;
+                                        if (isXml)
+                                            return TOK.XML_DECL;
+                                        else
+                                            return TOK.PI;
+                                    }
+                                    break;
+                                default:
+                                    off += minBPC;
+                                    break;
+                            }
+                        }
+                        throw new PartialTokenException();
+                    case BT_QUEST:
+                        token.NameEnd = off;
+                        off += minBPC;
+                        if (off == end)
+                            throw new PartialTokenException();
+                        checkCharMatches(buf, off, '>');
+                        token.TokenEnd = off + minBPC;
+                        return (targetIsXml(buf, target, token.NameEnd)
+                            ? TOK.XML_DECL
+                            : TOK.PI);
+                    default:
+                        throw new InvalidTokenException(off);
+                }
+            }
+            throw new PartialTokenException();
+        }
+
+        /* off points to character following "<![" */
+        private const string CDATA = "CDATA[";
+
+        private TOK scanCdataSection(byte[] buf, int off, int end, Token token)
+        {
+            /* "CDATA[".length() == 6 */
+            if (end - off < 6 * minBPC)
+                throw new PartialTokenException();
+            for (int i = 0; i < CDATA.Length; i++, off += minBPC)
+                checkCharMatches(buf, off, CDATA[i]);
+            token.TokenEnd = off;
+            return TOK.CDATA_SECT_OPEN;
+        }
+
+        /**
+         * Scans the first token of a byte subarrary that starts with the
+         * content of a CDATA section.
+         * Returns one of the following integers according to the type of token
+         * that the subarray starts with:
+         * <ul>
+         * <li><code>TOK.DATA_CHARS</code></li>
+         * <li><code>TOK.DATA_NEWLINE</code></li>
+         * <li><code>TOK.CDATA_SECT_CLOSE</code></li>
+         * </ul>
+         * <p>
+         * Information about the token is stored in <code>token</code>.
+         * </p>
+         * After <code>TOK.CDATA_SECT_CLOSE</code> is returned, the application
+         * should use <code>tokenizeContent</code>.
+         *
+         * @exception EmptyTokenException if the subarray is empty
+         * @exception PartialTokenException if the subarray contains only part of
+         * a legal token
+         * @exception InvalidTokenException if the subarrary does not start
+         * with a legal token or part of one
+         * @exception ExtensibleTokenException if the subarray encodes just a carriage
+         * return ('\r')
+         *
+         * @see #TOK.DATA_CHARS
+         * @see #TOK.DATA_NEWLINE
+         * @see #TOK.CDATA_SECT_CLOSE
+         * @see Token
+         * @see EmptyTokenException
+         * @see PartialTokenException
+         * @see InvalidTokenException
+         * @see ExtensibleTokenException
+         * @see #tokenizeContent
+         */
+        public TOK tokenizeCdataSection(byte[] buf, int off, int end,
+            Token token)
+        {
+            if (minBPC > 1)
+                end = adjustEnd(off, end);
+            if (off == end)
+                throw new EmptyTokenException();
+            switch (byteType(buf, off))
+            {
+                case BT_RSQB:
+                    off += minBPC;
+                    if (off == end)
+                        throw new PartialTokenException();
+                    if (!charMatches(buf, off, ']'))
+                        break;
+                    off += minBPC;
+                    if (off == end)
+                        throw new PartialTokenException();
+                    if (!charMatches(buf, off, '>'))
+                    {
+                        off -= minBPC;
+                        break;
+                    }
+                    token.TokenEnd = off + minBPC;
+                    return TOK.CDATA_SECT_CLOSE;
+                case BT_CR:
+                    off += minBPC;
+                    if (off == end)
+                        throw new ExtensibleTokenException(TOK.DATA_NEWLINE);
+                    if (byteType(buf, off) == BT_LF)
+                        off += minBPC;
+                    token.TokenEnd = off;
+                    return TOK.DATA_NEWLINE;
+                case BT_LF:
+                    token.TokenEnd = off + minBPC;
+                    return TOK.DATA_NEWLINE;
+                case BT_NONXML:
+                case BT_MALFORM:
+                    throw new InvalidTokenException(off);
+                case BT_LEAD2:
+                    if (end - off < 2)
+                        throw new PartialCharException(off);
+                    check2(buf, off);
+                    off += 2;
+                    break;
+                case BT_LEAD3:
+                    if (end - off < 3)
+                        throw new PartialCharException(off);
+                    check3(buf, off);
+                    off += 3;
+                    break;
+                case BT_LEAD4:
+                    if (end - off < 4)
+                        throw new PartialCharException(off);
+                    check4(buf, off);
+                    off += 4;
+                    break;
+                default:
+                    off += minBPC;
+                    break;
+            }
+            token.TokenEnd = extendCdata(buf, off, end);
+            return TOK.DATA_CHARS;
+        }
+
+        int extendCdata(byte[] buf, int off, int end)
+        {
+            while (off != end)
+            {
+                switch (byteType(buf, off))
+                {
+                    case BT_LEAD2:
+                        if (end - off < 2)
+                            return off;
+                        check2(buf, off);
+                        off += 2;
+                        break;
+                    case BT_LEAD3:
+                        if (end - off < 3)
+                            return off;
+                        check3(buf, off);
+                        off += 3;
+                        break;
+                    case BT_LEAD4:
+                        if (end - off < 4)
+                            return off;
+                        check4(buf, off);
+                        off += 4;
+                        break;
+                    case BT_RSQB:
+                    case BT_NONXML:
+                    case BT_MALFORM:
+                    case BT_CR:
+                    case BT_LF:
+                        return off;
+                    default:
+                        off += minBPC;
+                        break;
+                }
+            }
+            return off;
+        }
+
+
+        /* off points to character following "</" */
+        private TOK scanEndTag(byte[] buf, int off, int end, Token token)
+        {
+            if (off == end)
+                throw new PartialTokenException();
+            switch (byteType(buf, off))
+            {
+                case BT_NMSTRT:
+                    off += minBPC;
+                    break;
+                case BT_LEAD2:
+                    if (end - off < 2)
+                        throw new PartialCharException(off);
+                    if (byteType2(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 2;
+                    break;
+                case BT_LEAD3:
+                    if (end - off < 3)
+                        throw new PartialCharException(off);
+                    if (byteType3(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 3;
+                    break;
+                case BT_LEAD4:
+                    if (end - off < 4)
+                        throw new PartialCharException(off);
+                    if (byteType4(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 4;
+                    break;
+                default:
+                    throw new InvalidTokenException(off);
+            }
+            while (off != end)
+            {
+                switch (byteType(buf, off))
+                {
+                    case BT_NMSTRT:
+                    case BT_NAME:
+                    case BT_MINUS:
+                        off += minBPC;
+                        break;
+                    case BT_LEAD2:
+                        if (end - off < 2)
+                            throw new PartialCharException(off);
+                        if (!isNameChar2(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 2;
+                        break;
+                    case BT_LEAD3:
+                        if (end - off < 3)
+                            throw new PartialCharException(off);
+                        if (!isNameChar3(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 3;
+                        break;
+                    case BT_LEAD4:
+                        if (end - off < 4)
+                            throw new PartialCharException(off);
+                        if (!isNameChar4(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 4;
+                        break;
+                    case BT_S:
+                    case BT_CR:
+                    case BT_LF:
+                        token.NameEnd = off;
+                        for (off += minBPC; off != end; off += minBPC)
+                        {
+                            switch (byteType(buf, off))
+                            {
+                                case BT_S:
+                                case BT_CR:
+                                case BT_LF:
+                                    break;
+                                case BT_GT:
+                                    token.TokenEnd = off + minBPC;
+                                    return TOK.END_TAG;
+                                default:
+                                    throw new InvalidTokenException(off);
+                            }
+                        }
+                        throw new PartialTokenException();
+                    case BT_GT:
+                        token.NameEnd = off;
+                        token.TokenEnd = off + minBPC;
+                        return TOK.END_TAG;
+                    default:
+                        throw new InvalidTokenException(off);
+                }
+            }
+            throw new PartialTokenException();
+        }
+
+        /* off points to character following "&#X" */
+        private TOK scanHexCharRef(byte[] buf, int off, int end, Token token)
+        {
+            if (off != end)
+            {
+                int c = byteToAscii(buf, off);
+                int num;
+                switch (c)
+                {
+                    case '0': case '1': case '2': case '3': case '4':
+                    case '5': case '6': case '7': case '8': case '9':
+                        num = c - '0';
+                        break;
+                    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+                        num = c - ('A' - 10);
+                        break;
+                    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+                        num = c - ('a' - 10);
+                        break;
+                    default:
+                        throw new InvalidTokenException(off);
+                }
+                for (off += minBPC; off != end; off += minBPC)
+                {
+                    c = byteToAscii(buf, off);
+                    switch (c)
+                    {
+                        case '0': case '1': case '2': case '3': case '4':
+                        case '5': case '6': case '7': case '8': case '9':
+                            num = (num << 4) + c - '0';
+                            break;
+                        case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+                            num = (num << 4) + c - ('A' - 10);
+                            break;
+                        case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+                            num = (num << 4) + c - ('a' - 10);
+                            break;
+                        case ';':
+                            token.TokenEnd = off + minBPC;
+                            return setRefChar(num, token);
+                        default:
+                            throw new InvalidTokenException(off);
+                    }
+                    if (num >= 0x110000)
+                        throw new InvalidTokenException(off);
+                }
+            }
+            throw new PartialTokenException();
+        }
+
+        /* off points to character following "&#" */
+        private TOK scanCharRef(byte[] buf, int off, int end, Token token)
+        {
+            if (off != end)
+            {
+                int c = byteToAscii(buf, off);
+                switch (c)
+                {
+                    case 'x':
+                        return scanHexCharRef(buf, off + minBPC, end, token);
+                    case '0':
+                    case '1':
+                    case '2':
+                    case '3':
+                    case '4':
+                    case '5':
+                    case '6':
+                    case '7':
+                    case '8':
+                    case '9':
+                        break;
+                    default:
+                        throw new InvalidTokenException(off);
+                }
+
+                int num = c - '0';
+                for (off += minBPC; off != end; off += minBPC)
+                {
+                    c = byteToAscii(buf, off);
+                    switch (c)
+                    {
+                        case '0':
+                        case '1':
+                        case '2':
+                        case '3':
+                        case '4':
+                        case '5':
+                        case '6':
+                        case '7':
+                        case '8':
+                        case '9':
+                            num = num * 10 + (c - '0');
+                            if (num < 0x110000)
+                                break;
+                            /* fall through */
+                            goto default;
+                        default:
+                            throw new InvalidTokenException(off);
+                        case ';':
+                            token.TokenEnd = off + minBPC;
+                            return setRefChar(num, token);
+                    }
+                }
+            }
+            throw new PartialTokenException();
+        }
+
+        /* num is known to be < 0x110000; return the token code */
+        private TOK setRefChar(int num, Token token)
+        {
+            if (num < 0x10000)
+            {
+                switch (charTypeTable[num >> 8][num & 0xFF])
+                {
+                    case BT_NONXML:
+                    case BT_LEAD4:
+                    case BT_MALFORM:
+                        throw new InvalidTokenException(token.TokenEnd - minBPC);
+                }
+                token.RefChar1 = (char)num;
+                return TOK.CHAR_REF;
+            }
+            else
+            {
+                num -= 0x10000;
+                token.RefChar1 = (char)((num >> 10) + 0xD800);
+                token.RefChar2 = (char)((num & ((1 << 10) - 1)) + 0xDC00);
+                return TOK.CHAR_PAIR_REF;
+            }
+        }
+
+        private bool isMagicEntityRef(byte[] buf, int off, int end, Token token)
+        {
+            switch (byteToAscii(buf, off))
+            {
+                case 'a':
+                    if (end - off < minBPC*4)
+                        break;
+                switch (byteToAscii(buf, off + minBPC))
+                {
+                    case 'm':
+                        if (charMatches(buf, off + minBPC*2, 'p')
+                            && charMatches(buf, off + minBPC*3, ';'))
+                        {
+                            token.TokenEnd = off + minBPC*4;
+                            token.RefChar1 = '&';
+                            return true;
+                        }
+                        break;
+                    case 'p':
+                        if (end - off >= minBPC*5
+                            && charMatches(buf, off + minBPC*2, 'o')
+                            && charMatches(buf, off + minBPC*3, 's')
+                            && charMatches(buf, off + minBPC*4, ';'))
+                        {
+                            token.TokenEnd = off + minBPC*5;
+                            token.RefChar1 = '\'';
+                            return true;
+                        }
+                        break;
+                }
+                    break;
+                case 'l':
+                    if (end - off >= minBPC*3
+                        && charMatches(buf, off + minBPC, 't')
+                        && charMatches(buf, off + minBPC*2, ';'))
+                    {
+                        token.TokenEnd = off + minBPC*3;
+                        token.RefChar1 = '<';
+                        return true;
+                    }
+                    break;
+                case 'g':
+                    if (end - off >= minBPC*3
+                        && charMatches(buf, off + minBPC, 't')
+                        && charMatches(buf, off + minBPC*2, ';'))
+                    {
+                        token.TokenEnd = off + minBPC*3;
+                        token.RefChar1 = '>';
+                        return true;
+                    }
+                    break;
+                case 'q':
+                    if (end - off >= minBPC*5
+                        && charMatches(buf, off + minBPC, 'u')
+                        && charMatches(buf, off + minBPC*2, 'o')
+                        && charMatches(buf, off + minBPC*3, 't')
+                        && charMatches(buf, off + minBPC*4, ';'))
+                    {
+                        token.TokenEnd = off + minBPC*5;
+                        token.RefChar1 = '"';
+                        return true;
+                    }
+                    break;
+            }
+            return false;
+        }
+
+        /* off points to character following "&" */
+        private TOK scanRef(byte[] buf, int off, int end, Token token)
+        {
+            if (off == end)
+                throw new PartialTokenException();
+            if (isMagicEntityRef(buf, off, end, token))
+                return TOK.MAGIC_ENTITY_REF;
+            switch (byteType(buf, off))
+            {
+                case BT_NMSTRT:
+                    off += minBPC;
+                    break;
+                case BT_LEAD2:
+                    if (end - off < 2)
+                        throw new PartialCharException(off);
+                    if (byteType2(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 2;
+                    break;
+                case BT_LEAD3:
+                    if (end - off < 3)
+                        throw new PartialCharException(off);
+                    if (byteType3(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 3;
+                    break;
+                case BT_LEAD4:
+                    if (end - off < 4)
+                        throw new PartialCharException(off);
+                    if (byteType4(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 4;
+                    break;
+                case BT_NUM:
+                    return scanCharRef(buf, off + minBPC, end, token);
+                default:
+                    throw new InvalidTokenException(off);
+            }
+            while (off != end)
+            {
+                switch (byteType(buf, off))
+                {
+                    case BT_NMSTRT:
+                    case BT_NAME:
+                    case BT_MINUS:
+                        off += minBPC;
+                        break;
+                    case BT_LEAD2:
+                        if (end - off < 2)
+                            throw new PartialCharException(off);
+                        if (!isNameChar2(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 2;
+                        break;
+                    case BT_LEAD3:
+                        if (end - off < 3)
+                            throw new PartialCharException(off);
+                        if (!isNameChar3(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 3;
+                        break;
+                    case BT_LEAD4:
+                        if (end - off < 4)
+                            throw new PartialCharException(off);
+                        if (!isNameChar4(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 4;
+                        break;
+                    case BT_SEMI:
+                        token.NameEnd = off;
+                        token.TokenEnd = off + minBPC;
+                        return TOK.ENTITY_REF;
+                    default:
+                        throw new InvalidTokenException(off);
+                }
+            }
+            throw new PartialTokenException();
+        }
+
+        /* off points to character following first character of
+           attribute name */
+        private TOK scanAtts(int nameStart, byte[] buf, int off, int end,
+            ContentToken token)
+        {
+            int NameEnd = -1;
+            while (off != end)
+            {
+                switch (byteType(buf, off))
+                {
+                    case BT_NMSTRT:
+                    case BT_NAME:
+                    case BT_MINUS:
+                        off += minBPC;
+                        break;
+                    case BT_LEAD2:
+                        if (end - off < 2)
+                            throw new PartialCharException(off);
+                        if (!isNameChar2(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 2;
+                        break;
+                    case BT_LEAD3:
+                        if (end - off < 3)
+                            throw new PartialCharException(off);
+                        if (!isNameChar3(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 3;
+                        break;
+                    case BT_LEAD4:
+                        if (end - off < 4)
+                            throw new PartialCharException(off);
+                        if (!isNameChar4(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 4;
+                        break;
+                    case BT_S:
+                    case BT_CR:
+                    case BT_LF:
+                        NameEnd = off;
+                        for (;;)
+                        {
+                            off += minBPC;
+                            if (off == end)
+                                throw new PartialTokenException();
+                            switch (byteType(buf, off))
+                            {
+                                case BT_EQUALS:
+                                    goto loop;
+                                case BT_S:
+                                case BT_LF:
+                                case BT_CR:
+                                    break;
+                                default:
+                                    throw new InvalidTokenException(off);
+                            }
+                        }
+                        loop: ;
+                        /* fall through */
+                        goto case BT_EQUALS;
+                    case BT_EQUALS:
+                    {
+                        if (NameEnd < 0)
+                            NameEnd = off;
+                        int open;
+                        for (;;)
+                        {
+
+                            off += minBPC;
+                            if (off == end)
+                                throw new PartialTokenException();
+                            open = byteType(buf, off);
+                            if (open == BT_QUOT || open == BT_APOS)
+                                break;
+                            switch (open)
+                            {
+                                case BT_S:
+                                case BT_LF:
+                                case BT_CR:
+                                    break;
+                                default:
+                                    throw new InvalidTokenException(off);
+                            }
+                        }
+                        off += minBPC;
+                        int valueStart = off;
+                        bool normalized = true;
+                        int t;
+                        /* in attribute value */
+                        for (;;)
+                        {
+                            if (off == end)
+                                throw new PartialTokenException();
+                            t = byteType(buf, off);
+                            if (t == open)
+                                break;
+                            switch (t)
+                            {
+                                case BT_NONXML:
+                                case BT_MALFORM:
+                                    throw new InvalidTokenException(off);
+                                case BT_LEAD2:
+                                    if (end - off < 2)
+                                        throw new PartialCharException(off);
+                                    check2(buf, off);
+                                    off += 2;
+                                    break;
+                                case BT_LEAD3:
+                                    if (end - off < 3)
+                                        throw new PartialCharException(off);
+                                    check3(buf, off);
+                                    off += 3;
+                                    break;
+                                case BT_LEAD4:
+                                    if (end - off < 4)
+                                        throw new PartialCharException(off);
+                                    check4(buf, off);
+                                    off += 4;
+                                    break;
+                                case BT_AMP:
+                                {
+                                    normalized = false;
+                                    int saveNameEnd = token.NameEnd;
+                                    scanRef(buf, off + minBPC, end, token);
+                                    token.NameEnd = saveNameEnd;
+                                    off = token.TokenEnd;
+                                    break;
+                                }
+                                case BT_S:
+                                    if (normalized
+                                        && (off == valueStart
+                                        || byteToAscii(buf, off) != ' '
+                                        || (off + minBPC != end
+                                        && (byteToAscii(buf, off + minBPC) == ' '
+                                        || byteType(buf, off + minBPC) == open))))
+                                        normalized = false;
+                                    off += minBPC;
+                                    break;
+                                case BT_LT:
+                                    throw new InvalidTokenException(off);
+                                case BT_LF:
+                                case BT_CR:
+                                    normalized = false;
+                                    /* fall through */
+                                    goto default;
+                                default:
+                                    off += minBPC;
+                                    break;
+                            }
+                        }
+                        token.appendAttribute(nameStart, NameEnd, valueStart,
+                            off,
+                            normalized);
+                        off += minBPC;
+                        if (off == end)
+                            throw new PartialTokenException();
+                        t = byteType(buf, off);
+                        switch (t)
+                        {
+                            case BT_S:
+                            case BT_CR:
+                            case BT_LF:
+                                off += minBPC;
+                                if (off == end)
+                                    throw new PartialTokenException();
+                                t = byteType(buf, off);
+                                break;
+                            case BT_GT:
+                            case BT_SOL:
+                                break;
+                            default:
+                                throw new InvalidTokenException(off);
+                        }
+                        /* off points to closing quote */
+                        for (;;)
+                        {
+                            switch (t)
+                            {
+                                case BT_NMSTRT:
+                                    nameStart = off;
+                                    off += minBPC;
+                                    goto skipToName;
+                                case BT_LEAD2:
+                                    if (end - off < 2)
+                                        throw new PartialCharException(off);
+                                    if (byteType2(buf, off) != BT_NMSTRT)
+                                        throw new InvalidTokenException(off);
+                                    nameStart = off;
+                                    off += 2;
+                                    goto skipToName;
+                                case BT_LEAD3:
+                                    if (end - off < 3)
+                                        throw new PartialCharException(off);
+                                    if (byteType3(buf, off) != BT_NMSTRT)
+                                        throw new InvalidTokenException(off);
+                                    nameStart = off;
+                                    off += 3;
+                                    goto skipToName;
+                                case BT_LEAD4:
+                                    if (end - off < 4)
+                                        throw new PartialCharException(off);
+                                    if (byteType4(buf, off) != BT_NMSTRT)
+                                        throw new InvalidTokenException(off);
+                                    nameStart = off;
+                                    off += 4;
+                                    goto skipToName;
+                                case BT_S:
+                                case BT_CR:
+                                case BT_LF:
+                                    break;
+                                case BT_GT:
+                                    token.checkAttributeUniqueness(buf);
+                                    token.TokenEnd = off + minBPC;
+                                    return TOK.START_TAG_WITH_ATTS;
+                                case BT_SOL:
+                                    off += minBPC;
+                                    if (off == end)
+                                        throw new PartialTokenException();
+                                    checkCharMatches(buf, off, '>');
+                                    token.checkAttributeUniqueness(buf);
+                                    token.TokenEnd = off + minBPC;
+                                    return TOK.EMPTY_ELEMENT_WITH_ATTS;
+                                default:
+                                    throw new InvalidTokenException(off);
+                            }
+                            off += minBPC;
+                            if (off == end)
+                                throw new PartialTokenException();
+                            t = byteType(buf, off);
+                        }
+
+                        skipToName:
+                            NameEnd = -1;
+                        break;
+                    }
+                    default:
+                        throw new InvalidTokenException(off);
+                }
+            }
+            throw new PartialTokenException();
+        }
+
+        /* off points to character following "<" */
+        private TOK scanLt(byte[] buf, int off, int end, ContentToken token)
+        {
+            if (off == end)
+                throw new PartialTokenException();
+            switch (byteType(buf, off))
+            {
+                case BT_NMSTRT:
+                    off += minBPC;
+                    break;
+                case BT_LEAD2:
+                    if (end - off < 2)
+                        throw new PartialCharException(off);
+                    if (byteType2(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 2;
+                    break;
+                case BT_LEAD3:
+                    if (end - off < 3)
+                        throw new PartialCharException(off);
+                    if (byteType3(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 3;
+                    break;
+                case BT_LEAD4:
+                    if (end - off < 4)
+                        throw new PartialCharException(off);
+                    if (byteType4(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 4;
+                    break;
+                case BT_EXCL:
+                    if ((off += minBPC) == end)
+                        throw new PartialTokenException();
+                switch (byteType(buf, off))
+                {
+                    case BT_MINUS:
+                        return scanComment(buf, off + minBPC, end, token);
+                    case BT_LSQB:
+                        return scanCdataSection(buf, off + minBPC, end, token);
+                }
+                    throw new InvalidTokenException(off);
+                case BT_QUEST:
+                    return scanPi(buf, off + minBPC, end, token);
+                case BT_SOL:
+                    return scanEndTag(buf, off + minBPC, end, token);
+                default:
+                    throw new InvalidTokenException(off);
+            }
+            /* we have a start-tag */
+            token.NameEnd = -1;
+            token.clearAttributes();
+            while (off != end)
+            {
+                switch (byteType(buf, off))
+                {
+                    case BT_NMSTRT:
+                    case BT_NAME:
+                    case BT_MINUS:
+                        off += minBPC;
+                        break;
+                    case BT_LEAD2:
+                        if (end - off < 2)
+                            throw new PartialCharException(off);
+                        if (!isNameChar2(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 2;
+                        break;
+                    case BT_LEAD3:
+                        if (end - off < 3)
+                            throw new PartialCharException(off);
+                        if (!isNameChar3(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 3;
+                        break;
+                    case BT_LEAD4:
+                        if (end - off < 4)
+                            throw new PartialCharException(off);
+                        if (!isNameChar4(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 4;
+                        break;
+                    case BT_S:
+                    case BT_CR:
+                    case BT_LF:
+                        token.NameEnd = off;
+                        off += minBPC;
+                        for (;;)
+                        {
+                            if (off == end)
+                                throw new PartialTokenException();
+                            switch (byteType(buf, off))
+                            {
+                                case BT_NMSTRT:
+                                    return scanAtts(off, buf, off + minBPC, end, token);
+                                case BT_LEAD2:
+                                    if (end - off < 2)
+                                        throw new PartialCharException(off);
+                                    if (byteType2(buf, off) != BT_NMSTRT)
+                                        throw new InvalidTokenException(off);
+                                    return scanAtts(off, buf, off + 2, end, token);
+                                case BT_LEAD3:
+                                    if (end - off < 3)
+                                        throw new PartialCharException(off);
+                                    if (byteType3(buf, off) != BT_NMSTRT)
+                                        throw new InvalidTokenException(off);
+                                    return scanAtts(off, buf, off + 3, end, token);
+                                case BT_LEAD4:
+                                    if (end - off < 4)
+                                        throw new PartialCharException(off);
+                                    if (byteType4(buf, off) != BT_NMSTRT)
+                                        throw new InvalidTokenException(off);
+                                    return scanAtts(off, buf, off + 4, end, token);
+                                case BT_GT:
+                                case BT_SOL:
+                                    goto loop;
+                                case BT_S:
+                                case BT_CR:
+                                case BT_LF:
+                                    off += minBPC;
+                                    break;
+                                default:
+                                    throw new InvalidTokenException(off);
+                            }
+                        }
+                        loop:
+                            break;
+                    case BT_GT:
+                        if (token.NameEnd < 0)
+                            token.NameEnd = off;
+                        token.TokenEnd = off + minBPC;
+                        return TOK.START_TAG_NO_ATTS;
+                    case BT_SOL:
+                        if (token.NameEnd < 0)
+                            token.NameEnd = off;
+                        off += minBPC;
+                        if (off == end)
+                            throw new PartialTokenException();
+                        checkCharMatches(buf, off, '>');
+                        token.TokenEnd = off + minBPC;
+                        return TOK.EMPTY_ELEMENT_NO_ATTS;
+                    default:
+                        throw new InvalidTokenException(off);
+                }
+            }
+            throw new PartialTokenException();
+        }
+
+        // Ensure that we always scan a multiple of minBPC bytes.
+        private int adjustEnd(int off, int end)
+        {
+            int n = end - off;
+            if ((n & (minBPC - 1)) != 0)
+            {
+                n &= ~(minBPC - 1);
+                if (n == 0)
+                    throw new PartialCharException(off);
+                return off + n;
+            }
+            else
+                return end;
+        }
+
+        /**
+         * Scans the first token of a byte subarrary that contains content.
+         * Returns one of the following integers according to the type of token
+         * that the subarray starts with:
+         * <ul>
+         * <li><code>TOK.START_TAG_NO_ATTS</code></li>
+         * <li><code>TOK.START_TAG_WITH_ATTS</code></li>
+         * <li><code>TOK.EMPTY_ELEMENT_NO_ATTS</code></li>
+         * <li><code>TOK.EMPTY_ELEMENT_WITH_ATTS</code></li>
+         * <li><code>TOK.END_TAG</code></li>
+         * <li><code>TOK.DATA_CHARS</code></li>
+         * <li><code>TOK.DATA_NEWLINE</code></li>
+         * <li><code>TOK.CDATA_SECT_OPEN</code></li>
+         * <li><code>TOK.ENTITY_REF</code></li>
+         * <li><code>TOK.MAGIC_ENTITY_REF</code></li>
+         * <li><code>TOK.CHAR_REF</code></li>
+         * <li><code>TOK.CHAR_PAIR_REF</code></li>
+         * <li><code>TOK.PI</code></li>
+         * <li><code>TOK.XML_DECL</code></li>
+         * <li><code>TOK.COMMENT</code></li>
+         * </ul>
+         * <p>
+         * Information about the token is stored in <code>token</code>.
+         * </p>
+         * When <code>TOK.CDATA_SECT_OPEN</code> is returned,
+         * <code>tokenizeCdataSection</code> should be called until
+         * it returns <code>TOK.CDATA_SECT</code>.
+         *
+         * @exception EmptyTokenException if the subarray is empty
+         * @exception PartialTokenException if the subarray contains only part of
+         * a legal token
+         * @exception InvalidTokenException if the subarrary does not start
+         * with a legal token or part of one
+         * @exception ExtensibleTokenException if the subarray encodes just a carriage
+         * return ('\r')
+         *
+         * @see #TOK.START_TAG_NO_ATTS
+         * @see #TOK.START_TAG_WITH_ATTS
+         * @see #TOK.EMPTY_ELEMENT_NO_ATTS
+         * @see #TOK.EMPTY_ELEMENT_WITH_ATTS
+         * @see #TOK.END_TAG
+         * @see #TOK.DATA_CHARS
+         * @see #TOK.DATA_NEWLINE
+         * @see #TOK.CDATA_SECT_OPEN
+         * @see #TOK.ENTITY_REF
+         * @see #TOK.MAGIC_ENTITY_REF
+         * @see #TOK.CHAR_REF
+         * @see #TOK.CHAR_PAIR_REF
+         * @see #TOK.PI
+         * @see #TOK.XML_DECL
+         * @see #TOK.COMMENT
+         * @see ContentToken
+         * @see EmptyTokenException
+         * @see PartialTokenException
+         * @see InvalidTokenException
+         * @see ExtensibleTokenException
+         * @see #tokenizeCdataSection
+         */
+        public TOK tokenizeContent(byte[] buf, int off, int end,
+            ContentToken token)
+        {
+            if (minBPC > 1)
+                end = adjustEnd(off, end);
+            if (off == end)
+                throw new EmptyTokenException();
+            switch (byteType(buf, off))
+            {
+                case BT_LT:
+                    return scanLt(buf, off + minBPC, end, token);
+                case BT_AMP:
+                    return scanRef(buf, off + minBPC, end, token);
+                case BT_CR:
+                    off += minBPC;
+                    if (off == end)
+                        throw new ExtensibleTokenException(TOK.DATA_NEWLINE);
+                    if (byteType(buf, off) == BT_LF)
+                        off += minBPC;
+                    token.TokenEnd = off;
+                    return TOK.DATA_NEWLINE;
+                case BT_LF:
+                    token.TokenEnd = off + minBPC;
+                    return TOK.DATA_NEWLINE;
+                case BT_RSQB:
+                    off += minBPC;
+                    if (off == end)
+                        throw new ExtensibleTokenException(TOK.DATA_CHARS);
+                    if (!charMatches(buf, off, ']'))
+                        break;
+                    off += minBPC;
+                    if (off == end)
+                        throw new ExtensibleTokenException(TOK.DATA_CHARS);
+                    if (!charMatches(buf, off, '>'))
+                    {
+                        off -= minBPC;
+                        break;
+                    }
+                    throw new InvalidTokenException(off);
+                case BT_NONXML:
+                case BT_MALFORM:
+                    throw new InvalidTokenException(off);
+                case BT_LEAD2:
+                    if (end - off < 2)
+                        throw new PartialCharException(off);
+                    check2(buf, off);
+                    off += 2;
+                    break;
+                case BT_LEAD3:
+                    if (end - off < 3)
+                        throw new PartialCharException(off);
+                    check3(buf, off);
+                    off += 3;
+                    break;
+                case BT_LEAD4:
+                    if (end - off < 4)
+                        throw new PartialCharException(off);
+                    check4(buf, off);
+                    off += 4;
+                    break;
+                default:
+                    off += minBPC;
+                    break;
+            }
+            token.TokenEnd = extendData(buf, off, end);
+            return TOK.DATA_CHARS;
+        }
+
+        int extendData(byte[] buf, int off, int end)
+        {
+            while (off != end)
+            {
+                switch (byteType(buf, off))
+                {
+                    case BT_LEAD2:
+                        if (end - off < 2)
+                            return off;
+                        check2(buf, off);
+                        off += 2;
+                        break;
+                    case BT_LEAD3:
+                        if (end - off < 3)
+                            return off;
+                        check3(buf, off);
+                        off += 3;
+                        break;
+                    case BT_LEAD4:
+                        if (end - off < 4)
+                            return off;
+                        check4(buf, off);
+                        off += 4;
+                        break;
+                    case BT_RSQB:
+                    case BT_AMP:
+                    case BT_LT:
+                    case BT_NONXML:
+                    case BT_MALFORM:
+                    case BT_CR:
+                    case BT_LF:
+                        return off;
+                    default:
+                        off += minBPC;
+                        break;
+                }
+            }
+            return off;
+        }
+
+        /* off points to character following "%" */
+        private TOK scanPercent(byte[] buf, int off, int end, Token token)
+        {
+            if (off == end)
+                throw new PartialTokenException();
+            switch (byteType(buf, off))
+            {
+                case BT_NMSTRT:
+                    off += minBPC;
+                    break;
+                case BT_LEAD2:
+                    if (end - off < 2)
+                        throw new PartialCharException(off);
+                    if (byteType2(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 2;
+                    break;
+                case BT_LEAD3:
+                    if (end - off < 3)
+                        throw new PartialCharException(off);
+                    if (byteType3(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 3;
+                    break;
+                case BT_LEAD4:
+                    if (end - off < 4)
+                        throw new PartialCharException(off);
+                    if (byteType4(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 4;
+                    break;
+                case BT_S:
+                case BT_LF:
+                case BT_CR:
+                case BT_PERCNT:
+                    token.TokenEnd = off;
+                    return TOK.PERCENT;
+                default:
+                    throw new InvalidTokenException(off);
+            }
+            while (off != end)
+            {
+                switch (byteType(buf, off))
+                {
+                    case BT_NMSTRT:
+                    case BT_NAME:
+                    case BT_MINUS:
+                        off += minBPC;
+                        break;
+                    case BT_LEAD2:
+                        if (end - off < 2)
+                            throw new PartialCharException(off);
+                        if (!isNameChar2(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 2;
+                        break;
+                    case BT_LEAD3:
+                        if (end - off < 3)
+                            throw new PartialCharException(off);
+                        if (!isNameChar3(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 3;
+                        break;
+                    case BT_LEAD4:
+                        if (end - off < 4)
+                            throw new PartialCharException(off);
+                        if (!isNameChar4(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 4;
+                        break;
+                    case BT_SEMI:
+                        token.NameEnd = off;
+                        token.TokenEnd = off + minBPC;
+                        return TOK.PARAM_ENTITY_REF;
+                    default:
+                        throw new InvalidTokenException(off);
+                }
+            }
+            throw new PartialTokenException();
+        }
+
+
+        private TOK scanPoundName(byte[] buf, int off, int end, Token token)
+        {
+            if (off == end)
+                throw new PartialTokenException();
+            switch (byteType(buf, off))
+            {
+                case BT_NMSTRT:
+                    off += minBPC;
+                    break;
+                case BT_LEAD2:
+                    if (end - off < 2)
+                        throw new PartialCharException(off);
+                    if (byteType2(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 2;
+                    break;
+                case BT_LEAD3:
+                    if (end - off < 3)
+                        throw new PartialCharException(off);
+                    if (byteType3(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 3;
+                    break;
+                case BT_LEAD4:
+                    if (end - off < 4)
+                        throw new PartialCharException(off);
+                    if (byteType4(buf, off) != BT_NMSTRT)
+                        throw new InvalidTokenException(off);
+                    off += 4;
+                    break;
+                default:
+                    throw new InvalidTokenException(off);
+            }
+            while (off != end)
+            {
+                switch (byteType(buf, off))
+                {
+                    case BT_NMSTRT:
+                    case BT_NAME:
+                    case BT_MINUS:
+                        off += minBPC;
+                        break;
+                    case BT_LEAD2:
+                        if (end - off < 2)
+                            throw new PartialCharException(off);
+                        if (!isNameChar2(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 2;
+                        break;
+                    case BT_LEAD3:
+                        if (end - off < 3)
+                            throw new PartialCharException(off);
+                        if (!isNameChar3(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 3;
+                        break;
+                    case BT_LEAD4:
+                        if (end - off < 4)
+                            throw new PartialCharException(off);
+                        if (!isNameChar4(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 4;
+                        break;
+                    case BT_CR:
+                    case BT_LF:
+                    case BT_S:
+                    case BT_RPAR:
+                    case BT_GT:
+                    case BT_PERCNT:
+                    case BT_VERBAR:
+                        token.TokenEnd = off;
+                        return TOK.POUND_NAME;
+                    default:
+                        throw new InvalidTokenException(off);
+                }
+            }
+            throw new ExtensibleTokenException(TOK.POUND_NAME);
+        }
+
+        private TOK scanLit(int open, byte[] buf, int off, int end, Token token)
+        {
+            while (off != end)
+            {
+                int t = byteType(buf, off);
+                switch (t)
+                {
+                    case BT_LEAD2:
+                        if (end - off < 2)
+                            throw new PartialTokenException();
+                        check2(buf, off);
+                        off += 2;
+                        break;
+                    case BT_LEAD3:
+                        if (end - off < 3)
+                            throw new PartialTokenException();
+                        check3(buf, off);
+                        off += 3;
+                        break;
+                    case BT_LEAD4:
+                        if (end - off < 4)
+                            throw new PartialTokenException();
+                        check4(buf, off);
+                        off += 4;
+                        break;
+                    case BT_NONXML:
+                    case BT_MALFORM:
+                        throw new InvalidTokenException(off);
+                    case BT_QUOT:
+                    case BT_APOS:
+                        off += minBPC;
+                        if (t != open)
+                            break;
+                        if (off == end)
+                            throw new ExtensibleTokenException(TOK.LITERAL);
+                    switch (byteType(buf, off))
+                    {
+                        case BT_S:
+                        case BT_CR:
+                        case BT_LF:
+                        case BT_GT:
+                        case BT_PERCNT:
+                        case BT_LSQB:
+                            token.TokenEnd = off;
+                            return TOK.LITERAL;
+                        default:
+                            throw new InvalidTokenException(off);
+                    }
+                    default:
+                        off += minBPC;
+                        break;
+                }
+            }
+            throw new PartialTokenException();
+        }
+
+        /**
+         * Returns an encoding object to be used to start parsing an
+         * external entity.  The encoding is chosen based on the
+         * initial 4 bytes of the entity.
+         *
+         * @param buf the byte array containing the initial bytes of
+         * the entity @param off the index in <code>buf</code> of the
+         * first byte of the entity @param end the index in
+         * <code>buf</code> following the last available byte of the
+         * entity; <code>end - off</code> must be greater than or
+         * equal to 4 unless the entity has fewer that 4 bytes, in
+         * which case it must be equal to the length of the entity
+         * @param token receives information about the presence of a
+         * byte order mark; if the entity starts with a byte order
+         * mark then <code>token.getTokenEnd()</code> will return
+         * <code>off + 2</code>, otherwise it will return
+         * <code>off</code>
+         *
+         * @see TextDecl
+         * @see XmlDecl
+         * @see #TOK.XML_DECL
+         * @see #getEncoding
+         * @see #getInternalEncoding
+         */
+        public static Encoding getInitialEncoding(byte[] buf, int off, int end,
+            Token token)
+        {
+            token.TokenEnd = off;
+            switch (end - off)
+            {
+                case 0:
+                    break;
+                case 1:
+                    if (buf[off] > 127)
+                        return null;
+                    break;
+                default:
+                    int b0 = buf[off] & 0xFF;
+                    int b1 = buf[off + 1] & 0xFF;
+                switch ((b0 << 8) | b1)
+                {
+                    case 0xFEFF:
+                        token.TokenEnd = off + 2;
+                        /* fall through */
+                        goto case '<';
+                    case '<': /* not legal; but not a fatal error */
+                        return getEncoding(UTF16_BIG_ENDIAN_ENCODING);
+                    case 0xFFFE:
+                        token.TokenEnd = off + 2;
+                        /* fall through */
+                        goto case '<' << 8;
+                    case '<' << 8:  /* not legal; but not a fatal error */
+                        return getEncoding(UTF16_LITTLE_ENDIAN_ENCODING);
+                }
+                    break;
+            }
+            return getEncoding(UTF8_ENCODING);
+        }
+
+        /**
+         * Returns an <code>Encoding</code> corresponding to the
+         * specified IANA character set name.  Returns this
+         * <code>Encoding</code> if the name is null.  Returns null if
+         * the specified encoding is not supported.  Note that there
+         * are two distinct <code>Encoding</code> objects associated
+         * with the name <code>UTF-16</code>, one for each possible
+         * byte order; if this <code>Encoding</code> is UTF-16 with
+         * little-endian byte ordering, then
+         * <code>getEncoding("UTF-16")</code> will return this,
+         * otherwise it will return an <code>Encoding</code> for
+         * UTF-16 with big-endian byte ordering.  @param name a string
+         * specifying the IANA name of the encoding; this is case
+         * insensitive
+         */
+        public Encoding getEncoding(string name)
+        {
+            if (name == null)
+                return this;
+
+            switch (name.ToUpper())
+            {
+                case "UTF-8":
+                    return getEncoding(UTF8_ENCODING);
+                    /*
+                case "UTF-16":
+                    return getUTF16Encoding();
+                case "ISO-8859-1":
+                    return getEncoding(ISO8859_1_ENCODING);
+                case "US-ASCII":
+                    return getEncoding(ASCII_ENCODING);
+                    */
+            }
+            return null;
+        }
+
+        /**
+         * Returns an <code>Encoding</code> for entities encoded with
+         * a single-byte encoding (an encoding in which each byte
+         * represents exactly one character).  @param map a string
+         * specifying the character represented by each byte; the
+         * string must have a length of 256;
+         * <code>map.charAt(b)</code> specifies the character encoded
+         * by byte <code>b</code>; bytes that do not represent any
+         * character should be mapped to <code>\uFFFD</code>
+         */
+        public Encoding getSingleByteEncoding(string map)
+        {
+            //return new SingleByteEncoding(map);
+            throw new System.NotImplementedException();
+        }
+
+        /**
+         * Returns an <code>Encoding</code> object for use with
+         * internal entities.  This is a UTF-16 big endian encoding,
+         * except that newlines are assumed to have been normalized
+         * into line feed, so carriage return is treated like a space.
+         */
+        public static Encoding getInternalEncoding()
+        {
+            return getEncoding(INTERNAL_ENCODING);
+        }
+
+        /**
+         * Scans the first token of a byte subarray that contains part of a
+         * prolog.
+         * Returns one of the following integers according to the type of token
+         * that the subarray starts with:
+         * <ul>
+         * <li><code>TOK.PI</code></li>
+         * <li><code>TOK.XML_DECL</code></li>
+         * <li><code>TOK.COMMENT</code></li>
+         * <li><code>TOK.PARAM_ENTITY_REF</code></li>
+         * <li><code>TOK.PROLOG_S</code></li>
+         * <li><code>TOK.DECL_OPEN</code></li>
+         * <li><code>TOK.DECL_CLOSE</code></li>
+         * <li><code>TOK.NAME</code></li>
+         * <li><code>TOK.NMTOKEN</code></li>
+         * <li><code>TOK.POUND_NAME</code></li>
+         * <li><code>TOK.OR</code></li>
+         * <li><code>TOK.PERCENT</code></li>
+         * <li><code>TOK.OPEN_PAREN</code></li>
+         * <li><code>TOK.CLOSE_PAREN</code></li>
+         * <li><code>TOK.OPEN_BRACKET</code></li>
+         * <li><code>TOK.CLOSE_BRACKET</code></li>
+         * <li><code>TOK.LITERAL</code></li>
+         * <li><code>TOK.NAME_QUESTION</code></li>
+         * <li><code>TOK.NAME_ASTERISK</code></li>
+         * <li><code>TOK.NAME_PLUS</code></li>
+         * <li><code>TOK.COND_SECT_OPEN</code></li>
+         * <li><code>TOK.COND_SECT_CLOSE</code></li>
+         * <li><code>TOK.CLOSE_PAREN_QUESTION</code></li>
+         * <li><code>TOK.CLOSE_PAREN_ASTERISK</code></li>
+         * <li><code>TOK.CLOSE_PAREN_PLUS</code></li>
+         * <li><code>TOK.COMMA</code></li>
+         * </ul>
+         * @exception EmptyTokenException if the subarray is empty
+         * @exception PartialTokenException if the subarray contains only part of
+         * a legal token
+         * @exception InvalidTokenException if the subarrary does not start
+         * with a legal token or part of one
+         * @exception EndOfPrologException if the subarray starts with the document
+         * element; <code>tokenizeContent</code> should be used on the remainder
+         * of the entity
+         * @exception ExtensibleTokenException if the subarray is a legal token
+         * but subsequent bytes in the same entity could be part of the token
+         * @see #TOK.PI
+         * @see #TOK.XML_DECL
+         * @see #TOK.COMMENT
+         * @see #TOK.PARAM_ENTITY_REF
+         * @see #TOK.PROLOG_S
+         * @see #TOK.DECL_OPEN
+         * @see #TOK.DECL_CLOSE
+         * @see #TOK.NAME
+         * @see #TOK.NMTOKEN
+         * @see #TOK.POUND_NAME
+         * @see #TOK.OR
+         * @see #TOK.PERCENT
+         * @see #TOK.OPEN_PAREN
+         * @see #TOK.CLOSE_PAREN
+         * @see #TOK.OPEN_BRACKET
+         * @see #TOK.CLOSE_BRACKET
+         * @see #TOK.LITERAL
+         * @see #TOK.NAME_QUESTION
+         * @see #TOK.NAME_ASTERISK
+         * @see #TOK.NAME_PLUS
+         * @see #TOK.COND_SECT_OPEN
+         * @see #TOK.COND_SECT_CLOSE
+         * @see #TOK.CLOSE_PAREN_QUESTION
+         * @see #TOK.CLOSE_PAREN_ASTERISK
+         * @see #TOK.CLOSE_PAREN_PLUS
+         * @see #TOK.COMMA
+         * @see ContentToken
+         * @see EmptyTokenException
+         * @see PartialTokenException
+         * @see InvalidTokenException
+         * @see ExtensibleTokenException
+         * @see EndOfPrologException
+         */
+        public TOK tokenizeProlog(byte[] buf, int off, int end, Token token)
+        {
+            TOK tok;
+            if (minBPC > 1)
+                end = adjustEnd(off, end);
+            if (off == end)
+                throw new EmptyTokenException();
+            switch (byteType(buf, off))
+            {
+                case BT_QUOT:
+                    return scanLit(BT_QUOT, buf, off + minBPC, end, token);
+                case BT_APOS:
+                    return scanLit(BT_APOS, buf, off + minBPC, end, token);
+                case BT_LT:
+                {
+                    off += minBPC;
+                    if (off == end)
+                        throw new PartialTokenException();
+                    switch (byteType(buf, off))
+                    {
+                        case BT_EXCL:
+                            return scanDecl(buf, off + minBPC, end, token);
+                        case BT_QUEST:
+                            return scanPi(buf, off + minBPC, end, token);
+                        case BT_NMSTRT:
+                        case BT_LEAD2:
+                        case BT_LEAD3:
+                        case BT_LEAD4:
+                            token.TokenEnd = off - minBPC;
+                            throw new EndOfPrologException();
+                    }
+                    throw new InvalidTokenException(off);
+                }
+                case BT_CR:
+                    if (off + minBPC == end)
+                        throw new ExtensibleTokenException(TOK.PROLOG_S);
+                    /* fall through */
+                    goto case BT_S;
+                case BT_S:
+                case BT_LF:
+                    for (;;)
+                    {
+                        off += minBPC;
+                        if (off == end)
+                            break;
+                        switch (byteType(buf, off))
+                        {
+                            case BT_S:
+                            case BT_LF:
+                                break;
+                            case BT_CR:
+                                /* don't split CR/LF pair */
+                                if (off + minBPC != end)
+                                    break;
+                                /* fall through */
+                                goto default;
+                            default:
+                                token.TokenEnd = off;
+                                return TOK.PROLOG_S;
+                        }
+                    }
+                    token.TokenEnd = off;
+                    return TOK.PROLOG_S;
+                case BT_PERCNT:
+                    return scanPercent(buf, off + minBPC, end, token);
+                case BT_COMMA:
+                    token.TokenEnd = off + minBPC;
+                    return TOK.COMMA;
+                case BT_LSQB:
+                    token.TokenEnd = off + minBPC;
+                    return TOK.OPEN_BRACKET;
+                case BT_RSQB:
+                    off += minBPC;
+                    if (off == end)
+                        throw new ExtensibleTokenException(TOK.CLOSE_BRACKET);
+                    if (charMatches(buf, off, ']'))
+                    {
+                        if (off + minBPC == end)
+                            throw new PartialTokenException();
+                        if (charMatches(buf, off + minBPC, '>'))
+                        {
+                            token.TokenEnd = off + 2*minBPC;
+                            return TOK.COND_SECT_CLOSE;
+                        }
+                    }
+                    token.TokenEnd = off;
+                    return TOK.CLOSE_BRACKET;
+                case BT_LPAR:
+                    token.TokenEnd = off + minBPC;
+                    return TOK.OPEN_PAREN;
+                case BT_RPAR:
+                    off += minBPC;
+                    if (off == end)
+                        throw new ExtensibleTokenException(TOK.CLOSE_PAREN);
+                switch (byteType(buf, off))
+                {
+                    case BT_AST:
+                        token.TokenEnd = off + minBPC;
+                        return TOK.CLOSE_PAREN_ASTERISK;
+                    case BT_QUEST:
+                        token.TokenEnd = off + minBPC;
+                        return TOK.CLOSE_PAREN_QUESTION;
+                    case BT_PLUS:
+                        token.TokenEnd = off + minBPC;
+                        return TOK.CLOSE_PAREN_PLUS;
+                    case BT_CR:
+                    case BT_LF:
+                    case BT_S:
+                    case BT_GT:
+                    case BT_COMMA:
+                    case BT_VERBAR:
+                    case BT_RPAR:
+                        token.TokenEnd = off;
+                        return TOK.CLOSE_PAREN;
+                }
+                    throw new InvalidTokenException(off);
+                case BT_VERBAR:
+                    token.TokenEnd = off + minBPC;
+                    return TOK.OR;
+                case BT_GT:
+                    token.TokenEnd = off + minBPC;
+                    return TOK.DECL_CLOSE;
+                case BT_NUM:
+                    return scanPoundName(buf, off + minBPC, end, token);
+                case BT_LEAD2:
+                    if (end - off < 2)
+                        throw new PartialCharException(off);
+                switch (byteType2(buf, off))
+                {
+                    case BT_NMSTRT:
+                        off += 2;
+                        tok = TOK.NAME;
+                        break;
+                    case BT_NAME:
+                        off += 2;
+                        tok = TOK.NMTOKEN;
+                        break;
+                    default:
+                        throw new InvalidTokenException(off);
+                }
+                    break;
+                case BT_LEAD3:
+                    if (end - off < 3)
+                        throw new PartialCharException(off);
+                switch (byteType3(buf, off))
+                {
+                    case BT_NMSTRT:
+                        off += 3;
+                        tok = TOK.NAME;
+                        break;
+                    case BT_NAME:
+                        off += 3;
+                        tok = TOK.NMTOKEN;
+                        break;
+                    default:
+                        throw new InvalidTokenException(off);
+                }
+                    break;
+                case BT_LEAD4:
+                    if (end - off < 4)
+                        throw new PartialCharException(off);
+                switch (byteType4(buf, off))
+                {
+                    case BT_NMSTRT:
+                        off += 4;
+                        tok = TOK.NAME;
+                        break;
+                    case BT_NAME:
+                        off += 4;
+                        tok = TOK.NMTOKEN;
+                        break;
+                    default:
+                        throw new InvalidTokenException(off);
+                }
+                    break;
+                case BT_NMSTRT:
+                    tok = TOK.NAME;
+                    off += minBPC;
+                    break;
+                case BT_NAME:
+                case BT_MINUS:
+                    tok = TOK.NMTOKEN;
+                    off += minBPC;
+                    break;
+                default:
+                    throw new InvalidTokenException(off);
+            }
+            while (off != end)
+            {
+                switch (byteType(buf, off))
+                {
+                    case BT_NMSTRT:
+                    case BT_NAME:
+                    case BT_MINUS:
+                        off += minBPC;
+                        break;
+                    case BT_LEAD2:
+                        if (end - off < 2)
+                            throw new PartialCharException(off);
+                        if (!isNameChar2(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 2;
+                        break;
+                    case BT_LEAD3:
+                        if (end - off < 3)
+                            throw new PartialCharException(off);
+                        if (!isNameChar3(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 3;
+                        break;
+                    case BT_LEAD4:
+                        if (end - off < 4)
+                            throw new PartialCharException(off);
+                        if (!isNameChar4(buf, off))
+                            throw new InvalidTokenException(off);
+                        off += 4;
+                        break;
+                    case BT_GT:
+                    case BT_RPAR:
+                    case BT_COMMA:
+                    case BT_VERBAR:
+                    case BT_LSQB:
+                    case BT_PERCNT:
+                    case BT_S:
+                    case BT_CR:
+                    case BT_LF:
+                        token.TokenEnd = off;
+                        return tok;
+                    case BT_PLUS:
+                        if (tok != TOK.NAME)
+                            throw new InvalidTokenException(off);
+                        token.TokenEnd = off + minBPC;
+                        return TOK.NAME_PLUS;
+                    case BT_AST:
+                        if (tok != TOK.NAME)
+                            throw new InvalidTokenException(off);
+                        token.TokenEnd = off + minBPC;
+                        return TOK.NAME_ASTERISK;
+                    case BT_QUEST:
+                        if (tok != TOK.NAME)
+                            throw new InvalidTokenException(off);
+                        token.TokenEnd = off + minBPC;
+                        return TOK.NAME_QUESTION;
+                    default:
+                        throw new InvalidTokenException(off);
+                }
+            }
+            throw new ExtensibleTokenException(tok);
+        }
+
+        /**
+         * Scans the first token of a byte subarrary that contains part of
+         * literal attribute value.  The opening and closing delimiters
+         * are not included in the subarrary.
+         * Returns one of the following integers according to the type of
+         * token that the subarray starts with:
+         * <ul>
+         * <li><code>TOK.DATA_CHARS</code></li>
+         * <li><code>TOK.DATA_NEWLINE</code></li>
+         * <li><code>TOK.ATTRIBUTE_VALUE_S</code></li>
+         * <li><code>TOK.MAGIC_ENTITY_REF</code></li>
+         * <li><code>TOK.ENTITY_REF</code></li>
+         * <li><code>TOK.CHAR_REF</code></li>
+         * <li><code>TOK.CHAR_PAIR_REF</code></li>
+         * </ul>
+         * @exception EmptyTokenException if the subarray is empty
+         * @exception PartialTokenException if the subarray contains only part of
+         * a legal token
+         * @exception InvalidTokenException if the subarrary does not start
+         * with a legal token or part of one
+         * @exception ExtensibleTokenException if the subarray encodes just a carriage
+         * return ('\r')
+         * @see #TOK.DATA_CHARS
+         * @see #TOK.DATA_NEWLINE
+         * @see #TOK.ATTRIBUTE_VALUE_S
+         * @see #TOK.MAGIC_ENTITY_REF
+         * @see #TOK.ENTITY_REF
+         * @see #TOK.CHAR_REF
+         * @see #TOK.CHAR_PAIR_REF
+         * @see Token
+         * @see EmptyTokenException
+         * @see PartialTokenException
+         * @see InvalidTokenException
+         * @see ExtensibleTokenException
+         */
+        public TOK tokenizeAttributeValue(byte[] buf, int off, int end, Token token)
+        {
+            if (minBPC > 1)
+                end = adjustEnd(off, end);
+            if (off == end)
+                throw new EmptyTokenException();
+            int start = off;
+            while (off != end)
+            {
+                switch (byteType(buf, off))
+                {
+                    case BT_LEAD2:
+                        if (end - off < 2)
+                            throw new PartialCharException(off);
+                        off += 2;
+                        break;
+                    case BT_LEAD3:
+                        if (end - off < 3)
+                            throw new PartialCharException(off);
+                        off += 3;
+                        break;
+                    case BT_LEAD4:
+                        if (end - off < 4)
+                            throw new PartialCharException(off);
+                        off += 4;
+                        break;
+                    case BT_AMP:
+                        if (off == start)
+                            return scanRef(buf, off + minBPC, end, token);
+                        token.TokenEnd = off;
+                        return TOK.DATA_CHARS;
+                    case BT_LT:
+                        /* this is for inside entity references */
+                        throw new InvalidTokenException(off);
+                    case BT_S:
+                        if (off == start)
+                        {
+                            token.TokenEnd = off + minBPC;
+                            return TOK.ATTRIBUTE_VALUE_S;
+                        }
+                        token.TokenEnd = off;
+                        return TOK.DATA_CHARS;
+                    case BT_LF:
+                        if (off == start)
+                        {
+                            token.TokenEnd = off + minBPC;
+                            return TOK.DATA_NEWLINE;
+                        }
+                        token.TokenEnd = off;
+                        return TOK.DATA_CHARS;
+                    case BT_CR:
+                        if (off == start)
+                        {
+                            off += minBPC;
+                            if (off == end)
+                                throw new ExtensibleTokenException(TOK.DATA_NEWLINE);
+                            if (byteType(buf, off) == BT_LF)
+                                off += minBPC;
+                            token.TokenEnd = off;
+                            return TOK.DATA_NEWLINE;
+                        }
+                        token.TokenEnd = off;
+                        return TOK.DATA_CHARS;
+                    default:
+                        off += minBPC;
+                        break;
+                }
+            }
+            token.TokenEnd = off;
+            return TOK.DATA_CHARS;
+        }
+
+        /**
+         * Scans the first token of a byte subarrary that contains part of
+         * literal entity value.  The opening and closing delimiters
+         * are not included in the subarrary.
+         * Returns one of the following integers according to the type of
+         * token that the subarray starts with:
+         * <ul>
+         * <li><code>TOK.DATA_CHARS</code></li>
+         * <li><code>TOK.DATA_NEWLINE</code></li>
+         * <li><code>TOK.PARAM_ENTITY_REF</code></li>
+         * <li><code>TOK.MAGIC_ENTITY_REF</code></li>
+         * <li><code>TOK.ENTITY_REF</code></li>
+         * <li><code>TOK.CHAR_REF</code></li>
+         * <li><code>TOK.CHAR_PAIR_REF</code></li>
+         * </ul>
+         * @exception EmptyTokenException if the subarray is empty
+         * @exception PartialTokenException if the subarray contains only part of
+         * a legal token
+         * @exception InvalidTokenException if the subarrary does not start
+         * with a legal token or part of one
+         * @exception ExtensibleTokenException if the subarray encodes just a carriage
+         * return ('\r')
+         * @see #TOK.DATA_CHARS
+         * @see #TOK.DATA_NEWLINE
+         * @see #TOK.MAGIC_ENTITY_REF
+         * @see #TOK.ENTITY_REF
+         * @see #TOK.PARAM_ENTITY_REF
+         * @see #TOK.CHAR_REF
+         * @see #TOK.CHAR_PAIR_REF
+         * @see Token
+         * @see EmptyTokenException
+         * @see PartialTokenException
+         * @see InvalidTokenException
+         * @see ExtensibleTokenException
+         */
+        public TOK tokenizeEntityValue(byte[] buf, int off, int end,
+            Token token)
+        {
+            if (minBPC > 1)
+                end = adjustEnd(off, end);
+            if (off == end)
+                throw new EmptyTokenException();
+            int start = off;
+            while (off != end)
+            {
+                switch (byteType(buf, off))
+                {
+                    case BT_LEAD2:
+                        if (end - off < 2)
+                            throw new PartialCharException(off);
+                        off += 2;
+                        break;
+                    case BT_LEAD3:
+                        if (end - off < 3)
+                            throw new PartialCharException(off);
+                        off += 3;
+                        break;
+                    case BT_LEAD4:
+                        if (end - off < 4)
+                            throw new PartialCharException(off);
+                        off += 4;
+                        break;
+                    case BT_AMP:
+                        if (off == start)
+                            return scanRef(buf, off + minBPC, end, token);
+                        token.TokenEnd = off;
+                        return TOK.DATA_CHARS;
+                    case BT_PERCNT:
+                        if (off == start)
+                            return scanPercent(buf, off + minBPC, end, token);
+                        token.TokenEnd = off;
+                        return TOK.DATA_CHARS;
+                    case BT_LF:
+                        if (off == start)
+                        {
+                            token.TokenEnd = off + minBPC;
+                            return TOK.DATA_NEWLINE;
+                        }
+                        token.TokenEnd = off;
+                        return TOK.DATA_CHARS;
+                    case BT_CR:
+                        if (off == start)
+                        {
+                            off += minBPC;
+                            if (off == end)
+                                throw new ExtensibleTokenException(TOK.DATA_NEWLINE);
+                            if (byteType(buf, off) == BT_LF)
+                                off += minBPC;
+                            token.TokenEnd = off;
+                            return TOK.DATA_NEWLINE;
+                        }
+                        token.TokenEnd = off;
+                        return TOK.DATA_CHARS;
+                    default:
+                        off += minBPC;
+                        break;
+                }
+            }
+            token.TokenEnd = off;
+            return TOK.DATA_CHARS;
+        }
+
+        /**
+         * Skips over an ignored conditional section.
+         * The subarray starts following the <code><![ IGNORE [</code>.
+         *
+         * @return the index of the character following the closing
+         * <code>]]></code>
+         *
+         * @exception PartialTokenException if the subarray does not contain the
+         * complete ignored conditional section
+         * @exception InvalidTokenException if the ignored conditional section
+         * contains illegal characters
+         */
+        public int skipIgnoreSect(byte[] buf, int off, int end)
+        {
+            if (minBPC > 1)
+                end = adjustEnd(off, end);
+            int level = 0;
+            while (off != end)
+            {
+                switch (byteType(buf, off))
+                {
+                    case BT_LEAD2:
+                        if (end - off < 2)
+                            throw new PartialCharException(off);
+                        check2(buf, off);
+                        off += 2;
+                        break;
+                    case BT_LEAD3:
+                        if (end - off < 3)
+                            throw new PartialCharException(off);
+                        check3(buf, off);
+                        off += 3;
+                        break;
+                    case BT_LEAD4:
+                        if (end - off < 4)
+                            throw new PartialCharException(off);
+                        check4(buf, off);
+                        off += 4;
+                        break;
+                    case BT_NONXML:
+                    case BT_MALFORM:
+                        throw new InvalidTokenException(off);
+                    case BT_LT:
+                        off += minBPC;
+                        if (off == end)
+                            goto loop;
+                        if (!charMatches(buf, off, '!'))
+                            break;
+                        off += minBPC;
+                        if (off == end)
+                            goto loop;
+                        if (!charMatches(buf, off, '['))
+                            break;
+                        level++;
+                        off += minBPC;
+                        break;
+                    case BT_RSQB:
+                        off += minBPC;
+                        if (off == end)
+                            goto loop;
+                        if (!charMatches(buf, off, ']'))
+                            break;
+                        off += minBPC;
+                        if (off == end)
+                            goto loop;
+                        if (charMatches(buf, off, '>'))
+                        {
+                            if (level == 0)
+                                return off + minBPC;
+                            level--;
+                        }
+                        else if (charMatches(buf, off, ']'))
+                            break;
+                        off += minBPC;
+                        break;
+                    default:
+                        off += minBPC;
+                        break;
+                }
+            }
+            loop:
+                throw new PartialTokenException();
+        }
+
+        /**
+         * Checks that a literal contained in the specified byte subarray
+         * is a legal public identifier and returns a string with
+         * the normalized content of the public id.
+         * The subarray includes the opening and closing quotes.
+         * @exception InvalidTokenException if it is not a legal public identifier
+         */
+        public string getPublicId(byte[] buf, int off, int end)
+        {
+            System.Text.StringBuilder sbuf = new System.Text.StringBuilder();
+            off += minBPC;
+            end -= minBPC;
+            for (; off != end; off += minBPC)
+            {
+                char c = (char)byteToAscii(buf, off);
+                switch (byteType(buf, off))
+                {
+                    case BT_MINUS:
+                    case BT_APOS:
+                    case BT_LPAR:
+                    case BT_RPAR:
+                    case BT_PLUS:
+                    case BT_COMMA:
+                    case BT_SOL:
+                    case BT_EQUALS:
+                    case BT_QUEST:
+                    case BT_SEMI:
+                    case BT_EXCL:
+                    case BT_AST:
+                    case BT_PERCNT:
+                    case BT_NUM:
+                        sbuf.Append(c);
+                        break;
+                    case BT_S:
+                        if (charMatches(buf, off, '\t'))
+                            throw new InvalidTokenException(off);
+                        /* fall through */
+                        goto case BT_CR;
+                    case BT_CR:
+                    case BT_LF:
+                        if ((sbuf.Length > 0) && (sbuf[sbuf.Length - 1] != ' '))
+                            sbuf.Append(' ');
+                        break;
+                    case BT_NAME:
+                    case BT_NMSTRT:
+                        if ((c & ~0x7f) == 0)
+                        {
+                            sbuf.Append(c);
+                            break;
+                        }
+                        // fall through
+                        goto default;
+                    default:
+                    switch (c)
+                    {
+                        case '$':
+                        case '@':
+                            break;
+                        default:
+                            throw new InvalidTokenException(off);
+                    }
+                        break;
+                }
+            }
+            if (sbuf.Length > 0 && sbuf[sbuf.Length - 1] == ' ')
+                sbuf.Length = sbuf.Length - 1;
+            return sbuf.ToString();
+        }
+
+        /**
+         * Returns true if the specified byte subarray is equal to the string.
+         * The string must contain only XML significant characters.
+         */
+        public bool matchesXMLstring(byte[] buf, int off, int end, string str)
+        {
+            int len = str.Length;
+            if (len*minBPC != end - off)
+                return false;
+            for (int i = 0; i < len; off += minBPC, i++)
+            {
+                if (!charMatches(buf, off, str[i]))
+                    return false;
+            }
+            return true;
+        }
+
+        /**
+         * Skips over XML whitespace characters at the start of the specified
+         * subarray.
+         *
+         * @return the index of the first non-whitespace character,
+         * <code>end</code> if there is the subarray is all whitespace
+         */
+        public int skipS(byte[] buf, int off, int end)
+        {
+            while (off < end)
+            {
+                switch (byteType(buf, off))
+                {
+                    case BT_S:
+                    case BT_CR:
+                    case BT_LF:
+                        off += minBPC;
+                        break;
+                    default:
+                        goto loop;
+                }
+            }
+            loop:
+                return off;
+        }
+
+        private bool isNameChar2(byte[] buf, int off)
+        {
+            int bt = byteType2(buf, off);
+            return bt == BT_NAME || bt == BT_NMSTRT;
+        }
+
+        private bool isNameChar3(byte[] buf, int off)
+        {
+            int bt = byteType3(buf, off);
+            return bt == BT_NAME || bt == BT_NMSTRT;
+        }
+
+        private bool isNameChar4(byte[] buf, int off)
+        {
+            int bt = byteType4(buf, off);
+            return bt == BT_NAME || bt == BT_NMSTRT;
+        }
+
+        private const string nameStartSingles =
+            "\u003a\u005f\u0386\u038c\u03da\u03dc\u03de\u03e0\u0559\u06d5\u093d\u09b2" +
+            "\u0a5e\u0a8d\u0abd\u0ae0\u0b3d\u0b9c\u0cde\u0e30\u0e84\u0e8a\u0e8d\u0ea5" +
+            "\u0ea7\u0eb0\u0ebd\u1100\u1109\u113c\u113e\u1140\u114c\u114e\u1150\u1159" +
+            "\u1163\u1165\u1167\u1169\u1175\u119e\u11a8\u11ab\u11ba\u11eb\u11f0\u11f9" +
+            "\u1f59\u1f5b\u1f5d\u1fbe\u2126\u212e\u3007";
+
+        private const string nameStartRanges =
+            "\u0041\u005a\u0061\u007a\u00c0\u00d6\u00d8\u00f6\u00f8\u00ff\u0100\u0131" +
+            "\u0134\u013e\u0141\u0148\u014a\u017e\u0180\u01c3\u01cd\u01f0\u01f4\u01f5" +
+            "\u01fa\u0217\u0250\u02a8\u02bb\u02c1\u0388\u038a\u038e\u03a1\u03a3\u03ce" +
+            "\u03d0\u03d6\u03e2\u03f3\u0401\u040c\u040e\u044f\u0451\u045c\u045e\u0481" +
+            "\u0490\u04c4\u04c7\u04c8\u04cb\u04cc\u04d0\u04eb\u04ee\u04f5\u04f8\u04f9" +
+            "\u0531\u0556\u0561\u0586\u05d0\u05ea\u05f0\u05f2\u0621\u063a\u0641\u064a" +
+            "\u0671\u06b7\u06ba\u06be\u06c0\u06ce\u06d0\u06d3\u06e5\u06e6\u0905\u0939" +
+            "\u0958\u0961\u0985\u098c\u098f\u0990\u0993\u09a8\u09aa\u09b0\u09b6\u09b9" +
+            "\u09dc\u09dd\u09df\u09e1\u09f0\u09f1\u0a05\u0a0a\u0a0f\u0a10\u0a13\u0a28" +
+            "\u0a2a\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59\u0a5c\u0a72\u0a74" +
+            "\u0a85\u0a8b\u0a8f\u0a91\u0a93\u0aa8\u0aaa\u0ab0\u0ab2\u0ab3\u0ab5\u0ab9" +
+            "\u0b05\u0b0c\u0b0f\u0b10\u0b13\u0b28\u0b2a\u0b30\u0b32\u0b33\u0b36\u0b39" +
+            "\u0b5c\u0b5d\u0b5f\u0b61\u0b85\u0b8a\u0b8e\u0b90\u0b92\u0b95\u0b99\u0b9a" +
+            "\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8\u0baa\u0bae\u0bb5\u0bb7\u0bb9\u0c05\u0c0c" +
+            "\u0c0e\u0c10\u0c12\u0c28\u0c2a\u0c33\u0c35\u0c39\u0c60\u0c61\u0c85\u0c8c" +
+            "\u0c8e\u0c90\u0c92\u0ca8\u0caa\u0cb3\u0cb5\u0cb9\u0ce0\u0ce1\u0d05\u0d0c" +
+            "\u0d0e\u0d10\u0d12\u0d28\u0d2a\u0d39\u0d60\u0d61\u0e01\u0e2e\u0e32\u0e33" +
+            "\u0e40\u0e45\u0e81\u0e82\u0e87\u0e88\u0e94\u0e97\u0e99\u0e9f\u0ea1\u0ea3" +
+            "\u0eaa\u0eab\u0ead\u0eae\u0eb2\u0eb3\u0ec0\u0ec4\u0f40\u0f47\u0f49\u0f69" +
+            "\u10a0\u10c5\u10d0\u10f6\u1102\u1103\u1105\u1107\u110b\u110c\u110e\u1112" +
+            "\u1154\u1155\u115f\u1161\u116d\u116e\u1172\u1173\u11ae\u11af\u11b7\u11b8" +
+            "\u11bc\u11c2\u1e00\u1e9b\u1ea0\u1ef9\u1f00\u1f15\u1f18\u1f1d\u1f20\u1f45" +
+            "\u1f48\u1f4d\u1f50\u1f57\u1f5f\u1f7d\u1f80\u1fb4\u1fb6\u1fbc\u1fc2\u1fc4" +
+            "\u1fc6\u1fcc\u1fd0\u1fd3\u1fd6\u1fdb\u1fe0\u1fec\u1ff2\u1ff4\u1ff6\u1ffc" +
+            "\u212a\u212b\u2180\u2182\u3041\u3094\u30a1\u30fa\u3105\u312c\uac00\ud7a3" +
+            "\u4e00\u9fa5\u3021\u3029";
+
+        private const string nameSingles =
+            "\u002d\u002e\u05bf\u05c4\u0670\u093c\u094d\u09bc\u09be\u09bf\u09d7\u0a02" +
+            "\u0a3c\u0a3e\u0a3f\u0abc\u0b3c\u0bd7\u0d57\u0e31\u0eb1\u0f35\u0f37\u0f39" +
+            "\u0f3e\u0f3f\u0f97\u0fb9\u20e1\u3099\u309a\u00b7\u02d0\u02d1\u0387\u0640" +
+            "\u0e46\u0ec6\u3005";
+
+        private const string nameRanges =
+            "\u0300\u0345\u0360\u0361\u0483\u0486\u0591\u05a1\u05a3\u05b9\u05bb\u05bd" +
+            "\u05c1\u05c2\u064b\u0652\u06d6\u06dc\u06dd\u06df\u06e0\u06e4\u06e7\u06e8" +
+            "\u06ea\u06ed\u0901\u0903\u093e\u094c\u0951\u0954\u0962\u0963\u0981\u0983" +
+            "\u09c0\u09c4\u09c7\u09c8\u09cb\u09cd\u09e2\u09e3\u0a40\u0a42\u0a47\u0a48" +
+            "\u0a4b\u0a4d\u0a70\u0a71\u0a81\u0a83\u0abe\u0ac5\u0ac7\u0ac9\u0acb\u0acd" +
+            "\u0b01\u0b03\u0b3e\u0b43\u0b47\u0b48\u0b4b\u0b4d\u0b56\u0b57\u0b82\u0b83" +
+            "\u0bbe\u0bc2\u0bc6\u0bc8\u0bca\u0bcd\u0c01\u0c03\u0c3e\u0c44\u0c46\u0c48" +
+            "\u0c4a\u0c4d\u0c55\u0c56\u0c82\u0c83\u0cbe\u0cc4\u0cc6\u0cc8\u0cca\u0ccd" +
+            "\u0cd5\u0cd6\u0d02\u0d03\u0d3e\u0d43\u0d46\u0d48\u0d4a\u0d4d\u0e34\u0e3a" +
+            "\u0e47\u0e4e\u0eb4\u0eb9\u0ebb\u0ebc\u0ec8\u0ecd\u0f18\u0f19\u0f71\u0f84" +
+            "\u0f86\u0f8b\u0f90\u0f95\u0f99\u0fad\u0fb1\u0fb7\u20d0\u20dc\u302a\u302f" +
+            "\u0030\u0039\u0660\u0669\u06f0\u06f9\u0966\u096f\u09e6\u09ef\u0a66\u0a6f" +
+            "\u0ae6\u0aef\u0b66\u0b6f\u0be7\u0bef\u0c66\u0c6f\u0ce6\u0cef\u0d66\u0d6f" +
+            "\u0e50\u0e59\u0ed0\u0ed9\u0f20\u0f29\u3031\u3035\u309d\u309e\u30fc\u30fe";
+
+        /// <summary>
+        ///
+        /// </summary>
+        protected static int[][] charTypeTable;
+        private static void setCharType(char c, int type)
+        {
+            if (c < 0x80)
+                return;
+            int hi = c >> 8;
+            if (charTypeTable[hi] == null)
+            {
+                charTypeTable[hi] = new int[256];
+                for (int i = 0; i < 256; i++)
+                    charTypeTable[hi][i] = BT_OTHER;
+            }
+            charTypeTable[hi][c & 0xFF] = type;
+        }
+
+        private static void setCharType(char min, char max, int type)
+        {
+            int[] shared = null;
+            do
+            {
+                if ((min & 0xFF) == 0)
+                {
+                    for (; min + (char)0xFF <= max; min += (char)0x100)
+                    {
+                        if (shared == null)
+                        {
+                            shared = new int[256];
+                            for (int i = 0; i < 256; i++)
+                                shared[i] = type;
+                        }
+                        charTypeTable[min >> 8] = shared;
+                        if (min + 0xFF == max)
+                            return;
+                    }
+                }
+                setCharType(min, type);
+            } while (min++ != max);
+        }
+
+        static Encoding()
+        {
+            charTypeTable = new int[256][];
+            foreach (char c in nameSingles)
+                setCharType(c, BT_NAME);
+            for (int i = 0; i < nameRanges.Length; i += 2)
+                setCharType(nameRanges[i], nameRanges[i + 1], BT_NAME);
+            for (int i = 0; i < nameStartSingles.Length; i++)
+                setCharType(nameStartSingles[i], BT_NMSTRT);
+            for (int i = 0; i < nameStartRanges.Length; i += 2)
+                setCharType(nameStartRanges[i], nameStartRanges[i + 1],
+                    BT_NMSTRT);
+            setCharType('\uD800', '\uDBFF', BT_LEAD4);
+            setCharType('\uDC00', '\uDFFF', BT_MALFORM);
+            setCharType('\uFFFE', '\uFFFF', BT_NONXML);
+            int[] other = new int[256];
+            for (int i = 0; i < 256; i++)
+                other[i] = BT_OTHER;
+            for (int i = 0; i < 256; i++)
+                if (charTypeTable[i] == null)
+                    charTypeTable[i] = other;
+            System.Array.Copy(asciiTypeTable, 0, charTypeTable[0], 0, 128);
+        }
+
+        /**
+         * Returns the minimum number of bytes required to represent a single
+         * character in this encoding.  The value will be 1, 2 or 4.
+         */
+        public int MinBytesPerChar
+        {
+            get { return minBPC; }
+        }
+    }
+}
diff --git a/lib/jabber-net/xpnet/Exceptions.cs b/lib/jabber-net/xpnet/Exceptions.cs
new file mode 100644
index 0000000..ea32220
--- /dev/null
+++ b/lib/jabber-net/xpnet/Exceptions.cs
@@ -0,0 +1,180 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ *
+ * xpnet is a deriviative of James Clark's XP.  See copying.txt for more info.
+ * --------------------------------------------------------------------------*/
+namespace xpnet
+{
+    using bedrock.util;
+
+    /// <summary>
+    /// Base class for other exceptions
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class TokenException : System.Exception
+    {
+    }
+
+    /// <summary>
+    /// An empty token was detected.  This only happens with a buffer of length 0 is passed in
+    /// to the parser.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class EmptyTokenException : TokenException
+    {
+    }
+
+    /// <summary>
+    /// End of prolog.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class EndOfPrologException : TokenException
+    {
+    }
+    /**
+     * Thrown to indicate that the byte subarray being tokenized is a legal XML
+     * token, but that subsequent bytes in the same entity could be part of
+     * the token.  For example, <code>Encoding.tokenizeProlog</code>
+     * would throw this if the byte subarray consists of a legal XML name.
+     * @version $Revision$ $Date$
+     */
+    [SVN(@"$Id$")]
+    public class ExtensibleTokenException : TokenException
+    {
+        private TOK tokType;
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="tokType"></param>
+        public ExtensibleTokenException(TOK tokType)
+        {
+            this.tokType = tokType;
+        }
+
+        /**
+         * Returns the type of token in the byte subarrary.
+         */
+        public TOK TokenType
+        {
+            get { return tokType; }
+        }
+    }
+
+    /// <summary>
+    /// Several kinds of token problems.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class InvalidTokenException : TokenException
+    {
+        private int offset;
+        private byte type;
+
+        /// <summary>
+        /// An illegal character
+        /// </summary>
+        public const byte ILLEGAL_CHAR = 0;
+        /// <summary>
+        /// Doc prefix wasn't XML
+        /// </summary>
+        public const byte XML_TARGET = 1;
+        /// <summary>
+        /// More than one attribute with the same name on the same element
+        /// </summary>
+        public const byte DUPLICATE_ATTRIBUTE = 2;
+
+        /// <summary>
+        /// Some other type of bad token detected
+        /// </summary>
+        /// <param name="offset"></param>
+        /// <param name="type"></param>
+        public InvalidTokenException(int offset, byte type)
+        {
+            this.offset = offset;
+            this.type = type;
+        }
+
+        /// <summary>
+        /// Illegal character detected
+        /// </summary>
+        /// <param name="offset"></param>
+        public InvalidTokenException(int offset)
+        {
+            this.offset = offset;
+            this.type = ILLEGAL_CHAR;
+        }
+
+        /// <summary>
+        /// Offset into the buffer where the problem ocurred.
+        /// </summary>
+        public int Offset
+        {
+            get { return this.offset; }
+        }
+
+        /// <summary>
+        /// Type of exception
+        /// </summary>
+        public int Type
+        {
+            get { return this.type; }
+        }
+
+        /// <summary>
+        /// String
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            return "OFFSET: " + this.offset.ToString() + "\r\nTYPE: " + this.type.ToString() + "\r\n" +  base.ToString();
+        }
+    }
+
+    /**
+     * Thrown to indicate that the subarray being tokenized is not the
+     * complete encoding of one or more characters, but might be if
+     * more bytes were added.
+     * @version $Revision$ $Date$
+     */
+    [SVN(@"$Id$")]
+    public class PartialCharException : PartialTokenException
+    {
+        private int leadByteIndex;
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="leadByteIndex"></param>
+        public PartialCharException(int leadByteIndex)
+        {
+            this.leadByteIndex = leadByteIndex;
+        }
+
+        /**
+         * Returns the index of the first byte that is not part of the complete
+         * encoding of a character.
+         */
+        public int LeadByteIndex
+        {
+            get { return leadByteIndex; }
+        }
+    }
+
+    /// <summary>
+    /// A partial token was received.  Try again, after you add more bytes to the buffer.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class PartialTokenException : TokenException
+    {
+    }
+}
diff --git a/lib/jabber-net/xpnet/Position.cs b/lib/jabber-net/xpnet/Position.cs
new file mode 100644
index 0000000..4be3b0b
--- /dev/null
+++ b/lib/jabber-net/xpnet/Position.cs
@@ -0,0 +1,74 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ *
+ * xpnet is a deriviative of James Clark's XP.  See copying.txt for more info.
+ * --------------------------------------------------------------------------*/
+namespace xpnet
+{
+    using bedrock.util;
+
+    /**
+     * Represents a position in an entity.
+     * A position can be modified by <code>Encoding.movePosition</code>.
+     * @see Encoding#movePosition
+     * @version $Revision$ $Date$
+     */
+    ///<summary>
+    /// Position of an entry in a table.
+    ///</summary>
+    [SVN(@"$Id$")]
+    public class Position : System.ICloneable
+    {
+        private int lineNumber;
+        private int columnNumber;
+
+        /**
+         * Creates a position for the start of an entity: the line number is
+         * 1 and the column number is 0.
+         */
+        public Position()
+        {
+            lineNumber = 1;
+            columnNumber = 0;
+        }
+
+        /**
+         * Returns the line number.
+         * The first line number is 1.
+         */
+        public int LineNumber
+        {
+            get {return lineNumber;}
+            set {lineNumber = value;}
+        }
+
+        /**
+         * Returns the column number.
+         * The first column number is 0.
+         * A tab character is not treated specially.
+         */
+        public int ColumnNumber
+        {
+            get { return columnNumber; }
+            set { columnNumber = value; }
+        }
+
+        /**
+         * Returns a copy of this position.
+         */
+        public object Clone()
+        {
+            throw new System.NotImplementedException();
+        }
+    }
+}
diff --git a/lib/jabber-net/xpnet/Token.cs b/lib/jabber-net/xpnet/Token.cs
new file mode 100644
index 0000000..56b4d4d
--- /dev/null
+++ b/lib/jabber-net/xpnet/Token.cs
@@ -0,0 +1,73 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ *
+ * xpnet is a deriviative of James Clark's XP.  See copying.txt for more info.
+ * --------------------------------------------------------------------------*/
+namespace xpnet
+{
+    using bedrock.util;
+
+    /// <summary>
+    /// A token that was parsed.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class Token
+    {
+        private int tokenEnd = -1;
+        private int nameEnd = -1;
+        private char refChar1 = (char)0;
+        private char refChar2 = (char)0;
+
+        /// <summary>
+        /// The end of the current token, in relation to the beginning of the buffer.
+        /// </summary>
+        public int TokenEnd
+        {
+            get {return tokenEnd;}
+            set {tokenEnd = value; }
+        }
+
+        /// <summary>
+        /// The end of the current token's name, in relation to the beginning of the buffer.
+        /// </summary>
+        public int NameEnd
+        {
+            get {return nameEnd;}
+            set {nameEnd = value;}
+        }
+
+        /// <summary>
+        /// The parsed-out character. & for &amp;
+        /// </summary>
+        public char RefChar1
+        {
+            get {return refChar1;}
+            set {refChar1 = value; }
+        }
+        /// <summary>
+        /// The second of two parsed-out characters.  TODO: find example.
+        /// </summary>
+        public char RefChar2
+        {
+            get {return refChar2;}
+            set {refChar2 = value; }
+        }
+
+        /*
+        public void getRefCharPair(char[] ch, int off) {
+            ch[off] = refChar1;
+            ch[off + 1] = refChar2;
+        }
+        */
+    }
+}
diff --git a/lib/jabber-net/xpnet/UTF8Encoding.cs b/lib/jabber-net/xpnet/UTF8Encoding.cs
new file mode 100644
index 0000000..631a81e
--- /dev/null
+++ b/lib/jabber-net/xpnet/UTF8Encoding.cs
@@ -0,0 +1,266 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ *
+ * xpnet is a deriviative of James Clark's XP.  See copying.txt for more info.
+ * --------------------------------------------------------------------------*/
+namespace xpnet
+{
+    using bedrock.util;
+
+    /// <summary>
+    /// UTF-8 specific tokenizer.
+    /// </summary>
+    [SVN(@"$Id$")]
+    public class UTF8Encoding : Encoding
+    {
+        private static readonly int[] utf8HiTypeTable = new int[]
+        {
+            /* 0x80 */ BT_MALFORM, BT_MALFORM, BT_MALFORM, BT_MALFORM,
+            /* 0x84 */ BT_MALFORM, BT_MALFORM, BT_MALFORM, BT_MALFORM,
+            /* 0x88 */ BT_MALFORM, BT_MALFORM, BT_MALFORM, BT_MALFORM,
+            /* 0x8C */ BT_MALFORM, BT_MALFORM, BT_MALFORM, BT_MALFORM,
+            /* 0x90 */ BT_MALFORM, BT_MALFORM, BT_MALFORM, BT_MALFORM,
+            /* 0x94 */ BT_MALFORM, BT_MALFORM, BT_MALFORM, BT_MALFORM,
+            /* 0x98 */ BT_MALFORM, BT_MALFORM, BT_MALFORM, BT_MALFORM,
+            /* 0x9C */ BT_MALFORM, BT_MALFORM, BT_MALFORM, BT_MALFORM,
+            /* 0xA0 */ BT_MALFORM, BT_MALFORM, BT_MALFORM, BT_MALFORM,
+            /* 0xA4 */ BT_MALFORM, BT_MALFORM, BT_MALFORM, BT_MALFORM,
+            /* 0xA8 */ BT_MALFORM, BT_MALFORM, BT_MALFORM, BT_MALFORM,
+            /* 0xAC */ BT_MALFORM, BT_MALFORM, BT_MALFORM, BT_MALFORM,
+            /* 0xB0 */ BT_MALFORM, BT_MALFORM, BT_MALFORM, BT_MALFORM,
+            /* 0xB4 */ BT_MALFORM, BT_MALFORM, BT_MALFORM, BT_MALFORM,
+            /* 0xB8 */ BT_MALFORM, BT_MALFORM, BT_MALFORM, BT_MALFORM,
+            /* 0xBC */ BT_MALFORM, BT_MALFORM, BT_MALFORM, BT_MALFORM,
+            /* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+            /* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+            /* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+            /* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+            /* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+            /* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+            /* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+            /* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+            /* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+            /* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+            /* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+            /* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+            /* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
+            /* 0xF4 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
+            /* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+            /* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM
+        };
+
+        private static int[] utf8TypeTable = new int[256];
+
+        static UTF8Encoding()
+        {
+            System.Array.Copy(asciiTypeTable,  0, utf8TypeTable,   0, 128);
+            System.Array.Copy(utf8HiTypeTable, 0, utf8TypeTable, 128, 128);
+        }
+
+        /// <summary>
+        /// New tokenizer
+        /// </summary>
+        public UTF8Encoding() : base(1)
+        {
+        }
+
+        /// <summary>
+        /// What is the type of the current byte?
+        /// </summary>
+        /// <param name="buf"></param>
+        /// <param name="off"></param>
+        /// <returns></returns>
+        protected override int byteType(byte[] buf, int off)
+        {
+            return utf8TypeTable[buf[off] & 0xFF];
+        }
+
+        /// <summary>
+        /// Current byte to ASCII char
+        /// </summary>
+        /// <param name="buf"></param>
+        /// <param name="off"></param>
+        /// <returns></returns>
+        protected override char byteToAscii(byte[] buf, int off)
+        {
+            return (char)buf[off];
+        }
+
+        /// <summary>
+        /// c is a significant ASCII character
+        /// </summary>
+        /// <param name="buf"></param>
+        /// <param name="off"></param>
+        /// <param name="c"></param>
+        /// <returns></returns>
+        protected override bool charMatches(byte[] buf, int off, char c)
+        {
+            return ((char)buf[off]) == c;
+        }
+
+        /// <summary>
+        /// A 2 byte UTF-8 representation splits the characters 11 bits
+        /// between the bottom 5 and 6 bits of the bytes.
+        /// </summary>
+        /// <param name="buf"></param>
+        /// <param name="off"></param>
+        /// <returns></returns>
+        protected override int byteType2(byte[] buf, int off)
+        {
+            int[] page = charTypeTable[(buf[off] >> 2) & 0x7];
+            return page[((buf[off] & 3) << 6) | (buf[off + 1] & 0x3F)];
+        }
+
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="sourceBuf"></param>
+        /// <param name="sourceStart"></param>
+        /// <param name="sourceEnd"></param>
+        /// <param name="targetBuf"></param>
+        /// <param name="targetStart"></param>
+        /// <returns></returns>
+        protected override int convert(byte[] sourceBuf,
+            int sourceStart, int sourceEnd,
+            char[] targetBuf, int targetStart)
+        {
+            int initTargetStart = targetStart;
+            int c;
+            while (sourceStart != sourceEnd)
+            {
+                byte b = sourceBuf[sourceStart++];
+                if (b >= 0)
+                    targetBuf[targetStart++] = (char)b;
+                else
+                {
+                    switch (utf8TypeTable[b & 0xFF])
+                    {
+                        case BT_LEAD2:
+                            /* 5, 6 */
+                            targetBuf[targetStart++]
+                                = (char)(((b & 0x1F) << 6) | (sourceBuf[sourceStart++] & 0x3F));
+                            break;
+                        case BT_LEAD3:
+                            /* 4, 6, 6 */
+                            c = (b & 0xF) << 12;
+                            c |= (sourceBuf[sourceStart++] & 0x3F) << 6;
+                            c |= (sourceBuf[sourceStart++] & 0x3F);
+                            targetBuf[targetStart++] = (char)c;
+                            break;
+                        case BT_LEAD4:
+                            /* 3, 6, 6, 6 */
+                            c = (b & 0x7) << 18;
+                            c |= (sourceBuf[sourceStart++] & 0x3F) << 12;
+                            c |= (sourceBuf[sourceStart++] & 0x3F) << 6;
+                            c |= (sourceBuf[sourceStart++] & 0x3F);
+                            c -= 0x10000;
+                            targetBuf[targetStart++] = (char)((c >> 10) | 0xD800);
+                            targetBuf[targetStart++] = (char)((c & ((1 << 10) - 1)) | 0xDC00);
+                            break;
+                    }
+                }
+            }
+            return targetStart - initTargetStart;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="buf"></param>
+        /// <param name="off"></param>
+        /// <param name="end"></param>
+        /// <param name="pos"></param>
+        protected override void movePosition(byte[] buf, int off, int end, Position pos)
+        {
+            /* Maintain the invariant: off - colDiff == colNumber. */
+            int colDiff = off - pos.ColumnNumber;
+            int lineNumber = pos.LineNumber;
+            while (off != end)
+            {
+                byte b = buf[off];
+                if (b >= 0)
+                {
+                    ++off;
+                    switch (b)
+                    {
+                        case (byte)'\n':
+                            lineNumber += 1;
+                            colDiff = off;
+                            break;
+                        case (byte)'\r':
+                            lineNumber += 1;
+                            if (off != end && buf[off] == '\n')
+                                off++;
+                            colDiff = off;
+                            break;
+                    }
+                }
+                else
+                {
+                    switch (utf8TypeTable[b & 0xFF])
+                    {
+                        default:
+                            off += 1;
+                            break;
+                        case BT_LEAD2:
+                            off += 2;
+                            colDiff++;
+                            break;
+                        case BT_LEAD3:
+                            off += 3;
+                            colDiff += 2;
+                            break;
+                        case BT_LEAD4:
+                            off += 4;
+                            colDiff += 3;
+                            break;
+                    }
+                }
+            }
+            pos.ColumnNumber = off - colDiff;
+            pos.LineNumber = lineNumber;
+        }
+
+        /*
+        int extendData(byte[] buf, int off, int end)
+        {
+            while (off != end)
+            {
+                int type = utf8TypeTable[buf[off] & 0xFF];
+                if (type >= 0)
+                    off++;
+                else if (type < BT_LEAD4)
+                    break;
+                else
+                {
+                    if (end - off + type < 0)
+                        break;
+                    switch (type)
+                    {
+                        case BT_LEAD3:
+                            check3(buf, off);
+                            break;
+                        case BT_LEAD4:
+                            check4(buf, off);
+                            break;
+                    }
+
+                    off -= (int)type; // this is an ugly hack, James
+                }
+            }
+            return off;
+        }
+        */
+    }
+}
diff --git a/lib/osx/Info.plist.in b/lib/osx/Info.plist.in
new file mode 100644
index 0000000..247fa6b
--- /dev/null
+++ b/lib/osx/Info.plist.in
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>smuxi</string>
+	<key>CFBundleIconFile</key>
+	<string>smuxi.icns</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.smuxi</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>Smuxi</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>@VERSION@</string>
+	<key>CFBundleSignature</key>
+	<string>smxi</string>
+	<key>CFBundleVersion</key>
+	<string>@VERSION@</string>
+	<key>NSAppleScriptEnabled</key>
+	<string>NO</string>
+</dict>
+</plist>
diff --git a/libtool.m4 b/libtool.m4
new file mode 100644
index 0000000..828104c
--- /dev/null
+++ b/libtool.m4
@@ -0,0 +1,8001 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 57 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+       [m4_default([$3],
+		   [m4_fatal([Libtool version $1 or higher is required],
+		             63)])],
+       [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+  *\ * | *\	*)
+    AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+  case $cc_temp in
+    compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+    distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    _LT_PATH_MAGIC
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+              [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME.  Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+    [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+	[m4_ifval([$1], [$1], [$2])])
+    lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+    m4_ifval([$4],
+	[lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+    lt_dict_add_subkey([lt_decl_dict], [$2],
+	[tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+  [0], [m4_fatal([$0: too few arguments: $#])],
+  [1], [m4_fatal([$0: too few arguments: $#: $1])],
+  [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+  [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+  [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+    m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+    m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+     m4_if([$2], [],
+	   m4_quote(lt_decl_varnames),
+	m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+			lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'.  VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly.  In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+#    <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+    [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+#    # Some comment about what VAR is for.
+#    visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+					   [description])))[]dnl
+m4_pushdef([_libtool_name],
+    m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+    [0], [_libtool_name=[$]$1],
+    [1], [_libtool_name=$lt_[]$1],
+    [2], [_libtool_name=$lt_[]$1],
+    [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script.  Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+    m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'.  Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+	dnl If the libtool generation code has been placed in $CONFIG_LT,
+	dnl instead of duplicating it all over again into config.status,
+	dnl then we will have config.status run $CONFIG_LT later, so it
+	dnl needs to know what name is stored there:
+        [AC_CONFIG_COMMANDS([libtool],
+            [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+    dnl If the libtool generation code is destined for config.status,
+    dnl expand the accumulated commands and init code now:
+    [AC_CONFIG_COMMANDS([libtool],
+        [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable.  If COMMENT is supplied, it is inserted after the
+# `#!' sequence but before initialization text begins.  After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script.  The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test $lt_write_fail = 0 && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+  echo
+  AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+  -h, --help      print this help, then exit
+  -V, --version   print version number, then exit
+  -q, --quiet     do not print progress messages
+  -d, --debug     don't remove temporary files
+
+Report bugs to <bug-libtool at gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+  case $[1] in
+    --version | --v* | -V )
+      echo "$lt_cl_version"; exit 0 ;;
+    --help | --h* | -h )
+      echo "$lt_cl_help"; exit 0 ;;
+    --debug | --d* | -d )
+      debug=: ;;
+    --quiet | --q* | --silent | --s* | -q )
+      lt_cl_silent=: ;;
+
+    -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+    *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+  esac
+  shift
+done
+
+if $lt_cl_silent; then
+  exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure.  Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test "$silent" = yes &&
+  lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars.  Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+  m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+  m4_if(_LT_TAG, [C], [
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+  _LT_PROG_LTMAIN
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  _LT_PROG_REPLACE_SHELLFNS
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+#    autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+  [C],			[_LT_LANG(C)],
+  [C++],		[_LT_LANG(CXX)],
+  [Go],			[_LT_LANG(GO)],
+  [Java],		[_LT_LANG(GCJ)],
+  [Fortran 77],		[_LT_LANG(F77)],
+  [Fortran],		[_LT_LANG(FC)],
+  [Windows Resource],	[_LT_LANG(RC)],
+  [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+    [_LT_LANG($1)],
+    [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+  [LT_SUPPORTED_TAG([$1])dnl
+  m4_append([_LT_TAGS], [$1 ])dnl
+  m4_define([_LT_LANG_]$1[_enabled], [])dnl
+  _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_GO.  When it is available in    #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC],     [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+  if test -n "$ac_tool_prefix"; then
+    AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+  fi
+fi
+if test -z "$GOC"; then
+  AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+  [LT_LANG(CXX)],
+  [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+  [LT_LANG(F77)],
+  [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+  [LT_LANG(FC)],
+  [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+  [LT_LANG(GCJ)],
+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+    [LT_LANG(GCJ)],
+    [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+      [LT_LANG(GCJ)],
+      [m4_ifdef([AC_PROG_GCJ],
+	[m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([A][M_PROG_GCJ],
+	[m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([LT_PROG_GCJ],
+	[m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+  [LT_LANG(GO)],
+  [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+  [LT_LANG(RC)],
+  [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+  case $host_os in
+    rhapsody* | darwin*)
+    AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+    AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+    AC_CHECK_TOOL([LIPO], [lipo], [:])
+    AC_CHECK_TOOL([OTOOL], [otool], [:])
+    AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+    _LT_DECL([], [DSYMUTIL], [1],
+      [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+    _LT_DECL([], [NMEDIT], [1],
+      [Tool to change global to local symbols on Mac OS X])
+    _LT_DECL([], [LIPO], [1],
+      [Tool to manipulate fat objects and archives on Mac OS X])
+    _LT_DECL([], [OTOOL], [1],
+      [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+    _LT_DECL([], [OTOOL64], [1],
+      [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+    AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+      [lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	# If there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi])
+
+    AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+      [lt_cv_ld_exported_symbols_list],
+      [lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+	[lt_cv_ld_exported_symbols_list=yes],
+	[lt_cv_ld_exported_symbols_list=no])
+	LDFLAGS="$save_LDFLAGS"
+    ])
+
+    AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+      [lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+      echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+      $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+      echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+      $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&AS_MESSAGE_LOG_FD
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&AS_MESSAGE_LOG_FD
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+    ])
+    case $host_os in
+    rhapsody* | darwin1.[[012]])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[[012]]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+  m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_automatic, $1)=yes
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+    m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+                  [FC],  [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+  else
+    _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+  fi
+  _LT_TAGVAR(link_all_deplibs, $1)=yes
+  _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=func_echo_all
+    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+    m4_if([$1], [CXX],
+[   if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+    fi
+],[])
+  else
+  _LT_TAGVAR(ld_shlibs, $1)=no
+  fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+  [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+  lt_aix_libpath_sed='[
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }]'
+  _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi],[])
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
+  fi
+  ])
+  aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*" 
+}
+
+case "$ECHO" in
+  printf*) AC_MSG_RESULT([printf]) ;;
+  print*) AC_MSG_RESULT([print -r]) ;;
+  *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+  test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test "X`printf %s $ECHO`" = "X$ECHO" \
+      || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[  --with-sysroot[=DIR] Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted.  We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   AC_MSG_RESULT([${with_sysroot}])
+   AC_MSG_ERROR([The sysroot must be an absolute path.])
+   ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and in which our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+  [AS_HELP_STRING([--disable-libtool-lock],
+    [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE="32"
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE="64"
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_i386"
+	    ;;
+	  ppc64-*linux*|powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  ppc*-*linux*|powerpc*-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_PUSH(C)
+     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_POP])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+  [lt_cv_ar_at_file=no
+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+     [echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([lt_ar_try])
+      if test "$ac_status" -eq 0; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	AC_TRY_EVAL([lt_ar_try])
+	if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+     ])
+  ])
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+  [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+    [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+    [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+    [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#		[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$3"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       $2=yes
+     fi
+   fi
+   $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+    m4_if([$5], , :, [$5])
+else
+    m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                  [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $3"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&AS_MESSAGE_LOG_FD
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         $2=yes
+       fi
+     else
+       $2=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+    m4_if([$4], , :, [$4])
+else
+    m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+  i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[	 ]]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+  AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+    [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                      ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+  [$4]
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}]
+_LT_EOF
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_dlunknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ])
+    ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+	  [lt_cv_dlopen="shl_load"],
+      [AC_CHECK_LIB([dld], [shl_load],
+	    [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+	[AC_CHECK_FUNC([dlopen],
+	      [lt_cv_dlopen="dlopen"],
+	  [AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+	    [AC_CHECK_LIB([svld], [dlopen],
+		  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+	      [AC_CHECK_LIB([dld], [dld_link],
+		    [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+	      ])
+	    ])
+	  ])
+	])
+      ])
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+	  lt_cv_dlopen_self, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+	  lt_cv_dlopen_self_static, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+	    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+	 [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+	 [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+	 [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+     fi
+   fi
+   chmod u+w . 2>&AS_MESSAGE_LOG_FD
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+	[Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+         [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+  [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+   test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+   test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+    # Linking always hardcodes the temporary library directory.
+    _LT_TAGVAR(hardcode_action, $1)=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    _LT_TAGVAR(hardcode_action, $1)=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+   test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+    [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      AC_MSG_RESULT([yes])
+    else
+      AC_MSG_RESULT([no])
+    fi
+    ;;
+  *)
+    AC_MSG_RESULT([no])
+    ;;
+  esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+	[], [
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+  if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[[4-9]]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[[45]]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+m4_if([$1], [],[
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[[23]].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2.*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+  freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[[3-9]]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux # correct to gnu/linux during the next big refactor
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+    [lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+	 LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+      [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+	 [lt_cv_shlibpath_overrides_runpath=yes])])
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+    ])
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux # correct to gnu/linux during the next big refactor
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+    [Variables whose values should be saved in libtool wrapper scripts and
+    restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+    [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0],  [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+    [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+    [[List of archive names.  First name is the real one, the rest are links.
+    The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+    [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+    [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+    [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+    [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+    [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+    [[As "finish_cmds", except a single script fragment to be evaled but
+    not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+    [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+    [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+    [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] |  ?:[\\/]*])
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="m4_if([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool at gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+	 [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+    [AS_HELP_STRING([--with-gnu-ld],
+	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test "$withval" = no || with_gnu_ld=yes],
+    [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by $CC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | ?:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+  lt_cv_ld_reload_flag,
+  [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[[45]]*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc*)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+haiku*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[[3-9]]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd* | netbsdelf*-gnu)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+    [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+    [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+    [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+    [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
+  AC_SUBST([DUMPBIN])
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+  [lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+  cat conftest.out >&AS_MESSAGE_LOG_FD
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+    [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+  [lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*])
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+  # These system don't have libm, or don't need it
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
+  ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+  case $cc_basename in
+  nvcc*)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+  esac
+
+  _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+    lt_cv_prog_compiler_rtti_exceptions,
+    [-fno-rtti -fno-exceptions], [],
+    [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+	[Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[[ABCDEGRST]]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[[BCDEGRST]]'
+  ;;
+osf*)
+  symcode='[[BCDEGQRST]]'
+  ;;
+solaris*)
+  symcode='[[BDRT]]'
+  ;;
+sco3.2v5*)
+  symcode='[[DT]]'
+  ;;
+sysv4.2uw2*)
+  symcode='[[DT]]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[[ABDT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK ['"\
+"     {last_section=section; section=\$ 3};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx]"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT@&t at _DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT@&t at _DLSYM_CONST
+#else
+# define LT@&t at _DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+LT@&t at _DLSYM_CONST struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_globsym_save_LIBS=$LIBS
+	  lt_globsym_save_CFLAGS=$CFLAGS
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+	  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS=$lt_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_save_CFLAGS
+	else
+	  echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+    fi
+  else
+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+    [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+    [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+    [lt_cv_sys_global_symbol_to_c_name_address], [1],
+    [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+    [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+    [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([], [nm_file_list_spec], [1],
+    [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | cygwin* | os2* | pw32* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)=
+      ;;
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix[[4-9]]*)
+	# All AIX code is PIC.
+	if test "$host_cpu" = ia64; then
+	  # AIX 5 now supports IA64 processor
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	else
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+      mingw* | cygwin* | os2* | pw32* | cegcc*)
+	# This hack is so that the source file can tell whether it is being
+	# built for inclusion in a dll (and should export symbols for example).
+	m4_if([$1], [GCJ], [],
+	  [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+	    # IBM XL 8.0, 9.0 on PPC and BlueGene
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd* | netbsdelf*-gnu)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+	;;
+    esac
+  fi
+],
+[
+  if test "$GCC" = yes; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)=
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+      if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+      fi
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      else
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC (with -KPIC) is the default.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        ;;
+      ccc*)
+        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        # All Alpha code is PIC.
+        _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+        ;;
+      xl* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  ;;
+        *Intel*\ [[CF]]*Compiler*)
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	  ;;
+	*Portland\ Group*)
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # All OSF/1 code is PIC.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    rdos*)
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    unicos*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+    esac
+  fi
+])
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+    ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t at m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+    ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+  _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+    [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+    [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t at m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+    [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+     "" | " "*) ;;
+     *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+     esac],
+    [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+     _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+	[Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+	[How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+  _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+  $lt_tmp_static_flag,
+  [],
+  [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+	[Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  case $host_os in
+  aix[[4-9]]*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+    ;;
+  cygwin* | mingw* | cegcc*)
+    case $cc_basename in
+    cl*)
+      _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+      ;;
+    *)
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+      ;;
+    esac
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+    ;;
+  *)
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+    ;;
+  esac
+], [
+  runpath_var=
+  _LT_TAGVAR(allow_undefined_flag, $1)=
+  _LT_TAGVAR(always_export_symbols, $1)=no
+  _LT_TAGVAR(archive_cmds, $1)=
+  _LT_TAGVAR(archive_expsym_cmds, $1)=
+  _LT_TAGVAR(compiler_needs_object, $1)=no
+  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+  _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(hardcode_automatic, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+  _LT_TAGVAR(hardcode_minus_L, $1)=no
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_TAGVAR(inherit_rpath, $1)=no
+  _LT_TAGVAR(link_all_deplibs, $1)=unknown
+  _LT_TAGVAR(module_cmds, $1)=
+  _LT_TAGVAR(module_expsym_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+  _LT_TAGVAR(thread_safe_flag_spec, $1)=
+  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  _LT_TAGVAR(include_expsyms, $1)=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+    ;;
+  esac
+
+  _LT_TAGVAR(ld_shlibs, $1)=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+	  *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[[3-9]]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+      # as there is no search path for DLLs.
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=no
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    haiku*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    interix[[3-9]]*)
+      _LT_TAGVAR(hardcode_direct, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=' $pic_flag'
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# Portland Group f77 and f90 compilers
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+	  tmp_sharedflag='--shared' ;;
+	xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf* | bgf* | bgxlf* | mpixlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        _LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+
+    if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+      runpath_var=
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	_LT_TAGVAR(hardcode_direct, $1)=unsupported
+      fi
+      ;;
+
+    aix[[4-9]]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      _LT_TAGVAR(archive_cmds, $1)=''
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[[012]]|aix4.[[012]].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+	_LT_TAGVAR(link_all_deplibs, $1)=no
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        _LT_SYS_MODULE_PATH_AIX([$1])
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	  _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 _LT_SYS_MODULE_PATH_AIX([$1])
+	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	  if test "$with_gnu_ld" = yes; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	  fi
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[[45]]*)
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	_LT_TAGVAR(always_export_symbols, $1)=yes
+	_LT_TAGVAR(file_list_spec, $1)='@'
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	_LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+	_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+	# The linker will automatically build a .lib file if we build a DLL.
+	_LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	# FIXME: Should let the user specify the lib program.
+	_LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+      _LT_DARWIN_LINKER_FEATURES($1)
+      ;;
+
+    dgux*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2.*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	_LT_TAGVAR(hardcode_minus_L, $1)=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	m4_if($1, [], [
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  _LT_LINKER_OPTION([if $CC understands -b],
+	    _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+	    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  ;;
+	*)
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+	# This should be the same for all languages, so no per-tag cache variable.
+	AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+	  [lt_cv_irix_exported_symbol],
+	  [save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+	   AC_LINK_IFELSE(
+	     [AC_LANG_SOURCE(
+	        [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+			      [C++], [[int foo (void) { return 0; }]],
+			      [Fortran 77], [[
+      subroutine foo
+      end]],
+			      [Fortran], [[
+      subroutine foo
+      end]])])],
+	      [lt_cv_irix_exported_symbol=yes],
+	      [lt_cv_irix_exported_symbol=no])
+           LDFLAGS="$save_LDFLAGS"])
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+	fi
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(inherit_rpath, $1)=yes
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+	     _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	     ;;
+	   *)
+	     _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    os2*)
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      case $host_os in
+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+        ;;
+	motorola)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4.3*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	_LT_TAGVAR(ld_shlibs, $1)=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      _LT_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+    [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+  # Assume -lc should be added
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $_LT_TAGVAR(archive_cmds, $1) in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+	[lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+	[$RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+	  pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+	  _LT_TAGVAR(allow_undefined_flag, $1)=
+	  if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+	  then
+	    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	  else
+	    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  fi
+	  _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+	])
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+    [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+    [enable_shared_with_static_runtimes], [0],
+    [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+    [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+    [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+    [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+    [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+    [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+    [Commands used to build a loadable module if different from building
+    a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+    [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+    [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+    [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+    [Flag to hardcode $libdir into a binary during linking.
+    This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+    [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+    DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+    DIR into the resulting binary and the resulting library dependency is
+    "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+    library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+    [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+    [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+    [Set to "yes" if building a shared library automatically hardcodes DIR
+    into the library and all subsequent libraries and executables linked
+    against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+    [Set to yes if linker adds runtime paths of dependent libraries
+    to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+    [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+    [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+    [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+    [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+    [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+    [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+    [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+    [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl    [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_SYS_DYNAMIC_LINKER($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+  LT_SYS_DLOPEN_SELF
+  _LT_CMD_STRIPLIB
+
+  # Report which library types will actually be built
+  AC_MSG_CHECKING([if libtool supports shared libraries])
+  AC_MSG_RESULT([$can_build_shared])
+
+  AC_MSG_CHECKING([whether to build shared libraries])
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[[4-9]]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  AC_MSG_RESULT([$enable_shared])
+
+  AC_MSG_CHECKING([whether to build static libraries])
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  AC_MSG_RESULT([$enable_static])
+
+  _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  AC_PROG_CXXCPP
+else
+  _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="int some_variable = 0;"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_CFLAGS=$CFLAGS
+  lt_save_LD=$LD
+  lt_save_GCC=$GCC
+  GCC=$GXX
+  lt_save_with_gnu_ld=$with_gnu_ld
+  lt_save_path_LD=$lt_cv_path_LD
+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+  else
+    $as_unset lt_cv_prog_gnu_ld
+  fi
+  if test -n "${lt_cv_path_LDCXX+set}"; then
+    lt_cv_path_LD=$lt_cv_path_LDCXX
+  else
+    $as_unset lt_cv_path_LD
+  fi
+  test -z "${LDCXX+set}" || LD=$LDCXX
+  CC=${CXX-"c++"}
+  CFLAGS=$CXXFLAGS
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    # We don't want -fno-exception when compiling C++ code, so set the
+    # no_builtin_flag separately
+    if test "$GXX" = yes; then
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+    else
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+      LT_PATH_LD
+
+      # Check if GNU C++ uses GNU ld as the underlying linker, since the
+      # archiving commands below assume that GNU ld is being used.
+      if test "$with_gnu_ld" = yes; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+        # If archive_cmds runs LD, not CC, wlarc should be empty
+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+        #     investigate it a little bit more. (MM)
+        wlarc='${wl}'
+
+        # ancient GNU ld didn't support --whole-archive et. al.
+        if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+	  $GREP 'no-whole-archive' > /dev/null; then
+          _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          _LT_TAGVAR(whole_archive_flag_spec, $1)=
+        fi
+      else
+        with_gnu_ld=no
+        wlarc=
+
+        # A generic and very simple default shared library creation
+        # command for GNU C++ for the case where it uses the native
+        # linker, instead of GNU ld.  If possible, this setting should
+        # overridden to take advantage of the native linker features on
+        # the platform it is being used on.
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      fi
+
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+    _LT_TAGVAR(ld_shlibs, $1)=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+      aix[[4-9]]*)
+        if test "$host_cpu" = ia64; then
+          # On IA64, the linker does run time linking by default, so we don't
+          # have to do anything special.
+          aix_use_runtimelinking=no
+          exp_sym_flag='-Bexport'
+          no_entry_flag=""
+        else
+          aix_use_runtimelinking=no
+
+          # Test if we are trying to use run time linking or normal
+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+          # need to do runtime linking.
+          case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	    for ld_flag in $LDFLAGS; do
+	      case $ld_flag in
+	      *-brtl*)
+	        aix_use_runtimelinking=yes
+	        break
+	        ;;
+	      esac
+	    done
+	    ;;
+          esac
+
+          exp_sym_flag='-bexport'
+          no_entry_flag='-bnoentry'
+        fi
+
+        # When large executables or shared objects are built, AIX ld can
+        # have problems creating the table of contents.  If linking a library
+        # or program results in "error TOC overflow" add -mminimal-toc to
+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+        _LT_TAGVAR(archive_cmds, $1)=''
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+        if test "$GXX" = yes; then
+          case $host_os in aix4.[[012]]|aix4.[[012]].*)
+          # We only want to do this on AIX 4.2 and lower, the check
+          # below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	    # We have reworked collect2
+	    :
+	  else
+	    # We have old collect2
+	    _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	    # It fails to find uninstalled libraries when the uninstalled
+	    # path is not listed in the libpath.  Setting hardcode_minus_L
+	    # to unsupported forces relinking
+	    _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+          esac
+          shared_flag='-shared'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
+	  fi
+        else
+          # not using gcc
+          if test "$host_cpu" = ia64; then
+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	  # chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+          else
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
+	    else
+	      shared_flag='${wl}-bM:SRE'
+	    fi
+          fi
+        fi
+
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+        # It seems that -bexpall does not export symbols beginning with
+        # underscore (_), so it is better to generate a list of symbols to
+	# export.
+        _LT_TAGVAR(always_export_symbols, $1)=yes
+        if test "$aix_use_runtimelinking" = yes; then
+          # Warning - without using the other runtime loading flags (-brtl),
+          # -berok will link without error, but may produce a broken library.
+          _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          _LT_SYS_MODULE_PATH_AIX([$1])
+          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	    _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+          else
+	    # Determine the default libpath from the value encoded in an
+	    # empty executable.
+	    _LT_SYS_MODULE_PATH_AIX([$1])
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	    # Warning - without using the other run time loading flags,
+	    # -berok will link without error, but may produce a broken library.
+	    _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	    _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
+	      # We only use this code for GNU lds that support --whole-archive.
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    else
+	      # Exported symbols can be pulled into shared objects from archives
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	    fi
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+          fi
+        fi
+        ;;
+
+      beos*)
+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+	case $GXX,$cc_basename in
+	,cl* | no,cl*)
+	  # Native MSVC
+	  # hardcode_libdir_flag_spec is actually meaningless, as there is
+	  # no search path for DLLs.
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  _LT_TAGVAR(always_export_symbols, $1)=yes
+	  _LT_TAGVAR(file_list_spec, $1)='@'
+	  # Tell ltmain to make .lib files, not .a files.
+	  libext=lib
+	  # Tell ltmain to make .dll files, not .so files.
+	  shrext_cmds=".dll"
+	  # FIXME: Setting linknames here is a bad hack.
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
+	  # The linker will not automatically build a static lib if we build a DLL.
+	  # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	  # Don't use ranlib
+	  _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+	  _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
+	  ;;
+	*)
+	  # g++
+	  # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+	  # as there is no search path for DLLs.
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  _LT_TAGVAR(always_export_symbols, $1)=no
+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file (1st line
+	    # is EXPORTS), use it as is; otherwise, prepend...
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      cp $export_symbols $output_objdir/$soname.def;
+	    else
+	      echo EXPORTS > $output_objdir/$soname.def;
+	      cat $export_symbols >> $output_objdir/$soname.def;
+	    fi~
+	    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	  ;;
+	esac
+	;;
+      darwin* | rhapsody*)
+        _LT_DARWIN_LINKER_FEATURES($1)
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      freebsd2.*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      freebsd-elf*)
+        _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+        ;;
+
+      gnu*)
+        ;;
+
+      haiku*)
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        ;;
+
+      hpux9*)
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+				             # but as the default
+				             # location of the library.
+
+        case $cc_basename in
+          CC*)
+            # FIXME: insert proper C++ library support
+            _LT_TAGVAR(ld_shlibs, $1)=no
+            ;;
+          aCC*)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            # Commands to make compiler produce verbose output that lists
+            # what "hidden" libraries, object files and flags are used when
+            # linking a shared library.
+            #
+            # There doesn't appear to be a way to prevent this compiler from
+            # explicitly linking system object files so we need to strip them
+            # from the output so that they don't get included in the library
+            # dependencies.
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            else
+              # FIXME: insert proper C++ library support
+              _LT_TAGVAR(ld_shlibs, $1)=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            _LT_TAGVAR(hardcode_direct, $1)=no
+            _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+            ;;
+          *)
+            _LT_TAGVAR(hardcode_direct, $1)=yes
+            _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+					         # but as the default
+					         # location of the library.
+            ;;
+        esac
+
+        case $cc_basename in
+          CC*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	    esac
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	        esac
+	      fi
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[[3-9]]*)
+	_LT_TAGVAR(hardcode_direct, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+	# Instead, shared libraries are loaded at an image base (0x10000000 by
+	# default) and relocated if they conflict, which is a slow very memory
+	# consuming and fragmenting process.  To avoid this, we pick a random,
+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	;;
+      irix5* | irix6*)
+        case $cc_basename in
+          CC*)
+	    # SGI C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+	      fi
+	    fi
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+	    ;;
+        esac
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(inherit_rpath, $1)=yes
+        ;;
+
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+	    ;;
+	  icpc* | ecpc* )
+	    # Intel C++
+	    with_gnu_ld=yes
+	    # version 8.0 and above of icpc choke on multiply defined symbols
+	    # if we add $predep_objects and $postdep_objects, however 7.1 and
+	    # earlier do not add the objects themselves.
+	    case `$CC -V 2>&1` in
+	      *"Version 7."*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	      *)  # Version 8.0 or newer
+	        tmp_idyn=
+	        case $host_cpu in
+		  ia64*) tmp_idyn=' -i_dynamic';;
+		esac
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+		$RANLIB $oldlib'
+	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 and above use weak symbols
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+	    runpath_var=LD_RUN_PATH
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    ;;
+	  xl* | mpixl* | bgxl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	    fi
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	      _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+	      # Not sure whether something based on
+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	      # would be better.
+	      output_verbose_link_cmd='func_echo_all'
+
+	      # Archives containing C++ object files must be created using
+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	      # necessary to make sure instantiated templates are included
+	      # in the archive.
+	      _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	fi
+	# Workaround some broken pre-1.5 toolchains
+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+	;;
+
+      *nto* | *qnx*)
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=func_echo_all
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      osf3* | osf4* | osf5*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+		;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	      # Commands to make compiler produce verbose output that lists
+	      # what "hidden" libraries, object files and flags are used when
+	      # linking a shared library.
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	    case $host_os in
+	      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+	      *)
+		# The compiler driver will combine and reorder linker options,
+		# but understands `-z linker_flag'.
+	        # Supported since Solaris 2.6 (maybe 2.5.1?)
+		_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+	    output_verbose_link_cmd='func_echo_all'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+	    # The C++ compiler must be used to create the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      fi
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+		*)
+		  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+      esac
+      ;;
+
+      sysv5* | sco3.2v5* | sco5v6*)
+	# Note: We can NOT use -z defs as we might desire, because we do not
+	# link with -lc, and that would cause any symbols used from libc to
+	# always be unresolved, which means just about no library would
+	# ever link correctly.  If we're not using GNU ld we use -z text
+	# though, which does catch some bad symbols but isn't as heavy-handed
+	# as -z defs.
+	_LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+	_LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+	_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+	_LT_TAGVAR(link_all_deplibs, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+	      '"$_LT_TAGVAR(old_archive_cmds, $1)"
+	    _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+	      '"$_LT_TAGVAR(reload_cmds, $1)"
+	    ;;
+	  *)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	esac
+      ;;
+
+      tandem*)
+        case $cc_basename in
+          NCC*)
+	    # NonStop-UX NCC 3.20
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+    esac
+
+    AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+    test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+    _LT_TAGVAR(GCC, $1)="$GXX"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+  LDCXX=$LD
+  LD=$lt_save_LD
+  GCC=$lt_save_GCC
+  with_gnu_ld=$lt_save_with_gnu_ld
+  lt_cv_path_LDCXX=$lt_cv_path_LD
+  lt_cv_path_LD=$lt_save_path_LD
+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+  esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library.  It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer*4 a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+  private int a;
+  public void bar (void) {
+    a = 0;
+  }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  for p in `eval "$output_verbose_link_cmd"`; do
+    case ${prev}${p} in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" ||
+          test $p = "-R"; then
+	 prev=$p
+	 continue
+       fi
+
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} in
+	 -L | -R)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+	   else
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+	   _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+	 else
+	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+	 fi
+       fi
+       prev=
+       ;;
+
+    *.lto.$objext) ;; # Ignore GCC LTO objects
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+	   _LT_TAGVAR(predep_objects, $1)="$p"
+	 else
+	   _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+	 fi
+       else
+	 if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+	   _LT_TAGVAR(postdep_objects, $1)="$p"
+	 else
+	   _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  _LT_TAGVAR(predep_objects,$1)=
+  _LT_TAGVAR(postdep_objects,$1)=
+  _LT_TAGVAR(postdeps,$1)=
+  ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+    [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+    [Dependencies to place before and after the objects being linked to
+    create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+    [The library search path used internally by the compiler when linking
+    a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test "X$F77" = "Xno"; then
+  _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  lt_save_CFLAGS=$CFLAGS
+  CC=${F77-"f77"}
+  CFLAGS=$FFLAGS
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+  GCC=$G77
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)="$G77"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC="$lt_save_CC"
+  CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test "X$FC" = "Xno"; then
+  _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  lt_save_CFLAGS=$CFLAGS
+  CC=${FC-"f95"}
+  CFLAGS=$FCFLAGS
+  compiler=$CC
+  GCC=$ac_cv_fc_compiler_gnu
+
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+  :
+  _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+  [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+    [AC_CHECK_TOOL(GCJ, gcj,)
+      test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+      AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+    [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && continue
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([	 ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
+
+
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+    # positional parameters, so assign one to ordinary parameter first.
+    func_stripname_result=${3}
+    func_stripname_result=${func_stripname_result#"${1}"}
+    func_stripname_result=${func_stripname_result%"${2}"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+    func_split_long_opt_name=${1%%=*}
+    func_split_long_opt_arg=${1#*=}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+    func_split_short_opt_arg=${1#??}
+    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+    case ${1} in
+      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+      *)    func_lo2o_result=${1} ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_xform], [    func_xform_result=${1%.*}.lo])
+
+  _LT_PROG_FUNCTION_REPLACE([func_arith], [    func_arith_result=$(( $[*] ))])
+
+  _LT_PROG_FUNCTION_REPLACE([func_len], [    func_len_result=${#1}])
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_append], [    eval "${1}+=\\${2}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+    func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+    eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine which file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path).  These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+         [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+         [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
diff --git a/ltmain.sh b/ltmain.sh
index 0bf3848..c7d06c3 100644
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -1,52 +1,90 @@
-# ltmain.sh - Provide generalized library-building support services.
-# NOTE: Changing this file will not affect anything until you rerun configure.
-#
+
+# libtool (GNU libtool) 2.4.2
+# Written by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
-# 2007, 2008  Free Software Foundation, Inc.
-# Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
-#
-# This program is free software; you can redistribute it and/or modify
+# 2007, 2008, 2009, 2010, 2011 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.
+
+# GNU Libtool 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
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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.
-
-basename="s,^.*/,,g"
-
-# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
-# is ksh but when the shell is invoked as "sh" and the current value of
-# the _XPG environment variable is not equal to 1 (one), the special
-# positional parameter $0, within a function call, is the name of the
-# function.
-progpath="$0"
-
-# The name of this program:
-progname=`echo "$progpath" | $SED $basename`
-modename="$progname"
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
-# Global variables:
-EXIT_SUCCESS=0
-EXIT_FAILURE=1
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+#       --config             show all configuration variables
+#       --debug              enable verbose shell tracing
+#   -n, --dry-run            display commands without modifying any files
+#       --features           display basic configuration information and exit
+#       --mode=MODE          use operation mode MODE
+#       --preserve-dup-deps  don't remove duplicate dependency libraries
+#       --quiet, --silent    don't print informational messages
+#       --no-quiet, --no-silent
+#                            print informational messages (default)
+#       --no-warn            don't display warning messages
+#       --tag=TAG            use configuration variables from tag TAG
+#   -v, --verbose            print more informational messages than default
+#       --no-verbose         don't print the extra informational messages
+#       --version            print version information
+#   -h, --help, --help-all   print short, long, or detailed help message
+#
+# MODE must be one of the following:
+#
+#         clean              remove files from the build directory
+#         compile            compile a source file into a libtool object
+#         execute            automatically set library path, then run a program
+#         finish             complete the installation of libtool libraries
+#         install            install libraries or executables
+#         link               create a library or an executable
+#         uninstall          remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE.  When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+#         host-triplet:	$host
+#         shell:		$SHELL
+#         compiler:		$LTCC
+#         compiler flags:		$LTCFLAGS
+#         linker:		$LD (gnu? $with_gnu_ld)
+#         $progname:	(GNU libtool) 2.4.2 Debian-2.4.2-1
+#         automake:	$automake_version
+#         autoconf:	$autoconf_version
+#
+# Report bugs to <bug-libtool at gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
 
-PROGRAM=ltmain.sh
+PROGRAM=libtool
 PACKAGE=libtool
-VERSION="1.5.26 Debian 1.5.26-4"
-TIMESTAMP=" (1.1220.2.493 2008/02/01 16:58:18)"
+VERSION="2.4.2 Debian-2.4.2-1"
+TIMESTAMP=""
+package_revision=1.3337
 
-# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).
+# Be Bourne compatible
 if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
   emulate sh
   NULLCMD=:
@@ -60,104 +98,457 @@ fi
 BIN_SH=xpg4; export BIN_SH # for Tru64
 DUALCASE=1; export DUALCASE # for MKS sh
 
-# Check that we have a working $echo.
-if test "X$1" = X--no-reexec; then
-  # Discard the --no-reexec flag, and continue.
-  shift
-elif test "X$1" = X--fallback-echo; then
-  # Avoid inline document here, it may be left over
-  :
-elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
-  # Yippee, $echo works!
-  :
-else
-  # Restart under the correct shell, and then maybe $echo will work.
-  exec $SHELL "$progpath" --no-reexec ${1+"$@"}
-fi
-
-if test "X$1" = X--fallback-echo; then
-  # used as fallback echo
-  shift
-  cat <<EOF
-$*
-EOF
-  exit $EXIT_SUCCESS
-fi
-
-default_mode=
-help="Try \`$progname --help' for more information."
-magic="%%%MAGIC variable%%%"
-mkdir="mkdir"
-mv="mv -f"
-rm="rm -f"
-
-# Sed substitution that helps us do robust quoting.  It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed="${SED}"' -e 1s/^X//'
-sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
-# test EBCDIC or ASCII
-case `echo X|tr X '\101'` in
- A) # ASCII based system
-    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
-  SP2NL='tr \040 \012'
-  NL2SP='tr \015\012 \040\040'
-  ;;
- *) # EBCDIC based system
-  SP2NL='tr \100 \n'
-  NL2SP='tr \r\n \100\100'
-  ;;
-esac
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
 
-# NLS nuisances.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-# We save the old values to restore during execute mode.
-lt_env=
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
 for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
 do
   eval "if test \"\${$lt_var+set}\" = set; then
-	  save_$lt_var=\$$lt_var
-	  lt_env=\"$lt_var=\$$lt_var \$lt_env\"
-	  $lt_var=C
+          save_$lt_var=\$$lt_var
+          $lt_var=C
 	  export $lt_var
+	  lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+	  lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
 	fi"
 done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
+
+$lt_unset CDPATH
 
-if test -n "$lt_env"; then
-  lt_env="env $lt_env"
-fi
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+
+
+: ${CP="cp -f"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
 
 # Make sure IFS has a sensible default
 lt_nl='
 '
 IFS=" 	$lt_nl"
 
-if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
-  $echo "$modename: not configured to build any kind of library" 1>&2
-  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
-  exit $EXIT_FAILURE
-fi
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
 
-# Global variables.
-mode=$default_mode
-nonopt=
-prev=
-prevopt=
-run=
-show="$echo"
-show_help=
-execute_dlfiles=
-duplicate_deps=no
-preserve_args=
-lo2o="s/\\.lo\$/.${objext}/"
-o2lo="s/\\.${objext}\$/.lo/"
-extracted_archives=
-extracted_serial=0
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+    func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+} # func_dirname may be replaced by extended shell implementation
+
+
+# func_basename file
+func_basename ()
+{
+    func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+    # Extract subdirectory from the argument.
+    func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+    func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+    case ${2} in
+      .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+      *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+    esac
+} # func_stripname may be replaced by extended shell implementation
+
+
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+		s@/\./@/@g
+		t dotsl
+		s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
+
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+#             value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+  # Start from root dir and reassemble the path.
+  func_normal_abspath_result=
+  func_normal_abspath_tpath=$1
+  func_normal_abspath_altnamespace=
+  case $func_normal_abspath_tpath in
+    "")
+      # Empty path, that just means $cwd.
+      func_stripname '' '/' "`pwd`"
+      func_normal_abspath_result=$func_stripname_result
+      return
+    ;;
+    # The next three entries are used to spot a run of precisely
+    # two leading slashes without using negated character classes;
+    # we take advantage of case's first-match behaviour.
+    ///*)
+      # Unusual form of absolute path, do nothing.
+    ;;
+    //*)
+      # Not necessarily an ordinary path; POSIX reserves leading '//'
+      # and for example Cygwin uses it to access remote file shares
+      # over CIFS/SMB, so we conserve a leading double slash if found.
+      func_normal_abspath_altnamespace=/
+    ;;
+    /*)
+      # Absolute path, do nothing.
+    ;;
+    *)
+      # Relative path, prepend $cwd.
+      func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+    ;;
+  esac
+  # Cancel out all the simple stuff to save iterations.  We also want
+  # the path to end with a slash for ease of parsing, so make sure
+  # there is one (and only one) here.
+  func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+  while :; do
+    # Processed it all yet?
+    if test "$func_normal_abspath_tpath" = / ; then
+      # If we ascended to the root using ".." the result may be empty now.
+      if test -z "$func_normal_abspath_result" ; then
+        func_normal_abspath_result=/
+      fi
+      break
+    fi
+    func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcar"`
+    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcdr"`
+    # Figure out what to do with it
+    case $func_normal_abspath_tcomponent in
+      "")
+        # Trailing empty path component, ignore it.
+      ;;
+      ..)
+        # Parent dir; strip last assembled component from result.
+        func_dirname "$func_normal_abspath_result"
+        func_normal_abspath_result=$func_dirname_result
+      ;;
+      *)
+        # Actual path component, append it.
+        func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+      ;;
+    esac
+  done
+  # Restore leading double-slash if one was found on entry.
+  func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+#             value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+  func_relative_path_result=
+  func_normal_abspath "$1"
+  func_relative_path_tlibdir=$func_normal_abspath_result
+  func_normal_abspath "$2"
+  func_relative_path_tbindir=$func_normal_abspath_result
+
+  # Ascend the tree starting from libdir
+  while :; do
+    # check if we have found a prefix of bindir
+    case $func_relative_path_tbindir in
+      $func_relative_path_tlibdir)
+        # found an exact match
+        func_relative_path_tcancelled=
+        break
+        ;;
+      $func_relative_path_tlibdir*)
+        # found a matching prefix
+        func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+        func_relative_path_tcancelled=$func_stripname_result
+        if test -z "$func_relative_path_result"; then
+          func_relative_path_result=.
+        fi
+        break
+        ;;
+      *)
+        func_dirname $func_relative_path_tlibdir
+        func_relative_path_tlibdir=${func_dirname_result}
+        if test "x$func_relative_path_tlibdir" = x ; then
+          # Have to descend all the way to the root!
+          func_relative_path_result=../$func_relative_path_result
+          func_relative_path_tcancelled=$func_relative_path_tbindir
+          break
+        fi
+        func_relative_path_result=../$func_relative_path_result
+        ;;
+    esac
+  done
+
+  # Now calculate path; take care to avoid doubling-up slashes.
+  func_stripname '' '/' "$func_relative_path_result"
+  func_relative_path_result=$func_stripname_result
+  func_stripname '/' '/' "$func_relative_path_tcancelled"
+  if test "x$func_stripname_result" != x ; then
+    func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+  fi
+
+  # Normalisation. If bindir is libdir, return empty string,
+  # else relative path ending with a slash; either way, target
+  # file name can be directly appended.
+  if test ! -z "$func_relative_path_result"; then
+    func_stripname './' '' "$func_relative_path_result/"
+    func_relative_path_result=$func_stripname_result
+  fi
+}
+
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+  [\\/]*|[A-Za-z]:\\*) ;;
+  *[\\/]*)
+     progdir=$func_dirname_result
+     progdir=`cd "$progdir" && pwd`
+     progpath="$progdir/$progname"
+     ;;
+  *)
+     save_IFS="$IFS"
+     IFS=${PATH_SEPARATOR-:}
+     for progdir in $PATH; do
+       IFS="$save_IFS"
+       test -x "$progdir/$progname" && break
+     done
+     IFS="$save_IFS"
+     test -n "$progdir" || progdir=`pwd`
+     progpath="$progdir/$progname"
+     ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes.  A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same.  If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'.  `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+  s/$bs4/&\\
+/g
+  s/^$bs2$dollar/$bs&/
+  s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+  s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+    $opt_verbose && func_echo ${1+"$@"}
+
+    # A bug in bash halts the script if the last line of a function
+    # fails when set -e is in force, so we need another command to
+    # work around that:
+    :
+}
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+    $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
+
+    # bash bug again:
+    :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+    func_error ${1+"$@"}
+    exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+    func_error ${1+"$@"}
+    func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information."  ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+    $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+    my_directory_path="$1"
+    my_dir_list=
+
+    if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+      # Protect directory names starting with `-'
+      case $my_directory_path in
+        -*) my_directory_path="./$my_directory_path" ;;
+      esac
+
+      # While some portion of DIR does not yet exist...
+      while test ! -d "$my_directory_path"; do
+        # ...make a list in topmost first order.  Use a colon delimited
+	# list incase some portion of path contains whitespace.
+        my_dir_list="$my_directory_path:$my_dir_list"
+
+        # If the last portion added has no slash in it, the list is done
+        case $my_directory_path in */*) ;; *) break ;; esac
+
+        # ...otherwise throw away the child directory and loop
+        my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
+      done
+      my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
+
+      save_mkdir_p_IFS="$IFS"; IFS=':'
+      for my_dir in $my_dir_list; do
+	IFS="$save_mkdir_p_IFS"
+        # mkdir can fail with a `File exist' error if two processes
+        # try to create one of the directories concurrently.  Don't
+        # stop in that case!
+        $MKDIR "$my_dir" 2>/dev/null || :
+      done
+      IFS="$save_mkdir_p_IFS"
+
+      # Bail out if we (or some other process) failed to create a directory.
+      test -d "$my_directory_path" || \
+        func_fatal_error "Failed to create \`$1'"
+    fi
+}
 
-#####################################
-# Shell function definitions:
-# This seems to be the best place for them
 
 # func_mktempdir [string]
 # Make a temporary directory that won't clash with other running
@@ -167,7 +558,7 @@ func_mktempdir ()
 {
     my_template="${TMPDIR-/tmp}/${1-$progname}"
 
-    if test "$run" = ":"; then
+    if test "$opt_dry_run" = ":"; then
       # Return a directory name, but don't create it in dry-run mode
       my_tmpdir="${my_template}-$$"
     else
@@ -176,6366 +567,8888 @@ func_mktempdir ()
       my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
 
       if test ! -d "$my_tmpdir"; then
-	# Failing that, at least try and use $RANDOM to avoid a race
-	my_tmpdir="${my_template}-${RANDOM-0}$$"
+        # Failing that, at least try and use $RANDOM to avoid a race
+        my_tmpdir="${my_template}-${RANDOM-0}$$"
 
-	save_mktempdir_umask=`umask`
-	umask 0077
-	$mkdir "$my_tmpdir"
-	umask $save_mktempdir_umask
+        save_mktempdir_umask=`umask`
+        umask 0077
+        $MKDIR "$my_tmpdir"
+        umask $save_mktempdir_umask
       fi
 
       # If we're not in dry-run mode, bomb out on failure
-      test -d "$my_tmpdir" || {
-        $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2
-	exit $EXIT_FAILURE
-      }
+      test -d "$my_tmpdir" || \
+        func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
     fi
 
-    $echo "X$my_tmpdir" | $Xsed
+    $ECHO "$my_tmpdir"
 }
 
 
-# func_win32_libid arg
-# return the library type of file 'arg'
-#
-# Need a lot of goo to handle *both* DLLs and import libs
-# Has to be a shell function in order to 'eat' the argument
-# that is supplied when $file_magic_command is called.
-func_win32_libid ()
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
 {
-  win32_libid_type="unknown"
-  win32_fileres=`file -L $1 2>/dev/null`
-  case $win32_fileres in
-  *ar\ archive\ import\ library*) # definitely import
-    win32_libid_type="x86 archive import"
-    ;;
-  *ar\ archive*) # could be an import, or static
-    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
-      $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
-      win32_nmres=`eval $NM -f posix -A $1 | \
-	$SED -n -e '1,100{
-		/ I /{
-			s,.*,import,
-			p
-			q
-			}
-		}'`
-      case $win32_nmres in
-      import*)  win32_libid_type="x86 archive import";;
-      *)        win32_libid_type="x86 archive static";;
-      esac
+    case $1 in
+      *[\\\`\"\$]*)
+	func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+      *)
+        func_quote_for_eval_unquoted_result="$1" ;;
+    esac
+
+    case $func_quote_for_eval_unquoted_result in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and and variable
+      # expansion for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+        ;;
+      *)
+        func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+    esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+    case $1 in
+      *[\\\`\"]*)
+	my_arg=`$ECHO "$1" | $SED \
+	    -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+      *)
+        my_arg="$1" ;;
+    esac
+
+    case $my_arg in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting and command substitution for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        my_arg="\"$my_arg\""
+        ;;
+    esac
+
+    func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$my_cmd"
+      my_status=$?
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
     fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.  Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$lt_user_locale
+	    $my_cmd"
+      my_status=$?
+      eval "$lt_safe_locale"
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result.  All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+  case $1 in
+  [0-9]* | *[!a-zA-Z0-9_]*)
+    func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
     ;;
-  *DLL*)
-    win32_libid_type="x86 DLL"
-    ;;
-  *executable*) # but shell scripts are "executable" too...
-    case $win32_fileres in
-    *MS\ Windows\ PE\ Intel*)
-      win32_libid_type="x86 DLL"
-      ;;
-    esac
+  * )
+    func_tr_sh_result=$1
     ;;
   esac
-  $echo $win32_libid_type
 }
 
 
-# func_infer_tag arg
-# Infer tagged configuration to use if any are available and
-# if one wasn't chosen via the "--tag" command line option.
-# Only attempt this if the compiler in the base compile
-# command doesn't match the default compiler.
-# arg is usually of the form 'gcc ...'
-func_infer_tag ()
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
 {
-    if test -n "$available_tags" && test -z "$tagname"; then
-      CC_quoted=
-      for arg in $CC; do
-	case $arg in
-	  *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	  arg="\"$arg\""
-	  ;;
-	esac
-	CC_quoted="$CC_quoted $arg"
-      done
-      case $@ in
-      # Blanks in the command may have been stripped by the calling shell,
-      # but not from the CC environment variable when configure was run.
-      " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;;
-      # Blanks at the start of $base_compile will cause this to fail
-      # if we don't check for them as well.
-      *)
-	for z in $available_tags; do
-	  if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
-	    # Evaluate the configuration.
-	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
-	    CC_quoted=
-	    for arg in $CC; do
-	    # Double-quote args containing other shell metacharacters.
-	    case $arg in
-	      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	      arg="\"$arg\""
-	      ;;
-	    esac
-	    CC_quoted="$CC_quoted $arg"
-	  done
-	    case "$@ " in
-	      " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*)
-	      # The compiler in the base compile command matches
-	      # the one in the tagged configuration.
-	      # Assume this is the tagged configuration we want.
-	      tagname=$z
-	      break
-	      ;;
-	    esac
-	  fi
-	done
-	# If $tagname still isn't set, then no tagged configuration
-	# was found and let the user know that the "--tag" command
-	# line option must be used.
-	if test -z "$tagname"; then
-	  $echo "$modename: unable to infer tagged configuration"
-	  $echo "$modename: specify a tag with \`--tag'" 1>&2
-	  exit $EXIT_FAILURE
-#        else
-#          $echo "$modename: using $tagname tagged configuration"
-	fi
-	;;
-      esac
-    fi
+    $opt_debug
+
+    $SED -n '/(C)/!b go
+	:more
+	/\./!{
+	  N
+	  s/\n# / /
+	  b more
+	}
+	:go
+	/^# '$PROGRAM' (GNU /,/# warranty; / {
+        s/^# //
+	s/^# *$//
+        s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+        p
+     }' < "$progpath"
+     exit $?
 }
 
-
-# func_extract_an_archive dir oldlib
-func_extract_an_archive ()
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
 {
-    f_ex_an_ar_dir="$1"; shift
-    f_ex_an_ar_oldlib="$1"
-
-    $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)"
-    $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $?
-    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
-     :
-    else
-      $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2
-      exit $EXIT_FAILURE
-    fi
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/^#  *.*--help/ {
+        s/^# //
+	s/^# *$//
+	s/\$progname/'$progname'/
+	p
+    }' < "$progpath"
+    echo
+    $ECHO "run \`$progname --help | more' for full usage"
+    exit $?
 }
 
-# func_extract_archives gentop oldlib ...
-func_extract_archives ()
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
+func_help ()
 {
-    my_gentop="$1"; shift
-    my_oldlibs=${1+"$@"}
-    my_oldobjs=""
-    my_xlib=""
-    my_xabs=""
-    my_xdir=""
-    my_status=""
-
-    $show "${rm}r $my_gentop"
-    $run ${rm}r "$my_gentop"
-    $show "$mkdir $my_gentop"
-    $run $mkdir "$my_gentop"
-    my_status=$?
-    if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then
-      exit $my_status
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/# Report bugs to/ {
+	:print
+        s/^# //
+	s/^# *$//
+	s*\$progname*'$progname'*
+	s*\$host*'"$host"'*
+	s*\$SHELL*'"$SHELL"'*
+	s*\$LTCC*'"$LTCC"'*
+	s*\$LTCFLAGS*'"$LTCFLAGS"'*
+	s*\$LD*'"$LD"'*
+	s/\$with_gnu_ld/'"$with_gnu_ld"'/
+	s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+	s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
+	p
+	d
+     }
+     /^# .* home page:/b print
+     /^# General help using/b print
+     ' < "$progpath"
+    ret=$?
+    if test -z "$1"; then
+      exit $ret
     fi
+}
 
-    for my_xlib in $my_oldlibs; do
-      # Extract the objects.
-      case $my_xlib in
-	[\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
-	*) my_xabs=`pwd`"/$my_xlib" ;;
-      esac
-      my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'`
-      my_xlib_u=$my_xlib
-      while :; do
-        case " $extracted_archives " in
-	*" $my_xlib_u "*)
-	  extracted_serial=`expr $extracted_serial + 1`
-	  my_xlib_u=lt$extracted_serial-$my_xlib ;;
-	*) break ;;
-	esac
-      done
-      extracted_archives="$extracted_archives $my_xlib_u"
-      my_xdir="$my_gentop/$my_xlib_u"
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+    $opt_debug
 
-      $show "${rm}r $my_xdir"
-      $run ${rm}r "$my_xdir"
-      $show "$mkdir $my_xdir"
-      $run $mkdir "$my_xdir"
-      exit_status=$?
-      if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then
-	exit $exit_status
-      fi
-      case $host in
-      *-darwin*)
-	$show "Extracting $my_xabs"
-	# Do not bother doing anything if just a dry run
-	if test -z "$run"; then
-	  darwin_orig_dir=`pwd`
-	  cd $my_xdir || exit $?
-	  darwin_archive=$my_xabs
-	  darwin_curdir=`pwd`
-	  darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'`
-	  darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null`
-	  if test -n "$darwin_arches"; then 
-	    darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'`
-	    darwin_arch=
-	    $show "$darwin_base_archive has multiple architectures $darwin_arches"
-	    for darwin_arch in  $darwin_arches ; do
-	      mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
-	      lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
-	      cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
-	      func_extract_an_archive "`pwd`" "${darwin_base_archive}"
-	      cd "$darwin_curdir"
-	      $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
-	    done # $darwin_arches
-      ## Okay now we have a bunch of thin objects, gotta fatten them up :)
-	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP`
-	    darwin_file=
-	    darwin_files=
-	    for darwin_file in $darwin_filelist; do
-	      darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
-	      lipo -create -output "$darwin_file" $darwin_files
-	    done # $darwin_filelist
-	    ${rm}r unfat-$$
-	    cd "$darwin_orig_dir"
-	  else
-	    cd "$darwin_orig_dir"
- 	    func_extract_an_archive "$my_xdir" "$my_xabs"
-	  fi # $darwin_arches
-	fi # $run
-	;;
-      *)
-        func_extract_an_archive "$my_xdir" "$my_xabs"
-        ;;
-      esac
-      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
-    done
-    func_extract_archives_result="$my_oldobjs"
+    func_error "missing argument for $1."
+    exit_cmd=exit
 }
-# End of Shell function definitions
-#####################################
 
-# Darwin sucks
-eval std_shrext=\"$shrext_cmds\"
 
-disable_libs=no
+# func_split_short_opt shortopt
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+func_split_short_opt ()
+{
+    my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+    my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
+
+    func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+    func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
 
-# Parse our command line options once, thoroughly.
-while test "$#" -gt 0
-do
-  arg="$1"
-  shift
 
-  case $arg in
-  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
-  *) optarg= ;;
-  esac
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
+{
+    my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+    my_sed_long_arg='1s/^--[^=]*=//'
 
-  # If the previous option needs an argument, assign it.
-  if test -n "$prev"; then
-    case $prev in
-    execute_dlfiles)
-      execute_dlfiles="$execute_dlfiles $arg"
-      ;;
-    tag)
-      tagname="$arg"
-      preserve_args="${preserve_args}=$arg"
-
-      # Check whether tagname contains only valid characters
-      case $tagname in
-      *[!-_A-Za-z0-9,/]*)
-	$echo "$progname: invalid tag name: $tagname" 1>&2
-	exit $EXIT_FAILURE
-	;;
-      esac
+    func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+    func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
 
-      case $tagname in
-      CC)
-	# Don't test for the "default" C tag, as we know, it's there, but
-	# not specially marked.
-	;;
-      *)
-	if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then
-	  taglist="$taglist $tagname"
-	  # Evaluate the configuration.
-	  eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`"
-	else
-	  $echo "$progname: ignoring unknown tag $tagname" 1>&2
-	fi
-	;;
-      esac
-      ;;
-    *)
-      eval "$prev=\$arg"
-      ;;
-    esac
+exit_cmd=:
 
-    prev=
-    prevopt=
-    continue
-  fi
 
-  # Have we seen a non-optional argument yet?
-  case $arg in
-  --help)
-    show_help=yes
-    ;;
 
-  --version)
-    echo "\
-$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP
 
-Copyright (C) 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."
-    exit $?
-    ;;
 
-  --config)
-    ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+    eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
+
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
+{
+    func_quote_for_eval "${2}"
+    eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
+
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+    func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
+
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+    func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
+
+
+# func_lo2o object
+func_lo2o ()
+{
+    func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
+
+
+# func_xform libobj-or-source
+func_xform ()
+{
+    func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
+
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+    func_error ${1+"$@"}
+    func_error "See the $PACKAGE documentation for more information."
+    func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+    re_begincf='^# ### BEGIN LIBTOOL'
+    re_endcf='^# ### END LIBTOOL'
+
+    # Default configuration.
+    $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
     # Now print the configurations for the tags.
     for tagname in $taglist; do
-      ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath"
+      $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
     done
-    exit $?
-    ;;
-
-  --debug)
-    $echo "$progname: enabling shell trace mode"
-    set -x
-    preserve_args="$preserve_args $arg"
-    ;;
 
-  --dry-run | -n)
-    run=:
-    ;;
+    exit $?
+}
 
-  --features)
-    $echo "host: $host"
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+    echo "host: $host"
     if test "$build_libtool_libs" = yes; then
-      $echo "enable shared libraries"
+      echo "enable shared libraries"
     else
-      $echo "disable shared libraries"
+      echo "disable shared libraries"
     fi
     if test "$build_old_libs" = yes; then
-      $echo "enable static libraries"
+      echo "enable static libraries"
     else
-      $echo "disable static libraries"
+      echo "disable static libraries"
     fi
-    exit $?
-    ;;
-
-  --finish) mode="finish" ;;
 
-  --mode) prevopt="--mode" prev=mode ;;
-  --mode=*) mode="$optarg" ;;
+    exit $?
+}
 
-  --preserve-dup-deps) duplicate_deps="yes" ;;
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+  # Global variable:
+  tagname="$1"
 
-  --quiet | --silent)
-    show=:
-    preserve_args="$preserve_args $arg"
-    ;;
+  re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+  re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+  sed_extractcf="/$re_begincf/,/$re_endcf/p"
 
-  --tag)
-    prevopt="--tag"
-    prev=tag
-    preserve_args="$preserve_args --tag"
-    ;;
-  --tag=*)
-    set tag "$optarg" ${1+"$@"}
-    shift
-    prev=tag
-    preserve_args="$preserve_args --tag"
-    ;;
+  # Validate tagname.
+  case $tagname in
+    *[!-_A-Za-z0-9,/]*)
+      func_fatal_error "invalid tag name: $tagname"
+      ;;
+  esac
 
-  -dlopen)
-    prevopt="-dlopen"
-    prev=execute_dlfiles
-    ;;
+  # Don't test for the "default" C tag, as we know it's
+  # there but not specially marked.
+  case $tagname in
+    CC) ;;
+    *)
+      if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+	taglist="$taglist $tagname"
+
+	# Evaluate the configuration.  Be careful to quote the path
+	# and the sed script, to avoid splitting on whitespace, but
+	# also don't use non-portable quotes within backquotes within
+	# quotes we have to do it in 2 steps:
+	extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+	eval "$extractedcf"
+      else
+	func_error "ignoring unknown tag $tagname"
+      fi
+      ;;
+  esac
+}
 
-  -*)
-    $echo "$modename: unrecognized option \`$arg'" 1>&2
-    $echo "$help" 1>&2
-    exit $EXIT_FAILURE
-    ;;
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+  if test "$package_revision" != "$macro_revision"; then
+    if test "$VERSION" != "$macro_version"; then
+      if test -z "$macro_version"; then
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      else
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      fi
+    else
+      cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+    fi
 
-  *)
-    nonopt="$arg"
-    break
-    ;;
-  esac
-done
+    exit $EXIT_MISMATCH
+  fi
+}
 
-if test -n "$prevopt"; then
-  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
-  $echo "$help" 1>&2
-  exit $EXIT_FAILURE
-fi
 
-case $disable_libs in
-no) 
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+  shift; set dummy --mode clean ${1+"$@"}; shift
+  ;;
+compile|compil|compi|comp|com|co|c)
+  shift; set dummy --mode compile ${1+"$@"}; shift
+  ;;
+execute|execut|execu|exec|exe|ex|e)
+  shift; set dummy --mode execute ${1+"$@"}; shift
+  ;;
+finish|finis|fini|fin|fi|f)
+  shift; set dummy --mode finish ${1+"$@"}; shift
   ;;
-shared)
-  build_libtool_libs=no
-  build_old_libs=yes
+install|instal|insta|inst|ins|in|i)
+  shift; set dummy --mode install ${1+"$@"}; shift
   ;;
-static)
-  build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+link|lin|li|l)
+  shift; set dummy --mode link ${1+"$@"}; shift
+  ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+  shift; set dummy --mode uninstall ${1+"$@"}; shift
   ;;
 esac
 
-# If this variable is set in any of the actions, the command in it
-# will be execed at the end.  This prevents here-documents from being
-# left over by shells.
-exec_cmd=
 
-if test -z "$show_help"; then
 
-  # Infer the operation mode.
-  if test -z "$mode"; then
-    $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2
-    $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2
-    case $nonopt in
-    *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*)
-      mode=link
-      for arg
-      do
-	case $arg in
-	-c)
-	   mode=compile
-	   break
-	   ;;
-	esac
-      done
-      ;;
-    *db | *dbx | *strace | *truss)
-      mode=execute
-      ;;
-    *install*|cp|mv)
-      mode=install
-      ;;
-    *rm)
-      mode=uninstall
-      ;;
-    *)
-      # If we have no mode, but dlfiles were specified, then do execute mode.
-      test -n "$execute_dlfiles" && mode=execute
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
 
-      # Just use the default operation mode.
-      if test -z "$mode"; then
-	if test -n "$nonopt"; then
-	  $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
-	else
-	  $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
-	fi
-      fi
-      ;;
+
+# Parse options once, thoroughly.  This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
+{
+  # this just eases exit handling
+  while test $# -gt 0; do
+    opt="$1"
+    shift
+    case $opt in
+      --debug|-x)	opt_debug='set -x'
+			func_echo "enabling shell trace mode"
+			$opt_debug
+			;;
+      --dry-run|--dryrun|-n)
+			opt_dry_run=:
+			;;
+      --config)
+			opt_config=:
+func_config
+			;;
+      --dlopen|-dlopen)
+			optarg="$1"
+			opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+			shift
+			;;
+      --preserve-dup-deps)
+			opt_preserve_dup_deps=:
+			;;
+      --features)
+			opt_features=:
+func_features
+			;;
+      --finish)
+			opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+			;;
+      --help)
+			opt_help=:
+			;;
+      --help-all)
+			opt_help_all=:
+opt_help=': help-all'
+			;;
+      --mode)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_mode="$optarg"
+case $optarg in
+  # Valid mode arguments:
+  clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+  # Catch anything else as an error
+  *) func_error "invalid argument for $opt"
+     exit_cmd=exit
+     break
+     ;;
+esac
+			shift
+			;;
+      --no-silent|--no-quiet)
+			opt_silent=false
+func_append preserve_args " $opt"
+			;;
+      --no-warning|--no-warn)
+			opt_warning=false
+func_append preserve_args " $opt"
+			;;
+      --no-verbose)
+			opt_verbose=false
+func_append preserve_args " $opt"
+			;;
+      --silent|--quiet)
+			opt_silent=:
+func_append preserve_args " $opt"
+        opt_verbose=false
+			;;
+      --verbose|-v)
+			opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+			;;
+      --tag)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+			shift
+			;;
+
+      -\?|-h)		func_usage				;;
+      --help)		func_help				;;
+      --version)	func_version				;;
+
+      # Separate optargs to long options:
+      --*=*)
+			func_split_long_opt "$opt"
+			set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      # Separate non-argument short options:
+      -\?*|-h*|-n*|-v*)
+			func_split_short_opt "$opt"
+			set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      --)		break					;;
+      -*)		func_fatal_help "unrecognized option \`$opt'" ;;
+      *)		set dummy "$opt" ${1+"$@"};	shift; break  ;;
     esac
-  fi
+  done
 
-  # Only execute mode is allowed to have -dlopen flags.
-  if test -n "$execute_dlfiles" && test "$mode" != execute; then
-    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
-    $echo "$help" 1>&2
-    exit $EXIT_FAILURE
+  # Validate options:
+
+  # save first non-option argument
+  if test "$#" -gt 0; then
+    nonopt="$opt"
+    shift
   fi
 
-  # Change the help message to a mode-specific one.
-  generic_help="$help"
-  help="Try \`$modename --help --mode=$mode' for more information."
+  # preserve --debug
+  test "$opt_debug" = : || func_append preserve_args " --debug"
 
-  # These modes are in order of execution frequency so that they run quickly.
-  case $mode in
-  # libtool compile mode
-  compile)
-    modename="$modename: compile"
-    # Get the compilation command and the source file.
-    base_compile=
-    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
-    suppress_opt=yes
-    suppress_output=
-    arg_mode=normal
-    libobj=
-    later=
-
-    for arg
-    do
-      case $arg_mode in
-      arg  )
-	# do not "continue".  Instead, add this to base_compile
-	lastarg="$arg"
-	arg_mode=normal
-	;;
-
-      target )
-	libobj="$arg"
-	arg_mode=normal
-	continue
-	;;
+  case $host in
+    *cygwin* | *mingw* | *pw32* | *cegcc*)
+      # don't eliminate duplications in $postdeps and $predeps
+      opt_duplicate_compiler_generated_deps=:
+      ;;
+    *)
+      opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+      ;;
+  esac
 
-      normal )
-	# Accept any command-line options.
-	case $arg in
-	-o)
-	  if test -n "$libobj" ; then
-	    $echo "$modename: you cannot specify \`-o' more than once" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-	  arg_mode=target
-	  continue
-	  ;;
+  $opt_help || {
+    # Sanity checks first:
+    func_check_version_match
 
-	-static | -prefer-pic | -prefer-non-pic)
-	  later="$later $arg"
-	  continue
-	  ;;
+    if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+      func_fatal_configuration "not configured to build any kind of library"
+    fi
 
-	-no-suppress)
-	  suppress_opt=no
-	  continue
-	  ;;
+    # Darwin sucks
+    eval std_shrext=\"$shrext_cmds\"
 
-	-Xcompiler)
-	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
-	  continue      #  The current "srcfile" will either be retained or
-	  ;;            #  replaced later.  I would guess that would be a bug.
+    # Only execute mode is allowed to have -dlopen flags.
+    if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+      func_error "unrecognized option \`-dlopen'"
+      $ECHO "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
 
-	-Wc,*)
-	  args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
-	  lastarg=
-	  save_ifs="$IFS"; IFS=','
- 	  for arg in $args; do
-	    IFS="$save_ifs"
+    # Change the help message to a mode-specific one.
+    generic_help="$help"
+    help="Try \`$progname --help --mode=$opt_mode' for more information."
+  }
 
-	    # Double-quote args containing other shell metacharacters.
-	    # Many Bourne shells cannot handle close brackets correctly
-	    # in scan sets, so we specify it separately.
-	    case $arg in
-	      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	      arg="\"$arg\""
-	      ;;
-	    esac
-	    lastarg="$lastarg $arg"
-	  done
-	  IFS="$save_ifs"
-	  lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
 
-	  # Add the arguments to base_compile.
-	  base_compile="$base_compile $lastarg"
-	  continue
-	  ;;
+  # Bail if the options were screwed
+  $exit_cmd $EXIT_FAILURE
+}
 
-	* )
-	  # Accept the current argument as the source file.
-	  # The previous "srcfile" becomes the current argument.
-	  #
-	  lastarg="$srcfile"
-	  srcfile="$arg"
-	  ;;
-	esac  #  case $arg
-	;;
-      esac    #  case $arg_mode
 
-      # Aesthetically quote the previous argument.
-      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
 
-      case $lastarg in
-      # Double-quote args containing other shell metacharacters.
-      # Many Bourne shells cannot handle close brackets correctly
-      # in scan sets, and some SunOS ksh mistreat backslash-escaping
-      # in scan sets (worked around with variable expansion),
-      # and furthermore cannot handle '|' '&' '(' ')' in scan sets 
-      # at all, so we specify them separately.
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	lastarg="\"$lastarg\""
-	;;
-      esac
 
-      base_compile="$base_compile $lastarg"
-    done # for arg
+## ----------- ##
+##    Main.    ##
+## ----------- ##
 
-    case $arg_mode in
-    arg)
-      $echo "$modename: you must specify an argument for -Xcompile"
-      exit $EXIT_FAILURE
-      ;;
-    target)
-      $echo "$modename: you must specify a target with \`-o'" 1>&2
-      exit $EXIT_FAILURE
-      ;;
-    *)
-      # Get the name of the library object.
-      [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
-      ;;
-    esac
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+    test -f "$1" &&
+      $SED -e 4q "$1" 2>/dev/null \
+        | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
 
-    # Recognize several different file suffixes.
-    # If the user specifies -o file.o, it is replaced with file.lo
-    xform='[cCFSifmso]'
-    case $libobj in
-    *.ada) xform=ada ;;
-    *.adb) xform=adb ;;
-    *.ads) xform=ads ;;
-    *.asm) xform=asm ;;
-    *.c++) xform=c++ ;;
-    *.cc) xform=cc ;;
-    *.ii) xform=ii ;;
-    *.class) xform=class ;;
-    *.cpp) xform=cpp ;;
-    *.cxx) xform=cxx ;;
-    *.[fF][09]?) xform=[fF][09]. ;;
-    *.for) xform=for ;;
-    *.java) xform=java ;;
-    *.obj) xform=obj ;;
-    *.sx) xform=sx ;;
-    esac
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs.  To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway.  Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+    lalib_p=no
+    if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+	for lalib_p_l in 1 2 3 4
+	do
+	    read lalib_p_line
+	    case "$lalib_p_line" in
+		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+	    esac
+	done
+	exec 0<&5 5<&-
+    fi
+    test "$lalib_p" = yes
+}
 
-    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+    func_lalib_p "$1"
+}
 
-    case $libobj in
-    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
-    *)
-      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
-      exit $EXIT_FAILURE
-      ;;
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+    func_ltwrapper_exec_suffix=
+    case $1 in
+    *.exe) ;;
+    *) func_ltwrapper_exec_suffix=.exe ;;
     esac
+    $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
 
-    func_infer_tag $base_compile
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+    func_dirname_and_basename "$1" "" "."
+    func_stripname '' '.exe' "$func_basename_result"
+    func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+}
 
-    for arg in $later; do
-      case $arg in
-      -static)
-	build_old_libs=yes
-	continue
-	;;
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+    func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
 
-      -prefer-pic)
-	pic_mode=yes
-	continue
-	;;
 
-      -prefer-non-pic)
-	pic_mode=no
-	continue
-	;;
-      esac
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+    $opt_debug
+    save_ifs=$IFS; IFS='~'
+    for cmd in $1; do
+      IFS=$save_ifs
+      eval cmd=\"$cmd\"
+      func_show_eval "$cmd" "${2-:}"
     done
+    IFS=$save_ifs
+}
 
-    qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"`
-    case $qlibobj in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	qlibobj="\"$qlibobj\"" ;;
-    esac
-    test "X$libobj" != "X$qlibobj" \
-	&& $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' 	&()|`$[]' \
-	&& $echo "$modename: libobj name \`$libobj' may not contain shell special characters."
-    objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
-    xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
-    if test "X$xdir" = "X$obj"; then
-      xdir=
-    else
-      xdir=$xdir/
-    fi
-    lobj=${xdir}$objdir/$objname
 
-    if test -z "$base_compile"; then
-      $echo "$modename: you must specify a compilation command" 1>&2
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-    fi
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)!  Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+    $opt_debug
+    case $1 in
+    */* | *\\*)	. "$1" ;;
+    *)		. "./$1" ;;
+    esac
+}
 
-    # Delete any leftover library objects.
-    if test "$build_old_libs" = yes; then
-      removelist="$obj $lobj $libobj ${libobj}T"
-    else
-      removelist="$lobj $libobj ${libobj}T"
-    fi
 
-    $run $rm $removelist
-    trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot.  Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+  func_resolve_sysroot_result=$1
+  case $func_resolve_sysroot_result in
+  =*)
+    func_stripname '=' '' "$func_resolve_sysroot_result"
+    func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+    ;;
+  esac
+}
 
-    # On Cygwin there's no "real" PIC flag so we must build both object types
-    case $host_os in
-    cygwin* | mingw* | pw32* | os2*)
-      pic_mode=default
-      ;;
-    esac
-    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
-      # non-PIC code in shared libraries is not supported
-      pic_mode=default
-    fi
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+  case "$lt_sysroot:$1" in
+  ?*:"$lt_sysroot"*)
+    func_stripname "$lt_sysroot" '' "$1"
+    func_replace_sysroot_result="=$func_stripname_result"
+    ;;
+  *)
+    # Including no sysroot.
+    func_replace_sysroot_result=$1
+    ;;
+  esac
+}
 
-    # Calculate the filename of the output object if compiler does
-    # not support -o with -c
-    if test "$compiler_c_o" = no; then
-      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
-      lockfile="$output_obj.lock"
-      removelist="$removelist $output_obj $lockfile"
-      trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
-    else
-      output_obj=
-      need_locks=no
-      lockfile=
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+    $opt_debug
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+	func_append_quoted CC_quoted "$arg"
+      done
+      CC_expanded=`func_echo_all $CC`
+      CC_quoted_expanded=`func_echo_all $CC_quoted`
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+      " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+	for z in $available_tags; do
+	  if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+	    # Evaluate the configuration.
+	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+	    CC_quoted=
+	    for arg in $CC; do
+	      # Double-quote args containing other shell metacharacters.
+	      func_append_quoted CC_quoted "$arg"
+	    done
+	    CC_expanded=`func_echo_all $CC`
+	    CC_quoted_expanded=`func_echo_all $CC_quoted`
+	    case "$@ " in
+	    " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+	    " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+	      # The compiler in the base compile command matches
+	      # the one in the tagged configuration.
+	      # Assume this is the tagged configuration we want.
+	      tagname=$z
+	      break
+	      ;;
+	    esac
+	  fi
+	done
+	# If $tagname still isn't set, then no tagged configuration
+	# was found and let the user know that the "--tag" command
+	# line option must be used.
+	if test -z "$tagname"; then
+	  func_echo "unable to infer tagged configuration"
+	  func_fatal_error "specify a tag with \`--tag'"
+#	else
+#	  func_verbose "using $tagname tagged configuration"
+	fi
+	;;
+      esac
     fi
+}
 
-    # Lock this critical section if it is needed
-    # We use this script file to make the link, it avoids creating a new file
-    if test "$need_locks" = yes; then
-      until $run ln "$progpath" "$lockfile" 2>/dev/null; do
-	$show "Waiting for $lockfile to be removed"
-	sleep 2
-      done
-    elif test "$need_locks" = warn; then
-      if test -f "$lockfile"; then
-	$echo "\
-*** ERROR, $lockfile exists and contains:
-`cat $lockfile 2>/dev/null`
 
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together.  If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
 
-	$run $rm $removelist
-	exit $EXIT_FAILURE
-      fi
-      $echo "$srcfile" > "$lockfile"
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+    write_libobj=${1}
+    if test "$build_libtool_libs" = yes; then
+      write_lobj=\'${2}\'
+    else
+      write_lobj=none
     fi
 
-    if test -n "$fix_srcfile_path"; then
-      eval srcfile=\"$fix_srcfile_path\"
+    if test "$build_old_libs" = yes; then
+      write_oldobj=\'${3}\'
+    else
+      write_oldobj=none
     fi
-    qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"`
-    case $qsrcfile in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-      qsrcfile="\"$qsrcfile\"" ;;
-    esac
-
-    $run $rm "$libobj" "${libobj}T"
 
-    # Create a libtool object file (analogous to a ".la" file),
-    # but don't create it if we're doing a dry run.
-    test -z "$run" && cat > ${libobj}T <<EOF
-# $libobj - a libtool object file
-# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+    $opt_dry_run || {
+      cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
 #
 # Please DO NOT delete this file!
 # It is necessary for linking the library.
 
 # Name of the PIC object.
-EOF
+pic_object=$write_lobj
 
-    # Only build a PIC object if we are building libtool libraries.
-    if test "$build_libtool_libs" = yes; then
-      # Without this assignment, base_compile gets emptied.
-      fbsd_hideous_sh_bug=$base_compile
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
 
-      if test "$pic_mode" != no; then
-	command="$base_compile $qsrcfile $pic_flag"
-      else
-	# Don't build PIC code
-	command="$base_compile $qsrcfile"
-      fi
+EOF
+      $MV "${write_libobj}T" "${write_libobj}"
+    }
+}
 
-      if test ! -d "${xdir}$objdir"; then
-	$show "$mkdir ${xdir}$objdir"
-	$run $mkdir ${xdir}$objdir
-	exit_status=$?
-	if test "$exit_status" -ne 0 && test ! -d "${xdir}$objdir"; then
-	  exit $exit_status
-	fi
-      fi
 
-      if test -z "$output_obj"; then
-	# Place PIC objects in $objdir
-	command="$command -o $lobj"
-      fi
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
 
-      $run $rm "$lobj" "$output_obj"
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+  $opt_debug
+  func_convert_core_file_wine_to_w32_result="$1"
+  if test -n "$1"; then
+    # Unfortunately, winepath does not exit with a non-zero error code, so we
+    # are forced to check the contents of stdout. On the other hand, if the
+    # command is not found, the shell will set an exit code of 127 and print
+    # *an error message* to stdout. So we must check for both error code of
+    # zero AND non-empty stdout, which explains the odd construction:
+    func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+    if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
+      func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+        $SED -e "$lt_sed_naive_backslashify"`
+    else
+      func_convert_core_file_wine_to_w32_result=
+    fi
+  fi
+}
+# end: func_convert_core_file_wine_to_w32
 
-      $show "$command"
-      if $run eval $lt_env "$command"; then :
-      else
-	test -n "$output_obj" && $run $rm $removelist
-	exit $EXIT_FAILURE
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+  $opt_debug
+  # unfortunately, winepath doesn't convert paths, only file names
+  func_convert_core_path_wine_to_w32_result=""
+  if test -n "$1"; then
+    oldIFS=$IFS
+    IFS=:
+    for func_convert_core_path_wine_to_w32_f in $1; do
+      IFS=$oldIFS
+      func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+      if test -n "$func_convert_core_file_wine_to_w32_result" ; then
+        if test -z "$func_convert_core_path_wine_to_w32_result"; then
+          func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
+        else
+          func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+        fi
       fi
+    done
+    IFS=$oldIFS
+  fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+  $opt_debug
+  if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+    func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+    if test "$?" -ne 0; then
+      # on failure, ensure result is empty
+      func_cygpath_result=
+    fi
+  else
+    func_cygpath_result=
+    func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
+  fi
+}
+#end: func_cygpath
 
-      if test "$need_locks" = warn &&
-	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
-	$echo "\
-*** ERROR, $lockfile contains:
-`cat $lockfile 2>/dev/null`
 
-but it should contain:
-$srcfile
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format.  Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+  $opt_debug
+  # awkward: cmd appends spaces to result
+  func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+    $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
 
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together.  If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
 
-	$run $rm $removelist
-	exit $EXIT_FAILURE
-      fi
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+  $opt_debug
+  if test -z "$2" && test -n "$1" ; then
+    func_error "Could not determine host file name corresponding to"
+    func_error "  \`$1'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback:
+    func_to_host_file_result="$1"
+  fi
+}
+# end func_convert_file_check
 
-      # Just move the object if needed, then go on to compile the next one
-      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
-	$show "$mv $output_obj $lobj"
-	if $run $mv $output_obj $lobj; then :
-	else
-	  error=$?
-	  $run $rm $removelist
-	  exit $error
-	fi
-      fi
 
-      # Append the name of the PIC object to the libtool object file.
-      test -z "$run" && cat >> ${libobj}T <<EOF
-pic_object='$objdir/$objname'
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+  $opt_debug
+  if test -z "$4" && test -n "$3"; then
+    func_error "Could not determine the host path corresponding to"
+    func_error "  \`$3'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback.  This is a deliberately simplistic "conversion" and
+    # should not be "improved".  See libtool.info.
+    if test "x$1" != "x$2"; then
+      lt_replace_pathsep_chars="s|$1|$2|g"
+      func_to_host_path_result=`echo "$3" |
+        $SED -e "$lt_replace_pathsep_chars"`
+    else
+      func_to_host_path_result="$3"
+    fi
+  fi
+}
+# end func_convert_path_check
 
-EOF
 
-      # Allow error messages only from the first compilation.
-      if test "$suppress_opt" = yes; then
-        suppress_output=' >/dev/null 2>&1'
-      fi
-    else
-      # No PIC object so indicate it doesn't exist in the libtool
-      # object file.
-      test -z "$run" && cat >> ${libobj}T <<EOF
-pic_object=none
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+  $opt_debug
+  case $4 in
+  $1 ) func_to_host_path_result="$3$func_to_host_path_result"
+    ;;
+  esac
+  case $4 in
+  $2 ) func_append func_to_host_path_result "$3"
+    ;;
+  esac
+}
+# end func_convert_path_front_back_pathsep
 
-EOF
-    fi
 
-    # Only build a position-dependent object if we build old libraries.
-    if test "$build_old_libs" = yes; then
-      if test "$pic_mode" != yes; then
-	# Don't build PIC code
-	command="$base_compile $qsrcfile"
-      else
-	command="$base_compile $qsrcfile $pic_flag"
-      fi
-      if test "$compiler_c_o" = yes; then
-	command="$command -o $obj"
-      fi
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via `$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
 
-      # Suppress compiler output if we already did a PIC compilation.
-      command="$command$suppress_output"
-      $run $rm "$obj" "$output_obj"
-      $show "$command"
-      if $run eval $lt_env "$command"; then :
-      else
-	$run $rm $removelist
-	exit $EXIT_FAILURE
-      fi
 
-      if test "$need_locks" = warn &&
-	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
-	$echo "\
-*** ERROR, $lockfile contains:
-`cat $lockfile 2>/dev/null`
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+  $opt_debug
+  $to_host_file_cmd "$1"
+}
+# end func_to_host_file
 
-but it should contain:
-$srcfile
 
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together.  If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result.  If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+  $opt_debug
+  case ,$2, in
+    *,"$to_tool_file_cmd",*)
+      func_to_tool_file_result=$1
+      ;;
+    *)
+      $to_tool_file_cmd "$1"
+      func_to_tool_file_result=$func_to_host_file_result
+      ;;
+  esac
+}
+# end func_to_tool_file
 
-	$run $rm $removelist
-	exit $EXIT_FAILURE
-      fi
 
-      # Just move the object if needed
-      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
-	$show "$mv $output_obj $obj"
-	if $run $mv $output_obj $obj; then :
-	else
-	  error=$?
-	  $run $rm $removelist
-	  exit $error
-	fi
-      fi
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+  func_to_host_file_result="$1"
+}
+# end func_convert_file_noop
 
-      # Append the name of the non-PIC object the libtool object file.
-      # Only append if the libtool object file exists.
-      test -z "$run" && cat >> ${libobj}T <<EOF
-# Name of the non-PIC object.
-non_pic_object='$objname'
 
-EOF
-    else
-      # Append the name of the non-PIC object the libtool object file.
-      # Only append if the libtool object file exists.
-      test -z "$run" && cat >> ${libobj}T <<EOF
-# Name of the non-PIC object.
-non_pic_object=none
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_to_host_file_result="$func_convert_core_msys_to_w32_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
 
-EOF
-    fi
 
-    $run $mv "${libobj}T" "${libobj}"
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+    # LT_CYGPATH in this case.
+    func_to_host_file_result=`cygpath -m "$1"`
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
 
-    # Unlock the critical section if it was locked
-    if test "$need_locks" != no; then
-      $run $rm "$lockfile"
-    fi
 
-    exit $EXIT_SUCCESS
-    ;;
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format.  Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_file_wine_to_w32 "$1"
+    func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
 
-  # libtool link mode
-  link | relink)
-    modename="$modename: link"
-    case $host in
-    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
-      # It is impossible to link a dll without this setting, and
-      # we shouldn't force the makefile maintainer to figure out
-      # which system we are compiling for in order to pass an extra
-      # flag for every libtool invocation.
-      # allow_undefined=no
 
-      # FIXME: Unfortunately, there are problems with the above when trying
-      # to make a dll which has undefined symbols, in which case not
-      # even a static library is built.  For now, we need to specify
-      # -no-undefined on the libtool link line when we can be certain
-      # that all symbols are satisfied, otherwise we get a static library.
-      allow_undefined=yes
-      ;;
-    *)
-      allow_undefined=yes
-      ;;
-    esac
-    libtool_args="$nonopt"
-    base_compile="$nonopt $@"
-    compile_command="$nonopt"
-    finalize_command="$nonopt"
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_msys_to_w32_result"
+    func_to_host_file_result="$func_cygpath_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
 
-    compile_rpath=
-    finalize_rpath=
-    compile_shlibpath=
-    finalize_shlibpath=
-    convenience=
-    old_convenience=
-    deplibs=
-    old_deplibs=
-    compiler_flags=
-    linker_flags=
-    dllsearchpath=
-    lib_search_path=`pwd`
-    inst_prefix_dir=
 
-    avoid_version=no
-    dlfiles=
-    dlprefiles=
-    dlself=no
-    export_dynamic=no
-    export_symbols=
-    export_symbols_regex=
-    generated=
-    libobjs=
-    ltlibs=
-    module=no
-    no_install=no
-    objs=
-    non_pic_objects=
-    notinst_path= # paths that contain not-installed libtool libraries
-    precious_files_regex=
-    prefer_static_libs=no
-    preload=no
-    prev=
-    prevarg=
-    release=
-    rpath=
-    xrpath=
-    perm_rpath=
-    temp_rpath=
-    thread_safe=no
-    vinfo=
-    vinfo_number=no
-    single_module="${wl}-single_module"
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format.  Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set.  Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+    func_convert_core_file_wine_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+    func_to_host_file_result="$func_cygpath_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
 
-    func_infer_tag $base_compile
 
-    # We need to know -static, to get the right output filenames.
-    for arg
-    do
-      case $arg in
-      -all-static | -static | -static-libtool-libs)
-	case $arg in
-	-all-static)
-	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
-	    $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
-	  fi
-	  if test -n "$link_static_flag"; then
-	    dlopen_self=$dlopen_self_static
-	  fi
-	  prefer_static_libs=yes
-	  ;;
-	-static)
-	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
-	    dlopen_self=$dlopen_self_static
-	  fi
-	  prefer_static_libs=built
-	  ;;
-	-static-libtool-libs)
-	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
-	    dlopen_self=$dlopen_self_static
-	  fi
-	  prefer_static_libs=yes
-	  ;;
-	esac
-	build_libtool_libs=no
-	build_old_libs=yes
-	break
-	;;
-      esac
-    done
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format.  If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+#   file name conversion function    : func_convert_file_X_to_Y ()
+#   path conversion function         : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same.  If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+  $opt_debug
+  if test -z "$to_host_path_cmd"; then
+    func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+    to_host_path_cmd="func_convert_path_${func_stripname_result}"
+  fi
+}
 
-    # See if our shared archives depend on static archives.
-    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
 
-    # Go through the arguments, transforming them on the way.
-    while test "$#" -gt 0; do
-      arg="$1"
-      shift
-      case $arg in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
-	;;
-      *) qarg=$arg ;;
-      esac
-      libtool_args="$libtool_args $qarg"
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+  $opt_debug
+  func_init_to_host_path_cmd
+  $to_host_path_cmd "$1"
+}
+# end func_to_host_path
 
-      # If the previous option needs an argument, assign it.
-      if test -n "$prev"; then
-	case $prev in
-	output)
-	  compile_command="$compile_command @OUTPUT@"
-	  finalize_command="$finalize_command @OUTPUT@"
-	  ;;
-	esac
 
-	case $prev in
-	dlfiles|dlprefiles)
-	  if test "$preload" = no; then
-	    # Add the symbol object into the linking commands.
-	    compile_command="$compile_command @SYMFILE@"
-	    finalize_command="$finalize_command @SYMFILE@"
-	    preload=yes
-	  fi
-	  case $arg in
-	  *.la | *.lo) ;;  # We handle these cases below.
-	  force)
-	    if test "$dlself" = no; then
-	      dlself=needless
-	      export_dynamic=yes
-	    fi
-	    prev=
-	    continue
-	    ;;
-	  self)
-	    if test "$prev" = dlprefiles; then
-	      dlself=yes
-	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
-	      dlself=yes
-	    else
-	      dlself=needless
-	      export_dynamic=yes
-	    fi
-	    prev=
-	    continue
-	    ;;
-	  *)
-	    if test "$prev" = dlfiles; then
-	      dlfiles="$dlfiles $arg"
-	    else
-	      dlprefiles="$dlprefiles $arg"
-	    fi
-	    prev=
-	    continue
-	    ;;
-	  esac
-	  ;;
-	expsyms)
-	  export_symbols="$arg"
-	  if test ! -f "$arg"; then
-	    $echo "$modename: symbol file \`$arg' does not exist"
-	    exit $EXIT_FAILURE
-	  fi
-	  prev=
-	  continue
-	  ;;
-	expsyms_regex)
-	  export_symbols_regex="$arg"
-	  prev=
-	  continue
-	  ;;
-	inst_prefix)
-	  inst_prefix_dir="$arg"
-	  prev=
-	  continue
-	  ;;
-	precious_regex)
-	  precious_files_regex="$arg"
-	  prev=
-	  continue
-	  ;;
-	release)
-	  release="-$arg"
-	  prev=
-	  continue
-	  ;;
-	objectlist)
-	  if test -f "$arg"; then
-	    save_arg=$arg
-	    moreargs=
-	    for fil in `cat $save_arg`
-	    do
-#	      moreargs="$moreargs $fil"
-	      arg=$fil
-	      # A libtool-controlled object.
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+  func_to_host_path_result="$1"
+}
+# end func_convert_path_noop
 
-	      # Check to see that this really is a libtool object.
-	      if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-		pic_object=
-		non_pic_object=
 
-		# Read the .lo file
-		# If there is no directory component, then add one.
-		case $arg in
-		*/* | *\\*) . $arg ;;
-		*) . ./$arg ;;
-		esac
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from ARG.  MSYS
+    # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+    # and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result="$func_convert_core_msys_to_w32_result"
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_msys_to_w32
 
-		if test -z "$pic_object" || \
-		   test -z "$non_pic_object" ||
-		   test "$pic_object" = none && \
-		   test "$non_pic_object" = none; then
-		  $echo "$modename: cannot find name of object for \`$arg'" 1>&2
-		  exit $EXIT_FAILURE
-		fi
 
-		# Extract subdirectory from the argument.
-		xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
-		if test "X$xdir" = "X$arg"; then
-		  xdir=
-		else
-		  xdir="$xdir/"
-		fi
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_cygwin_to_w32
 
-		if test "$pic_object" != none; then
-		  # Prepend the subdirectory the object is found in.
-		  pic_object="$xdir$pic_object"
 
-		  if test "$prev" = dlfiles; then
-		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
-		      dlfiles="$dlfiles $pic_object"
-		      prev=
-		      continue
-		    else
-		      # If libtool objects are unsupported, then we need to preload.
-		      prev=dlprefiles
-		    fi
-		  fi
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format.  Requires a wine environment and
+# a working winepath.  Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_nix_to_w32
 
-		  # CHECK ME:  I think I busted this.  -Ossama
-		  if test "$prev" = dlprefiles; then
-		    # Preload the old-style object.
-		    dlprefiles="$dlprefiles $pic_object"
-		    prev=
-		  fi
 
-		  # A PIC object.
-		  libobjs="$libobjs $pic_object"
-		  arg="$pic_object"
-		fi
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+    func_to_host_path_result="$func_cygpath_result"
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_msys_to_cygwin
 
-		# Non-PIC object.
-		if test "$non_pic_object" != none; then
-		  # Prepend the subdirectory the object is found in.
-		  non_pic_object="$xdir$non_pic_object"
 
-		  # A standard non-PIC object
-		  non_pic_objects="$non_pic_objects $non_pic_object"
-		  if test -z "$pic_object" || test "$pic_object" = none ; then
-		    arg="$non_pic_object"
-		  fi
-		else
-		  # If the PIC object exists, use it instead.
-		  # $xdir was prepended to $pic_object above.
-		  non_pic_object="$pic_object"
-		  non_pic_objects="$non_pic_objects $non_pic_object"
-		fi
-	      else
-		# Only an error if not doing a dry-run.
-		if test -z "$run"; then
-		  $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
-		  exit $EXIT_FAILURE
-		else
-		  # Dry-run case.
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format.  Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set.  Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from
+    # ARG. msys behavior is inconsistent here, cygpath turns them
+    # into '.;' and ';.', and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+    func_to_host_path_result="$func_cygpath_result"
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_nix_to_cygwin
 
-		  # Extract subdirectory from the argument.
-		  xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
-		  if test "X$xdir" = "X$arg"; then
-		    xdir=
-		  else
-		    xdir="$xdir/"
-		  fi
 
-		  pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
-		  non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
-		  libobjs="$libobjs $pic_object"
-		  non_pic_objects="$non_pic_objects $non_pic_object"
-		fi
-	      fi
-	    done
-	  else
-	    $echo "$modename: link input file \`$save_arg' does not exist"
-	    exit $EXIT_FAILURE
-	  fi
-	  arg=$save_arg
-	  prev=
-	  continue
-	  ;;
-	rpath | xrpath)
-	  # We need an absolute path.
-	  case $arg in
-	  [\\/]* | [A-Za-z]:[\\/]*) ;;
-	  *)
-	    $echo "$modename: only absolute run-paths are allowed" 1>&2
-	    exit $EXIT_FAILURE
-	    ;;
-	  esac
-	  if test "$prev" = rpath; then
-	    case "$rpath " in
-	    *" $arg "*) ;;
-	    *) rpath="$rpath $arg" ;;
-	    esac
-	  else
-	    case "$xrpath " in
-	    *" $arg "*) ;;
-	    *) xrpath="$xrpath $arg" ;;
-	    esac
-	  fi
-	  prev=
-	  continue
-	  ;;
-	xcompiler)
-	  compiler_flags="$compiler_flags $qarg"
-	  prev=
-	  compile_command="$compile_command $qarg"
-	  finalize_command="$finalize_command $qarg"
-	  continue
-	  ;;
-	xlinker)
-	  linker_flags="$linker_flags $qarg"
-	  compiler_flags="$compiler_flags $wl$qarg"
-	  prev=
-	  compile_command="$compile_command $wl$qarg"
-	  finalize_command="$finalize_command $wl$qarg"
-	  continue
-	  ;;
-	xcclinker)
-	  linker_flags="$linker_flags $qarg"
-	  compiler_flags="$compiler_flags $qarg"
-	  prev=
-	  compile_command="$compile_command $qarg"
-	  finalize_command="$finalize_command $qarg"
+# func_mode_compile arg...
+func_mode_compile ()
+{
+    $opt_debug
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+    pie_flag=
+
+    for arg
+    do
+      case $arg_mode in
+      arg  )
+	# do not "continue".  Instead, add this to base_compile
+	lastarg="$arg"
+	arg_mode=normal
+	;;
+
+      target )
+	libobj="$arg"
+	arg_mode=normal
+	continue
+	;;
+
+      normal )
+	# Accept any command-line options.
+	case $arg in
+	-o)
+	  test -n "$libobj" && \
+	    func_fatal_error "you cannot specify \`-o' more than once"
+	  arg_mode=target
 	  continue
 	  ;;
-	shrext)
-  	  shrext_cmds="$arg"
-	  prev=
+
+	-pie | -fpie | -fPIE)
+          func_append pie_flag " $arg"
 	  continue
 	  ;;
-	darwin_framework|darwin_framework_skip)
-	  test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg"
-	  compile_command="$compile_command $arg"
-	  finalize_command="$finalize_command $arg"
-	  prev=
+
+	-shared | -static | -prefer-pic | -prefer-non-pic)
+	  func_append later " $arg"
 	  continue
 	  ;;
-	*)
-	  eval "$prev=\"\$arg\""
-	  prev=
+
+	-no-suppress)
+	  suppress_opt=no
 	  continue
 	  ;;
-	esac
-      fi # test -n "$prev"
 
-      prevarg="$arg"
+	-Xcompiler)
+	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
+	  continue      #  The current "srcfile" will either be retained or
+	  ;;            #  replaced later.  I would guess that would be a bug.
 
-      case $arg in
-      -all-static)
-	if test -n "$link_static_flag"; then
-	  compile_command="$compile_command $link_static_flag"
-	  finalize_command="$finalize_command $link_static_flag"
-	fi
-	continue
-	;;
+	-Wc,*)
+	  func_stripname '-Wc,' '' "$arg"
+	  args=$func_stripname_result
+	  lastarg=
+	  save_ifs="$IFS"; IFS=','
+	  for arg in $args; do
+	    IFS="$save_ifs"
+	    func_append_quoted lastarg "$arg"
+	  done
+	  IFS="$save_ifs"
+	  func_stripname ' ' '' "$lastarg"
+	  lastarg=$func_stripname_result
 
-      -allow-undefined)
-	# FIXME: remove this flag sometime in the future.
-	$echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
-	continue
-	;;
+	  # Add the arguments to base_compile.
+	  func_append base_compile " $lastarg"
+	  continue
+	  ;;
 
-      -avoid-version)
-	avoid_version=yes
-	continue
+	*)
+	  # Accept the current argument as the source file.
+	  # The previous "srcfile" becomes the current argument.
+	  #
+	  lastarg="$srcfile"
+	  srcfile="$arg"
+	  ;;
+	esac  #  case $arg
 	;;
+      esac    #  case $arg_mode
 
-      -dlopen)
-	prev=dlfiles
-	continue
-	;;
+      # Aesthetically quote the previous argument.
+      func_append_quoted base_compile "$lastarg"
+    done # for arg
 
-      -dlpreopen)
-	prev=dlprefiles
-	continue
-	;;
-
-      -export-dynamic)
-	export_dynamic=yes
-	continue
-	;;
+    case $arg_mode in
+    arg)
+      func_fatal_error "you must specify an argument for -Xcompile"
+      ;;
+    target)
+      func_fatal_error "you must specify a target with \`-o'"
+      ;;
+    *)
+      # Get the name of the library object.
+      test -z "$libobj" && {
+	func_basename "$srcfile"
+	libobj="$func_basename_result"
+      }
+      ;;
+    esac
 
-      -export-symbols | -export-symbols-regex)
-	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
-	  $echo "$modename: more than one -exported-symbols argument is not allowed"
-	  exit $EXIT_FAILURE
-	fi
-	if test "X$arg" = "X-export-symbols"; then
-	  prev=expsyms
-	else
-	  prev=expsyms_regex
-	fi
-	continue
-	;;
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    case $libobj in
+    *.[cCFSifmso] | \
+    *.ada | *.adb | *.ads | *.asm | \
+    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+    *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+      func_xform "$libobj"
+      libobj=$func_xform_result
+      ;;
+    esac
 
-      -framework|-arch|-isysroot)
-	case " $CC " in
-	  *" ${arg} ${1} "* | *" ${arg}	${1} "*) 
-		prev=darwin_framework_skip ;;
-	  *) compiler_flags="$compiler_flags $arg"
-	     prev=darwin_framework ;;
-	esac
-	compile_command="$compile_command $arg"
-	finalize_command="$finalize_command $arg"
-	continue
-	;;
+    case $libobj in
+    *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+    *)
+      func_fatal_error "cannot determine name of library object from \`$libobj'"
+      ;;
+    esac
 
-      -inst-prefix-dir)
-	prev=inst_prefix
-	continue
-	;;
+    func_infer_tag $base_compile
 
-      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
-      # so, if we see these flags be careful not to treat them like -L
-      -L[A-Z][A-Z]*:*)
-	case $with_gcc/$host in
-	no/*-*-irix* | /*-*-irix*)
-	  compile_command="$compile_command $arg"
-	  finalize_command="$finalize_command $arg"
-	  ;;
-	esac
+    for arg in $later; do
+      case $arg in
+      -shared)
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
+	build_old_libs=no
 	continue
 	;;
 
-      -L*)
-	dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
-	# We need an absolute path.
-	case $dir in
-	[\\/]* | [A-Za-z]:[\\/]*) ;;
-	*)
-	  absdir=`cd "$dir" && pwd`
-	  if test -z "$absdir"; then
-	    $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
-	    absdir="$dir"
-	    notinst_path="$notinst_path $dir"
-	  fi
-	  dir="$absdir"
-	  ;;
-	esac
-	case "$deplibs " in
-	*" -L$dir "*) ;;
-	*)
-	  deplibs="$deplibs -L$dir"
-	  lib_search_path="$lib_search_path $dir"
-	  ;;
-	esac
-	case $host in
-	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
-	  testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'`
-	  case :$dllsearchpath: in
-	  *":$dir:"*) ;;
-	  *) dllsearchpath="$dllsearchpath:$dir";;
-	  esac
-	  case :$dllsearchpath: in
-	  *":$testbindir:"*) ;;
-	  *) dllsearchpath="$dllsearchpath:$testbindir";;
-	  esac
-	  ;;
-	esac
+      -static)
+	build_libtool_libs=no
+	build_old_libs=yes
 	continue
 	;;
 
-      -l*)
-	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
-	  case $host in
-	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*)
-	    # These systems don't actually have a C or math library (as such)
-	    continue
-	    ;;
-	  *-*-os2*)
-	    # These systems don't actually have a C library (as such)
-	    test "X$arg" = "X-lc" && continue
-	    ;;
-	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
-	    # Do not include libc due to us having libc/libc_r.
-	    test "X$arg" = "X-lc" && continue
-	    ;;
-	  *-*-rhapsody* | *-*-darwin1.[012])
-	    # Rhapsody C and math libraries are in the System framework
-	    deplibs="$deplibs -framework System"
-	    continue
-	    ;;
-	  *-*-sco3.2v5* | *-*-sco5v6*)
-	    # Causes problems with __ctype
-	    test "X$arg" = "X-lc" && continue
-	    ;;
-	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
-	    # Compiler inserts libc in the correct place for threads to work
-	    test "X$arg" = "X-lc" && continue
-	    ;;
-	  esac
-	elif test "X$arg" = "X-lc_r"; then
-	 case $host in
-	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
-	   # Do not include libc_r directly, use -pthread flag.
-	   continue
-	   ;;
-	 esac
-	fi
-	deplibs="$deplibs $arg"
+      -prefer-pic)
+	pic_mode=yes
 	continue
 	;;
 
-      # Tru64 UNIX uses -model [arg] to determine the layout of C++
-      # classes, name mangling, and exception handling.
-      -model)
-	compile_command="$compile_command $arg"
-	compiler_flags="$compiler_flags $arg"
-	finalize_command="$finalize_command $arg"
-	prev=xcompiler
+      -prefer-non-pic)
+	pic_mode=no
 	continue
 	;;
+      esac
+    done
 
-     -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
-	compiler_flags="$compiler_flags $arg"
-	compile_command="$compile_command $arg"
-	finalize_command="$finalize_command $arg"
-	continue
-	;;
+    func_quote_for_eval "$libobj"
+    test "X$libobj" != "X$func_quote_for_eval_result" \
+      && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
+      && func_warning "libobj name \`$libobj' may not contain shell special characters."
+    func_dirname_and_basename "$obj" "/" ""
+    objname="$func_basename_result"
+    xdir="$func_dirname_result"
+    lobj=${xdir}$objdir/$objname
 
-      -multi_module)
-	single_module="${wl}-multi_module"
-	continue
-	;;
+    test -z "$base_compile" && \
+      func_fatal_help "you must specify a compilation command"
 
-      -module)
-	module=yes
-	continue
-	;;
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
 
-      # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
-      # -r[0-9][0-9]* specifies the processor on the SGI compiler
-      # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
-      # +DA*, +DD* enable 64-bit mode on the HP compiler
-      # -q* pass through compiler args for the IBM compiler
-      # -m* pass through architecture-specific compiler args for GCC
-      # -m*, -t[45]*, -txscale* pass through architecture-specific
-      # compiler args for GCC
-      # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
-      # -F/path gives path to uninstalled frameworks, gcc on darwin
-      # @file GCC response files
-      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
-      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2* | cegcc*)
+      pic_mode=default
+      ;;
+    esac
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
 
-	# Unknown arguments in both finalize_command and compile_command need
-	# to be aesthetically quoted because they are evaled later.
-	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-	case $arg in
-	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	  arg="\"$arg\""
-	  ;;
-	esac
-        compile_command="$compile_command $arg"
-        finalize_command="$finalize_command $arg"
-        compiler_flags="$compiler_flags $arg"
-        continue
-        ;;
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
 
-      -shrext)
-	prev=shrext
-	continue
-	;;
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+	$ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
 
-      -no-fast-install)
-	fast_install=no
-	continue
-	;;
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
 
-      -no-install)
-	case $host in
-	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin*)
-	  # The PATH hackery in wrapper scripts is required on Windows
-	  # and Darwin in order for the loader to find any dlls it needs.
-	  $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
-	  $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
-	  fast_install=no
-	  ;;
-	*) no_install=yes ;;
-	esac
-	continue
-	;;
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+      func_append removelist " $output_obj"
+      $ECHO "$srcfile" > "$lockfile"
+    fi
 
-      -no-undefined)
-	allow_undefined=no
-	continue
-	;;
+    $opt_dry_run || $RM $removelist
+    func_append removelist " $lockfile"
+    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
 
-      -objectlist)
-	prev=objectlist
-	continue
-	;;
+    func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+    srcfile=$func_to_tool_file_result
+    func_quote_for_eval "$srcfile"
+    qsrcfile=$func_quote_for_eval_result
 
-      -o) prev=output ;;
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
 
-      -precious-files-regex)
-	prev=precious_regex
-	continue
-	;;
+      if test "$pic_mode" != no; then
+	command="$base_compile $qsrcfile $pic_flag"
+      else
+	# Don't build PIC code
+	command="$base_compile $qsrcfile"
+      fi
 
-      -release)
-	prev=release
-	continue
-	;;
+      func_mkdir_p "$xdir$objdir"
 
-      -rpath)
-	prev=rpath
-	continue
-	;;
+      if test -z "$output_obj"; then
+	# Place PIC objects in $objdir
+	func_append command " -o $lobj"
+      fi
 
-      -R)
-	prev=xrpath
-	continue
-	;;
+      func_show_eval_locale "$command"	\
+          'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
 
-      -R*)
-	dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
-	# We need an absolute path.
-	case $dir in
-	[\\/]* | [A-Za-z]:[\\/]*) ;;
-	*)
-	  $echo "$modename: only absolute run-paths are allowed" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
-	case "$xrpath " in
-	*" $dir "*) ;;
-	*) xrpath="$xrpath $dir" ;;
-	esac
-	continue
-	;;
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
 
-      -static | -static-libtool-libs)
-	# The effects of -static are defined in a previous loop.
-	# We used to do the same as -all-static on platforms that
-	# didn't have a PIC flag, but the assumption that the effects
-	# would be equivalent was wrong.  It would break on at least
-	# Digital Unix and AIX.
-	continue
-	;;
-
-      -thread-safe)
-	thread_safe=yes
-	continue
-	;;
+but it should contain:
+$srcfile
 
-      -version-info)
-	prev=vinfo
-	continue
-	;;
-      -version-number)
-	prev=vinfo
-	vinfo_number=yes
-	continue
-	;;
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
 
-      -Wc,*)
-	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
-	arg=
-	save_ifs="$IFS"; IFS=','
-	for flag in $args; do
-	  IFS="$save_ifs"
-	  case $flag in
-	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	    flag="\"$flag\""
-	    ;;
-	  esac
-	  arg="$arg $wl$flag"
-	  compiler_flags="$compiler_flags $flag"
-	done
-	IFS="$save_ifs"
-	arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
-	;;
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
 
-      -Wl,*)
-	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
-	arg=
-	save_ifs="$IFS"; IFS=','
-	for flag in $args; do
-	  IFS="$save_ifs"
-	  case $flag in
-	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	    flag="\"$flag\""
-	    ;;
-	  esac
-	  arg="$arg $wl$flag"
-	  compiler_flags="$compiler_flags $wl$flag"
-	  linker_flags="$linker_flags $flag"
-	done
-	IFS="$save_ifs"
-	arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
-	;;
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+	func_show_eval '$MV "$output_obj" "$lobj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
 
-      -Xcompiler)
-	prev=xcompiler
-	continue
-	;;
+      # Allow error messages only from the first compilation.
+      if test "$suppress_opt" = yes; then
+	suppress_output=' >/dev/null 2>&1'
+      fi
+    fi
 
-      -Xlinker)
-	prev=xlinker
-	continue
-	;;
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
+	# Don't build PIC code
+	command="$base_compile $qsrcfile$pie_flag"
+      else
+	command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test "$compiler_c_o" = yes; then
+	func_append command " -o $obj"
+      fi
 
-      -XCClinker)
-	prev=xcclinker
-	continue
-	;;
+      # Suppress compiler output if we already did a PIC compilation.
+      func_append command "$suppress_output"
+      func_show_eval_locale "$command" \
+        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
 
-      # Some other compiler flag.
-      -* | +*)
-	# Unknown arguments in both finalize_command and compile_command need
-	# to be aesthetically quoted because they are evaled later.
-	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-	case $arg in
-	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	  arg="\"$arg\""
-	  ;;
-	esac
-	;;
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
 
-      *.$objext)
-	# A standard object.
-	objs="$objs $arg"
-	;;
+but it should contain:
+$srcfile
 
-      *.lo)
-	# A libtool-controlled object.
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
 
-	# Check to see that this really is a libtool object.
-	if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-	  pic_object=
-	  non_pic_object=
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
 
-	  # Read the .lo file
-	  # If there is no directory component, then add one.
-	  case $arg in
-	  */* | *\\*) . $arg ;;
-	  *) . ./$arg ;;
-	  esac
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+	func_show_eval '$MV "$output_obj" "$obj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+    fi
 
-	  if test -z "$pic_object" || \
-	     test -z "$non_pic_object" ||
-	     test "$pic_object" = none && \
-	     test "$non_pic_object" = none; then
-	    $echo "$modename: cannot find name of object for \`$arg'" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
+    $opt_dry_run || {
+      func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
 
-	  # Extract subdirectory from the argument.
-	  xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
-	  if test "X$xdir" = "X$arg"; then
-	    xdir=
- 	  else
-	    xdir="$xdir/"
-	  fi
+      # Unlock the critical section if it was locked
+      if test "$need_locks" != no; then
+	removelist=$lockfile
+        $RM "$lockfile"
+      fi
+    }
 
-	  if test "$pic_object" != none; then
-	    # Prepend the subdirectory the object is found in.
-	    pic_object="$xdir$pic_object"
+    exit $EXIT_SUCCESS
+}
 
-	    if test "$prev" = dlfiles; then
-	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
-		dlfiles="$dlfiles $pic_object"
-		prev=
-		continue
-	      else
-		# If libtool objects are unsupported, then we need to preload.
-		prev=dlprefiles
-	      fi
-	    fi
+$opt_help || {
+  test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
+}
 
-	    # CHECK ME:  I think I busted this.  -Ossama
-	    if test "$prev" = dlprefiles; then
-	      # Preload the old-style object.
-	      dlprefiles="$dlprefiles $pic_object"
-	      prev=
-	    fi
+func_mode_help ()
+{
+    # We need to display help for each of the modes.
+    case $opt_mode in
+      "")
+        # Generic help is extracted from the usage comments
+        # at the start of this file.
+        func_help
+        ;;
 
-	    # A PIC object.
-	    libobjs="$libobjs $pic_object"
-	    arg="$pic_object"
-	  fi
+      clean)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
 
-	  # Non-PIC object.
-	  if test "$non_pic_object" != none; then
-	    # Prepend the subdirectory the object is found in.
-	    non_pic_object="$xdir$non_pic_object"
+Remove files from the build directory.
 
-	    # A standard non-PIC object
-	    non_pic_objects="$non_pic_objects $non_pic_object"
-	    if test -z "$pic_object" || test "$pic_object" = none ; then
-	      arg="$non_pic_object"
-	    fi
-	  else
-	    # If the PIC object exists, use it instead.
-	    # $xdir was prepended to $pic_object above.
-	    non_pic_object="$pic_object"
-	    non_pic_objects="$non_pic_objects $non_pic_object"
-	  fi
-	else
-	  # Only an error if not doing a dry-run.
-	  if test -z "$run"; then
-	    $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
-	    exit $EXIT_FAILURE
-	  else
-	    # Dry-run case.
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
 
-	    # Extract subdirectory from the argument.
-	    xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
-	    if test "X$xdir" = "X$arg"; then
-	      xdir=
-	    else
-	      xdir="$xdir/"
-	    fi
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+        ;;
 
-	    pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
-	    non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
-	    libobjs="$libobjs $pic_object"
-	    non_pic_objects="$non_pic_objects $non_pic_object"
-	  fi
-	fi
-	;;
+      compile)
+      $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
 
-      *.$libext)
-	# An archive.
-	deplibs="$deplibs $arg"
-	old_deplibs="$old_deplibs $arg"
-	continue
-	;;
+Compile a source file into a libtool library object.
 
-      *.la)
-	# A libtool-controlled library.
+This mode accepts the following additional options:
 
-	if test "$prev" = dlfiles; then
-	  # This library was specified with -dlopen.
-	  dlfiles="$dlfiles $arg"
-	  prev=
-	elif test "$prev" = dlprefiles; then
-	  # The library was specified with -dlpreopen.
-	  dlprefiles="$dlprefiles $arg"
-	  prev=
-	else
-	  deplibs="$deplibs $arg"
-	fi
-	continue
-	;;
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -no-suppress      do not suppress compiler output for multiple passes
+  -prefer-pic       try to build PIC objects only
+  -prefer-non-pic   try to build non-PIC objects only
+  -shared           do not build a \`.o' file suitable for static linking
+  -static           only build a \`.o' file suitable for static linking
+  -Wc,FLAG          pass FLAG directly to the compiler
 
-      # Some other compiler argument.
-      *)
-	# Unknown arguments in both finalize_command and compile_command need
-	# to be aesthetically quoted because they are evaled later.
-	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-	case $arg in
-	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	  arg="\"$arg\""
-	  ;;
-	esac
-	;;
-      esac # arg
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
 
-      # Now actually substitute the argument into the commands.
-      if test -n "$arg"; then
-	compile_command="$compile_command $arg"
-	finalize_command="$finalize_command $arg"
-      fi
-    done # argument parsing loop
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+        ;;
 
-    if test -n "$prev"; then
-      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-    fi
+      execute)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
 
-    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
-      eval arg=\"$export_dynamic_flag_spec\"
-      compile_command="$compile_command $arg"
-      finalize_command="$finalize_command $arg"
-    fi
+Automatically set library path, then run a program.
 
-    oldlibs=
-    # calculate the name of the file, without its directory
-    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
-    libobjs_save="$libobjs"
+This mode accepts the following additional options:
 
-    if test -n "$shlibpath_var"; then
-      # get the directories listed in $shlibpath_var
-      eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
-    else
-      shlib_search_path=
-    fi
-    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
-    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+  -dlopen FILE      add the directory containing FILE to the library path
 
-    output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
-    if test "X$output_objdir" = "X$output"; then
-      output_objdir="$objdir"
-    else
-      output_objdir="$output_objdir/$objdir"
-    fi
-    # Create the object directory.
-    if test ! -d "$output_objdir"; then
-      $show "$mkdir $output_objdir"
-      $run $mkdir $output_objdir
-      exit_status=$?
-      if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then
-	exit $exit_status
-      fi
-    fi
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
 
-    # Determine the type of output
-    case $output in
-    "")
-      $echo "$modename: you must specify an output file" 1>&2
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-      ;;
-    *.$libext) linkmode=oldlib ;;
-    *.lo | *.$objext) linkmode=obj ;;
-    *.la) linkmode=lib ;;
-    *) linkmode=prog ;; # Anything else should be a program.
-    esac
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
 
-    case $host in
-    *cygwin* | *mingw* | *pw32*)
-      # don't eliminate duplications in $postdeps and $predeps
-      duplicate_compiler_generated_deps=yes
-      ;;
-    *)
-      duplicate_compiler_generated_deps=$duplicate_deps
-      ;;
+Then, COMMAND is executed, with ARGS as arguments."
+        ;;
+
+      finish)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+        ;;
+
+      install)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+  -inst-prefix-dir PREFIX-DIR  Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+        ;;
+
+      link)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -bindir BINDIR    specify path to binaries directory (for systems where
+                    libraries must be found in the PATH setting at runtime)
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
+  -precious-files-regex REGEX
+                    don't remove output files matching REGEX
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -shared           only do dynamic linking of libtool libraries
+  -shrext SUFFIX    override the standard shared library file extension
+  -static           do not do any dynamic linking of uninstalled libtool libraries
+  -static-libtool-libs
+                    do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                    specify library version info [each variable defaults to 0]
+  -weak LIBNAME     declare that the target provides the LIBNAME interface
+  -Wc,FLAG
+  -Xcompiler FLAG   pass linker-specific FLAG directly to the compiler
+  -Wl,FLAG
+  -Xlinker FLAG     pass linker-specific FLAG directly to the linker
+  -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+        ;;
+
+      uninstall)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      *)
+        func_fatal_help "invalid operation mode \`$opt_mode'"
+        ;;
     esac
-    specialdeplibs=
 
-    libs=
-    # Find all interdependent deplibs by searching for libraries
-    # that are linked more than once (e.g. -la -lb -la)
-    for deplib in $deplibs; do
-      if test "X$duplicate_deps" = "Xyes" ; then
-	case "$libs " in
-	*" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-	esac
-      fi
-      libs="$libs $deplib"
-    done
+    echo
+    $ECHO "Try \`$progname --help' for more information about other modes."
+}
 
-    if test "$linkmode" = lib; then
-      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+  if test "$opt_help" = :; then
+    func_mode_help
+  else
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	func_mode_help
+      done
+    } | sed -n '1p; 2,$s/^Usage:/  or: /p'
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	echo
+	func_mode_help
+      done
+    } |
+    sed '1d
+      /^When reporting/,/^Report/{
+	H
+	d
+      }
+      $x
+      /information about other modes/d
+      /more detailed .*MODE/d
+      s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+  fi
+  exit $?
+fi
 
-      # Compute libraries that are listed more than once in $predeps
-      # $postdeps and mark them as special (i.e., whose duplicates are
-      # not to be eliminated).
-      pre_post_deps=
-      if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then
-	for pre_post_dep in $predeps $postdeps; do
-	  case "$pre_post_deps " in
-	  *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
-	  esac
-	  pre_post_deps="$pre_post_deps $pre_post_dep"
-	done
-      fi
-      pre_post_deps=
-    fi
 
-    deplibs=
-    newdependency_libs=
-    newlib_search_path=
-    need_relink=no # whether we're linking any uninstalled libtool libraries
-    notinst_deplibs= # not-installed libtool libraries
-    case $linkmode in
-    lib)
-	passes="conv link"
-	for file in $dlfiles $dlprefiles; do
-	  case $file in
-	  *.la) ;;
-	  *)
-	    $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
-	    exit $EXIT_FAILURE
-	    ;;
-	  esac
-	done
+# func_mode_execute arg...
+func_mode_execute ()
+{
+    $opt_debug
+    # The first argument is the command name.
+    cmd="$nonopt"
+    test -z "$cmd" && \
+      func_fatal_help "you must specify a COMMAND"
+
+    # Handle -dlopen flags immediately.
+    for file in $opt_dlopen; do
+      test -f "$file" \
+	|| func_fatal_help "\`$file' is not a file"
+
+      dir=
+      case $file in
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+	func_source "$file"
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && \
+	    func_warning "\`$file' was not linked with \`-export-dynamic'"
+	  continue
+	fi
+
+	func_dirname "$file" "" "."
+	dir="$func_dirname_result"
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  func_append dir "/$objdir"
+	else
+	  if test ! -f "$dir/$dlname"; then
+	    func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+	  fi
+	fi
 	;;
-    prog)
-	compile_deplibs=
-	finalize_deplibs=
-	alldeplibs=no
-	newdlfiles=
-	newdlprefiles=
-	passes="conv scan dlopen dlpreopen link"
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	func_dirname "$file" "" "."
+	dir="$func_dirname_result"
 	;;
-    *)  passes="conv"
+
+      *)
+	func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+	continue
 	;;
-    esac
-    for pass in $passes; do
-      if test "$linkmode,$pass" = "lib,link" ||
-	 test "$linkmode,$pass" = "prog,scan"; then
-	libs="$deplibs"
-	deplibs=
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
       fi
-      if test "$linkmode" = prog; then
-	case $pass in
-	dlopen) libs="$dlfiles" ;;
-	dlpreopen) libs="$dlprefiles" ;;
-	link)
-	  libs="$deplibs %DEPLIBS%"
-	  test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
-	  ;;
-	esac
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -* | *.la | *.lo ) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if func_ltwrapper_script_p "$file"; then
+	  func_source "$file"
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	elif func_ltwrapper_executable_p "$file"; then
+	  func_ltwrapper_scriptname "$file"
+	  func_source "$func_ltwrapper_scriptname_result"
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	fi
+	;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      func_append_quoted args "$file"
+    done
+
+    if test "X$opt_dry_run" = Xfalse; then
+      if test -n "$shlibpath_var"; then
+	# Export the shlibpath_var.
+	eval "export $shlibpath_var"
       fi
-      if test "$pass" = dlopen; then
-	# Collect dlpreopened libraries
-	save_deplibs="$deplibs"
-	deplibs=
+
+      # Restore saved environment variables
+      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+      do
+	eval "if test \"\${save_$lt_var+set}\" = set; then
+                $lt_var=\$save_$lt_var; export $lt_var
+	      else
+		$lt_unset $lt_var
+	      fi"
+      done
+
+      # Now prepare to actually exec the command.
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+	echo "export $shlibpath_var"
       fi
-      for deplib in $libs; do
-	lib=
-	found=no
-	case $deplib in
-	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
-	  if test "$linkmode,$pass" = "prog,link"; then
-	    compile_deplibs="$deplib $compile_deplibs"
-	    finalize_deplibs="$deplib $finalize_deplibs"
-	  else
-	    compiler_flags="$compiler_flags $deplib"
-	  fi
-	  continue
-	  ;;
-	-l*)
-	  if test "$linkmode" != lib && test "$linkmode" != prog; then
-	    $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2
-	    continue
-	  fi
-	  name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
-	  if test "$linkmode" = lib; then
-	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
-	  else
-	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
-	  fi
-	  for searchdir in $searchdirs; do
-	    for search_ext in .la $std_shrext .so .a; do
-	      # Search the libtool library
-	      lib="$searchdir/lib${name}${search_ext}"
-	      if test -f "$lib"; then
-		if test "$search_ext" = ".la"; then
-		  found=yes
-		else
-		  found=no
-		fi
-		break 2
-	      fi
-	    done
-	  done
-	  if test "$found" != yes; then
-	    # deplib doesn't seem to be a libtool library
-	    if test "$linkmode,$pass" = "prog,link"; then
-	      compile_deplibs="$deplib $compile_deplibs"
-	      finalize_deplibs="$deplib $finalize_deplibs"
-	    else
-	      deplibs="$deplib $deplibs"
-	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
-	    fi
-	    continue
-	  else # deplib is a libtool library
-	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
-	    # We need to do some special things here, and not later.
-	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
-	      case " $predeps $postdeps " in
-	      *" $deplib "*)
-		if (${SED} -e '2q' $lib |
-                    grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-		  library_names=
-		  old_library=
-		  case $lib in
-		  */* | *\\*) . $lib ;;
-		  *) . ./$lib ;;
-		  esac
-		  for l in $old_library $library_names; do
-		    ll="$l"
-		  done
-		  if test "X$ll" = "X$old_library" ; then # only static version available
-		    found=no
-		    ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
-		    test "X$ladir" = "X$lib" && ladir="."
-		    lib=$ladir/$old_library
-		    if test "$linkmode,$pass" = "prog,link"; then
-		      compile_deplibs="$deplib $compile_deplibs"
-		      finalize_deplibs="$deplib $finalize_deplibs"
-		    else
-		      deplibs="$deplib $deplibs"
-		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
-		    fi
-		    continue
-		  fi
-		fi
-	        ;;
-	      *) ;;
-	      esac
-	    fi
-	  fi
-	  ;; # -l
-	-L*)
-	  case $linkmode in
-	  lib)
-	    deplibs="$deplib $deplibs"
-	    test "$pass" = conv && continue
-	    newdependency_libs="$deplib $newdependency_libs"
-	    newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
-	    ;;
-	  prog)
-	    if test "$pass" = conv; then
-	      deplibs="$deplib $deplibs"
-	      continue
-	    fi
-	    if test "$pass" = scan; then
-	      deplibs="$deplib $deplibs"
-	    else
-	      compile_deplibs="$deplib $compile_deplibs"
-	      finalize_deplibs="$deplib $finalize_deplibs"
-	    fi
-	    newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
-	    ;;
-	  *)
-	    $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2
-	    ;;
-	  esac # linkmode
-	  continue
-	  ;; # -L
-	-R*)
-	  if test "$pass" = link; then
-	    dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
-	    # Make sure the xrpath contains only unique directories.
-	    case "$xrpath " in
-	    *" $dir "*) ;;
-	    *) xrpath="$xrpath $dir" ;;
-	    esac
-	  fi
-	  deplibs="$deplib $deplibs"
-	  continue
-	  ;;
-	*.la) lib="$deplib" ;;
-	*.$libext)
-	  if test "$pass" = conv; then
-	    deplibs="$deplib $deplibs"
-	    continue
-	  fi
-	  case $linkmode in
-	  lib)
-	    valid_a_lib=no
-	    case $deplibs_check_method in
-	      match_pattern*)
-		set dummy $deplibs_check_method
-	        match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
-		if eval $echo \"$deplib\" 2>/dev/null \
-		    | $SED 10q \
-		    | $EGREP "$match_pattern_regex" > /dev/null; then
-		  valid_a_lib=yes
-		fi
-		;;
-	      pass_all)
-		valid_a_lib=yes
-		;;
-            esac
-	    if test "$valid_a_lib" != yes; then
-	      $echo
-	      $echo "*** Warning: Trying to link with static lib archive $deplib."
-	      $echo "*** I have the capability to make that library automatically link in when"
-	      $echo "*** you link to this library.  But I can only do this if you have a"
-	      $echo "*** shared version of the library, which you do not appear to have"
-	      $echo "*** because the file extensions .$libext of this argument makes me believe"
-	      $echo "*** that it is just a static archive that I should not used here."
-	    else
-	      $echo
-	      $echo "*** Warning: Linking the shared library $output against the"
-	      $echo "*** static library $deplib is not portable!"
-	      deplibs="$deplib $deplibs"
-	    fi
-	    continue
-	    ;;
-	  prog)
-	    if test "$pass" != link; then
-	      deplibs="$deplib $deplibs"
-	    else
-	      compile_deplibs="$deplib $compile_deplibs"
-	      finalize_deplibs="$deplib $finalize_deplibs"
-	    fi
-	    continue
-	    ;;
-	  esac # linkmode
-	  ;; # *.$libext
-	*.lo | *.$objext)
-	  if test "$pass" = conv; then
-	    deplibs="$deplib $deplibs"
-	  elif test "$linkmode" = prog; then
-	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
-	      # If there is no dlopen support or we're linking statically,
-	      # we need to preload.
-	      newdlprefiles="$newdlprefiles $deplib"
-	      compile_deplibs="$deplib $compile_deplibs"
-	      finalize_deplibs="$deplib $finalize_deplibs"
-	    else
-	      newdlfiles="$newdlfiles $deplib"
-	    fi
-	  fi
-	  continue
-	  ;;
-	%DEPLIBS%)
-	  alldeplibs=yes
-	  continue
-	  ;;
-	esac # case $deplib
-	if test "$found" = yes || test -f "$lib"; then :
-	else
-	  $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2
-	  exit $EXIT_FAILURE
-	fi
-
-	# Check to see that this really is a libtool archive.
-	if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
-	else
-	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
-	  exit $EXIT_FAILURE
-	fi
+      $ECHO "$cmd$args"
+      exit $EXIT_SUCCESS
+    fi
+}
 
-	ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
-	test "X$ladir" = "X$lib" && ladir="."
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
 
-	dlname=
-	dlopen=
-	dlpreopen=
-	libdir=
-	library_names=
-	old_library=
-	# If the library was installed with an old release of libtool,
-	# it will not redefine variables installed, or shouldnotlink
-	installed=yes
-	shouldnotlink=no
-	avoidtemprpath=
 
+# func_mode_finish arg...
+func_mode_finish ()
+{
+    $opt_debug
+    libs=
+    libdirs=
+    admincmds=
 
-	# Read the .la file
-	case $lib in
-	*/* | *\\*) . $lib ;;
-	*) . ./$lib ;;
-	esac
+    for opt in "$nonopt" ${1+"$@"}
+    do
+      if test -d "$opt"; then
+	func_append libdirs " $opt"
 
-	if test "$linkmode,$pass" = "lib,link" ||
-	   test "$linkmode,$pass" = "prog,scan" ||
-	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
-	  test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
-	  test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+      elif test -f "$opt"; then
+	if func_lalib_unsafe_p "$opt"; then
+	  func_append libs " $opt"
+	else
+	  func_warning "\`$opt' is not a valid libtool archive"
 	fi
 
-	if test "$pass" = conv; then
-	  # Only check for convenience libraries
-	  deplibs="$lib $deplibs"
-	  if test -z "$libdir"; then
-	    if test -z "$old_library"; then
-	      $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
-	      exit $EXIT_FAILURE
-	    fi
-	    # It is a libtool convenience library, so add in its objects.
-	    convenience="$convenience $ladir/$objdir/$old_library"
-	    old_convenience="$old_convenience $ladir/$objdir/$old_library"
-	    tmp_libs=
-	    for deplib in $dependency_libs; do
-	      deplibs="$deplib $deplibs"
-              if test "X$duplicate_deps" = "Xyes" ; then
-	        case "$tmp_libs " in
-	        *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-	        esac
-              fi
-	      tmp_libs="$tmp_libs $deplib"
-	    done
-	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
-	    $echo "$modename: \`$lib' is not a convenience library" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-	  continue
-	fi # $pass = conv
+      else
+	func_fatal_error "invalid argument \`$opt'"
+      fi
+    done
 
+    if test -n "$libs"; then
+      if test -n "$lt_sysroot"; then
+        sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+        sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+      else
+        sysroot_cmd=
+      fi
 
-	# Get the name of the library we link against.
-	linklib=
-	for l in $old_library $library_names; do
-	  linklib="$l"
+      # Remove sysroot references
+      if $opt_dry_run; then
+        for lib in $libs; do
+          echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
+        done
+      else
+        tmpdir=`func_mktempdir`
+        for lib in $libs; do
+	  sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+	    > $tmpdir/tmp-la
+	  mv -f $tmpdir/tmp-la $lib
 	done
-	if test -z "$linklib"; then
-	  $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
-	  exit $EXIT_FAILURE
+        ${RM}r "$tmpdir"
+      fi
+    fi
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
 	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $opt_dry_run || eval "$cmds" || func_append admincmds "
+       $cmds"
+	fi
+      done
+    fi
 
-	# This library was specified with -dlopen.
-	if test "$pass" = dlopen; then
-	  if test -z "$libdir"; then
-	    $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-	  if test -z "$dlname" ||
-	     test "$dlopen_support" != yes ||
-	     test "$build_libtool_libs" = no; then
-	    # If there is no dlname, no dlopen support or we're linking
-	    # statically, we need to preload.  We also need to preload any
-	    # dependent libraries so libltdl's deplib preloader doesn't
-	    # bomb out in the load deplibs phase.
-	    dlprefiles="$dlprefiles $lib $dependency_libs"
-	  else
-	    newdlfiles="$newdlfiles $lib"
-	  fi
-	  continue
-	fi # $pass = dlopen
+    # Exit here if they wanted silent mode.
+    $opt_silent && exit $EXIT_SUCCESS
 
-	# We need an absolute path.
-	case $ladir in
-	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
-	*)
-	  abs_ladir=`cd "$ladir" && pwd`
-	  if test -z "$abs_ladir"; then
-	    $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2
-	    $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
-	    abs_ladir="$ladir"
-	  fi
-	  ;;
-	esac
-	laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      echo "----------------------------------------------------------------------"
+      echo "Libraries have been installed in:"
+      for libdir in $libdirs; do
+	$ECHO "   $libdir"
+      done
+      echo
+      echo "If you ever happen to want to link against installed libraries"
+      echo "in a given directory, LIBDIR, you must either use libtool, and"
+      echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+      echo "flag during linking and do at least one of the following:"
+      if test -n "$shlibpath_var"; then
+	echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+	echo "     during execution"
+      fi
+      if test -n "$runpath_var"; then
+	echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+	echo "     during linking"
+      fi
+      if test -n "$hardcode_libdir_flag_spec"; then
+	libdir=LIBDIR
+	eval flag=\"$hardcode_libdir_flag_spec\"
 
-	# Find the relevant object directory and library name.
-	if test "X$installed" = Xyes; then
-	  if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
-	    $echo "$modename: warning: library \`$lib' was moved." 1>&2
-	    dir="$ladir"
-	    absdir="$abs_ladir"
-	    libdir="$abs_ladir"
-	  else
-	    dir="$libdir"
-	    absdir="$libdir"
-	  fi
-	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
-	else
-	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
-	    dir="$ladir"
-	    absdir="$abs_ladir"
-	    # Remove this search path later
-	    notinst_path="$notinst_path $abs_ladir"
-	  else
-	    dir="$ladir/$objdir"
-	    absdir="$abs_ladir/$objdir"
-	    # Remove this search path later
-	    notinst_path="$notinst_path $abs_ladir"
-	  fi
-	fi # $installed = yes
-	name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+	$ECHO "   - use the \`$flag' linker flag"
+      fi
+      if test -n "$admincmds"; then
+	$ECHO "   - have your system administrator run these commands:$admincmds"
+      fi
+      if test -f /etc/ld.so.conf; then
+	echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+      fi
+      echo
 
-	# This library was specified with -dlpreopen.
-	if test "$pass" = dlpreopen; then
-	  if test -z "$libdir"; then
-	    $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-	  # Prefer using a static library (so that no silly _DYNAMIC symbols
-	  # are required to link).
-	  if test -n "$old_library"; then
-	    newdlprefiles="$newdlprefiles $dir/$old_library"
-	  # Otherwise, use the dlname, so that lt_dlopen finds it.
-	  elif test -n "$dlname"; then
-	    newdlprefiles="$newdlprefiles $dir/$dlname"
-	  else
-	    newdlprefiles="$newdlprefiles $dir/$linklib"
-	  fi
-	fi # $pass = dlpreopen
+      echo "See any operating system documentation about shared libraries for"
+      case $host in
+	solaris2.[6789]|solaris2.1[0-9])
+	  echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+	  echo "pages."
+	  ;;
+	*)
+	  echo "more information, such as the ld(1) and ld.so(8) manual pages."
+	  ;;
+      esac
+      echo "----------------------------------------------------------------------"
+    fi
+    exit $EXIT_SUCCESS
+}
 
-	if test -z "$libdir"; then
-	  # Link the convenience library
-	  if test "$linkmode" = lib; then
-	    deplibs="$dir/$old_library $deplibs"
-	  elif test "$linkmode,$pass" = "prog,link"; then
-	    compile_deplibs="$dir/$old_library $compile_deplibs"
-	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
-	  else
-	    deplibs="$lib $deplibs" # used for prog,scan pass
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+    $opt_debug
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+       # Allow the use of GNU shtool's install command.
+       case $nonopt in *shtool*) :;; *) false;; esac; then
+      # Aesthetically quote it.
+      func_quote_for_eval "$nonopt"
+      install_prog="$func_quote_for_eval_result "
+      arg=$1
+      shift
+    else
+      install_prog=
+      arg=$nonopt
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    func_quote_for_eval "$arg"
+    func_append install_prog "$func_quote_for_eval_result"
+    install_shared_prog=$install_prog
+    case " $install_prog " in
+      *[\\\ /]cp\ *) install_cp=: ;;
+      *) install_cp=false ;;
+    esac
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    no_mode=:
+    for arg
+    do
+      arg2=
+      if test -n "$dest"; then
+	func_append files " $dest"
+	dest=$arg
+	continue
+      fi
+
+      case $arg in
+      -d) isdir=yes ;;
+      -f)
+	if $install_cp; then :; else
+	  prev=$arg
+	fi
+	;;
+      -g | -m | -o)
+	prev=$arg
+	;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*)
+	;;
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  if test "x$prev" = x-m && test -n "$install_override_mode"; then
+	    arg2=$install_override_mode
+	    no_mode=false
 	  fi
+	  prev=
+	else
+	  dest=$arg
 	  continue
 	fi
+	;;
+      esac
 
+      # Aesthetically quote the argument.
+      func_quote_for_eval "$arg"
+      func_append install_prog " $func_quote_for_eval_result"
+      if test -n "$arg2"; then
+	func_quote_for_eval "$arg2"
+      fi
+      func_append install_shared_prog " $func_quote_for_eval_result"
+    done
 
-	if test "$linkmode" = prog && test "$pass" != link; then
-	  newlib_search_path="$newlib_search_path $ladir"
-	  deplibs="$lib $deplibs"
+    test -z "$install_prog" && \
+      func_fatal_help "you must specify an install program"
 
-	  linkalldeplibs=no
-	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
-	     test "$build_libtool_libs" = no; then
-	    linkalldeplibs=yes
-	  fi
+    test -n "$prev" && \
+      func_fatal_help "the \`$prev' option requires an argument"
 
-	  tmp_libs=
-	  for deplib in $dependency_libs; do
-	    case $deplib in
-	    -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
-	    esac
-	    # Need to link against all dependency_libs?
-	    if test "$linkalldeplibs" = yes; then
-	      deplibs="$deplib $deplibs"
-	    else
-	      # Need to hardcode shared library paths
-	      # or/and link against static libraries
-	      newdependency_libs="$deplib $newdependency_libs"
-	    fi
-	    if test "X$duplicate_deps" = "Xyes" ; then
-	      case "$tmp_libs " in
-	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-	      esac
-	    fi
-	    tmp_libs="$tmp_libs $deplib"
-	  done # for deplib
-	  continue
-	fi # $linkmode = prog...
+    if test -n "$install_override_mode" && $no_mode; then
+      if $install_cp; then :; else
+	func_quote_for_eval "$install_override_mode"
+	func_append install_shared_prog " -m $func_quote_for_eval_result"
+      fi
+    fi
 
-	if test "$linkmode,$pass" = "prog,link"; then
-	  if test -n "$library_names" &&
-	     { { test "$prefer_static_libs" = no ||
-		 test "$prefer_static_libs,$installed" = "built,yes"; } ||
-	       test -z "$old_library"; }; then
-	    # We need to hardcode the library path
-	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
-	      # Make sure the rpath contains only unique directories.
-	      case "$temp_rpath " in
-	      *" $dir "*) ;;
-	      *" $absdir "*) ;;
-	      *) temp_rpath="$temp_rpath $absdir" ;;
-	      esac
-	    fi
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	func_fatal_help "no file or destination specified"
+      else
+	func_fatal_help "you must specify a destination"
+      fi
+    fi
 
-	    # Hardcode the library path.
-	    # Skip directories that are in the system default run-time
-	    # search path.
-	    case " $sys_lib_dlsearch_path " in
-	    *" $absdir "*) ;;
-	    *)
-	      case "$compile_rpath " in
-	      *" $absdir "*) ;;
-	      *) compile_rpath="$compile_rpath $absdir"
-	      esac
-	      ;;
-	    esac
-	    case " $sys_lib_dlsearch_path " in
-	    *" $libdir "*) ;;
-	    *)
-	      case "$finalize_rpath " in
-	      *" $libdir "*) ;;
-	      *) finalize_rpath="$finalize_rpath $libdir"
-	      esac
-	      ;;
-	    esac
-	  fi # $linkmode,$pass = prog,link...
+    # Strip any trailing slash from the destination.
+    func_stripname '' '/' "$dest"
+    dest=$func_stripname_result
 
-	  if test "$alldeplibs" = yes &&
-	     { test "$deplibs_check_method" = pass_all ||
-	       { test "$build_libtool_libs" = yes &&
-		 test -n "$library_names"; }; }; then
-	    # We only need to search for static libraries
-	    continue
-	  fi
-	fi
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      func_dirname_and_basename "$dest" "" "."
+      destdir="$func_dirname_result"
+      destname="$func_basename_result"
 
-	link_static=no # Whether the deplib will be linked statically
-	use_static_libs=$prefer_static_libs
-	if test "$use_static_libs" = built && test "$installed" = yes ; then
-	  use_static_libs=no
-	fi
-	if test -n "$library_names" &&
-	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
-	  if test "$installed" = no; then
-	    notinst_deplibs="$notinst_deplibs $lib"
-	    need_relink=yes
-	  fi
-	  # This is a shared library
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files; shift
+      test "$#" -gt 1 && \
+	func_fatal_help "\`$dest' is not a directory"
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case $file in
+	*.lo) ;;
+	*)
+	  func_fatal_help "\`$destdir' must be an absolute directory name"
+	  ;;
+	esac
+      done
+      ;;
+    esac
 
-	  # Warn about portability, can't link against -module's on
-	  # some systems (darwin)
-	  if test "$shouldnotlink" = yes && test "$pass" = link ; then
-	    $echo
-	    if test "$linkmode" = prog; then
-	      $echo "*** Warning: Linking the executable $output against the loadable module"
-	    else
-	      $echo "*** Warning: Linking the shared library $output against the loadable module"
-	    fi
-	    $echo "*** $linklib is not portable!"
-	  fi
-	  if test "$linkmode" = lib &&
-	     test "$hardcode_into_libs" = yes; then
-	    # Hardcode the library path.
-	    # Skip directories that are in the system default run-time
-	    # search path.
-	    case " $sys_lib_dlsearch_path " in
-	    *" $absdir "*) ;;
-	    *)
-	      case "$compile_rpath " in
-	      *" $absdir "*) ;;
-	      *) compile_rpath="$compile_rpath $absdir"
-	      esac
-	      ;;
-	    esac
-	    case " $sys_lib_dlsearch_path " in
-	    *" $libdir "*) ;;
-	    *)
-	      case "$finalize_rpath " in
-	      *" $libdir "*) ;;
-	      *) finalize_rpath="$finalize_rpath $libdir"
-	      esac
-	      ;;
-	    esac
-	  fi
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
 
-	  if test -n "$old_archive_from_expsyms_cmds"; then
-	    # figure out the soname
-	    set dummy $library_names
-	    realname="$2"
-	    shift; shift
-	    libname=`eval \\$echo \"$libname_spec\"`
-	    # use dlname if we got it. it's perfectly good, no?
-	    if test -n "$dlname"; then
-	      soname="$dlname"
-	    elif test -n "$soname_spec"; then
-	      # bleh windows
-	      case $host in
-	      *cygwin* | mingw*)
-		major=`expr $current - $age`
-		versuffix="-$major"
-		;;
-	      esac
-	      eval soname=\"$soname_spec\"
-	    else
-	      soname="$realname"
-	    fi
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
 
-	    # Make a new name for the extract_expsyms_cmds to use
-	    soroot="$soname"
-	    soname=`$echo $soroot | ${SED} -e 's/^.*\///'`
-	    newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a"
+      # Do each installation.
+      case $file in
+      *.$libext)
+	# Do the static libraries later.
+	func_append staticlibs " $file"
+	;;
 
-	    # If the library has no export list, then create one now
-	    if test -f "$output_objdir/$soname-def"; then :
-	    else
-	      $show "extracting exported symbol list from \`$soname'"
-	      save_ifs="$IFS"; IFS='~'
-	      cmds=$extract_expsyms_cmds
-	      for cmd in $cmds; do
-		IFS="$save_ifs"
-		eval cmd=\"$cmd\"
-		$show "$cmd"
-		$run eval "$cmd" || exit $?
-	      done
-	      IFS="$save_ifs"
-	    fi
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
 
-	    # Create $newlib
-	    if test -f "$output_objdir/$newlib"; then :; else
-	      $show "generating import library for \`$soname'"
-	      save_ifs="$IFS"; IFS='~'
-	      cmds=$old_archive_from_expsyms_cmds
-	      for cmd in $cmds; do
-		IFS="$save_ifs"
-		eval cmd=\"$cmd\"
-		$show "$cmd"
-		$run eval "$cmd" || exit $?
-	      done
-	      IFS="$save_ifs"
-	    fi
-	    # make sure the library variables are pointing to the new library
-	    dir=$output_objdir
-	    linklib=$newlib
-	  fi # test -n "$old_archive_from_expsyms_cmds"
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "\`$file' is not a valid libtool archive"
 
-	  if test "$linkmode" = prog || test "$mode" != relink; then
-	    add_shlibpath=
-	    add_dir=
-	    add=
-	    lib_linked=yes
-	    case $hardcode_action in
-	    immediate | unsupported)
-	      if test "$hardcode_direct" = no; then
-		add="$dir/$linklib"
-		case $host in
-		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
-		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
-		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
-		    *-*-unixware7*) add_dir="-L$dir" ;;
-		  *-*-darwin* )
-		    # if the lib is a module then we can not link against
-		    # it, someone is ignoring the new warnings I added
-		    if /usr/bin/file -L $add 2> /dev/null |
-                      $EGREP ": [^:]* bundle" >/dev/null ; then
-		      $echo "** Warning, lib $linklib is a module, not a shared library"
-		      if test -z "$old_library" ; then
-		        $echo
-		        $echo "** And there doesn't seem to be a static archive available"
-		        $echo "** The link will probably fail, sorry"
-		      else
-		        add="$dir/$old_library"
-		      fi
-		    fi
-		esac
-	      elif test "$hardcode_minus_L" = no; then
-		case $host in
-		*-*-sunos*) add_shlibpath="$dir" ;;
-		esac
-		add_dir="-L$dir"
-		add="-l$name"
-	      elif test "$hardcode_shlibpath_var" = no; then
-		add_shlibpath="$dir"
-		add="-l$name"
-	      else
-		lib_linked=no
-	      fi
-	      ;;
-	    relink)
-	      if test "$hardcode_direct" = yes; then
-		add="$dir/$linklib"
-	      elif test "$hardcode_minus_L" = yes; then
-		add_dir="-L$dir"
-		# Try looking first in the location we're being installed to.
-		if test -n "$inst_prefix_dir"; then
-		  case $libdir in
-		    [\\/]*)
-		      add_dir="$add_dir -L$inst_prefix_dir$libdir"
-		      ;;
-		  esac
-		fi
-		add="-l$name"
-	      elif test "$hardcode_shlibpath_var" = yes; then
-		add_shlibpath="$dir"
-		add="-l$name"
-	      else
-		lib_linked=no
-	      fi
-	      ;;
-	    *) lib_linked=no ;;
-	    esac
+	library_names=
+	old_library=
+	relink_command=
+	func_source "$file"
 
-	    if test "$lib_linked" != yes; then
-	      $echo "$modename: configuration error: unsupported hardcode properties"
-	      exit $EXIT_FAILURE
-	    fi
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append current_libdirs " $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append future_libdirs " $libdir" ;;
+	  esac
+	fi
 
-	    if test -n "$add_shlibpath"; then
-	      case :$compile_shlibpath: in
-	      *":$add_shlibpath:"*) ;;
-	      *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
-	      esac
-	    fi
-	    if test "$linkmode" = prog; then
-	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
-	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
-	    else
-	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
-	      test -n "$add" && deplibs="$add $deplibs"
-	      if test "$hardcode_direct" != yes && \
-		 test "$hardcode_minus_L" != yes && \
-		 test "$hardcode_shlibpath_var" = yes; then
-		case :$finalize_shlibpath: in
-		*":$libdir:"*) ;;
-		*) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
-		esac
-	      fi
-	    fi
-	  fi
+	func_dirname "$file" "/" ""
+	dir="$func_dirname_result"
+	func_append dir "$objdir"
 
-	  if test "$linkmode" = prog || test "$mode" = relink; then
-	    add_shlibpath=
-	    add_dir=
-	    add=
-	    # Finalize command for both is simple: just hardcode it.
-	    if test "$hardcode_direct" = yes; then
-	      add="$libdir/$linklib"
-	    elif test "$hardcode_minus_L" = yes; then
-	      add_dir="-L$libdir"
-	      add="-l$name"
-	    elif test "$hardcode_shlibpath_var" = yes; then
-	      case :$finalize_shlibpath: in
-	      *":$libdir:"*) ;;
-	      *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
-	      esac
-	      add="-l$name"
-	    elif test "$hardcode_automatic" = yes; then
-	      if test -n "$inst_prefix_dir" &&
-		 test -f "$inst_prefix_dir$libdir/$linklib" ; then
-	        add="$inst_prefix_dir$libdir/$linklib"
-	      else
-	        add="$libdir/$linklib"
-	      fi
-	    else
-	      # We cannot seem to hardcode it, guess we'll fake it.
-	      add_dir="-L$libdir"
-	      # Try looking first in the location we're being installed to.
-	      if test -n "$inst_prefix_dir"; then
-		case $libdir in
-		  [\\/]*)
-		    add_dir="$add_dir -L$inst_prefix_dir$libdir"
-		    ;;
-		esac
-	      fi
-	      add="-l$name"
-	    fi
+	if test -n "$relink_command"; then
+	  # Determine the prefix the user has applied to our future dir.
+	  inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
 
-	    if test "$linkmode" = prog; then
-	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
-	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
-	    else
-	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
-	      test -n "$add" && deplibs="$add $deplibs"
-	    fi
-	  fi
-	elif test "$linkmode" = prog; then
-	  # Here we assume that one of hardcode_direct or hardcode_minus_L
-	  # is not unsupported.  This is valid on all known static and
-	  # shared platforms.
-	  if test "$hardcode_direct" != unsupported; then
-	    test -n "$old_library" && linklib="$old_library"
-	    compile_deplibs="$dir/$linklib $compile_deplibs"
-	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
+	  # Don't allow the user to place us outside of our expected
+	  # location b/c this prevents finding dependent libraries that
+	  # are installed to the same prefix.
+	  # At present, this check doesn't affect windows .dll's that
+	  # are installed into $libdir/../bin (currently, that works fine)
+	  # but it's something to keep an eye on.
+	  test "$inst_prefix_dir" = "$destdir" && \
+	    func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+	  if test -n "$inst_prefix_dir"; then
+	    # Stick the inst_prefix_dir data into the link command.
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
 	  else
-	    compile_deplibs="-l$name -L$dir $compile_deplibs"
-	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
 	  fi
-	elif test "$build_libtool_libs" = yes; then
-	  # Not a shared library
-	  if test "$deplibs_check_method" != pass_all; then
-	    # We're trying link a shared library against a static one
-	    # but the system doesn't support it.
 
-	    # Just print a warning and add the library to dependency_libs so
-	    # that the program can be linked against the static library.
-	    $echo
-	    $echo "*** Warning: This system can not link to static lib archive $lib."
-	    $echo "*** I have the capability to make that library automatically link in when"
-	    $echo "*** you link to this library.  But I can only do this if you have a"
-	    $echo "*** shared version of the library, which you do not appear to have."
-	    if test "$module" = yes; then
-	      $echo "*** But as you try to build a module library, libtool will still create "
-	      $echo "*** a static module, that should work as long as the dlopening application"
-	      $echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
-	      if test -z "$global_symbol_pipe"; then
-		$echo
-		$echo "*** However, this would only work if libtool was able to extract symbol"
-		$echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
-		$echo "*** not find such a program.  So, this module is probably useless."
-		$echo "*** \`nm' from GNU binutils and a full rebuild may help."
-	      fi
-	      if test "$build_old_libs" = no; then
-		build_libtool_libs=module
-		build_old_libs=yes
-	      else
-		build_libtool_libs=no
-	      fi
-	    fi
-	  else
-	    deplibs="$dir/$old_library $deplibs"
-	    link_static=yes
+	  func_warning "relinking \`$file'"
+	  func_show_eval "$relink_command" \
+	    'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+	fi
+
+	# See the names of the shared library.
+	set dummy $library_names; shift
+	if test -n "$1"; then
+	  realname="$1"
+	  shift
+
+	  srcname="$realname"
+	  test -n "$relink_command" && srcname="$realname"T
+
+	  # Install the shared library and build the symlinks.
+	  func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+	      'exit $?'
+	  tstripme="$stripme"
+	  case $host_os in
+	  cygwin* | mingw* | pw32* | cegcc*)
+	    case $realname in
+	    *.dll.a)
+	      tstripme=""
+	      ;;
+	    esac
+	    ;;
+	  esac
+	  if test -n "$tstripme" && test -n "$striplib"; then
+	    func_show_eval "$striplib $destdir/$realname" 'exit $?'
 	  fi
-	fi # link shared/static library?
 
-	if test "$linkmode" = lib; then
-	  if test -n "$dependency_libs" &&
-	     { test "$hardcode_into_libs" != yes ||
-	       test "$build_old_libs" = yes ||
-	       test "$link_static" = yes; }; then
-	    # Extract -R from dependency_libs
-	    temp_deplibs=
-	    for libdir in $dependency_libs; do
-	      case $libdir in
-	      -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'`
-		   case " $xrpath " in
-		   *" $temp_xrpath "*) ;;
-		   *) xrpath="$xrpath $temp_xrpath";;
-		   esac;;
-	      *) temp_deplibs="$temp_deplibs $libdir";;
-	      esac
+	  if test "$#" -gt 0; then
+	    # Delete the old symlinks, and create new ones.
+	    # Try `ln -sf' first, because the `ln' binary might depend on
+	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
+	    # so we also need to try rm && ln -s.
+	    for linkname
+	    do
+	      test "$linkname" != "$realname" \
+		&& func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
 	    done
-	    dependency_libs="$temp_deplibs"
 	  fi
 
-	  newlib_search_path="$newlib_search_path $absdir"
-	  # Link against this library
-	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
-	  # ... and its dependency_libs
-	  tmp_libs=
-	  for deplib in $dependency_libs; do
-	    newdependency_libs="$deplib $newdependency_libs"
-	    if test "X$duplicate_deps" = "Xyes" ; then
-	      case "$tmp_libs " in
-	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-	      esac
-	    fi
-	    tmp_libs="$tmp_libs $deplib"
-	  done
+	  # Do each command in the postinstall commands.
+	  lib="$destdir/$realname"
+	  func_execute_cmds "$postinstall_cmds" 'exit $?'
+	fi
 
-	  if test "$link_all_deplibs" != no; then
-	    # Add the search paths of all dependency libraries
-	    for deplib in $dependency_libs; do
-	      case $deplib in
-	      -L*) path="$deplib" ;;
-	      *.la)
-		dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
-		test "X$dir" = "X$deplib" && dir="."
-		# We need an absolute path.
-		case $dir in
-		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
-		*)
-		  absdir=`cd "$dir" && pwd`
-		  if test -z "$absdir"; then
-		    $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
-		    absdir="$dir"
-		  fi
-		  ;;
-		esac
-		if grep "^installed=no" $deplib > /dev/null; then
-		  path="$absdir/$objdir"
-		else
-		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
-		  if test -z "$libdir"; then
-		    $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
-		    exit $EXIT_FAILURE
-		  fi
-		  if test "$absdir" != "$libdir"; then
-		    $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
-		  fi
-		  path="$absdir"
-		fi
-		depdepl=
-		case $host in
-		*-*-darwin*)
-		  # we do not want to link against static libs,
-		  # but need to link against shared
-		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
-		  eval deplibdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
-		  if test -n "$deplibrary_names" ; then
-		    for tmp in $deplibrary_names ; do
-		      depdepl=$tmp
-		    done
-		    if test -f "$deplibdir/$depdepl" ; then
-		      depdepl="$deplibdir/$depdepl"
-	      	    elif test -f "$path/$depdepl" ; then
-		      depdepl="$path/$depdepl"
-		    else
-		      # Can't find it, oh well...
-		      depdepl=
-		    fi
-		    # do not add paths which are already there
-		    case " $newlib_search_path " in
-		    *" $path "*) ;;
-		    *) newlib_search_path="$newlib_search_path $path";;
-		    esac
-		  fi
-		  path=""
-		  ;;
-		*)
-		  path="-L$path"
-		  ;;
-		esac
-		;;
-	      -l*)
-		case $host in
-		*-*-darwin*)
-		  # Again, we only want to link against shared libraries
-		  eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"`
-		  for tmp in $newlib_search_path ; do
-		    if test -f "$tmp/lib$tmp_libs.dylib" ; then
-		      eval depdepl="$tmp/lib$tmp_libs.dylib"
-		      break
-		    fi
-		  done
-		  path=""
-		  ;;
-		*) continue ;;
-		esac
-		;;
-	      *) continue ;;
-	      esac
-	      case " $deplibs " in
-	      *" $path "*) ;;
-	      *) deplibs="$path $deplibs" ;;
-	      esac
-	      case " $deplibs " in
-	      *" $depdepl "*) ;;
-	      *) deplibs="$depdepl $deplibs" ;;
-	      esac
-	    done
-	  fi # link_all_deplibs != no
-	fi # linkmode = lib
-      done # for deplib in $libs
-      dependency_libs="$newdependency_libs"
-      if test "$pass" = dlpreopen; then
-	# Link the dlpreopened libraries before other libraries
-	for deplib in $save_deplibs; do
-	  deplibs="$deplib $deplibs"
-	done
-      fi
-      if test "$pass" != dlopen; then
-	if test "$pass" != conv; then
-	  # Make sure lib_search_path contains only unique directories.
-	  lib_search_path=
-	  for dir in $newlib_search_path; do
-	    case "$lib_search_path " in
-	    *" $dir "*) ;;
-	    *) lib_search_path="$lib_search_path $dir" ;;
-	    esac
-	  done
-	  newlib_search_path=
-	fi
+	# Install the pseudo-library for information purposes.
+	func_basename "$file"
+	name="$func_basename_result"
+	instname="$dir/$name"i
+	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
 
-	if test "$linkmode,$pass" != "prog,link"; then
-	  vars="deplibs"
+	# Maybe install the static library, too.
+	test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+	;;
+
+      *.lo)
+	# Install (i.e. copy) a libtool object.
+
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
 	else
-	  vars="compile_deplibs finalize_deplibs"
+	  func_basename "$file"
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
 	fi
-	for var in $vars dependency_libs; do
-	  # Add libraries to $var in reverse order
-	  eval tmp_libs=\"\$$var\"
-	  new_libs=
-	  for deplib in $tmp_libs; do
-	    # FIXME: Pedantically, this is the right thing to do, so
-	    #        that some nasty dependency loop isn't accidentally
-	    #        broken:
-	    #new_libs="$deplib $new_libs"
-	    # Pragmatically, this seems to cause very few problems in
-	    # practice:
-	    case $deplib in
-	    -L*) new_libs="$deplib $new_libs" ;;
-	    -R*) ;;
-	    *)
-	      # And here is the reason: when a library appears more
-	      # than once as an explicit dependence of a library, or
-	      # is implicitly linked in more than once by the
-	      # compiler, it is considered special, and multiple
-	      # occurrences thereof are not removed.  Compare this
-	      # with having the same library being listed as a
-	      # dependency of multiple other libraries: in this case,
-	      # we know (pedantically, we assume) the library does not
-	      # need to be listed more than once, so we keep only the
-	      # last copy.  This is not always right, but it is rare
-	      # enough that we require users that really mean to play
-	      # such unportable linking tricks to link the library
-	      # using -Wl,-lname, so that libtool does not consider it
-	      # for duplicate removal.
-	      case " $specialdeplibs " in
-	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
-	      *)
-		case " $new_libs " in
-		*" $deplib "*) ;;
-		*) new_libs="$deplib $new_libs" ;;
-		esac
-		;;
-	      esac
-	      ;;
-	    esac
-	  done
-	  tmp_libs=
-	  for deplib in $new_libs; do
-	    case $deplib in
-	    -L*)
-	      case " $tmp_libs " in
-	      *" $deplib "*) ;;
-	      *) tmp_libs="$tmp_libs $deplib" ;;
-	      esac
-	      ;;
-	    *) tmp_libs="$tmp_libs $deplib" ;;
-	    esac
-	  done
-	  eval $var=\"$tmp_libs\"
-	done # for var
-      fi
-      # Last step: remove runtime libs from dependency_libs
-      # (they stay in deplibs)
-      tmp_libs=
-      for i in $dependency_libs ; do
-	case " $predeps $postdeps $compiler_lib_search_path " in
-	*" $i "*)
-	  i=""
+
+	# Deduce the name of the destination old-style object file.
+	case $destfile in
+	*.lo)
+	  func_lo2o "$destfile"
+	  staticdest=$func_lo2o_result
+	  ;;
+	*.$objext)
+	  staticdest="$destfile"
+	  destfile=
+	  ;;
+	*)
+	  func_fatal_help "cannot copy a libtool object to \`$destfile'"
 	  ;;
 	esac
-	if test -n "$i" ; then
-	  tmp_libs="$tmp_libs $i"
-	fi
-      done
-      dependency_libs=$tmp_libs
-    done # for pass
-    if test "$linkmode" = prog; then
-      dlfiles="$newdlfiles"
-      dlprefiles="$newdlprefiles"
-    fi
 
-    case $linkmode in
-    oldlib)
-      case " $deplibs" in
-      *\ -l* | *\ -L*)
-	$echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 ;;
-      esac
+	# Install the libtool object if requested.
+	test -n "$destfile" && \
+	  func_show_eval "$install_prog $file $destfile" 'exit $?'
 
-      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
-	$echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
-      fi
+	# Install the old object if enabled.
+	if test "$build_old_libs" = yes; then
+	  # Deduce the name of the old-style object file.
+	  func_lo2o "$file"
+	  staticobj=$func_lo2o_result
+	  func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+	fi
+	exit $EXIT_SUCCESS
+	;;
 
-      if test -n "$rpath"; then
-	$echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
-      fi
+      *)
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  func_basename "$file"
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
+	fi
 
-      if test -n "$xrpath"; then
-	$echo "$modename: warning: \`-R' is ignored for archives" 1>&2
-      fi
+	# If the file is missing, and there is a .exe on the end, strip it
+	# because it is most likely a libtool script we actually want to
+	# install
+	stripped_ext=""
+	case $file in
+	  *.exe)
+	    if test ! -f "$file"; then
+	      func_stripname '' '.exe' "$file"
+	      file=$func_stripname_result
+	      stripped_ext=".exe"
+	    fi
+	    ;;
+	esac
 
-      if test -n "$vinfo"; then
-	$echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2
-      fi
+	# Do a test to see if this is really a libtool program.
+	case $host in
+	*cygwin* | *mingw*)
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      wrapper=$func_ltwrapper_scriptname_result
+	    else
+	      func_stripname '' '.exe' "$file"
+	      wrapper=$func_stripname_result
+	    fi
+	    ;;
+	*)
+	    wrapper=$file
+	    ;;
+	esac
+	if func_ltwrapper_script_p "$wrapper"; then
+	  notinst_deplibs=
+	  relink_command=
 
-      if test -n "$release"; then
-	$echo "$modename: warning: \`-release' is ignored for archives" 1>&2
-      fi
+	  func_source "$wrapper"
 
-      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
-	$echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
-      fi
+	  # Check the variables that should have been set.
+	  test -z "$generated_by_libtool_version" && \
+	    func_fatal_error "invalid libtool wrapper script \`$wrapper'"
 
-      # Now set the variables for building old libraries.
-      build_libtool_libs=no
-      oldlibs="$output"
-      objs="$objs$old_deplibs"
-      ;;
+	  finalize=yes
+	  for lib in $notinst_deplibs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      func_source "$lib"
+	    fi
+	    libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      func_warning "\`$lib' has not been installed in \`$libdir'"
+	      finalize=no
+	    fi
+	  done
 
-    lib)
-      # Make sure we only generate libraries of the form `libNAME.la'.
-      case $outputname in
-      lib*)
-	name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
-	eval shared_ext=\"$shrext_cmds\"
-	eval libname=\"$libname_spec\"
-	;;
-      *)
-	if test "$module" = no; then
-	  $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
-	  $echo "$help" 1>&2
-	  exit $EXIT_FAILURE
+	  relink_command=
+	  func_source "$wrapper"
+
+	  outputname=
+	  if test "$fast_install" = no && test -n "$relink_command"; then
+	    $opt_dry_run || {
+	      if test "$finalize" = yes; then
+	        tmpdir=`func_mktempdir`
+		func_basename "$file$stripped_ext"
+		file="$func_basename_result"
+	        outputname="$tmpdir/$file"
+	        # Replace the output file specification.
+	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+	        $opt_silent || {
+	          func_quote_for_expand "$relink_command"
+		  eval "func_echo $func_quote_for_expand_result"
+	        }
+	        if eval "$relink_command"; then :
+	          else
+		  func_error "error: relink \`$file' with the above command before installing it"
+		  $opt_dry_run || ${RM}r "$tmpdir"
+		  continue
+	        fi
+	        file="$outputname"
+	      else
+	        func_warning "cannot relink \`$file'"
+	      fi
+	    }
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+	  fi
 	fi
-	if test "$need_lib_prefix" != no; then
-	  # Add the "lib" prefix for modules if required
-	  name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
-	  eval shared_ext=\"$shrext_cmds\"
-	  eval libname=\"$libname_spec\"
-	else
-	  libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+
+	# remove .exe since cygwin /usr/bin/install will append another
+	# one anyway
+	case $install_prog,$host in
+	*/usr/bin/install*,*cygwin*)
+	  case $file:$destfile in
+	  *.exe:*.exe)
+	    # this is ok
+	    ;;
+	  *.exe:*)
+	    destfile=$destfile.exe
+	    ;;
+	  *:*.exe)
+	    func_stripname '' '.exe' "$destfile"
+	    destfile=$func_stripname_result
+	    ;;
+	  esac
+	  ;;
+	esac
+	func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+	$opt_dry_run || if test -n "$outputname"; then
+	  ${RM}r "$tmpdir"
 	fi
 	;;
       esac
+    done
 
-      if test -n "$objs"; then
-	if test "$deplibs_check_method" != pass_all; then
-	  $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
-	  exit $EXIT_FAILURE
-	else
-	  $echo
-	  $echo "*** Warning: Linking the shared library $output against the non-libtool"
-	  $echo "*** objects $objs is not portable!"
-	  libobjs="$libobjs $objs"
-	fi
-      fi
-
-      if test "$dlself" != no; then
-	$echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2
-      fi
+    for file in $staticlibs; do
+      func_basename "$file"
+      name="$func_basename_result"
 
-      set dummy $rpath
-      if test "$#" -gt 2; then
-	$echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+      func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+      tool_oldlib=$func_to_tool_file_result
+
+      func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+	func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
       fi
-      install_libdir="$2"
 
-      oldlibs=
-      if test -z "$rpath"; then
-	if test "$build_libtool_libs" = yes; then
-	  # Building a libtool convenience library.
-	  # Some compilers have problems with a `.al' extension so
-	  # convenience libraries should have the same extension an
-	  # archive normally would.
-	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
-	  build_libtool_libs=convenience
-	  build_old_libs=yes
-	fi
+      # Do each command in the postinstall commands.
+      func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+    done
 
-	if test -n "$vinfo"; then
-	  $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2
-	fi
+    test -n "$future_libdirs" && \
+      func_warning "remember to run \`$progname --finish$future_libdirs'"
 
-	if test -n "$release"; then
-	  $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
-	fi
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      $opt_dry_run && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+    $opt_debug
+    my_outputname="$1"
+    my_originator="$2"
+    my_pic_p="${3-no}"
+    my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+    my_dlsyms=
+
+    if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+      if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	my_dlsyms="${my_outputname}S.c"
       else
+	func_error "not configured to extract global symbols from dlpreopened files"
+      fi
+    fi
 
-	# Parse the version information argument.
-	save_ifs="$IFS"; IFS=':'
-	set dummy $vinfo 0 0 0
-	IFS="$save_ifs"
+    if test -n "$my_dlsyms"; then
+      case $my_dlsyms in
+      "") ;;
+      *.c)
+	# Discover the nlist of each of the dlfiles.
+	nlist="$output_objdir/${my_outputname}.nm"
 
-	if test -n "$8"; then
-	  $echo "$modename: too many parameters to \`-version-info'" 1>&2
-	  $echo "$help" 1>&2
-	  exit $EXIT_FAILURE
-	fi
+	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
 
-	# convert absolute version numbers to libtool ages
-	# this retains compatibility with .la files and attempts
-	# to make the code below a bit more comprehensible
+	# Parse the name list into a source file.
+	func_verbose "creating $output_objdir/$my_dlsyms"
 
-	case $vinfo_number in
-	yes)
-	  number_major="$2"
-	  number_minor="$3"
-	  number_revision="$4"
-	  #
-	  # There are really only two kinds -- those that
-	  # use the current revision as the major version
-	  # and those that subtract age and use age as
-	  # a minor version.  But, then there is irix
-	  # which has an extra 1 added just for fun
-	  #
-	  case $version_type in
-	  darwin|linux|osf|windows|none)
-	    current=`expr $number_major + $number_minor`
-	    age="$number_minor"
-	    revision="$number_revision"
-	    ;;
-	  freebsd-aout|freebsd-elf|sunos)
-	    current="$number_major"
-	    revision="$number_minor"
-	    age="0"
-	    ;;
-	  irix|nonstopux)
-	    current=`expr $number_major + $number_minor`
-	    age="$number_minor"
-	    revision="$number_minor"
-	    lt_irix_increment=no
-	    ;;
-	  *)
-	    $echo "$modename: unknown library version type \`$version_type'" 1>&2
-	    $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
-	    exit $EXIT_FAILURE
-	    ;;
-	  esac
-	  ;;
-	no)
-	  current="$2"
-	  revision="$3"
-	  age="$4"
-	  ;;
-	esac
+	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
 
-	# Check that each of the things are valid numbers.
-	case $current in
-	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
-	*)
-	  $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2
-	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
+#ifdef __cplusplus
+extern \"C\" {
+#endif
 
-	case $revision in
-	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
-	*)
-	  $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2
-	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
 
-	case $age in
-	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
-	*)
-	  $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2
-	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
 
-	if test "$age" -gt "$current"; then
-	  $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
-	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-	  exit $EXIT_FAILURE
-	fi
+/* External symbol declarations for the compiler. */\
+"
 
-	# Calculate the version variables.
-	major=
-	versuffix=
-	verstring=
-	case $version_type in
-	none) ;;
+	if test "$dlself" = yes; then
+	  func_verbose "generating symbol list for \`$output'"
 
-	darwin)
-	  # Like Linux, but with the current version available in
-	  # verstring for coding it into the library header
-	  major=.`expr $current - $age`
-	  versuffix="$major.$age.$revision"
-	  # Darwin ld doesn't like 0 for these options...
-	  minor_current=`expr $current + 1`
-	  xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
-	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
-	  ;;
+	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
 
-	freebsd-aout)
-	  major=".$current"
-	  versuffix=".$current.$revision";
-	  ;;
+	  # Add our own program objects to the symbol list.
+	  progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	  for progfile in $progfiles; do
+	    func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+	    func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
+	    $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+	  done
 
-	freebsd-elf)
-	  major=".$current"
-	  versuffix=".$current";
-	  ;;
+	  if test -n "$exclude_expsyms"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
 
-	irix | nonstopux)
-	  if test "X$lt_irix_increment" = "Xno"; then
-	    major=`expr $current - $age`
+	  if test -n "$export_symbols_regex"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  # Prepare the list of exported symbols
+	  if test -z "$export_symbols"; then
+	    export_symbols="$output_objdir/$outputname.exp"
+	    $opt_dry_run || {
+	      $RM $export_symbols
+	      eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	      case $host in
+	      *cygwin* | *mingw* | *cegcc* )
+                eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+                eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+	        ;;
+	      esac
+	    }
 	  else
-	    major=`expr $current - $age + 1`
+	    $opt_dry_run || {
+	      eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	      case $host in
+	        *cygwin* | *mingw* | *cegcc* )
+	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+	          ;;
+	      esac
+	    }
 	  fi
-	  case $version_type in
-	    nonstopux) verstring_prefix=nonstopux ;;
-	    *)         verstring_prefix=sgi ;;
-	  esac
-	  verstring="$verstring_prefix$major.$revision"
+	fi
 
-	  # Add in all the interfaces that we are compatible with.
-	  loop=$revision
-	  while test "$loop" -ne 0; do
-	    iface=`expr $revision - $loop`
-	    loop=`expr $loop - 1`
-	    verstring="$verstring_prefix$major.$iface:$verstring"
-	  done
+	for dlprefile in $dlprefiles; do
+	  func_verbose "extracting global C symbols from \`$dlprefile'"
+	  func_basename "$dlprefile"
+	  name="$func_basename_result"
+          case $host in
+	    *cygwin* | *mingw* | *cegcc* )
+	      # if an import library, we need to obtain dlname
+	      if func_win32_import_lib_p "$dlprefile"; then
+	        func_tr_sh "$dlprefile"
+	        eval "curr_lafile=\$libfile_$func_tr_sh_result"
+	        dlprefile_dlbasename=""
+	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+	          # Use subshell, to avoid clobbering current variable values
+	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+	          if test -n "$dlprefile_dlname" ; then
+	            func_basename "$dlprefile_dlname"
+	            dlprefile_dlbasename="$func_basename_result"
+	          else
+	            # no lafile. user explicitly requested -dlpreopen <import library>.
+	            $sharedlib_from_linklib_cmd "$dlprefile"
+	            dlprefile_dlbasename=$sharedlib_from_linklib_result
+	          fi
+	        fi
+	        $opt_dry_run || {
+	          if test -n "$dlprefile_dlbasename" ; then
+	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+	          else
+	            func_warning "Could not compute DLL name from $name"
+	            eval '$ECHO ": $name " >> "$nlist"'
+	          fi
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+	            $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+	        }
+	      else # not an import lib
+	        $opt_dry_run || {
+	          eval '$ECHO ": $name " >> "$nlist"'
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	        }
+	      fi
+	    ;;
+	    *)
+	      $opt_dry_run || {
+	        eval '$ECHO ": $name " >> "$nlist"'
+	        func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	        eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	      }
+	    ;;
+          esac
+	done
 
-	  # Before this point, $major must not contain `.'.
-	  major=.$major
-	  versuffix="$major.$revision"
-	  ;;
+	$opt_dry_run || {
+	  # Make sure we have at least an empty file.
+	  test -f "$nlist" || : > "$nlist"
 
-	linux)
-	  major=.`expr $current - $age`
-	  versuffix="$major.$age.$revision"
-	  ;;
+	  if test -n "$exclude_expsyms"; then
+	    $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+	    $MV "$nlist"T "$nlist"
+	  fi
 
-	osf)
-	  major=.`expr $current - $age`
-	  versuffix=".$current.$age.$revision"
-	  verstring="$current.$age.$revision"
+	  # Try sorting and uniquifying the output.
+	  if $GREP -v "^: " < "$nlist" |
+	      if sort -k 3 </dev/null >/dev/null 2>&1; then
+		sort -k 3
+	      else
+		sort +2
+	      fi |
+	      uniq > "$nlist"S; then
+	    :
+	  else
+	    $GREP -v "^: " < "$nlist" > "$nlist"S
+	  fi
 
-	  # Add in all the interfaces that we are compatible with.
-	  loop=$age
-	  while test "$loop" -ne 0; do
-	    iface=`expr $current - $loop`
-	    loop=`expr $loop - 1`
-	    verstring="$verstring:${iface}.0"
-	  done
+	  if test -f "$nlist"S; then
+	    eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+	  else
+	    echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+	  fi
 
-	  # Make executables depend on our current version.
-	  verstring="$verstring:${current}.0"
-	  ;;
+	  echo >> "$output_objdir/$my_dlsyms" "\
 
-	sunos)
-	  major=".$current"
-	  versuffix=".$current.$revision"
-	  ;;
+/* The mapping between symbol names and symbols.  */
+typedef struct {
+  const char *name;
+  void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+  { \"$my_originator\", (void *) 0 },"
 
-	windows)
-	  # Use '-' rather than '.', since we only want one
-	  # extension on DOS 8.3 filesystems.
-	  major=`expr $current - $age`
-	  versuffix="-$major"
-	  ;;
+	  case $need_lib_prefix in
+	  no)
+	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  *)
+	    eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  esac
+	  echo >> "$output_objdir/$my_dlsyms" "\
+  {0, (void *) 0}
+};
 
-	*)
-	  $echo "$modename: unknown library version type \`$version_type'" 1>&2
-	  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
 
-	# Clear the version info if we defaulted, and they specified a release.
-	if test -z "$vinfo" && test -n "$release"; then
-	  major=
-	  case $version_type in
-	  darwin)
-	    # we can't check for "0.0" in archive_cmds due to quoting
-	    # problems, so we reset it completely
-	    verstring=
-	    ;;
+#ifdef __cplusplus
+}
+#endif\
+"
+	} # !$opt_dry_run
+
+	pic_flag_for_symtable=
+	case "$compile_command " in
+	*" -static "*) ;;
+	*)
+	  case $host in
+	  # compiling the symbol table file with pic_flag works around
+	  # a FreeBSD bug that causes programs to crash when -lm is
+	  # linked before any other PIC object.  But we must not use
+	  # pic_flag when linking with -static.  The problem exists in
+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+	  *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+	    pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+	  *-*-hpux*)
+	    pic_flag_for_symtable=" $pic_flag"  ;;
 	  *)
-	    verstring="0.0"
+	    if test "X$my_pic_p" != Xno; then
+	      pic_flag_for_symtable=" $pic_flag"
+	    fi
 	    ;;
 	  esac
-	  if test "$need_version" = no; then
-	    versuffix=
+	  ;;
+	esac
+	symtab_cflags=
+	for arg in $LTCFLAGS; do
+	  case $arg in
+	  -pie | -fpie | -fPIE) ;;
+	  *) func_append symtab_cflags " $arg" ;;
+	  esac
+	done
+
+	# Now compile the dynamic symbol file.
+	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+	# Clean up the generated files.
+	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+	# Transform the symbol file into the correct name.
+	symfileobj="$output_objdir/${my_outputname}S.$objext"
+	case $host in
+	*cygwin* | *mingw* | *cegcc* )
+	  if test -f "$output_objdir/$my_outputname.def"; then
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
 	  else
-	    versuffix=".0.0"
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
 	  fi
-	fi
+	  ;;
+	*)
+	  compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  ;;
+	esac
+	;;
+      *)
+	func_fatal_error "unknown suffix for \`$my_dlsyms'"
+	;;
+      esac
+    else
+      # We keep going just in case the user didn't refer to
+      # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+      # really was required.
 
-	# Remove version info from name if versioning should be avoided
-	if test "$avoid_version" = yes && test "$need_version" = no; then
-	  major=
-	  versuffix=
-	  verstring=""
-	fi
+      # Nullify the symbol file.
+      compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+      finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+    fi
+}
 
-	# Check to see if the archive will have undefined symbols.
-	if test "$allow_undefined" = yes; then
-	  if test "$allow_undefined_flag" = unsupported; then
-	    $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
-	    build_libtool_libs=no
-	    build_old_libs=yes
-	  fi
-	else
-	  # Don't allow undefined symbols.
-	  allow_undefined_flag="$no_undefined_flag"
-	fi
-      fi
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+  $opt_debug
+  win32_libid_type="unknown"
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+      func_to_tool_file "$1" func_convert_file_msys_to_w32
+      win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+	$SED -n -e '
+	    1,100{
+		/ I /{
+		    s,.*,import,
+		    p
+		    q
+		}
+	    }'`
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $ECHO "$win32_libid_type"
+}
 
-      if test "$mode" != relink; then
-	# Remove our outputs, but don't remove object files since they
-	# may have been created when compiling PIC objects.
-	removelist=
-	tempremovelist=`$echo "$output_objdir/*"`
-	for p in $tempremovelist; do
-	  case $p in
-	    *.$objext)
-	       ;;
-	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
-	       if test "X$precious_files_regex" != "X"; then
-	         if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
-	         then
-		   continue
-		 fi
-	       fi
-	       removelist="$removelist $p"
-	       ;;
-	    *) ;;
-	  esac
-	done
-	if test -n "$removelist"; then
-	  $show "${rm}r $removelist"
-	  $run ${rm}r $removelist
-	fi
-      fi
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+  $opt_debug
+  sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
 
-      # Now set the variables for building old libraries.
-      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
-	oldlibs="$oldlibs $output_objdir/$libname.$libext"
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+  $opt_debug
+  match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+  $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+    $SED '/^Contents of section '"$match_literal"':/{
+      # Place marker at beginning of archive member dllname section
+      s/.*/====MARK====/
+      p
+      d
+    }
+    # These lines can sometimes be longer than 43 characters, but
+    # are always uninteresting
+    /:[	 ]*file format pe[i]\{,1\}-/d
+    /^In archive [^:]*:/d
+    # Ensure marker is printed
+    /^====MARK====/p
+    # Remove all lines with less than 43 characters
+    /^.\{43\}/!d
+    # From remaining lines, remove first 43 characters
+    s/^.\{43\}//' |
+    $SED -n '
+      # Join marker and all lines until next marker into a single line
+      /^====MARK====/ b para
+      H
+      $ b para
+      b
+      :para
+      x
+      s/\n//g
+      # Remove the marker
+      s/^====MARK====//
+      # Remove trailing dots and whitespace
+      s/[\. \t]*$//
+      # Print
+      /./p' |
+    # we now have a list, one entry per line, of the stringified
+    # contents of the appropriate section of all members of the
+    # archive which possess that section. Heuristic: eliminate
+    # all those which have a first or second character that is
+    # a '.' (that is, objdump's representation of an unprintable
+    # character.) This should work for all archives with less than
+    # 0x302f exports -- but will fail for DLLs whose name actually
+    # begins with a literal '.' or a single character followed by
+    # a '.'.
+    #
+    # Of those that remain, print the first one.
+    $SED -e '/^\./d;/^.\./d;q'
+}
 
-	# Transform .lo files to .o files.
-	oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
-      fi
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+  test -n "$func_cygming_gnu_implib_tmp"
+}
 
-      # Eliminate all temporary directories.
-      #for path in $notinst_path; do
-      #	lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"`
-      #	deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"`
-      #	dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"`
-      #done
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+  test -n "$func_cygming_ms_implib_tmp"
+}
 
-      if test -n "$xrpath"; then
-	# If the user specified any rpath flags, then add them.
-	temp_xrpath=
-	for libdir in $xrpath; do
-	  temp_xrpath="$temp_xrpath -R$libdir"
-	  case "$finalize_rpath " in
-	  *" $libdir "*) ;;
-	  *) finalize_rpath="$finalize_rpath $libdir" ;;
-	  esac
-	done
-	if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
-	  dependency_libs="$temp_xrpath $dependency_libs"
-	fi
-      fi
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+  $opt_debug
+  if func_cygming_gnu_implib_p "$1" ; then
+    # binutils import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+  elif func_cygming_ms_implib_p "$1" ; then
+    # ms-generated import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+  else
+    # unknown
+    sharedlib_from_linklib_result=""
+  fi
+}
 
-      # Make sure dlfiles contains only unique files that won't be dlpreopened
-      old_dlfiles="$dlfiles"
-      dlfiles=
-      for lib in $old_dlfiles; do
-	case " $dlprefiles $dlfiles " in
-	*" $lib "*) ;;
-	*) dlfiles="$dlfiles $lib" ;;
-	esac
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    $opt_debug
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+    if test "$lock_old_archive_extraction" = yes; then
+      lockfile=$f_ex_an_ar_oldlib.lock
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
       done
+    fi
+    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+		   'stat=$?; rm -f "$lockfile"; exit $stat'
+    if test "$lock_old_archive_extraction" = yes; then
+      $opt_dry_run || rm -f "$lockfile"
+    fi
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+    fi
+}
 
-      # Make sure dlprefiles contains only unique files
-      old_dlprefiles="$dlprefiles"
-      dlprefiles=
-      for lib in $old_dlprefiles; do
-	case "$dlprefiles " in
-	*" $lib "*) ;;
-	*) dlprefiles="$dlprefiles $lib" ;;
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    $opt_debug
+    my_gentop="$1"; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
+
+    for my_xlib in $my_oldlibs; do
+      # Extract the objects.
+      case $my_xlib in
+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+	*) my_xabs=`pwd`"/$my_xlib" ;;
+      esac
+      func_basename "$my_xlib"
+      my_xlib="$func_basename_result"
+      my_xlib_u=$my_xlib
+      while :; do
+        case " $extracted_archives " in
+	*" $my_xlib_u "*)
+	  func_arith $extracted_serial + 1
+	  extracted_serial=$func_arith_result
+	  my_xlib_u=lt$extracted_serial-$my_xlib ;;
+	*) break ;;
 	esac
       done
+      extracted_archives="$extracted_archives $my_xlib_u"
+      my_xdir="$my_gentop/$my_xlib_u"
 
-      if test "$build_libtool_libs" = yes; then
-	if test -n "$rpath"; then
-	  case $host in
-	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
-	    # these systems don't actually have a c library (as such)!
-	    ;;
-	  *-*-rhapsody* | *-*-darwin1.[012])
-	    # Rhapsody C library is in the System framework
-	    deplibs="$deplibs -framework System"
-	    ;;
-	  *-*-netbsd*)
-	    # Don't link with libc until the a.out ld.so is fixed.
-	    ;;
-	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
-	    # Do not include libc due to us having libc/libc_r.
-	    ;;
-	  *-*-sco3.2v5* | *-*-sco5v6*)
-	    # Causes problems with __ctype
-	    ;;
-	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
-	    # Compiler inserts libc in the correct place for threads to work
-	    ;;
- 	  *)
-	    # Add libc to deplibs on all other systems if necessary.
-	    if test "$build_libtool_need_lc" = "yes"; then
-	      deplibs="$deplibs -lc"
-	    fi
-	    ;;
-	  esac
-	fi
+      func_mkdir_p "$my_xdir"
 
-	# Transform deplibs into only deplibs that can be linked in shared.
-	name_save=$name
-	libname_save=$libname
-	release_save=$release
-	versuffix_save=$versuffix
-	major_save=$major
-	# I'm not sure if I'm treating the release correctly.  I think
-	# release should show up in the -l (ie -lgmp5) so we don't want to
-	# add it in twice.  Is that correct?
-	release=""
-	versuffix=""
-	major=""
-	newdeplibs=
-	droppeddeps=no
-	case $deplibs_check_method in
-	pass_all)
-	  # Don't check for shared/static.  Everything works.
-	  # This might be a little naive.  We might want to check
-	  # whether the library exists or not.  But this is on
-	  # osf3 & osf4 and I'm not really sure... Just
-	  # implementing what was already the behavior.
-	  newdeplibs=$deplibs
-	  ;;
-	test_compile)
-	  # This code stresses the "libraries are programs" paradigm to its
-	  # limits. Maybe even breaks it.  We compile a program, linking it
-	  # against the deplibs as a proxy for the library.  Then we can check
-	  # whether they linked in statically or dynamically with ldd.
-	  $rm conftest.c
-	  cat > conftest.c <<EOF
-	  int main() { return 0; }
-EOF
-	  $rm conftest
-	  if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
-	    ldd_output=`ldd conftest`
-	    for i in $deplibs; do
-	      name=`expr $i : '-l\(.*\)'`
-	      # If $name is empty we are operating on a -L argument.
-              if test "$name" != "" && test "$name" != "0"; then
-		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
-		  case " $predeps $postdeps " in
-		  *" $i "*)
-		    newdeplibs="$newdeplibs $i"
-		    i=""
-		    ;;
-		  esac
-	        fi
-		if test -n "$i" ; then
-		  libname=`eval \\$echo \"$libname_spec\"`
-		  deplib_matches=`eval \\$echo \"$library_names_spec\"`
-		  set dummy $deplib_matches
-		  deplib_match=$2
-		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
-		    newdeplibs="$newdeplibs $i"
-		  else
-		    droppeddeps=yes
-		    $echo
-		    $echo "*** Warning: dynamic linker does not accept needed library $i."
-		    $echo "*** I have the capability to make that library automatically link in when"
-		    $echo "*** you link to this library.  But I can only do this if you have a"
-		    $echo "*** shared version of the library, which I believe you do not have"
-		    $echo "*** because a test_compile did reveal that the linker did not use it for"
-		    $echo "*** its dynamic dependency list that programs get resolved with at runtime."
-		  fi
-		fi
-	      else
-		newdeplibs="$newdeplibs $i"
-	      fi
-	    done
+      case $host in
+      *-darwin*)
+	func_verbose "Extracting $my_xabs"
+	# Do not bother doing anything if just a dry run
+	$opt_dry_run || {
+	  darwin_orig_dir=`pwd`
+	  cd $my_xdir || exit $?
+	  darwin_archive=$my_xabs
+	  darwin_curdir=`pwd`
+	  darwin_base_archive=`basename "$darwin_archive"`
+	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+	  if test -n "$darwin_arches"; then
+	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+	    darwin_arch=
+	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+	    for darwin_arch in  $darwin_arches ; do
+	      func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+	      cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+	      cd "$darwin_curdir"
+	      $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+	    done # $darwin_arches
+            ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+	    darwin_file=
+	    darwin_files=
+	    for darwin_file in $darwin_filelist; do
+	      darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+	      $LIPO -create -output "$darwin_file" $darwin_files
+	    done # $darwin_filelist
+	    $RM -rf unfat-$$
+	    cd "$darwin_orig_dir"
 	  else
-	    # Error occurred in the first compile.  Let's try to salvage
-	    # the situation: Compile a separate program for each library.
-	    for i in $deplibs; do
-	      name=`expr $i : '-l\(.*\)'`
-	      # If $name is empty we are operating on a -L argument.
-              if test "$name" != "" && test "$name" != "0"; then
-		$rm conftest
-		if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
-		  ldd_output=`ldd conftest`
-		  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
-		    case " $predeps $postdeps " in
-		    *" $i "*)
-		      newdeplibs="$newdeplibs $i"
-		      i=""
-		      ;;
-		    esac
-		  fi
-		  if test -n "$i" ; then
-		    libname=`eval \\$echo \"$libname_spec\"`
-		    deplib_matches=`eval \\$echo \"$library_names_spec\"`
-		    set dummy $deplib_matches
-		    deplib_match=$2
-		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
-		      newdeplibs="$newdeplibs $i"
-		    else
-		      droppeddeps=yes
-		      $echo
-		      $echo "*** Warning: dynamic linker does not accept needed library $i."
-		      $echo "*** I have the capability to make that library automatically link in when"
-		      $echo "*** you link to this library.  But I can only do this if you have a"
-		      $echo "*** shared version of the library, which you do not appear to have"
-		      $echo "*** because a test_compile did reveal that the linker did not use this one"
-		      $echo "*** as a dynamic dependency that programs can get resolved with at runtime."
-		    fi
-		  fi
-		else
-		  droppeddeps=yes
-		  $echo
-		  $echo "*** Warning!  Library $i is needed by this library but I was not able to"
-		  $echo "*** make it link in!  You will probably need to install it or some"
-		  $echo "*** library that it depends on before this library will be fully"
-		  $echo "*** functional.  Installing it before continuing would be even better."
-		fi
-	      else
-		newdeplibs="$newdeplibs $i"
-	      fi
-	    done
-	  fi
-	  ;;
-	file_magic*)
-	  set dummy $deplibs_check_method
-	  file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
-	  for a_deplib in $deplibs; do
-	    name=`expr $a_deplib : '-l\(.*\)'`
-	    # If $name is empty we are operating on a -L argument.
-            if test "$name" != "" && test  "$name" != "0"; then
-	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
-		case " $predeps $postdeps " in
-		*" $a_deplib "*)
-		  newdeplibs="$newdeplibs $a_deplib"
-		  a_deplib=""
-		  ;;
-		esac
-	      fi
-	      if test -n "$a_deplib" ; then
-		libname=`eval \\$echo \"$libname_spec\"`
-		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
-		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
-		  for potent_lib in $potential_libs; do
-		      # Follow soft links.
-		      if ls -lLd "$potent_lib" 2>/dev/null \
-			 | grep " -> " >/dev/null; then
-			continue
-		      fi
-		      # The statement above tries to avoid entering an
-		      # endless loop below, in case of cyclic links.
-		      # We might still enter an endless loop, since a link
-		      # loop can be closed while we follow links,
-		      # but so what?
-		      potlib="$potent_lib"
-		      while test -h "$potlib" 2>/dev/null; do
-			potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
-			case $potliblink in
-			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
-			*) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
-			esac
-		      done
-		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
-			 | ${SED} 10q \
-			 | $EGREP "$file_magic_regex" > /dev/null; then
-			newdeplibs="$newdeplibs $a_deplib"
-			a_deplib=""
-			break 2
-		      fi
-		  done
-		done
-	      fi
-	      if test -n "$a_deplib" ; then
-		droppeddeps=yes
-		$echo
-		$echo "*** Warning: linker path does not have real file for library $a_deplib."
-		$echo "*** I have the capability to make that library automatically link in when"
-		$echo "*** you link to this library.  But I can only do this if you have a"
-		$echo "*** shared version of the library, which you do not appear to have"
-		$echo "*** because I did check the linker path looking for a file starting"
-		if test -z "$potlib" ; then
-		  $echo "*** with $libname but no candidates were found. (...for file magic test)"
-		else
-		  $echo "*** with $libname and none of the candidates passed a file format test"
-		  $echo "*** using a file magic. Last file checked: $potlib"
-		fi
-	      fi
-	    else
-	      # Add a -L argument.
-	      newdeplibs="$newdeplibs $a_deplib"
-	    fi
-	  done # Gone through all deplibs.
-	  ;;
-	match_pattern*)
-	  set dummy $deplibs_check_method
-	  match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
-	  for a_deplib in $deplibs; do
-	    name=`expr $a_deplib : '-l\(.*\)'`
-	    # If $name is empty we are operating on a -L argument.
-	    if test -n "$name" && test "$name" != "0"; then
-	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
-		case " $predeps $postdeps " in
-		*" $a_deplib "*)
-		  newdeplibs="$newdeplibs $a_deplib"
-		  a_deplib=""
-		  ;;
-		esac
-	      fi
-	      if test -n "$a_deplib" ; then
-		libname=`eval \\$echo \"$libname_spec\"`
-		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
-		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
-		  for potent_lib in $potential_libs; do
-		    potlib="$potent_lib" # see symlink-check above in file_magic test
-		    if eval $echo \"$potent_lib\" 2>/dev/null \
-		        | ${SED} 10q \
-		        | $EGREP "$match_pattern_regex" > /dev/null; then
-		      newdeplibs="$newdeplibs $a_deplib"
-		      a_deplib=""
-		      break 2
-		    fi
-		  done
-		done
-	      fi
-	      if test -n "$a_deplib" ; then
-		droppeddeps=yes
-		$echo
-		$echo "*** Warning: linker path does not have real file for library $a_deplib."
-		$echo "*** I have the capability to make that library automatically link in when"
-		$echo "*** you link to this library.  But I can only do this if you have a"
-		$echo "*** shared version of the library, which you do not appear to have"
-		$echo "*** because I did check the linker path looking for a file starting"
-		if test -z "$potlib" ; then
-		  $echo "*** with $libname but no candidates were found. (...for regex pattern test)"
-		else
-		  $echo "*** with $libname and none of the candidates passed a file format test"
-		  $echo "*** using a regex pattern. Last file checked: $potlib"
-		fi
-	      fi
-	    else
-	      # Add a -L argument.
-	      newdeplibs="$newdeplibs $a_deplib"
-	    fi
-	  done # Gone through all deplibs.
-	  ;;
-	none | unknown | *)
-	  newdeplibs=""
-	  tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
-	    -e 's/ -[LR][^ ]*//g'`
-	  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
-	    for i in $predeps $postdeps ; do
-	      # can't use Xsed below, because $i might contain '/'
-	      tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"`
-	    done
-	  fi
-	  if $echo "X $tmp_deplibs" | $Xsed -e 's/[ 	]//g' \
-	    | grep . >/dev/null; then
-	    $echo
-	    if test "X$deplibs_check_method" = "Xnone"; then
-	      $echo "*** Warning: inter-library dependencies are not supported in this platform."
-	    else
-	      $echo "*** Warning: inter-library dependencies are not known to be supported."
-	    fi
-	    $echo "*** All declared inter-library dependencies are being dropped."
-	    droppeddeps=yes
-	  fi
-	  ;;
-	esac
-	versuffix=$versuffix_save
-	major=$major_save
-	release=$release_save
-	libname=$libname_save
-	name=$name_save
+	    cd $darwin_orig_dir
+	    func_extract_an_archive "$my_xdir" "$my_xabs"
+	  fi # $darwin_arches
+	} # !$opt_dry_run
+	;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+	;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+    done
 
-	case $host in
-	*-*-rhapsody* | *-*-darwin1.[012])
-	  # On Rhapsody replace the C library is the System framework
-	  newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'`
-	  ;;
-	esac
+    func_extract_archives_result="$my_oldobjs"
+}
 
-	if test "$droppeddeps" = yes; then
-	  if test "$module" = yes; then
-	    $echo
-	    $echo "*** Warning: libtool could not satisfy all declared inter-library"
-	    $echo "*** dependencies of module $libname.  Therefore, libtool will create"
-	    $echo "*** a static module, that should work as long as the dlopening"
-	    $echo "*** application is linked with the -dlopen flag."
-	    if test -z "$global_symbol_pipe"; then
-	      $echo
-	      $echo "*** However, this would only work if libtool was able to extract symbol"
-	      $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
-	      $echo "*** not find such a program.  So, this module is probably useless."
-	      $echo "*** \`nm' from GNU binutils and a full rebuild may help."
-	    fi
-	    if test "$build_old_libs" = no; then
-	      oldlibs="$output_objdir/$libname.$libext"
-	      build_libtool_libs=module
-	      build_old_libs=yes
-	    else
-	      build_libtool_libs=no
-	    fi
-	  else
-	    $echo "*** The inter-library dependencies that have been dropped here will be"
-	    $echo "*** automatically added whenever a program is linked with this library"
-	    $echo "*** or is declared to -dlopen it."
 
-	    if test "$allow_undefined" = no; then
-	      $echo
-	      $echo "*** Since this library must not contain undefined symbols,"
-	      $echo "*** because either the platform does not support them or"
-	      $echo "*** it was explicitly requested with -no-undefined,"
-	      $echo "*** libtool will only create a static version of it."
-	      if test "$build_old_libs" = no; then
-		oldlibs="$output_objdir/$libname.$libext"
-		build_libtool_libs=module
-		build_old_libs=yes
-	      else
-		build_libtool_libs=no
-	      fi
-	    fi
-	  fi
-	fi
-	# Done checking deplibs!
-	deplibs=$newdeplibs
-      fi
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable.  Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take.  If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory.  This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+	func_emit_wrapper_arg1=${1-no}
 
+	$ECHO "\
+#! $SHELL
 
-      # move library search paths that coincide with paths to not yet
-      # installed libraries to the beginning of the library search list
-      new_libs=
-      for path in $notinst_path; do
-	case " $new_libs " in
-	*" -L$path/$objdir "*) ;;
-	*)
-	  case " $deplibs " in
-	  *" -L$path/$objdir "*)
-	    new_libs="$new_libs -L$path/$objdir" ;;
-	  esac
-	  ;;
-	esac
-      done
-      for deplib in $deplibs; do
-	case $deplib in
-	-L*)
-	  case " $new_libs " in
-	  *" $deplib "*) ;;
-	  *) new_libs="$new_libs $deplib" ;;
-	  esac
-	  ;;
-	*) new_libs="$new_libs $deplib" ;;
-	esac
-      done
-      deplibs="$new_libs"
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
 
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
 
-      # All the library-specific variables (install_libdir is set above).
-      library_names=
-      old_library=
-      dlname=
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
 
-      # Test again, we may have decided not to build it any more
-      if test "$build_libtool_libs" = yes; then
-	if test "$hardcode_into_libs" = yes; then
-	  # Hardcode the library paths
-	  hardcode_libdirs=
-	  dep_rpath=
-	  rpath="$finalize_rpath"
-	  test "$mode" != relink && rpath="$compile_rpath$rpath"
-	  for libdir in $rpath; do
-	    if test -n "$hardcode_libdir_flag_spec"; then
-	      if test -n "$hardcode_libdir_separator"; then
-		if test -z "$hardcode_libdirs"; then
-		  hardcode_libdirs="$libdir"
-		else
-		  # Just accumulate the unique libdirs.
-		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
-		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
-		    ;;
-		  *)
-		    hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
-		    ;;
-		  esac
-		fi
-	      else
-		eval flag=\"$hardcode_libdir_flag_spec\"
-		dep_rpath="$dep_rpath $flag"
-	      fi
-	    elif test -n "$runpath_var"; then
-	      case "$perm_rpath " in
-	      *" $libdir "*) ;;
-	      *) perm_rpath="$perm_rpath $libdir" ;;
-	      esac
-	    fi
-	  done
-	  # Substitute the hardcoded libdirs into the rpath.
-	  if test -n "$hardcode_libdir_separator" &&
-	     test -n "$hardcode_libdirs"; then
-	    libdir="$hardcode_libdirs"
-	    if test -n "$hardcode_libdir_flag_spec_ld"; then
-	      case $archive_cmds in
-	      *\$LD*) eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" ;;
-	      *)      eval dep_rpath=\"$hardcode_libdir_flag_spec\" ;;
-	      esac
-	    else
-	      eval dep_rpath=\"$hardcode_libdir_flag_spec\"
-	    fi
-	  fi
-	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
-	    # We should set the runpath_var.
-	    rpath=
-	    for dir in $perm_rpath; do
-	      rpath="$rpath$dir:"
-	    done
-	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
-	  fi
-	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
-	fi
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
-	shlibpath="$finalize_shlibpath"
-	test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
-	if test -n "$shlibpath"; then
-	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
-	fi
+relink_command=\"$relink_command\"
 
-	# Get the real and link names of the library.
-	eval shared_ext=\"$shrext_cmds\"
-	eval library_names=\"$library_names_spec\"
-	set dummy $library_names
-	realname="$2"
-	shift; shift
-
-	if test -n "$soname_spec"; then
-	  eval soname=\"$soname_spec\"
-	else
-	  soname="$realname"
-	fi
-	if test -z "$dlname"; then
-	  dlname=$soname
-	fi
-
-	lib="$output_objdir/$realname"
-	linknames=
-	for link
-	do
-	  linknames="$linknames $link"
-	done
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variables:
+  generated_by_libtool_version='$macro_version'
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$ECHO are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    file=\"\$0\""
 
-	# Use standard objects if they are pic
-	test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+    $ECHO "\
 
-	# Prepare the list of exported symbols
-	if test -z "$export_symbols"; then
-	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
-	    $show "generating symbol list for \`$libname.la'"
-	    export_symbols="$output_objdir/$libname.exp"
-	    $run $rm $export_symbols
-	    cmds=$export_symbols_cmds
-	    save_ifs="$IFS"; IFS='~'
-	    for cmd in $cmds; do
-	      IFS="$save_ifs"
-	      eval cmd=\"$cmd\"
-	      if len=`expr "X$cmd" : ".*"` &&
-	       test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
-	        $show "$cmd"
-	        $run eval "$cmd" || exit $?
-	        skipped_export=false
-	      else
-	        # The command line is too long to execute in one step.
-	        $show "using reloadable object file for export list..."
-	        skipped_export=:
-		# Break out early, otherwise skipped_export may be
-		# set to false by a later but shorter cmd.
-		break
-	      fi
-	    done
-	    IFS="$save_ifs"
-	    if test -n "$export_symbols_regex"; then
-	      $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
-	      $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
-	      $show "$mv \"${export_symbols}T\" \"$export_symbols\""
-	      $run eval '$mv "${export_symbols}T" "$export_symbols"'
-	    fi
-	  fi
-	fi
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+    ECHO=\"$qECHO\"
+  fi
 
-	if test -n "$export_symbols" && test -n "$include_expsyms"; then
-	  $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
-	fi
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+  lt_script_arg0=\$0
+  shift
+  for lt_opt
+  do
+    case \"\$lt_opt\" in
+    --lt-debug) lt_option_debug=1 ;;
+    --lt-dump-script)
+        lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+        test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+        lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+        cat \"\$lt_dump_D/\$lt_dump_F\"
+        exit 0
+      ;;
+    --lt-*)
+        \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+        exit 1
+      ;;
+    esac
+  done
 
-	tmp_deplibs=
-	for test_deplib in $deplibs; do
-		case " $convenience " in
-		*" $test_deplib "*) ;;
-		*)
-			tmp_deplibs="$tmp_deplibs $test_deplib"
-			;;
-		esac
-	done
-	deplibs="$tmp_deplibs"
+  # Print the debug banner immediately:
+  if test -n \"\$lt_option_debug\"; then
+    echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
+  fi
+}
 
-	if test -n "$convenience"; then
-	  if test -n "$whole_archive_flag_spec"; then
-	    save_libobjs=$libobjs
-	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
-	  else
-	    gentop="$output_objdir/${outputname}x"
-	    generated="$generated $gentop"
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+  lt_dump_args_N=1;
+  for lt_arg
+  do
+    \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
+    lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+  done
+}
 
-	    func_extract_archives $gentop $convenience
-	    libobjs="$libobjs $func_extract_archives_result"
-	  fi
-	fi
-	
-	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
-	  eval flag=\"$thread_safe_flag_spec\"
-	  linker_flags="$linker_flags $flag"
-	fi
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+  case $host in
+  # Backslashes separate directories on plain windows
+  *-*-mingw | *-*-os2* | *-cegcc*)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+    ;;
 
-	# Make a backup of the uninstalled library when relinking
-	if test "$mode" = relink; then
-	  $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $?
-	fi
+  *)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+    ;;
+  esac
+  $ECHO "\
+      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+      exit 1
+}
 
-	# Do each of the archive commands.
-	if test "$module" = yes && test -n "$module_cmds" ; then
-	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
-	    eval test_cmds=\"$module_expsym_cmds\"
-	    cmds=$module_expsym_cmds
-	  else
-	    eval test_cmds=\"$module_cmds\"
-	    cmds=$module_cmds
-	  fi
-	else
-	if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
-	  eval test_cmds=\"$archive_expsym_cmds\"
-	  cmds=$archive_expsym_cmds
-	else
-	  eval test_cmds=\"$archive_cmds\"
-	  cmds=$archive_cmds
-	  fi
-	fi
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+  case \" \$* \" in
+  *\\ --lt-*)
+    for lt_wr_arg
+    do
+      case \$lt_wr_arg in
+      --lt-*) ;;
+      *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+      esac
+      shift
+    done ;;
+  esac
+  func_exec_program_core \${1+\"\$@\"}
+}
 
-	if test "X$skipped_export" != "X:" &&
-	   len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
-	   test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
-	  :
-	else
-	  # The command line is too long to link in one step, link piecewise.
-	  $echo "creating reloadable object files..."
+  # Parse options
+  func_parse_lt_options \"\$0\" \${1+\"\$@\"}
 
-	  # Save the value of $output and $libobjs because we want to
-	  # use them later.  If we have whole_archive_flag_spec, we
-	  # want to use save_libobjs as it was before
-	  # whole_archive_flag_spec was expanded, because we can't
-	  # assume the linker understands whole_archive_flag_spec.
-	  # This may have to be revisited, in case too many
-	  # convenience libraries get linked in and end up exceeding
-	  # the spec.
-	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
-	    save_libobjs=$libobjs
-	  fi
-	  save_output=$output
-	  output_la=`$echo "X$output" | $Xsed -e "$basename"`
+  # Find the directory that this script lives in.
+  thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
 
-	  # Clear the reloadable object creation command queue and
-	  # initialize k to one.
-	  test_cmds=
-	  concat_cmds=
-	  objlist=
-	  delfiles=
-	  last_robj=
-	  k=1
-	  output=$output_objdir/$output_la-${k}.$objext
-	  # Loop over the list of objects to be linked.
-	  for obj in $save_libobjs
-	  do
-	    eval test_cmds=\"$reload_cmds $objlist $last_robj\"
-	    if test "X$objlist" = X ||
-	       { len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
-		 test "$len" -le "$max_cmd_len"; }; then
-	      objlist="$objlist $obj"
-	    else
-	      # The command $test_cmds is almost too long, add a
-	      # command to the queue.
-	      if test "$k" -eq 1 ; then
-		# The first file doesn't have a previous command to add.
-		eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
-	      else
-		# All subsequent reloadable object files will link in
-		# the last one created.
-		eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\"
-	      fi
-	      last_robj=$output_objdir/$output_la-${k}.$objext
-	      k=`expr $k + 1`
-	      output=$output_objdir/$output_la-${k}.$objext
-	      objlist=$obj
-	      len=1
-	    fi
-	  done
-	  # Handle the remaining objects by creating one last
-	  # reloadable object file.  All subsequent reloadable object
-	  # files will link in the last one created.
-	  test -z "$concat_cmds" || concat_cmds=$concat_cmds~
-	  eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
-
-	  if ${skipped_export-false}; then
-	    $show "generating symbol list for \`$libname.la'"
-	    export_symbols="$output_objdir/$libname.exp"
-	    $run $rm $export_symbols
-	    libobjs=$output
-	    # Append the command to create the export file.
-	    eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\"
-          fi
-
-	  # Set up a command to remove the reloadable object files
-	  # after they are used.
-	  i=0
-	  while test "$i" -lt "$k"
-	  do
-	    i=`expr $i + 1`
-	    delfiles="$delfiles $output_objdir/$output_la-${i}.$objext"
-	  done
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
 
-	  $echo "creating a temporary reloadable object file: $output"
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
 
-	  # Loop through the commands generated above and execute them.
-	  save_ifs="$IFS"; IFS='~'
-	  for cmd in $concat_cmds; do
-	    IFS="$save_ifs"
-	    $show "$cmd"
-	    $run eval "$cmd" || exit $?
-	  done
-	  IFS="$save_ifs"
+    file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+  done
 
-	  libobjs=$output
-	  # Restore the value of output.
-	  output=$save_output
+  # Usually 'no', except on cygwin/mingw when embedded into
+  # the cwrapper.
+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+  if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+    # special case for '.'
+    if test \"\$thisdir\" = \".\"; then
+      thisdir=\`pwd\`
+    fi
+    # remove .libs from thisdir
+    case \"\$thisdir\" in
+    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+    $objdir )   thisdir=. ;;
+    esac
+  fi
 
-	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
-	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
-	  fi
-	  # Expand the library linking commands again to reset the
-	  # value of $libobjs for piecewise linking.
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
 
-	  # Do each of the archive commands.
-	  if test "$module" = yes && test -n "$module_cmds" ; then
-	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
-	      cmds=$module_expsym_cmds
-	    else
-	      cmds=$module_cmds
-	    fi
-	  else
-	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
-	    cmds=$archive_expsym_cmds
-	  else
-	    cmds=$archive_cmds
-	    fi
-	  fi
+	if test "$fast_install" = yes; then
+	  $ECHO "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
 
-	  # Append the command to remove the reloadable object files
-	  # to the just-reset $cmds.
-	  eval cmds=\"\$cmds~\$rm $delfiles\"
-	fi
-	save_ifs="$IFS"; IFS='~'
-	for cmd in $cmds; do
-	  IFS="$save_ifs"
-	  eval cmd=\"$cmd\"
-	  $show "$cmd"
-	  $run eval "$cmd" || {
-	    lt_exit=$?
+  if test ! -f \"\$progdir/\$program\" ||
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
 
-	    # Restore the uninstalled library and exit
-	    if test "$mode" = relink; then
-	      $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
-	    fi
+    file=\"\$\$-\$program\"
 
-	    exit $lt_exit
-	  }
-	done
-	IFS="$save_ifs"
+    if test ! -d \"\$progdir\"; then
+      $MKDIR \"\$progdir\"
+    else
+      $RM \"\$progdir/\$file\"
+    fi"
 
-	# Restore the uninstalled library and exit
-	if test "$mode" = relink; then
-	  $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
+	  $ECHO "\
 
-	  if test -n "$convenience"; then
-	    if test -z "$whole_archive_flag_spec"; then
-	      $show "${rm}r $gentop"
-	      $run ${rm}r "$gentop"
-	    fi
-	  fi
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+	$ECHO \"\$relink_command_output\" >&2
+	$RM \"\$progdir/\$file\"
+	exit 1
+      fi
+    fi
 
-	  exit $EXIT_SUCCESS
+    $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $RM \"\$progdir/\$program\";
+      $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $RM \"\$progdir/\$file\"
+  fi"
+	else
+	  $ECHO "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
 	fi
 
-	# Create links to the real library.
-	for linkname in $linknames; do
-	  if test "$realname" != "$linkname"; then
-	    $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
-	    $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
-	  fi
-	done
+	$ECHO "\
 
-	# If -module or -export-dynamic was specified, set the dlname.
-	if test "$module" = yes || test "$export_dynamic" = yes; then
-	  # On all known operating systems, these are identical.
-	  dlname="$soname"
+  if test -f \"\$progdir/\$program\"; then"
+
+	# fixup the dll searchpath if we need to.
+	#
+	# Fix the DLL searchpath if we need to.  Do this before prepending
+	# to shlibpath, because on Windows, both are PATH and uninstalled
+	# libraries must come first.
+	if test -n "$dllsearchpath"; then
+	  $ECHO "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
 	fi
-      fi
-      ;;
 
-    obj)
-      case " $deplibs" in
-      *\ -l* | *\ -L*)
-	$echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 ;;
-      esac
+	# Export our shlibpath_var if we have one.
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $ECHO "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
 
-      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
-	$echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
-      fi
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
 
-      if test -n "$rpath"; then
-	$echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
-      fi
+    export $shlibpath_var
+"
+	fi
 
-      if test -n "$xrpath"; then
-	$echo "$modename: warning: \`-R' is ignored for objects" 1>&2
-      fi
+	$ECHO "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+      func_exec_program \${1+\"\$@\"}
+    fi
+  else
+    # The program doesn't exist.
+    \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+    \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+    \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+}
 
-      if test -n "$vinfo"; then
-	$echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
-      fi
 
-      if test -n "$release"; then
-	$echo "$modename: warning: \`-release' is ignored for objects" 1>&2
-      fi
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+	cat <<EOF
 
-      case $output in
-      *.lo)
-	if test -n "$objs$old_deplibs"; then
-	  $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
-	  exit $EXIT_FAILURE
-	fi
-	libobj="$output"
-	obj=`$echo "X$output" | $Xsed -e "$lo2o"`
-	;;
-      *)
-	libobj=
-	obj="$output"
-	;;
-      esac
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
 
-      # Delete the old objects.
-      $run $rm $obj $libobj
+   The $output program cannot be directly executed until all the libtool
+   libraries that it depends on are installed.
 
-      # Objects from convenience libraries.  This assumes
-      # single-version convenience libraries.  Whenever we create
-      # different ones for PIC/non-PIC, this we'll have to duplicate
-      # the extraction.
-      reload_conv_objs=
-      gentop=
-      # reload_cmds runs $LD directly, so let us get rid of
-      # -Wl from whole_archive_flag_spec and hope we can get by with
-      # turning comma into space..
-      wl=
+   This wrapper executable should never be moved out of the build directory.
+   If it is, it will not operate correctly.
+*/
+EOF
+	    cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+#  include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
 
-      if test -n "$convenience"; then
-	if test -n "$whole_archive_flag_spec"; then
-	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
-	  reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
-	else
-	  gentop="$output_objdir/${obj}x"
-	  generated="$generated $gentop"
+/* declarations of non-ANSI functions */
+#if defined(__MINGW32__)
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined(__CYGWIN__)
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined (other platforms) ... */
+#endif
 
-	  func_extract_archives $gentop $convenience
-	  reload_conv_objs="$reload_objs $func_extract_archives_result"
-	fi
-      fi
+/* portability defines, excluding path handling macros */
+#if defined(_MSC_VER)
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+# define S_IXUSR _S_IEXEC
+# ifndef _INTPTR_T_DEFINED
+#  define _INTPTR_T_DEFINED
+#  define intptr_t int
+# endif
+#elif defined(__MINGW32__)
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+#elif defined(__CYGWIN__)
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined (other platforms) ... */
+#endif
 
-      # Create the old-style object.
-      reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
 
-      output="$obj"
-      cmds=$reload_cmds
-      save_ifs="$IFS"; IFS='~'
-      for cmd in $cmds; do
-	IFS="$save_ifs"
-	eval cmd=\"$cmd\"
-	$show "$cmd"
-	$run eval "$cmd" || exit $?
-      done
-      IFS="$save_ifs"
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
 
-      # Exit if we aren't doing a library object file.
-      if test -z "$libobj"; then
-	if test -n "$gentop"; then
-	  $show "${rm}r $gentop"
-	  $run ${rm}r $gentop
-	fi
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
 
-	exit $EXIT_SUCCESS
-      fi
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+#  define PATH_SEPARATOR_2 ';'
+# endif
+#endif
 
-      if test "$build_libtool_libs" != yes; then
-	if test -n "$gentop"; then
-	  $show "${rm}r $gentop"
-	  $run ${rm}r $gentop
-	fi
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
 
-	# Create an invalid libtool object if no PIC, so that we don't
-	# accidentally link it into a program.
-	# $show "echo timestamp > $libobj"
-	# $run eval "echo timestamp > $libobj" || exit $?
-	exit $EXIT_SUCCESS
-      fi
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
 
-      if test -n "$pic_flag" || test "$pic_mode" != default; then
-	# Only do commands if we really have different PIC objects.
-	reload_objs="$libobjs $reload_conv_objs"
-	output="$libobj"
-	cmds=$reload_cmds
-	save_ifs="$IFS"; IFS='~'
-	for cmd in $cmds; do
-	  IFS="$save_ifs"
-	  eval cmd=\"$cmd\"
-	  $show "$cmd"
-	  $run eval "$cmd" || exit $?
-	done
-	IFS="$save_ifs"
-      fi
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
 
-      if test -n "$gentop"; then
-	$show "${rm}r $gentop"
-	$run ${rm}r $gentop
-      fi
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
 
-      exit $EXIT_SUCCESS
-      ;;
+#if defined(LT_DEBUGWRAPPER)
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
 
-    prog)
-      case $host in
-	*cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;;
-      esac
-      if test -n "$vinfo"; then
-	$echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
-      fi
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
 
-      if test -n "$release"; then
-	$echo "$modename: warning: \`-release' is ignored for programs" 1>&2
-      fi
+	    cat <<EOF
+volatile const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
 
-      if test "$preload" = yes; then
-	if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown &&
-	   test "$dlopen_self_static" = unknown; then
-	  $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
-	fi
-      fi
+	    if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+              func_to_host_path "$temp_rpath"
+	      cat <<EOF
+const char * LIB_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * LIB_PATH_VALUE   = "";
+EOF
+	    fi
 
-      case $host in
-      *-*-rhapsody* | *-*-darwin1.[012])
-	# On Rhapsody replace the C library is the System framework
-	compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
-	finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
-	;;
-      esac
+	    if test -n "$dllsearchpath"; then
+              func_to_host_path "$dllsearchpath:"
+	      cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE   = "";
+EOF
+	    fi
 
-      case $host in
-      *darwin*)
-        # Don't allow lazy linking, it breaks C++ global constructors
-        if test "$tagname" = CXX ; then
-        compile_command="$compile_command ${wl}-bind_at_load"
-        finalize_command="$finalize_command ${wl}-bind_at_load"
-        fi
-        ;;
-      esac
+	    if test "$fast_install" = yes; then
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+	    else
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+	    fi
 
 
-      # move library search paths that coincide with paths to not yet
-      # installed libraries to the beginning of the library search list
-      new_libs=
-      for path in $notinst_path; do
-	case " $new_libs " in
-	*" -L$path/$objdir "*) ;;
-	*)
-	  case " $compile_deplibs " in
-	  *" -L$path/$objdir "*)
-	    new_libs="$new_libs -L$path/$objdir" ;;
-	  esac
-	  ;;
-	esac
-      done
-      for deplib in $compile_deplibs; do
-	case $deplib in
-	-L*)
-	  case " $new_libs " in
-	  *" $deplib "*) ;;
-	  *) new_libs="$new_libs $deplib" ;;
-	  esac
-	  ;;
-	*) new_libs="$new_libs $deplib" ;;
-	esac
-      done
-      compile_deplibs="$new_libs"
+	    cat <<"EOF"
 
+#define LTWRAPPER_OPTION_PREFIX         "--lt-"
 
-      compile_command="$compile_command $compile_deplibs"
-      finalize_command="$finalize_command $finalize_deplibs"
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt            = LTWRAPPER_OPTION_PREFIX "debug";
 
-      if test -n "$rpath$xrpath"; then
-	# If the user specified any rpath flags, then add them.
-	for libdir in $rpath $xrpath; do
-	  # This is the magic to use -rpath.
-	  case "$finalize_rpath " in
-	  *" $libdir "*) ;;
-	  *) finalize_rpath="$finalize_rpath $libdir" ;;
-	  esac
-	done
-      fi
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int  newargc;
+  char *tmp_pathspec;
+  char *actual_cwrapper_path;
+  char *actual_cwrapper_name;
+  char *target_name;
+  char *lt_argv_zero;
+  intptr_t rval = 127;
 
-      # Now hardcode the library paths
-      rpath=
-      hardcode_libdirs=
-      for libdir in $compile_rpath $finalize_rpath; do
-	if test -n "$hardcode_libdir_flag_spec"; then
-	  if test -n "$hardcode_libdir_separator"; then
-	    if test -z "$hardcode_libdirs"; then
-	      hardcode_libdirs="$libdir"
-	    else
-	      # Just accumulate the unique libdirs.
-	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
-	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
-		;;
-	      *)
-		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+  int i;
+
+  program_name = (char *) xstrdup (base_name (argv[0]));
+  newargz = XMALLOC (char *, argc + 1);
+
+  /* very simple arg parsing; don't want to rely on getopt
+   * also, copy all non cwrapper options to newargz, except
+   * argz[0], which is handled differently
+   */
+  newargc=0;
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[i], dumpscript_opt) == 0)
+	{
+EOF
+	    case "$host" in
+	      *mingw* | *cygwin* )
+		# make stdout use "unix" line endings
+		echo "          setmode(1,_O_BINARY);"
 		;;
 	      esac
-	    fi
-	  else
-	    eval flag=\"$hardcode_libdir_flag_spec\"
-	    rpath="$rpath $flag"
-	  fi
-	elif test -n "$runpath_var"; then
-	  case "$perm_rpath " in
-	  *" $libdir "*) ;;
-	  *) perm_rpath="$perm_rpath $libdir" ;;
-	  esac
-	fi
-	case $host in
-	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
-	  testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'`
-	  case :$dllsearchpath: in
-	  *":$libdir:"*) ;;
-	  *) dllsearchpath="$dllsearchpath:$libdir";;
-	  esac
-	  case :$dllsearchpath: in
-	  *":$testbindir:"*) ;;
-	  *) dllsearchpath="$dllsearchpath:$testbindir";;
-	  esac
-	  ;;
-	esac
-      done
-      # Substitute the hardcoded libdirs into the rpath.
-      if test -n "$hardcode_libdir_separator" &&
-	 test -n "$hardcode_libdirs"; then
-	libdir="$hardcode_libdirs"
-	eval rpath=\" $hardcode_libdir_flag_spec\"
-      fi
-      compile_rpath="$rpath"
 
-      rpath=
-      hardcode_libdirs=
-      for libdir in $finalize_rpath; do
-	if test -n "$hardcode_libdir_flag_spec"; then
-	  if test -n "$hardcode_libdir_separator"; then
-	    if test -z "$hardcode_libdirs"; then
-	      hardcode_libdirs="$libdir"
-	    else
-	      # Just accumulate the unique libdirs.
-	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
-	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
-		;;
-	      *)
-		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
-		;;
-	      esac
-	    fi
-	  else
-	    eval flag=\"$hardcode_libdir_flag_spec\"
-	    rpath="$rpath $flag"
-	  fi
-	elif test -n "$runpath_var"; then
-	  case "$finalize_perm_rpath " in
-	  *" $libdir "*) ;;
-	  *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
-	  esac
-	fi
-      done
-      # Substitute the hardcoded libdirs into the rpath.
-      if test -n "$hardcode_libdir_separator" &&
-	 test -n "$hardcode_libdirs"; then
-	libdir="$hardcode_libdirs"
-	eval rpath=\" $hardcode_libdir_flag_spec\"
-      fi
-      finalize_rpath="$rpath"
+	    cat <<"EOF"
+	  lt_dump_script (stdout);
+	  return 0;
+	}
+      if (strcmp (argv[i], debug_opt) == 0)
+	{
+          lt_debug = 1;
+          continue;
+	}
+      if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
+        {
+          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+             namespace, but it is not one of the ones we know about and
+             have already dealt with, above (inluding dump-script), then
+             report an error. Otherwise, targets might begin to believe
+             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+             namespace. The first time any user complains about this, we'll
+             need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+             or a configure.ac-settable value.
+           */
+          lt_fatal (__FILE__, __LINE__,
+		    "unrecognized %s option: '%s'",
+                    ltwrapper_option_prefix, argv[i]);
+        }
+      /* otherwise ... */
+      newargz[++newargc] = xstrdup (argv[i]);
+    }
+  newargz[++newargc] = NULL;
 
-      if test -n "$libobjs" && test "$build_old_libs" = yes; then
-	# Transform all the library objects into standard objects.
-	compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-	finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-      fi
+EOF
+	    cat <<EOF
+  /* The GNU banner must be the first non-error debug message */
+  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
+EOF
+	    cat <<"EOF"
+  lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+  tmp_pathspec = find_executable (argv[0]);
+  if (tmp_pathspec == NULL)
+    lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (before symlink chase) at: %s\n",
+		  tmp_pathspec);
+
+  actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (after symlink chase) at: %s\n",
+		  actual_cwrapper_path);
+  XFREE (tmp_pathspec);
+
+  actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+  strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+  /* wrapper name transforms */
+  strendzap (actual_cwrapper_name, ".exe");
+  tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+  XFREE (actual_cwrapper_name);
+  actual_cwrapper_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  /* target_name transforms -- use actual target program name; might have lt- prefix */
+  target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+  strendzap (target_name, ".exe");
+  tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+  XFREE (target_name);
+  target_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(main) libtool target name: %s\n",
+		  target_name);
+EOF
 
-      dlsyms=
-      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
-	if test -n "$NM" && test -n "$global_symbol_pipe"; then
-	  dlsyms="${outputname}S.c"
-	else
-	  $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
-	fi
-      fi
+	    cat <<EOF
+  newargz[0] =
+    XMALLOC (char, (strlen (actual_cwrapper_path) +
+		    strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+  strcpy (newargz[0], actual_cwrapper_path);
+  strcat (newargz[0], "$objdir");
+  strcat (newargz[0], "/");
+EOF
 
-      if test -n "$dlsyms"; then
-	case $dlsyms in
-	"") ;;
-	*.c)
-	  # Discover the nlist of each of the dlfiles.
-	  nlist="$output_objdir/${outputname}.nm"
+	    cat <<"EOF"
+  /* stop here, and copy so we don't have to do this twice */
+  tmp_pathspec = xstrdup (newargz[0]);
 
-	  $show "$rm $nlist ${nlist}S ${nlist}T"
-	  $run $rm "$nlist" "${nlist}S" "${nlist}T"
+  /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+  strcat (newargz[0], actual_cwrapper_name);
 
-	  # Parse the name list into a source file.
-	  $show "creating $output_objdir/$dlsyms"
+  /* DO want the lt- prefix here if it exists, so use target_name */
+  lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+  XFREE (tmp_pathspec);
+  tmp_pathspec = NULL;
+EOF
 
-	  test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
-/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
-/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+	    case $host_os in
+	      mingw*)
+	    cat <<"EOF"
+  {
+    char* p;
+    while ((p = strchr (newargz[0], '\\')) != NULL)
+      {
+	*p = '/';
+      }
+    while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+      {
+	*p = '/';
+      }
+  }
+EOF
+	    ;;
+	    esac
 
-#ifdef __cplusplus
-extern \"C\" {
-#endif
+	    cat <<"EOF"
+  XFREE (target_name);
+  XFREE (actual_cwrapper_path);
+  XFREE (actual_cwrapper_name);
+
+  lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+  lt_setenv ("DUALCASE", "1");  /* for MSK sh */
+  /* Update the DLL searchpath.  EXE_PATH_VALUE ($dllsearchpath) must
+     be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+     because on Windows, both *_VARNAMEs are PATH but uninstalled
+     libraries must come first. */
+  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+  lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+		  nonnull (lt_argv_zero));
+  for (i = 0; i < newargc; i++)
+    {
+      lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+		      i, nonnull (newargz[i]));
+    }
 
-/* Prevent the only kind of declaration conflicts we can make. */
-#define lt_preloaded_symbols some_other_symbol
+EOF
 
-/* External symbol declarations for the compiler. */\
-"
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+  /* execv doesn't actually work on mingw as expected on unix */
+  newargz = prepare_spawn (newargz);
+  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+  if (rval == -1)
+    {
+      /* failed to start process */
+      lt_debugprintf (__FILE__, __LINE__,
+		      "(main) failed to launch target \"%s\": %s\n",
+		      lt_argv_zero, nonnull (strerror (errno)));
+      return 127;
+    }
+  return rval;
+EOF
+		;;
+	      *)
+		cat <<"EOF"
+  execv (lt_argv_zero, newargz);
+  return rval; /* =127, but avoids unused variable warning */
+EOF
+		;;
+	    esac
 
-	  if test "$dlself" = yes; then
-	    $show "generating symbol list for \`$output'"
+	    cat <<"EOF"
+}
 
-	    test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+void *
+xmalloc (size_t num)
+{
+  void *p = (void *) malloc (num);
+  if (!p)
+    lt_fatal (__FILE__, __LINE__, "memory exhausted");
 
-	    # Add our own program objects to the symbol list.
-	    progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-	    for arg in $progfiles; do
-	      $show "extracting global C symbols from \`$arg'"
-	      $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
-	    done
+  return p;
+}
 
-	    if test -n "$exclude_expsyms"; then
-	      $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
-	      $run eval '$mv "$nlist"T "$nlist"'
-	    fi
+char *
+xstrdup (const char *string)
+{
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+			  string) : NULL;
+}
 
-	    if test -n "$export_symbols_regex"; then
-	      $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
-	      $run eval '$mv "$nlist"T "$nlist"'
-	    fi
+const char *
+base_name (const char *name)
+{
+  const char *base;
 
-	    # Prepare the list of exported symbols
-	    if test -z "$export_symbols"; then
-	      export_symbols="$output_objdir/$outputname.exp"
-	      $run $rm $export_symbols
-	      $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
-              case $host in
-              *cygwin* | *mingw* )
-	        $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
-		$run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
-                ;;
-              esac
-	    else
-	      $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
-	      $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
-	      $run eval 'mv "$nlist"T "$nlist"'
-              case $host in
-              *cygwin* | *mingw* )
-	        $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
-		$run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
-                ;;
-              esac
-	    fi
-	  fi
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  /* Skip over the disk name in MSDOS pathnames. */
+  if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+    name += 2;
+#endif
 
-	  for arg in $dlprefiles; do
-	    $show "extracting global C symbols from \`$arg'"
-	    name=`$echo "$arg" | ${SED} -e 's%^.*/%%'`
-	    $run eval '$echo ": $name " >> "$nlist"'
-	    $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
-	  done
+  for (base = name; *name; name++)
+    if (IS_DIR_SEPARATOR (*name))
+      base = name + 1;
+  return base;
+}
 
-	  if test -z "$run"; then
-	    # Make sure we have at least an empty file.
-	    test -f "$nlist" || : > "$nlist"
+int
+check_executable (const char *path)
+{
+  struct stat st;
 
-	    if test -n "$exclude_expsyms"; then
-	      $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
-	      $mv "$nlist"T "$nlist"
-	    fi
+  lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
 
-	    # Try sorting and uniquifying the output.
-	    if grep -v "^: " < "$nlist" |
-		if sort -k 3 </dev/null >/dev/null 2>&1; then
-		  sort -k 3
-		else
-		  sort +2
-		fi |
-		uniq > "$nlist"S; then
-	      :
-	    else
-	      grep -v "^: " < "$nlist" > "$nlist"S
-	    fi
+  if ((stat (path, &st) >= 0)
+      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+    return 1;
+  else
+    return 0;
+}
 
-	    if test -f "$nlist"S; then
-	      eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
-	    else
-	      $echo '/* NONE */' >> "$output_objdir/$dlsyms"
-	    fi
+int
+make_executable (const char *path)
+{
+  int rval = 0;
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
 
-	    $echo >> "$output_objdir/$dlsyms" "\
+  if (stat (path, &st) >= 0)
+    {
+      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+    }
+  return rval;
+}
 
-#undef lt_preloaded_symbols
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise
+   Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+  int has_slash = 0;
+  const char *p;
+  const char *p_next;
+  /* static buffer for getcwd */
+  char tmp[LT_PATHMAX + 1];
+  int tmp_len;
+  char *concat_name;
 
-#if defined (__STDC__) && __STDC__
-# define lt_ptr void *
-#else
-# define lt_ptr char *
-# define const
-#endif
+  lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+                  nonempty (wrapper));
 
-/* The mapping between symbol names and symbols. */
-"
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
 
-	    case $host in
-	    *cygwin* | *mingw* )
-	  $echo >> "$output_objdir/$dlsyms" "\
-/* DATA imports from DLLs on WIN32 can't be const, because
-   runtime relocations are performed -- see ld's documentation
-   on pseudo-relocs */
-struct {
-"
-	      ;;
-	    * )
-	  $echo >> "$output_objdir/$dlsyms" "\
-const struct {
-"
-	      ;;
-	    esac
+  /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable (concat_name))
+	return concat_name;
+      XFREE (concat_name);
+    }
+  else
+    {
+#endif
+      if (IS_DIR_SEPARATOR (wrapper[0]))
+	{
+	  concat_name = xstrdup (wrapper);
+	  if (check_executable (concat_name))
+	    return concat_name;
+	  XFREE (concat_name);
+	}
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+    }
+#endif
 
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+      {
+	has_slash = 1;
+	break;
+      }
+  if (!has_slash)
+    {
+      /* no slashes; search PATH */
+      const char *path = getenv ("PATH");
+      if (path != NULL)
+	{
+	  for (p = path; *p; p = p_next)
+	    {
+	      const char *q;
+	      size_t p_len;
+	      for (q = p; *q; q++)
+		if (IS_PATH_SEPARATOR (*q))
+		  break;
+	      p_len = q - p;
+	      p_next = (*q == '\0' ? q : q + 1);
+	      if (p_len == 0)
+		{
+		  /* empty path: current directory */
+		  if (getcwd (tmp, LT_PATHMAX) == NULL)
+		    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+                              nonnull (strerror (errno)));
+		  tmp_len = strlen (tmp);
+		  concat_name =
+		    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, tmp, tmp_len);
+		  concat_name[tmp_len] = '/';
+		  strcpy (concat_name + tmp_len + 1, wrapper);
+		}
+	      else
+		{
+		  concat_name =
+		    XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, p, p_len);
+		  concat_name[p_len] = '/';
+		  strcpy (concat_name + p_len + 1, wrapper);
+		}
+	      if (check_executable (concat_name))
+		return concat_name;
+	      XFREE (concat_name);
+	    }
+	}
+      /* not found in PATH; assume curdir */
+    }
+  /* Relative path | not found in path: prepend cwd */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+              nonnull (strerror (errno)));
+  tmp_len = strlen (tmp);
+  concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
 
-	  $echo >> "$output_objdir/$dlsyms" "\
-  const char *name;
-  lt_ptr address;
+  if (check_executable (concat_name))
+    return concat_name;
+  XFREE (concat_name);
+  return NULL;
 }
-lt_preloaded_symbols[] =
-{\
-"
 
-	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+  return xstrdup (pathspec);
+#else
+  char buf[LT_PATHMAX];
+  struct stat s;
+  char *tmp_pathspec = xstrdup (pathspec);
+  char *p;
+  int has_symlinks = 0;
+  while (strlen (tmp_pathspec) && !has_symlinks)
+    {
+      lt_debugprintf (__FILE__, __LINE__,
+		      "checking path component for symlinks: %s\n",
+		      tmp_pathspec);
+      if (lstat (tmp_pathspec, &s) == 0)
+	{
+	  if (S_ISLNK (s.st_mode) != 0)
+	    {
+	      has_symlinks = 1;
+	      break;
+	    }
 
-	    $echo >> "$output_objdir/$dlsyms" "\
-  {0, (lt_ptr) 0}
-};
+	  /* search backwards for last DIR_SEPARATOR */
+	  p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+	  while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    p--;
+	  if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    {
+	      /* no more DIR_SEPARATORS left */
+	      break;
+	    }
+	  *p = '\0';
+	}
+      else
+	{
+	  lt_fatal (__FILE__, __LINE__,
+		    "error accessing file \"%s\": %s",
+		    tmp_pathspec, nonnull (strerror (errno)));
+	}
+    }
+  XFREE (tmp_pathspec);
 
-/* This works around a problem in FreeBSD linker */
-#ifdef FREEBSD_WORKAROUND
-static const void *lt_preloaded_setup() {
-  return lt_preloaded_symbols;
-}
-#endif
+  if (!has_symlinks)
+    {
+      return xstrdup (pathspec);
+    }
 
-#ifdef __cplusplus
+  tmp_pathspec = realpath (pathspec, buf);
+  if (tmp_pathspec == 0)
+    {
+      lt_fatal (__FILE__, __LINE__,
+		"could not follow symlinks for %s", pathspec);
+    }
+  return xstrdup (tmp_pathspec);
+#endif
 }
-#endif\
-"
-	  fi
 
-	  pic_flag_for_symtable=
-	  case $host in
-	  # compiling the symbol table file with pic_flag works around
-	  # a FreeBSD bug that causes programs to crash when -lm is
-	  # linked before any other PIC object.  But we must not use
-	  # pic_flag when linking with -static.  The problem exists in
-	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
-	  *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
-	    case "$compile_command " in
-	    *" -static "*) ;;
-	    *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";;
-	    esac;;
-	  *-*-hpux*)
-	    case "$compile_command " in
-	    *" -static "*) ;;
-	    *) pic_flag_for_symtable=" $pic_flag";;
-	    esac
-	  esac
+char *
+strendzap (char *str, const char *pat)
+{
+  size_t len, patlen;
 
-	  # Now compile the dynamic symbol file.
-	  $show "(cd $output_objdir && $LTCC  $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
-	  $run eval '(cd $output_objdir && $LTCC  $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+  assert (str != NULL);
+  assert (pat != NULL);
 
-	  # Clean up the generated files.
-	  $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
-	  $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+  len = strlen (str);
+  patlen = strlen (pat);
 
-	  # Transform the symbol file into the correct name.
-          case $host in
-          *cygwin* | *mingw* )
-            if test -f "$output_objdir/${outputname}.def" ; then
-              compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP`
-              finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP`
-            else
-              compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
-              finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
-             fi
-            ;;
-          * )
-            compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
-            finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
-            ;;
-          esac
-	  ;;
-	*)
-	  $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
-      else
-	# We keep going just in case the user didn't refer to
-	# lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
-	# really was required.
+  if (patlen <= len)
+    {
+      str += len - patlen;
+      if (strcmp (str, pat) == 0)
+	*str = '\0';
+    }
+  return str;
+}
 
-	# Nullify the symbol file.
-	compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP`
-	finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP`
-      fi
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+  va_list args;
+  if (lt_debug)
+    {
+      (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+      va_start (args, fmt);
+      (void) vfprintf (stderr, fmt, args);
+      va_end (args);
+    }
+}
 
-      if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
-	# Replace the output file specification.
-	compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$output"'%g' | $NL2SP`
-	link_command="$compile_command$compile_rpath"
+static void
+lt_error_core (int exit_status, const char *file,
+	       int line, const char *mode,
+	       const char *message, va_list ap)
+{
+  fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
 
-	# We have no uninstalled library dependencies, so finalize right now.
-	$show "$link_command"
-	$run eval "$link_command"
-	exit_status=$?
+  if (exit_status >= 0)
+    exit (exit_status);
+}
 
-	# Delete the generated files.
-	if test -n "$dlsyms"; then
-	  $show "$rm $output_objdir/${outputname}S.${objext}"
-	  $run $rm "$output_objdir/${outputname}S.${objext}"
-	fi
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+  va_end (ap);
+}
 
-	exit $exit_status
-      fi
+static const char *
+nonnull (const char *s)
+{
+  return s ? s : "(null)";
+}
 
-      if test -n "$shlibpath_var"; then
-	# We should set the shlibpath_var
-	rpath=
-	for dir in $temp_rpath; do
-	  case $dir in
-	  [\\/]* | [A-Za-z]:[\\/]*)
-	    # Absolute path.
-	    rpath="$rpath$dir:"
-	    ;;
-	  *)
-	    # Relative path: add a thisdir entry.
-	    rpath="$rpath\$thisdir/$dir:"
-	    ;;
-	  esac
-	done
-	temp_rpath="$rpath"
-      fi
-
-      if test -n "$compile_shlibpath$finalize_shlibpath"; then
-	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
-      fi
-      if test -n "$finalize_shlibpath"; then
-	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
-      fi
-
-      compile_var=
-      finalize_var=
-      if test -n "$runpath_var"; then
-	if test -n "$perm_rpath"; then
-	  # We should set the runpath_var.
-	  rpath=
-	  for dir in $perm_rpath; do
-	    rpath="$rpath$dir:"
-	  done
-	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
-	fi
-	if test -n "$finalize_perm_rpath"; then
-	  # We should set the runpath_var.
-	  rpath=
-	  for dir in $finalize_perm_rpath; do
-	    rpath="$rpath$dir:"
-	  done
-	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
-	fi
-      fi
-
-      if test "$no_install" = yes; then
-	# We don't need to create a wrapper script.
-	link_command="$compile_var$compile_command$compile_rpath"
-	# Replace the output file specification.
-	link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
-	# Delete the old output file.
-	$run $rm $output
-	# Link the executable and exit
-	$show "$link_command"
-	$run eval "$link_command" || exit $?
-	exit $EXIT_SUCCESS
-      fi
-
-      if test "$hardcode_action" = relink; then
-	# Fast installation is not supported
-	link_command="$compile_var$compile_command$compile_rpath"
-	relink_command="$finalize_var$finalize_command$finalize_rpath"
-
-	$echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
-	$echo "$modename: \`$output' will be relinked during installation" 1>&2
-      else
-	if test "$fast_install" != no; then
-	  link_command="$finalize_var$compile_command$finalize_rpath"
-	  if test "$fast_install" = yes; then
-	    relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $SP2NL | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g' | $NL2SP`
-	  else
-	    # fast_install is set to needless
-	    relink_command=
-	  fi
-	else
-	  link_command="$compile_var$compile_command$compile_rpath"
-	  relink_command="$finalize_var$finalize_command$finalize_rpath"
-	fi
-      fi
-
-      # Replace the output file specification.
-      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
-
-      # Delete the old output files.
-      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
-
-      $show "$link_command"
-      $run eval "$link_command" || exit $?
-
-      # Now create the wrapper script.
-      $show "creating $output"
-
-      # Quote the relink command for shipping.
-      if test -n "$relink_command"; then
-	# Preserve any variables that may affect compiler behavior
-	for var in $variables_saved_for_relink; do
-	  if eval test -z \"\${$var+set}\"; then
-	    relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
-	  elif eval var_value=\$$var; test -z "$var_value"; then
-	    relink_command="$var=; export $var; $relink_command"
-	  else
-	    var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
-	    relink_command="$var=\"$var_value\"; export $var; $relink_command"
-	  fi
-	done
-	relink_command="(cd `pwd`; $relink_command)"
-	relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP`
-      fi
-
-      # Quote $echo for shipping.
-      if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then
-	case $progpath in
-	[\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
-	*) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
-	esac
-	qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
-      else
-	qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
-      fi
-
-      # Only actually do things if our run command is non-null.
-      if test -z "$run"; then
-	# win32 will think the script is a binary if it has
-	# a .exe suffix, so we strip it off here.
-	case $output in
-	  *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;;
-	esac
-	# test for cygwin because mv fails w/o .exe extensions
-	case $host in
-	  *cygwin*)
-	    exeext=.exe
-	    outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;;
-	  *) exeext= ;;
-	esac
-	case $host in
-	  *cygwin* | *mingw* )
-            output_name=`basename $output`
-            output_path=`dirname $output`
-            cwrappersource="$output_path/$objdir/lt-$output_name.c"
-            cwrapper="$output_path/$output_name.exe"
-            $rm $cwrappersource $cwrapper
-            trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
-
-	    cat > $cwrappersource <<EOF
-
-/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
-   Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
-
-   The $output program cannot be directly executed until all the libtool
-   libraries that it depends on are installed.
-
-   This wrapper executable should never be moved out of the build directory.
-   If it is, it will not operate correctly.
-
-   Currently, it simply execs the wrapper *script* "/bin/sh $output",
-   but could eventually absorb all of the scripts functionality and
-   exec $objdir/$outputname directly.
-*/
-EOF
-	    cat >> $cwrappersource<<"EOF"
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <malloc.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/stat.h>
+static const char *
+nonempty (const char *s)
+{
+  return (s && !*s) ? "(empty)" : nonnull (s);
+}
 
-#if defined(PATH_MAX)
-# define LT_PATHMAX PATH_MAX
-#elif defined(MAXPATHLEN)
-# define LT_PATHMAX MAXPATHLEN
+void
+lt_setenv (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_setenv) setting '%s' to '%s'\n",
+                  nonnull (name), nonnull (value));
+  {
+#ifdef HAVE_SETENV
+    /* always make a copy, for consistency with !HAVE_SETENV */
+    char *str = xstrdup (value);
+    setenv (name, str, 1);
 #else
-# define LT_PATHMAX 1024
-#endif
-
-#ifndef DIR_SEPARATOR
-# define DIR_SEPARATOR '/'
-# define PATH_SEPARATOR ':'
-#endif
-
-#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
-  defined (__OS2__)
-# define HAVE_DOS_BASED_FILE_SYSTEM
-# ifndef DIR_SEPARATOR_2
-#  define DIR_SEPARATOR_2 '\\'
-# endif
-# ifndef PATH_SEPARATOR_2
-#  define PATH_SEPARATOR_2 ';'
-# endif
+    int len = strlen (name) + 1 + strlen (value) + 1;
+    char *str = XMALLOC (char, len);
+    sprintf (str, "%s=%s", name, value);
+    if (putenv (str) != EXIT_SUCCESS)
+      {
+        XFREE (str);
+      }
 #endif
+  }
+}
 
-#ifndef DIR_SEPARATOR_2
-# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
-#else /* DIR_SEPARATOR_2 */
-# define IS_DIR_SEPARATOR(ch) \
-        (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
-#endif /* DIR_SEPARATOR_2 */
-
-#ifndef PATH_SEPARATOR_2
-# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
-#else /* PATH_SEPARATOR_2 */
-# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
-#endif /* PATH_SEPARATOR_2 */
-
-#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
-#define XFREE(stale) do { \
-  if (stale) { free ((void *) stale); stale = 0; } \
-} while (0)
-
-/* -DDEBUG is fairly common in CFLAGS.  */
-#undef DEBUG
-#if defined DEBUGWRAPPER
-# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__)
-#else
-# define DEBUG(format, ...)
-#endif
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+  char *new_value;
+  if (orig_value && *orig_value)
+    {
+      int orig_value_len = strlen (orig_value);
+      int add_len = strlen (add);
+      new_value = XMALLOC (char, add_len + orig_value_len + 1);
+      if (to_end)
+        {
+          strcpy (new_value, orig_value);
+          strcpy (new_value + orig_value_len, add);
+        }
+      else
+        {
+          strcpy (new_value, add);
+          strcpy (new_value + add_len, orig_value);
+        }
+    }
+  else
+    {
+      new_value = xstrdup (add);
+    }
+  return new_value;
+}
 
-const char *program_name = NULL;
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
 
-void * xmalloc (size_t num);
-char * xstrdup (const char *string);
-const char * base_name (const char *name);
-char * find_executable(const char *wrapper);
-int    check_executable(const char *path);
-char * strendzap(char *str, const char *pat);
-void lt_fatal (const char *message, ...);
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      /* some systems can't cope with a ':'-terminated path #' */
+      int len = strlen (new_value);
+      while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+        {
+          new_value[len-1] = '\0';
+        }
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
 
-int
-main (int argc, char *argv[])
+void
+lt_update_lib_path (const char *name, const char *value)
 {
-  char **newargz;
-  int i;
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
 
-  program_name = (char *) xstrdup (base_name (argv[0]));
-  DEBUG("(main) argv[0]      : %s\n",argv[0]);
-  DEBUG("(main) program_name : %s\n",program_name);
-  newargz = XMALLOC(char *, argc+2);
-EOF
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
 
-            cat >> $cwrappersource <<EOF
-  newargz[0] = (char *) xstrdup("$SHELL");
 EOF
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+   Note that spawn() does not by itself call the command interpreter
+     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+         GetVersionEx(&v);
+         v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+      }) ? "cmd.exe" : "command.com").
+   Instead it simply concatenates the arguments, separated by ' ', and calls
+   CreateProcess().  We must quote the arguments since Win32 CreateProcess()
+   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+   special way:
+   - Space and tab are interpreted as delimiters. They are not treated as
+     delimiters if they are surrounded by double quotes: "...".
+   - Unescaped double quotes are removed from the input. Their only effect is
+     that within double quotes, space and tab are treated like normal
+     characters.
+   - Backslashes not followed by double quotes are not special.
+   - But 2*n+1 backslashes followed by a double quote become
+     n backslashes followed by a double quote (n >= 0):
+       \" -> "
+       \\\" -> \"
+       \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+  size_t argc;
+  char **new_argv;
+  size_t i;
 
-            cat >> $cwrappersource <<"EOF"
-  newargz[1] = find_executable(argv[0]);
-  if (newargz[1] == NULL)
-    lt_fatal("Couldn't find %s", argv[0]);
-  DEBUG("(main) found exe at : %s\n",newargz[1]);
-  /* we know the script has the same name, without the .exe */
-  /* so make sure newargz[1] doesn't end in .exe */
-  strendzap(newargz[1],".exe");
-  for (i = 1; i < argc; i++)
-    newargz[i+1] = xstrdup(argv[i]);
-  newargz[argc+1] = NULL;
-
-  for (i=0; i<argc+1; i++)
-  {
-    DEBUG("(main) newargz[%d]   : %s\n",i,newargz[i]);
+  /* Count number of arguments.  */
+  for (argc = 0; argv[argc] != NULL; argc++)
     ;
-  }
 
-EOF
-
-            case $host_os in
-              mingw*)
-                cat >> $cwrappersource <<EOF
-  execv("$SHELL",(char const **)newargz);
-EOF
-              ;;
-              *)
-                cat >> $cwrappersource <<EOF
-  execv("$SHELL",newargz);
-EOF
-              ;;
-            esac
+  /* Allocate new argument vector.  */
+  new_argv = XMALLOC (char *, argc + 1);
 
-            cat >> $cwrappersource <<"EOF"
-  return 127;
-}
+  /* Put quoted arguments into the new argument vector.  */
+  for (i = 0; i < argc; i++)
+    {
+      const char *string = argv[i];
+
+      if (string[0] == '\0')
+	new_argv[i] = xstrdup ("\"\"");
+      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+	{
+	  int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+	  size_t length;
+	  unsigned int backslashes;
+	  const char *s;
+	  char *quoted_string;
+	  char *p;
+
+	  length = 0;
+	  backslashes = 0;
+	  if (quote_around)
+	    length++;
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		length += backslashes + 1;
+	      length++;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    length += backslashes + 1;
+
+	  quoted_string = XMALLOC (char, length + 1);
+
+	  p = quoted_string;
+	  backslashes = 0;
+	  if (quote_around)
+	    *p++ = '"';
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		{
+		  unsigned int j;
+		  for (j = backslashes + 1; j > 0; j--)
+		    *p++ = '\\';
+		}
+	      *p++ = c;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    {
+	      unsigned int j;
+	      for (j = backslashes; j > 0; j--)
+		*p++ = '\\';
+	      *p++ = '"';
+	    }
+	  *p = '\0';
 
-void *
-xmalloc (size_t num)
-{
-  void * p = (void *) malloc (num);
-  if (!p)
-    lt_fatal ("Memory exhausted");
+	  new_argv[i] = quoted_string;
+	}
+      else
+	new_argv[i] = (char *) string;
+    }
+  new_argv[argc] = NULL;
 
-  return p;
+  return new_argv;
 }
+EOF
+		;;
+	    esac
 
-char *
-xstrdup (const char *string)
+            cat <<"EOF"
+void lt_dump_script (FILE* f)
 {
-  return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL
-;
+EOF
+	    func_emit_wrapper yes |
+	      $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/  fputs ("\1", f);/p
+g
+D'
+            cat <<"EOF"
 }
-
-const char *
-base_name (const char *name)
-{
-  const char *base;
-
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
-  /* Skip over the disk name in MSDOS pathnames. */
-  if (isalpha ((unsigned char)name[0]) && name[1] == ':')
-    name += 2;
-#endif
-
-  for (base = name; *name; name++)
-    if (IS_DIR_SEPARATOR (*name))
-      base = name + 1;
-  return base;
+EOF
 }
+# end: func_emit_cwrapperexe_src
 
-int
-check_executable(const char * path)
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
 {
-  struct stat st;
-
-  DEBUG("(check_executable)  : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!");
-  if ((!path) || (!*path))
-    return 0;
-
-  if ((stat (path, &st) >= 0) &&
-      (
-        /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */
-#if defined (S_IXOTH)
-       ((st.st_mode & S_IXOTH) == S_IXOTH) ||
-#endif
-#if defined (S_IXGRP)
-       ((st.st_mode & S_IXGRP) == S_IXGRP) ||
-#endif
-       ((st.st_mode & S_IXUSR) == S_IXUSR))
-      )
-    return 1;
-  else
-    return 0;
+    $opt_debug
+    case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+    *import*) : ;;
+    *) false ;;
+    esac
 }
 
-/* Searches for the full path of the wrapper.  Returns
-   newly allocated full path name if found, NULL otherwise */
-char *
-find_executable (const char* wrapper)
+# func_mode_link arg...
+func_mode_link ()
 {
-  int has_slash = 0;
-  const char* p;
-  const char* p_next;
-  /* static buffer for getcwd */
-  char tmp[LT_PATHMAX + 1];
-  int tmp_len;
-  char* concat_name;
+    $opt_debug
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
 
-  DEBUG("(find_executable)  : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!");
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args=$nonopt
+    base_compile="$nonopt $@"
+    compile_command=$nonopt
+    finalize_command=$nonopt
 
-  if ((wrapper == NULL) || (*wrapper == '\0'))
-    return NULL;
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+    new_inherited_linker_flags=
 
-  /* Absolute path? */
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
-  if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':')
-  {
-    concat_name = xstrdup (wrapper);
-    if (check_executable(concat_name))
-      return concat_name;
-    XFREE(concat_name);
-  }
-  else
-  {
-#endif
-    if (IS_DIR_SEPARATOR (wrapper[0]))
-    {
-      concat_name = xstrdup (wrapper);
-      if (check_executable(concat_name))
-        return concat_name;
-      XFREE(concat_name);
-    }
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
-  }
-#endif
+    avoid_version=no
+    bindir=
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    non_pic_objects=
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+    weak_libs=
+    single_module="${wl}-single_module"
+    func_infer_tag $base_compile
 
-  for (p = wrapper; *p; p++)
-    if (*p == '/')
-    {
-      has_slash = 1;
-      break;
-    }
-  if (!has_slash)
-  {
-    /* no slashes; search PATH */
-    const char* path = getenv ("PATH");
-    if (path != NULL)
-    {
-      for (p = path; *p; p = p_next)
-      {
-        const char* q;
-        size_t p_len;
-        for (q = p; *q; q++)
-          if (IS_PATH_SEPARATOR(*q))
-            break;
-        p_len = q - p;
-        p_next = (*q == '\0' ? q : q + 1);
-        if (p_len == 0)
-        {
-          /* empty path: current directory */
-          if (getcwd (tmp, LT_PATHMAX) == NULL)
-            lt_fatal ("getcwd failed");
-          tmp_len = strlen(tmp);
-          concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
-          memcpy (concat_name, tmp, tmp_len);
-          concat_name[tmp_len] = '/';
-          strcpy (concat_name + tmp_len + 1, wrapper);
-        }
-        else
-        {
-          concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1);
-          memcpy (concat_name, p, p_len);
-          concat_name[p_len] = '/';
-          strcpy (concat_name + p_len + 1, wrapper);
-        }
-        if (check_executable(concat_name))
-          return concat_name;
-        XFREE(concat_name);
-      }
-    }
-    /* not found in PATH; assume curdir */
-  }
-  /* Relative path | not found in path: prepend cwd */
-  if (getcwd (tmp, LT_PATHMAX) == NULL)
-    lt_fatal ("getcwd failed");
-  tmp_len = strlen(tmp);
-  concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
-  memcpy (concat_name, tmp, tmp_len);
-  concat_name[tmp_len] = '/';
-  strcpy (concat_name + tmp_len + 1, wrapper);
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -shared)
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
+	build_old_libs=no
+	break
+	;;
+      -all-static | -static | -static-libtool-libs)
+	case $arg in
+	-all-static)
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+	    func_warning "complete static linking is impossible in this configuration"
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	-static)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=built
+	  ;;
+	-static-libtool-libs)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	esac
+	build_libtool_libs=no
+	build_old_libs=yes
+	break
+	;;
+      esac
+    done
 
-  if (check_executable(concat_name))
-    return concat_name;
-  XFREE(concat_name);
-  return NULL;
-}
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
 
-char *
-strendzap(char *str, const char *pat)
-{
-  size_t len, patlen;
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg="$1"
+      shift
+      func_quote_for_eval "$arg"
+      qarg=$func_quote_for_eval_unquoted_result
+      func_append libtool_args " $func_quote_for_eval_result"
 
-  assert(str != NULL);
-  assert(pat != NULL);
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case $prev in
+	output)
+	  func_append compile_command " @OUTPUT@"
+	  func_append finalize_command " @OUTPUT@"
+	  ;;
+	esac
 
-  len = strlen(str);
-  patlen = strlen(pat);
+	case $prev in
+	bindir)
+	  bindir="$arg"
+	  prev=
+	  continue
+	  ;;
+	dlfiles|dlprefiles)
+	  if test "$preload" = no; then
+	    # Add the symbol object into the linking commands.
+	    func_append compile_command " @SYMFILE@"
+	    func_append finalize_command " @SYMFILE@"
+	    preload=yes
+	  fi
+	  case $arg in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  force)
+	    if test "$dlself" = no; then
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  self)
+	    if test "$prev" = dlprefiles; then
+	      dlself=yes
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test "$prev" = dlfiles; then
+	      func_append dlfiles " $arg"
+	    else
+	      func_append dlprefiles " $arg"
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols="$arg"
+	  test -f "$arg" \
+	    || func_fatal_error "symbol file \`$arg' does not exist"
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	framework)
+	  case $host in
+	    *-*-darwin*)
+	      case "$deplibs " in
+		*" $qarg.ltframework "*) ;;
+		*) func_append deplibs " $qarg.ltframework" # this is fixed later
+		   ;;
+	      esac
+	      ;;
+	  esac
+	  prev=
+	  continue
+	  ;;
+	inst_prefix)
+	  inst_prefix_dir="$arg"
+	  prev=
+	  continue
+	  ;;
+	objectlist)
+	  if test -f "$arg"; then
+	    save_arg=$arg
+	    moreargs=
+	    for fil in `cat "$save_arg"`
+	    do
+#	      func_append moreargs " $fil"
+	      arg=$fil
+	      # A libtool-controlled object.
 
-  if (patlen <= len)
-  {
-    str += len - patlen;
-    if (strcmp(str, pat) == 0)
-      *str = '\0';
-  }
-  return str;
-}
+	      # Check to see that this really is a libtool object.
+	      if func_lalib_unsafe_p "$arg"; then
+		pic_object=
+		non_pic_object=
 
-static void
-lt_error_core (int exit_status, const char * mode,
-          const char * message, va_list ap)
-{
-  fprintf (stderr, "%s: %s: ", program_name, mode);
-  vfprintf (stderr, message, ap);
-  fprintf (stderr, ".\n");
+		# Read the .lo file
+		func_source "$arg"
 
-  if (exit_status >= 0)
-    exit (exit_status);
-}
+		if test -z "$pic_object" ||
+		   test -z "$non_pic_object" ||
+		   test "$pic_object" = none &&
+		   test "$non_pic_object" = none; then
+		  func_fatal_error "cannot find name of object for \`$arg'"
+		fi
 
-void
-lt_fatal (const char *message, ...)
-{
-  va_list ap;
-  va_start (ap, message);
-  lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
-  va_end (ap);
-}
-EOF
-          # we should really use a build-platform specific compiler
-          # here, but OTOH, the wrappers (shell script and this C one)
-          # are only useful if you want to execute the "real" binary.
-          # Since the "real" binary is built for $host, then this
-          # wrapper might as well be built for $host, too.
-          $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource
-          ;;
-        esac
-        $rm $output
-        trap "$rm $output; exit $EXIT_FAILURE" 1 2 15
+		# Extract subdirectory from the argument.
+		func_dirname "$arg" "/" ""
+		xdir="$func_dirname_result"
 
-	$echo > $output "\
-#! $SHELL
+		if test "$pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  pic_object="$xdir$pic_object"
 
-# $output - temporary wrapper script for $objdir/$outputname
-# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
-#
-# The $output program cannot be directly executed until all the libtool
-# libraries that it depends on are installed.
-#
-# This wrapper script should never be moved out of the build directory.
-# If it is, it will not operate correctly.
+		  if test "$prev" = dlfiles; then
+		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		      func_append dlfiles " $pic_object"
+		      prev=
+		      continue
+		    else
+		      # If libtool objects are unsupported, then we need to preload.
+		      prev=dlprefiles
+		    fi
+		  fi
 
-# Sed substitution that helps us do robust quoting.  It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed='${SED} -e 1s/^X//'
-sed_quote_subst='$sed_quote_subst'
+		  # CHECK ME:  I think I busted this.  -Ossama
+		  if test "$prev" = dlprefiles; then
+		    # Preload the old-style object.
+		    func_append dlprefiles " $pic_object"
+		    prev=
+		  fi
 
-# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).
-if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
-  emulate sh
-  NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '\${1+\"\$@\"}'='\"\$@\"'
-  setopt NO_GLOB_SUBST
-else
-  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
-fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
+		  # A PIC object.
+		  func_append libobjs " $pic_object"
+		  arg="$pic_object"
+		fi
 
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+		# Non-PIC object.
+		if test "$non_pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  non_pic_object="$xdir$non_pic_object"
 
-relink_command=\"$relink_command\"
+		  # A standard non-PIC object
+		  func_append non_pic_objects " $non_pic_object"
+		  if test -z "$pic_object" || test "$pic_object" = none ; then
+		    arg="$non_pic_object"
+		  fi
+		else
+		  # If the PIC object exists, use it instead.
+		  # $xdir was prepended to $pic_object above.
+		  non_pic_object="$pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+		fi
+	      else
+		# Only an error if not doing a dry-run.
+		if $opt_dry_run; then
+		  # Extract subdirectory from the argument.
+		  func_dirname "$arg" "/" ""
+		  xdir="$func_dirname_result"
+
+		  func_lo2o "$arg"
+		  pic_object=$xdir$objdir/$func_lo2o_result
+		  non_pic_object=$xdir$func_lo2o_result
+		  func_append libobjs " $pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+	        else
+		  func_fatal_error "\`$arg' is not a valid libtool object"
+		fi
+	      fi
+	    done
+	  else
+	    func_fatal_error "link input file \`$arg' does not exist"
+	  fi
+	  arg=$save_arg
+	  prev=
+	  continue
+	  ;;
+	precious_regex)
+	  precious_files_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release="-$arg"
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case $arg in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    func_fatal_error "only absolute run-paths are allowed"
+	    ;;
+	  esac
+	  if test "$prev" = rpath; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) func_append rpath " $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) func_append xrpath " $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	shrext)
+	  shrext_cmds="$arg"
+	  prev=
+	  continue
+	  ;;
+	weak)
+	  func_append weak_libs " $arg"
+	  prev=
+	  continue
+	  ;;
+	xcclinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xcompiler)
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xlinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $wl$qarg"
+	  prev=
+	  func_append compile_command " $wl$qarg"
+	  func_append finalize_command " $wl$qarg"
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi # test -n "$prev"
 
-# This environment variable determines our operation mode.
-if test \"\$libtool_install_magic\" = \"$magic\"; then
-  # install mode needs the following variable:
-  notinst_deplibs='$notinst_deplibs'
-else
-  # When we are sourced in execute mode, \$file and \$echo are already set.
-  if test \"\$libtool_execute_magic\" != \"$magic\"; then
-    echo=\"$qecho\"
-    file=\"\$0\"
-    # Make sure echo works.
-    if test \"X\$1\" = X--no-reexec; then
-      # Discard the --no-reexec flag, and continue.
-      shift
-    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
-      # Yippee, \$echo works!
-      :
-    else
-      # Restart under the correct shell, and then maybe \$echo will work.
-      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
-    fi
-  fi\
-"
-	$echo >> $output "\
+      prevarg="$arg"
 
-  # Find the directory that this script lives in.
-  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
-  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+      case $arg in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  # See comment for -static flag below, for more details.
+	  func_append compile_command " $link_static_flag"
+	  func_append finalize_command " $link_static_flag"
+	fi
+	continue
+	;;
 
-  # Follow symbolic links until we get to the real thisdir.
-  file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
-  while test -n \"\$file\"; do
-    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+	;;
 
-    # If there was a directory component, then change thisdir.
-    if test \"x\$destdir\" != \"x\$file\"; then
-      case \"\$destdir\" in
-      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
-      *) thisdir=\"\$thisdir/\$destdir\" ;;
-      esac
-    fi
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
 
-    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
-    file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
-  done
+      -bindir)
+	prev=bindir
+	continue
+	;;
 
-  # Try to get the absolute directory name.
-  absdir=\`cd \"\$thisdir\" && pwd\`
-  test -n \"\$absdir\" && thisdir=\"\$absdir\"
-"
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
 
-	if test "$fast_install" = yes; then
-	  $echo >> $output "\
-  program=lt-'$outputname'$exeext
-  progdir=\"\$thisdir/$objdir\"
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
 
-  if test ! -f \"\$progdir/\$program\" || \\
-     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
-       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
 
-    file=\"\$\$-\$program\"
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  func_fatal_error "more than one -exported-symbols argument is not allowed"
+	fi
+	if test "X$arg" = "X-export-symbols"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
 
-    if test ! -d \"\$progdir\"; then
-      $mkdir \"\$progdir\"
-    else
-      $rm \"\$progdir/\$file\"
-    fi"
+      -framework)
+	prev=framework
+	continue
+	;;
+
+      -inst-prefix-dir)
+	prev=inst_prefix
+	continue
+	;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+	case $with_gcc/$host in
+	no/*-*-irix* | /*-*-irix*)
+	  func_append compile_command " $arg"
+	  func_append finalize_command " $arg"
+	  ;;
+	esac
+	continue
+	;;
+
+      -L*)
+	func_stripname "-L" '' "$arg"
+	if test -z "$func_stripname_result"; then
+	  if test "$#" -gt 0; then
+	    func_fatal_error "require no space between \`-L' and \`$1'"
+	  else
+	    func_fatal_error "need path for \`-L' option"
+	  fi
+	fi
+	func_resolve_sysroot "$func_stripname_result"
+	dir=$func_resolve_sysroot_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  test -z "$absdir" && \
+	    func_fatal_error "cannot determine absolute directory name of \`$dir'"
+	  dir="$absdir"
+	  ;;
+	esac
+	case "$deplibs " in
+	*" -L$dir "* | *" $arg "*)
+	  # Will only happen for absolute or sysroot arguments
+	  ;;
+	*)
+	  # Preserve sysroot, but never include relative directories
+	  case $dir in
+	    [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+	    *) func_append deplibs " -L$dir" ;;
+	  esac
+	  func_append lib_search_path " $dir"
+	  ;;
+	esac
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$dir:"*) ;;
+	  ::) dllsearchpath=$dir;;
+	  *) func_append dllsearchpath ":$dir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append dllsearchpath ":$testbindir";;
+	  esac
+	  ;;
+	esac
+	continue
+	;;
+
+      -l*)
+	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	    # These systems don't actually have a C or math library (as such)
+	    continue
+	    ;;
+	  *-*-os2*)
+	    # These systems don't actually have a C library (as such)
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C and math libraries are in the System framework
+	    func_append deplibs " System.ltframework"
+	    continue
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  esac
+	elif test "X$arg" = "X-lc_r"; then
+	 case $host in
+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	   # Do not include libc_r directly, use -pthread flag.
+	   continue
+	   ;;
+	 esac
+	fi
+	func_append deplibs " $arg"
+	continue
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      # Darwin uses the -arch flag to determine output architecture.
+      -model|-arch|-isysroot|--sysroot)
+	func_append compiler_flags " $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	prev=xcompiler
+	continue
+	;;
+
+      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+      |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+	func_append compiler_flags " $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	case "$new_inherited_linker_flags " in
+	    *" $arg "*) ;;
+	    * ) func_append new_inherited_linker_flags " $arg" ;;
+	esac
+	continue
+	;;
+
+      -multi_module)
+	single_module="${wl}-multi_module"
+	continue
+	;;
+
+      -no-fast-install)
+	fast_install=no
+	continue
+	;;
+
+      -no-install)
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+	  # The PATH hackery in wrapper scripts is required on Windows
+	  # and Darwin in order for the loader to find any dlls it needs.
+	  func_warning "\`-no-install' is ignored for $host"
+	  func_warning "assuming \`-no-fast-install' instead"
+	  fast_install=no
+	  ;;
+	*) no_install=yes ;;
+	esac
+	continue
+	;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -objectlist)
+	prev=objectlist
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -precious-files-regex)
+	prev=precious_regex
+	continue
+	;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+	prev=rpath
+	continue
+	;;
+
+      -R)
+	prev=xrpath
+	continue
+	;;
+
+      -R*)
+	func_stripname '-R' '' "$arg"
+	dir=$func_stripname_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	=*)
+	  func_stripname '=' '' "$dir"
+	  dir=$lt_sysroot$func_stripname_result
+	  ;;
+	*)
+	  func_fatal_error "only absolute run-paths are allowed"
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) func_append xrpath " $dir" ;;
+	esac
+	continue
+	;;
+
+      -shared)
+	# The effects of -shared are defined in a previous loop.
+	continue
+	;;
+
+      -shrext)
+	prev=shrext
+	continue
+	;;
+
+      -static | -static-libtool-libs)
+	# The effects of -static are defined in a previous loop.
+	# We used to do the same as -all-static on platforms that
+	# didn't have a PIC flag, but the assumption that the effects
+	# would be equivalent was wrong.  It would break on at least
+	# Digital Unix and AIX.
+	continue
+	;;
+
+      -thread-safe)
+	thread_safe=yes
+	continue
+	;;
+
+      -version-info)
+	prev=vinfo
+	continue
+	;;
+
+      -version-number)
+	prev=vinfo
+	vinfo_number=yes
+	continue
+	;;
+
+      -weak)
+        prev=weak
+	continue
+	;;
+
+      -Wc,*)
+	func_stripname '-Wc,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+	  func_append arg " $func_quote_for_eval_result"
+	  func_append compiler_flags " $func_quote_for_eval_result"
+	done
+	IFS="$save_ifs"
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Wl,*)
+	func_stripname '-Wl,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+	  func_append arg " $wl$func_quote_for_eval_result"
+	  func_append compiler_flags " $wl$func_quote_for_eval_result"
+	  func_append linker_flags " $func_quote_for_eval_result"
+	done
+	IFS="$save_ifs"
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Xcompiler)
+	prev=xcompiler
+	continue
+	;;
+
+      -Xlinker)
+	prev=xlinker
+	continue
+	;;
+
+      -XCClinker)
+	prev=xcclinker
+	continue
+	;;
+
+      # -msg_* for osf cc
+      -msg_*)
+	func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+
+      # Flags to be passed through unchanged, with rationale:
+      # -64, -mips[0-9]      enable 64-bit mode for the SGI compiler
+      # -r[0-9][0-9]*        specify processor for the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+      # +DA*, +DD*           enable 64-bit mode for the HP compiler
+      # -q*                  compiler args for the IBM compiler
+      # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+      # -F/path              path to uninstalled frameworks, gcc on darwin
+      # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC
+      # @file                GCC response files
+      # -tp=*                Portland pgcc target processor selection
+      # --sysroot=*          for sysroot support
+      # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+      -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
+        func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+        func_append compile_command " $arg"
+        func_append finalize_command " $arg"
+        func_append compiler_flags " $arg"
+        continue
+        ;;
+
+      # Some other compiler flag.
+      -* | +*)
+        func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+
+      *.$objext)
+	# A standard object.
+	func_append objs " $arg"
+	;;
+
+      *.lo)
+	# A libtool-controlled object.
+
+	# Check to see that this really is a libtool object.
+	if func_lalib_unsafe_p "$arg"; then
+	  pic_object=
+	  non_pic_object=
+
+	  # Read the .lo file
+	  func_source "$arg"
+
+	  if test -z "$pic_object" ||
+	     test -z "$non_pic_object" ||
+	     test "$pic_object" = none &&
+	     test "$non_pic_object" = none; then
+	    func_fatal_error "cannot find name of object for \`$arg'"
+	  fi
+
+	  # Extract subdirectory from the argument.
+	  func_dirname "$arg" "/" ""
+	  xdir="$func_dirname_result"
+
+	  if test "$pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    pic_object="$xdir$pic_object"
+
+	    if test "$prev" = dlfiles; then
+	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		func_append dlfiles " $pic_object"
+		prev=
+		continue
+	      else
+		# If libtool objects are unsupported, then we need to preload.
+		prev=dlprefiles
+	      fi
+	    fi
+
+	    # CHECK ME:  I think I busted this.  -Ossama
+	    if test "$prev" = dlprefiles; then
+	      # Preload the old-style object.
+	      func_append dlprefiles " $pic_object"
+	      prev=
+	    fi
+
+	    # A PIC object.
+	    func_append libobjs " $pic_object"
+	    arg="$pic_object"
+	  fi
+
+	  # Non-PIC object.
+	  if test "$non_pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    non_pic_object="$xdir$non_pic_object"
+
+	    # A standard non-PIC object
+	    func_append non_pic_objects " $non_pic_object"
+	    if test -z "$pic_object" || test "$pic_object" = none ; then
+	      arg="$non_pic_object"
+	    fi
+	  else
+	    # If the PIC object exists, use it instead.
+	    # $xdir was prepended to $pic_object above.
+	    non_pic_object="$pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  fi
+	else
+	  # Only an error if not doing a dry-run.
+	  if $opt_dry_run; then
+	    # Extract subdirectory from the argument.
+	    func_dirname "$arg" "/" ""
+	    xdir="$func_dirname_result"
+
+	    func_lo2o "$arg"
+	    pic_object=$xdir$objdir/$func_lo2o_result
+	    non_pic_object=$xdir$func_lo2o_result
+	    func_append libobjs " $pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  else
+	    func_fatal_error "\`$arg' is not a valid libtool object"
+	  fi
+	fi
+	;;
+
+      *.$libext)
+	# An archive.
+	func_append deplibs " $arg"
+	func_append old_deplibs " $arg"
+	continue
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	func_resolve_sysroot "$arg"
+	if test "$prev" = dlfiles; then
+	  # This library was specified with -dlopen.
+	  func_append dlfiles " $func_resolve_sysroot_result"
+	  prev=
+	elif test "$prev" = dlprefiles; then
+	  # The library was specified with -dlpreopen.
+	  func_append dlprefiles " $func_resolve_sysroot_result"
+	  prev=
+	else
+	  func_append deplibs " $func_resolve_sysroot_result"
+	fi
+	continue
+	;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+      fi
+    done # argument parsing loop
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prevarg' option requires an argument"
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      func_append compile_command " $arg"
+      func_append finalize_command " $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    func_basename "$output"
+    outputname="$func_basename_result"
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    func_dirname "$output" "/" ""
+    output_objdir="$func_dirname_result$objdir"
+    func_to_tool_file "$output_objdir/"
+    tool_output_objdir=$func_to_tool_file_result
+    # Create the object directory.
+    func_mkdir_p "$output_objdir"
+
+    # Determine the type of output
+    case $output in
+    "")
+      func_fatal_help "you must specify an output file"
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if $opt_preserve_dup_deps ; then
+	case "$libs " in
+	*" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	esac
+      fi
+      func_append libs " $deplib"
+    done
+
+    if test "$linkmode" = lib; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if $opt_duplicate_compiler_generated_deps; then
+	for pre_post_dep in $predeps $postdeps; do
+	  case "$pre_post_deps " in
+	  *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+	  esac
+	  func_append pre_post_deps " $pre_post_dep"
+	done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    notinst_path= # paths that contain not-installed libtool libraries
+
+    case $linkmode in
+    lib)
+	passes="conv dlpreopen link"
+	for file in $dlfiles $dlprefiles; do
+	  case $file in
+	  *.la) ;;
+	  *)
+	    func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+	    ;;
+	  esac
+	done
+	;;
+    prog)
+	compile_deplibs=
+	finalize_deplibs=
+	alldeplibs=no
+	newdlfiles=
+	newdlprefiles=
+	passes="conv scan dlopen dlpreopen link"
+	;;
+    *)  passes="conv"
+	;;
+    esac
+
+    for pass in $passes; do
+      # The preopen pass in lib mode reverses $deplibs; put it back here
+      # so that -L comes before libs that need it for instance...
+      if test "$linkmode,$pass" = "lib,link"; then
+	## FIXME: Find the place where the list is rebuilt in the wrong
+	##        order, and fix it there properly
+        tmp_deplibs=
+	for deplib in $deplibs; do
+	  tmp_deplibs="$deplib $tmp_deplibs"
+	done
+	deplibs="$tmp_deplibs"
+      fi
+
+      if test "$linkmode,$pass" = "lib,link" ||
+	 test "$linkmode,$pass" = "prog,scan"; then
+	libs="$deplibs"
+	deplibs=
+      fi
+      if test "$linkmode" = prog; then
+	case $pass in
+	dlopen) libs="$dlfiles" ;;
+	dlpreopen) libs="$dlprefiles" ;;
+	link)
+	  libs="$deplibs %DEPLIBS%"
+	  test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+	  ;;
+	esac
+      fi
+      if test "$linkmode,$pass" = "lib,dlpreopen"; then
+	# Collect and forward deplibs of preopened libtool libs
+	for lib in $dlprefiles; do
+	  # Ignore non-libtool-libs
+	  dependency_libs=
+	  func_resolve_sysroot "$lib"
+	  case $lib in
+	  *.la)	func_source "$func_resolve_sysroot_result" ;;
+	  esac
+
+	  # Collect preopened libtool deplibs, except any this library
+	  # has declared as weak libs
+	  for deplib in $dependency_libs; do
+	    func_basename "$deplib"
+            deplib_base=$func_basename_result
+	    case " $weak_libs " in
+	    *" $deplib_base "*) ;;
+	    *) func_append deplibs " $deplib" ;;
+	    esac
+	  done
+	done
+	libs="$dlprefiles"
+      fi
+      if test "$pass" = dlopen; then
+	# Collect dlpreopened libraries
+	save_deplibs="$deplibs"
+	deplibs=
+      fi
+
+      for deplib in $libs; do
+	lib=
+	found=no
+	case $deplib in
+	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+        |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    func_append compiler_flags " $deplib"
+	    if test "$linkmode" = lib ; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-l*)
+	  if test "$linkmode" != lib && test "$linkmode" != prog; then
+	    func_warning "\`-l' is ignored for archives/objects"
+	    continue
+	  fi
+	  func_stripname '-l' '' "$deplib"
+	  name=$func_stripname_result
+	  if test "$linkmode" = lib; then
+	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+	  else
+	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+	  fi
+	  for searchdir in $searchdirs; do
+	    for search_ext in .la $std_shrext .so .a; do
+	      # Search the libtool library
+	      lib="$searchdir/lib${name}${search_ext}"
+	      if test -f "$lib"; then
+		if test "$search_ext" = ".la"; then
+		  found=yes
+		else
+		  found=no
+		fi
+		break 2
+	      fi
+	    done
+	  done
+	  if test "$found" != yes; then
+	    # deplib doesn't seem to be a libtool library
+	    if test "$linkmode,$pass" = "prog,link"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  else # deplib is a libtool library
+	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+	    # We need to do some special things here, and not later.
+	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	      case " $predeps $postdeps " in
+	      *" $deplib "*)
+		if func_lalib_p "$lib"; then
+		  library_names=
+		  old_library=
+		  func_source "$lib"
+		  for l in $old_library $library_names; do
+		    ll="$l"
+		  done
+		  if test "X$ll" = "X$old_library" ; then # only static version available
+		    found=no
+		    func_dirname "$lib" "" "."
+		    ladir="$func_dirname_result"
+		    lib=$ladir/$old_library
+		    if test "$linkmode,$pass" = "prog,link"; then
+		      compile_deplibs="$deplib $compile_deplibs"
+		      finalize_deplibs="$deplib $finalize_deplibs"
+		    else
+		      deplibs="$deplib $deplibs"
+		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+		    fi
+		    continue
+		  fi
+		fi
+		;;
+	      *) ;;
+	      esac
+	    fi
+	  fi
+	  ;; # -l
+	*.ltframework)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    deplibs="$deplib $deplibs"
+	    if test "$linkmode" = lib ; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-L*)
+	  case $linkmode in
+	  lib)
+	    deplibs="$deplib $deplibs"
+	    test "$pass" = conv && continue
+	    newdependency_libs="$deplib $newdependency_libs"
+	    func_stripname '-L' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    func_append newlib_search_path " $func_resolve_sysroot_result"
+	    ;;
+	  prog)
+	    if test "$pass" = conv; then
+	      deplibs="$deplib $deplibs"
+	      continue
+	    fi
+	    if test "$pass" = scan; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    func_stripname '-L' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    func_append newlib_search_path " $func_resolve_sysroot_result"
+	    ;;
+	  *)
+	    func_warning "\`-L' is ignored for archives/objects"
+	    ;;
+	  esac # linkmode
+	  continue
+	  ;; # -L
+	-R*)
+	  if test "$pass" = link; then
+	    func_stripname '-R' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    dir=$func_resolve_sysroot_result
+	    # Make sure the xrpath contains only unique directories.
+	    case "$xrpath " in
+	    *" $dir "*) ;;
+	    *) func_append xrpath " $dir" ;;
+	    esac
+	  fi
+	  deplibs="$deplib $deplibs"
+	  continue
+	  ;;
+	*.la)
+	  func_resolve_sysroot "$deplib"
+	  lib=$func_resolve_sysroot_result
+	  ;;
+	*.$libext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  case $linkmode in
+	  lib)
+	    # Linking convenience modules into shared libraries is allowed,
+	    # but linking other static libraries is non-portable.
+	    case " $dlpreconveniencelibs " in
+	    *" $deplib "*) ;;
+	    *)
+	      valid_a_lib=no
+	      case $deplibs_check_method in
+		match_pattern*)
+		  set dummy $deplibs_check_method; shift
+		  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+		  if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+		    | $EGREP "$match_pattern_regex" > /dev/null; then
+		    valid_a_lib=yes
+		  fi
+		;;
+		pass_all)
+		  valid_a_lib=yes
+		;;
+	      esac
+	      if test "$valid_a_lib" != yes; then
+		echo
+		$ECHO "*** Warning: Trying to link with static lib archive $deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because the file extensions .$libext of this argument makes me believe"
+		echo "*** that it is just a static archive that I should not use here."
+	      else
+		echo
+		$ECHO "*** Warning: Linking the shared library $output against the"
+		$ECHO "*** static library $deplib is not portable!"
+		deplibs="$deplib $deplibs"
+	      fi
+	      ;;
+	    esac
+	    continue
+	    ;;
+	  prog)
+	    if test "$pass" != link; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    continue
+	    ;;
+	  esac # linkmode
+	  ;; # *.$libext
+	*.lo | *.$objext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	  elif test "$linkmode" = prog; then
+	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+	      # If there is no dlopen support or we're linking statically,
+	      # we need to preload.
+	      func_append newdlprefiles " $deplib"
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      func_append newdlfiles " $deplib"
+	    fi
+	  fi
+	  continue
+	  ;;
+	%DEPLIBS%)
+	  alldeplibs=yes
+	  continue
+	  ;;
+	esac # case $deplib
+
+	if test "$found" = yes || test -f "$lib"; then :
+	else
+	  func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+	fi
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$lib" \
+	  || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+	func_dirname "$lib" "" "."
+	ladir="$func_dirname_result"
+
+	dlname=
+	dlopen=
+	dlpreopen=
+	libdir=
+	library_names=
+	old_library=
+	inherited_linker_flags=
+	# If the library was installed with an old release of libtool,
+	# it will not redefine variables installed, or shouldnotlink
+	installed=yes
+	shouldnotlink=no
+	avoidtemprpath=
+
+
+	# Read the .la file
+	func_source "$lib"
+
+	# Convert "-framework foo" to "foo.ltframework"
+	if test -n "$inherited_linker_flags"; then
+	  tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+	  for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+	    case " $new_inherited_linker_flags " in
+	      *" $tmp_inherited_linker_flag "*) ;;
+	      *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+	    esac
+	  done
+	fi
+	dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	if test "$linkmode,$pass" = "lib,link" ||
+	   test "$linkmode,$pass" = "prog,scan" ||
+	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+	  test -n "$dlopen" && func_append dlfiles " $dlopen"
+	  test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+	fi
+
+	if test "$pass" = conv; then
+	  # Only check for convenience libraries
+	  deplibs="$lib $deplibs"
+	  if test -z "$libdir"; then
+	    if test -z "$old_library"; then
+	      func_fatal_error "cannot find name of link library for \`$lib'"
+	    fi
+	    # It is a libtool convenience library, so add in its objects.
+	    func_append convenience " $ladir/$objdir/$old_library"
+	    func_append old_convenience " $ladir/$objdir/$old_library"
+	    tmp_libs=
+	    for deplib in $dependency_libs; do
+	      deplibs="$deplib $deplibs"
+	      if $opt_preserve_dup_deps ; then
+		case "$tmp_libs " in
+		*" $deplib "*) func_append specialdeplibs " $deplib" ;;
+		esac
+	      fi
+	      func_append tmp_libs " $deplib"
+	    done
+	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
+	    func_fatal_error "\`$lib' is not a convenience library"
+	  fi
+	  continue
+	fi # $pass = conv
+
+
+	# Get the name of the library we link against.
+	linklib=
+	if test -n "$old_library" &&
+	   { test "$prefer_static_libs" = yes ||
+	     test "$prefer_static_libs,$installed" = "built,no"; }; then
+	  linklib=$old_library
+	else
+	  for l in $old_library $library_names; do
+	    linklib="$l"
+	  done
+	fi
+	if test -z "$linklib"; then
+	  func_fatal_error "cannot find name of link library for \`$lib'"
+	fi
+
+	# This library was specified with -dlopen.
+	if test "$pass" = dlopen; then
+	  if test -z "$libdir"; then
+	    func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+	  fi
+	  if test -z "$dlname" ||
+	     test "$dlopen_support" != yes ||
+	     test "$build_libtool_libs" = no; then
+	    # If there is no dlname, no dlopen support or we're linking
+	    # statically, we need to preload.  We also need to preload any
+	    # dependent libraries so libltdl's deplib preloader doesn't
+	    # bomb out in the load deplibs phase.
+	    func_append dlprefiles " $lib $dependency_libs"
+	  else
+	    func_append newdlfiles " $lib"
+	  fi
+	  continue
+	fi # $pass = dlopen
+
+	# We need an absolute path.
+	case $ladir in
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+	*)
+	  abs_ladir=`cd "$ladir" && pwd`
+	  if test -z "$abs_ladir"; then
+	    func_warning "cannot determine absolute directory name of \`$ladir'"
+	    func_warning "passing it literally to the linker, although it might fail"
+	    abs_ladir="$ladir"
+	  fi
+	  ;;
+	esac
+	func_basename "$lib"
+	laname="$func_basename_result"
+
+	# Find the relevant object directory and library name.
+	if test "X$installed" = Xyes; then
+	  if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    func_warning "library \`$lib' was moved."
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    libdir="$abs_ladir"
+	  else
+	    dir="$lt_sysroot$libdir"
+	    absdir="$lt_sysroot$libdir"
+	  fi
+	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+	else
+	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    # Remove this search path later
+	    func_append notinst_path " $abs_ladir"
+	  else
+	    dir="$ladir/$objdir"
+	    absdir="$abs_ladir/$objdir"
+	    # Remove this search path later
+	    func_append notinst_path " $abs_ladir"
+	  fi
+	fi # $installed = yes
+	func_stripname 'lib' '.la' "$laname"
+	name=$func_stripname_result
+
+	# This library was specified with -dlpreopen.
+	if test "$pass" = dlpreopen; then
+	  if test -z "$libdir" && test "$linkmode" = prog; then
+	    func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+	  fi
+	  case "$host" in
+	    # special handling for platforms with PE-DLLs.
+	    *cygwin* | *mingw* | *cegcc* )
+	      # Linker will automatically link against shared library if both
+	      # static and shared are present.  Therefore, ensure we extract
+	      # symbols from the import library if a shared library is present
+	      # (otherwise, the dlopen module name will be incorrect).  We do
+	      # this by putting the import library name into $newdlprefiles.
+	      # We recover the dlopen module name by 'saving' the la file
+	      # name in a special purpose variable, and (later) extracting the
+	      # dlname from the la file.
+	      if test -n "$dlname"; then
+	        func_tr_sh "$dir/$linklib"
+	        eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+	        func_append newdlprefiles " $dir/$linklib"
+	      else
+	        func_append newdlprefiles " $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          func_append dlpreconveniencelibs " $dir/$old_library"
+	      fi
+	    ;;
+	    * )
+	      # Prefer using a static library (so that no silly _DYNAMIC symbols
+	      # are required to link).
+	      if test -n "$old_library"; then
+	        func_append newdlprefiles " $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          func_append dlpreconveniencelibs " $dir/$old_library"
+	      # Otherwise, use the dlname, so that lt_dlopen finds it.
+	      elif test -n "$dlname"; then
+	        func_append newdlprefiles " $dir/$dlname"
+	      else
+	        func_append newdlprefiles " $dir/$linklib"
+	      fi
+	    ;;
+	  esac
+	fi # $pass = dlpreopen
+
+	if test -z "$libdir"; then
+	  # Link the convenience library
+	  if test "$linkmode" = lib; then
+	    deplibs="$dir/$old_library $deplibs"
+	  elif test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$dir/$old_library $compile_deplibs"
+	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
+	  else
+	    deplibs="$lib $deplibs" # used for prog,scan pass
+	  fi
+	  continue
+	fi
+
+
+	if test "$linkmode" = prog && test "$pass" != link; then
+	  func_append newlib_search_path " $ladir"
+	  deplibs="$lib $deplibs"
+
+	  linkalldeplibs=no
+	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
+	     test "$build_libtool_libs" = no; then
+	    linkalldeplibs=yes
+	  fi
+
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    case $deplib in
+	    -L*) func_stripname '-L' '' "$deplib"
+	         func_resolve_sysroot "$func_stripname_result"
+	         func_append newlib_search_path " $func_resolve_sysroot_result"
+		 ;;
+	    esac
+	    # Need to link against all dependency_libs?
+	    if test "$linkalldeplibs" = yes; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      # Need to hardcode shared library paths
+	      # or/and link against static libraries
+	      newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    if $opt_preserve_dup_deps ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $deplib"
+	  done # for deplib
+	  continue
+	fi # $linkmode = prog...
+
+	if test "$linkmode,$pass" = "prog,link"; then
+	  if test -n "$library_names" &&
+	     { { test "$prefer_static_libs" = no ||
+	         test "$prefer_static_libs,$installed" = "built,yes"; } ||
+	       test -z "$old_library"; }; then
+	    # We need to hardcode the library path
+	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+	      # Make sure the rpath contains only unique directories.
+	      case "$temp_rpath:" in
+	      *"$absdir:"*) ;;
+	      *) func_append temp_rpath "$absdir:" ;;
+	      esac
+	    fi
+
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) func_append compile_rpath " $absdir" ;;
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append finalize_rpath " $libdir" ;;
+	      esac
+	      ;;
+	    esac
+	  fi # $linkmode,$pass = prog,link...
+
+	  if test "$alldeplibs" = yes &&
+	     { test "$deplibs_check_method" = pass_all ||
+	       { test "$build_libtool_libs" = yes &&
+		 test -n "$library_names"; }; }; then
+	    # We only need to search for static libraries
+	    continue
+	  fi
+	fi
+
+	link_static=no # Whether the deplib will be linked statically
+	use_static_libs=$prefer_static_libs
+	if test "$use_static_libs" = built && test "$installed" = yes; then
+	  use_static_libs=no
+	fi
+	if test -n "$library_names" &&
+	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
+	  case $host in
+	  *cygwin* | *mingw* | *cegcc*)
+	      # No point in relinking DLLs because paths are not encoded
+	      func_append notinst_deplibs " $lib"
+	      need_relink=no
+	    ;;
+	  *)
+	    if test "$installed" = no; then
+	      func_append notinst_deplibs " $lib"
+	      need_relink=yes
+	    fi
+	    ;;
+	  esac
+	  # This is a shared library
+
+	  # Warn about portability, can't link against -module's on some
+	  # systems (darwin).  Don't bleat about dlopened modules though!
+	  dlopenmodule=""
+	  for dlpremoduletest in $dlprefiles; do
+	    if test "X$dlpremoduletest" = "X$lib"; then
+	      dlopenmodule="$dlpremoduletest"
+	      break
+	    fi
+	  done
+	  if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+	    echo
+	    if test "$linkmode" = prog; then
+	      $ECHO "*** Warning: Linking the executable $output against the loadable module"
+	    else
+	      $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+	    fi
+	    $ECHO "*** $linklib is not portable!"
+	  fi
+	  if test "$linkmode" = lib &&
+	     test "$hardcode_into_libs" = yes; then
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) func_append compile_rpath " $absdir" ;;
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append finalize_rpath " $libdir" ;;
+	      esac
+	      ;;
+	    esac
+	  fi
+
+	  if test -n "$old_archive_from_expsyms_cmds"; then
+	    # figure out the soname
+	    set dummy $library_names
+	    shift
+	    realname="$1"
+	    shift
+	    libname=`eval "\\$ECHO \"$libname_spec\""`
+	    # use dlname if we got it. it's perfectly good, no?
+	    if test -n "$dlname"; then
+	      soname="$dlname"
+	    elif test -n "$soname_spec"; then
+	      # bleh windows
+	      case $host in
+	      *cygwin* | mingw* | *cegcc*)
+	        func_arith $current - $age
+		major=$func_arith_result
+		versuffix="-$major"
+		;;
+	      esac
+	      eval soname=\"$soname_spec\"
+	    else
+	      soname="$realname"
+	    fi
+
+	    # Make a new name for the extract_expsyms_cmds to use
+	    soroot="$soname"
+	    func_basename "$soroot"
+	    soname="$func_basename_result"
+	    func_stripname 'lib' '.dll' "$soname"
+	    newlib=libimp-$func_stripname_result.a
+
+	    # If the library has no export list, then create one now
+	    if test -f "$output_objdir/$soname-def"; then :
+	    else
+	      func_verbose "extracting exported symbol list from \`$soname'"
+	      func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+	    fi
+
+	    # Create $newlib
+	    if test -f "$output_objdir/$newlib"; then :; else
+	      func_verbose "generating import library for \`$soname'"
+	      func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+	    fi
+	    # make sure the library variables are pointing to the new library
+	    dir=$output_objdir
+	    linklib=$newlib
+	  fi # test -n "$old_archive_from_expsyms_cmds"
+
+	  if test "$linkmode" = prog || test "$opt_mode" != relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    lib_linked=yes
+	    case $hardcode_action in
+	    immediate | unsupported)
+	      if test "$hardcode_direct" = no; then
+		add="$dir/$linklib"
+		case $host in
+		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+		    *-*-unixware7*) add_dir="-L$dir" ;;
+		  *-*-darwin* )
+		    # if the lib is a (non-dlopened) module then we can not
+		    # link against it, someone is ignoring the earlier warnings
+		    if /usr/bin/file -L $add 2> /dev/null |
+			 $GREP ": [^:]* bundle" >/dev/null ; then
+		      if test "X$dlopenmodule" != "X$lib"; then
+			$ECHO "*** Warning: lib $linklib is a module, not a shared library"
+			if test -z "$old_library" ; then
+			  echo
+			  echo "*** And there doesn't seem to be a static archive available"
+			  echo "*** The link will probably fail, sorry"
+			else
+			  add="$dir/$old_library"
+			fi
+		      elif test -n "$old_library"; then
+			add="$dir/$old_library"
+		      fi
+		    fi
+		esac
+	      elif test "$hardcode_minus_L" = no; then
+		case $host in
+		*-*-sunos*) add_shlibpath="$dir" ;;
+		esac
+		add_dir="-L$dir"
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = no; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    relink)
+	      if test "$hardcode_direct" = yes &&
+	         test "$hardcode_direct_absolute" = no; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = yes; then
+		add_dir="-L$absdir"
+		# Try looking first in the location we're being installed to.
+		if test -n "$inst_prefix_dir"; then
+		  case $libdir in
+		    [\\/]*)
+		      func_append add_dir " -L$inst_prefix_dir$libdir"
+		      ;;
+		  esac
+		fi
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = yes; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    *) lib_linked=no ;;
+	    esac
+
+	    if test "$lib_linked" != yes; then
+	      func_fatal_configuration "unsupported hardcode properties"
+	    fi
+
+	    if test -n "$add_shlibpath"; then
+	      case :$compile_shlibpath: in
+	      *":$add_shlibpath:"*) ;;
+	      *) func_append compile_shlibpath "$add_shlibpath:" ;;
+	      esac
+	    fi
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	      if test "$hardcode_direct" != yes &&
+		 test "$hardcode_minus_L" != yes &&
+		 test "$hardcode_shlibpath_var" = yes; then
+		case :$finalize_shlibpath: in
+		*":$libdir:"*) ;;
+		*) func_append finalize_shlibpath "$libdir:" ;;
+		esac
+	      fi
+	    fi
+	  fi
+
+	  if test "$linkmode" = prog || test "$opt_mode" = relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    # Finalize command for both is simple: just hardcode it.
+	    if test "$hardcode_direct" = yes &&
+	       test "$hardcode_direct_absolute" = no; then
+	      add="$libdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      add_dir="-L$libdir"
+	      add="-l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
+	      case :$finalize_shlibpath: in
+	      *":$libdir:"*) ;;
+	      *) func_append finalize_shlibpath "$libdir:" ;;
+	      esac
+	      add="-l$name"
+	    elif test "$hardcode_automatic" = yes; then
+	      if test -n "$inst_prefix_dir" &&
+		 test -f "$inst_prefix_dir$libdir/$linklib" ; then
+		add="$inst_prefix_dir$libdir/$linklib"
+	      else
+		add="$libdir/$linklib"
+	      fi
+	    else
+	      # We cannot seem to hardcode it, guess we'll fake it.
+	      add_dir="-L$libdir"
+	      # Try looking first in the location we're being installed to.
+	      if test -n "$inst_prefix_dir"; then
+		case $libdir in
+		  [\\/]*)
+		    func_append add_dir " -L$inst_prefix_dir$libdir"
+		    ;;
+		esac
+	      fi
+	      add="-l$name"
+	    fi
+
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	    fi
+	  fi
+	elif test "$linkmode" = prog; then
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
+	    compile_deplibs="$dir/$linklib $compile_deplibs"
+	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
+	  else
+	    compile_deplibs="-l$name -L$dir $compile_deplibs"
+	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+	  fi
+	elif test "$build_libtool_libs" = yes; then
+	  # Not a shared library
+	  if test "$deplibs_check_method" != pass_all; then
+	    # We're trying link a shared library against a static one
+	    # but the system doesn't support it.
+
+	    # Just print a warning and add the library to dependency_libs so
+	    # that the program can be linked against the static library.
+	    echo
+	    $ECHO "*** Warning: This system can not link to static lib archive $lib."
+	    echo "*** I have the capability to make that library automatically link in when"
+	    echo "*** you link to this library.  But I can only do this if you have a"
+	    echo "*** shared version of the library, which you do not appear to have."
+	    if test "$module" = yes; then
+	      echo "*** But as you try to build a module library, libtool will still create "
+	      echo "*** a static module, that should work as long as the dlopening application"
+	      echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+	      if test -z "$global_symbol_pipe"; then
+		echo
+		echo "*** However, this would only work if libtool was able to extract symbol"
+		echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+		echo "*** not find such a program.  So, this module is probably useless."
+		echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	      fi
+	      if test "$build_old_libs" = no; then
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  else
+	    deplibs="$dir/$old_library $deplibs"
+	    link_static=yes
+	  fi
+	fi # link shared/static library?
+
+	if test "$linkmode" = lib; then
+	  if test -n "$dependency_libs" &&
+	     { test "$hardcode_into_libs" != yes ||
+	       test "$build_old_libs" = yes ||
+	       test "$link_static" = yes; }; then
+	    # Extract -R from dependency_libs
+	    temp_deplibs=
+	    for libdir in $dependency_libs; do
+	      case $libdir in
+	      -R*) func_stripname '-R' '' "$libdir"
+	           temp_xrpath=$func_stripname_result
+		   case " $xrpath " in
+		   *" $temp_xrpath "*) ;;
+		   *) func_append xrpath " $temp_xrpath";;
+		   esac;;
+	      *) func_append temp_deplibs " $libdir";;
+	      esac
+	    done
+	    dependency_libs="$temp_deplibs"
+	  fi
+
+	  func_append newlib_search_path " $absdir"
+	  # Link against this library
+	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+	  # ... and its dependency_libs
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    newdependency_libs="$deplib $newdependency_libs"
+	    case $deplib in
+              -L*) func_stripname '-L' '' "$deplib"
+                   func_resolve_sysroot "$func_stripname_result";;
+              *) func_resolve_sysroot "$deplib" ;;
+            esac
+	    if $opt_preserve_dup_deps ; then
+	      case "$tmp_libs " in
+	      *" $func_resolve_sysroot_result "*)
+                func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $func_resolve_sysroot_result"
+	  done
+
+	  if test "$link_all_deplibs" != no; then
+	    # Add the search paths of all dependency libraries
+	    for deplib in $dependency_libs; do
+	      path=
+	      case $deplib in
+	      -L*) path="$deplib" ;;
+	      *.la)
+	        func_resolve_sysroot "$deplib"
+	        deplib=$func_resolve_sysroot_result
+	        func_dirname "$deplib" "" "."
+		dir=$func_dirname_result
+		# We need an absolute path.
+		case $dir in
+		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+		*)
+		  absdir=`cd "$dir" && pwd`
+		  if test -z "$absdir"; then
+		    func_warning "cannot determine absolute directory name of \`$dir'"
+		    absdir="$dir"
+		  fi
+		  ;;
+		esac
+		if $GREP "^installed=no" $deplib > /dev/null; then
+		case $host in
+		*-*-darwin*)
+		  depdepl=
+		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+		  if test -n "$deplibrary_names" ; then
+		    for tmp in $deplibrary_names ; do
+		      depdepl=$tmp
+		    done
+		    if test -f "$absdir/$objdir/$depdepl" ; then
+		      depdepl="$absdir/$objdir/$depdepl"
+		      darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+                      if test -z "$darwin_install_name"; then
+                          darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
+                      fi
+		      func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+		      func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
+		      path=
+		    fi
+		  fi
+		  ;;
+		*)
+		  path="-L$absdir/$objdir"
+		  ;;
+		esac
+		else
+		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  test -z "$libdir" && \
+		    func_fatal_error "\`$deplib' is not a valid libtool archive"
+		  test "$absdir" != "$libdir" && \
+		    func_warning "\`$deplib' seems to be moved"
+
+		  path="-L$absdir"
+		fi
+		;;
+	      esac
+	      case " $deplibs " in
+	      *" $path "*) ;;
+	      *) deplibs="$path $deplibs" ;;
+	      esac
+	    done
+	  fi # link_all_deplibs != no
+	fi # linkmode = lib
+      done # for deplib in $libs
+      if test "$pass" = link; then
+	if test "$linkmode" = "prog"; then
+	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+	  finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+	else
+	  compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	fi
+      fi
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
+	# Link the dlpreopened libraries before other libraries
+	for deplib in $save_deplibs; do
+	  deplibs="$deplib $deplibs"
+	done
+      fi
+      if test "$pass" != dlopen; then
+	if test "$pass" != conv; then
+	  # Make sure lib_search_path contains only unique directories.
+	  lib_search_path=
+	  for dir in $newlib_search_path; do
+	    case "$lib_search_path " in
+	    *" $dir "*) ;;
+	    *) func_append lib_search_path " $dir" ;;
+	    esac
+	  done
+	  newlib_search_path=
+	fi
+
+	if test "$linkmode,$pass" != "prog,link"; then
+	  vars="deplibs"
+	else
+	  vars="compile_deplibs finalize_deplibs"
+	fi
+	for var in $vars dependency_libs; do
+	  # Add libraries to $var in reverse order
+	  eval tmp_libs=\"\$$var\"
+	  new_libs=
+	  for deplib in $tmp_libs; do
+	    # FIXME: Pedantically, this is the right thing to do, so
+	    #        that some nasty dependency loop isn't accidentally
+	    #        broken:
+	    #new_libs="$deplib $new_libs"
+	    # Pragmatically, this seems to cause very few problems in
+	    # practice:
+	    case $deplib in
+	    -L*) new_libs="$deplib $new_libs" ;;
+	    -R*) ;;
+	    *)
+	      # And here is the reason: when a library appears more
+	      # than once as an explicit dependence of a library, or
+	      # is implicitly linked in more than once by the
+	      # compiler, it is considered special, and multiple
+	      # occurrences thereof are not removed.  Compare this
+	      # with having the same library being listed as a
+	      # dependency of multiple other libraries: in this case,
+	      # we know (pedantically, we assume) the library does not
+	      # need to be listed more than once, so we keep only the
+	      # last copy.  This is not always right, but it is rare
+	      # enough that we require users that really mean to play
+	      # such unportable linking tricks to link the library
+	      # using -Wl,-lname, so that libtool does not consider it
+	      # for duplicate removal.
+	      case " $specialdeplibs " in
+	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
+	      *)
+		case " $new_libs " in
+		*" $deplib "*) ;;
+		*) new_libs="$deplib $new_libs" ;;
+		esac
+		;;
+	      esac
+	      ;;
+	    esac
+	  done
+	  tmp_libs=
+	  for deplib in $new_libs; do
+	    case $deplib in
+	    -L*)
+	      case " $tmp_libs " in
+	      *" $deplib "*) ;;
+	      *) func_append tmp_libs " $deplib" ;;
+	      esac
+	      ;;
+	    *) func_append tmp_libs " $deplib" ;;
+	    esac
+	  done
+	  eval $var=\"$tmp_libs\"
+	done # for var
+      fi
+      # Last step: remove runtime libs from dependency_libs
+      # (they stay in deplibs)
+      tmp_libs=
+      for i in $dependency_libs ; do
+	case " $predeps $postdeps $compiler_lib_search_path " in
+	*" $i "*)
+	  i=""
+	  ;;
+	esac
+	if test -n "$i" ; then
+	  func_append tmp_libs " $i"
+	fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
+    fi
+    if test "$linkmode" = prog || test "$linkmode" = lib; then
+      dlprefiles="$newdlprefiles"
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for archives"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "\`-l' and \`-L' are ignored for archives" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "\`-rpath' is ignored for archives"
+
+      test -n "$xrpath" && \
+	func_warning "\`-R' is ignored for archives"
+
+      test -n "$vinfo" && \
+	func_warning "\`-version-info/-version-number' is ignored for archives"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for archives"
+
+      test -n "$export_symbols$export_symbols_regex" && \
+	func_warning "\`-export-symbols' is ignored for archives"
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      func_append objs "$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case $outputname in
+      lib*)
+	func_stripname 'lib' '.la' "$outputname"
+	name=$func_stripname_result
+	eval shared_ext=\"$shrext_cmds\"
+	eval libname=\"$libname_spec\"
+	;;
+      *)
+	test "$module" = no && \
+	  func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+	if test "$need_lib_prefix" != no; then
+	  # Add the "lib" prefix for modules if required
+	  func_stripname '' '.la' "$outputname"
+	  name=$func_stripname_result
+	  eval shared_ext=\"$shrext_cmds\"
+	  eval libname=\"$libname_spec\"
+	else
+	  func_stripname '' '.la' "$outputname"
+	  libname=$func_stripname_result
+	fi
+	;;
+      esac
+
+      if test -n "$objs"; then
+	if test "$deplibs_check_method" != pass_all; then
+	  func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+	else
+	  echo
+	  $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+	  $ECHO "*** objects $objs is not portable!"
+	  func_append libobjs " $objs"
+	fi
+      fi
+
+      test "$dlself" != no && \
+	func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+      set dummy $rpath
+      shift
+      test "$#" -gt 1 && \
+	func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+      install_libdir="$1"
+
+      oldlibs=
+      if test -z "$rpath"; then
+	if test "$build_libtool_libs" = yes; then
+	  # Building a libtool convenience library.
+	  # Some compilers have problems with a `.al' extension so
+	  # convenience libraries should have the same extension an
+	  # archive normally would.
+	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
+	  build_libtool_libs=convenience
+	  build_old_libs=yes
+	fi
+
+	test -n "$vinfo" && \
+	  func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+	test -n "$release" && \
+	  func_warning "\`-release' is ignored for convenience libraries"
+      else
+
+	# Parse the version information argument.
+	save_ifs="$IFS"; IFS=':'
+	set dummy $vinfo 0 0 0
+	shift
+	IFS="$save_ifs"
+
+	test -n "$7" && \
+	  func_fatal_help "too many parameters to \`-version-info'"
+
+	# convert absolute version numbers to libtool ages
+	# this retains compatibility with .la files and attempts
+	# to make the code below a bit more comprehensible
+
+	case $vinfo_number in
+	yes)
+	  number_major="$1"
+	  number_minor="$2"
+	  number_revision="$3"
+	  #
+	  # There are really only two kinds -- those that
+	  # use the current revision as the major version
+	  # and those that subtract age and use age as
+	  # a minor version.  But, then there is irix
+	  # which has an extra 1 added just for fun
+	  #
+	  case $version_type in
+	  # correct linux to gnu/linux during the next big refactor
+	  darwin|linux|osf|windows|none)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age="$number_minor"
+	    revision="$number_revision"
+	    ;;
+	  freebsd-aout|freebsd-elf|qnx|sunos)
+	    current="$number_major"
+	    revision="$number_minor"
+	    age="0"
+	    ;;
+	  irix|nonstopux)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age="$number_minor"
+	    revision="$number_minor"
+	    lt_irix_increment=no
+	    ;;
+	  *)
+	    func_fatal_configuration "$modename: unknown library version type \`$version_type'"
+	    ;;
+	  esac
+	  ;;
+	no)
+	  current="$1"
+	  revision="$2"
+	  age="$3"
+	  ;;
+	esac
+
+	# Check that each of the things are valid numbers.
+	case $current in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "CURRENT \`$current' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $revision in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "REVISION \`$revision' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $age in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "AGE \`$age' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	if test "$age" -gt "$current"; then
+	  func_error "AGE \`$age' is greater than the current interface number \`$current'"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	fi
+
+	# Calculate the version variables.
+	major=
+	versuffix=
+	verstring=
+	case $version_type in
+	none) ;;
+
+	darwin)
+	  # Like Linux, but with the current version available in
+	  # verstring for coding it into the library header
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix="$major.$age.$revision"
+	  # Darwin ld doesn't like 0 for these options...
+	  func_arith $current + 1
+	  minor_current=$func_arith_result
+	  xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+	  ;;
+
+	freebsd-aout)
+	  major=".$current"
+	  versuffix=".$current.$revision";
+	  ;;
+
+	freebsd-elf)
+	  major=".$current"
+	  versuffix=".$current"
+	  ;;
+
+	irix | nonstopux)
+	  if test "X$lt_irix_increment" = "Xno"; then
+	    func_arith $current - $age
+	  else
+	    func_arith $current - $age + 1
+	  fi
+	  major=$func_arith_result
+
+	  case $version_type in
+	    nonstopux) verstring_prefix=nonstopux ;;
+	    *)         verstring_prefix=sgi ;;
+	  esac
+	  verstring="$verstring_prefix$major.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$revision
+	  while test "$loop" -ne 0; do
+	    func_arith $revision - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring="$verstring_prefix$major.$iface:$verstring"
+	  done
+
+	  # Before this point, $major must not contain `.'.
+	  major=.$major
+	  versuffix="$major.$revision"
+	  ;;
+
+	linux) # correct to gnu/linux during the next big refactor
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix="$major.$age.$revision"
+	  ;;
+
+	osf)
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix=".$current.$age.$revision"
+	  verstring="$current.$age.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$age
+	  while test "$loop" -ne 0; do
+	    func_arith $current - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring="$verstring:${iface}.0"
+	  done
+
+	  # Make executables depend on our current version.
+	  func_append verstring ":${current}.0"
+	  ;;
+
+	qnx)
+	  major=".$current"
+	  versuffix=".$current"
+	  ;;
+
+	sunos)
+	  major=".$current"
+	  versuffix=".$current.$revision"
+	  ;;
+
+	windows)
+	  # Use '-' rather than '.', since we only want one
+	  # extension on DOS 8.3 filesystems.
+	  func_arith $current - $age
+	  major=$func_arith_result
+	  versuffix="-$major"
+	  ;;
+
+	*)
+	  func_fatal_configuration "unknown library version type \`$version_type'"
+	  ;;
+	esac
+
+	# Clear the version info if we defaulted, and they specified a release.
+	if test -z "$vinfo" && test -n "$release"; then
+	  major=
+	  case $version_type in
+	  darwin)
+	    # we can't check for "0.0" in archive_cmds due to quoting
+	    # problems, so we reset it completely
+	    verstring=
+	    ;;
+	  *)
+	    verstring="0.0"
+	    ;;
+	  esac
+	  if test "$need_version" = no; then
+	    versuffix=
+	  else
+	    versuffix=".0.0"
+	  fi
+	fi
+
+	# Remove version info from name if versioning should be avoided
+	if test "$avoid_version" = yes && test "$need_version" = no; then
+	  major=
+	  versuffix=
+	  verstring=""
+	fi
+
+	# Check to see if the archive will have undefined symbols.
+	if test "$allow_undefined" = yes; then
+	  if test "$allow_undefined_flag" = unsupported; then
+	    func_warning "undefined symbols not allowed in $host shared libraries"
+	    build_libtool_libs=no
+	    build_old_libs=yes
+	  fi
+	else
+	  # Don't allow undefined symbols.
+	  allow_undefined_flag="$no_undefined_flag"
+	fi
+
+      fi
+
+      func_generate_dlsyms "$libname" "$libname" "yes"
+      func_append libobjs " $symfileobj"
+      test "X$libobjs" = "X " && libobjs=
+
+      if test "$opt_mode" != relink; then
+	# Remove our outputs, but don't remove object files since they
+	# may have been created when compiling PIC objects.
+	removelist=
+	tempremovelist=`$ECHO "$output_objdir/*"`
+	for p in $tempremovelist; do
+	  case $p in
+	    *.$objext | *.gcno)
+	       ;;
+	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+	       if test "X$precious_files_regex" != "X"; then
+		 if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+		 then
+		   continue
+		 fi
+	       fi
+	       func_append removelist " $p"
+	       ;;
+	    *) ;;
+	  esac
+	done
+	test -n "$removelist" && \
+	  func_show_eval "${RM}r \$removelist"
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+	func_append oldlibs " $output_objdir/$libname.$libext"
+
+	# Transform .lo files to .o files.
+	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      #for path in $notinst_path; do
+      #	lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+      #	deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+      #	dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+      #done
+
+      if test -n "$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	temp_xrpath=
+	for libdir in $xrpath; do
+	  func_replace_sysroot "$libdir"
+	  func_append temp_xrpath " -R$func_replace_sysroot_result"
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_rpath " $libdir" ;;
+	  esac
+	done
+	if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+	  dependency_libs="$temp_xrpath $dependency_libs"
+	fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles="$dlfiles"
+      dlfiles=
+      for lib in $old_dlfiles; do
+	case " $dlprefiles $dlfiles " in
+	*" $lib "*) ;;
+	*) func_append dlfiles " $lib" ;;
+	esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles="$dlprefiles"
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+	case "$dlprefiles " in
+	*" $lib "*) ;;
+	*) func_append dlprefiles " $lib" ;;
+	esac
+      done
+
+      if test "$build_libtool_libs" = yes; then
+	if test -n "$rpath"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	    # these systems don't actually have a c library (as such)!
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C library is in the System framework
+	    func_append deplibs " System.ltframework"
+	    ;;
+	  *-*-netbsd*)
+	    # Don't link with libc until the a.out ld.so is fixed.
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    ;;
+	  *)
+	    # Add libc to deplibs on all other systems if necessary.
+	    if test "$build_libtool_need_lc" = "yes"; then
+	      func_append deplibs " -lc"
+	    fi
+	    ;;
+	  esac
+	fi
+
+	# Transform deplibs into only deplibs that can be linked in shared.
+	name_save=$name
+	libname_save=$libname
+	release_save=$release
+	versuffix_save=$versuffix
+	major_save=$major
+	# I'm not sure if I'm treating the release correctly.  I think
+	# release should show up in the -l (ie -lgmp5) so we don't want to
+	# add it in twice.  Is that correct?
+	release=""
+	versuffix=""
+	major=""
+	newdeplibs=
+	droppeddeps=no
+	case $deplibs_check_method in
+	pass_all)
+	  # Don't check for shared/static.  Everything works.
+	  # This might be a little naive.  We might want to check
+	  # whether the library exists or not.  But this is on
+	  # osf3 & osf4 and I'm not really sure... Just
+	  # implementing what was already the behavior.
+	  newdeplibs=$deplibs
+	  ;;
+	test_compile)
+	  # This code stresses the "libraries are programs" paradigm to its
+	  # limits. Maybe even breaks it.  We compile a program, linking it
+	  # against the deplibs as a proxy for the library.  Then we can check
+	  # whether they linked in statically or dynamically with ldd.
+	  $opt_dry_run || $RM conftest.c
+	  cat > conftest.c <<EOF
+	  int main() { return 0; }
+EOF
+	  $opt_dry_run || $RM conftest
+	  if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+	    ldd_output=`ldd conftest`
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		  case " $predeps $postdeps " in
+		  *" $i "*)
+		    func_append newdeplibs " $i"
+		    i=""
+		    ;;
+		  esac
+		fi
+		if test -n "$i" ; then
+		  libname=`eval "\\$ECHO \"$libname_spec\""`
+		  deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		  set dummy $deplib_matches; shift
+		  deplib_match=$1
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		    func_append newdeplibs " $i"
+		  else
+		    droppeddeps=yes
+		    echo
+		    $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		    echo "*** I have the capability to make that library automatically link in when"
+		    echo "*** you link to this library.  But I can only do this if you have a"
+		    echo "*** shared version of the library, which I believe you do not have"
+		    echo "*** because a test_compile did reveal that the linker did not use it for"
+		    echo "*** its dynamic dependency list that programs get resolved with at runtime."
+		  fi
+		fi
+		;;
+	      *)
+		func_append newdeplibs " $i"
+		;;
+	      esac
+	    done
+	  else
+	    # Error occurred in the first compile.  Let's try to salvage
+	    # the situation: Compile a separate program for each library.
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		$opt_dry_run || $RM conftest
+		if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+		  ldd_output=`ldd conftest`
+		  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		    case " $predeps $postdeps " in
+		    *" $i "*)
+		      func_append newdeplibs " $i"
+		      i=""
+		      ;;
+		    esac
+		  fi
+		  if test -n "$i" ; then
+		    libname=`eval "\\$ECHO \"$libname_spec\""`
+		    deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		    set dummy $deplib_matches; shift
+		    deplib_match=$1
+		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		      func_append newdeplibs " $i"
+		    else
+		      droppeddeps=yes
+		      echo
+		      $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		      echo "*** I have the capability to make that library automatically link in when"
+		      echo "*** you link to this library.  But I can only do this if you have a"
+		      echo "*** shared version of the library, which you do not appear to have"
+		      echo "*** because a test_compile did reveal that the linker did not use this one"
+		      echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+		    fi
+		  fi
+		else
+		  droppeddeps=yes
+		  echo
+		  $ECHO "*** Warning!  Library $i is needed by this library but I was not able to"
+		  echo "*** make it link in!  You will probably need to install it or some"
+		  echo "*** library that it depends on before this library will be fully"
+		  echo "*** functional.  Installing it before continuing would be even better."
+		fi
+		;;
+	      *)
+		func_append newdeplibs " $i"
+		;;
+	      esac
+	    done
+	  fi
+	  ;;
+	file_magic*)
+	  set dummy $deplibs_check_method; shift
+	  file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  func_append newdeplibs " $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		if test -n "$file_magic_glob"; then
+		  libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+		else
+		  libnameglob=$libname
+		fi
+		test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  if test "$want_nocaseglob" = yes; then
+		    shopt -s nocaseglob
+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+		    $nocaseglob
+		  else
+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+		  fi
+		  for potent_lib in $potential_libs; do
+		      # Follow soft links.
+		      if ls -lLd "$potent_lib" 2>/dev/null |
+			 $GREP " -> " >/dev/null; then
+			continue
+		      fi
+		      # The statement above tries to avoid entering an
+		      # endless loop below, in case of cyclic links.
+		      # We might still enter an endless loop, since a link
+		      # loop can be closed while we follow links,
+		      # but so what?
+		      potlib="$potent_lib"
+		      while test -h "$potlib" 2>/dev/null; do
+			potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+			case $potliblink in
+			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+			*) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
+			esac
+		      done
+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+			 $SED -e 10q |
+			 $EGREP "$file_magic_regex" > /dev/null; then
+			func_append newdeplibs " $a_deplib"
+			a_deplib=""
+			break 2
+		      fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		echo
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a file magic. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      func_append newdeplibs " $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	match_pattern*)
+	  set dummy $deplibs_check_method; shift
+	  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  func_append newdeplibs " $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		    potlib="$potent_lib" # see symlink-check above in file_magic test
+		    if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+		       $EGREP "$match_pattern_regex" > /dev/null; then
+		      func_append newdeplibs " $a_deplib"
+		      a_deplib=""
+		      break 2
+		    fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		echo
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a regex pattern. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      func_append newdeplibs " $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	none | unknown | *)
+	  newdeplibs=""
+	  tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+	  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	    for i in $predeps $postdeps ; do
+	      # can't use Xsed below, because $i might contain '/'
+	      tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
+	    done
+	  fi
+	  case $tmp_deplibs in
+	  *[!\	\ ]*)
+	    echo
+	    if test "X$deplibs_check_method" = "Xnone"; then
+	      echo "*** Warning: inter-library dependencies are not supported in this platform."
+	    else
+	      echo "*** Warning: inter-library dependencies are not known to be supported."
+	    fi
+	    echo "*** All declared inter-library dependencies are being dropped."
+	    droppeddeps=yes
+	    ;;
+	  esac
+	  ;;
+	esac
+	versuffix=$versuffix_save
+	major=$major_save
+	release=$release_save
+	libname=$libname_save
+	name=$name_save
 
-	  $echo >> $output "\
+	case $host in
+	*-*-rhapsody* | *-*-darwin1.[012])
+	  # On Rhapsody replace the C library with the System framework
+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+	  ;;
+	esac
 
-    # relink executable if necessary
-    if test -n \"\$relink_command\"; then
-      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
-      else
-	$echo \"\$relink_command_output\" >&2
-	$rm \"\$progdir/\$file\"
-	exit $EXIT_FAILURE
-      fi
-    fi
+	if test "$droppeddeps" = yes; then
+	  if test "$module" = yes; then
+	    echo
+	    echo "*** Warning: libtool could not satisfy all declared inter-library"
+	    $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
+	    echo "*** a static module, that should work as long as the dlopening"
+	    echo "*** application is linked with the -dlopen flag."
+	    if test -z "$global_symbol_pipe"; then
+	      echo
+	      echo "*** However, this would only work if libtool was able to extract symbol"
+	      echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+	      echo "*** not find such a program.  So, this module is probably useless."
+	      echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	    fi
+	    if test "$build_old_libs" = no; then
+	      oldlibs="$output_objdir/$libname.$libext"
+	      build_libtool_libs=module
+	      build_old_libs=yes
+	    else
+	      build_libtool_libs=no
+	    fi
+	  else
+	    echo "*** The inter-library dependencies that have been dropped here will be"
+	    echo "*** automatically added whenever a program is linked with this library"
+	    echo "*** or is declared to -dlopen it."
 
-    $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
-    { $rm \"\$progdir/\$program\";
-      $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
-    $rm \"\$progdir/\$file\"
-  fi"
-	else
-	  $echo >> $output "\
-  program='$outputname'
-  progdir=\"\$thisdir/$objdir\"
-"
+	    if test "$allow_undefined" = no; then
+	      echo
+	      echo "*** Since this library must not contain undefined symbols,"
+	      echo "*** because either the platform does not support them or"
+	      echo "*** it was explicitly requested with -no-undefined,"
+	      echo "*** libtool will only create a static version of it."
+	      if test "$build_old_libs" = no; then
+		oldlibs="$output_objdir/$libname.$libext"
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  fi
 	fi
+	# Done checking deplibs!
+	deplibs=$newdeplibs
+      fi
+      # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+      case $host in
+	*-*-darwin*)
+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  ;;
+      esac
 
-	$echo >> $output "\
-
-  if test -f \"\$progdir/\$program\"; then"
-
-	# Export our shlibpath_var if we have one.
-	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
-	  $echo >> $output "\
-    # Add our own library path to $shlibpath_var
-    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $deplibs " in
+	  *" -L$path/$objdir "*)
+	    func_append new_libs " -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) func_append new_libs " $deplib" ;;
+	  esac
+	  ;;
+	*) func_append new_libs " $deplib" ;;
+	esac
+      done
+      deplibs="$new_libs"
 
-    # Some systems cannot cope with colon-terminated $shlibpath_var
-    # The second colon is a workaround for a bug in BeOS R4 sed
-    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
 
-    export $shlibpath_var
-"
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+	# Remove ${wl} instances when linking with ld.
+	# FIXME: should test the right _cmds variable.
+	case $archive_cmds in
+	  *\$LD\ *) wl= ;;
+        esac
+	if test "$hardcode_into_libs" = yes; then
+	  # Hardcode the library paths
+	  hardcode_libdirs=
+	  dep_rpath=
+	  rpath="$finalize_rpath"
+	  test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
+	  for libdir in $rpath; do
+	    if test -n "$hardcode_libdir_flag_spec"; then
+	      if test -n "$hardcode_libdir_separator"; then
+		func_replace_sysroot "$libdir"
+		libdir=$func_replace_sysroot_result
+		if test -z "$hardcode_libdirs"; then
+		  hardcode_libdirs="$libdir"
+		else
+		  # Just accumulate the unique libdirs.
+		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		    ;;
+		  *)
+		    func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		    ;;
+		  esac
+		fi
+	      else
+		eval flag=\"$hardcode_libdir_flag_spec\"
+		func_append dep_rpath " $flag"
+	      fi
+	    elif test -n "$runpath_var"; then
+	      case "$perm_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append perm_rpath " $libdir" ;;
+	      esac
+	    fi
+	  done
+	  # Substitute the hardcoded libdirs into the rpath.
+	  if test -n "$hardcode_libdir_separator" &&
+	     test -n "$hardcode_libdirs"; then
+	    libdir="$hardcode_libdirs"
+	    eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+	  fi
+	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
+	    # We should set the runpath_var.
+	    rpath=
+	    for dir in $perm_rpath; do
+	      func_append rpath "$dir:"
+	    done
+	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+	  fi
+	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
 	fi
 
-	# fixup the dll searchpath if we need to.
-	if test -n "$dllsearchpath"; then
-	  $echo >> $output "\
-    # Add the dll search path components to the executable PATH
-    PATH=$dllsearchpath:\$PATH
-"
+	shlibpath="$finalize_shlibpath"
+	test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+	if test -n "$shlibpath"; then
+	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
 	fi
 
-	$echo >> $output "\
-    if test \"\$libtool_execute_magic\" != \"$magic\"; then
-      # Run the actual program with our arguments.
-"
-	case $host in
-	# Backslashes separate directories on plain windows
-	*-*-mingw | *-*-os2*)
-	  $echo >> $output "\
-      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
-"
-	  ;;
-
-	*)
-	  $echo >> $output "\
-      exec \"\$progdir/\$program\" \${1+\"\$@\"}
-"
-	  ;;
-	esac
-	$echo >> $output "\
-      \$echo \"\$0: cannot exec \$program \$*\"
-      exit $EXIT_FAILURE
-    fi
-  else
-    # The program doesn't exist.
-    \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
-    \$echo \"This script is just a wrapper for \$program.\" 1>&2
-    $echo \"See the $PACKAGE documentation for more information.\" 1>&2
-    exit $EXIT_FAILURE
-  fi
-fi\
-"
-	chmod +x $output
-      fi
-      exit $EXIT_SUCCESS
-      ;;
-    esac
-
-    # See if we need to build an old-fashioned archive.
-    for oldlib in $oldlibs; do
+	# Get the real and link names of the library.
+	eval shared_ext=\"$shrext_cmds\"
+	eval library_names=\"$library_names_spec\"
+	set dummy $library_names
+	shift
+	realname="$1"
+	shift
 
-      if test "$build_libtool_libs" = convenience; then
-	oldobjs="$libobjs_save"
-	addlibs="$convenience"
-	build_libtool_libs=no
-      else
-	if test "$build_libtool_libs" = module; then
-	  oldobjs="$libobjs_save"
-	  build_libtool_libs=no
+	if test -n "$soname_spec"; then
+	  eval soname=\"$soname_spec\"
 	else
-	  oldobjs="$old_deplibs $non_pic_objects"
+	  soname="$realname"
+	fi
+	if test -z "$dlname"; then
+	  dlname=$soname
 	fi
-	addlibs="$old_convenience"
-      fi
 
-      if test -n "$addlibs"; then
-	gentop="$output_objdir/${outputname}x"
-	generated="$generated $gentop"
+	lib="$output_objdir/$realname"
+	linknames=
+	for link
+	do
+	  func_append linknames " $link"
+	done
 
-	func_extract_archives $gentop $addlibs
-	oldobjs="$oldobjs $func_extract_archives_result"
-      fi
+	# Use standard objects if they are pic
+	test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	test "X$libobjs" = "X " && libobjs=
 
-      # Do each command in the archive commands.
-      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
-       cmds=$old_archive_from_new_cmds
-      else
-	# POSIX demands no paths to be encoded in archives.  We have
-	# to avoid creating archives with duplicate basenames if we
-	# might have to extract them afterwards, e.g., when creating a
-	# static archive out of a convenience library, or when linking
-	# the entirety of a libtool archive into another (currently
-	# not supported by libtool).
-	if (for obj in $oldobjs
-	    do
-	      $echo "X$obj" | $Xsed -e 's%^.*/%%'
-	    done | sort | sort -uc >/dev/null 2>&1); then
-	  :
-	else
-	  $echo "copying selected object files to avoid basename conflicts..."
+	delfiles=
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+	  export_symbols="$output_objdir/$libname.uexp"
+	  func_append delfiles " $export_symbols"
+	fi
 
-	  if test -z "$gentop"; then
-	    gentop="$output_objdir/${outputname}x"
-	    generated="$generated $gentop"
-
-	    $show "${rm}r $gentop"
-	    $run ${rm}r "$gentop"
-	    $show "$mkdir $gentop"
-	    $run $mkdir "$gentop"
-	    exit_status=$?
-	    if test "$exit_status" -ne 0 && test ! -d "$gentop"; then
-	      exit $exit_status
+	orig_export_symbols=
+	case $host_os in
+	cygwin* | mingw* | cegcc*)
+	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+	    # exporting using user supplied symfile
+	    if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+	      # and it's NOT already a .def file. Must figure out
+	      # which of the given symbols are data symbols and tag
+	      # them as such. So, trigger use of export_symbols_cmds.
+	      # export_symbols gets reassigned inside the "prepare
+	      # the list of exported symbols" if statement, so the
+	      # include_expsyms logic still works.
+	      orig_export_symbols="$export_symbols"
+	      export_symbols=
+	      always_export_symbols=yes
 	    fi
 	  fi
+	  ;;
+	esac
 
-	  save_oldobjs=$oldobjs
-	  oldobjs=
-	  counter=1
-	  for obj in $save_oldobjs
-	  do
-	    objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
-	    case " $oldobjs " in
-	    " ") oldobjs=$obj ;;
-	    *[\ /]"$objbase "*)
-	      while :; do
-		# Make sure we don't pick an alternate name that also
-		# overlaps.
-		newobj=lt$counter-$objbase
-		counter=`expr $counter + 1`
-		case " $oldobjs " in
-		*[\ /]"$newobj "*) ;;
-		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
-		esac
-	      done
-	      $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
-	      $run ln "$obj" "$gentop/$newobj" ||
-	      $run cp "$obj" "$gentop/$newobj"
-	      oldobjs="$oldobjs $gentop/$newobj"
-	      ;;
-	    *) oldobjs="$oldobjs $obj" ;;
-	    esac
-	  done
+	# Prepare the list of exported symbols
+	if test -z "$export_symbols"; then
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    func_verbose "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $opt_dry_run || $RM $export_symbols
+	    cmds=$export_symbols_cmds
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd1 in $cmds; do
+	      IFS="$save_ifs"
+	      # Take the normal branch if the nm_file_list_spec branch
+	      # doesn't work or if tool conversion is not needed.
+	      case $nm_file_list_spec~$to_tool_file_cmd in
+		*~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+		  try_normal_branch=yes
+		  eval cmd=\"$cmd1\"
+		  func_len " $cmd"
+		  len=$func_len_result
+		  ;;
+		*)
+		  try_normal_branch=no
+		  ;;
+	      esac
+	      if test "$try_normal_branch" = yes \
+		 && { test "$len" -lt "$max_cmd_len" \
+		      || test "$max_cmd_len" -le -1; }
+	      then
+		func_show_eval "$cmd" 'exit $?'
+		skipped_export=false
+	      elif test -n "$nm_file_list_spec"; then
+		func_basename "$output"
+		output_la=$func_basename_result
+		save_libobjs=$libobjs
+		save_output=$output
+		output=${output_objdir}/${output_la}.nm
+		func_to_tool_file "$output"
+		libobjs=$nm_file_list_spec$func_to_tool_file_result
+		func_append delfiles " $output"
+		func_verbose "creating $NM input file list: $output"
+		for obj in $save_libobjs; do
+		  func_to_tool_file "$obj"
+		  $ECHO "$func_to_tool_file_result"
+		done > "$output"
+		eval cmd=\"$cmd1\"
+		func_show_eval "$cmd" 'exit $?'
+		output=$save_output
+		libobjs=$save_libobjs
+		skipped_export=false
+	      else
+		# The command line is too long to execute in one step.
+		func_verbose "using reloadable object file for export list..."
+		skipped_export=:
+		# Break out early, otherwise skipped_export may be
+		# set to false by a later but shorter cmd.
+		break
+	      fi
+	    done
+	    IFS="$save_ifs"
+	    if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+	fi
+
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  tmp_export_symbols="$export_symbols"
+	  test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+	  $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
 	fi
 
-	eval cmds=\"$old_archive_cmds\"
+	if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+	  # The given exports_symbols file has to be filtered, so filter it.
+	  func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+	  # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	  # 's' commands which not all seds can handle. GNU sed should be fine
+	  # though. Also, the filter scales superlinearly with the number of
+	  # global variables. join(1) would be nice here, but unfortunately
+	  # isn't a blessed tool.
+	  $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	  func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+	  export_symbols=$output_objdir/$libname.def
+	  $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	fi
 
-	if len=`expr "X$cmds" : ".*"` &&
-	     test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
-	  cmds=$old_archive_cmds
-	else
-	  # the command line is too long to link in one step, link in parts
-	  $echo "using piecewise archive linking..."
-	  save_RANLIB=$RANLIB
-	  RANLIB=:
-	  objlist=
-	  concat_cmds=
-	  save_oldobjs=$oldobjs
+	tmp_deplibs=
+	for test_deplib in $deplibs; do
+	  case " $convenience " in
+	  *" $test_deplib "*) ;;
+	  *)
+	    func_append tmp_deplibs " $test_deplib"
+	    ;;
+	  esac
+	done
+	deplibs="$tmp_deplibs"
 
-	  # Is there a better way of finding the last object in the list?
-	  for obj in $save_oldobjs
-	  do
-	    last_oldobj=$obj
-	  done
-	  for obj in $save_oldobjs
-	  do
-	    oldobjs="$objlist $obj"
-	    objlist="$objlist $obj"
-	    eval test_cmds=\"$old_archive_cmds\"
-	    if len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
-	       test "$len" -le "$max_cmd_len"; then
-	      :
-	    else
-	      # the above command should be used before it gets too long
-	      oldobjs=$objlist
-	      if test "$obj" = "$last_oldobj" ; then
-	        RANLIB=$save_RANLIB
-	      fi
-	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
-	      eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
-	      objlist=
-	    fi
-	  done
-	  RANLIB=$save_RANLIB
-	  oldobjs=$objlist
-	  if test "X$oldobjs" = "X" ; then
-	    eval cmds=\"\$concat_cmds\"
+	if test -n "$convenience"; then
+	  if test -n "$whole_archive_flag_spec" &&
+	    test "$compiler_needs_object" = yes &&
+	    test -z "$libobjs"; then
+	    # extract the archives, so we have objects to list.
+	    # TODO: could optimize this to just extract one archive.
+	    whole_archive_flag_spec=
+	  fi
+	  if test -n "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
 	  else
-	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+	    gentop="$output_objdir/${outputname}x"
+	    func_append generated " $gentop"
+
+	    func_extract_archives $gentop $convenience
+	    func_append libobjs " $func_extract_archives_result"
+	    test "X$libobjs" = "X " && libobjs=
 	  fi
 	fi
-      fi
-      save_ifs="$IFS"; IFS='~'
-      for cmd in $cmds; do
-        eval cmd=\"$cmd\"
-	IFS="$save_ifs"
-	$show "$cmd"
-	$run eval "$cmd" || exit $?
-      done
-      IFS="$save_ifs"
-    done
 
-    if test -n "$generated"; then
-      $show "${rm}r$generated"
-      $run ${rm}r$generated
-    fi
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+	  eval flag=\"$thread_safe_flag_spec\"
+	  func_append linker_flags " $flag"
+	fi
 
-    # Now create the libtool archive.
-    case $output in
-    *.la)
-      old_library=
-      test "$build_old_libs" = yes && old_library="$libname.$libext"
-      $show "creating $output"
+	# Make a backup of the uninstalled library when relinking
+	if test "$opt_mode" = relink; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+	fi
 
-      # Preserve any variables that may affect compiler behavior
-      for var in $variables_saved_for_relink; do
-	if eval test -z \"\${$var+set}\"; then
-	  relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
-	elif eval var_value=\$$var; test -z "$var_value"; then
-	  relink_command="$var=; export $var; $relink_command"
+	# Do each of the archive commands.
+	if test "$module" = yes && test -n "$module_cmds" ; then
+	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	    eval test_cmds=\"$module_expsym_cmds\"
+	    cmds=$module_expsym_cmds
+	  else
+	    eval test_cmds=\"$module_cmds\"
+	    cmds=$module_cmds
+	  fi
 	else
-	  var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
-	  relink_command="$var=\"$var_value\"; export $var; $relink_command"
+	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	    eval test_cmds=\"$archive_expsym_cmds\"
+	    cmds=$archive_expsym_cmds
+	  else
+	    eval test_cmds=\"$archive_cmds\"
+	    cmds=$archive_cmds
+	  fi
 	fi
-      done
-      # Quote the link command for shipping.
-      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
-      relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP`
-      if test "$hardcode_automatic" = yes ; then
-	relink_command=
-      fi
 
+	if test "X$skipped_export" != "X:" &&
+	   func_len " $test_cmds" &&
+	   len=$func_len_result &&
+	   test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  :
+	else
+	  # The command line is too long to link in one step, link piecewise
+	  # or, if using GNU ld and skipped_export is not :, use a linker
+	  # script.
 
-      # Only create the output if not a dry run.
-      if test -z "$run"; then
-	for installed in no yes; do
-	  if test "$installed" = yes; then
-	    if test -z "$install_libdir"; then
-	      break
+	  # Save the value of $output and $libobjs because we want to
+	  # use them later.  If we have whole_archive_flag_spec, we
+	  # want to use save_libobjs as it was before
+	  # whole_archive_flag_spec was expanded, because we can't
+	  # assume the linker understands whole_archive_flag_spec.
+	  # This may have to be revisited, in case too many
+	  # convenience libraries get linked in and end up exceeding
+	  # the spec.
+	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	  fi
+	  save_output=$output
+	  func_basename "$output"
+	  output_la=$func_basename_result
+
+	  # Clear the reloadable object creation command queue and
+	  # initialize k to one.
+	  test_cmds=
+	  concat_cmds=
+	  objlist=
+	  last_robj=
+	  k=1
+
+	  if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+	    output=${output_objdir}/${output_la}.lnkscript
+	    func_verbose "creating GNU ld script: $output"
+	    echo 'INPUT (' > $output
+	    for obj in $save_libobjs
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
+	    done
+	    echo ')' >> $output
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$func_to_tool_file_result
+	  elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+	    output=${output_objdir}/${output_la}.lnk
+	    func_verbose "creating linker input file list: $output"
+	    : > $output
+	    set x $save_libobjs
+	    shift
+	    firstobj=
+	    if test "$compiler_needs_object" = yes; then
+	      firstobj="$1 "
+	      shift
 	    fi
-	    output="$output_objdir/$outputname"i
-	    # Replace all uninstalled libtool libraries with the installed ones
-	    newdependency_libs=
-	    for deplib in $dependency_libs; do
-	      case $deplib in
-	      *.la)
-		name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'`
-		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
-		if test -z "$libdir"; then
-		  $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
-		  exit $EXIT_FAILURE
-		fi
-		newdependency_libs="$newdependency_libs $libdir/$name"
-		;;
-	      *) newdependency_libs="$newdependency_libs $deplib" ;;
-	      esac
+	    for obj
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
 	    done
-	    dependency_libs="$newdependency_libs"
-	    newdlfiles=
-	    for lib in $dlfiles; do
-	      name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
-	      eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
-	      if test -z "$libdir"; then
-		$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
-		exit $EXIT_FAILURE
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+	  else
+	    if test -n "$save_libobjs"; then
+	      func_verbose "creating reloadable object files..."
+	      output=$output_objdir/$output_la-${k}.$objext
+	      eval test_cmds=\"$reload_cmds\"
+	      func_len " $test_cmds"
+	      len0=$func_len_result
+	      len=$len0
+
+	      # Loop over the list of objects to be linked.
+	      for obj in $save_libobjs
+	      do
+		func_len " $obj"
+		func_arith $len + $func_len_result
+		len=$func_arith_result
+		if test "X$objlist" = X ||
+		   test "$len" -lt "$max_cmd_len"; then
+		  func_append objlist " $obj"
+		else
+		  # The command $test_cmds is almost too long, add a
+		  # command to the queue.
+		  if test "$k" -eq 1 ; then
+		    # The first file doesn't have a previous command to add.
+		    reload_objs=$objlist
+		    eval concat_cmds=\"$reload_cmds\"
+		  else
+		    # All subsequent reloadable object files will link in
+		    # the last one created.
+		    reload_objs="$objlist $last_robj"
+		    eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+		  fi
+		  last_robj=$output_objdir/$output_la-${k}.$objext
+		  func_arith $k + 1
+		  k=$func_arith_result
+		  output=$output_objdir/$output_la-${k}.$objext
+		  objlist=" $obj"
+		  func_len " $last_robj"
+		  func_arith $len0 + $func_len_result
+		  len=$func_arith_result
+		fi
+	      done
+	      # Handle the remaining objects by creating one last
+	      # reloadable object file.  All subsequent reloadable object
+	      # files will link in the last one created.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      reload_objs="$objlist $last_robj"
+	      eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
+	      if test -n "$last_robj"; then
+	        eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
 	      fi
-	      newdlfiles="$newdlfiles $libdir/$name"
-	    done
-	    dlfiles="$newdlfiles"
-	    newdlprefiles=
-	    for lib in $dlprefiles; do
-	      name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
-	      eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
-	      if test -z "$libdir"; then
-		$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
-		exit $EXIT_FAILURE
+	      func_append delfiles " $output"
+
+	    else
+	      output=
+	    fi
+
+	    if ${skipped_export-false}; then
+	      func_verbose "generating symbol list for \`$libname.la'"
+	      export_symbols="$output_objdir/$libname.exp"
+	      $opt_dry_run || $RM $export_symbols
+	      libobjs=$output
+	      # Append the command to create the export file.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+	      if test -n "$last_robj"; then
+		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
 	      fi
-	      newdlprefiles="$newdlprefiles $libdir/$name"
+	    fi
+
+	    test -n "$save_libobjs" &&
+	      func_verbose "creating a temporary reloadable object file: $output"
+
+	    # Loop through the commands generated above and execute them.
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd in $concat_cmds; do
+	      IFS="$save_ifs"
+	      $opt_silent || {
+		  func_quote_for_expand "$cmd"
+		  eval "func_echo $func_quote_for_expand_result"
+	      }
+	      $opt_dry_run || eval "$cmd" || {
+		lt_exit=$?
+
+		# Restore the uninstalled library and exit
+		if test "$opt_mode" = relink; then
+		  ( cd "$output_objdir" && \
+		    $RM "${realname}T" && \
+		    $MV "${realname}U" "$realname" )
+		fi
+
+		exit $lt_exit
+	      }
 	    done
-	    dlprefiles="$newdlprefiles"
+	    IFS="$save_ifs"
+
+	    if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+
+          if ${skipped_export-false}; then
+	    if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	      tmp_export_symbols="$export_symbols"
+	      test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+	      $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+	    fi
+
+	    if test -n "$orig_export_symbols"; then
+	      # The given exports_symbols file has to be filtered, so filter it.
+	      func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+	      # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	      # 's' commands which not all seds can handle. GNU sed should be fine
+	      # though. Also, the filter scales superlinearly with the number of
+	      # global variables. join(1) would be nice here, but unfortunately
+	      # isn't a blessed tool.
+	      $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	      func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+	      export_symbols=$output_objdir/$libname.def
+	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	    fi
+	  fi
+
+	  libobjs=$output
+	  # Restore the value of output.
+	  output=$save_output
+
+	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	  # Expand the library linking commands again to reset the
+	  # value of $libobjs for piecewise linking.
+
+	  # Do each of the archive commands.
+	  if test "$module" = yes && test -n "$module_cmds" ; then
+	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	      cmds=$module_expsym_cmds
+	    else
+	      cmds=$module_cmds
+	    fi
 	  else
-	    newdlfiles=
-	    for lib in $dlfiles; do
-	      case $lib in
-		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
-		*) abs=`pwd`"/$lib" ;;
-	      esac
-	      newdlfiles="$newdlfiles $abs"
-	    done
-	    dlfiles="$newdlfiles"
-	    newdlprefiles=
-	    for lib in $dlprefiles; do
-	      case $lib in
-		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
-		*) abs=`pwd`"/$lib" ;;
-	      esac
-	      newdlprefiles="$newdlprefiles $abs"
-	    done
-	    dlprefiles="$newdlprefiles"
+	    if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	      cmds=$archive_expsym_cmds
+	    else
+	      cmds=$archive_cmds
+	    fi
 	  fi
-	  $rm $output
-	  # place dlname in correct position for cygwin
-	  tdlname=$dlname
-	  case $host,$output,$installed,$module,$dlname in
-	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
-	  esac
-	  $echo > $output "\
-# $outputname - a libtool library file
-# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
-#
-# Please DO NOT delete this file!
-# It is necessary for linking the library.
+	fi
 
-# The name that we can dlopen(3).
-dlname='$tdlname'
+	if test -n "$delfiles"; then
+	  # Append the command to remove temporary files to $cmds.
+	  eval cmds=\"\$cmds~\$RM $delfiles\"
+	fi
 
-# Names of this library.
-library_names='$library_names'
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
 
-# The name of the static archive.
-old_library='$old_library'
+	  func_extract_archives $gentop $dlprefiles
+	  func_append libobjs " $func_extract_archives_result"
+	  test "X$libobjs" = "X " && libobjs=
+	fi
 
-# Libraries that this one depends upon.
-dependency_libs='$dependency_libs'
+	save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  eval cmd=\"$cmd\"
+	  $opt_silent || {
+	    func_quote_for_expand "$cmd"
+	    eval "func_echo $func_quote_for_expand_result"
+	  }
+	  $opt_dry_run || eval "$cmd" || {
+	    lt_exit=$?
 
-# Version information for $libname.
-current=$current
-age=$age
-revision=$revision
+	    # Restore the uninstalled library and exit
+	    if test "$opt_mode" = relink; then
+	      ( cd "$output_objdir" && \
+	        $RM "${realname}T" && \
+		$MV "${realname}U" "$realname" )
+	    fi
 
-# Is this an already installed library?
-installed=$installed
+	    exit $lt_exit
+	  }
+	done
+	IFS="$save_ifs"
 
-# Should we warn about portability when linking against -modules?
-shouldnotlink=$module
+	# Restore the uninstalled library and exit
+	if test "$opt_mode" = relink; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
 
-# Files to dlopen/dlpreopen
-dlopen='$dlfiles'
-dlpreopen='$dlprefiles'
+	  if test -n "$convenience"; then
+	    if test -z "$whole_archive_flag_spec"; then
+	      func_show_eval '${RM}r "$gentop"'
+	    fi
+	  fi
 
-# Directory that this library needs to be installed in:
-libdir='$install_libdir'"
-	  if test "$installed" = no && test "$need_relink" = yes; then
-	    $echo >> $output "\
-relink_command=\"$relink_command\""
+	  exit $EXIT_SUCCESS
+	fi
+
+	# Create links to the real library.
+	for linkname in $linknames; do
+	  if test "$realname" != "$linkname"; then
+	    func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
 	  fi
 	done
-      fi
 
-      # Do a symbolic link so that the libtool archive can be found in
-      # LD_LIBRARY_PATH before the program is installed.
-      $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
-      $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $?
+	# If -module or -export-dynamic was specified, set the dlname.
+	if test "$module" = yes || test "$export_dynamic" = yes; then
+	  # On all known operating systems, these are identical.
+	  dlname="$soname"
+	fi
+      fi
       ;;
-    esac
-    exit $EXIT_SUCCESS
-    ;;
 
-  # libtool install mode
-  install)
-    modename="$modename: install"
+    obj)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for objects"
+      fi
 
-    # There may be an optional sh(1) argument at the beginning of
-    # install_prog (especially on Windows NT).
-    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
-       # Allow the use of GNU shtool's install command.
-       $echo "X$nonopt" | grep shtool > /dev/null; then
-      # Aesthetically quote it.
-      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
-      case $arg in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	arg="\"$arg\""
-	;;
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "\`-l' and \`-L' are ignored for objects" ;;
       esac
-      install_prog="$arg "
-      arg="$1"
-      shift
-    else
-      install_prog=
-      arg=$nonopt
-    fi
 
-    # The real first argument should be the name of the installation program.
-    # Aesthetically quote it.
-    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-    case $arg in
-    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-      arg="\"$arg\""
-      ;;
-    esac
-    install_prog="$install_prog$arg"
+      test -n "$rpath" && \
+	func_warning "\`-rpath' is ignored for objects"
 
-    # We need to accept at least all the BSD install flags.
-    dest=
-    files=
-    opts=
-    prev=
-    install_type=
-    isdir=no
-    stripme=
-    for arg
-    do
-      if test -n "$dest"; then
-	files="$files $dest"
-	dest=$arg
-	continue
-      fi
+      test -n "$xrpath" && \
+	func_warning "\`-R' is ignored for objects"
 
-      case $arg in
-      -d) isdir=yes ;;
-      -f) 
-      	case " $install_prog " in
-	*[\\\ /]cp\ *) ;;
-	*) prev=$arg ;;
-	esac
-	;;
-      -g | -m | -o) prev=$arg ;;
-      -s)
-	stripme=" -s"
-	continue
-	;;
-      -*)
+      test -n "$vinfo" && \
+	func_warning "\`-version-info' is ignored for objects"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for objects"
+
+      case $output in
+      *.lo)
+	test -n "$objs$old_deplibs" && \
+	  func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+	libobj=$output
+	func_lo2o "$libobj"
+	obj=$func_lo2o_result
 	;;
       *)
-	# If the previous option needed an argument, then skip it.
-	if test -n "$prev"; then
-	  prev=
-	else
-	  dest=$arg
-	  continue
-	fi
+	libobj=
+	obj="$output"
 	;;
       esac
 
-      # Aesthetically quote the argument.
-      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-      case $arg in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	arg="\"$arg\""
-	;;
-      esac
-      install_prog="$install_prog $arg"
-    done
+      # Delete the old objects.
+      $opt_dry_run || $RM $obj $libobj
 
-    if test -z "$install_prog"; then
-      $echo "$modename: you must specify an install program" 1>&2
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-    fi
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec and hope we can get by with
+      # turning comma into space..
+      wl=
 
-    if test -n "$prev"; then
-      $echo "$modename: the \`$prev' option requires an argument" 1>&2
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-    fi
+      if test -n "$convenience"; then
+	if test -n "$whole_archive_flag_spec"; then
+	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+	  reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+	else
+	  gentop="$output_objdir/${obj}x"
+	  func_append generated " $gentop"
 
-    if test -z "$files"; then
-      if test -z "$dest"; then
-	$echo "$modename: no file or destination specified" 1>&2
-      else
-	$echo "$modename: you must specify a destination" 1>&2
+	  func_extract_archives $gentop $convenience
+	  reload_conv_objs="$reload_objs $func_extract_archives_result"
+	fi
       fi
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-    fi
 
-    # Strip any trailing slash from the destination.
-    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+      # If we're not building shared, we need to use non_pic_objs
+      test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
 
-    # Check to see that the destination is a directory.
-    test -d "$dest" && isdir=yes
-    if test "$isdir" = yes; then
-      destdir="$dest"
-      destname=
-    else
-      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
-      test "X$destdir" = "X$dest" && destdir=.
-      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+      # Create the old-style object.
+      reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
 
-      # Not a directory, so check to see that there is only one file specified.
-      set dummy $files
-      if test "$#" -gt 2; then
-	$echo "$modename: \`$dest' is not a directory" 1>&2
-	$echo "$help" 1>&2
-	exit $EXIT_FAILURE
+      output="$obj"
+      func_execute_cmds "$reload_cmds" 'exit $?'
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	exit $EXIT_SUCCESS
       fi
-    fi
-    case $destdir in
-    [\\/]* | [A-Za-z]:[\\/]*) ;;
-    *)
-      for file in $files; do
-	case $file in
-	*.lo) ;;
-	*)
-	  $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
-	  $echo "$help" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
-      done
+
+      if test "$build_libtool_libs" != yes; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	# Create an invalid libtool object if no PIC, so that we don't
+	# accidentally link it into a program.
+	# $show "echo timestamp > $libobj"
+	# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+	exit $EXIT_SUCCESS
+      fi
+
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
+	# Only do commands if we really have different PIC objects.
+	reload_objs="$libobjs $reload_conv_objs"
+	output="$libobj"
+	func_execute_cmds "$reload_cmds" 'exit $?'
+      fi
+
+      if test -n "$gentop"; then
+	func_show_eval '${RM}r "$gentop"'
+      fi
+
+      exit $EXIT_SUCCESS
       ;;
-    esac
 
-    # This variable tells wrapper scripts just to set variables rather
-    # than running their programs.
-    libtool_install_magic="$magic"
+    prog)
+      case $host in
+	*cygwin*) func_stripname '' '.exe' "$output"
+	          output=$func_stripname_result.exe;;
+      esac
+      test -n "$vinfo" && \
+	func_warning "\`-version-info' is ignored for programs"
 
-    staticlibs=
-    future_libdirs=
-    current_libdirs=
-    for file in $files; do
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for programs"
 
-      # Do each installation.
-      case $file in
-      *.$libext)
-	# Do the static libraries later.
-	staticlibs="$staticlibs $file"
+      test "$preload" = yes \
+        && test "$dlopen_support" = unknown \
+	&& test "$dlopen_self" = unknown \
+	&& test "$dlopen_self_static" = unknown && \
+	  func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+	# On Rhapsody replace the C library is the System framework
+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
 	;;
+      esac
 
-      *.la)
-	# Check to see that this really is a libtool archive.
-	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
-	else
-	  $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
-	  $echo "$help" 1>&2
-	  exit $EXIT_FAILURE
+      case $host in
+      *-*-darwin*)
+	# Don't allow lazy linking, it breaks C++ global constructors
+	# But is supposedly fixed on 10.4 or later (yay!).
+	if test "$tagname" = CXX ; then
+	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+	    10.[0123])
+	      func_append compile_command " ${wl}-bind_at_load"
+	      func_append finalize_command " ${wl}-bind_at_load"
+	    ;;
+	  esac
 	fi
+	# Time to change all our "foo.ltframework" stuff back to "-framework foo"
+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	;;
+      esac
 
-	library_names=
-	old_library=
-	relink_command=
-	# If there is no directory component, then add one.
-	case $file in
-	*/* | *\\*) . $file ;;
-	*) . ./$file ;;
-	esac
 
-	# Add the libdir to current_libdirs if it is the destination.
-	if test "X$destdir" = "X$libdir"; then
-	  case "$current_libdirs " in
-	  *" $libdir "*) ;;
-	  *) current_libdirs="$current_libdirs $libdir" ;;
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $compile_deplibs " in
+	  *" -L$path/$objdir "*)
+	    func_append new_libs " -L$path/$objdir" ;;
 	  esac
-	else
-	  # Note the libdir as a future libdir.
-	  case "$future_libdirs " in
-	  *" $libdir "*) ;;
-	  *) future_libdirs="$future_libdirs $libdir" ;;
+	  ;;
+	esac
+      done
+      for deplib in $compile_deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) func_append new_libs " $deplib" ;;
 	  esac
-	fi
+	  ;;
+	*) func_append new_libs " $deplib" ;;
+	esac
+      done
+      compile_deplibs="$new_libs"
 
-	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/
-	test "X$dir" = "X$file/" && dir=
-	dir="$dir$objdir"
 
-	if test -n "$relink_command"; then
-	  # Determine the prefix the user has applied to our future dir.
-	  inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"`
+      func_append compile_command " $compile_deplibs"
+      func_append finalize_command " $finalize_deplibs"
 
-	  # Don't allow the user to place us outside of our expected
-	  # location b/c this prevents finding dependent libraries that
-	  # are installed to the same prefix.
-	  # At present, this check doesn't affect windows .dll's that
-	  # are installed into $libdir/../bin (currently, that works fine)
-	  # but it's something to keep an eye on.
-	  if test "$inst_prefix_dir" = "$destdir"; then
-	    $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
+      if test -n "$rpath$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath $xrpath; do
+	  # This is the magic to use -rpath.
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_rpath " $libdir" ;;
+	  esac
+	done
+      fi
 
-	  if test -n "$inst_prefix_dir"; then
-	    # Stick the inst_prefix_dir data into the link command.
-	    relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%" | $NL2SP`
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
 	  else
-	    relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%%" | $NL2SP`
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    func_append rpath " $flag"
 	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append perm_rpath " $libdir" ;;
+	  esac
+	fi
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$libdir:"*) ;;
+	  ::) dllsearchpath=$libdir;;
+	  *) func_append dllsearchpath ":$libdir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append dllsearchpath ":$testbindir";;
+	  esac
+	  ;;
+	esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
 
-	  $echo "$modename: warning: relinking \`$file'" 1>&2
-	  $show "$relink_command"
-	  if $run eval "$relink_command"; then :
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
 	  else
-	    $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
-	    exit $EXIT_FAILURE
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    func_append rpath " $flag"
 	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_perm_rpath " $libdir" ;;
+	  esac
 	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
 
-	# See the names of the shared library.
-	set dummy $library_names
-	if test -n "$2"; then
-	  realname="$2"
-	  shift
-	  shift
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+	# Transform all the library objects into standard objects.
+	compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+      fi
 
-	  srcname="$realname"
-	  test -n "$relink_command" && srcname="$realname"T
+      func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
 
-	  # Install the shared library and build the symlinks.
-	  $show "$install_prog $dir/$srcname $destdir/$realname"
-	  $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $?
-	  if test -n "$stripme" && test -n "$striplib"; then
-	    $show "$striplib $destdir/$realname"
-	    $run eval "$striplib $destdir/$realname" || exit $?
-	  fi
+      # template prelinking step
+      if test -n "$prelink_cmds"; then
+	func_execute_cmds "$prelink_cmds" 'exit $?'
+      fi
 
-	  if test "$#" -gt 0; then
-	    # Delete the old symlinks, and create new ones.
-	    # Try `ln -sf' first, because the `ln' binary might depend on
-	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
-	    # so we also need to try rm && ln -s.
-	    for linkname
-	    do
-	      if test "$linkname" != "$realname"; then
-                $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
-                $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
-	      fi
-	    done
-	  fi
+      wrappers_required=yes
+      case $host in
+      *cegcc* | *mingw32ce*)
+        # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+        wrappers_required=no
+        ;;
+      *cygwin* | *mingw* )
+        if test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      *)
+        if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      esac
+      if test "$wrappers_required" = no; then
+	# Replace the output file specification.
+	compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+	link_command="$compile_command$compile_rpath"
 
-	  # Do each command in the postinstall commands.
-	  lib="$destdir/$realname"
-	  cmds=$postinstall_cmds
-	  save_ifs="$IFS"; IFS='~'
-	  for cmd in $cmds; do
-	    IFS="$save_ifs"
-	    eval cmd=\"$cmd\"
-	    $show "$cmd"
-	    $run eval "$cmd" || {
-	      lt_exit=$?
-
-	      # Restore the uninstalled library and exit
-	      if test "$mode" = relink; then
-		$run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
-	      fi
+	# We have no uninstalled library dependencies, so finalize right now.
+	exit_status=0
+	func_show_eval "$link_command" 'exit_status=$?'
 
-	      exit $lt_exit
-	    }
-	  done
-	  IFS="$save_ifs"
+	if test -n "$postlink_cmds"; then
+	  func_to_tool_file "$output"
+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	  func_execute_cmds "$postlink_cmds" 'exit $?'
 	fi
 
-	# Install the pseudo-library for information purposes.
-	name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-	instname="$dir/$name"i
-	$show "$install_prog $instname $destdir/$name"
-	$run eval "$install_prog $instname $destdir/$name" || exit $?
+	# Delete the generated files.
+	if test -f "$output_objdir/${outputname}S.${objext}"; then
+	  func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+	fi
 
-	# Maybe install the static library, too.
-	test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
-	;;
+	exit $exit_status
+      fi
 
-      *.lo)
-	# Install (i.e. copy) a libtool object.
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
 
-	# Figure out destination file name, if it wasn't already specified.
-	if test -n "$destname"; then
-	  destfile="$destdir/$destname"
-	else
-	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-	  destfile="$destdir/$destfile"
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+	if test -n "$perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $perm_rpath; do
+	    func_append rpath "$dir:"
+	  done
+	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
 	fi
-
-	# Deduce the name of the destination old-style object file.
-	case $destfile in
-	*.lo)
-	  staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
-	  ;;
-	*.$objext)
-	  staticdest="$destfile"
-	  destfile=
-	  ;;
-	*)
-	  $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
-	  $echo "$help" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
-
-	# Install the libtool object if requested.
-	if test -n "$destfile"; then
-	  $show "$install_prog $file $destfile"
-	  $run eval "$install_prog $file $destfile" || exit $?
+	if test -n "$finalize_perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $finalize_perm_rpath; do
+	    func_append rpath "$dir:"
+	  done
+	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
 	fi
+      fi
 
-	# Install the old object if enabled.
-	if test "$build_old_libs" = yes; then
-	  # Deduce the name of the old-style object file.
-	  staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+      if test "$no_install" = yes; then
+	# We don't need to create a wrapper script.
+	link_command="$compile_var$compile_command$compile_rpath"
+	# Replace the output file specification.
+	link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+	# Delete the old output file.
+	$opt_dry_run || $RM $output
+	# Link the executable and exit
+	func_show_eval "$link_command" 'exit $?'
 
-	  $show "$install_prog $staticobj $staticdest"
-	  $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+	if test -n "$postlink_cmds"; then
+	  func_to_tool_file "$output"
+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	  func_execute_cmds "$postlink_cmds" 'exit $?'
 	fi
+
 	exit $EXIT_SUCCESS
-	;;
+      fi
 
-      *)
-	# Figure out destination file name, if it wasn't already specified.
-	if test -n "$destname"; then
-	  destfile="$destdir/$destname"
+      if test "$hardcode_action" = relink; then
+	# Fast installation is not supported
+	link_command="$compile_var$compile_command$compile_rpath"
+	relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+	func_warning "this platform does not like uninstalled shared libraries"
+	func_warning "\`$output' will be relinked during installation"
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+	  else
+	    # fast_install is set to needless
+	    relink_command=
+	  fi
 	else
-	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-	  destfile="$destdir/$destfile"
+	  link_command="$compile_var$compile_command$compile_rpath"
+	  relink_command="$finalize_var$finalize_command$finalize_rpath"
 	fi
+      fi
 
-	# If the file is missing, and there is a .exe on the end, strip it
-	# because it is most likely a libtool script we actually want to
-	# install
-	stripped_ext=""
-	case $file in
-	  *.exe)
-	    if test ! -f "$file"; then
-	      file=`$echo $file|${SED} 's,.exe$,,'`
-	      stripped_ext=".exe"
-	    fi
-	    ;;
-	esac
-
-	# Do a test to see if this is really a libtool program.
-	case $host in
-	*cygwin*|*mingw*)
-	    wrapper=`$echo $file | ${SED} -e 's,.exe$,,'`
-	    ;;
-	*)
-	    wrapper=$file
-	    ;;
-	esac
-	if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then
-	  notinst_deplibs=
-	  relink_command=
+      # Replace the output file specification.
+      link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
 
-	  # Note that it is not necessary on cygwin/mingw to append a dot to
-	  # foo even if both foo and FILE.exe exist: automatic-append-.exe
-	  # behavior happens only for exec(3), not for open(2)!  Also, sourcing
-	  # `FILE.' does not work on cygwin managed mounts.
-	  #
-	  # If there is no directory component, then add one.
-	  case $wrapper in
-	  */* | *\\*) . ${wrapper} ;;
-	  *) . ./${wrapper} ;;
-	  esac
+      # Delete the old output files.
+      $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
 
-	  # Check the variables that should have been set.
-	  if test -z "$notinst_deplibs"; then
-	    $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
+      func_show_eval "$link_command" 'exit $?'
 
-	  finalize=yes
-	  for lib in $notinst_deplibs; do
-	    # Check to see that each library is installed.
-	    libdir=
-	    if test -f "$lib"; then
-	      # If there is no directory component, then add one.
-	      case $lib in
-	      */* | *\\*) . $lib ;;
-	      *) . ./$lib ;;
-	      esac
-	    fi
-	    libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
-	    if test -n "$libdir" && test ! -f "$libfile"; then
-	      $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
-	      finalize=no
-	    fi
-	  done
+      if test -n "$postlink_cmds"; then
+	func_to_tool_file "$output_objdir/$outputname"
+	postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	func_execute_cmds "$postlink_cmds" 'exit $?'
+      fi
 
-	  relink_command=
-	  # Note that it is not necessary on cygwin/mingw to append a dot to
-	  # foo even if both foo and FILE.exe exist: automatic-append-.exe
-	  # behavior happens only for exec(3), not for open(2)!  Also, sourcing
-	  # `FILE.' does not work on cygwin managed mounts.
-	  #
-	  # If there is no directory component, then add one.
-	  case $wrapper in
-	  */* | *\\*) . ${wrapper} ;;
-	  *) . ./${wrapper} ;;
-	  esac
+      # Now create the wrapper script.
+      func_verbose "creating $output"
 
-	  outputname=
-	  if test "$fast_install" = no && test -n "$relink_command"; then
-	    if test "$finalize" = yes && test -z "$run"; then
-	      tmpdir=`func_mktempdir`
-	      file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'`
-	      outputname="$tmpdir/$file"
-	      # Replace the output file specification.
-	      relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g' | $NL2SP`
-
-	      $show "$relink_command"
-	      if $run eval "$relink_command"; then :
-	      else
-		$echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
-		${rm}r "$tmpdir"
-		continue
-	      fi
-	      file="$outputname"
-	    else
-	      $echo "$modename: warning: cannot relink \`$file'" 1>&2
-	    fi
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+	# Preserve any variables that may affect compiler behavior
+	for var in $variables_saved_for_relink; do
+	  if eval test -z \"\${$var+set}\"; then
+	    relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	  elif eval var_value=\$$var; test -z "$var_value"; then
+	    relink_command="$var=; export $var; $relink_command"
 	  else
-	    # Install the binary that we compiled earlier.
-	    file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+	    func_quote_for_eval "$var_value"
+	    relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
 	  fi
-	fi
-
-	# remove .exe since cygwin /usr/bin/install will append another
-	# one anyway 
-	case $install_prog,$host in
-	*/usr/bin/install*,*cygwin*)
-	  case $file:$destfile in
-	  *.exe:*.exe)
-	    # this is ok
-	    ;;
-	  *.exe:*)
-	    destfile=$destfile.exe
-	    ;;
-	  *:*.exe)
-	    destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'`
-	    ;;
-	  esac
-	  ;;
+	done
+	relink_command="(cd `pwd`; $relink_command)"
+	relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if not in dry run mode.
+      $opt_dry_run || {
+	# win32 will think the script is a binary if it has
+	# a .exe suffix, so we strip it off here.
+	case $output in
+	  *.exe) func_stripname '' '.exe' "$output"
+	         output=$func_stripname_result ;;
 	esac
-	$show "$install_prog$stripme $file $destfile"
-	$run eval "$install_prog\$stripme \$file \$destfile" || exit $?
-	test -n "$outputname" && ${rm}r "$tmpdir"
-	;;
-      esac
-    done
+	# test for cygwin because mv fails w/o .exe extensions
+	case $host in
+	  *cygwin*)
+	    exeext=.exe
+	    func_stripname '' '.exe' "$outputname"
+	    outputname=$func_stripname_result ;;
+	  *) exeext= ;;
+	esac
+	case $host in
+	  *cygwin* | *mingw* )
+	    func_dirname_and_basename "$output" "" "."
+	    output_name=$func_basename_result
+	    output_path=$func_dirname_result
+	    cwrappersource="$output_path/$objdir/lt-$output_name.c"
+	    cwrapper="$output_path/$output_name.exe"
+	    $RM $cwrappersource $cwrapper
+	    trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_cwrapperexe_src > $cwrappersource
+
+	    # The wrapper executable is built using the $host compiler,
+	    # because it contains $host paths and files. If cross-
+	    # compiling, it, like the target executable, must be
+	    # executed on the $host or under an emulation environment.
+	    $opt_dry_run || {
+	      $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+	      $STRIP $cwrapper
+	    }
 
-    for file in $staticlibs; do
-      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	    # Now, create the wrapper script for func_source use:
+	    func_ltwrapper_scriptname $cwrapper
+	    $RM $func_ltwrapper_scriptname_result
+	    trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+	    $opt_dry_run || {
+	      # note: this script will not be executed, so do not chmod.
+	      if test "x$build" = "x$host" ; then
+		$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+	      else
+		func_emit_wrapper no > $func_ltwrapper_scriptname_result
+	      fi
+	    }
+	  ;;
+	  * )
+	    $RM $output
+	    trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
 
-      # Set up the ranlib parameters.
-      oldlib="$destdir/$name"
+	    func_emit_wrapper no > $output
+	    chmod +x $output
+	  ;;
+	esac
+      }
+      exit $EXIT_SUCCESS
+      ;;
+    esac
 
-      $show "$install_prog $file $oldlib"
-      $run eval "$install_prog \$file \$oldlib" || exit $?
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
 
-      if test -n "$stripme" && test -n "$old_striplib"; then
-	$show "$old_striplib $oldlib"
-	$run eval "$old_striplib $oldlib" || exit $?
+      if test "$build_libtool_libs" = convenience; then
+	oldobjs="$libobjs_save $symfileobj"
+	addlibs="$convenience"
+	build_libtool_libs=no
+      else
+	if test "$build_libtool_libs" = module; then
+	  oldobjs="$libobjs_save"
+	  build_libtool_libs=no
+	else
+	  oldobjs="$old_deplibs $non_pic_objects"
+	  if test "$preload" = yes && test -f "$symfileobj"; then
+	    func_append oldobjs " $symfileobj"
+	  fi
+	fi
+	addlibs="$old_convenience"
       fi
 
-      # Do each command in the postinstall commands.
-      cmds=$old_postinstall_cmds
-      save_ifs="$IFS"; IFS='~'
-      for cmd in $cmds; do
-	IFS="$save_ifs"
-	eval cmd=\"$cmd\"
-	$show "$cmd"
-	$run eval "$cmd" || exit $?
-      done
-      IFS="$save_ifs"
-    done
+      if test -n "$addlibs"; then
+	gentop="$output_objdir/${outputname}x"
+	func_append generated " $gentop"
 
-    if test -n "$future_libdirs"; then
-      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
-    fi
+	func_extract_archives $gentop $addlibs
+	func_append oldobjs " $func_extract_archives_result"
+      fi
 
-    if test -n "$current_libdirs"; then
-      # Maybe just do a dry run.
-      test -n "$run" && current_libdirs=" -n$current_libdirs"
-      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
-    else
-      exit $EXIT_SUCCESS
-    fi
-    ;;
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+	cmds=$old_archive_from_new_cmds
+      else
 
-  # libtool finish mode
-  finish)
-    modename="$modename: finish"
-    libdirs="$nonopt"
-    admincmds=
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
 
-    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
-      for dir
-      do
-	libdirs="$libdirs $dir"
-      done
+	  func_extract_archives $gentop $dlprefiles
+	  func_append oldobjs " $func_extract_archives_result"
+	fi
 
-      for libdir in $libdirs; do
-	if test -n "$finish_cmds"; then
-	  # Do each command in the finish commands.
-	  cmds=$finish_cmds
-	  save_ifs="$IFS"; IFS='~'
-	  for cmd in $cmds; do
-	    IFS="$save_ifs"
-	    eval cmd=\"$cmd\"
-	    $show "$cmd"
-	    $run eval "$cmd" || admincmds="$admincmds
-       $cmd"
+	# POSIX demands no paths to be encoded in archives.  We have
+	# to avoid creating archives with duplicate basenames if we
+	# might have to extract them afterwards, e.g., when creating a
+	# static archive out of a convenience library, or when linking
+	# the entirety of a libtool archive into another (currently
+	# not supported by libtool).
+	if (for obj in $oldobjs
+	    do
+	      func_basename "$obj"
+	      $ECHO "$func_basename_result"
+	    done | sort | sort -uc >/dev/null 2>&1); then
+	  :
+	else
+	  echo "copying selected object files to avoid basename conflicts..."
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
+	  func_mkdir_p "$gentop"
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  counter=1
+	  for obj in $save_oldobjs
+	  do
+	    func_basename "$obj"
+	    objbase="$func_basename_result"
+	    case " $oldobjs " in
+	    " ") oldobjs=$obj ;;
+	    *[\ /]"$objbase "*)
+	      while :; do
+		# Make sure we don't pick an alternate name that also
+		# overlaps.
+		newobj=lt$counter-$objbase
+		func_arith $counter + 1
+		counter=$func_arith_result
+		case " $oldobjs " in
+		*[\ /]"$newobj "*) ;;
+		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
+		esac
+	      done
+	      func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+	      func_append oldobjs " $gentop/$newobj"
+	      ;;
+	    *) func_append oldobjs " $obj" ;;
+	    esac
 	  done
-	  IFS="$save_ifs"
-	fi
-	if test -n "$finish_eval"; then
-	  # Do the single finish_eval.
-	  eval cmds=\"$finish_eval\"
-	  $run eval "$cmds" || admincmds="$admincmds
-       $cmds"
 	fi
-      done
-    fi
-
-    # Exit here if they wanted silent mode.
-    test "$show" = : && exit $EXIT_SUCCESS
+	func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+	tool_oldlib=$func_to_tool_file_result
+	eval cmds=\"$old_archive_cmds\"
 
-    $echo "X----------------------------------------------------------------------" | $Xsed
-    $echo "Libraries have been installed in:"
-    for libdir in $libdirs; do
-      $echo "   $libdir"
+	func_len " $cmds"
+	len=$func_len_result
+	if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  cmds=$old_archive_cmds
+	elif test -n "$archiver_list_spec"; then
+	  func_verbose "using command file archive linking..."
+	  for obj in $oldobjs
+	  do
+	    func_to_tool_file "$obj"
+	    $ECHO "$func_to_tool_file_result"
+	  done > $output_objdir/$libname.libcmd
+	  func_to_tool_file "$output_objdir/$libname.libcmd"
+	  oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+	  cmds=$old_archive_cmds
+	else
+	  # the command line is too long to link in one step, link in parts
+	  func_verbose "using piecewise archive linking..."
+	  save_RANLIB=$RANLIB
+	  RANLIB=:
+	  objlist=
+	  concat_cmds=
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  # Is there a better way of finding the last object in the list?
+	  for obj in $save_oldobjs
+	  do
+	    last_oldobj=$obj
+	  done
+	  eval test_cmds=\"$old_archive_cmds\"
+	  func_len " $test_cmds"
+	  len0=$func_len_result
+	  len=$len0
+	  for obj in $save_oldobjs
+	  do
+	    func_len " $obj"
+	    func_arith $len + $func_len_result
+	    len=$func_arith_result
+	    func_append objlist " $obj"
+	    if test "$len" -lt "$max_cmd_len"; then
+	      :
+	    else
+	      # the above command should be used before it gets too long
+	      oldobjs=$objlist
+	      if test "$obj" = "$last_oldobj" ; then
+		RANLIB=$save_RANLIB
+	      fi
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+	      objlist=
+	      len=$len0
+	    fi
+	  done
+	  RANLIB=$save_RANLIB
+	  oldobjs=$objlist
+	  if test "X$oldobjs" = "X" ; then
+	    eval cmds=\"\$concat_cmds\"
+	  else
+	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+	  fi
+	fi
+      fi
+      func_execute_cmds "$cmds" 'exit $?'
     done
-    $echo
-    $echo "If you ever happen to want to link against installed libraries"
-    $echo "in a given directory, LIBDIR, you must either use libtool, and"
-    $echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
-    $echo "flag during linking and do at least one of the following:"
-    if test -n "$shlibpath_var"; then
-      $echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
-      $echo "     during execution"
-    fi
-    if test -n "$runpath_var"; then
-      $echo "   - add LIBDIR to the \`$runpath_var' environment variable"
-      $echo "     during linking"
-    fi
-    if test -n "$hardcode_libdir_flag_spec"; then
-      libdir=LIBDIR
-      eval flag=\"$hardcode_libdir_flag_spec\"
-
-      $echo "   - use the \`$flag' linker flag"
-    fi
-    if test -n "$admincmds"; then
-      $echo "   - have your system administrator run these commands:$admincmds"
-    fi
-    if test -f /etc/ld.so.conf; then
-      $echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
-    fi
-    $echo
-    $echo "See any operating system documentation about shared libraries for"
-    $echo "more information, such as the ld(1) and ld.so(8) manual pages."
-    $echo "X----------------------------------------------------------------------" | $Xsed
-    exit $EXIT_SUCCESS
-    ;;
 
-  # libtool execute mode
-  execute)
-    modename="$modename: execute"
-
-    # The first argument is the command name.
-    cmd="$nonopt"
-    if test -z "$cmd"; then
-      $echo "$modename: you must specify a COMMAND" 1>&2
-      $echo "$help"
-      exit $EXIT_FAILURE
-    fi
+    test -n "$generated" && \
+      func_show_eval "${RM}r$generated"
 
-    # Handle -dlopen flags immediately.
-    for file in $execute_dlfiles; do
-      if test ! -f "$file"; then
-	$echo "$modename: \`$file' is not a file" 1>&2
-	$echo "$help" 1>&2
-	exit $EXIT_FAILURE
-      fi
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      func_verbose "creating $output"
 
-      dir=
-      case $file in
-      *.la)
-	# Check to see that this really is a libtool archive.
-	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+	if eval test -z \"\${$var+set}\"; then
+	  relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	elif eval var_value=\$$var; test -z "$var_value"; then
+	  relink_command="$var=; export $var; $relink_command"
 	else
-	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
-	  $echo "$help" 1>&2
-	  exit $EXIT_FAILURE
+	  func_quote_for_eval "$var_value"
+	  relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
 	fi
+      done
+      # Quote the link command for shipping.
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      if test "$hardcode_automatic" = yes ; then
+	relink_command=
+      fi
 
-	# Read the libtool library.
-	dlname=
-	library_names=
+      # Only create the output if not a dry run.
+      $opt_dry_run || {
+	for installed in no yes; do
+	  if test "$installed" = yes; then
+	    if test -z "$install_libdir"; then
+	      break
+	    fi
+	    output="$output_objdir/$outputname"i
+	    # Replace all uninstalled libtool libraries with the installed ones
+	    newdependency_libs=
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      *.la)
+		func_basename "$deplib"
+		name="$func_basename_result"
+		func_resolve_sysroot "$deplib"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$deplib' is not a valid libtool archive"
+		func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      -L*)
+		func_stripname -L '' "$deplib"
+		func_replace_sysroot "$func_stripname_result"
+		func_append newdependency_libs " -L$func_replace_sysroot_result"
+		;;
+	      -R*)
+		func_stripname -R '' "$deplib"
+		func_replace_sysroot "$func_stripname_result"
+		func_append newdependency_libs " -R$func_replace_sysroot_result"
+		;;
+	      *) func_append newdependency_libs " $deplib" ;;
+	      esac
+	    done
+	    dependency_libs="$newdependency_libs"
+	    newdlfiles=
+
+	    for lib in $dlfiles; do
+	      case $lib in
+	      *.la)
+	        func_basename "$lib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
+		func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      *) func_append newdlfiles " $lib" ;;
+	      esac
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+	      *.la)
+		# Only pass preopened files to the pseudo-archive (for
+		# eventual linking with the app. that links it) if we
+		# didn't already link the preopened objects directly into
+		# the library:
+		func_basename "$lib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
+		func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      esac
+	    done
+	    dlprefiles="$newdlprefiles"
+	  else
+	    newdlfiles=
+	    for lib in $dlfiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      func_append newdlfiles " $abs"
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      func_append newdlprefiles " $abs"
+	    done
+	    dlprefiles="$newdlprefiles"
+	  fi
+	  $RM $output
+	  # place dlname in correct position for cygwin
+	  # In fact, it would be nice if we could use this code for all target
+	  # systems that can't hard-code library paths into their executables
+	  # and that have no shared library path variable independent of PATH,
+	  # but it turns out we can't easily determine that from inspecting
+	  # libtool variables, so we have to hard-code the OSs to which it
+	  # applies here; at the moment, that means platforms that use the PE
+	  # object format with DLL files.  See the long comment at the top of
+	  # tests/bindir.at for full details.
+	  tdlname=$dlname
+	  case $host,$output,$installed,$module,$dlname in
+	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+	      # If a -bindir argument was supplied, place the dll there.
+	      if test "x$bindir" != x ;
+	      then
+		func_relative_path "$install_libdir" "$bindir"
+		tdlname=$func_relative_path_result$dlname
+	      else
+		# Otherwise fall back on heuristic.
+		tdlname=../bin/$dlname
+	      fi
+	      ;;
+	  esac
+	  $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
 
-	# If there is no directory component, then add one.
-	case $file in
-	*/* | *\\*) . $file ;;
-	*) . ./$file ;;
-	esac
+# The name that we can dlopen(3).
+dlname='$tdlname'
 
-	# Skip this library if it cannot be dlopened.
-	if test -z "$dlname"; then
-	  # Warn if it was a shared library.
-	  test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
-	  continue
-	fi
+# Names of this library.
+library_names='$library_names'
 
-	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
-	test "X$dir" = "X$file" && dir=.
+# The name of the static archive.
+old_library='$old_library'
 
-	if test -f "$dir/$objdir/$dlname"; then
-	  dir="$dir/$objdir"
-	else
-	  if test ! -f "$dir/$dlname"; then
-	    $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-	fi
-	;;
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
 
-      *.lo)
-	# Just add the directory containing the .lo file.
-	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
-	test "X$dir" = "X$file" && dir=.
-	;;
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
 
-      *)
-	$echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
-	continue
-	;;
-      esac
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
 
-      # Get the absolute pathname.
-      absdir=`cd "$dir" && pwd`
-      test -n "$absdir" && dir="$absdir"
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
 
-      # Now add the directory to shlibpath_var.
-      if eval "test -z \"\$$shlibpath_var\""; then
-	eval "$shlibpath_var=\"\$dir\""
-      else
-	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
-      fi
-    done
+# Is this an already installed library?
+installed=$installed
 
-    # This variable tells wrapper scripts just to set shlibpath_var
-    # rather than running their programs.
-    libtool_execute_magic="$magic"
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
 
-    # Check if any of the arguments is a wrapper script.
-    args=
-    for file
-    do
-      case $file in
-      -*) ;;
-      *)
-	# Do a test to see if this is really a libtool program.
-	if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-	  # If there is no directory component, then add one.
-	  case $file in
-	  */* | *\\*) . $file ;;
-	  *) . ./$file ;;
-	  esac
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
 
-	  # Transform arg to wrapped name.
-	  file="$progdir/$program"
-	fi
-	;;
-      esac
-      # Quote arguments (to preserve shell metacharacters).
-      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
-      args="$args \"$file\""
-    done
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+	  if test "$installed" = no && test "$need_relink" = yes; then
+	    $ECHO >> $output "\
+relink_command=\"$relink_command\""
+	  fi
+	done
+      }
 
-    if test -z "$run"; then
-      if test -n "$shlibpath_var"; then
-	# Export the shlibpath_var.
-	eval "export $shlibpath_var"
-      fi
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+      ;;
+    esac
+    exit $EXIT_SUCCESS
+}
 
-      # Restore saved environment variables
-      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
-      do
-	eval "if test \"\${save_$lt_var+set}\" = set; then
-		$lt_var=\$save_$lt_var; export $lt_var
-	      fi"
-      done
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+    func_mode_link ${1+"$@"}
 
-      # Now prepare to actually exec the command.
-      exec_cmd="\$cmd$args"
-    else
-      # Display what would be done.
-      if test -n "$shlibpath_var"; then
-	eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
-	$echo "export $shlibpath_var"
-      fi
-      $echo "$cmd$args"
-      exit $EXIT_SUCCESS
-    fi
-    ;;
 
-  # libtool clean and uninstall mode
-  clean | uninstall)
-    modename="$modename: $mode"
-    rm="$nonopt"
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+    $opt_debug
+    RM="$nonopt"
     files=
     rmforce=
     exit_status=0
@@ -6547,44 +9460,41 @@ relink_command=\"$relink_command\""
     for arg
     do
       case $arg in
-      -f) rm="$rm $arg"; rmforce=yes ;;
-      -*) rm="$rm $arg" ;;
-      *) files="$files $arg" ;;
+      -f) func_append RM " $arg"; rmforce=yes ;;
+      -*) func_append RM " $arg" ;;
+      *) func_append files " $arg" ;;
       esac
     done
 
-    if test -z "$rm"; then
-      $echo "$modename: you must specify an RM program" 1>&2
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-    fi
+    test -z "$RM" && \
+      func_fatal_help "you must specify an RM program"
 
     rmdirs=
 
-    origobjdir="$objdir"
     for file in $files; do
-      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
-      if test "X$dir" = "X$file"; then
-	dir=.
-	objdir="$origobjdir"
+      func_dirname "$file" "" "."
+      dir="$func_dirname_result"
+      if test "X$dir" = X.; then
+	odir="$objdir"
       else
-	objdir="$dir/$origobjdir"
+	odir="$dir/$objdir"
       fi
-      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-      test "$mode" = uninstall && objdir="$dir"
+      func_basename "$file"
+      name="$func_basename_result"
+      test "$opt_mode" = uninstall && odir="$dir"
 
-      # Remember objdir for removal later, being careful to avoid duplicates
-      if test "$mode" = clean; then
+      # Remember odir for removal later, being careful to avoid duplicates
+      if test "$opt_mode" = clean; then
 	case " $rmdirs " in
-	  *" $objdir "*) ;;
-	  *) rmdirs="$rmdirs $objdir" ;;
+	  *" $odir "*) ;;
+	  *) func_append rmdirs " $odir" ;;
 	esac
       fi
 
       # Don't error if the file doesn't exist and rm -f was used.
-      if (test -L "$file") >/dev/null 2>&1 \
-	|| (test -h "$file") >/dev/null 2>&1 \
-	|| test -f "$file"; then
+      if { test -L "$file"; } >/dev/null 2>&1 ||
+	 { test -h "$file"; } >/dev/null 2>&1 ||
+	 test -f "$file"; then
 	:
       elif test -d "$file"; then
 	exit_status=1
@@ -6598,55 +9508,32 @@ relink_command=\"$relink_command\""
       case $name in
       *.la)
 	# Possibly a libtool archive, so verify it.
-	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-	  . $dir/$name
+	if func_lalib_p "$file"; then
+	  func_source $dir/$name
 
 	  # Delete the libtool libraries and symlinks.
 	  for n in $library_names; do
-	    rmfiles="$rmfiles $objdir/$n"
+	    func_append rmfiles " $odir/$n"
 	  done
-	  test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+	  test -n "$old_library" && func_append rmfiles " $odir/$old_library"
 
-	  case "$mode" in
+	  case "$opt_mode" in
 	  clean)
-	    case "  $library_names " in
-	    # "  " in the beginning catches empty $dlname
+	    case " $library_names " in
 	    *" $dlname "*) ;;
-	    *) rmfiles="$rmfiles $objdir/$dlname" ;;
+	    *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
 	    esac
-	     test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+	    test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
 	    ;;
 	  uninstall)
 	    if test -n "$library_names"; then
 	      # Do each command in the postuninstall commands.
-	      cmds=$postuninstall_cmds
-	      save_ifs="$IFS"; IFS='~'
-	      for cmd in $cmds; do
-		IFS="$save_ifs"
-		eval cmd=\"$cmd\"
-		$show "$cmd"
-		$run eval "$cmd"
-		if test "$?" -ne 0 && test "$rmforce" != yes; then
-		  exit_status=1
-		fi
-	      done
-	      IFS="$save_ifs"
+	      func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
 	    fi
 
 	    if test -n "$old_library"; then
 	      # Do each command in the old_postuninstall commands.
-	      cmds=$old_postuninstall_cmds
-	      save_ifs="$IFS"; IFS='~'
-	      for cmd in $cmds; do
-		IFS="$save_ifs"
-		eval cmd=\"$cmd\"
-		$show "$cmd"
-		$run eval "$cmd"
-		if test "$?" -ne 0 && test "$rmforce" != yes; then
-		  exit_status=1
-		fi
-	      done
-	      IFS="$save_ifs"
+	      func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
 	    fi
 	    # FIXME: should reinstall the best remaining shared library.
 	    ;;
@@ -6656,288 +9543,95 @@ relink_command=\"$relink_command\""
 
       *.lo)
 	# Possibly a libtool object, so verify it.
-	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	if func_lalib_p "$file"; then
 
 	  # Read the .lo file
-	  . $dir/$name
+	  func_source $dir/$name
 
 	  # Add PIC object to the list of files to remove.
-	  if test -n "$pic_object" \
-	     && test "$pic_object" != none; then
-	    rmfiles="$rmfiles $dir/$pic_object"
+	  if test -n "$pic_object" &&
+	     test "$pic_object" != none; then
+	    func_append rmfiles " $dir/$pic_object"
 	  fi
 
 	  # Add non-PIC object to the list of files to remove.
-	  if test -n "$non_pic_object" \
-	     && test "$non_pic_object" != none; then
-	    rmfiles="$rmfiles $dir/$non_pic_object"
+	  if test -n "$non_pic_object" &&
+	     test "$non_pic_object" != none; then
+	    func_append rmfiles " $dir/$non_pic_object"
 	  fi
 	fi
 	;;
 
       *)
-	if test "$mode" = clean ; then
+	if test "$opt_mode" = clean ; then
 	  noexename=$name
 	  case $file in
 	  *.exe)
-	    file=`$echo $file|${SED} 's,.exe$,,'`
-	    noexename=`$echo $name|${SED} 's,.exe$,,'`
+	    func_stripname '' '.exe' "$file"
+	    file=$func_stripname_result
+	    func_stripname '' '.exe' "$name"
+	    noexename=$func_stripname_result
 	    # $file with .exe has already been added to rmfiles,
 	    # add $file without .exe
-	    rmfiles="$rmfiles $file"
+	    func_append rmfiles " $file"
 	    ;;
 	  esac
 	  # Do a test to see if this is a libtool program.
-	  if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-	    relink_command=
-	    . $dir/$noexename
+	  if func_ltwrapper_p "$file"; then
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      relink_command=
+	      func_source $func_ltwrapper_scriptname_result
+	      func_append rmfiles " $func_ltwrapper_scriptname_result"
+	    else
+	      relink_command=
+	      func_source $dir/$noexename
+	    fi
 
 	    # note $name still contains .exe if it was in $file originally
 	    # as does the version of $file that was added into $rmfiles
-	    rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+	    func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
 	    if test "$fast_install" = yes && test -n "$relink_command"; then
-	      rmfiles="$rmfiles $objdir/lt-$name"
+	      func_append rmfiles " $odir/lt-$name"
 	    fi
 	    if test "X$noexename" != "X$name" ; then
-	      rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+	      func_append rmfiles " $odir/lt-${noexename}.c"
 	    fi
 	  fi
 	fi
 	;;
       esac
-      $show "$rm $rmfiles"
-      $run $rm $rmfiles || exit_status=1
+      func_show_eval "$RM $rmfiles" 'exit_status=1'
     done
-    objdir="$origobjdir"
 
     # Try to remove the ${objdir}s in the directories where we deleted files
     for dir in $rmdirs; do
       if test -d "$dir"; then
-	$show "rmdir $dir"
-	$run rmdir $dir >/dev/null 2>&1
+	func_show_eval "rmdir $dir >/dev/null 2>&1"
       fi
     done
 
     exit $exit_status
-    ;;
+}
 
-  "")
-    $echo "$modename: you must specify a MODE" 1>&2
-    $echo "$generic_help" 1>&2
-    exit $EXIT_FAILURE
-    ;;
-  esac
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+    func_mode_uninstall ${1+"$@"}
 
-  if test -z "$exec_cmd"; then
-    $echo "$modename: invalid operation mode \`$mode'" 1>&2
-    $echo "$generic_help" 1>&2
-    exit $EXIT_FAILURE
-  fi
-fi # test -z "$show_help"
+test -z "$opt_mode" && {
+  help="$generic_help"
+  func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+  func_fatal_help "invalid operation mode \`$opt_mode'"
 
 if test -n "$exec_cmd"; then
-  eval exec $exec_cmd
+  eval exec "$exec_cmd"
   exit $EXIT_FAILURE
 fi
 
-# We need to display help for each of the modes.
-case $mode in
-"") $echo \
-"Usage: $modename [OPTION]... [MODE-ARG]...
-
-Provide generalized library-building support services.
-
-    --config          show all configuration variables
-    --debug           enable verbose shell tracing
--n, --dry-run         display commands without modifying any files
-    --features        display basic configuration information and exit
-    --finish          same as \`--mode=finish'
-    --help            display this help message and exit
-    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
-    --quiet           same as \`--silent'
-    --silent          don't print informational messages
-    --tag=TAG         use configuration variables from tag TAG
-    --version         print version information
-
-MODE must be one of the following:
-
-      clean           remove files from the build directory
-      compile         compile a source file into a libtool object
-      execute         automatically set library path, then run a program
-      finish          complete the installation of libtool libraries
-      install         install libraries or executables
-      link            create a library or an executable
-      uninstall       remove libraries from an installed directory
-
-MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
-a more detailed description of MODE.
-
-Report bugs to <bug-libtool at gnu.org>."
-  exit $EXIT_SUCCESS
-  ;;
-
-clean)
-  $echo \
-"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
-
-Remove files from the build directory.
-
-RM is the name of the program to use to delete files associated with each FILE
-(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
-to RM.
-
-If FILE is a libtool library, object or program, all the files associated
-with it are deleted. Otherwise, only FILE itself is deleted using RM."
-  ;;
-
-compile)
-  $echo \
-"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
-
-Compile a source file into a libtool library object.
-
-This mode accepts the following additional options:
-
-  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
-  -prefer-pic       try to building PIC objects only
-  -prefer-non-pic   try to building non-PIC objects only
-  -static           always build a \`.o' file suitable for static linking
-
-COMPILE-COMMAND is a command to be used in creating a \`standard' object file
-from the given SOURCEFILE.
-
-The output file name is determined by removing the directory component from
-SOURCEFILE, then substituting the C source code suffix \`.c' with the
-library object suffix, \`.lo'."
-  ;;
-
-execute)
-  $echo \
-"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
-
-Automatically set library path, then run a program.
-
-This mode accepts the following additional options:
-
-  -dlopen FILE      add the directory containing FILE to the library path
-
-This mode sets the library path environment variable according to \`-dlopen'
-flags.
-
-If any of the ARGS are libtool executable wrappers, then they are translated
-into their corresponding uninstalled binary, and any of their required library
-directories are added to the library path.
-
-Then, COMMAND is executed, with ARGS as arguments."
-  ;;
-
-finish)
-  $echo \
-"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
-
-Complete the installation of libtool libraries.
-
-Each LIBDIR is a directory that contains libtool libraries.
-
-The commands that this mode executes may require superuser privileges.  Use
-the \`--dry-run' option if you just want to see what would be executed."
-  ;;
-
-install)
-  $echo \
-"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
-
-Install executables or libraries.
-
-INSTALL-COMMAND is the installation command.  The first component should be
-either the \`install' or \`cp' program.
-
-The rest of the components are interpreted as arguments to that command (only
-BSD-compatible install options are recognized)."
-  ;;
-
-link)
-  $echo \
-"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
-
-Link object files or libraries together to form another library, or to
-create an executable program.
-
-LINK-COMMAND is a command using the C compiler that you would use to create
-a program from several object files.
-
-The following components of LINK-COMMAND are treated specially:
-
-  -all-static       do not do any dynamic linking at all
-  -avoid-version    do not add a version suffix if possible
-  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
-  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
-  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
-  -export-symbols SYMFILE
-                    try to export only the symbols listed in SYMFILE
-  -export-symbols-regex REGEX
-                    try to export only the symbols matching REGEX
-  -LLIBDIR          search LIBDIR for required installed libraries
-  -lNAME            OUTPUT-FILE requires the installed library libNAME
-  -module           build a library that can dlopened
-  -no-fast-install  disable the fast-install mode
-  -no-install       link a not-installable executable
-  -no-undefined     declare that a library does not refer to external symbols
-  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
-  -objectlist FILE  Use a list of object files found in FILE to specify objects
-  -precious-files-regex REGEX
-                    don't remove output files matching REGEX
-  -release RELEASE  specify package release information
-  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
-  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
-  -static           do not do any dynamic linking of uninstalled libtool libraries
-  -static-libtool-libs
-                    do not do any dynamic linking of libtool libraries
-  -version-info CURRENT[:REVISION[:AGE]]
-                    specify library version info [each variable defaults to 0]
-
-All other options (arguments beginning with \`-') are ignored.
-
-Every other argument is treated as a filename.  Files ending in \`.la' are
-treated as uninstalled libtool libraries, other files are standard or library
-object files.
-
-If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
-only library objects (\`.lo' files) may be specified, and \`-rpath' is
-required, except when creating a convenience library.
-
-If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
-using \`ar' and \`ranlib', or on Windows using \`lib'.
-
-If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
-is created, otherwise an executable program is created."
-  ;;
-
-uninstall)
-  $echo \
-"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+exit $exit_status
 
-Remove libraries from an installation directory.
-
-RM is the name of the program to use to delete files associated with each FILE
-(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
-to RM.
-
-If FILE is a libtool library, all the files associated with it are deleted.
-Otherwise, only FILE itself is deleted using RM."
-  ;;
-
-*)
-  $echo "$modename: invalid operation mode \`$mode'" 1>&2
-  $echo "$help" 1>&2
-  exit $EXIT_FAILURE
-  ;;
-esac
-
-$echo
-$echo "Try \`$modename --help' for more information about other modes."
-
-exit $?
 
 # The TAGs below are defined such that we never get into a situation
 # in which we disable both kinds of libraries.  Given conflicting
@@ -6951,14 +9645,17 @@ exit $?
 # configuration.  But we'll never go from static-only to shared-only.
 
 # ### BEGIN LIBTOOL TAG CONFIG: disable-shared
-disable_libs=shared
+build_libtool_libs=no
+build_old_libs=yes
 # ### END LIBTOOL TAG CONFIG: disable-shared
 
 # ### BEGIN LIBTOOL TAG CONFIG: disable-static
-disable_libs=static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
 # ### END LIBTOOL TAG CONFIG: disable-static
 
 # Local Variables:
 # mode:shell-script
 # sh-indentation:2
 # End:
+# vi:sw=2
+
diff --git a/ltoptions.m4 b/ltoptions.m4
new file mode 100644
index 0000000..5d9acd8
--- /dev/null
+++ b/ltoptions.m4
@@ -0,0 +1,384 @@
+# Helper functions for option handling.                    -*- Autoconf -*-
+#
+#   Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+#   Inc.
+#   Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 7 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it.  Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+        _LT_MANGLE_DEFUN([$1], [$2]),
+    [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+	    [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+		      [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME.  If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+    [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+  dnl
+  dnl Simply set some default values (i.e off) if boolean options were not
+  dnl specified:
+  _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+  ])
+  _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+  ])
+  dnl
+  dnl If no reference was made to various pairs of opposing options, then
+  dnl we run the default mode handler for the pair.  For example, if neither
+  dnl `shared' nor `disable-shared' was passed, we enable building of shared
+  dnl archives by default:
+  _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+  _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+  		   [_LT_ENABLE_FAST_INSTALL])
+  ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS],      [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+    [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+	[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+    _LT_DECL([build_libtool_libs], [enable_shared], [0],
+	[Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+    [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+	[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+    _LT_DECL([build_old_libs], [enable_static], [0],
+	[Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+    [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+    [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+	 [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+    [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+	[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+	IFS="$lt_save_ifs"
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+		 [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+		 [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+		 [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+		 [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+		 [m4_define([_LTDL_TYPE], [convenience])])
diff --git a/ltsugar.m4 b/ltsugar.m4
new file mode 100644
index 0000000..9000a05
--- /dev/null
+++ b/ltsugar.m4
@@ -0,0 +1,123 @@
+# ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+       [$#], [2], [[$2]],
+       [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+       [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+       [$#], 1, [],
+       [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+	   m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn.  Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+       [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+	     [m4_foreach([_Lt_suffix],
+		]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+	[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+	  [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+		 [lt_append([$1], [$2], [$3])$4],
+		 [$5])],
+	  [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+	m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+    m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+	[$5],
+    [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+  [lt_join(m4_quote(m4_default([$4], [[, ]])),
+           lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+		      [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
diff --git a/ltversion.m4 b/ltversion.m4
new file mode 100644
index 0000000..07a8602
--- /dev/null
+++ b/ltversion.m4
@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers			-*- Autoconf -*-
+#
+#   Copyright (C) 2004 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# @configure_input@
+
+# serial 3337 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.2'
+macro_revision='1.3337'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
diff --git a/lt~obsolete.m4 b/lt~obsolete.m4
new file mode 100644
index 0000000..c573da9
--- /dev/null
+++ b/lt~obsolete.m4
@@ -0,0 +1,98 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
+#
+#   Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick.  It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else.  This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION],	[AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP],		[AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT],		[AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX],	[AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN],		[AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR],		[AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL],	[AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN],		[AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER],	[AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK],		[AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE],	[AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF],	[AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O],	[AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR],		[AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR],		[AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP],	[AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC],		[AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU],		[AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG],	[AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD],	[AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS],	[AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP],	[AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP],		[AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED],		[AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME],		[AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE],	[AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE],	[AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL],		[AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP],		[AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN],		[AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER],	[AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG],		[AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL],	[AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX],		[AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77],		[AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ],		[AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG],	[AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG],	[AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG],	[AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG],	[AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG],	[AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG],		[AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C],	[AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS],	[AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP],		[AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS],	[AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77],		[AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC],		[AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX],		[AC_DEFUN([_LT_PROG_CXX])])
diff --git a/po-Engine-IRC/LINGUAS b/po-Engine-IRC/LINGUAS
index c8280af..8c8da6a 100644
--- a/po-Engine-IRC/LINGUAS
+++ b/po-Engine-IRC/LINGUAS
@@ -8,4 +8,9 @@ es_AR
 fr
 it
 pt
+ru
 sv
+sk
+tr
+ur
+zh_CN
diff --git a/po-Engine-IRC/POTFILES.skip b/po-Engine-IRC/POTFILES.skip
index f3503ba..2b6775f 100644
--- a/po-Engine-IRC/POTFILES.skip
+++ b/po-Engine-IRC/POTFILES.skip
@@ -8,6 +8,8 @@ src/Engine-Twitter/
 src/Frontend/
 src/Frontend-GNOME/
 src/Frontend-GNOME-IRC/
+src/Frontend-STFL/
 src/Frontend-SWF/
 src/Frontend-WPF/
 src/Server/
+lib/
diff --git a/po-Engine-IRC/ca.po b/po-Engine-IRC/ca.po
index ea177de..b6649b7 100644
--- a/po-Engine-IRC/ca.po
+++ b/po-Engine-IRC/ca.po
@@ -1,230 +1,237 @@
+# 
 msgid ""
 msgstr ""
 "Project-Id-Version: Smuxi\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
 "PO-Revision-Date: \n"
 "Last-Translator: Siegfried-Angel Gevatter Pujals <rainct at ubuntu.com>\n"
 "Language-Team: Siegfried-Angel Gevatter Pujals <siegfried at gevatter.com>\n"
-"Language: \n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: \n"
 "Plural-Forms: nplurals=2; plural=n != 1\n"
 "X-Poedit-Language: Catalan\n"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:221
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1412
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:234
+#, csharp-format
+msgid "{0} invites you to {1}"
+msgstr "{0} us invita a {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:255
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1468
 msgid "away"
 msgstr "absent"
 
 #. TRANSLATOR: {0} is the amount of seconds
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:227
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:261
 #, csharp-format
 msgid "lag: {0} seconds"
 msgstr "retard: {0} segons"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:233
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:267
 msgid "not connected"
 msgstr "no esteu connectat"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:292
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:337
 #, csharp-format
 msgid "Connecting to {0} port {1}..."
 msgstr "S'està connectant a {0} al port {1}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:298
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:390
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:343
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:438
 #, csharp-format
 msgid "Connection to {0} established"
 msgstr "S'ha establert la connexió a {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:301
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:346
 msgid "Logging in..."
 msgstr "S'està iniciant sessió..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:321
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:369
 msgid "Connection failed!"
 msgstr "Ha fallat la connexió!"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:322
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:370
 msgid "Connection failed! Reason: "
 msgstr "Ha fallat la connexió! Motiu:"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:331
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:379
 msgid "Disconnecting..."
 msgstr "S'està desconnectant..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:334
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:382
 #, csharp-format
 msgid "Disconnecting from {0}..."
 msgstr "S'està desconnectant de {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:339
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:387
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "S'ha desconnectat de {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:342
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:390
 msgid "Connection closed"
 msgstr "S'ha tancat la connexió"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:347
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:404
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:452
 msgid "Not connected"
 msgstr "No esteu connectat"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:376
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:424
 msgid "Reconnecting..."
 msgstr "S'està tornant a connectar..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:384
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:432
 #, csharp-format
 msgid "Reconnecting to {0}..."
 msgstr "S'està tornant a connectar a {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:398
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:446
 msgid "Reconnect Error"
 msgstr "Error al tornar a connectar"
 
 #. TRANSLATOR: this line is used as label / category for a
 #. list of commands below
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:747
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:816
 msgid "IrcProtocolManager Commands"
 msgstr "Ordres del protocol IRC"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:816
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:887
 #, csharp-format
 msgid "Invalid port: {0}"
 msgstr "Port invàlid: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:944
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:997
 #, csharp-format
 msgid "Queuing joins: {0}"
-msgstr ""
+msgstr "S'està afegint les unions a la cua: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:958
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1011
 #, csharp-format
 msgid "Already joined to channel: {0}. Type /window {0} to switch to it."
 msgstr "Ja esteu a la sala {0}. Escriviu /window {0} per a canviar-hi."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:993
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1046
 #, csharp-format
 msgid "Active joins: {0} - Queued joins: {1}"
-msgstr ""
+msgstr "Unions actives: {0} - Unions a la cua: {1}"
 
 #. TRANSLATORS: final message will look like this:
 #. Joining: #chan1 - Remaining active joins: #chan2 / queued joins: #chan3
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1016
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1047
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1069
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1100
 #, csharp-format
 msgid "Joining: {0}"
-msgstr ""
+msgstr "Unint-se a: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1018
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1071
 msgid "Remaining"
-msgstr ""
+msgstr "En cua:"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1023
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1076
 #, csharp-format
 msgid "active joins: {0}"
-msgstr ""
+msgstr "unions actives: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1032
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1085
 #, csharp-format
 msgid "queued joins: {0}"
-msgstr ""
+msgstr "unions a la cua: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1399
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1455
 msgid "IRC Op"
 msgstr "Operador d'IRC"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1401
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1457
 msgid "Op"
 msgstr "Op"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1403
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1459
 msgid "Voice"
 msgstr "Dóna veu"
 
-#. For translators: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1455
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1519
 #, csharp-format
 msgid "Topic for {0}: {1}"
 msgstr "Títol de {0}: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1465
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1524
 #, csharp-format
 msgid "No topic set for {0}"
 msgstr "No hi ha cap títol a {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1559
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1604
 msgid "ban"
 msgstr "expulsa"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1569
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1614
 msgid "No bans in channel"
 msgstr "No hi ha bandejaments en aquesta sala"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1683
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1726
 #, csharp-format
 msgid "Inviting {0} to {1}"
 msgstr "S'està invitant {0} a {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1687
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1730
 #, csharp-format
 msgid "{0} is already on {1}"
 msgstr "{0} ja està a {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1715
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1755
 msgid "Users"
 msgstr "Usuaris"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1766
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1797
 #, csharp-format
 msgid "Total of {0} users [{1} ops, {2} voices, {3} normal]"
 msgstr "Total de {0} usuaris [{1} operadors, {2} amb veus, {3} normals]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1909
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1928
 msgid "Connection error! Reason: "
 msgstr "Error de connexió! Motiu:"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1919
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1938
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "No heu proporcionat preu paràmetres per a l'ordre {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1929
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1948
 msgid "Not connected to server"
 msgstr "No esteu connectat al servidor"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2306
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2156
 #, csharp-format
 msgid "{0}: No such nick/channel"
 msgstr "{0}: No existeix aquest usuari o aquesta sala"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2432
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2279
 #, csharp-format
 msgid "Increased send delay to {0}ms to avoid being flooded off the server again."
 msgstr "S'ha incrementat el retard de l'enviament a {0}ms per evitar ser expulsat un altre cop pel control d'inundacions del servidor."
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2448
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2293
 msgid "Nick"
 msgstr "El nom d'usuari"
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2459
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2303
 msgid "is already in use"
 msgstr "ja està en ús"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2489
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2329
 msgid "Cannot join to channel:"
 msgstr "No podeu unir-vos a la sala:"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2498
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2337
 msgid "You are banned"
 msgstr "Esteu bandejats"
 
@@ -232,83 +239,94 @@ msgstr "Esteu bandejats"
 #. {2}: CTCP command, {3}: own nickname, {4}: CTCP parameter
 #. example:
 #. meebey [meebey at example.com] requested CTCP VERSION from meebey:
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2608
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2413
 #, csharp-format
 msgid "{0} [{1}] requested CTCP {2} from {3}: {4}"
 msgstr "{0} [{1}] ha enviat una petició CTCP {2} a {3}: {4}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2633
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2438
 #, csharp-format
 msgid "CTCP PING reply from {0}: {1} seconds"
 msgstr "Resposta a CTCP PING de {0}: {1} segons"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2641
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2446
 #, csharp-format
 msgid "CTCP {0} reply from {1}: {2}"
 msgstr "Resposta a CTCP {0} de {1}: {2}"
 
-#. For translators: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2888
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2643
 #, csharp-format
 msgid "{0} [{1}] has joined {2}"
 msgstr "{0} [{1}] s'ha unit a {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3024
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2769
 #, csharp-format
-msgid "{0} [{1}] has left {2} [{3}]"
-msgstr "{0} [{1}] ha deixat {2} [{3}]"
+msgid "{0} [{1}] has left {2}"
+msgstr "{0} [{1}] ha deixat {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3043
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2794
 #, csharp-format
 msgid "You were kicked from {0} by {1} [{2}]"
 msgstr "Heu estat expulsat de {0} per {1} [{2}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3051
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2802
 #, csharp-format
 msgid "{0} was kicked from {1} by {2} [{3}]"
 msgstr "{0} ha estat expulsat de {1} per {2} [{3}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3069
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3115
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2819
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2852
 #, csharp-format
 msgid "You're now known as {0}"
 msgstr "El vostre sobrenom ha canviat a {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3143
+#. TRANSLATOR: do NOT change the position of {0} or {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2857
 #, csharp-format
 msgid "{0} is now known as {1}"
 msgstr "{0} s'ha canviat el sobrenom per {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3200
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2894
 #, csharp-format
 msgid "{0} changed the topic of {1} to: {2}"
 msgstr "{0} ha canviat el títol de {1} a: {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3285
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2970
 #, csharp-format
 msgid "Mode change [{0}] for user {1}"
 msgstr "S'ha canviat el mode [{0}] a l'usuari {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3302
+#. TRANSLATOR: do NOT change the position of {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2980
 #, csharp-format
 msgid "mode/{0} [{1}] by {2}"
 msgstr "mode/{0} [{1}] per {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3339
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3017
 #, csharp-format
-msgid "{0} [{1}] has quit [{2}]"
-msgstr "{0} [{1}] ha sortit [{2}]"
+msgid "{0} [{1}] has quit"
+msgstr "{0} [{1}] ha sortit"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3459
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3094
+#, csharp-format
+msgid "Connection to {0} port {1} has failed (attempt {2}), retrying in {3} seconds..."
+msgstr "La connexió a {0} utilitzant el port {1} ha fallat (intent {2}). Es tornarà a intentar en {3} segons..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3143
 #, csharp-format
 msgid "{0} is away: {1}"
 msgstr "{0} està absent: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3465
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3149
 msgid "You are no longer marked as being away"
 msgstr "Ja no esteu marcat com a absent"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3471
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3155
 msgid "You have been marked as being away"
 msgstr "Heu estat marcat com a absent"
-
diff --git a/po-Engine-IRC/da.po b/po-Engine-IRC/da.po
index 18ee350..afbdc00 100644
--- a/po-Engine-IRC/da.po
+++ b/po-Engine-IRC/da.po
@@ -1,211 +1,219 @@
-# Danish translation smuxi-engine-irc.
-# Copyright (C) 2010 Mirco Bauer <meebey at meebey.net> & nedenstående oversættere.
-# This file is distributed under the same license as the smuxi-engine-irc package.
-# Joe Hansen (joedalton2 at yahoo.dk), 2010.
-#
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
 msgid ""
 msgstr ""
-"Project-Id-Version: smuxi-engine-irc\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-21 00:46+0200\n"
-"PO-Revision-Date: 2010-07-22 12:42+0000\n"
-"Last-Translator: Joe Hansen <joedalton2 at yahoo.dk>\n"
-"Language-Team: Danish <debian-l10n-danish at lists.debian.org>\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:20+0100\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: Danish (http://www.transifex.net/projects/p/smuxi/team/da/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: da\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:221
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1416
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:245
+#, csharp-format
+msgid "{0} invites you to {1}"
+msgstr "{0} inviterer dig til {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:276
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1519
 msgid "away"
 msgstr "fraværende"
 
 #. TRANSLATOR: {0} is the amount of seconds
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:227
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:282
 #, csharp-format
 msgid "lag: {0} seconds"
 msgstr "lag: {0} sekunder"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:233
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:288
 msgid "not connected"
 msgstr "ikke forbundet"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:292
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:351
 #, csharp-format
 msgid "Connecting to {0} port {1}..."
 msgstr "Forbinder til {0} port {1}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:298
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:393
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:357
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:463
 #, csharp-format
 msgid "Connection to {0} established"
 msgstr "Forbindelse til {0} etableret"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:301
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:360
 msgid "Logging in..."
 msgstr "Logger ind..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:324
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:394
 msgid "Connection failed!"
 msgstr "Forbindelse mislykkedes!"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:325
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
 msgid "Connection failed! Reason: "
 msgstr "Forbindelse mislykkedes! Ã…rsag: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:334
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:404
 msgid "Disconnecting..."
 msgstr "Afbryder..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:337
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:407
 #, csharp-format
 msgid "Disconnecting from {0}..."
 msgstr "Afbryder fra {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:342
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:412
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Afbrudt fra {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:345
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:415
 msgid "Connection closed"
 msgstr "Forbindelse lukket"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:350
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:407
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:420
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:477
 msgid "Not connected"
 msgstr "Ikke forbundet"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:379
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:449
 msgid "Reconnecting..."
 msgstr "Genforbinder..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:387
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:457
 #, csharp-format
 msgid "Reconnecting to {0}..."
 msgstr "Genforbinder til {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:401
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:471
 msgid "Reconnect Error"
 msgstr "Genforbindingsfejl"
 
 #. TRANSLATOR: this line is used as label / category for a
 #. list of commands below
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:751
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:875
 msgid "IrcProtocolManager Commands"
 msgstr "Kommandoer for IrcProtocolManager"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:820
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:943
 #, csharp-format
 msgid "Invalid port: {0}"
 msgstr "Ugyldig port: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:948
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1047
 #, csharp-format
 msgid "Queuing joins: {0}"
 msgstr "Sætter join sammen: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:962
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1061
 #, csharp-format
 msgid "Already joined to channel: {0}. Type /window {0} to switch to it."
 msgstr "Allerede tilsluttet til kanal: {0}. Tast /window {0} for at skifte."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:997
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1096
 #, csharp-format
 msgid "Active joins: {0} - Queued joins: {1}"
 msgstr "Aktive join: {0} - Join i kø: {1}"
 
 #. TRANSLATORS: final message will look like this:
 #. Joining: #chan1 - Remaining active joins: #chan2 / queued joins: #chan3
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1020
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1051
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1119
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1150
 #, csharp-format
 msgid "Joining: {0}"
 msgstr "Joiner: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1022
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1121
 msgid "Remaining"
 msgstr "Tilbage"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1027
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1126
 #, csharp-format
 msgid "active joins: {0}"
 msgstr "aktive join: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1036
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1135
 #, csharp-format
 msgid "queued joins: {0}"
 msgstr "join i kø: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1403
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1506
 msgid "IRC Op"
 msgstr "IRC Op"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1405
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1508
 msgid "Op"
 msgstr "Op"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1407
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1510
 msgid "Voice"
 msgstr "Voice"
 
-#. For translators: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1469
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1570
 #, csharp-format
 msgid "Topic for {0}: {1}"
 msgstr "Emne for {0}: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1479
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1575
 #, csharp-format
 msgid "No topic set for {0}"
 msgstr "Intet emne angivet for {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1573
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1655
 msgid "ban"
 msgstr "giv karantæne"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1583
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1665
 msgid "No bans in channel"
 msgstr "Ingen karantæner i kanal"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1697
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1777
 #, csharp-format
 msgid "Inviting {0} to {1}"
 msgstr "Inviterer {0} til {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1701
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1781
 #, csharp-format
 msgid "{0} is already on {1}"
 msgstr "{0} er allerede på {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1729
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1806
 msgid "Users"
 msgstr "Brugere"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1780
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1848
 #, csharp-format
 msgid "Total of {0} users [{1} ops, {2} voices, {3} normal]"
 msgstr "I alt {0} brugere [{1} op'er, {2} voice'er, {3} normale]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1923
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1979
 msgid "Connection error! Reason: "
 msgstr "Forbindelsesfejl! Ã…rsag: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1933
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1989
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Ikke nok parametre for {0} kommando"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1943
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1999
 msgid "Not connected to server"
 msgstr "Ikke forbundet til server"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2320
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2261
 #, csharp-format
 msgid "{0}: No such nick/channel"
 msgstr "{0}: Intet sådan brugernavn/kanal"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2446
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2390
 #, csharp-format
 msgid ""
 "Increased send delay to {0}ms to avoid being flooded off the server again."
@@ -215,21 +223,21 @@ msgstr ""
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2462
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2404
 msgid "Nick"
 msgstr "Brugernavn"
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2473
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2414
 msgid "is already in use"
 msgstr "er allerede i brug"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2503
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2424
 msgid "Cannot join to channel:"
 msgstr "Kan ikke slutte til kanal:"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2512
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2432
 msgid "You are banned"
 msgstr "Du har karantæne"
 
@@ -237,85 +245,100 @@ msgstr "Du har karantæne"
 #. {2}: CTCP command, {3}: own nickname, {4}: CTCP parameter
 #. example:
 #. meebey [meebey at example.com] requested CTCP VERSION from meebey:
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2622
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2508
 #, csharp-format
 msgid "{0} [{1}] requested CTCP {2} from {3}: {4}"
 msgstr "{0} [{1}] anmod om CTCP {2} fra {3}: {4}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2647
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2533
 #, csharp-format
 msgid "CTCP PING reply from {0}: {1} seconds"
 msgstr "CTCP PING svar fra {0}: {1} sekunder"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2655
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2541
 #, csharp-format
 msgid "CTCP {0} reply from {1}: {2}"
 msgstr "CTCP {0} svar fra {1}: {2}"
 
-#. For translators: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2902
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2747
 #, csharp-format
 msgid "{0} [{1}] has joined {2}"
 msgstr "{0} [{1}] har sluttet sig til {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3038
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2873
 #, csharp-format
-msgid "{0} [{1}] has left {2} [{3}]"
-msgstr "{0} [{1}] har forladt {2} [{3}]"
+msgid "{0} [{1}] has left {2}"
+msgstr "{0} [{1}] har forladt {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3057
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2898
 #, csharp-format
 msgid "You were kicked from {0} by {1} [{2}]"
 msgstr "Du blev smidt ud fra {0} af {1} [{2}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3065
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2906
 #, csharp-format
 msgid "{0} was kicked from {1} by {2} [{3}]"
 msgstr "{0} blev smidt ud af {1} af {2} [{3}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3083
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3129
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2923
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2956
 #, csharp-format
 msgid "You're now known as {0}"
 msgstr "Du er nu kendt som {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3157
+#. TRANSLATOR: do NOT change the position of {0} or {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2961
 #, csharp-format
 msgid "{0} is now known as {1}"
 msgstr "{0} er nu kendt som {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3214
+#. TRANSLATOR: do NOT change the position of {0} and {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2998
 #, csharp-format
 msgid "{0} changed the topic of {1} to: {2}"
 msgstr "{0} ændrede emnet på {1} til: {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3299
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3075
 #, csharp-format
 msgid "Mode change [{0}] for user {1}"
 msgstr "Tilstandsændring [{0}] for bruger {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3316
+#. TRANSLATOR: do NOT change the position of {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3085
 #, csharp-format
 msgid "mode/{0} [{1}] by {2}"
 msgstr "tilstand/{0} [{1}] af {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3353
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3122
 #, csharp-format
-msgid "{0} [{1}] has quit [{2}]"
-msgstr "{0} [{1}] har forladt [{2}]"
+msgid "{0} [{1}] has quit"
+msgstr "{0} [{1}] er gået"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3473
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3199
+#, csharp-format
+msgid ""
+"Connection to {0} port {1} has failed (attempt {2}), retrying in {3} "
+"seconds..."
+msgstr ""
+"Forbindelse til {0} port {1} er mislykkedes (forsøg {2}), forsøger om {3} "
+"sekunder..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3248
 #, csharp-format
 msgid "{0} is away: {1}"
 msgstr "{0} er fraværende: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3479
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3254
 msgid "You are no longer marked as being away"
 msgstr "Du er ikke længere registreret som fraværende"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3485
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3260
 msgid "You have been marked as being away"
 msgstr "Du er registreret som fraværende"
 
-#~ msgid "Not connected!"
-#~ msgstr "Ikke forbundet!"
+
diff --git a/po-Engine-IRC/de.po b/po-Engine-IRC/de.po
index aec82e1..5d02bca 100644
--- a/po-Engine-IRC/de.po
+++ b/po-Engine-IRC/de.po
@@ -1,233 +1,245 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-# Mirco Bauer <meebey at meebey.net>, 2008.
-# Bianca Mix <heavydemon at freenet.de>, 2010
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
 # 
+# Translators:
 msgid ""
 msgstr ""
-"Project-Id-Version: 0.6.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-01-03 00:09+0100\n"
-"Last-Translator: Bianca Mix <heavydemon at freenet.de>\n"
-"Language-Team: German Localization <debian-l10n-german at lists.debian.org>\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:20+0100\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: German (http://www.transifex.net/projects/p/smuxi/team/de/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: de\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:221
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1412
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:245
+#, csharp-format
+msgid "{0} invites you to {1}"
+msgstr "{0} lädt Sie in {1} ein"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:276
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1519
 msgid "away"
 msgstr "abwesend"
 
 #. TRANSLATOR: {0} is the amount of seconds
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:227
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:282
 #, csharp-format
 msgid "lag: {0} seconds"
 msgstr "Verzögerung: {0} Sekunden"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:233
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:288
 msgid "not connected"
 msgstr "nicht verbunden"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:292
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:351
 #, csharp-format
 msgid "Connecting to {0} port {1}..."
 msgstr "Verbinde zu {0} Port {1}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:298
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:390
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:357
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:463
 #, csharp-format
 msgid "Connection to {0} established"
 msgstr "Verbindung zu {0} ist hergestellt"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:301
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:360
 msgid "Logging in..."
 msgstr "Anmelden..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:321
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:394
 msgid "Connection failed!"
 msgstr "Verbindung ist fehlgeschlagen!"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:322
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
 msgid "Connection failed! Reason: "
 msgstr "Verbindung ist fehlgeschlagen! Ursache: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:331
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:404
 msgid "Disconnecting..."
 msgstr "Trenne..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:334
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:407
 #, csharp-format
 msgid "Disconnecting from {0}..."
 msgstr "Trenne von {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:339
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:412
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Getrennt von {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:342
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:415
 msgid "Connection closed"
 msgstr "Verbindung wurde geschlossen"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:347
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:404
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:420
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:477
 msgid "Not connected"
 msgstr "Nicht verbunden"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:376
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:449
 msgid "Reconnecting..."
 msgstr "Verbinde erneut..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:384
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:457
 #, csharp-format
 msgid "Reconnecting to {0}..."
 msgstr "Verbinde erneut zu {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:398
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:471
 msgid "Reconnect Error"
 msgstr "Fehler beim Wiederverbinden"
 
 #. TRANSLATOR: this line is used as label / category for a
 #. list of commands below
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:747
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:875
 msgid "IrcProtocolManager Commands"
 msgstr "IrcProtocolManager Befehle"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:816
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:943
 #, csharp-format
 msgid "Invalid port: {0}"
 msgstr "Ungültiger Port: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:944
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1047
 #, csharp-format
 msgid "Queuing joins: {0}"
 msgstr "Verzögere Beitritte: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:958
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1061
 #, csharp-format
 msgid "Already joined to channel: {0}. Type /window {0} to switch to it."
-msgstr "Channel wurde bereits betreten: {0}. Tippen Sie /window {0} um dorthin zu wechseln."
+msgstr ""
+"Channel wurde bereits betreten: {0}. Tippen Sie /window {0} um dorthin zu "
+"wechseln."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:993
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1096
 #, csharp-format
 msgid "Active joins: {0} - Queued joins: {1}"
 msgstr "Aktive Beitritte: {0} - Wartende Beitritte: {1}"
 
 #. TRANSLATORS: final message will look like this:
 #. Joining: #chan1 - Remaining active joins: #chan2 / queued joins: #chan3
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1016
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1047
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1119
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1150
 #, csharp-format
 msgid "Joining: {0}"
 msgstr "Betrete: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1018
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1121
 msgid "Remaining"
 msgstr "Verbleibend"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1023
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1126
 #, csharp-format
 msgid "active joins: {0}"
 msgstr "Aktive Beitritte: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1032
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1135
 #, csharp-format
 msgid "queued joins: {0}"
 msgstr "Wartende Beitritte: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1399
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1506
 msgid "IRC Op"
 msgstr "IRC Op"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1401
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1508
 msgid "Op"
 msgstr "Op"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1403
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1510
 msgid "Voice"
 msgstr "Voice"
 
-#. For translators: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1455
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1570
 #, csharp-format
 msgid "Topic for {0}: {1}"
 msgstr "Thema für {0}: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1465
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1575
 #, csharp-format
 msgid "No topic set for {0}"
 msgstr "Kein Thema für {0} gesetzt"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1559
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1655
 msgid "ban"
 msgstr "Sperre"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1569
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1665
 msgid "No bans in channel"
 msgstr "Keine Sperren in diesem Channel"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1683
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1777
 #, csharp-format
 msgid "Inviting {0} to {1}"
 msgstr "Lade {0} in {1} ein"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1687
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1781
 #, csharp-format
 msgid "{0} is already on {1}"
 msgstr "{0} ist bereits in {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1715
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1806
 msgid "Users"
 msgstr "Benutzer"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1766
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1848
 #, csharp-format
 msgid "Total of {0} users [{1} ops, {2} voices, {3} normal]"
 msgstr "Insgesamt {0} Benutzer [{1} Ops, {2} Voices, {3} normal]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1909
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1979
 msgid "Connection error! Reason: "
 msgstr "Verbindungsfehler! Grund: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1919
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1989
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Nicht genügend Parameter für den Befehl: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1929
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1999
 msgid "Not connected to server"
 msgstr "Nicht mit Server verbunden"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2306
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2261
 #, csharp-format
 msgid "{0}: No such nick/channel"
 msgstr "{0}: Kein solcher Nick/Channel"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2432
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2390
 #, csharp-format
-msgid "Increased send delay to {0}ms to avoid being flooded off the server again."
-msgstr "Nachrichtenverzögerung auf {0}ms erhöht, um eine Überflutung des Servers zu verhindern."
+msgid ""
+"Increased send delay to {0}ms to avoid being flooded off the server again."
+msgstr ""
+"Nachrichtenverzögerung auf {0}ms erhöht, um eine Überflutung des Servers zu "
+"verhindern."
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2448
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2404
 msgid "Nick"
 msgstr "Nick"
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2459
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2414
 msgid "is already in use"
 msgstr "wird bereits verwendet"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2489
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2424
 msgid "Cannot join to channel:"
 msgstr "Konnte Channel nicht beitreten:"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2498
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2432
 msgid "You are banned"
 msgstr "Sie sind gesperrt"
 
@@ -235,91 +247,100 @@ msgstr "Sie sind gesperrt"
 #. {2}: CTCP command, {3}: own nickname, {4}: CTCP parameter
 #. example:
 #. meebey [meebey at example.com] requested CTCP VERSION from meebey:
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2608
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2508
 #, csharp-format
 msgid "{0} [{1}] requested CTCP {2} from {3}: {4}"
 msgstr "{0} [{1}] fragt CTCP {2} von {3} ab: {4}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2633
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2533
 #, csharp-format
 msgid "CTCP PING reply from {0}: {1} seconds"
 msgstr "CTCP PING Antwort von {0}: {1} Sekunden"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2641
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2541
 #, csharp-format
 msgid "CTCP {0} reply from {1}: {2}"
 msgstr "CTCP {0} Antwort von {1}: {2}"
 
-#. For translators: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2888
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2747
 #, csharp-format
 msgid "{0} [{1}] has joined {2}"
 msgstr "{0} [{1}] hat {2} betreten"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3024
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2873
 #, csharp-format
-msgid "{0} [{1}] has left {2} [{3}]"
-msgstr "{0} [{1}] hat {2} verlassen [{3}]"
+msgid "{0} [{1}] has left {2}"
+msgstr "{0} [{1}] hat {2} verlassen"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3043
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2898
 #, csharp-format
 msgid "You were kicked from {0} by {1} [{2}]"
 msgstr "Sie wurden von {1} aus {0} hinausgeworfen [{2}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3051
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2906
 #, csharp-format
 msgid "{0} was kicked from {1} by {2} [{3}]"
 msgstr "{0} wurde von {2} aus {1} hinausgeworfen [{3}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3069
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3115
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2923
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2956
 #, csharp-format
 msgid "You're now known as {0}"
 msgstr "Sie sind nun bekannt als: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3143
+#. TRANSLATOR: do NOT change the position of {0} or {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2961
 #, csharp-format
 msgid "{0} is now known as {1}"
 msgstr "{0} ist nun bekannt als: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3200
+#. TRANSLATOR: do NOT change the position of {0} and {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2998
 #, csharp-format
 msgid "{0} changed the topic of {1} to: {2}"
 msgstr "{0} hat das Thema von {1} auf {2} geändert"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3285
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3075
 #, csharp-format
 msgid "Mode change [{0}] for user {1}"
 msgstr "Mode für Benutzer {1} geändert [{0}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3302
+#. TRANSLATOR: do NOT change the position of {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3085
 #, csharp-format
 msgid "mode/{0} [{1}] by {2}"
 msgstr "mode/{0} [{1}] von {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3339
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3122
+#, csharp-format
+msgid "{0} [{1}] has quit"
+msgstr "{0} [{1}] hat beendet"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3199
 #, csharp-format
-msgid "{0} [{1}] has quit [{2}]"
-msgstr "{0} [{1}] hat uns verlassen [{2}]"
+msgid ""
+"Connection to {0} port {1} has failed (attempt {2}), retrying in {3} "
+"seconds..."
+msgstr ""
+"Die Verbindung {0} über Port {1} ist fehlgeschlagen (Versuch {2}), erneuter "
+"Versuch in {3} Sekunden"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3459
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3248
 #, csharp-format
 msgid "{0} is away: {1}"
 msgstr "{0} ist abwesend: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3465
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3254
 msgid "You are no longer marked as being away"
 msgstr "Sie sind nicht mehr als abwesend gekenntzeichet"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3471
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3260
 msgid "You have been marked as being away"
 msgstr "Sie sind als abwesend gekenntzeichnet"
 
-#~ msgid "Not connected!"
-#~ msgstr "Nicht verbunden!"
-
-#~ msgid "lag"
-#~ msgstr "Verzögerung"
 
-#~ msgid "You're now known as"
-#~ msgstr "Sie sind nun bekannt als"
diff --git a/po-Engine-IRC/es.po b/po-Engine-IRC/es.po
index 6c66d2b..0eb27e4 100644
--- a/po-Engine-IRC/es.po
+++ b/po-Engine-IRC/es.po
@@ -2,185 +2,237 @@
 # Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
 # This file is distributed under the same license as the Smuxi package.
 # Juan Miguel Carrero <streinleght at gmail.com>, 2008-2009.
-#
+# 
 msgid ""
 msgstr ""
 "Project-Id-Version: 0.6.2\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-01-09 21:43+0100\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
 "PO-Revision-Date: 2009-08-12 17:01+0100\n"
 "Last-Translator: Juan Miguel Carrero <streinleght at gmail.com>\n"
-"Language-Team: Spanish Spanish Localization <debian-l10n-spanish at lists."
-"debian.org>\n"
+"Language-Team: Spanish Spanish Localization <debian-l10n-spanish at lists.debian.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:212
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1270
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:234
+#, csharp-format
+msgid "{0} invites you to {1}"
+msgstr "{0} te ha invitado a {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:255
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1468
 msgid "away"
 msgstr "ausente"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:215
-msgid "not connected"
-msgstr "no conectado"
-
 #. TRANSLATOR: {0} is the amount of seconds
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:223
-#, fuzzy, csharp-format
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:261
+#, csharp-format
 msgid "lag: {0} seconds"
-msgstr "segundos"
+msgstr "lag: {0} segundos"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:267
+msgid "not connected"
+msgstr "no conectado"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:285
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:337
 #, csharp-format
 msgid "Connecting to {0} port {1}..."
 msgstr "Conectando a {0} puerto {1}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:291
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:343
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:438
 #, csharp-format
 msgid "Connection to {0} established"
 msgstr "Conexión a {0} establecida"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:294
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:346
 msgid "Logging in..."
 msgstr "Autenticando..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:316
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:369
 msgid "Connection failed!"
 msgstr "Conexión fallida!"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:317
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:370
 msgid "Connection failed! Reason: "
 msgstr "Conexión fallida! Razón: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:326
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:379
 msgid "Disconnecting..."
 msgstr "Desconectando..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:329
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:382
 #, csharp-format
 msgid "Disconnecting from {0}..."
 msgstr "Desconectando de {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:333
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:387
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Desconectado de {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:335
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:390
 msgid "Connection closed"
 msgstr "Conexion terminada"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:339
-msgid "Not connected!"
-msgstr "No conectado!"
-
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:341
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:452
 msgid "Not connected"
 msgstr "No conectado"
 
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:424
+msgid "Reconnecting..."
+msgstr "Reconectando..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:432
+#, csharp-format
+msgid "Reconnecting to {0}..."
+msgstr "Reconectando a {0}..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:446
+msgid "Reconnect Error"
+msgstr "Error de Reconexión"
+
 #. TRANSLATOR: this line is used as label / category for a
 #. list of commands below
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:717
-#, fuzzy
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:816
 msgid "IrcProtocolManager Commands"
-msgstr "[Comandos IrcProtocolManager]"
+msgstr "Comandos IrcProtocolManager"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:786
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:887
 #, csharp-format
 msgid "Invalid port: {0}"
 msgstr "Puerto no válido: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:911
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:997
+#, csharp-format
+msgid "Queuing joins: {0}"
+msgstr "Entradas listadas: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1011
 #, csharp-format
 msgid "Already joined to channel: {0}. Type /window {0} to switch to it."
 msgstr "Ya estás dentro del canal: {0}. Escribe /window {0} para cambiar a él."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1257
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1046
+#, csharp-format
+msgid "Active joins: {0} - Queued joins: {1}"
+msgstr "Entradas activas: {0} - Entradas enlistadas: {1}"
+
+#. TRANSLATORS: final message will look like this:
+#. Joining: #chan1 - Remaining active joins: #chan2 / queued joins: #chan3
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1069
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1100
+#, csharp-format
+msgid "Joining: {0}"
+msgstr "Entrando: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1071
+msgid "Remaining"
+msgstr "Restantes"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1076
+#, csharp-format
+msgid "active joins: {0}"
+msgstr "entradas activas: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1085
+#, csharp-format
+msgid "queued joins: {0}"
+msgstr "entradas enlistadas: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1455
 msgid "IRC Op"
 msgstr "IRC Op"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1259
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1457
 msgid "Op"
 msgstr "Op"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1261
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1459
 msgid "Voice"
 msgstr "Voz"
 
-#. For translators: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1313
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1519
 #, csharp-format
 msgid "Topic for {0}: {1}"
 msgstr "Topic para {0}: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1321
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1524
 #, csharp-format
 msgid "No topic set for {0}"
 msgstr "No hay topic fijado en {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1415
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1604
 msgid "ban"
 msgstr "ban"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1425
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1614
 msgid "No bans in channel"
 msgstr "No hay bans en el canal"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1534
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1726
 #, csharp-format
 msgid "Inviting {0} to {1}"
 msgstr "Invitando {0} a {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1538
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1730
 #, csharp-format
-msgid "{0} is already on channel"
-msgstr "{0} ya está en el canal"
+msgid "{0} is already on {1}"
+msgstr "{0} ya se encuentra en {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1566
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1755
 msgid "Users"
 msgstr "Usuarios"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1617
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1797
 #, csharp-format
 msgid "Total of {0} users [{1} ops, {2} voices, {3} normal]"
 msgstr "Total de {0} usuarios [{1} opers, {2} voz, {3} normal]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1757
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1928
 msgid "Connection error! Reason: "
 msgstr "Error de conexión! Razón: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1767
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1938
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Parámetros insuficientes para el comando {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1777
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1948
 msgid "Not connected to server"
 msgstr "No conectado al servidor"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2080
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2156
 #, csharp-format
 msgid "{0}: No such nick/channel"
 msgstr "{0}: No existe nick/canal"
 
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2279
+#, csharp-format
+msgid "Increased send delay to {0}ms to avoid being flooded off the server again."
+msgstr "El retraso para los envíos se ha aumentado {0}ms para evitar inundar el servidor nuevamente."
+
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2207
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2293
 msgid "Nick"
 msgstr "Nick"
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2218
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2303
 msgid "is already in use"
 msgstr "ya está en uso"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2248
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2329
 msgid "Cannot join to channel:"
 msgstr "No se puede entrar al canal"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2257
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2337
 msgid "You are banned"
 msgstr "Estás baneado"
 
@@ -188,85 +240,100 @@ msgstr "Estás baneado"
 #. {2}: CTCP command, {3}: own nickname, {4}: CTCP parameter
 #. example:
 #. meebey [meebey at example.com] requested CTCP VERSION from meebey:
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2335
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2413
 #, csharp-format
 msgid "{0} [{1}] requested CTCP {2} from {3}: {4}"
 msgstr "{0} [{1}] solicitó CTCP {2} de {3}: {4}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2360
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2438
 #, csharp-format
 msgid "CTCP PING reply from {0}: {1} seconds"
 msgstr "CTCP PING respuesta de {0}: {1} segundos"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2368
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2446
 #, csharp-format
 msgid "CTCP {0} reply from {1}: {2}"
 msgstr "CTCP {0} respuesta de  {1}: {2}"
 
-#. For translators: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2591
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2643
 #, csharp-format
 msgid "{0} [{1}] has joined {2}"
 msgstr "{0} [{1}] entró {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2732
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2769
 #, csharp-format
-msgid "{0} [{1}] has left {2} [{3}]"
-msgstr "{0} [{1}] se marchó {2} [{3}]"
+msgid "{0} [{1}] has left {2}"
+msgstr "{0} [{1}] ha dejado {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2751
-#, fuzzy, csharp-format
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2794
+#, csharp-format
 msgid "You were kicked from {0} by {1} [{2}]"
 msgstr "Has sido pateado de {0} por {1} [{2}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2759
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2802
 #, csharp-format
 msgid "{0} was kicked from {1} by {2} [{3}]"
 msgstr "{0} ha sido pateado de {1} by {2} [{3}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2777
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2823
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2819
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2852
 #, csharp-format
 msgid "You're now known as {0}"
 msgstr "Ahora eres conocido como {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2851
+#. TRANSLATOR: do NOT change the position of {0} or {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2857
 #, csharp-format
 msgid "{0} is now known as {1}"
 msgstr "{0} es ahora conocido como {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2902
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2894
 #, csharp-format
 msgid "{0} changed the topic of {1} to: {2}"
 msgstr "{0} cambió el topic de {1} a: {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2987
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2970
 #, csharp-format
 msgid "Mode change [{0}] for user {1}"
 msgstr "Modo cambiado [{0}] para el usuario {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3004
+#. TRANSLATOR: do NOT change the position of {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2980
 #, csharp-format
 msgid "mode/{0} [{1}] by {2}"
 msgstr "modo/{0} [{1}] por {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3041
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3017
 #, csharp-format
-msgid "{0} [{1}] has quit [{2}]"
-msgstr "{0} [{1}] ha cerrado [{2}]"
+msgid "{0} [{1}] has quit"
+msgstr "{0} [{1}] ha salido"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3149
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3094
+#, csharp-format
+msgid "Connection to {0} port {1} has failed (attempt {2}), retrying in {3} seconds..."
+msgstr "Conexión a {0} por el puerto {1} ha fallado (intento {2}), reintentando en {3} segundos..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3143
 #, csharp-format
 msgid "{0} is away: {1}"
 msgstr "{0} está ausente: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3155
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3149
 msgid "You are no longer marked as being away"
 msgstr "No estás más tiempo como ausente"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3161
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3155
 msgid "You have been marked as being away"
 msgstr "Estás ahora ausente"
 
+#~ msgid "Not connected!"
+#~ msgstr "No conectado!"
+
 #~ msgid "lag"
 #~ msgstr "lag"
diff --git a/po-Engine-IRC/fr.po b/po-Engine-IRC/fr.po
index e74db0d..3ed0e19 100644
--- a/po-Engine-IRC/fr.po
+++ b/po-Engine-IRC/fr.po
@@ -1,216 +1,222 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-# Clement BOURGEOIS <moonpyk at gmail.com>, 2008.
-#
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
 msgid ""
 msgstr ""
-"Project-Id-Version: Smuxi 0.6.2\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-15 22:18+0100\n"
-"Last-Translator: Clément Bourgeois <moonpyk at gmail.com>\n"
-"Language-Team: French Localization <debian-l10n-french at lists.debian.org>\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:20+0100\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: French (http://www.transifex.net/projects/p/smuxi/team/fr/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: French\n"
-"X-Poedit-Country: FRANCE\n"
+"Language: fr\n"
+"Plural-Forms: nplurals=2; plural=(n > 1)\n"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:221
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1412
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:245
+#, csharp-format
+msgid "{0} invites you to {1}"
+msgstr "{0} vous invite sur {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:276
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1519
 msgid "away"
 msgstr "parti"
 
 #. TRANSLATOR: {0} is the amount of seconds
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:227
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:282
 #, csharp-format
 msgid "lag: {0} seconds"
 msgstr "lag : {0} secondes"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:233
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:288
 msgid "not connected"
 msgstr "non connecté"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:292
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:351
 #, csharp-format
 msgid "Connecting to {0} port {1}..."
 msgstr "Connexion au serveur {0}, sur le port {1} en cours..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:298
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:390
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:357
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:463
 #, csharp-format
 msgid "Connection to {0} established"
 msgstr "Connexion au serveur {0} établie"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:301
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:360
 msgid "Logging in..."
 msgstr "Enregistrement en cours..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:321
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:394
 msgid "Connection failed!"
 msgstr "Connexion impossible !"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:322
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
 msgid "Connection failed! Reason: "
 msgstr "Connexion impossible ! Raison :"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:331
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:404
 msgid "Disconnecting..."
 msgstr "Déconnexion en cours..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:334
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:407
 #, csharp-format
 msgid "Disconnecting from {0}..."
 msgstr "Déconnexion de {0} en cours..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:339
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:412
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Déconnecté de {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:342
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:415
 msgid "Connection closed"
 msgstr "Connexion fermée"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:347
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:404
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:420
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:477
 msgid "Not connected"
 msgstr "Non connecté"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:376
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:449
 msgid "Reconnecting..."
 msgstr "Reconnexion en cours..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:384
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:457
 #, csharp-format
 msgid "Reconnecting to {0}..."
 msgstr "Reconnexion à {0} en cours..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:398
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:471
 msgid "Reconnect Error"
 msgstr "Erreur à la reconnexion"
 
 #. TRANSLATOR: this line is used as label / category for a
 #. list of commands below
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:747
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:875
 msgid "IrcProtocolManager Commands"
 msgstr "Commandes IrcProtocolManager"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:816
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:943
 #, csharp-format
 msgid "Invalid port: {0}"
 msgstr "Port invalide : {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:944
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1047
 #, csharp-format
 msgid "Queuing joins: {0}"
 msgstr "Mise des en attente des inscriptions en cours : {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:958
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1061
 #, csharp-format
 msgid "Already joined to channel: {0}. Type /window {0} to switch to it."
 msgstr ""
-"Vous êtes déjà sur le canal: {0}. Utilisez /window {0} pour passer sur celui-"
-"ci."
+"Vous êtes déjà sur le canal: {0}. Utilisez /window {0} pour passer sur "
+"celui-ci."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:993
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1096
 #, csharp-format
 msgid "Active joins: {0} - Queued joins: {1}"
 msgstr "Inscriptions en cours : {0} - Inscriptions en attente : {1}"
 
 #. TRANSLATORS: final message will look like this:
 #. Joining: #chan1 - Remaining active joins: #chan2 / queued joins: #chan3
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1016
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1047
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1119
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1150
 #, csharp-format
 msgid "Joining: {0}"
 msgstr "Raccordement : {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1018
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1121
 msgid "Remaining"
 msgstr "Restant"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1023
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1126
 #, csharp-format
 msgid "active joins: {0}"
 msgstr "raccordements actifs : {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1032
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1135
 #, csharp-format
 msgid "queued joins: {0}"
 msgstr "raccordements en attente : {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1399
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1506
 msgid "IRC Op"
 msgstr "Opérateur IRC"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1401
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1508
 msgid "Op"
 msgstr "Opérateur"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1403
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1510
 msgid "Voice"
 msgstr "Voicé"
 
-#. For translators: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1455
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1570
 #, csharp-format
 msgid "Topic for {0}: {1}"
 msgstr "Sujet de {0} : {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1465
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1575
 #, csharp-format
 msgid "No topic set for {0}"
 msgstr "Pas de sujet sélectionné pour {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1559
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1655
 msgid "ban"
 msgstr "ban"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1569
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1665
 msgid "No bans in channel"
 msgstr "Aucun utilisateur banni sur le canal"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1683
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1777
 #, csharp-format
 msgid "Inviting {0} to {1}"
 msgstr "Invitation de {0} par {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1687
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1781
 #, csharp-format
 msgid "{0} is already on {1}"
 msgstr "{0} est déjà sur {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1715
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1806
 msgid "Users"
 msgstr "Utilisateurs"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1766
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1848
 #, csharp-format
 msgid "Total of {0} users [{1} ops, {2} voices, {3} normal]"
 msgstr ""
 "Total de {0} utilisateurs, [{1} opérateur(s), {2} voicé(s), {3} normal(ux)]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1909
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1979
 msgid "Connection error! Reason: "
 msgstr "Erreur de connexion ! Raison :"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1919
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1989
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Pas assez de paramètres pour la commande {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1929
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1999
 msgid "Not connected to server"
 msgstr "Non connecté au serveur"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2306
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2261
 #, csharp-format
 msgid "{0}: No such nick/channel"
 msgstr "{0}: Impossible de trouver le surnom/canal"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2432
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2390
 #, csharp-format
 msgid ""
 "Increased send delay to {0}ms to avoid being flooded off the server again."
@@ -220,21 +226,21 @@ msgstr ""
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2448
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2404
 msgid "Nick"
 msgstr "Surnom"
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2459
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2414
 msgid "is already in use"
 msgstr "est déjà en cours d'utilisation"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2489
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2424
 msgid "Cannot join to channel:"
 msgstr "Impossible de rejoindre le canal :"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2498
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2432
 msgid "You are banned"
 msgstr "Vous êtes banni"
 
@@ -242,88 +248,100 @@ msgstr "Vous êtes banni"
 #. {2}: CTCP command, {3}: own nickname, {4}: CTCP parameter
 #. example:
 #. meebey [meebey at example.com] requested CTCP VERSION from meebey:
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2608
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2508
 #, csharp-format
 msgid "{0} [{1}] requested CTCP {2} from {3}: {4}"
 msgstr "{0} [{1}] a fait une requête CTCP {2} de {3}: {4}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2633
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2533
 #, csharp-format
 msgid "CTCP PING reply from {0}: {1} seconds"
 msgstr "Réponse CTCP PING de {0} : {1} secondes"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2641
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2541
 #, csharp-format
 msgid "CTCP {0} reply from {1}: {2}"
 msgstr "Réponse CTCP {0} de {1} : {2}"
 
-#. For translators: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2888
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2747
 #, csharp-format
 msgid "{0} [{1}] has joined {2}"
 msgstr "{0} [{1}] a rejoint {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3024
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2873
 #, csharp-format
-msgid "{0} [{1}] has left {2} [{3}]"
-msgstr "{0} [{1}] a quitté {2} [{3}]"
+msgid "{0} [{1}] has left {2}"
+msgstr "{0} [{1}] a quitté {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3043
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2898
 #, csharp-format
 msgid "You were kicked from {0} by {1} [{2}]"
 msgstr "Vous avez été kické du canal {0} par {1} [{2}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3051
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2906
 #, csharp-format
 msgid "{0} was kicked from {1} by {2} [{3}]"
 msgstr "{0} a été kické de {1} par {2} [{3}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3069
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3115
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2923
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2956
 #, csharp-format
 msgid "You're now known as {0}"
 msgstr "Vous êtes maintenant connu en tant que {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3143
+#. TRANSLATOR: do NOT change the position of {0} or {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2961
 #, csharp-format
 msgid "{0} is now known as {1}"
 msgstr "{0} est maintenant connu en tant que {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3200
+#. TRANSLATOR: do NOT change the position of {0} and {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2998
 #, csharp-format
 msgid "{0} changed the topic of {1} to: {2}"
 msgstr "{0} a changé le sujet de {1} en : {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3285
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3075
 #, csharp-format
 msgid "Mode change [{0}] for user {1}"
 msgstr "Changement de mode [{0}] pour l'utilisateur {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3302
+#. TRANSLATOR: do NOT change the position of {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3085
 #, csharp-format
 msgid "mode/{0} [{1}] by {2}"
 msgstr "mode/{0} [{1}] par {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3339
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3122
+#, csharp-format
+msgid "{0} [{1}] has quit"
+msgstr "{0} [{1}] a quitté"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3199
 #, csharp-format
-msgid "{0} [{1}] has quit [{2}]"
-msgstr "{0} [{1}] a quitté [{2}]"
+msgid ""
+"Connection to {0} port {1} has failed (attempt {2}), retrying in {3} "
+"seconds..."
+msgstr ""
+"La connexion vers {0}, port {1} a échoué (essai {2}), nouvel essai dans {3} "
+"secondes..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3459
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3248
 #, csharp-format
 msgid "{0} is away: {1}"
 msgstr "{0} est parti : {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3465
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3254
 msgid "You are no longer marked as being away"
 msgstr "Vous êtes marqué comme étant revenu"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3471
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3260
 msgid "You have been marked as being away"
 msgstr "Vous avez été marqué comme étant parti"
 
-#~ msgid "Not connected!"
-#~ msgstr "Non connecté !"
 
-#~ msgid "lag"
-#~ msgstr "latence"
diff --git a/po-Engine-IRC/it.po b/po-Engine-IRC/it.po
index 6799b77..153f694 100644
--- a/po-Engine-IRC/it.po
+++ b/po-Engine-IRC/it.po
@@ -1,15 +1,15 @@
 # Smuxi - IRC client for sophisticated users
 # Copyright (C) 2005-2010 Mirco Bauer <meebey at meebey.net>
 # This file is distributed under the same license as the Smuxi package.
-# David Paleino <d.paleino at gmail.com>, 2008.
 #
-# Vincenzo Campanella <vinz65 at gmail.com>, 2009-2010, 2010.
+# David Paleino <d.paleino at gmail.com>, 2008.
+# Vincenzo Campanella <vinz65 at gmail.com>, 2009, 2010.
 msgid ""
 msgstr ""
 "Project-Id-Version: smuxi-engine-irc\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-15 13:07+0200\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2010-09-11 09:37+0200\n"
 "Last-Translator: Vincenzo Campanella <vinz65 at gmail.com>\n"
 "Language-Team: Italian <tp at lists.linux.it>\n"
 "Language: it\n"
@@ -18,198 +18,204 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:221
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1412
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:234
+#, csharp-format
+msgid "{0} invites you to {1}"
+msgstr "{0} ti ha invitato in {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:255
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1468
 msgid "away"
 msgstr "assente"
 
 #. TRANSLATOR: {0} is the amount of seconds
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:227
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:261
 #, csharp-format
 msgid "lag: {0} seconds"
 msgstr "ritardo: {0} secondi"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:233
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:267
 msgid "not connected"
 msgstr "non connesso"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:292
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:337
 #, csharp-format
 msgid "Connecting to {0} port {1}..."
 msgstr "Connessione a {0} porta {1} in corso"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:298
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:390
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:343
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:438
 #, csharp-format
 msgid "Connection to {0} established"
 msgstr "Connessione a {0} stabilita"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:301
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:346
 msgid "Logging in..."
 msgstr "Accesso in corso"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:321
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:369
 msgid "Connection failed!"
 msgstr "Connessione non riuscita."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:322
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:370
 msgid "Connection failed! Reason: "
 msgstr "La connessione non è riuscita. Motivo: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:331
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:379
 msgid "Disconnecting..."
 msgstr "Disconnessione in corso"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:334
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:382
 #, csharp-format
 msgid "Disconnecting from {0}..."
 msgstr "Disconnessione da {0} in corso"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:339
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:387
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Disconnesso da {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:342
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:390
 msgid "Connection closed"
 msgstr "Connessione chiusa"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:347
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:404
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:452
 msgid "Not connected"
 msgstr "Non connesso"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:376
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:424
 msgid "Reconnecting..."
 msgstr "Riconnessione in corso"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:384
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:432
 #, csharp-format
 msgid "Reconnecting to {0}..."
 msgstr "Riconnessione a {0} in corso"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:398
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:446
 msgid "Reconnect Error"
 msgstr "Errore di riconnessione"
 
 #
 #. TRANSLATOR: this line is used as label / category for a
 #. list of commands below
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:747
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:816
 msgid "IrcProtocolManager Commands"
 msgstr "Comandi di IrcProtocolManager"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:816
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:887
 #, csharp-format
 msgid "Invalid port: {0}"
 msgstr "Porta non valida: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:944
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:997
 #, csharp-format
 msgid "Queuing joins: {0}"
 msgstr "Accodamento degli accessi a «{0}» in corso"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:958
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1011
 #, csharp-format
 msgid "Already joined to channel: {0}. Type /window {0} to switch to it."
 msgstr "Si è già nel canale: {0}. Digitare «/window» {0} per potervi accedere."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:993
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1046
 #, csharp-format
 msgid "Active joins: {0} - Queued joins: {1}"
 msgstr "Accessi attivi: «{0}» - Accessi accodati: «{1}»"
 
 #. TRANSLATORS: final message will look like this:
 #. Joining: #chan1 - Remaining active joins: #chan2 / queued joins: #chan3
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1016
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1047
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1069
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1100
 #, csharp-format
 msgid "Joining: {0}"
 msgstr "Accesso a «{0}» in corso"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1018
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1071
 msgid "Remaining"
 msgstr "Rimanente"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1023
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1076
 #, csharp-format
 msgid "active joins: {0}"
 msgstr "accessi attivi: «{0}»"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1032
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1085
 #, csharp-format
 msgid "queued joins: {0}"
 msgstr "accessi accodati: «{0}»"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1399
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1455
 msgid "IRC Op"
 msgstr "Operatore IRC"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1401
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1457
 msgid "Op"
 msgstr "Operatore"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1403
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1459
 msgid "Voice"
 msgstr "Dai la parola"
 
-#. For translators: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1455
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1519
 #, csharp-format
 msgid "Topic for {0}: {1}"
 msgstr "Argomento per {0}: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1465
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1524
 #, csharp-format
 msgid "No topic set for {0}"
 msgstr "Nessun argomento impostato per {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1559
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1604
 msgid "ban"
 msgstr "allontana (ban)"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1569
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1614
 msgid "No bans in channel"
 msgstr "Nessun allontanamento (ban) nel canale"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1683
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1726
 #, csharp-format
 msgid "Inviting {0} to {1}"
 msgstr "Invito di {0} su {1} in corso"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1687
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1730
 #, csharp-format
 msgid "{0} is already on {1}"
 msgstr "{0} è già nel canale {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1715
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1755
 msgid "Users"
 msgstr "Utenti"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1766
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1797
 #, csharp-format
 msgid "Total of {0} users [{1} ops, {2} voices, {3} normal]"
 msgstr "Totale di {0} utenti [{1} operatori, {2} voci, {3} normali]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1909
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1928
 msgid "Connection error! Reason: "
 msgstr "Errore di connessione. Motivo: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1919
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1938
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Non sono stati forniti abbastanza parametri per il comando {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1929
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1948
 msgid "Not connected to server"
 msgstr "Non connesso a un server"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2306
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2156
 #, csharp-format
 msgid "{0}: No such nick/channel"
 msgstr "{0}: soprannome o canale inesistente"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2432
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2279
 #, csharp-format
 msgid ""
 "Increased send delay to {0}ms to avoid being flooded off the server again."
@@ -219,21 +225,21 @@ msgstr ""
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2448
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2293
 msgid "Nick"
 msgstr "Soprannome"
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2459
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2303
 msgid "is already in use"
 msgstr "è già in uso"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2489
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2329
 msgid "Cannot join to channel:"
 msgstr "Impossibile accedere al canale:"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2498
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2337
 msgid "You are banned"
 msgstr "Sei stato allontanato"
 
@@ -241,83 +247,99 @@ msgstr "Sei stato allontanato"
 #. {2}: CTCP command, {3}: own nickname, {4}: CTCP parameter
 #. example:
 #. meebey [meebey at example.com] requested CTCP VERSION from meebey:
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2608
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2413
 #, csharp-format
 msgid "{0} [{1}] requested CTCP {2} from {3}: {4}"
 msgstr "{0} [{1}] ha richiesto CTCP {2} da {3}: {4}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2633
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2438
 #, csharp-format
 msgid "CTCP PING reply from {0}: {1} seconds"
 msgstr "Risposta CTCP PING da {0}: {1} secondi"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2641
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2446
 #, csharp-format
 msgid "CTCP {0} reply from {1}: {2}"
 msgstr "Risposta CTCP {0} da {1}: {2}"
 
-#. For translators: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2888
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2643
 #, csharp-format
 msgid "{0} [{1}] has joined {2}"
 msgstr "{0} [{1}] è entrato in {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3024
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2769
 #, csharp-format
-msgid "{0} [{1}] has left {2} [{3}]"
-msgstr "{0} [{1}] ha lasciato {2} [{3}]"
+msgid "{0} [{1}] has left {2}"
+msgstr "{0} [{1}] ha lasciato {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3043
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2794
 #, csharp-format
 msgid "You were kicked from {0} by {1} [{2}]"
 msgstr "Sei stato espulso da {0} da {1} [{2}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3051
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2802
 #, csharp-format
 msgid "{0} was kicked from {1} by {2} [{3}]"
 msgstr "{0} è stato espulso da {1} da {2} [{3}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3069
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3115
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2819
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2852
 #, csharp-format
 msgid "You're now known as {0}"
 msgstr "Sei ora conosciuto come {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3143
+#. TRANSLATOR: do NOT change the position of {0} or {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2857
 #, csharp-format
 msgid "{0} is now known as {1}"
 msgstr "{0} è ora conosciuto come {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3200
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2894
 #, csharp-format
 msgid "{0} changed the topic of {1} to: {2}"
 msgstr "{0} ha cambiato l'argomento di {1} in: {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3285
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2970
 #, csharp-format
 msgid "Mode change [{0}] for user {1}"
 msgstr "Cambio modalità [{0}] per l'utente {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3302
+#. TRANSLATOR: do NOT change the position of {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2980
 #, csharp-format
 msgid "mode/{0} [{1}] by {2}"
 msgstr "mode/{0} [{1}] di {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3339
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3017
+#, csharp-format
+msgid "{0} [{1}] has quit"
+msgstr "{0} [{1}] si è disconnesso"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3094
 #, csharp-format
-msgid "{0} [{1}] has quit [{2}]"
-msgstr "{0} [{1}] si è disconnesso [{2}]"
+msgid ""
+"Connection to {0} port {1} has failed (attempt {2}), retrying in {3} "
+"seconds..."
+msgstr ""
+"La connessione a {0} porta {1} non è riuscita (tentativo {2}), nuovo "
+"tentativo fra {3} secondi"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3459
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3143
 #, csharp-format
 msgid "{0} is away: {1}"
 msgstr "{0} è assente: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3465
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3149
 msgid "You are no longer marked as being away"
 msgstr "Non sei più segnato come assente"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3471
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3155
 msgid "You have been marked as being away"
 msgstr "Sei stato segnato come assente"
 
diff --git a/po-Engine-IRC/pt.po b/po-Engine-IRC/pt.po
index d82541d..5d1c58a 100644
--- a/po-Engine-IRC/pt.po
+++ b/po-Engine-IRC/pt.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: smuxi-engine-irc \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-16 00:41+0100\n"
+"POT-Creation-Date: 2010-09-11 11:54+0200\n"
+"PO-Revision-Date: 2010-09-08 01:32+0100\n"
 "Last-Translator: Américo Monteiro <a_monteiro at netcabo.pt>\n"
 "Language-Team: Portuguese <traduz at debianpt.org>\n"
 "Language: pt\n"
@@ -18,221 +18,227 @@ msgstr ""
 "X-Generator: Lokalize 1.0\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:221
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1412
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:234
+#, csharp-format
+msgid "{0} invites you to {1}"
+msgstr "{0} convida-o para {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:255
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1468
 msgid "away"
 msgstr "longe"
 
 #. TRANSLATOR: {0} is the amount of seconds
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:227
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:261
 #, csharp-format
 msgid "lag: {0} seconds"
 msgstr "demora: {0} segundos"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:233
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:267
 msgid "not connected"
 msgstr "não ligado"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:292
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:337
 #, csharp-format
 msgid "Connecting to {0} port {1}..."
 msgstr "A ligar ao {0} porto {1}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:298
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:390
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:343
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:438
 #, csharp-format
 msgid "Connection to {0} established"
 msgstr "Ligação a {0} estabelecida"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:301
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:346
 msgid "Logging in..."
 msgstr "A efectuar o login..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:321
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:369
 msgid "Connection failed!"
 msgstr "Ligação falhada!"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:322
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:370
 msgid "Connection failed! Reason: "
 msgstr "Ligação falhada! Razão: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:331
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:379
 msgid "Disconnecting..."
 msgstr "A desligar..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:334
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:382
 #, csharp-format
 msgid "Disconnecting from {0}..."
 msgstr "A desligar de {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:339
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:387
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Desligado de {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:342
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:390
 msgid "Connection closed"
 msgstr "Ligação fechada"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:347
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:404
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:452
 msgid "Not connected"
 msgstr "Não ligado"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:376
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:424
 msgid "Reconnecting..."
 msgstr "A voltar a ligar..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:384
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:432
 #, csharp-format
 msgid "Reconnecting to {0}..."
 msgstr "A voltar a ligar a {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:398
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:446
 msgid "Reconnect Error"
 msgstr "Erro ao Re-ligar"
 
 #. TRANSLATOR: this line is used as label / category for a
 #. list of commands below
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:747
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:816
 msgid "IrcProtocolManager Commands"
 msgstr "Comandos do IrcProtocolManager"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:816
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:887
 #, csharp-format
 msgid "Invalid port: {0}"
 msgstr "Porto inválido: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:944
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:997
 #, csharp-format
 msgid "Queuing joins: {0}"
 msgstr "A colocar entradas em fila de espera: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:958
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1011
 #, csharp-format
 msgid "Already joined to channel: {0}. Type /window {0} to switch to it."
 msgstr "Já entrou no canal: {0}. Escreva /window {0} para mudar para lá."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:993
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1046
 #, csharp-format
 msgid "Active joins: {0} - Queued joins: {1}"
 msgstr "Entradas activas: {0} - Entradas em fila de espera: {1}"
 
 #. TRANSLATORS: final message will look like this:
 #. Joining: #chan1 - Remaining active joins: #chan2 / queued joins: #chan3
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1016
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1047
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1069
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1100
 #, csharp-format
 msgid "Joining: {0}"
 msgstr "A entrar em: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1018
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1071
 msgid "Remaining"
 msgstr "Restante"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1023
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1076
 #, csharp-format
 msgid "active joins: {0}"
 msgstr "entradas activas: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1032
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1085
 #, csharp-format
 msgid "queued joins: {0}"
 msgstr "entradas em fila de espera: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1399
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1455
 msgid "IRC Op"
 msgstr "Op de IRC"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1401
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1457
 msgid "Op"
 msgstr "Op"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1403
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1459
 msgid "Voice"
 msgstr "Voz"
 
-#. For translators: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1455
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1519
 #, csharp-format
 msgid "Topic for {0}: {1}"
 msgstr "Tópico para {0}: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1465
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1524
 #, csharp-format
 msgid "No topic set for {0}"
 msgstr "Nenhum tópico definido para {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1559
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1604
 msgid "ban"
 msgstr "banir"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1569
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1614
 msgid "No bans in channel"
 msgstr "Ninguém banido no canal"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1683
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1726
 #, csharp-format
 msgid "Inviting {0} to {1}"
 msgstr "A convidar {0} para {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1687
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1730
 #, csharp-format
 msgid "{0} is already on {1}"
 msgstr "{0} já está em {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1715
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1755
 msgid "Users"
 msgstr "Utilizadores"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1766
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1797
 #, csharp-format
 msgid "Total of {0} users [{1} ops, {2} voices, {3} normal]"
 msgstr "Total de {0} utilizadores [{1} ops, {2} vozes, {3} normal]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1909
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1928
 msgid "Connection error! Reason: "
 msgstr "Erro de ligação! Razão: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1919
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1938
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Parâmetros insuficientes para o comando {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1929
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1948
 msgid "Not connected to server"
 msgstr "Não ligado ao servidor"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2306
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2156
 #, csharp-format
 msgid "{0}: No such nick/channel"
 msgstr "{0}: Não existe tal alcunha/canal"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2432
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2279
 #, csharp-format
 msgid ""
 "Increased send delay to {0}ms to avoid being flooded off the server again."
 msgstr ""
-"Atraso de envio aumentado para {0}ms para evitar ser posto fora do "
-"servidor por flood outra vez."
+"Atraso de envio aumentado para {0}ms para evitar ser posto fora do servidor "
+"por flood outra vez."
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2448
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2293
 msgid "Nick"
 msgstr "Alcunha"
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2459
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2303
 msgid "is already in use"
 msgstr "já está em uso"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2489
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2329
 msgid "Cannot join to channel:"
 msgstr "Não pode entrar no canal:"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2498
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2337
 msgid "You are banned"
 msgstr "Você está banido"
 
@@ -240,83 +246,99 @@ msgstr "Você está banido"
 #. {2}: CTCP command, {3}: own nickname, {4}: CTCP parameter
 #. example:
 #. meebey [meebey at example.com] requested CTCP VERSION from meebey:
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2608
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2413
 #, csharp-format
 msgid "{0} [{1}] requested CTCP {2} from {3}: {4}"
 msgstr "{0} [{1}] pedido CTCP {2} de {3}: {4}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2633
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2438
 #, csharp-format
 msgid "CTCP PING reply from {0}: {1} seconds"
 msgstr "resposta CTCP PING de {0}: {1} segundos"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2641
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2446
 #, csharp-format
 msgid "CTCP {0} reply from {1}: {2}"
 msgstr "CTCP {0} resposta de {1}: {2}"
 
-#. For translators: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2888
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2643
 #, csharp-format
 msgid "{0} [{1}] has joined {2}"
 msgstr "{0} [{1}] entrou em {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3024
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2769
 #, csharp-format
-msgid "{0} [{1}] has left {2} [{3}]"
-msgstr "{0} [{1}] abandonou {2} [{3}]"
+msgid "{0} [{1}] has left {2}"
+msgstr "{0} [{1}] abandonou {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3043
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2794
 #, csharp-format
 msgid "You were kicked from {0} by {1} [{2}]"
 msgstr "Você foi expulso de {0} por {1} [{2}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3051
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2802
 #, csharp-format
 msgid "{0} was kicked from {1} by {2} [{3}]"
 msgstr "{0} foi expulso de {1} por {2} [{3}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3069
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3115
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2819
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2852
 #, csharp-format
 msgid "You're now known as {0}"
 msgstr "Você é agora conhecido como {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3143
+#. TRANSLATOR: do NOT change the position of {0} or {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2857
 #, csharp-format
 msgid "{0} is now known as {1}"
 msgstr "{0} é agora conhecido como {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3200
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2894
 #, csharp-format
 msgid "{0} changed the topic of {1} to: {2}"
 msgstr "{0} mudou o tópico de {1} para: {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3285
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2970
 #, csharp-format
 msgid "Mode change [{0}] for user {1}"
 msgstr "Alteração de modo [{0}] para o utilizador {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3302
+#. TRANSLATOR: do NOT change the position of {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2980
 #, csharp-format
 msgid "mode/{0} [{1}] by {2}"
 msgstr "modo/{0} [{1}] por {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3339
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3017
 #, csharp-format
-msgid "{0} [{1}] has quit [{2}]"
-msgstr "{0} [{1}] saiu [{2}]"
+msgid "{0} [{1}] has quit"
+msgstr "{0} [{1}] saiu"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3459
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3094
+#, csharp-format
+msgid ""
+"Connection to {0} port {1} has failed (attempt {2}), retrying in {3} "
+"seconds..."
+msgstr ""
+"A ligação para {0} no porto {1} falhou (tentativa {2}), a tentar de novo em "
+"{3} segundos..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3143
 #, csharp-format
 msgid "{0} is away: {1}"
 msgstr "{0} está longe: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3465
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3149
 msgid "You are no longer marked as being away"
 msgstr "Você não está mais marcado como estando longe"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3471
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3155
 msgid "You have been marked as being away"
 msgstr "Você foi marcado como estando longe"
 
diff --git a/po-Engine-IRC/ru.po b/po-Engine-IRC/ru.po
new file mode 100644
index 0000000..dd97f05
--- /dev/null
+++ b/po-Engine-IRC/ru.po
@@ -0,0 +1,330 @@
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: smuxi 0.8\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: \n"
+"Last-Translator: Urmas <davian818 at gmail.com>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=(n==1) ? 0 : (n%10==1 && n%100!=11 ? 3 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:234
+#, csharp-format
+msgid "{0} invites you to {1}"
+msgstr "{0} пригласил вас на {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:255
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1468
+msgid "away"
+msgstr ""
+
+#. TRANSLATOR: {0} is the amount of seconds
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:261
+#, csharp-format
+msgid "lag: {0} seconds"
+msgstr "задержка: {0} сек."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:267
+msgid "not connected"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:337
+#, csharp-format
+msgid "Connecting to {0} port {1}..."
+msgstr "Подключение к {0} на порт {1}..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:343
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:438
+#, csharp-format
+msgid "Connection to {0} established"
+msgstr "Подключение к {0} установлено."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:346
+msgid "Logging in..."
+msgstr "Вход на сервер..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:369
+msgid "Connection failed!"
+msgstr "Сбой подключения!"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:370
+msgid "Connection failed! Reason: "
+msgstr "Сбой подключения! Причина:"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:379
+msgid "Disconnecting..."
+msgstr "Отключение..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:382
+#, csharp-format
+msgid "Disconnecting from {0}..."
+msgstr "Отключение от {0}..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:387
+#, csharp-format
+msgid "Disconnected from {0}"
+msgstr "Отключен от {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:390
+msgid "Connection closed"
+msgstr "Соединение закрыто"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:452
+msgid "Not connected"
+msgstr "Нет соединения"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:424
+msgid "Reconnecting..."
+msgstr "Возобновление соединения..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:432
+#, csharp-format
+msgid "Reconnecting to {0}..."
+msgstr "Возобновление соединения с {0}..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:446
+msgid "Reconnect Error"
+msgstr ""
+
+#. TRANSLATOR: this line is used as label / category for a
+#. list of commands below
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:816
+msgid "IrcProtocolManager Commands"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:887
+#, csharp-format
+msgid "Invalid port: {0}"
+msgstr "Неверный порт: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:997
+#, csharp-format
+msgid "Queuing joins: {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1011
+#, csharp-format
+msgid "Already joined to channel: {0}. Type /window {0} to switch to it."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1046
+#, csharp-format
+msgid "Active joins: {0} - Queued joins: {1}"
+msgstr ""
+
+#. TRANSLATORS: final message will look like this:
+#. Joining: #chan1 - Remaining active joins: #chan2 / queued joins: #chan3
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1069
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1100
+#, csharp-format
+msgid "Joining: {0}"
+msgstr "Вход на канал: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1071
+msgid "Remaining"
+msgstr "Осталось"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1076
+#, csharp-format
+msgid "active joins: {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1085
+#, csharp-format
+msgid "queued joins: {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1455
+msgid "IRC Op"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1457
+msgid "Op"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1459
+msgid "Voice"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1519
+#, csharp-format
+msgid "Topic for {0}: {1}"
+msgstr "Тема канала {0}: {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1524
+#, csharp-format
+msgid "No topic set for {0}"
+msgstr "У канала {0} нет темы"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1604
+msgid "ban"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1614
+msgid "No bans in channel"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1726
+#, csharp-format
+msgid "Inviting {0} to {1}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1730
+#, csharp-format
+msgid "{0} is already on {1}"
+msgstr "{0} уже на {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1755
+msgid "Users"
+msgstr "Пользователи"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1797
+#, csharp-format
+msgid "Total of {0} users [{1} ops, {2} voices, {3} normal]"
+msgstr "Пользователей: {0} [операторов: {1}, разрешенных: {2}, обычных: {3}]"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1928
+msgid "Connection error! Reason: "
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1938
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1948
+msgid "Not connected to server"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2156
+#, csharp-format
+msgid "{0}: No such nick/channel"
+msgstr "{0}: Нет такого имени или канала"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2279
+#, csharp-format
+msgid "Increased send delay to {0}ms to avoid being flooded off the server again."
+msgstr ""
+
+#. TRANSLATOR: the final line will look like this:
+#. -!- Nick {0} is already in use
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2293
+msgid "Nick"
+msgstr "Имя"
+
+#. TRANSLATOR: the final line will look like this:
+#. -!- Nick {0} is already in use
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2303
+msgid "is already in use"
+msgstr "уже используется"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2329
+msgid "Cannot join to channel:"
+msgstr "Не удалось зайти на канал:"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2337
+msgid "You are banned"
+msgstr ""
+
+#. TRANSLATOR: {0}: nickname, {1}: ident at host,
+#. {2}: CTCP command, {3}: own nickname, {4}: CTCP parameter
+#. example:
+#. meebey [meebey at example.com] requested CTCP VERSION from meebey:
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2413
+#, csharp-format
+msgid "{0} [{1}] requested CTCP {2} from {3}: {4}"
+msgstr "{0} [{1}] запросил CTCP {2} у {3}: {4}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2438
+#, csharp-format
+msgid "CTCP PING reply from {0}: {1} seconds"
+msgstr "Ответ CTCP PING от {0}: {1} сек."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2446
+#, csharp-format
+msgid "CTCP {0} reply from {1}: {2}"
+msgstr "Ответ CTCP {0} от {1}: {2}"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2643
+#, csharp-format
+msgid "{0} [{1}] has joined {2}"
+msgstr "{0} [{1}] зашел на канал {2}"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2769
+#, csharp-format
+msgid "{0} [{1}] has left {2}"
+msgstr "{0} [{1}] вышел из канала {2}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2794
+#, csharp-format
+msgid "You were kicked from {0} by {1} [{2}]"
+msgstr "{1} выгнал вас из канала {0} [{2}]"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2802
+#, csharp-format
+msgid "{0} was kicked from {1} by {2} [{3}]"
+msgstr "{2} выгнал {0} из канала {1} [{3}]"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2819
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2852
+#, csharp-format
+msgid "You're now known as {0}"
+msgstr "Ваше имя теперь {0}"
+
+#. TRANSLATOR: do NOT change the position of {0} or {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2857
+#, csharp-format
+msgid "{0} is now known as {1}"
+msgstr "{0} сменил имя на {1}"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2894
+#, csharp-format
+msgid "{0} changed the topic of {1} to: {2}"
+msgstr "{0} изменил тему канала {1} на: {2}"
+
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2970
+#, csharp-format
+msgid "Mode change [{0}] for user {1}"
+msgstr "Изменен режим [{0}] для пользователя {1}"
+
+#. TRANSLATOR: do NOT change the position of {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2980
+#, csharp-format
+msgid "mode/{0} [{1}] by {2}"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3017
+#, csharp-format
+msgid "{0} [{1}] has quit"
+msgstr "{0} [{1}] покинул канал"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3094
+#, csharp-format
+msgid "Connection to {0} port {1} has failed (attempt {2}), retrying in {3} seconds..."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3143
+#, csharp-format
+msgid "{0} is away: {1}"
+msgstr "{0} отошел: {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3149
+msgid "You are no longer marked as being away"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3155
+msgid "You have been marked as being away"
+msgstr ""
diff --git a/po-Engine-IRC/sk.po b/po-Engine-IRC/sk.po
new file mode 100644
index 0000000..1dcfd69
--- /dev/null
+++ b/po-Engine-IRC/sk.po
@@ -0,0 +1,347 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Tomáš Vadina <kyberdev at gmail.com>, 2011.
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2011-09-30 08:38+0000\n"
+"Last-Translator: Tomáš Vadina <kyberdev at gmail.com>\n"
+"Language-Team: Slovak (http://www.transifex.net/projects/p/smuxi/team/sk/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: sk\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:234
+#, csharp-format
+msgid "{0} invites you to {1}"
+msgstr "{0} vás pozýva na {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:255
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1468
+msgid "away"
+msgstr "preč"
+
+#. TRANSLATOR: {0} is the amount of seconds
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:261
+#, csharp-format
+msgid "lag: {0} seconds"
+msgstr "oneskorenie: {0} sekúnd"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:267
+msgid "not connected"
+msgstr "nepripojené"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:337
+#, csharp-format
+msgid "Connecting to {0} port {1}..."
+msgstr "Pripája sa k {0} port {1}..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:343
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:438
+#, csharp-format
+msgid "Connection to {0} established"
+msgstr "Pripojenie k {0} nadviazané"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:346
+msgid "Logging in..."
+msgstr "Prihlasovanie..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:369
+msgid "Connection failed!"
+msgstr "Pripojenie zlyhalo!"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:370
+msgid "Connection failed! Reason: "
+msgstr "Pripojenie zlyhalo! Príčina: "
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:379
+msgid "Disconnecting..."
+msgstr "Odpájanie..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:382
+#, csharp-format
+msgid "Disconnecting from {0}..."
+msgstr "Odpájanie od {0}..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:387
+#, csharp-format
+msgid "Disconnected from {0}"
+msgstr "Odpojené od {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:390
+msgid "Connection closed"
+msgstr "Pripojenie zatvorené"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:452
+msgid "Not connected"
+msgstr "Nepripojené"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:424
+msgid "Reconnecting..."
+msgstr "Opätovné pripájanie..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:432
+#, csharp-format
+msgid "Reconnecting to {0}..."
+msgstr "Opätovné pripájanie k {0}..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:446
+msgid "Reconnect Error"
+msgstr "Chyba pri opätovnom pripojovaní"
+
+#. TRANSLATOR: this line is used as label / category for a
+#. list of commands below
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:816
+msgid "IrcProtocolManager Commands"
+msgstr "Príkazy správcu protokolu Irc"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:887
+#, csharp-format
+msgid "Invalid port: {0}"
+msgstr "Neplatný port: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:997
+#, csharp-format
+msgid "Queuing joins: {0}"
+msgstr "Zaraďovanie pripojenia do frontu: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1011
+#, csharp-format
+msgid "Already joined to channel: {0}. Type /window {0} to switch to it."
+msgstr ""
+"Už ste pripojení na kanál: {0}. Pre prepnutie na tento kanál zadajte "
+"/window."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1046
+#, csharp-format
+msgid "Active joins: {0} - Queued joins: {1}"
+msgstr "Aktívne pripojenia: {0} - Front s pripojeniami: {1}"
+
+#. TRANSLATORS: final message will look like this:
+#. Joining: #chan1 - Remaining active joins: #chan2 / queued joins: #chan3
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1069
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1100
+#, csharp-format
+msgid "Joining: {0}"
+msgstr "Pripájanie: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1071
+msgid "Remaining"
+msgstr "Ostávajúci"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1076
+#, csharp-format
+msgid "active joins: {0}"
+msgstr "aktívne pripojenia: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1085
+#, csharp-format
+msgid "queued joins: {0}"
+msgstr "front s pripojeniami: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1455
+msgid "IRC Op"
+msgstr "IRC Op"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1457
+msgid "Op"
+msgstr "Op"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1459
+msgid "Voice"
+msgstr "Hlas"
+
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1519
+#, csharp-format
+msgid "Topic for {0}: {1}"
+msgstr "Téma pre {0}: {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1524
+#, csharp-format
+msgid "No topic set for {0}"
+msgstr "{0} nemá nastavenú tému"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1604
+msgid "ban"
+msgstr "zákaz"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1614
+msgid "No bans in channel"
+msgstr "V kanále nie sú žiadne zákazy"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1726
+#, csharp-format
+msgid "Inviting {0} to {1}"
+msgstr "Pozvanie {0} do {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1730
+#, csharp-format
+msgid "{0} is already on {1}"
+msgstr "{0} je už na {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1755
+msgid "Users"
+msgstr "Používatelia"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1797
+#, csharp-format
+msgid "Total of {0} users [{1} ops, {2} voices, {3} normal]"
+msgstr "Celkom {0} používateľov [{1} opov, {2} hlasových, {3} normálnych]"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1928
+msgid "Connection error! Reason: "
+msgstr "Chyba spojenia! Príčina: "
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1938
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr "Pre príkaz {0} nie je vložený dostatok parametrov"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1948
+msgid "Not connected to server"
+msgstr "Nie je pripojené k serveru"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2156
+#, csharp-format
+msgid "{0}: No such nick/channel"
+msgstr "{0}: Neplatná prezývka/kanál"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2279
+#, csharp-format
+msgid ""
+"Increased send delay to {0}ms to avoid being flooded off the server again."
+msgstr ""
+"Aby opäť nedošlo k zahlteniu servera, bolo zvýšené oneskorenie odoslania na "
+"{0} ms."
+
+#. TRANSLATOR: the final line will look like this:
+#. -!- Nick {0} is already in use
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2293
+msgid "Nick"
+msgstr "Prezývka"
+
+#. TRANSLATOR: the final line will look like this:
+#. -!- Nick {0} is already in use
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2303
+msgid "is already in use"
+msgstr "sa už používa"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2329
+msgid "Cannot join to channel:"
+msgstr "Nie je možné pripojiť na kanál:"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2337
+msgid "You are banned"
+msgstr "Dostali ste zákaz"
+
+#. TRANSLATOR: {0}: nickname, {1}: ident at host,
+#. {2}: CTCP command, {3}: own nickname, {4}: CTCP parameter
+#. example:
+#. meebey [meebey at example.com] requested CTCP VERSION from meebey:
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2413
+#, csharp-format
+msgid "{0} [{1}] requested CTCP {2} from {3}: {4}"
+msgstr "{0} [{1}] požiadal o CTCP {2} od {3}: {4}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2438
+#, csharp-format
+msgid "CTCP PING reply from {0}: {1} seconds"
+msgstr "odpoveď CTCP PING od {0}: {1} sekúnd"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2446
+#, csharp-format
+msgid "CTCP {0} reply from {1}: {2}"
+msgstr "CTCP {0} odpoveď od {1}: {2}"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2643
+#, csharp-format
+msgid "{0} [{1}] has joined {2}"
+msgstr "{0} [{1}] sa pripojil {2}"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2769
+#, csharp-format
+msgid "{0} [{1}] has left {2}"
+msgstr "{0} [{1}] opustil {2}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2794
+#, csharp-format
+msgid "You were kicked from {0} by {1} [{2}]"
+msgstr "Boli ste vykopnutí z {0} používateľom {1} [{2}]"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2802
+#, csharp-format
+msgid "{0} was kicked from {1} by {2} [{3}]"
+msgstr "{0} bol vykopnutí z {1} používateľom {2} [{3}]"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2819
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2852
+#, csharp-format
+msgid "You're now known as {0}"
+msgstr "Teraz ste známi ako {0}"
+
+#. TRANSLATOR: do NOT change the position of {0} or {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2857
+#, csharp-format
+msgid "{0} is now known as {1}"
+msgstr "{0} je teraz známy ako {1}"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2894
+#, csharp-format
+msgid "{0} changed the topic of {1} to: {2}"
+msgstr "{0} zmenil tému {1} na: {2}"
+
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2970
+#, csharp-format
+msgid "Mode change [{0}] for user {1}"
+msgstr "Zmena režimu [{0}] používateľa {1}"
+
+#. TRANSLATOR: do NOT change the position of {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2980
+#, csharp-format
+msgid "mode/{0} [{1}] by {2}"
+msgstr "režim/{0} [{1}] od {2}"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3017
+#, csharp-format
+msgid "{0} [{1}] has quit"
+msgstr "{0} [{1}] ukončil"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3094
+#, csharp-format
+msgid ""
+"Connection to {0} port {1} has failed (attempt {2}), retrying in {3} "
+"seconds..."
+msgstr ""
+"Pripojenie k {0} port {1} zlyhalo (pokus č. {2}), opakovanie za {3} "
+"sekúnd..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3143
+#, csharp-format
+msgid "{0} is away: {1}"
+msgstr "{0} je preč: {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3149
+msgid "You are no longer marked as being away"
+msgstr "Nebudete viac označovaní, že ste preč"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3155
+msgid "You have been marked as being away"
+msgstr "Boli ste označení, že ste preč"
+
+
diff --git a/po-Engine-IRC/sv.po b/po-Engine-IRC/sv.po
index 16ebe99..02b0eff 100644
--- a/po-Engine-IRC/sv.po
+++ b/po-Engine-IRC/sv.po
@@ -1,235 +1,246 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-#
-# Martin Bagge <brother at bsnet.se>, 2009
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+#   <flugsio at gmail.com>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: Smuxi Engine IRC\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-15 13:12+0100\n"
-"Last-Translator: Martin Bagge / brother <brother at bsnet.se>\n"
-"Language-Team: Swedish <tp-sv at listor.tp-sv.se>\n"
-"Language: sv\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:20+0100\n"
+"PO-Revision-Date: 2011-12-31 10:37+0000\n"
+"Last-Translator: flugsio <flugsio at gmail.com>\n"
+"Language-Team: Swedish (http://www.transifex.net/projects/p/smuxi/team/sv/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: Swedish\n"
-"X-Poedit-Country: Sweden\n"
+"Language: sv\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:221
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1412
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:245
+#, csharp-format
+msgid "{0} invites you to {1}"
+msgstr "{0} bjuder in dig till {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:276
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1519
 msgid "away"
 msgstr "borta"
 
 #. TRANSLATOR: {0} is the amount of seconds
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:227
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:282
 #, csharp-format
 msgid "lag: {0} seconds"
 msgstr "lagg: {0} sekunder"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:233
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:288
 msgid "not connected"
 msgstr "inte ansluten"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:292
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:351
 #, csharp-format
 msgid "Connecting to {0} port {1}..."
 msgstr "Anluter till {0} port {1}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:298
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:390
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:357
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:463
 #, csharp-format
 msgid "Connection to {0} established"
 msgstr "Anslutning till {0} upprättad"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:301
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:360
 msgid "Logging in..."
 msgstr "Logga in..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:321
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:394
 msgid "Connection failed!"
 msgstr "Anslutning misslyckades!"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:322
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
 msgid "Connection failed! Reason: "
 msgstr "Anslutning misslyckades! Anledning: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:331
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:404
 msgid "Disconnecting..."
 msgstr "Kopplar från..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:334
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:407
 #, csharp-format
 msgid "Disconnecting from {0}..."
 msgstr "Kopplar från {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:339
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:412
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Anslutning bortkopplad från {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:342
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:415
 msgid "Connection closed"
 msgstr "Anslutning stängd"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:347
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:404
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:420
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:477
 msgid "Not connected"
 msgstr "Inte ansluten"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:376
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:449
 msgid "Reconnecting..."
 msgstr "Ã…teransluter..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:384
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:457
 #, csharp-format
 msgid "Reconnecting to {0}..."
 msgstr "Ã…teransluter till {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:398
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:471
 msgid "Reconnect Error"
 msgstr "Ã…teranslutningsfel"
 
 #. TRANSLATOR: this line is used as label / category for a
 #. list of commands below
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:747
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:875
 msgid "IrcProtocolManager Commands"
 msgstr "Kommandon för IRC-protokollhanterare"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:816
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:943
 #, csharp-format
 msgid "Invalid port: {0}"
 msgstr "Felaktig port: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:944
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1047
 #, csharp-format
 msgid "Queuing joins: {0}"
 msgstr "Köar kanalanslutningar: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:958
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1061
 #, csharp-format
 msgid "Already joined to channel: {0}. Type /window {0} to switch to it."
-msgstr "Redan ansluten till kanal {0}. Ange kommandot /window {0} för att byta till den."
+msgstr ""
+"Redan ansluten till kanal {0}. Ange kommandot /window {0} för att byta till "
+"den."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:993
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1096
 #, csharp-format
 msgid "Active joins: {0} - Queued joins: {1}"
 msgstr "Aktiva kanalanslutningar: {0} - Köade kanalanslutningar: {1}"
 
 #. TRANSLATORS: final message will look like this:
 #. Joining: #chan1 - Remaining active joins: #chan2 / queued joins: #chan3
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1016
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1047
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1119
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1150
 #, csharp-format
 msgid "Joining: {0}"
 msgstr "Ansluter till kanal: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1018
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1121
 msgid "Remaining"
 msgstr "Återstår"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1023
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1126
 #, csharp-format
 msgid "active joins: {0}"
 msgstr "aktiva kanalanslutningar: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1032
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1135
 #, csharp-format
 msgid "queued joins: {0}"
 msgstr "köade kanalanslutningar: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1399
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1506
 msgid "IRC Op"
 msgstr "IRC Operatör"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1401
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1508
 msgid "Op"
 msgstr "Operatör"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1403
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1510
 msgid "Voice"
 msgstr "Voice"
 
-#. For translators: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1455
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1570
 #, csharp-format
 msgid "Topic for {0}: {1}"
 msgstr "Rubrik för {0}: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1465
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1575
 #, csharp-format
 msgid "No topic set for {0}"
 msgstr "Ingen rubrik satt för {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1559
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1655
 msgid "ban"
 msgstr "utestäng"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1569
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1665
 msgid "No bans in channel"
 msgstr "Ingen är utestängd ur kanalen"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1683
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1777
 #, csharp-format
 msgid "Inviting {0} to {1}"
 msgstr "Bjuder in {0} till {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1687
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1781
 #, csharp-format
 msgid "{0} is already on {1}"
 msgstr "{0} är redan på {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1715
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1806
 msgid "Users"
 msgstr "Användare"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1766
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1848
 #, csharp-format
 msgid "Total of {0} users [{1} ops, {2} voices, {3} normal]"
 msgstr "Totalt {0} användare [{1} operatörer, {2} voice, {3} vanliga]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1909
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1979
 msgid "Connection error! Reason: "
 msgstr "Fel i anslutning! Anledning: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1919
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1989
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Inte tillräckligt med parametrar för kommandot {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1929
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1999
 msgid "Not connected to server"
 msgstr "Inte ansluten till server"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2306
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2261
 #, csharp-format
 msgid "{0}: No such nick/channel"
 msgstr "{0}: Smeknamnet/kanalen finns inte"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2432
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2390
 #, csharp-format
-msgid "Increased send delay to {0}ms to avoid being flooded off the server again."
-msgstr "Ökar väntetid med {0}ms för att undvika att bli utkastad från servern på grund av för snabbt hanterade kommandon."
+msgid ""
+"Increased send delay to {0}ms to avoid being flooded off the server again."
+msgstr ""
+"Ökar väntetid med {0}ms för att undvika att bli utkastad från servern på "
+"grund av för snabbt hanterade kommandon."
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2448
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2404
 msgid "Nick"
 msgstr "Smeknamnet"
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2459
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2414
 msgid "is already in use"
 msgstr "används redan"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2489
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2424
 msgid "Cannot join to channel:"
 msgstr "Kan inte ansluta till kanalen:"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2498
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2432
 msgid "You are banned"
 msgstr "Du är utestängd"
 
@@ -237,86 +248,100 @@ msgstr "Du är utestängd"
 #. {2}: CTCP command, {3}: own nickname, {4}: CTCP parameter
 #. example:
 #. meebey [meebey at example.com] requested CTCP VERSION from meebey:
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2608
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2508
 #, csharp-format
 msgid "{0} [{1}] requested CTCP {2} from {3}: {4}"
 msgstr "{0} [{1}] begärde CTCP {2} från {3}: {4}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2633
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2533
 #, csharp-format
 msgid "CTCP PING reply from {0}: {1} seconds"
 msgstr "CTCP PING-svar från {0}: {1} sekunder"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2641
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2541
 #, csharp-format
 msgid "CTCP {0} reply from {1}: {2}"
 msgstr "CTCP {0}-svar från {1}: {2}"
 
-#. For translators: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2888
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2747
 #, csharp-format
 msgid "{0} [{1}] has joined {2}"
 msgstr "{0} [{1}] anslöt till {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3024
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2873
 #, csharp-format
-msgid "{0} [{1}] has left {2} [{3}]"
-msgstr "{0} [{1}] lämnade {2} [{3}]"
+msgid "{0} [{1}] has left {2}"
+msgstr "{0} [{1}] har lämnat {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3043
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2898
 #, csharp-format
 msgid "You were kicked from {0} by {1} [{2}]"
 msgstr "Du sparkades från {0} av {1} [{2}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3051
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2906
 #, csharp-format
 msgid "{0} was kicked from {1} by {2} [{3}]"
 msgstr "{0} sparkades från {1} av {2} [{3}]"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3069
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3115
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2923
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2956
 #, csharp-format
 msgid "You're now known as {0}"
 msgstr "Du kallas numera {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3143
+#. TRANSLATOR: do NOT change the position of {0} or {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2961
 #, csharp-format
 msgid "{0} is now known as {1}"
 msgstr "{0} kallas numera {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3200
+#. TRANSLATOR: do NOT change the position of {0} and {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2998
 #, csharp-format
 msgid "{0} changed the topic of {1} to: {2}"
 msgstr "{0} bytte rubrik för {1} till: {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3285
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3075
 #, csharp-format
 msgid "Mode change [{0}] for user {1}"
 msgstr "Ändrat användartillstånd [{0}] för användaren {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3302
+#. TRANSLATOR: do NOT change the position of {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3085
 #, csharp-format
 msgid "mode/{0} [{1}] by {2}"
 msgstr "användartillstånd/{0} [{1}] av {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3339
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3122
 #, csharp-format
-msgid "{0} [{1}] has quit [{2}]"
-msgstr "{0} [{1}] har lämnat [{2}]"
+msgid "{0} [{1}] has quit"
+msgstr "{0} [{1}] har avslutat"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3199
+#, csharp-format
+msgid ""
+"Connection to {0} port {1} has failed (attempt {2}), retrying in {3} "
+"seconds..."
+msgstr ""
+"Uppkoppling till {0}  på port {1} har misslyckats (försök {2}), prövar igen "
+"om {3} sekunder..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3459
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3248
 #, csharp-format
 msgid "{0} is away: {1}"
 msgstr "{0} är borta: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3465
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3254
 msgid "You are no longer marked as being away"
 msgstr "Du är inte längre markerad som borta"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3471
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3260
 msgid "You have been marked as being away"
 msgstr "Du har markerats tom borta"
 
-#~ msgid "Not connected!"
-#~ msgstr "Inte ansluten!"
 
diff --git a/po-Engine-IRC/tr.po b/po-Engine-IRC/tr.po
new file mode 100644
index 0000000..fde14ab
--- /dev/null
+++ b/po-Engine-IRC/tr.po
@@ -0,0 +1,340 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: Turkish (http://www.transifex.net/projects/p/smuxi/team/tr/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: tr\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:234
+#, csharp-format
+msgid "{0} invites you to {1}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:255
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1468
+msgid "away"
+msgstr ""
+
+#. TRANSLATOR: {0} is the amount of seconds
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:261
+#, csharp-format
+msgid "lag: {0} seconds"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:267
+msgid "not connected"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:337
+#, csharp-format
+msgid "Connecting to {0} port {1}..."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:343
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:438
+#, csharp-format
+msgid "Connection to {0} established"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:346
+msgid "Logging in..."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:369
+msgid "Connection failed!"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:370
+msgid "Connection failed! Reason: "
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:379
+msgid "Disconnecting..."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:382
+#, csharp-format
+msgid "Disconnecting from {0}..."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:387
+#, csharp-format
+msgid "Disconnected from {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:390
+msgid "Connection closed"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:452
+msgid "Not connected"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:424
+msgid "Reconnecting..."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:432
+#, csharp-format
+msgid "Reconnecting to {0}..."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:446
+msgid "Reconnect Error"
+msgstr ""
+
+#. TRANSLATOR: this line is used as label / category for a
+#. list of commands below
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:816
+msgid "IrcProtocolManager Commands"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:887
+#, csharp-format
+msgid "Invalid port: {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:997
+#, csharp-format
+msgid "Queuing joins: {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1011
+#, csharp-format
+msgid "Already joined to channel: {0}. Type /window {0} to switch to it."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1046
+#, csharp-format
+msgid "Active joins: {0} - Queued joins: {1}"
+msgstr ""
+
+#. TRANSLATORS: final message will look like this:
+#. Joining: #chan1 - Remaining active joins: #chan2 / queued joins: #chan3
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1069
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1100
+#, csharp-format
+msgid "Joining: {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1071
+msgid "Remaining"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1076
+#, csharp-format
+msgid "active joins: {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1085
+#, csharp-format
+msgid "queued joins: {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1455
+msgid "IRC Op"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1457
+msgid "Op"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1459
+msgid "Voice"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1519
+#, csharp-format
+msgid "Topic for {0}: {1}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1524
+#, csharp-format
+msgid "No topic set for {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1604
+msgid "ban"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1614
+msgid "No bans in channel"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1726
+#, csharp-format
+msgid "Inviting {0} to {1}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1730
+#, csharp-format
+msgid "{0} is already on {1}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1755
+msgid "Users"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1797
+#, csharp-format
+msgid "Total of {0} users [{1} ops, {2} voices, {3} normal]"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1928
+msgid "Connection error! Reason: "
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1938
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1948
+msgid "Not connected to server"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2156
+#, csharp-format
+msgid "{0}: No such nick/channel"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2279
+#, csharp-format
+msgid ""
+"Increased send delay to {0}ms to avoid being flooded off the server again."
+msgstr ""
+
+#. TRANSLATOR: the final line will look like this:
+#. -!- Nick {0} is already in use
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2293
+msgid "Nick"
+msgstr ""
+
+#. TRANSLATOR: the final line will look like this:
+#. -!- Nick {0} is already in use
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2303
+msgid "is already in use"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2329
+msgid "Cannot join to channel:"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2337
+msgid "You are banned"
+msgstr ""
+
+#. TRANSLATOR: {0}: nickname, {1}: ident at host,
+#. {2}: CTCP command, {3}: own nickname, {4}: CTCP parameter
+#. example:
+#. meebey [meebey at example.com] requested CTCP VERSION from meebey:
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2413
+#, csharp-format
+msgid "{0} [{1}] requested CTCP {2} from {3}: {4}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2438
+#, csharp-format
+msgid "CTCP PING reply from {0}: {1} seconds"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2446
+#, csharp-format
+msgid "CTCP {0} reply from {1}: {2}"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2643
+#, csharp-format
+msgid "{0} [{1}] has joined {2}"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2769
+#, csharp-format
+msgid "{0} [{1}] has left {2}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2794
+#, csharp-format
+msgid "You were kicked from {0} by {1} [{2}]"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2802
+#, csharp-format
+msgid "{0} was kicked from {1} by {2} [{3}]"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2819
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2852
+#, csharp-format
+msgid "You're now known as {0}"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {0} or {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2857
+#, csharp-format
+msgid "{0} is now known as {1}"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2894
+#, csharp-format
+msgid "{0} changed the topic of {1} to: {2}"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2970
+#, csharp-format
+msgid "Mode change [{0}] for user {1}"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2980
+#, csharp-format
+msgid "mode/{0} [{1}] by {2}"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3017
+#, csharp-format
+msgid "{0} [{1}] has quit"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3094
+#, csharp-format
+msgid ""
+"Connection to {0} port {1} has failed (attempt {2}), retrying in {3} "
+"seconds..."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3143
+#, csharp-format
+msgid "{0} is away: {1}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3149
+msgid "You are no longer marked as being away"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3155
+msgid "You have been marked as being away"
+msgstr ""
+
+
diff --git a/po-Engine-IRC/ur.po b/po-Engine-IRC/ur.po
new file mode 100644
index 0000000..c5ccc4d
--- /dev/null
+++ b/po-Engine-IRC/ur.po
@@ -0,0 +1,340 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: Urdu (http://www.transifex.net/projects/p/smuxi/team/ur/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ur\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:234
+#, csharp-format
+msgid "{0} invites you to {1}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:255
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1468
+msgid "away"
+msgstr ""
+
+#. TRANSLATOR: {0} is the amount of seconds
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:261
+#, csharp-format
+msgid "lag: {0} seconds"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:267
+msgid "not connected"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:337
+#, csharp-format
+msgid "Connecting to {0} port {1}..."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:343
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:438
+#, csharp-format
+msgid "Connection to {0} established"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:346
+msgid "Logging in..."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:369
+msgid "Connection failed!"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:370
+msgid "Connection failed! Reason: "
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:379
+msgid "Disconnecting..."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:382
+#, csharp-format
+msgid "Disconnecting from {0}..."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:387
+#, csharp-format
+msgid "Disconnected from {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:390
+msgid "Connection closed"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:452
+msgid "Not connected"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:424
+msgid "Reconnecting..."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:432
+#, csharp-format
+msgid "Reconnecting to {0}..."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:446
+msgid "Reconnect Error"
+msgstr ""
+
+#. TRANSLATOR: this line is used as label / category for a
+#. list of commands below
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:816
+msgid "IrcProtocolManager Commands"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:887
+#, csharp-format
+msgid "Invalid port: {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:997
+#, csharp-format
+msgid "Queuing joins: {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1011
+#, csharp-format
+msgid "Already joined to channel: {0}. Type /window {0} to switch to it."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1046
+#, csharp-format
+msgid "Active joins: {0} - Queued joins: {1}"
+msgstr ""
+
+#. TRANSLATORS: final message will look like this:
+#. Joining: #chan1 - Remaining active joins: #chan2 / queued joins: #chan3
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1069
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1100
+#, csharp-format
+msgid "Joining: {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1071
+msgid "Remaining"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1076
+#, csharp-format
+msgid "active joins: {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1085
+#, csharp-format
+msgid "queued joins: {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1455
+msgid "IRC Op"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1457
+msgid "Op"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1459
+msgid "Voice"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1519
+#, csharp-format
+msgid "Topic for {0}: {1}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1524
+#, csharp-format
+msgid "No topic set for {0}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1604
+msgid "ban"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1614
+msgid "No bans in channel"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1726
+#, csharp-format
+msgid "Inviting {0} to {1}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1730
+#, csharp-format
+msgid "{0} is already on {1}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1755
+msgid "Users"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1797
+#, csharp-format
+msgid "Total of {0} users [{1} ops, {2} voices, {3} normal]"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1928
+msgid "Connection error! Reason: "
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1938
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1948
+msgid "Not connected to server"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2156
+#, csharp-format
+msgid "{0}: No such nick/channel"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2279
+#, csharp-format
+msgid ""
+"Increased send delay to {0}ms to avoid being flooded off the server again."
+msgstr ""
+
+#. TRANSLATOR: the final line will look like this:
+#. -!- Nick {0} is already in use
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2293
+msgid "Nick"
+msgstr ""
+
+#. TRANSLATOR: the final line will look like this:
+#. -!- Nick {0} is already in use
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2303
+msgid "is already in use"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2329
+msgid "Cannot join to channel:"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2337
+msgid "You are banned"
+msgstr ""
+
+#. TRANSLATOR: {0}: nickname, {1}: ident at host,
+#. {2}: CTCP command, {3}: own nickname, {4}: CTCP parameter
+#. example:
+#. meebey [meebey at example.com] requested CTCP VERSION from meebey:
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2413
+#, csharp-format
+msgid "{0} [{1}] requested CTCP {2} from {3}: {4}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2438
+#, csharp-format
+msgid "CTCP PING reply from {0}: {1} seconds"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2446
+#, csharp-format
+msgid "CTCP {0} reply from {1}: {2}"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2643
+#, csharp-format
+msgid "{0} [{1}] has joined {2}"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2769
+#, csharp-format
+msgid "{0} [{1}] has left {2}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2794
+#, csharp-format
+msgid "You were kicked from {0} by {1} [{2}]"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2802
+#, csharp-format
+msgid "{0} was kicked from {1} by {2} [{3}]"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2819
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2852
+#, csharp-format
+msgid "You're now known as {0}"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {0} or {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2857
+#, csharp-format
+msgid "{0} is now known as {1}"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2894
+#, csharp-format
+msgid "{0} changed the topic of {1} to: {2}"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2970
+#, csharp-format
+msgid "Mode change [{0}] for user {1}"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2980
+#, csharp-format
+msgid "mode/{0} [{1}] by {2}"
+msgstr ""
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3017
+#, csharp-format
+msgid "{0} [{1}] has quit"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3094
+#, csharp-format
+msgid ""
+"Connection to {0} port {1} has failed (attempt {2}), retrying in {3} "
+"seconds..."
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3143
+#, csharp-format
+msgid "{0} is away: {1}"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3149
+msgid "You are no longer marked as being away"
+msgstr ""
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3155
+msgid "You have been marked as being away"
+msgstr ""
+
+
diff --git a/po-Engine-IRC/zh_CN.po b/po-Engine-IRC/zh_CN.po
new file mode 100644
index 0000000..3d77f3c
--- /dev/null
+++ b/po-Engine-IRC/zh_CN.po
@@ -0,0 +1,340 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:20+0100\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: Chinese (China) (http://www.transifex.net/projects/p/smuxi/team/zh_CN/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: zh_CN\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:245
+#, csharp-format
+msgid "{0} invites you to {1}"
+msgstr "{0} 邀请您加入 {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:276
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1519
+msgid "away"
+msgstr "离开"
+
+#. TRANSLATOR: {0} is the amount of seconds
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:282
+#, csharp-format
+msgid "lag: {0} seconds"
+msgstr "延后: {0} 秒"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:288
+msgid "not connected"
+msgstr "未连接"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:351
+#, csharp-format
+msgid "Connecting to {0} port {1}..."
+msgstr "正在连接到 {0} 端口 {1}..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:357
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:463
+#, csharp-format
+msgid "Connection to {0} established"
+msgstr "到 {0} 的连接已建立"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:360
+msgid "Logging in..."
+msgstr "正在登录..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:394
+msgid "Connection failed!"
+msgstr "连接失败!"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
+msgid "Connection failed! Reason: "
+msgstr "连接失败! 原因: "
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:404
+msgid "Disconnecting..."
+msgstr "正在断开连接..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:407
+#, csharp-format
+msgid "Disconnecting from {0}..."
+msgstr "正在从 {0} 断开连接..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:412
+#, csharp-format
+msgid "Disconnected from {0}"
+msgstr "已从 {0} 断开连接"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:415
+msgid "Connection closed"
+msgstr "连接已关闭"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:420
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:477
+msgid "Not connected"
+msgstr "未连接"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:449
+msgid "Reconnecting..."
+msgstr "正在重新连接..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:457
+#, csharp-format
+msgid "Reconnecting to {0}..."
+msgstr "正在重新连接到 {0}..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:471
+msgid "Reconnect Error"
+msgstr "重新连接出错"
+
+#. TRANSLATOR: this line is used as label / category for a
+#. list of commands below
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:875
+msgid "IrcProtocolManager Commands"
+msgstr "IrcProtocolManager 命令"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:943
+#, csharp-format
+msgid "Invalid port: {0}"
+msgstr "端口无效: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1047
+#, csharp-format
+msgid "Queuing joins: {0}"
+msgstr "正等待加入: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1061
+#, csharp-format
+msgid "Already joined to channel: {0}. Type /window {0} to switch to it."
+msgstr "已经加入了频道: {0}. 输入 /window {0} 切换过去。"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1096
+#, csharp-format
+msgid "Active joins: {0} - Queued joins: {1}"
+msgstr "已经加入: {0} - 等待加入: {1}"
+
+#. TRANSLATORS: final message will look like this:
+#. Joining: #chan1 - Remaining active joins: #chan2 / queued joins: #chan3
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1119
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1150
+#, csharp-format
+msgid "Joining: {0}"
+msgstr "正在加入: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1121
+msgid "Remaining"
+msgstr "剩余"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1126
+#, csharp-format
+msgid "active joins: {0}"
+msgstr "已经加入: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1135
+#, csharp-format
+msgid "queued joins: {0}"
+msgstr "等待加入: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1506
+msgid "IRC Op"
+msgstr "IRC 版主"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1508
+msgid "Op"
+msgstr "版主"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1510
+msgid "Voice"
+msgstr "认证用户"
+
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1570
+#, csharp-format
+msgid "Topic for {0}: {1}"
+msgstr "{0} 的主题: {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1575
+#, csharp-format
+msgid "No topic set for {0}"
+msgstr "{0} 尚未设定主题"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1655
+msgid "ban"
+msgstr "封禁"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1665
+msgid "No bans in channel"
+msgstr "频道内无被封禁用户"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1777
+#, csharp-format
+msgid "Inviting {0} to {1}"
+msgstr "正在邀请 {0} 加入 {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1781
+#, csharp-format
+msgid "{0} is already on {1}"
+msgstr "{0} 已在 {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1806
+msgid "Users"
+msgstr "用户"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1848
+#, csharp-format
+msgid "Total of {0} users [{1} ops, {2} voices, {3} normal]"
+msgstr "总计 {0} 位用户 [{1} 位版主, {2} 位认证用户, {3} 位普通用户]"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1979
+msgid "Connection error! Reason: "
+msgstr "连接出错! 原因: "
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1989
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr "{0} 命令参数不足"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1999
+msgid "Not connected to server"
+msgstr "未连接到服务器"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2261
+#, csharp-format
+msgid "{0}: No such nick/channel"
+msgstr "{0}: 无此昵称/频道"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2390
+#, csharp-format
+msgid ""
+"Increased send delay to {0}ms to avoid being flooded off the server again."
+msgstr "发送延时已增加到 {0}ms 以避免再次被服务器挤出。"
+
+#. TRANSLATOR: the final line will look like this:
+#. -!- Nick {0} is already in use
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2404
+msgid "Nick"
+msgstr "昵称"
+
+#. TRANSLATOR: the final line will look like this:
+#. -!- Nick {0} is already in use
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2414
+msgid "is already in use"
+msgstr "已被占用"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2424
+msgid "Cannot join to channel:"
+msgstr "无法加入频道:"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2432
+msgid "You are banned"
+msgstr "您已被封禁"
+
+#. TRANSLATOR: {0}: nickname, {1}: ident at host,
+#. {2}: CTCP command, {3}: own nickname, {4}: CTCP parameter
+#. example:
+#. meebey [meebey at example.com] requested CTCP VERSION from meebey:
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2508
+#, csharp-format
+msgid "{0} [{1}] requested CTCP {2} from {3}: {4}"
+msgstr "{0} [{1}] 请求 CTCP {2} 来自 {3}: {4}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2533
+#, csharp-format
+msgid "CTCP PING reply from {0}: {1} seconds"
+msgstr "CTCP PING 回复来自 {0}: {1} 秒"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2541
+#, csharp-format
+msgid "CTCP {0} reply from {1}: {2}"
+msgstr "CTCP {0} 回复来自 {1}: {2}"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2747
+#, csharp-format
+msgid "{0} [{1}] has joined {2}"
+msgstr "{0} [{1}] 已加入 {2}"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2873
+#, csharp-format
+msgid "{0} [{1}] has left {2}"
+msgstr "{0} [{1}] 已离开 {2}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2898
+#, csharp-format
+msgid "You were kicked from {0} by {1} [{2}]"
+msgstr "您被 {1} [{2}] 从 {0} 踢出"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2906
+#, csharp-format
+msgid "{0} was kicked from {1} by {2} [{3}]"
+msgstr "{0} 被 {2} [{3}] 从 {1} 踢出"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2923
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2956
+#, csharp-format
+msgid "You're now known as {0}"
+msgstr "您现在的昵称为 {0}"
+
+#. TRANSLATOR: do NOT change the position of {0} or {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2961
+#, csharp-format
+msgid "{0} is now known as {1}"
+msgstr "{0} 现在的昵称为 {1}"
+
+#. TRANSLATOR: do NOT change the position of {0} and {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2998
+#, csharp-format
+msgid "{0} changed the topic of {1} to: {2}"
+msgstr "{0} 将主题 {1} 改为: {2}"
+
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3075
+#, csharp-format
+msgid "Mode change [{0}] for user {1}"
+msgstr "用户 {1} 模式更改 [{0}]"
+
+#. TRANSLATOR: do NOT change the position of {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3085
+#, csharp-format
+msgid "mode/{0} [{1}] by {2}"
+msgstr "模式/{0} [{1}] by {2}"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3122
+#, csharp-format
+msgid "{0} [{1}] has quit"
+msgstr "{0} [{1}] 已退出"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3199
+#, csharp-format
+msgid ""
+"Connection to {0} port {1} has failed (attempt {2}), retrying in {3} "
+"seconds..."
+msgstr "到 {0} 端口 {1} 的连接失败 (第 {2}次尝试), 将在 {3} 秒后重试..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3248
+#, csharp-format
+msgid "{0} is away: {1}"
+msgstr "{0} 离开: {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3254
+msgid "You are no longer marked as being away"
+msgstr "您不再被标为离开状态"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3260
+msgid "You have been marked as being away"
+msgstr "您已被标为离开状态"
+
+
diff --git a/po-Engine-Twitter/LINGUAS b/po-Engine-Twitter/LINGUAS
index 9587292..8391e3f 100644
--- a/po-Engine-Twitter/LINGUAS
+++ b/po-Engine-Twitter/LINGUAS
@@ -1,8 +1,16 @@
 ca
 cs
 da
+de
+es
+en_GB
+fi
 fr
 it
 pt
+ru
+sk
 sv
-de
+tr
+ur
+zh_CN
diff --git a/po-Engine-Twitter/POTFILES.skip b/po-Engine-Twitter/POTFILES.skip
index e878ae3..e3ffa22 100644
--- a/po-Engine-Twitter/POTFILES.skip
+++ b/po-Engine-Twitter/POTFILES.skip
@@ -8,6 +8,8 @@ src/Engine-XMPP/
 src/Frontend/
 src/Frontend-GNOME/
 src/Frontend-GNOME-IRC/
+src/Frontend-STFL/
 src/Frontend-SWF/
 src/Frontend-WPF/
 src/Server/
+lib/
diff --git a/po-Engine-Twitter/ca.po b/po-Engine-Twitter/ca.po
index 9c0c26c..ba41bcb 100644
--- a/po-Engine-Twitter/ca.po
+++ b/po-Engine-Twitter/ca.po
@@ -1,112 +1,156 @@
+# 
 msgid ""
 msgstr ""
 "Project-Id-Version: Smuxi\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
 "PO-Revision-Date: \n"
 "Last-Translator: Siegfried-Angel Gevatter Pujals <rainct at ubuntu.com>\n"
 "Language-Team: Siegfried-Angel Gevatter Pujals <siegfried at gevatter.com>\n"
-"Language: \n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: \n"
 "Plural-Forms: nplurals=2; plural=n != 1\n"
 "X-Poedit-Language: Catalan\n"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:101
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:125
 msgid "Home Timeline"
 msgstr "Línia temporal"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:108
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:132
 msgid "Replies"
 msgstr "Respostes"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:115
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:139
 msgid "Direct Messages"
 msgstr "Missatges directes"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:133
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:174
 msgid "Connecting to Twitter..."
 msgstr "S'està connectant al Twitter..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:141
-msgid "Login failed!"
-msgstr "No s'ha pogut iniciar sessió!"
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:203
+msgid "Twitter authorization required."
+msgstr "Cal una autoritzat per a accedir al Twitter."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:218
+#, csharp-format
+msgid "Please open the following URL and click \"Allow\" to allow Smuxi to connect to your Twitter account: {0}"
+msgstr "Obriu l'adreça següent i premeu «Permet» per a permetre a l'Smuxi de connectar al vostre compte de Twitter: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:234
+msgid "Once you have allowed Smuxi to access your Twitter account, Twitter will provide a PIN."
+msgstr "Un cop hageu permès a l'Smuxi accedir al vostre compte de Twitter, aquest us proporcionarà un codi PIN."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:143
-msgid "Login failed! Username and/or password are incorrect."
-msgstr "No s'ha pogut iniciar sessió! El nom d'usuari i/o la contrasenya són incorrectes."
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:241
+msgid "Please type: /pin PIN_FROM_TWITTER"
+msgstr "Escriviu: /pin PIN_DEL_TWITTER"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:149
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:251
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:291
 msgid "Connection failed!"
 msgstr "Ha fallat la connexió!"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:151
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:253
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:293
 msgid "Connection failed! Reason: "
 msgstr "Ha fallat la connexió! Motiu:"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:156
-msgid "Successfully connected to Twitter."
-msgstr "S'ha connectat correctament amb Twitter."
-
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:164
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:266
 msgid "Fetching user details from Twitter, please wait..."
 msgstr "S'està recuperant els detalls de l'usuari de Twitter, espereu..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:169
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:271
 msgid "Finished fetching user details."
 msgstr "S'ha acabat de recuperar els detalls de l'usuari."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:176
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:276
+msgid "Successfully connected to Twitter."
+msgstr "S'ha connectat correctament amb Twitter."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
 msgid "Failed to fetch user details from Twitter. Reason: "
 msgstr "No s'ha pogut recuperar els detalls de l'usuari de Twitter. Motiu:"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:185
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:306
 msgid "Fetching friends from Twitter, please wait..."
 msgstr "S'està recuperant la llista d'amics de Twitter, espereu..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:190
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:311
 msgid "Finished fetching friends."
 msgstr "S'ha acabat de recuperar la llista d'amics."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:193
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:314
 msgid "Failed to fetch friends from Twitter. Reason: "
 msgstr "No s'ha pogut recuperar la llista d'amics de Twitter. Motiu:"
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:454
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:588
 msgid "Twitter Commands"
 msgstr "Ordres del Twitter"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:504
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:632
+msgid "No pending authorization request!"
+msgstr "No hi ha cap petició d'autorització pendent."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:653
+#, csharp-format
+msgid "Failed to authorize with Twitter: {0}"
+msgstr "No s'ha pogut autoritzar l'accés al Twitter: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:661
+msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
+msgstr "Twitter no ha acceptat el PIN. L'heu introduït correctament?"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:669
+#, csharp-format
+msgid "Please retry by closing this tab and reconnecting to the Twitter \"{0}\" account."
+msgstr "Torneu a intentar-ho tancant aquesta pestanya i tornant a connectar al compte de Twitter «{0}»."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:709
+msgid "Migrated Twitter account from basic auth to OAuth."
+msgstr "S'ha migrat el compte de Twitter de l'autenticació bàsica a OAuth."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:722
+#, csharp-format
+msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
+msgstr "L'Smuxi ha estat autoritzat per a accedir al compte de Twitter «{0}»."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:744
 #, csharp-format
 msgid "Could not update status - Reason: {0}"
 msgstr "No s'ha pogut actualitzar l'estat - Motiu: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:513
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:753
 msgid "Cannot send message - no target specified. Use: /msg $nick message"
 msgstr "No es pot enviar el missatge - no s'ha especificat cap destinatari. Utilitzeu: /msg $sobrenom missatge"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:526
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:568
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:766
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:803
 #, csharp-format
 msgid "Could not send message - Reason: {0}"
 msgstr "No s'ha pogut enviar el missatge - Motiu: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:555
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:790
 msgid "Could not send message - the specified user does not exist."
 msgstr "No s'ha pogut enviar el missatge - l'usuari especificat no existeix."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:631
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:879
 msgid "An error occurred while fetching the friends timeline from Twitter. Reason: "
 msgstr "S'ha produït un error al recuperar la línia temporal de l'amic de Twitter. Motiu:"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:721
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:980
 msgid "An error occurred while fetching the replies from Twitter. Reason: "
 msgstr "S'ha produït un error al recuperar les respostes de Twitter. Motiu:"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:816
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1073
 msgid "An error occurred while fetching direct messages from Twitter. Reason: "
 msgstr "S'ha produït un error al recuperar els missatges directes de Twitter. Motiu:"
 
+#~ msgid "Login failed!"
+#~ msgstr "No s'ha pogut iniciar sessió!"
+
+#~ msgid "Login failed! Username and/or password are incorrect."
+#~ msgstr "No s'ha pogut iniciar sessió! El nom d'usuari i/o la contrasenya són incorrectes."
diff --git a/po-Engine-Twitter/da.po b/po-Engine-Twitter/da.po
index 1f01688..1d41785 100644
--- a/po-Engine-Twitter/da.po
+++ b/po-Engine-Twitter/da.po
@@ -1,115 +1,175 @@
-# Danish translation smuxi-engine-twitter.
-# Copyright (C) 2010 smuxi-engine & nedenstående oversættere.
-# This file is distributed under the same license as the smuxi-engine-twitter package.
-# Joe Hansen (joedalton2 at yahoo.dk), 2010.
-#
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Joe Hansen <joedalton2 at yahoo.dk>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: smuxi-engine-twitter\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-16 12:42+0000\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:20+0100\n"
+"PO-Revision-Date: 2011-12-29 19:50+0000\n"
 "Last-Translator: Joe Hansen <joedalton2 at yahoo.dk>\n"
-"Language-Team: Danish <debian-l10n-danish at lists.debian.org>\n"
+"Language-Team: Danish (http://www.transifex.net/projects/p/smuxi/team/da/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: da\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:101
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:124
 msgid "Home Timeline"
 msgstr "Hjemmetidslinje"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:108
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:135
 msgid "Replies"
 msgstr "Svar"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:115
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:146
 msgid "Direct Messages"
 msgstr "Direkte beskeder"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:133
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:189
 msgid "Connecting to Twitter..."
 msgstr "Tilslutter til Twitter..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:141
-msgid "Login failed!"
-msgstr "Logind mislykkedes!"
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:228
+msgid "Twitter authorization required."
+msgstr "Twittergodkendelse krævet."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:143
-msgid "Login failed! Username and/or password are incorrect."
-msgstr "Logind mislykkedes! Brugernavn og/eller adgangskode er forkerte."
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:235
+#, csharp-format
+msgid ""
+"Please open the following URL and click \"Allow\" to allow Smuxi to connect "
+"to your Twitter account: {0}"
+msgstr ""
+"Åbn venligst den følgende adresse og klik »Tillad« for at tillade Smuxi at "
+"forbinde til din Twitterkonto: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:251
+msgid ""
+"Once you have allowed Smuxi to access your Twitter account, Twitter will "
+"provide a PIN."
+msgstr ""
+"Når du har tilladt Smuxi at tilgå din Twitterkonto, vil Twitter tilbyde en "
+"PIN."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:149
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:258
+msgid "Please type: /pin PIN_FROM_TWITTER"
+msgstr "Indtast venligst: /pin PIN_FRA_TWITTER"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:265
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:305
 msgid "Connection failed!"
 msgstr "Tilslutning mislykkedes!"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:151
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:267
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:307
 msgid "Connection failed! Reason: "
 msgstr "Tilslutning mislykkedes! Ã…rsag: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:156
-msgid "Successfully connected to Twitter."
-msgstr "Tilsluttet Twitter."
-
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:164
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:280
 msgid "Fetching user details from Twitter, please wait..."
 msgstr "Henter brugerdetaljer fra Twitter, vent venligst..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:169
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
 msgid "Finished fetching user details."
 msgstr "Færdig med hentning af brugerdetaljer."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:176
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:290
+msgid "Successfully connected to Twitter."
+msgstr "Tilsluttet Twitter."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:299
 msgid "Failed to fetch user details from Twitter. Reason: "
 msgstr "Kunne ikke hente brugerdetaljer fra Twitter. Ã…rsag: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:185
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:320
 msgid "Fetching friends from Twitter, please wait..."
 msgstr "Henter venneliste fra Twitter, vent venligst..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:190
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:325
 msgid "Finished fetching friends."
 msgstr "Afsluttede hentning af venneliste."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:193
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:328
 msgid "Failed to fetch friends from Twitter. Reason: "
-msgstr "Kunen ikke hente venneliste fra Twitter. Ã…rsag: "
+msgstr "Kunne ikke hente venneliste fra Twitter. Ã…rsag: "
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:454
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:605
 msgid "Twitter Commands"
 msgstr "Twitterkommandoer"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:504
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:647
+msgid "No pending authorization request!"
+msgstr "Ingen igangværende godkendelsesforespørgsel!"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:668
+#, csharp-format
+msgid "Failed to authorize with Twitter: {0}"
+msgstr "Kunne ikke indhente godkendelse hos Twitter: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:676
+msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
+msgstr "Twitter accepterede ikke din PIN. Indtastede du den korrekt?"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:684
+#, csharp-format
+msgid ""
+"Please retry by closing this tab and reconnecting to the Twitter \"{0}\" "
+"account."
+msgstr ""
+"Forsøg igen ved at lukke dette faneblad og forbinde igen til Twitter "
+"»{0}-kontoen«."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:725
+msgid "Migrated Twitter account from basic auth to OAuth."
+msgstr "Migrerede Twitterkonto fra grundlæggende auth til Oauth."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:739
+#, csharp-format
+msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
+msgstr "Godkendte Twitterkonto »{0}« til Smuxi"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:761
 #, csharp-format
 msgid "Could not update status - Reason: {0}"
 msgstr "Kunne ikke opdatere status - årsag: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:513
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:770
 msgid "Cannot send message - no target specified. Use: /msg $nick message"
 msgstr "Kan ikke sende besked - intet mål angivet. Brug: /msg $nick besked"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:526
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:568
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:783
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:820
 #, csharp-format
 msgid "Could not send message - Reason: {0}"
 msgstr "Kunne ikke sende besked - årsag: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:555
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:807
 msgid "Could not send message - the specified user does not exist."
 msgstr "Kunne ikke sende besked - den angivne bruger findes ikke."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:631
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:896
 msgid ""
 "An error occurred while fetching the friends timeline from Twitter. Reason: "
-msgstr ""
-"En fejl opstod under hentning af vennetidslinjen fra Twitter. Ã…rsag: "
+msgstr "En fejl opstod under hentning af vennetidslinjen fra Twitter. Ã…rsag: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:721
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1001
 msgid "An error occurred while fetching the replies from Twitter. Reason: "
 msgstr "En fejl opstod under hentning af svar fra Twitter. Ã…rsag: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:816
-msgid "An error occurred while fetching direct messages from Twitter. Reason: "
-msgstr "En fejl opstod under hentning af direkte beskeder fra Twitter. Ã…rsag: "
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1097
+msgid ""
+"An error occurred while fetching direct messages from Twitter. Reason: "
+msgstr ""
+"En fejl opstod under hentning af direkte beskeder fra Twitter. Ã…rsag: "
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1441
+msgid "Twitter didn't send a valid response, they're probably overloaded"
+msgstr "Twitter sendte ikke et gyldigt svar, de er sikkert overbelastet"
+
+
diff --git a/po-Engine-Twitter/de.po b/po-Engine-Twitter/de.po
index 85dd094..a9d997e 100644
--- a/po-Engine-Twitter/de.po
+++ b/po-Engine-Twitter/de.po
@@ -1,115 +1,185 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-# Bianca Mix <heavydemon at freenet.de>, 2010
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
 # 
+# Translators:
+# Bianca Mix <heavydemon at freenet.de>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: Smuxi 0.6.4\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-01-02 21:59+0100\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:20+0100\n"
+"PO-Revision-Date: 2011-12-30 22:59+0000\n"
 "Last-Translator: Bianca Mix <heavydemon at freenet.de>\n"
-"Language-Team: French Localization <debian-l10n-french at lists.debian.org>\n"
+"Language-Team: German (http://www.transifex.net/projects/p/smuxi/team/de/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Poedit-Language: French\n"
+"Language: de\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:101
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:124
 msgid "Home Timeline"
 msgstr "Zuhause Zeitachse"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:108
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:135
 msgid "Replies"
 msgstr "Antworten"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:115
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:146
 msgid "Direct Messages"
 msgstr "Direktnachrichten"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:133
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:189
 msgid "Connecting to Twitter..."
 msgstr "Verbinde zu Twitter..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:141
-msgid "Login failed!"
-msgstr "Das Anmelden ist fehlgeschlagen!"
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:228
+msgid "Twitter authorization required."
+msgstr "Twitter Autorisierung erfolgreich"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:143
-msgid "Login failed! Username and/or password are incorrect."
-msgstr "Das Verbinden ist fehlgeschlagen! Benutzername und/oder Passwort ist nicht korrekt."
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:235
+#, csharp-format
+msgid ""
+"Please open the following URL and click \"Allow\" to allow Smuxi to connect "
+"to your Twitter account: {0}"
+msgstr ""
+"Bitte öffnen Sie die follgende URL und klicken Sie \"Allow\" um Smuxi zu "
+"erlauben, sich mit ihrem Twitter-Benutzerkonto zu verbinden: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:149
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:251
+msgid ""
+"Once you have allowed Smuxi to access your Twitter account, Twitter will "
+"provide a PIN."
+msgstr ""
+"Sobald Sie Smuxi erlaubt haben, sich mit Ihrem Twitter-Benutzerkonto zu "
+"verbinden, wird Twitter Ihnen eine PIN bereitstellen"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:258
+msgid "Please type: /pin PIN_FROM_TWITTER"
+msgstr "Bitte tippen Sie: /pin PIN_VON_TWITTER"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:265
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:305
 msgid "Connection failed!"
 msgstr "Verbindung ist fehlgeschlagen!"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:151
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:267
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:307
 msgid "Connection failed! Reason: "
 msgstr "Verbindung ist fehlgeschlagen! Grund: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:156
-msgid "Successfully connected to Twitter."
-msgstr "Erfolgreich zu Twitter verbunden."
-
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:164
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:280
 msgid "Fetching user details from Twitter, please wait..."
 msgstr "Rufe die Benutzerinformationen von Twitter ab, bitte warten Sie..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:169
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
 msgid "Finished fetching user details."
 msgstr "Abrufen der Benutzerinformationen abgeschlossen."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:176
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:290
+msgid "Successfully connected to Twitter."
+msgstr "Erfolgreich zu Twitter verbunden."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:299
 msgid "Failed to fetch user details from Twitter. Reason: "
 msgstr "Abrufen der Benutzerinformationen fehlgeschlagen. Grund:"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:185
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:320
 msgid "Fetching friends from Twitter, please wait..."
 msgstr "Rufe Freunde von Twitter ab, bitte warten Sie..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:190
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:325
 msgid "Finished fetching friends."
 msgstr "Abrufen der Freunde abgeschlossen."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:193
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:328
 msgid "Failed to fetch friends from Twitter. Reason: "
 msgstr "Abrufen der Freunde von Twitter fehlgeschlagen. Grund :"
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:454
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:605
 msgid "Twitter Commands"
 msgstr "Twitter Befehle"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:504
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:647
+msgid "No pending authorization request!"
+msgstr "Keine ausstehenden Autorisierungsanfragen!"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:668
+#, csharp-format
+msgid "Failed to authorize with Twitter: {0}"
+msgstr "Autorisierung gegenüber Twitter fehlgeschlagen: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:676
+msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
+msgstr ""
+"Twitter hat Ihre PIN nicht akzeptiert. Haben Sie sie korrekt eingegeben?"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:684
+#, csharp-format
+msgid ""
+"Please retry by closing this tab and reconnecting to the Twitter \"{0}\" "
+"account."
+msgstr ""
+"Bitte versuchen Sie es erneut, indem Sie diesen Reiter schließen und sich "
+"erneut zum Twitter-Benutzerkont \"{0}\" verbinden."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:725
+msgid "Migrated Twitter account from basic auth to OAuth."
+msgstr "Migrierte Twitter-Benutzerkonto von basic auth zu OAuth"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:739
+#, csharp-format
+msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
+msgstr "Einrichtung des Twitter-Benutzerkontos \"{0}\" für Smuxi war erfolgreich "
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:761
 #, csharp-format
 msgid "Could not update status - Reason: {0}"
 msgstr "Konnte den Status nicht aktualisieren - Ursache: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:513
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:770
 msgid "Cannot send message - no target specified. Use: /msg $nick message"
-msgstr "Kann Nachricht nicht senden - Ziel ist nicht definiert. Verwenden Sie /msg $nick Nachricht"
+msgstr ""
+"Kann Nachricht nicht senden - Ziel ist nicht definiert. Verwenden Sie /msg "
+"$nick Nachricht"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:526
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:568
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:783
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:820
 #, csharp-format
 msgid "Could not send message - Reason: {0}"
 msgstr "Konnte Nachricht nicht senden - Ursache: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:555
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:807
 msgid "Could not send message - the specified user does not exist."
 msgstr "Konnte Nachricht nicht senden - der gewählte Benutzer existiert nicht"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:631
-msgid "An error occurred while fetching the friends timeline from Twitter. Reason: "
-msgstr "Ein Fehler ist aufgetreten, während die Freunde Zeitachse von Twitter abgerufen wurde. Grund:"
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:896
+msgid ""
+"An error occurred while fetching the friends timeline from Twitter. Reason: "
+msgstr ""
+"Ein Fehler ist aufgetreten, während die Freunde Zeitachse von Twitter "
+"abgerufen wurde. Grund:"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:721
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1001
 msgid "An error occurred while fetching the replies from Twitter. Reason: "
-msgstr "Während des Abrufens der Antworten von Twitter ist ein Fehler aufgetreten. Grund:"
+msgstr ""
+"Während des Abrufens der Antworten von Twitter ist ein Fehler aufgetreten. "
+"Grund:"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1097
+msgid ""
+"An error occurred while fetching direct messages from Twitter. Reason: "
+msgstr ""
+"Während des Abrufens der Direktenachrichten von Twitter ist ein Fehler "
+"aufgetreten. Grund:"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1441
+msgid "Twitter didn't send a valid response, they're probably overloaded"
+msgstr ""
+"Twitter hat keine gültige Antwort gesendet. Der Dienst ist womöglich "
+"überbeansprucht."
+
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:816
-msgid "An error occurred while fetching direct messages from Twitter. Reason: "
-msgstr "Während des Abrufens der Direktenachrichten von Twitter ist ein Fehler aufgetreten. Grund:"
diff --git a/po-Engine-Twitter/en_GB.po b/po-Engine-Twitter/en_GB.po
new file mode 100644
index 0000000..896454a
--- /dev/null
+++ b/po-Engine-Twitter/en_GB.po
@@ -0,0 +1,163 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: English (United Kingdom) (http://www.transifex.net/projects/p/smuxi/team/en_GB/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: en_GB\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:125
+msgid "Home Timeline"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:132
+msgid "Replies"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:139
+msgid "Direct Messages"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:174
+msgid "Connecting to Twitter..."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:203
+msgid "Twitter authorization required."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:218
+#, csharp-format
+msgid ""
+"Please open the following URL and click \"Allow\" to allow Smuxi to connect "
+"to your Twitter account: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:234
+msgid ""
+"Once you have allowed Smuxi to access your Twitter account, Twitter will "
+"provide a PIN."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:241
+msgid "Please type: /pin PIN_FROM_TWITTER"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:251
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:291
+msgid "Connection failed!"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:253
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:293
+msgid "Connection failed! Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:266
+msgid "Fetching user details from Twitter, please wait..."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:271
+msgid "Finished fetching user details."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:276
+msgid "Successfully connected to Twitter."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
+msgid "Failed to fetch user details from Twitter. Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:306
+msgid "Fetching friends from Twitter, please wait..."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:311
+msgid "Finished fetching friends."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:314
+msgid "Failed to fetch friends from Twitter. Reason: "
+msgstr ""
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:588
+msgid "Twitter Commands"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:632
+msgid "No pending authorization request!"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:653
+#, csharp-format
+msgid "Failed to authorize with Twitter: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:661
+msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:669
+#, csharp-format
+msgid ""
+"Please retry by closing this tab and reconnecting to the Twitter \"{0}\" "
+"account."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:709
+msgid "Migrated Twitter account from basic auth to OAuth."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:722
+#, csharp-format
+msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:744
+#, csharp-format
+msgid "Could not update status - Reason: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:753
+msgid "Cannot send message - no target specified. Use: /msg $nick message"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:766
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:803
+#, csharp-format
+msgid "Could not send message - Reason: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:790
+msgid "Could not send message - the specified user does not exist."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:879
+msgid ""
+"An error occurred while fetching the friends timeline from Twitter. Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:980
+msgid "An error occurred while fetching the replies from Twitter. Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1073
+msgid ""
+"An error occurred while fetching direct messages from Twitter. Reason: "
+msgstr ""
+
+
diff --git a/po-Engine-Twitter/es.po b/po-Engine-Twitter/es.po
new file mode 100644
index 0000000..014c554
--- /dev/null
+++ b/po-Engine-Twitter/es.po
@@ -0,0 +1,151 @@
+# po-Server/smuxi-server.pot Spanish translation file
+# Copyright (C) 2010
+# This file is distributed under the same license as the Smuxi - IRC Client package.
+# Ricardo A. Hermosilla Carrillo <ra.hermosillac at gmail.com>, 2010.
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2010-09-12 23:30-0400\n"
+"Last-Translator: Ricardo A. Hermosilla Carrillo <ra.hermosillac at gmail.com>\n"
+"Language-Team: Spanish <ES at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:125
+msgid "Home Timeline"
+msgstr "Línea de Tiempo"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:132
+msgid "Replies"
+msgstr "Respuestas"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:139
+msgid "Direct Messages"
+msgstr "Mensajes Directos"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:174
+msgid "Connecting to Twitter..."
+msgstr "Conectando a Twitter..."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:203
+msgid "Twitter authorization required."
+msgstr "Autorización de Twitter requerida."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:218
+#, csharp-format
+msgid "Please open the following URL and click \"Allow\" to allow Smuxi to connect to your Twitter account: {0}"
+msgstr "Por favor, abra la siguiente dirección y haga click en \"Autorizar\" para permitir a Smuxi conectarse a su cuenta de Twitter: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:234
+msgid "Once you have allowed Smuxi to access your Twitter account, Twitter will provide a PIN."
+msgstr "Una vez que haya autorizado a Smuxi acceder a su cuenta, Twitter le proveerá un número secreto."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:241
+msgid "Please type: /pin PIN_FROM_TWITTER"
+msgstr "Por favor, escriba: /pin NUMERO_SECRETO_DE_TWITTER"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:251
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:291
+msgid "Connection failed!"
+msgstr "Conexión fallida!"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:253
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:293
+msgid "Connection failed! Reason: "
+msgstr "Conexión fallida! Razón: "
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:266
+msgid "Fetching user details from Twitter, please wait..."
+msgstr "Buscando los detalles de usuario de Twitter, por favor espere..."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:271
+msgid "Finished fetching user details."
+msgstr "Búsqueda realizada."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:276
+msgid "Successfully connected to Twitter."
+msgstr "Conexión satisfactoria con Twitter."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
+msgid "Failed to fetch user details from Twitter. Reason: "
+msgstr "Error al buscar información del usuario en Twitter. Razón: "
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:306
+msgid "Fetching friends from Twitter, please wait..."
+msgstr "Buscando amigos en Twitter, por favor espere..."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:311
+msgid "Finished fetching friends."
+msgstr "Búsqueda realizada."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:314
+msgid "Failed to fetch friends from Twitter. Reason: "
+msgstr "Error al importar amigos de Twitter. Razón: "
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:588
+msgid "Twitter Commands"
+msgstr "Comandos de Twitter"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:632
+msgid "No pending authorization request!"
+msgstr "No hay autorización pendiente!"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:653
+#, csharp-format
+msgid "Failed to authorize with Twitter: {0}"
+msgstr "Error al autorizar con Twitter: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:661
+msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
+msgstr "Twitter no ha aceptado tu número secreto. Lo has ingresado correctamente?"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:669
+#, csharp-format
+msgid "Please retry by closing this tab and reconnecting to the Twitter \"{0}\" account."
+msgstr "Por favor, inténtelo nuevamente cerrando esta pestaña y reconectando a la cuenta \"{0}\" de Twitter."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:709
+msgid "Migrated Twitter account from basic auth to OAuth."
+msgstr "Cuenta de Twitter migrada de autenticación básica para OAuth"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:722
+#, csharp-format
+msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
+msgstr "Autorización satisfactoria de la cuenta Twitter \"{0}\" para Smuxi"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:744
+#, csharp-format
+msgid "Could not update status - Reason: {0}"
+msgstr "No se puede actualizar su estado. Razón: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:753
+msgid "Cannot send message - no target specified. Use: /msg $nick message"
+msgstr "No se puede enviar el mensaje. No se ha seleccionado un destinatario. Use: /msg $nick mensaje"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:766
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:803
+#, csharp-format
+msgid "Could not send message - Reason: {0}"
+msgstr "No se puede enviar el mensaje. Razón: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:790
+msgid "Could not send message - the specified user does not exist."
+msgstr "No se puede enviar el mensaje. El usuario especificado no existe."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:879
+msgid "An error occurred while fetching the friends timeline from Twitter. Reason: "
+msgstr "Un error ha ocurrido mientras se intentaba importar la línea de tiempo de sus amigos de Twitter. Razón: "
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:980
+msgid "An error occurred while fetching the replies from Twitter. Reason: "
+msgstr "Un error ha ocurrido mientras se importaban las respuestas desde Twitter. Razón: "
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1073
+msgid "An error occurred while fetching direct messages from Twitter. Reason: "
+msgstr "Un error ha ocurrido mientras se importaban los mensajes directos desde Twitter. Razón: "
diff --git a/po-Engine-Twitter/fi.po b/po-Engine-Twitter/fi.po
new file mode 100644
index 0000000..641860a
--- /dev/null
+++ b/po-Engine-Twitter/fi.po
@@ -0,0 +1,163 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: Finnish (http://www.transifex.net/projects/p/smuxi/team/fi/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: fi\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:125
+msgid "Home Timeline"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:132
+msgid "Replies"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:139
+msgid "Direct Messages"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:174
+msgid "Connecting to Twitter..."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:203
+msgid "Twitter authorization required."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:218
+#, csharp-format
+msgid ""
+"Please open the following URL and click \"Allow\" to allow Smuxi to connect "
+"to your Twitter account: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:234
+msgid ""
+"Once you have allowed Smuxi to access your Twitter account, Twitter will "
+"provide a PIN."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:241
+msgid "Please type: /pin PIN_FROM_TWITTER"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:251
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:291
+msgid "Connection failed!"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:253
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:293
+msgid "Connection failed! Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:266
+msgid "Fetching user details from Twitter, please wait..."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:271
+msgid "Finished fetching user details."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:276
+msgid "Successfully connected to Twitter."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
+msgid "Failed to fetch user details from Twitter. Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:306
+msgid "Fetching friends from Twitter, please wait..."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:311
+msgid "Finished fetching friends."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:314
+msgid "Failed to fetch friends from Twitter. Reason: "
+msgstr ""
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:588
+msgid "Twitter Commands"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:632
+msgid "No pending authorization request!"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:653
+#, csharp-format
+msgid "Failed to authorize with Twitter: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:661
+msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:669
+#, csharp-format
+msgid ""
+"Please retry by closing this tab and reconnecting to the Twitter \"{0}\" "
+"account."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:709
+msgid "Migrated Twitter account from basic auth to OAuth."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:722
+#, csharp-format
+msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:744
+#, csharp-format
+msgid "Could not update status - Reason: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:753
+msgid "Cannot send message - no target specified. Use: /msg $nick message"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:766
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:803
+#, csharp-format
+msgid "Could not send message - Reason: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:790
+msgid "Could not send message - the specified user does not exist."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:879
+msgid ""
+"An error occurred while fetching the friends timeline from Twitter. Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:980
+msgid "An error occurred while fetching the replies from Twitter. Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1073
+msgid ""
+"An error occurred while fetching direct messages from Twitter. Reason: "
+msgstr ""
+
+
diff --git a/po-Engine-Twitter/fr.po b/po-Engine-Twitter/fr.po
index 7892918..8261402 100644
--- a/po-Engine-Twitter/fr.po
+++ b/po-Engine-Twitter/fr.po
@@ -1,127 +1,189 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-# Clement BOURGEOIS <moonpyk at gmail.com>, 2009.
-#
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Clément Bourgeois <moonpyk at gmail.com>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: Smuxi 0.6.4\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-15 22:21+0100\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:20+0100\n"
+"PO-Revision-Date: 2011-12-30 22:56+0000\n"
 "Last-Translator: Clément Bourgeois <moonpyk at gmail.com>\n"
-"Language-Team: French Localization <debian-l10n-french at lists.debian.org>\n"
+"Language-Team: French (http://www.transifex.net/projects/p/smuxi/team/fr/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Poedit-Language: French\n"
+"Language: fr\n"
+"Plural-Forms: nplurals=2; plural=(n > 1)\n"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:101
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:124
 msgid "Home Timeline"
 msgstr "Chronologie générale"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:108
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:135
 msgid "Replies"
 msgstr "Réponses"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:115
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:146
 msgid "Direct Messages"
 msgstr "Messages directs"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:133
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:189
 msgid "Connecting to Twitter..."
 msgstr "Connexion à Twitter..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:141
-msgid "Login failed!"
-msgstr "Impossible de se logger !"
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:228
+msgid "Twitter authorization required."
+msgstr "Autorisation de Twitter nécessaire"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:143
-msgid "Login failed! Username and/or password are incorrect."
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:235
+#, csharp-format
+msgid ""
+"Please open the following URL and click \"Allow\" to allow Smuxi to connect "
+"to your Twitter account: {0}"
+msgstr ""
+"Veuillez ouvrir l'URL suivante et cliquez sur \"Autoriser\\” pour autoriser "
+"Smuxi à se connecter sur votre compte Twitter : {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:251
+msgid ""
+"Once you have allowed Smuxi to access your Twitter account, Twitter will "
+"provide a PIN."
 msgstr ""
-"Impossible de se logger ! Le nom d'utilisateur et/ou le mot de passe étaient "
-"incorrects."
+"Une fois que vous avez autorisé Smuxi à acceder à votre compte Twitter, "
+"Twitter va vous envoyer un code PIN."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:258
+msgid "Please type: /pin PIN_FROM_TWITTER"
+msgstr "Veuillez taper : /pin CODE_PIN_DE_TWITTER"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:149
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:265
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:305
 msgid "Connection failed!"
 msgstr "Connexion impossible !"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:151
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:267
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:307
 msgid "Connection failed! Reason: "
 msgstr "Connexion impossible ! Raison : "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:156
-msgid "Successfully connected to Twitter."
-msgstr "Connexion à Twitter réussie."
-
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:164
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:280
 msgid "Fetching user details from Twitter, please wait..."
 msgstr "Téléchargement des détails utilisateur Twitter. Veuillez patienter..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:169
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
 msgid "Finished fetching user details."
 msgstr "Téléchargement des détails utilisateur terminée."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:176
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:290
+msgid "Successfully connected to Twitter."
+msgstr "Connexion à Twitter réussie."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:299
 msgid "Failed to fetch user details from Twitter. Reason: "
-msgstr "Impossible de télécharger les détails utilisateur de Twitter. Raison :"
+msgstr ""
+"Impossible de télécharger les détails utilisateur de Twitter. Raison :"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:185
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:320
 msgid "Fetching friends from Twitter, please wait..."
 msgstr ""
 "Téléchargement de la liste des amis Twitter en cours, veuillez patienter..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:190
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:325
 msgid "Finished fetching friends."
 msgstr "Téléchargement de la liste des amis terminée."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:193
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:328
 msgid "Failed to fetch friends from Twitter. Reason: "
 msgstr "Impossible de télécharger la liste des amis Twitter. Raison :"
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:454
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:605
 msgid "Twitter Commands"
 msgstr "Commandes Twitter"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:504
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:647
+msgid "No pending authorization request!"
+msgstr "Aucune requête d'autorisation en attente !"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:668
+#, csharp-format
+msgid "Failed to authorize with Twitter: {0}"
+msgstr "Impossible d'obtenir une autorisation de Twitter : {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:676
+msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
+msgstr ""
+"Twitter n'a pas accepté votre code PIN. L'avez vous entré correctement ?"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:684
+#, csharp-format
+msgid ""
+"Please retry by closing this tab and reconnecting to the Twitter \"{0}\" "
+"account."
+msgstr ""
+"Veuillez réessayer en fermant cet onglet et en vous connectant à nouveau au "
+"compte Twitter \"{0}\"."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:725
+msgid "Migrated Twitter account from basic auth to OAuth."
+msgstr ""
+"Le compte Twitter géré par autorisation basique à été migré la methode "
+"OAuth."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:739
+#, csharp-format
+msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
+msgstr "Twitter a accepté la demande d'autorisation Smuxi pour le compte \"{0}\"."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:761
 #, csharp-format
 msgid "Could not update status - Reason: {0}"
 msgstr "Impossible de mettre à jour le statut - Raison : {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:513
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:770
 msgid "Cannot send message - no target specified. Use: /msg $nick message"
 msgstr ""
-"Impossible d'envoyer le message. Aucune cible spécifiée. Utilisez /msg $nick "
-"message"
+"Impossible d'envoyer le message. Aucune cible spécifiée. Utilisez /msg $nick"
+" message"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:526
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:568
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:783
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:820
 #, csharp-format
 msgid "Could not send message - Reason: {0}"
 msgstr "Impossible d'envoyer le message - Raison : {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:555
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:807
 msgid "Could not send message - the specified user does not exist."
 msgstr "Impossible d'envoyer le message. L'utilisateur spécifié n'existe pas."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:631
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:896
 msgid ""
 "An error occurred while fetching the friends timeline from Twitter. Reason: "
 msgstr ""
 "Une erreur c'est produite pendant le téléchargement de la chronologie des "
 "amis Twitter. Raison :"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:721
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1001
 msgid "An error occurred while fetching the replies from Twitter. Reason: "
 msgstr ""
 "Une erreur c'est produite pendant le téléchargement des réponses Twitter. "
 "Raison :"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:816
-msgid "An error occurred while fetching direct messages from Twitter. Reason: "
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1097
+msgid ""
+"An error occurred while fetching direct messages from Twitter. Reason: "
 msgstr ""
 "Un erreur s'est produite pendant le téléchargement des messages directs "
 "Twitter. Raison :"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1441
+msgid "Twitter didn't send a valid response, they're probably overloaded"
+msgstr ""
+"Twitter n'a pas envoyé de réponse valide, le service est peut-être en sur-"
+"capacité."
+
+
diff --git a/po-Engine-Twitter/it.po b/po-Engine-Twitter/it.po
index 56c245d..6f01205 100644
--- a/po-Engine-Twitter/it.po
+++ b/po-Engine-Twitter/it.po
@@ -2,14 +2,13 @@
 # Copyright (C) 2005-2010 Mirco Bauer <meebey at meebey.net>
 # This file is distributed under the same license as the Smuxi package.
 #
-#
 # Vincenzo Campanella <vinz65 at gmail.com>, 2009, 2010.
 msgid ""
 msgstr ""
 "Project-Id-Version: smuxi-engine-twitter\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-15 13:12+0200\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2010-09-11 09:43+0200\n"
 "Last-Translator: Vincenzo Campanella <vinz65 at gmail.com>\n"
 "Language-Team: Italian <tp at lists.linux.it>\n"
 "Language: it\n"
@@ -17,108 +16,167 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:101
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:125
 msgid "Home Timeline"
 msgstr "Cronologia di home"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:108
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:132
 msgid "Replies"
 msgstr "Risposte"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:115
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:139
 msgid "Direct Messages"
 msgstr "Messaggi diretti"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:133
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:174
 msgid "Connecting to Twitter..."
 msgstr "Connessione a Twitter in corso"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:141
-msgid "Login failed!"
-msgstr "Accesso non riuscito."
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:203
+msgid "Twitter authorization required."
+msgstr "È necessaria l'autorizzazione di Twitter."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:218
+#, csharp-format
+msgid ""
+"Please open the following URL and click \"Allow\" to allow Smuxi to connect "
+"to your Twitter account: {0}"
+msgstr ""
+"Aprire l'URL seguente e cliccare «Allow» per consentire a Smuxi di "
+"collegarsi al proprio account Twitter: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:234
+msgid ""
+"Once you have allowed Smuxi to access your Twitter account, Twitter will "
+"provide a PIN."
+msgstr ""
+"Dopo aver abilitato Smuxi ad accedere al proprio account Twitter, Twitter "
+"fornirà un PIN."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:143
-msgid "Login failed! Username and/or password are incorrect."
-msgstr "Accesso non riuscito: il nome utente o la password non sono corretti."
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:241
+msgid "Please type: /pin PIN_FROM_TWITTER"
+msgstr "Inserire: /pin PIN_FROM_TWITTER"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:149
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:251
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:291
 msgid "Connection failed!"
 msgstr "Connessione non riuscita."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:151
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:253
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:293
 msgid "Connection failed! Reason: "
 msgstr "Connessione non riuscita. Motivo: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:156
-msgid "Successfully connected to Twitter."
-msgstr "Collegamento a Twitter avvenuto con successo."
-
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:164
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:266
 msgid "Fetching user details from Twitter, please wait..."
 msgstr "Recupero dei dettagli sull'utente da Twitter in corso, attendere."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:169
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:271
 msgid "Finished fetching user details."
 msgstr "Recupero dei dettagli sull'utente terminato."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:176
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:276
+msgid "Successfully connected to Twitter."
+msgstr "Collegamento a Twitter avvenuto con successo."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
 msgid "Failed to fetch user details from Twitter. Reason: "
 msgstr "Impossibile recuperare i dettagli sull'utente da Twitter. Motivo: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:185
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:306
 msgid "Fetching friends from Twitter, please wait..."
 msgstr "Recupero degli amici da Twitter in corso, attendere."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:190
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:311
 msgid "Finished fetching friends."
 msgstr "Recupero degli amici terminato."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:193
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:314
 msgid "Failed to fetch friends from Twitter. Reason: "
 msgstr "Impossibile recuperare gli amici da Twitter. Motivo: "
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:454
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:588
 msgid "Twitter Commands"
 msgstr "Comandi di Twitter"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:504
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:632
+msgid "No pending authorization request!"
+msgstr "Nessuna richiesta d'autorizzazione in sospeso."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:653
+#, csharp-format
+msgid "Failed to authorize with Twitter: {0}"
+msgstr "Impossibile ottenere l'autorizzazione da Twitter: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:661
+msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
+msgstr ""
+"Twitter non ha accettato il PIN inserito. Controllare che sia stato inserito "
+"correttamente."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:669
+#, csharp-format
+msgid ""
+"Please retry by closing this tab and reconnecting to the Twitter \"{0}\" "
+"account."
+msgstr ""
+"Provare nuovamente chiudendo questa scheda e ricollegandosi all'account "
+"Twitter «{0}»."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:709
+msgid "Migrated Twitter account from basic auth to OAuth."
+msgstr "Account Twitter migrato da auth base a OAuth."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:722
+#, csharp-format
+msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
+msgstr "Autorizzazione dell'account Twitter «{0}» per Smuxi riuscita"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:744
 #, csharp-format
 msgid "Could not update status - Reason: {0}"
 msgstr "Impossibile aggiornare lo stato. Motivo: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:513
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:753
 msgid "Cannot send message - no target specified. Use: /msg $nick message"
 msgstr ""
 "Impossibile inviare il messaggio: nessun destinatario specificato. "
 "Utilizzare: /msg $nick messaggio"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:526
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:568
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:766
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:803
 #, csharp-format
 msgid "Could not send message - Reason: {0}"
 msgstr "Impossibile inviare il messaggio. Motivo: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:555
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:790
 msgid "Could not send message - the specified user does not exist."
 msgstr "Impossibile inviare il messaggio: l'utente specificato non esiste."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:631
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:879
 msgid ""
 "An error occurred while fetching the friends timeline from Twitter. Reason: "
 msgstr ""
 "Si è verificato un errore durante il recupero della cronologia degli amici "
 "da Twitter. Motivo: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:721
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:980
 msgid "An error occurred while fetching the replies from Twitter. Reason: "
 msgstr ""
 "Si è verificato un errore durante il recupero delle risposte da Twitter. "
 "Motivo: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:816
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1073
 msgid "An error occurred while fetching direct messages from Twitter. Reason: "
 msgstr ""
 "Si è verificato un errore durante il recupero dei messaggi diretti da "
 "Twitter. Motivo: "
+
+#~ msgid "Login failed!"
+#~ msgstr "Accesso non riuscito."
+
+#~ msgid "Login failed! Username and/or password are incorrect."
+#~ msgstr ""
+#~ "Accesso non riuscito: il nome utente o la password non sono corretti."
diff --git a/po-Engine-Twitter/pt.po b/po-Engine-Twitter/pt.po
index ba41e24..8c76f5d 100644
--- a/po-Engine-Twitter/pt.po
+++ b/po-Engine-Twitter/pt.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: smuxi-engine-twitter \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-15 01:42+0100\n"
+"POT-Creation-Date: 2010-09-11 11:54+0200\n"
+"PO-Revision-Date: 2010-09-08 01:44+0100\n"
 "Last-Translator: Américo Monteiro <a_monteiro at netcabo.pt>\n"
 "Language-Team: Portuguese <traduz at debianpt.org>\n"
 "Language: pt\n"
@@ -18,107 +18,163 @@ msgstr ""
 "X-Generator: Lokalize 1.0\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:101
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:125
 msgid "Home Timeline"
 msgstr "Timeline de Home"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:108
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:132
 msgid "Replies"
 msgstr "Respostas"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:115
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:139
 msgid "Direct Messages"
 msgstr "Mensagens Directas"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:133
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:174
 msgid "Connecting to Twitter..."
 msgstr "A ligar ao Twitter..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:141
-msgid "Login failed!"
-msgstr "Login falhado!"
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:203
+msgid "Twitter authorization required."
+msgstr "Necessária autorização do Twitter."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:143
-msgid "Login failed! Username and/or password are incorrect."
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:218
+#, csharp-format
+msgid ""
+"Please open the following URL and click \"Allow\" to allow Smuxi to connect "
+"to your Twitter account: {0}"
+msgstr ""
+"Por favor abra o seguinte URL e clique em \"Permitir\" (Allow) para permitir "
+"que o Smuxi se ligue à sua conta do Twitter: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:234
+msgid ""
+"Once you have allowed Smuxi to access your Twitter account, Twitter will "
+"provide a PIN."
 msgstr ""
-"Login falhado! O nome de utilizador e/ou a palavra-passe estão incorrectas."
+"Após ter permitido que o Smuxi tenha acesso à sua conta do Twitter, o "
+"Twitter irá fornecer um PIN."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:241
+msgid "Please type: /pin PIN_FROM_TWITTER"
+msgstr "Por favor escreva: /pin PIN_DO_TWITTER"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:149
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:251
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:291
 msgid "Connection failed!"
 msgstr "Ligação falhada!"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:151
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:253
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:293
 msgid "Connection failed! Reason: "
 msgstr "Ligação falhada! Razão: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:156
-msgid "Successfully connected to Twitter."
-msgstr "Ligação ao Twitter efectuada com sucesso."
-
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:164
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:266
 msgid "Fetching user details from Twitter, please wait..."
 msgstr ""
 "A obter detalhes do utilizador a partir do Twitter, por favor aguarde..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:169
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:271
 msgid "Finished fetching user details."
 msgstr "Obtenção de detalhes do utilizador terminada."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:176
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:276
+msgid "Successfully connected to Twitter."
+msgstr "Ligação ao Twitter efectuada com sucesso."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
 msgid "Failed to fetch user details from Twitter. Reason: "
 msgstr "Falhou ao obter os detalhes do utilizador a partir do Twitter. Razão: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:185
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:306
 msgid "Fetching friends from Twitter, please wait..."
 msgstr "A obter amigos a partir do Twitter, por favor aguarde..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:190
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:311
 msgid "Finished fetching friends."
 msgstr "Obtenção de amigos terminada."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:193
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:314
 msgid "Failed to fetch friends from Twitter. Reason: "
 msgstr "Falhou ao obter amigos a partir do Twitter. Razão: "
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:454
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:588
 msgid "Twitter Commands"
 msgstr "Comandos do Twitter"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:504
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:632
+msgid "No pending authorization request!"
+msgstr "Nenhum pedido de autorização pendente!"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:653
+#, csharp-format
+msgid "Failed to authorize with Twitter: {0}"
+msgstr "Falhou a autorização com o Twitter: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:661
+msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
+msgstr "O Twitter não aceitou o seu PIN. Você escreve-o correctamente?"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:669
+#, csharp-format
+msgid ""
+"Please retry by closing this tab and reconnecting to the Twitter \"{0}\" "
+"account."
+msgstr ""
+"Por favor tente de novo fechando este separador e ligando de novo à conta "
+"Twitter {0}."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:709
+msgid "Migrated Twitter account from basic auth to OAuth."
+msgstr "Conta Twitter migrada de autenticação básica para OAuth."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:722
+#, csharp-format
+msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
+msgstr "Conta Twitter {0} autorizada com sucesso para o Smuxi"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:744
 #, csharp-format
 msgid "Could not update status - Reason: {0}"
 msgstr "Incapaz de actualizar o estado - Razão: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:513
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:753
 msgid "Cannot send message - no target specified. Use: /msg $nick message"
 msgstr ""
 "Incapaz de enviar mensagem - nenhum destino especificado. Use: /msg $alcunha "
 "mensagem"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:526
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:568
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:766
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:803
 #, csharp-format
 msgid "Could not send message - Reason: {0}"
 msgstr "Incapaz de enviar mensagem - Razão: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:555
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:790
 msgid "Could not send message - the specified user does not exist."
 msgstr "Incapaz de enviar mensagem - o utilizador especificado não existe."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:631
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:879
 msgid ""
 "An error occurred while fetching the friends timeline from Twitter. Reason: "
 msgstr ""
 "Ocorreu um erro ao obter o timeline de amigos a partir do Twitter. Razão: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:721
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:980
 msgid "An error occurred while fetching the replies from Twitter. Reason: "
 msgstr "Ocorreu um erro ao obter as respostas a partir do Twitter. Razão: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:816
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1073
 msgid "An error occurred while fetching direct messages from Twitter. Reason: "
 msgstr ""
 "Ocorreu um erro ao obter as mensagens directas a partir do Twitter. Razão: "
 
+#~ msgid "Login failed!"
+#~ msgstr "Login falhado!"
+
+#~ msgid "Login failed! Username and/or password are incorrect."
+#~ msgstr ""
+#~ "Login falhado! O nome de utilizador e/ou a palavra-passe estão "
+#~ "incorrectas."
diff --git a/po-Engine-Twitter/ru.po b/po-Engine-Twitter/ru.po
new file mode 100644
index 0000000..463e943
--- /dev/null
+++ b/po-Engine-Twitter/ru.po
@@ -0,0 +1,163 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: Russian (http://www.transifex.net/projects/p/smuxi/team/ru/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ru\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:125
+msgid "Home Timeline"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:132
+msgid "Replies"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:139
+msgid "Direct Messages"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:174
+msgid "Connecting to Twitter..."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:203
+msgid "Twitter authorization required."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:218
+#, csharp-format
+msgid ""
+"Please open the following URL and click \"Allow\" to allow Smuxi to connect "
+"to your Twitter account: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:234
+msgid ""
+"Once you have allowed Smuxi to access your Twitter account, Twitter will "
+"provide a PIN."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:241
+msgid "Please type: /pin PIN_FROM_TWITTER"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:251
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:291
+msgid "Connection failed!"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:253
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:293
+msgid "Connection failed! Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:266
+msgid "Fetching user details from Twitter, please wait..."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:271
+msgid "Finished fetching user details."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:276
+msgid "Successfully connected to Twitter."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
+msgid "Failed to fetch user details from Twitter. Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:306
+msgid "Fetching friends from Twitter, please wait..."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:311
+msgid "Finished fetching friends."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:314
+msgid "Failed to fetch friends from Twitter. Reason: "
+msgstr ""
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:588
+msgid "Twitter Commands"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:632
+msgid "No pending authorization request!"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:653
+#, csharp-format
+msgid "Failed to authorize with Twitter: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:661
+msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:669
+#, csharp-format
+msgid ""
+"Please retry by closing this tab and reconnecting to the Twitter \"{0}\" "
+"account."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:709
+msgid "Migrated Twitter account from basic auth to OAuth."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:722
+#, csharp-format
+msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:744
+#, csharp-format
+msgid "Could not update status - Reason: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:753
+msgid "Cannot send message - no target specified. Use: /msg $nick message"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:766
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:803
+#, csharp-format
+msgid "Could not send message - Reason: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:790
+msgid "Could not send message - the specified user does not exist."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:879
+msgid ""
+"An error occurred while fetching the friends timeline from Twitter. Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:980
+msgid "An error occurred while fetching the replies from Twitter. Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1073
+msgid ""
+"An error occurred while fetching direct messages from Twitter. Reason: "
+msgstr ""
+
+
diff --git a/po-Engine-Twitter/sk.po b/po-Engine-Twitter/sk.po
new file mode 100644
index 0000000..acd19b6
--- /dev/null
+++ b/po-Engine-Twitter/sk.po
@@ -0,0 +1,179 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Tomáš Vadina <kyberdev at gmail.com>, 2011.
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2011-09-30 08:37+0000\n"
+"Last-Translator: Tomáš Vadina <kyberdev at gmail.com>\n"
+"Language-Team: Slovak (http://www.transifex.net/projects/p/smuxi/team/sk/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: sk\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:125
+msgid "Home Timeline"
+msgstr "Domovské časové pásmo"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:132
+msgid "Replies"
+msgstr "Odpovede"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:139
+msgid "Direct Messages"
+msgstr "Priame správy"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:174
+msgid "Connecting to Twitter..."
+msgstr "Pripájanie na Twitter..."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:203
+msgid "Twitter authorization required."
+msgstr "Vyžadované overenie Twitter."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:218
+#, csharp-format
+msgid ""
+"Please open the following URL and click \"Allow\" to allow Smuxi to connect "
+"to your Twitter account: {0}"
+msgstr ""
+"Prosím otvorte nasledujúcu URL adresu a kliknite na \"Povoliť\" pre "
+"povolenie pripojiť sa Smuxi na váš Twitter účet: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:234
+msgid ""
+"Once you have allowed Smuxi to access your Twitter account, Twitter will "
+"provide a PIN."
+msgstr ""
+"Akonáhle povolíte Smuxi prístup k vášmu Twitter účtu, Twitter poskytne "
+"bezpečnostný kód PIN."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:241
+msgid "Please type: /pin PIN_FROM_TWITTER"
+msgstr "Prosím zadajte: /pin PIN_Z_TWITTER_ÚČTU"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:251
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:291
+msgid "Connection failed!"
+msgstr "Pripojenie zlyhalo!"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:253
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:293
+msgid "Connection failed! Reason: "
+msgstr "Pripojenie zlyhalo! Príčina: "
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:266
+msgid "Fetching user details from Twitter, please wait..."
+msgstr ""
+"Prebieha príjem podrobností o používateľovi služby Twitter, čakajte "
+"prosím..."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:271
+msgid "Finished fetching user details."
+msgstr "Príjem podrobností o používateľovi dokončený."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:276
+msgid "Successfully connected to Twitter."
+msgstr "Pripojenie k službe Twitter prebehlo úspešne."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
+msgid "Failed to fetch user details from Twitter. Reason: "
+msgstr ""
+"Príjem podrobností o používateľovi zo služby Twitter zlyhal. Príčina: "
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:306
+msgid "Fetching friends from Twitter, please wait..."
+msgstr ""
+"Prebieha príjem zoznamu priateľov zo služby Twitter, čakajte prosím..."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:311
+msgid "Finished fetching friends."
+msgstr "Príjem zoznamu priateľov dokončený."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:314
+msgid "Failed to fetch friends from Twitter. Reason: "
+msgstr "Príjem zoznamu priateľov zo služby Twitter zlyhal. Príčina: "
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:588
+msgid "Twitter Commands"
+msgstr "Príkazy služby Twitter"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:632
+msgid "No pending authorization request!"
+msgstr "Žiadne nevybavené overovacie požiadavky!"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:653
+#, csharp-format
+msgid "Failed to authorize with Twitter: {0}"
+msgstr "Overenie so službou Twitter zlyhalo: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:661
+msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
+msgstr "Služba Twitter neprijala zadané PIN.  Zadali ste ho správne?"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:669
+#, csharp-format
+msgid ""
+"Please retry by closing this tab and reconnecting to the Twitter \"{0}\" "
+"account."
+msgstr ""
+"Prosím opakujte zatvorením tejto karty a znovupripojením k účtu služby "
+"Twitter \"{0}\"."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:709
+msgid "Migrated Twitter account from basic auth to OAuth."
+msgstr "Presunutý účet služby Twitter zo základného overovania na OAuth."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:722
+#, csharp-format
+msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
+msgstr "Overenie účtu služby Twitter \"{0}\" pre Smuxi prebehlo úspešne."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:744
+#, csharp-format
+msgid "Could not update status - Reason: {0}"
+msgstr "Nie je možné aktualizovať stav - Príčina: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:753
+msgid "Cannot send message - no target specified. Use: /msg $nick message"
+msgstr ""
+"Nie je možné odoslať správu - nebol zadaný príjemca. Použite: /msg $prezývka"
+" správa"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:766
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:803
+#, csharp-format
+msgid "Could not send message - Reason: {0}"
+msgstr "Nie je možné odoslať správu - Príčina: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:790
+msgid "Could not send message - the specified user does not exist."
+msgstr "Nie je možné odoslať správu - zadaný používateľ neexistuje."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:879
+msgid ""
+"An error occurred while fetching the friends timeline from Twitter. Reason: "
+msgstr ""
+"Počas príjmu časového pásma priateľov zo služby Twitter nastala chyba. "
+"Príčina: "
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:980
+msgid "An error occurred while fetching the replies from Twitter. Reason: "
+msgstr "Počas príjmu odpovedí zo služby Twitter nastala chyba. Príčina: "
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1073
+msgid ""
+"An error occurred while fetching direct messages from Twitter. Reason: "
+msgstr ""
+"Počas príjmu priamych správ zo služby Twitter nastala chyba. Príčina: "
+
+
diff --git a/po-Engine-Twitter/sv.po b/po-Engine-Twitter/sv.po
index d6951e9..966ae26 100644
--- a/po-Engine-Twitter/sv.po
+++ b/po-Engine-Twitter/sv.po
@@ -1,117 +1,180 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-#
-# Martin Bagge <brother at bsnet.se>, 2009
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+#   <flugsio at gmail.com>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: Smuxi Engine Twitter\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-15 13:12+0100\n"
-"Last-Translator: Martin Bagge / brother <brother at bsnet.se>\n"
-"Language-Team: Swedish <tp-sv at listor.tp-sv.se>\n"
-"Language: sv\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:20+0100\n"
+"PO-Revision-Date: 2011-12-31 11:10+0000\n"
+"Last-Translator: flugsio <flugsio at gmail.com>\n"
+"Language-Team: Swedish (http://www.transifex.net/projects/p/smuxi/team/sv/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: Swedish\n"
-"X-Poedit-Country: Sweden\n"
+"Language: sv\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:101
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:124
 msgid "Home Timeline"
 msgstr "Hem Tidslinje"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:108
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:135
 msgid "Replies"
 msgstr "Svar"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:115
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:146
 msgid "Direct Messages"
 msgstr "Direktmeddelanden"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:133
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:189
 msgid "Connecting to Twitter..."
 msgstr "Ansluter till Twitter..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:141
-msgid "Login failed!"
-msgstr "Inloggning misslyckades!"
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:228
+msgid "Twitter authorization required."
+msgstr "Inloggning till Twitter krävs."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:235
+#, csharp-format
+msgid ""
+"Please open the following URL and click \"Allow\" to allow Smuxi to connect "
+"to your Twitter account: {0}"
+msgstr ""
+"Vänligen öppna följande URL och klicka \"Godkänn\" för att tillåta Smuxi att"
+" ansluta till ditt Twitterkonto: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:251
+msgid ""
+"Once you have allowed Smuxi to access your Twitter account, Twitter will "
+"provide a PIN."
+msgstr ""
+"När du tillåtit Smuxi tillgång till ditt Twitterkonto, kommer Twitter att "
+"tillhandhålla en PIN-kod."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:143
-msgid "Login failed! Username and/or password are incorrect."
-msgstr "Inloggning misslyckades! Användarnamn och/eller lösenord var felaktigt."
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:258
+msgid "Please type: /pin PIN_FROM_TWITTER"
+msgstr "Vänligen skriv: /pin PIN_KOD_FRÅN_TWITTER"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:149
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:265
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:305
 msgid "Connection failed!"
 msgstr "Anslutning misslyckades!"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:151
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:267
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:307
 msgid "Connection failed! Reason: "
 msgstr "Anslutning misslyckades! Anledning: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:156
-msgid "Successfully connected to Twitter."
-msgstr "Ansluten till Twitter."
-
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:164
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:280
 msgid "Fetching user details from Twitter, please wait..."
 msgstr "Hämtar användarinformation från Twitter. Vänligen vänta..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:169
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
 msgid "Finished fetching user details."
 msgstr "Hämtade användarinformation."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:176
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:290
+msgid "Successfully connected to Twitter."
+msgstr "Ansluten till Twitter."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:299
 msgid "Failed to fetch user details from Twitter. Reason: "
-msgstr "Misslyckades med att hämta användarinformation från Twitter. Anledning: "
+msgstr ""
+"Misslyckades med att hämta användarinformation från Twitter. Anledning: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:185
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:320
 msgid "Fetching friends from Twitter, please wait..."
 msgstr "Hämtar vänner från Twitter. Vänligen vänta..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:190
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:325
 msgid "Finished fetching friends."
 msgstr "Hämtade vänner."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:193
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:328
 msgid "Failed to fetch friends from Twitter. Reason: "
 msgstr "Misslyckades med att hämta vänner från Twitter. Anledning: "
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:454
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:605
 msgid "Twitter Commands"
 msgstr "Twitter-kommandon"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:504
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:647
+msgid "No pending authorization request!"
+msgstr "Ingen pågående auktoriseringsansökan!"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:668
+#, csharp-format
+msgid "Failed to authorize with Twitter: {0}"
+msgstr "Misslyckades att autorisera med Twitter: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:676
+msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
+msgstr "Twitter accepterade inte din PIN-kod.  Angav du den korrekt?"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:684
+#, csharp-format
+msgid ""
+"Please retry by closing this tab and reconnecting to the Twitter \"{0}\" "
+"account."
+msgstr ""
+"Vänligen försök igen genom att stänga denna flik och återansluta till "
+"Twitterkontot \"{0}\"."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:725
+msgid "Migrated Twitter account from basic auth to OAuth."
+msgstr "Migrerade Twitterkontot från enkel auktorisering till OAuth."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:739
+#, csharp-format
+msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
+msgstr "Lyckades att auktorisera Twitterkontot \"{0}\" för Smuxi"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:761
 #, csharp-format
 msgid "Could not update status - Reason: {0}"
 msgstr "Kunde inte uppdatera status - Anledning: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:513
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:770
 msgid "Cannot send message - no target specified. Use: /msg $nick message"
-msgstr "Kan inte skicka meddelande - inget mål specificerades. Använd /msg $nick meddelande"
+msgstr ""
+"Kan inte skicka meddelande - inget mål specificerades. Använd /msg $nick "
+"meddelande"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:526
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:568
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:783
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:820
 #, csharp-format
 msgid "Could not send message - Reason: {0}"
 msgstr "Kunde inte skicka meddelande - Anledning: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:555
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:807
 msgid "Could not send message - the specified user does not exist."
-msgstr "Kunde inte skicka meddelande - den specificerade användaren hittades inte."
+msgstr ""
+"Kunde inte skicka meddelande - den specificerade användaren hittades inte."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:631
-msgid "An error occurred while fetching the friends timeline from Twitter. Reason: "
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:896
+msgid ""
+"An error occurred while fetching the friends timeline from Twitter. Reason: "
 msgstr "Ett fel uppstod vid hämtning av kvitter från dina vänner. Anledning: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:721
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1001
 msgid "An error occurred while fetching the replies from Twitter. Reason: "
 msgstr "Ett fel uppstod vid hämtning av svar från Twitter. Anledning: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:816
-msgid "An error occurred while fetching direct messages from Twitter. Reason: "
-msgstr "Ett fel uppstod vid hämtning av direktmeddelanden från Twitter. Anledning: "
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1097
+msgid ""
+"An error occurred while fetching direct messages from Twitter. Reason: "
+msgstr ""
+"Ett fel uppstod vid hämtning av direktmeddelanden från Twitter. Anledning: "
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1441
+msgid "Twitter didn't send a valid response, they're probably overloaded"
+msgstr ""
+"Twitter skickade inte ett giltigt svar, de är antagligen överbelastade"
+
 
diff --git a/po-Engine-Twitter/tr.po b/po-Engine-Twitter/tr.po
new file mode 100644
index 0000000..9f8c024
--- /dev/null
+++ b/po-Engine-Twitter/tr.po
@@ -0,0 +1,163 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: Turkish (http://www.transifex.net/projects/p/smuxi/team/tr/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: tr\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:125
+msgid "Home Timeline"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:132
+msgid "Replies"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:139
+msgid "Direct Messages"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:174
+msgid "Connecting to Twitter..."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:203
+msgid "Twitter authorization required."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:218
+#, csharp-format
+msgid ""
+"Please open the following URL and click \"Allow\" to allow Smuxi to connect "
+"to your Twitter account: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:234
+msgid ""
+"Once you have allowed Smuxi to access your Twitter account, Twitter will "
+"provide a PIN."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:241
+msgid "Please type: /pin PIN_FROM_TWITTER"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:251
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:291
+msgid "Connection failed!"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:253
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:293
+msgid "Connection failed! Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:266
+msgid "Fetching user details from Twitter, please wait..."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:271
+msgid "Finished fetching user details."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:276
+msgid "Successfully connected to Twitter."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
+msgid "Failed to fetch user details from Twitter. Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:306
+msgid "Fetching friends from Twitter, please wait..."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:311
+msgid "Finished fetching friends."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:314
+msgid "Failed to fetch friends from Twitter. Reason: "
+msgstr ""
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:588
+msgid "Twitter Commands"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:632
+msgid "No pending authorization request!"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:653
+#, csharp-format
+msgid "Failed to authorize with Twitter: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:661
+msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:669
+#, csharp-format
+msgid ""
+"Please retry by closing this tab and reconnecting to the Twitter \"{0}\" "
+"account."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:709
+msgid "Migrated Twitter account from basic auth to OAuth."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:722
+#, csharp-format
+msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:744
+#, csharp-format
+msgid "Could not update status - Reason: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:753
+msgid "Cannot send message - no target specified. Use: /msg $nick message"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:766
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:803
+#, csharp-format
+msgid "Could not send message - Reason: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:790
+msgid "Could not send message - the specified user does not exist."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:879
+msgid ""
+"An error occurred while fetching the friends timeline from Twitter. Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:980
+msgid "An error occurred while fetching the replies from Twitter. Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1073
+msgid ""
+"An error occurred while fetching direct messages from Twitter. Reason: "
+msgstr ""
+
+
diff --git a/po-Engine-Twitter/ur.po b/po-Engine-Twitter/ur.po
new file mode 100644
index 0000000..9566bcf
--- /dev/null
+++ b/po-Engine-Twitter/ur.po
@@ -0,0 +1,163 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: Urdu (http://www.transifex.net/projects/p/smuxi/team/ur/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ur\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:125
+msgid "Home Timeline"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:132
+msgid "Replies"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:139
+msgid "Direct Messages"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:174
+msgid "Connecting to Twitter..."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:203
+msgid "Twitter authorization required."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:218
+#, csharp-format
+msgid ""
+"Please open the following URL and click \"Allow\" to allow Smuxi to connect "
+"to your Twitter account: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:234
+msgid ""
+"Once you have allowed Smuxi to access your Twitter account, Twitter will "
+"provide a PIN."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:241
+msgid "Please type: /pin PIN_FROM_TWITTER"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:251
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:291
+msgid "Connection failed!"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:253
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:293
+msgid "Connection failed! Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:266
+msgid "Fetching user details from Twitter, please wait..."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:271
+msgid "Finished fetching user details."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:276
+msgid "Successfully connected to Twitter."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
+msgid "Failed to fetch user details from Twitter. Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:306
+msgid "Fetching friends from Twitter, please wait..."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:311
+msgid "Finished fetching friends."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:314
+msgid "Failed to fetch friends from Twitter. Reason: "
+msgstr ""
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:588
+msgid "Twitter Commands"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:632
+msgid "No pending authorization request!"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:653
+#, csharp-format
+msgid "Failed to authorize with Twitter: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:661
+msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:669
+#, csharp-format
+msgid ""
+"Please retry by closing this tab and reconnecting to the Twitter \"{0}\" "
+"account."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:709
+msgid "Migrated Twitter account from basic auth to OAuth."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:722
+#, csharp-format
+msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:744
+#, csharp-format
+msgid "Could not update status - Reason: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:753
+msgid "Cannot send message - no target specified. Use: /msg $nick message"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:766
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:803
+#, csharp-format
+msgid "Could not send message - Reason: {0}"
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:790
+msgid "Could not send message - the specified user does not exist."
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:879
+msgid ""
+"An error occurred while fetching the friends timeline from Twitter. Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:980
+msgid "An error occurred while fetching the replies from Twitter. Reason: "
+msgstr ""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1073
+msgid ""
+"An error occurred while fetching direct messages from Twitter. Reason: "
+msgstr ""
+
+
diff --git a/po-Engine-Twitter/zh_CN.po b/po-Engine-Twitter/zh_CN.po
new file mode 100644
index 0000000..0bb2246
--- /dev/null
+++ b/po-Engine-Twitter/zh_CN.po
@@ -0,0 +1,168 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Dean Lee <xslidian at gmail.com>, 2011.
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:20+0100\n"
+"PO-Revision-Date: 2011-12-30 15:58+0000\n"
+"Last-Translator: Dean Lee <xslidian at gmail.com>\n"
+"Language-Team: Chinese (China) (http://www.transifex.net/projects/p/smuxi/team/zh_CN/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: zh_CN\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:124
+msgid "Home Timeline"
+msgstr "主时间线"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:135
+msgid "Replies"
+msgstr "回复"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:146
+msgid "Direct Messages"
+msgstr "私信"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:189
+msgid "Connecting to Twitter..."
+msgstr "正在连接到 Twitter..."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:228
+msgid "Twitter authorization required."
+msgstr "需要 Twitter 认证。"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:235
+#, csharp-format
+msgid ""
+"Please open the following URL and click \"Allow\" to allow Smuxi to connect "
+"to your Twitter account: {0}"
+msgstr "请打开下面的 URL 并点击“允许”授权 Smuxi 连接您的 Twitter 账户: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:251
+msgid ""
+"Once you have allowed Smuxi to access your Twitter account, Twitter will "
+"provide a PIN."
+msgstr "在您允许 Smuxi 访问您的 Twitter 账户后,Twitter 将提供 PIN。"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:258
+msgid "Please type: /pin PIN_FROM_TWITTER"
+msgstr "请输入: /pin TWITTER_给您的_PIN"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:265
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:305
+msgid "Connection failed!"
+msgstr "连接失败!"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:267
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:307
+msgid "Connection failed! Reason: "
+msgstr "连接失败! 原因: "
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:280
+msgid "Fetching user details from Twitter, please wait..."
+msgstr "正在从 Twitter 装载用户详细信息,请稍候..."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
+msgid "Finished fetching user details."
+msgstr "装载用户详细信息完成。"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:290
+msgid "Successfully connected to Twitter."
+msgstr "成功连接到 Twitter。"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:299
+msgid "Failed to fetch user details from Twitter. Reason: "
+msgstr "从 Twitter 装载用户详细信息失败。原因: "
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:320
+msgid "Fetching friends from Twitter, please wait..."
+msgstr "正在从 Twitter 装载好友,请稍候..."
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:325
+msgid "Finished fetching friends."
+msgstr "装载好友完成。"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:328
+msgid "Failed to fetch friends from Twitter. Reason: "
+msgstr "从 Twitter 装载好友失败。原因: "
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:605
+msgid "Twitter Commands"
+msgstr "Twitter 命令"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:647
+msgid "No pending authorization request!"
+msgstr "无待处理的认证请求!"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:668
+#, csharp-format
+msgid "Failed to authorize with Twitter: {0}"
+msgstr "Twitter 认证失败: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:676
+msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
+msgstr "Twitter 不接受您提供的 PIN。您是否已经正确输入?"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:684
+#, csharp-format
+msgid ""
+"Please retry by closing this tab and reconnecting to the Twitter \"{0}\" "
+"account."
+msgstr "请关闭本标签,重新连接 Twitter \"{0}\" 账户再次尝试。"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:725
+msgid "Migrated Twitter account from basic auth to OAuth."
+msgstr "Twitter 账户已从 basic auth 迁移至 OAuth。"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:739
+#, csharp-format
+msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
+msgstr "Smuxi 成功认证 Twitter 账户 \"{0}\""
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:761
+#, csharp-format
+msgid "Could not update status - Reason: {0}"
+msgstr "无法更新状态 - 原因: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:770
+msgid "Cannot send message - no target specified. Use: /msg $nick message"
+msgstr "无法发送信息 - 未指定目标。用法: /msg $昵称 信息"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:783
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:820
+#, csharp-format
+msgid "Could not send message - Reason: {0}"
+msgstr "无法发送信息 - 原因: {0}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:807
+msgid "Could not send message - the specified user does not exist."
+msgstr "无法发送信息 - 指定用户不存在。"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:896
+msgid ""
+"An error occurred while fetching the friends timeline from Twitter. Reason: "
+msgstr "从 Twitter 装载好友时间线失败。原因: "
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1001
+msgid "An error occurred while fetching the replies from Twitter. Reason: "
+msgstr "从 Twitter 装载回复失败。原因: "
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1097
+msgid ""
+"An error occurred while fetching direct messages from Twitter. Reason: "
+msgstr "从 Twitter 装载私信失败。原因: "
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1441
+msgid "Twitter didn't send a valid response, they're probably overloaded"
+msgstr "Twitter 所发送的响应无效,该网站可能处于过载状态"
+
+
diff --git a/po-Engine/LINGUAS b/po-Engine/LINGUAS
index c6a7441..b7b7ab8 100644
--- a/po-Engine/LINGUAS
+++ b/po-Engine/LINGUAS
@@ -7,4 +7,9 @@ es_AR
 fr
 it
 pt
+ru
+sk
 sv
+tr
+ur
+zh_CN
diff --git a/po-Engine/POTFILES.in b/po-Engine/POTFILES.in
index 95ebddf..ad95f14 100644
--- a/po-Engine/POTFILES.in
+++ b/po-Engine/POTFILES.in
@@ -1,5 +1,7 @@
 src/Engine/FrontendManager.cs
+src/Engine/MessageBuffers/Db4oMessageBuffer.cs
 src/Engine/Protocols/ProtocolManagerBase.cs
 src/Engine/Session.cs
 src/Engine/Config/UserListController.cs
 src/Engine/Config/ServerListController.cs
+src/Engine/Chats/ChatModel.cs
diff --git a/po-Engine/POTFILES.skip b/po-Engine/POTFILES.skip
index 737e333..7f8925d 100644
--- a/po-Engine/POTFILES.skip
+++ b/po-Engine/POTFILES.skip
@@ -3,6 +3,7 @@ src/Common/
 src/Frontend/
 src/Frontend-GNOME/
 src/Frontend-GNOME-IRC/
+src/Frontend-STFL/
 src/Frontend-SWF/
 src/Frontend-WPF/
 src/Engine-IRC/
@@ -11,3 +12,4 @@ src/Engine-OSCAR/
 src/Engine-XMPP/
 src/Engine-Twitter/
 src/Server/
+lib/
diff --git a/po-Engine/da.po b/po-Engine/da.po
index 3d0a103..6434c87 100644
--- a/po-Engine/da.po
+++ b/po-Engine/da.po
@@ -1,145 +1,179 @@
-# Danish translation smuxi-engine.
-# Copyright (C) 2010 smuxi-engine & nedenstående oversættere.
-# This file is distributed under the same license as the smuxi-engine package.
-# Bjarke Sørensen <bs at wasd.dk>, 2006.
-# Joe Hansen (joedalton2 at yahoo.dk), 2010.
-#
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Joe Hansen <joedalton2 at yahoo.dk>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: smuxi-engine\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-08-05 01:46+0200\n"
-"PO-Revision-Date: 2010-08-14 12:42+0000\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:19+0100\n"
+"PO-Revision-Date: 2011-12-29 19:56+0000\n"
 "Last-Translator: Joe Hansen <joedalton2 at yahoo.dk>\n"
-"Language-Team: Danish <debian-l10n-danish at lists.debian.org>\n"
+"Language-Team: Danish (http://www.transifex.net/projects/p/smuxi/team/da/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: da\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Engine/FrontendManager.cs:223
+#: ../src/Engine/FrontendManager.cs:233
 msgid "No network connections"
 msgstr "Ingen netværksforbindelser"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:146
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:295
+#, csharp-format
+msgid "Optimizing: {0}..."
+msgstr "Optimerer: {0}..."
+
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:313
+#, csharp-format
+msgid "Failed to optimize: {0}. Reason: {1}"
+msgstr "Kunne ikke optimere: {0}. Ã…rsag: {1}"
+
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:347
+msgid ""
+"Your chat history is no longer available because of an error but will be "
+"preserved from now on."
+msgstr ""
+"Din snakkehistorik er ikke længere tilgængelig på grund af en fejl, men den "
+"vil blive gemt fremadrettet."
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:170
 msgid "Not connected to server"
 msgstr "Ikke forbundet til server"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:158
-#: ../src/Engine/Session.cs:736
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:178
+#: ../src/Engine/Session.cs:778
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Ikke nok parametre for kommandoen {0}"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:174
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
 #, csharp-format
 msgid "Connected to {0}"
 msgstr "Forbundet til {0}"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:196
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:207
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Ikke længere forbundet til {0}"
 
-#: ../src/Engine/Session.cs:154
-msgid "Welcome to Smuxi"
-msgstr "Velkommen til Smuxi"
-
-#: ../src/Engine/Session.cs:160
-msgid "Type /help to get a list of available commands."
-msgstr "Tast /help for en liste over tilgængelige kommandoer."
-
-#: ../src/Engine/Session.cs:163
-msgid ""
-"After you have made a connection the list of available commands changes. Use "
-"the /help command again to see the extended command list."
-msgstr ""
-"Efter du har foretaget en tilslutning ændres listen over tilgængelige "
-"kommandoer. Brug kommandoen /help igen for at se den udvidede kommandoliste."
-
-#: ../src/Engine/Session.cs:216
+#: ../src/Engine/Session.cs:218
 #, csharp-format
 msgid "Automatic connect to {0} failed!"
 msgstr "Automatisk tilslutning til {0} mislykkedes!"
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Engine/Session.cs:407
+#: ../src/Engine/Session.cs:416
 msgid "Engine Commands"
 msgstr "Motorkommandoer"
 
-#: ../src/Engine/Session.cs:510
+#: ../src/Engine/Session.cs:527
 msgid "Connect failed!"
 msgstr "Tilslutning mislykkedes!"
 
-#: ../src/Engine/Session.cs:540
+#: ../src/Engine/Session.cs:550
 #, csharp-format
 msgid "Disconnect failed - could not find server: {0}"
 msgstr "Afbrydelse fejlede - kunne ikke finde server: {0}"
 
-#: ../src/Engine/Session.cs:579
+#: ../src/Engine/Session.cs:589
 msgid "Reconnect failed!"
 msgstr "Gentilslutning mislykkedes!"
 
-#: ../src/Engine/Session.cs:598
+#: ../src/Engine/Session.cs:608
 msgid "Configuration reloaded"
 msgstr "Konfiguration genindlæst"
 
-#: ../src/Engine/Session.cs:603
+#: ../src/Engine/Session.cs:613
 msgid "Configuration saved"
 msgstr "Konfiguration gemt"
 
-#: ../src/Engine/Session.cs:607
+#: ../src/Engine/Session.cs:617
 msgid "Invalid parameter for config; use load or save"
 msgstr "Ugyldigt parameter for konfig; brug load (indlæs) eller save (gem)"
 
-#: ../src/Engine/Session.cs:637
+#: ../src/Engine/Session.cs:676
 msgid "Invalid parameter for network; use list, switch, or close"
 msgstr ""
 "Ugyldigt parameter for netværk; brug list (vis), switch (skift) eller close "
 "(luk)"
 
-#: ../src/Engine/Session.cs:648
+#: ../src/Engine/Session.cs:687
 msgid "Networks"
 msgstr "Netværk"
 
-#: ../src/Engine/Session.cs:652
-msgid "Type"
-msgstr "Type"
+#: ../src/Engine/Session.cs:691
+msgid "Protocol"
+msgstr "Protokol"
+
+#: ../src/Engine/Session.cs:692
+msgid "Network"
+msgstr "Netværk"
 
-#: ../src/Engine/Session.cs:653
+#: ../src/Engine/Session.cs:693
 msgid "Host"
 msgstr "Vært"
 
-#: ../src/Engine/Session.cs:654
+#: ../src/Engine/Session.cs:694
 msgid "Port"
 msgstr "Port"
 
-#: ../src/Engine/Session.cs:676
+#: ../src/Engine/Session.cs:709
 #, csharp-format
-msgid "Network close failed - could not find network with host: {0}"
-msgstr ""
-"Lukning af netværk mislykkedes - kunne ikke finde netværk med vært: {0}"
+msgid "Network close failed - could not find network: {0}"
+msgstr "Lukning af netværk fejlede - kunne ikke finde netværk: {0}"
 
-#: ../src/Engine/Session.cs:710
+#: ../src/Engine/Session.cs:748
 #, csharp-format
-msgid "Network switch failed - could not find network with host: {0}"
-msgstr "Skift af netværk mislykkedes - kunne ikke finde netværk med vært: {0}"
+msgid "Network switch failed - could not find network: {0}"
+msgstr "Netværksomskifter fejlede - kunne ikke finde netværk: {0}"
 
-#: ../src/Engine/Session.cs:725
+#: ../src/Engine/Session.cs:767
 msgid "Not connected to any network"
 msgstr "Ikke tilsluttet til noget netværk"
 
+#: ../src/Engine/Session.cs:1013
+#, csharp-format
+msgid ""
+"Failed to write to chat history. Your chat history will not be preserved. "
+"Reason: {0}"
+msgstr ""
+"Kunne ikke skrive snakkehistorik. Din snakkehistorik vil ikke blive gemt. "
+"Ã…rsag: {0}"
+
 #. just in case the ProtocolManager is not setting the
 #. protocol chat
-#: ../src/Engine/Session.cs:1052
+#: ../src/Engine/Session.cs:1185
 msgid "Connect failed."
 msgstr "Tilslutning mislykkedes."
 
-#: ../src/Engine/Session.cs:1083
+#: ../src/Engine/Session.cs:1216
 #, csharp-format
 msgid "No protocol manager found for the protocol: {0}"
 msgstr "Ingen protokolhåndtering fundet til denne protokol: {0}"
 
+#: ../src/Engine/Session.cs:1448
+msgid "Welcome to Smuxi"
+msgstr "Velkommen til Smuxi"
+
+#: ../src/Engine/Session.cs:1455
+msgid "Type /help to get a list of available commands."
+msgstr "Tast /help for en liste over tilgængelige kommandoer."
+
+#: ../src/Engine/Session.cs:1461
+msgid ""
+"After you have made a connection the list of available commands changes. Go "
+"to the newly opened connection tab and use the /help command again to see "
+"the extended command list."
+msgstr ""
+"Efter du har foretaget en forbindelsen så ændres listen over tilgængelige "
+"kommandoer. Gå til det netop åbnede forbindelsesfaneblad og brug kommandoen "
+"/help igen for at se den udvidede kommandoliste."
+
 #: ../src/Engine/Config/UserListController.cs:117
 msgid "Username must not be empty."
 msgstr "Brugernavn må ikke være tomt."
@@ -158,4 +192,17 @@ msgstr "Bruger »{0}« findes ikke."
 msgid "User \"{0}\" already exists."
 msgstr "Bruger »{0}« findes allerede."
 
+#: ../src/Engine/Config/ServerListController.cs:131
+msgid "Server hostname must not be empty."
+msgstr "Serverværtsnavn må ikke være tomt."
+
+#: ../src/Engine/Config/ServerListController.cs:134
+msgid "Server hostname contains invalid characters (newline)."
+msgstr "Serverværtsnavn indeholder ugyldige tegn (nylinje)."
+
+#: ../src/Engine/Config/ServerListController.cs:140
+#, csharp-format
+msgid "Server '{0}' already exists."
+msgstr "Server '{0}' findes allerede."
+
 
diff --git a/po-Engine/de.po b/po-Engine/de.po
index 501d067..313ea7b 100644
--- a/po-Engine/de.po
+++ b/po-Engine/de.po
@@ -1,138 +1,185 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-# Mirco Bauer <meebey at meebey.net>, 2008-2009.
-# Bianca Mix <heavydemon at freenet.de>, 2010
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
 # 
+# Translators:
+# Bianca Mix <heavydemon at freenet.de>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: 0.6.0\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-08-05 01:46+0200\n"
-"PO-Revision-Date: 2010-01-10 23:54+0100\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:19+0100\n"
+"PO-Revision-Date: 2011-12-30 22:34+0000\n"
 "Last-Translator: Bianca Mix <heavydemon at freenet.de>\n"
-"Language-Team: German Localization <debian-l10n-german at lists.debian.org>\n"
+"Language-Team: German (http://www.transifex.net/projects/p/smuxi/team/de/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: de\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Engine/FrontendManager.cs:223
+#: ../src/Engine/FrontendManager.cs:233
 msgid "No network connections"
 msgstr "Keine Netzwerkverbindungen"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:146
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:295
+#, csharp-format
+msgid "Optimizing: {0}..."
+msgstr "Optimiere: {0}..."
+
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:313
+#, csharp-format
+msgid "Failed to optimize: {0}. Reason: {1}"
+msgstr "Optimierung fehlgeschlagen: {0}. Grund: {1}"
+
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:347
+msgid ""
+"Your chat history is no longer available because of an error but will be "
+"preserved from now on."
+msgstr ""
+"Ihr Gesprächsverlauf ist auf Grund eines Fehlers nicht länger verfügbar, er "
+"wird aber von fortan vorgehalten."
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:170
 msgid "Not connected to server"
 msgstr "Nicht mit dem Server verbunden"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:158
-#: ../src/Engine/Session.cs:736
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:178
+#: ../src/Engine/Session.cs:778
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Nicht genügend Parameter für den Befehl: {0}"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:174
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
 #, csharp-format
 msgid "Connected to {0}"
 msgstr "Verbunden zu {0}"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:196
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:207
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Getrennt von {0}"
 
-#: ../src/Engine/Session.cs:154
-msgid "Welcome to Smuxi"
-msgstr "Willkommen bei Smuxi"
-
-#: ../src/Engine/Session.cs:160
-msgid "Type /help to get a list of available commands."
-msgstr "Geben Sie /help ein, um eine Liste der verfügbaren Befehle zu erhalten."
-
-#: ../src/Engine/Session.cs:163
-msgid "After you have made a connection the list of available commands changes. Use the /help command again to see the extended command list."
-msgstr "Nach dem Verbindungsaufbau stehen Ihnen weitere Befehle zur Verfügung. Verwenden Sie Befehl /help einfach erneut, um die erweiterte Befehlsliste zu erhalten."
-
-#: ../src/Engine/Session.cs:216
+#: ../src/Engine/Session.cs:218
 #, csharp-format
 msgid "Automatic connect to {0} failed!"
 msgstr "Automatische Verbindung zu {0} ist fehlgeschlagen!"
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Engine/Session.cs:407
+#: ../src/Engine/Session.cs:416
 msgid "Engine Commands"
 msgstr "Engine Befehle"
 
-#: ../src/Engine/Session.cs:510
+#: ../src/Engine/Session.cs:527
 msgid "Connect failed!"
 msgstr "Verbindung ist fehlgeschlagen!"
 
-#: ../src/Engine/Session.cs:540
+#: ../src/Engine/Session.cs:550
 #, csharp-format
 msgid "Disconnect failed - could not find server: {0}"
 msgstr "Die Trennung ist fehlgeschlagen - konnte den Server {0} nicht finden"
 
-#: ../src/Engine/Session.cs:579
+#: ../src/Engine/Session.cs:589
 msgid "Reconnect failed!"
 msgstr "Wiederverbinden ist fehlgeschlagen!"
 
-#: ../src/Engine/Session.cs:598
+#: ../src/Engine/Session.cs:608
 msgid "Configuration reloaded"
 msgstr "Konfiguration wurde erneuert"
 
-#: ../src/Engine/Session.cs:603
+#: ../src/Engine/Session.cs:613
 msgid "Configuration saved"
 msgstr "Konfiguration wurde gespeichert"
 
-#: ../src/Engine/Session.cs:607
+#: ../src/Engine/Session.cs:617
 msgid "Invalid parameter for config; use load or save"
 msgstr "Ungültiger Parameter für \"config\", verwenden Sie \"load\" oder \"save\""
 
-#: ../src/Engine/Session.cs:637
+#: ../src/Engine/Session.cs:676
 msgid "Invalid parameter for network; use list, switch, or close"
-msgstr "Ungültiger Parameter für \"network\", verwenden Sie \"list\", \"switch\" oder \"close\""
+msgstr ""
+"Ungültiger Parameter für \"network\", verwenden Sie \"list\", \"switch\" "
+"oder \"close\""
 
-#: ../src/Engine/Session.cs:648
+#: ../src/Engine/Session.cs:687
 msgid "Networks"
 msgstr "Netzwerke"
 
-#: ../src/Engine/Session.cs:652
-msgid "Type"
-msgstr "Typ"
+#: ../src/Engine/Session.cs:691
+msgid "Protocol"
+msgstr "Protokoll"
 
-#: ../src/Engine/Session.cs:653
+#: ../src/Engine/Session.cs:692
+msgid "Network"
+msgstr "Netzwerk"
+
+#: ../src/Engine/Session.cs:693
 msgid "Host"
 msgstr "Host"
 
-#: ../src/Engine/Session.cs:654
+#: ../src/Engine/Session.cs:694
 msgid "Port"
 msgstr "Port"
 
-#: ../src/Engine/Session.cs:676
+#: ../src/Engine/Session.cs:709
 #, csharp-format
-msgid "Network close failed - could not find network with host: {0}"
-msgstr "Beenden der Verbindung zum Netzwerk fehlgeschlagen, konnte das Netzwerk mit Host: {0} nicht finden"
+msgid "Network close failed - could not find network: {0}"
+msgstr ""
+"Schließen des Netzwerks fehlgeschlagen - Netzwerk konnte nicht gefunden "
+"werden: {0}"
 
-#: ../src/Engine/Session.cs:710
+#: ../src/Engine/Session.cs:748
 #, csharp-format
-msgid "Network switch failed - could not find network with host: {0}"
-msgstr "Wechseln des Netzwerks fehlgeschlagen, konnte das Netzwerk mit Host: {0} nicht finden"
+msgid "Network switch failed - could not find network: {0}"
+msgstr ""
+"Wechseln des Netzwerks fehlgeschlagen - Netzwerk konnte nicht gefunden "
+"werden: {0}"
 
-#: ../src/Engine/Session.cs:725
+#: ../src/Engine/Session.cs:767
 msgid "Not connected to any network"
 msgstr "Zu keinem Netzwerk verbunden"
 
+#: ../src/Engine/Session.cs:1013
+#, csharp-format
+msgid ""
+"Failed to write to chat history. Your chat history will not be preserved. "
+"Reason: {0}"
+msgstr ""
+"Schreiben des Gesprächverlaufs fehlgeschlagen. Ihr Gesprächsverlauf wird "
+"nicht vorgehalten. Grund: {0}"
+
 #. just in case the ProtocolManager is not setting the
 #. protocol chat
-#: ../src/Engine/Session.cs:1052
+#: ../src/Engine/Session.cs:1185
 msgid "Connect failed."
 msgstr "Verbindung ist fehlgeschlagen."
 
-#: ../src/Engine/Session.cs:1083
+#: ../src/Engine/Session.cs:1216
 #, csharp-format
 msgid "No protocol manager found for the protocol: {0}"
 msgstr "Kein Protokoll-Manager gefunden für das Protokoll: {0}"
 
+#: ../src/Engine/Session.cs:1448
+msgid "Welcome to Smuxi"
+msgstr "Willkommen bei Smuxi"
+
+#: ../src/Engine/Session.cs:1455
+msgid "Type /help to get a list of available commands."
+msgstr ""
+"Geben Sie /help ein, um eine Liste der verfügbaren Befehle zu erhalten."
+
+#: ../src/Engine/Session.cs:1461
+msgid ""
+"After you have made a connection the list of available commands changes. Go "
+"to the newly opened connection tab and use the /help command again to see "
+"the extended command list."
+msgstr ""
+"Nachdem Sie eine Verbindung aufgebaut haben, verändert sich die Liste der "
+"verfügbaren Kommandos. Gehen Sie zum neu geöffneten Verbindungsreiter und "
+"benutzen sie den Befehl /help erneut, um die erweiterte Kommandoliste zu "
+"sehen"
+
 #: ../src/Engine/Config/UserListController.cs:117
 msgid "Username must not be empty."
 msgstr "Benutzername darf nicht leer sein."
@@ -151,5 +198,17 @@ msgstr "Benutzer \"{0}\" ist nicht vorhanden."
 msgid "User \"{0}\" already exists."
 msgstr "Benutzer \"{0}\" ist bereits vorhanden."
 
-#~ msgid "Unknown protocol: {0}"
-#~ msgstr "Unbekanntes Protokoll: {0}"
+#: ../src/Engine/Config/ServerListController.cs:131
+msgid "Server hostname must not be empty."
+msgstr "Hostname des Servers darf nicht leer sein."
+
+#: ../src/Engine/Config/ServerListController.cs:134
+msgid "Server hostname contains invalid characters (newline)."
+msgstr "Hostname des Servers enthält unzuläissige Zeichen (neue Zeile)."
+
+#: ../src/Engine/Config/ServerListController.cs:140
+#, csharp-format
+msgid "Server '{0}' already exists."
+msgstr "Server \"{0}\" ist bereits vorhanden."
+
+
diff --git a/po-Engine/es.po b/po-Engine/es.po
index 4858f4b..1d95d0e 100644
--- a/po-Engine/es.po
+++ b/po-Engine/es.po
@@ -2,141 +2,166 @@
 # Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
 # This file is distributed under the same license as the Smuxi package.
 # Juan Miguel Carrero <streinleght at gmail.com>, 2008-2009.
-#
+# 
 msgid ""
 msgstr ""
 "Project-Id-Version: 0.6.2\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-01-09 21:43+0100\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
 "PO-Revision-Date: 2009-08-12 17:04+0100\n"
 "Last-Translator: Juan Miguel Carrero <streinleght at gmail.com>\n"
-"Language-Team: Spanish Spanish Localization <debian-l10n-spanish at lists."
-"debian.org>\n"
+"Language-Team: Spanish Spanish Localization <debian-l10n-spanish at lists.debian.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../src/Engine/FrontendManager.cs:219
-#, fuzzy
+#: ../src/Engine/FrontendManager.cs:230
 msgid "No network connections"
-msgstr "no hay conexiones a la red"
+msgstr "No hay conexiones de red"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:146
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:161
 msgid "Not connected to server"
 msgstr "No conectado al servidor"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:158
-#: ../src/Engine/Session.cs:684
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:173
+#: ../src/Engine/Session.cs:751
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Parámetros insuficientes para el comando {0}"
 
-#: ../src/Engine/Session.cs:151
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
+#, csharp-format
+msgid "Connected to {0}"
+msgstr "Conectado a {0}"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:213
+#, csharp-format
+msgid "Disconnected from {0}"
+msgstr "Desconectado desde {0}"
+
+#: ../src/Engine/Session.cs:154
 msgid "Welcome to Smuxi"
 msgstr "Bienvenido a Smuxi"
 
-#: ../src/Engine/Session.cs:157
+#: ../src/Engine/Session.cs:160
 msgid "Type /help to get a list of available commands."
 msgstr "Escribe /help para obtener una lista de comandos disponibles."
 
-#: ../src/Engine/Session.cs:160
-#, fuzzy
-msgid ""
-"After you have made a connection the list of available commands changes. Use "
-"the /help command again to see the extended command list."
-msgstr ""
-"Despues de efectuar una conexión la lista de comandos disponibles cambia , "
-"usa /help de nuevo."
+#: ../src/Engine/Session.cs:163
+msgid "After you have made a connection the list of available commands changes. Use the /help command again to see the extended command list."
+msgstr "Después de efectuar una conexión, la lista de comandos disponibles cambia. Usa el comando /help para ver la lista extendida de comandos."
 
-#: ../src/Engine/Session.cs:210
+#: ../src/Engine/Session.cs:216
 #, csharp-format
 msgid "Automatic connect to {0} failed!"
 msgstr "Conexión automática a {0} fallida!"
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Engine/Session.cs:398
-#, fuzzy
+#: ../src/Engine/Session.cs:411
 msgid "Engine Commands"
-msgstr "[Comandos del Motor]"
+msgstr "Comandos del Motor"
 
-#: ../src/Engine/Session.cs:510
-#, fuzzy, csharp-format
+#: ../src/Engine/Session.cs:514
+msgid "Connect failed!"
+msgstr "No se puede conectar"
+
+#: ../src/Engine/Session.cs:544
+#, csharp-format
 msgid "Disconnect failed - could not find server: {0}"
 msgstr "Desconexión fallida, no se encuentra el servidor: {0}"
 
-#: ../src/Engine/Session.cs:546
+#: ../src/Engine/Session.cs:583
+msgid "Reconnect failed!"
+msgstr "La reconexión ha fallado!"
+
+#: ../src/Engine/Session.cs:602
 msgid "Configuration reloaded"
 msgstr "Configuración importada"
 
-#: ../src/Engine/Session.cs:551
+#: ../src/Engine/Session.cs:607
 msgid "Configuration saved"
 msgstr "Configuración guardada"
 
-#: ../src/Engine/Session.cs:555
-#, fuzzy
+#: ../src/Engine/Session.cs:611
 msgid "Invalid parameter for config; use load or save"
-msgstr "Parámetro inválido de configuración , usa importar o guardar"
+msgstr "Parámetro inválido de configuración; use cargar o guardar"
 
-#: ../src/Engine/Session.cs:585
-#, fuzzy
+#: ../src/Engine/Session.cs:641
 msgid "Invalid parameter for network; use list, switch, or close"
-msgstr "Paŕametro inválido de configuración, usa list , switch o close"
+msgstr "Parámetro inválido para la red; utilice list, switch o close"
 
-#: ../src/Engine/Session.cs:596
+#: ../src/Engine/Session.cs:652
 msgid "Networks"
 msgstr "Redes"
 
-#: ../src/Engine/Session.cs:600
+#: ../src/Engine/Session.cs:656
 msgid "Type"
 msgstr "Tipo"
 
-#: ../src/Engine/Session.cs:601
+#: ../src/Engine/Session.cs:657
 msgid "Host"
 msgstr "Servidor"
 
-#: ../src/Engine/Session.cs:602
+#: ../src/Engine/Session.cs:658
 msgid "Port"
 msgstr "Puerto"
 
-#: ../src/Engine/Session.cs:624
-#, fuzzy, csharp-format
+#: ../src/Engine/Session.cs:680
+#, csharp-format
 msgid "Network close failed - could not find network with host: {0}"
-msgstr "Cierre de red fallido , no se puede encontrar la red con host: {0}"
+msgstr "Fallo en el cierre de la red. No se puede encontrar la red con el dominio: {0}"
 
-#: ../src/Engine/Session.cs:658
-#, fuzzy, csharp-format
+#: ../src/Engine/Session.cs:725
+#, csharp-format
 msgid "Network switch failed - could not find network with host: {0}"
-msgstr "Cambio de red fallido , no se puede encontrar la red con host: {0}"
+msgstr "El cambio de red ha fallado. No se puede encontrar la red con el dominio: {0}"
 
-#: ../src/Engine/Session.cs:673
+#: ../src/Engine/Session.cs:740
 msgid "Not connected to any network"
 msgstr "No conectado a ninguna red"
 
-#: ../src/Engine/Session.cs:962
+#. just in case the ProtocolManager is not setting the
+#. protocol chat
+#: ../src/Engine/Session.cs:1067
+msgid "Connect failed."
+msgstr "Ha fallado la conexión."
+
+#: ../src/Engine/Session.cs:1098
 #, csharp-format
 msgid "No protocol manager found for the protocol: {0}"
 msgstr "No existe gestor para el protocolo: {0}"
 
-#: ../src/Engine/Session.cs:985
-#, csharp-format
-msgid "Unknown protocol: {0}"
-msgstr "Protocolo desconocido: {0}"
-
-#: ../src/Engine/Config/UserListController.cs:112
+#: ../src/Engine/Config/UserListController.cs:117
 msgid "Username must not be empty."
-msgstr ""
+msgstr "El nombre de usuario no debe estar vacío"
 
-#: ../src/Engine/Config/UserListController.cs:122
+#: ../src/Engine/Config/UserListController.cs:127
 msgid "Password must not be empty."
-msgstr ""
+msgstr "La contraseña no debe estar vacía"
 
-#: ../src/Engine/Config/UserListController.cs:131
+#: ../src/Engine/Config/UserListController.cs:136
 #, csharp-format
 msgid "User \"{0}\" doesn't exist."
-msgstr ""
+msgstr "El usuario \"{0}\" no existe."
 
-#: ../src/Engine/Config/UserListController.cs:140
+#: ../src/Engine/Config/UserListController.cs:145
 #, csharp-format
 msgid "User \"{0}\" already exists."
-msgstr ""
+msgstr "El usuario \"{0}\" ya existe."
+
+#: ../src/Engine/Config/ServerListController.cs:131
+msgid "Server hostname must not be empty."
+msgstr "El dominio del servidor no debe estar vacío."
+
+#: ../src/Engine/Config/ServerListController.cs:134
+msgid "Server hostname contains invalid characters (newline)."
+msgstr "El dominio del servidor contiene caracteres inválidos (nueva línea)"
+
+#: ../src/Engine/Config/ServerListController.cs:140
+#, csharp-format
+msgid "Server '{0}' already exists."
+msgstr "El servidor '{0}' ya existe."
+
+#~ msgid "Unknown protocol: {0}"
+#~ msgstr "Protocolo desconocido: {0}"
diff --git a/po-Engine/fr.po b/po-Engine/fr.po
index ea9528f..8d1a3de 100644
--- a/po-Engine/fr.po
+++ b/po-Engine/fr.po
@@ -1,139 +1,179 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-# Clement BOURGEOIS <moonpyk at gmail.com>, 2008.
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
 # 
+# Translators:
+# Clément Bourgeois <moonpyk at gmail.com>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: Smuxi 0.6.4\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-08-05 01:46+0200\n"
-"PO-Revision-Date: 2010-07-15 22:27+0100\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:19+0100\n"
+"PO-Revision-Date: 2011-12-30 22:53+0000\n"
 "Last-Translator: Clément Bourgeois <moonpyk at gmail.com>\n"
-"Language-Team: French Localization <debian-l10n-french at lists.debian.org>\n"
+"Language-Team: French (http://www.transifex.net/projects/p/smuxi/team/fr/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: French\n"
-"X-Poedit-Country: FRANCE\n"
+"Language: fr\n"
+"Plural-Forms: nplurals=2; plural=(n > 1)\n"
 
-#: ../src/Engine/FrontendManager.cs:223
+#: ../src/Engine/FrontendManager.cs:233
 msgid "No network connections"
 msgstr "Aucune connexion réseau"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:146
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:295
+#, csharp-format
+msgid "Optimizing: {0}..."
+msgstr "Optimisation : {0}..."
+
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:313
+#, csharp-format
+msgid "Failed to optimize: {0}. Reason: {1}"
+msgstr "Impossible d'optimiser : {0}. Raison : {1}"
+
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:347
+msgid ""
+"Your chat history is no longer available because of an error but will be "
+"preserved from now on."
+msgstr ""
+"Votre historique de conversation n'est plus disponible en raison d'une "
+"erreur mais il sera préservé à partir de maintenant."
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:170
 msgid "Not connected to server"
-msgstr "Non connecté au serveur"
+msgstr "Pas de connexion au serveur"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:158
-#: ../src/Engine/Session.cs:736
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:178
+#: ../src/Engine/Session.cs:778
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Pas assez d'arguments pour la commande {0}"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:174
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
 #, csharp-format
 msgid "Connected to {0}"
 msgstr "Connecté à {0}"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:196
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:207
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Deconnecté de {0}"
 
-#: ../src/Engine/Session.cs:154
-msgid "Welcome to Smuxi"
-msgstr "Bienvenue dans Smuxi"
-
-#: ../src/Engine/Session.cs:160
-msgid "Type /help to get a list of available commands."
-msgstr "Tapez /help pour obtenir la liste des commandes disponibles."
-
-#: ../src/Engine/Session.cs:163
-msgid "After you have made a connection the list of available commands changes. Use the /help command again to see the extended command list."
-msgstr "Une fois la connexion établie, la liste des commandes disponibles change, vous pouvez retaper /help encore une fois pour obtenir une liste étendue de celles-ci."
-
-#: ../src/Engine/Session.cs:216
+#: ../src/Engine/Session.cs:218
 #, csharp-format
 msgid "Automatic connect to {0} failed!"
 msgstr "Connexion automatique à {0} impossible !"
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Engine/Session.cs:407
+#: ../src/Engine/Session.cs:416
 msgid "Engine Commands"
 msgstr "Commandes du moteur"
 
-#: ../src/Engine/Session.cs:510
+#: ../src/Engine/Session.cs:527
 msgid "Connect failed!"
 msgstr "Connexion impossible !"
 
-#: ../src/Engine/Session.cs:540
+#: ../src/Engine/Session.cs:550
 #, csharp-format
 msgid "Disconnect failed - could not find server: {0}"
 msgstr "Déconnexion impossible : serveur \"{0}\" introuvable"
 
-#: ../src/Engine/Session.cs:579
+#: ../src/Engine/Session.cs:589
 msgid "Reconnect failed!"
 msgstr "Reconnexion impossible !"
 
-#: ../src/Engine/Session.cs:598
+#: ../src/Engine/Session.cs:608
 msgid "Configuration reloaded"
 msgstr "Configuration rechargée"
 
-#: ../src/Engine/Session.cs:603
+#: ../src/Engine/Session.cs:613
 msgid "Configuration saved"
 msgstr "Configuration sauvegardée"
 
-#: ../src/Engine/Session.cs:607
+#: ../src/Engine/Session.cs:617
 msgid "Invalid parameter for config; use load or save"
 msgstr "Paramètre invalide pour la configuration ; utilisez load ou save"
 
-#: ../src/Engine/Session.cs:637
+#: ../src/Engine/Session.cs:676
 msgid "Invalid parameter for network; use list, switch, or close"
 msgstr "Paramètre invalide pour le réseau ; utilisez list, switch ou close"
 
-#: ../src/Engine/Session.cs:648
+#: ../src/Engine/Session.cs:687
 msgid "Networks"
 msgstr "Réseaux"
 
-#: ../src/Engine/Session.cs:652
-msgid "Type"
-msgstr "Type"
+#: ../src/Engine/Session.cs:691
+msgid "Protocol"
+msgstr "Protocole"
 
-#: ../src/Engine/Session.cs:653
+#: ../src/Engine/Session.cs:692
+msgid "Network"
+msgstr "Réseau"
+
+#: ../src/Engine/Session.cs:693
 msgid "Host"
 msgstr "Hôte"
 
-#: ../src/Engine/Session.cs:654
+#: ../src/Engine/Session.cs:694
 msgid "Port"
 msgstr "Port"
 
-#: ../src/Engine/Session.cs:676
+#: ../src/Engine/Session.cs:709
 #, csharp-format
-msgid "Network close failed - could not find network with host: {0}"
-msgstr "Fermeture réseau impossible, aucun réseau trouvé pour l'hôte : {0}"
+msgid "Network close failed - could not find network: {0}"
+msgstr ""
+"Impossible de fermer le réseau - impossible de trouver le réseau : {0}"
 
-#: ../src/Engine/Session.cs:710
+#: ../src/Engine/Session.cs:748
 #, csharp-format
-msgid "Network switch failed - could not find network with host: {0}"
-msgstr "Changement de réseau impossible, aucun réseau pour l'hôte : {0}"
+msgid "Network switch failed - could not find network: {0}"
+msgstr ""
+"Impossible de changer de réseau - impossible de trouver le réseau : {0}"
 
-#: ../src/Engine/Session.cs:725
+#: ../src/Engine/Session.cs:767
 msgid "Not connected to any network"
 msgstr "Aucun réseau connecté"
 
+#: ../src/Engine/Session.cs:1013
+#, csharp-format
+msgid ""
+"Failed to write to chat history. Your chat history will not be preserved. "
+"Reason: {0}"
+msgstr ""
+"Impossible d'écrire votre historique de discussion, celui-ci ne sera pas "
+"préservé. Raison : {0}"
+
 #. just in case the ProtocolManager is not setting the
 #. protocol chat
-#: ../src/Engine/Session.cs:1052
+#: ../src/Engine/Session.cs:1185
 msgid "Connect failed."
 msgstr "Connexion impossible."
 
-#: ../src/Engine/Session.cs:1083
+#: ../src/Engine/Session.cs:1216
 #, csharp-format
 msgid "No protocol manager found for the protocol: {0}"
 msgstr "Aucun gestionnaire de protocole trouvé pour le protocole : {0}"
 
+#: ../src/Engine/Session.cs:1448
+msgid "Welcome to Smuxi"
+msgstr "Bienvenue dans Smuxi"
+
+#: ../src/Engine/Session.cs:1455
+msgid "Type /help to get a list of available commands."
+msgstr "Tapez /help pour obtenir la liste des commandes disponibles."
+
+#: ../src/Engine/Session.cs:1461
+msgid ""
+"After you have made a connection the list of available commands changes. Go "
+"to the newly opened connection tab and use the /help command again to see "
+"the extended command list."
+msgstr ""
+"Apres s'être connecté, la liste des commandes disponibles change. Allez dans"
+" l'onglet de la nouvelle connexion et utilisez la commande /help pour voir "
+"la nouvelle liste étendue des commandes."
+
 #: ../src/Engine/Config/UserListController.cs:117
 msgid "Username must not be empty."
 msgstr "Le nom d'utilisateur ne peut pas être vide."
@@ -152,5 +192,17 @@ msgstr "L'utilisateur \"{0}\"  n'existe pas."
 msgid "User \"{0}\" already exists."
 msgstr "L'utilisateur \"{0}\" existe déjà."
 
-#~ msgid "Unknown protocol: {0}"
-#~ msgstr "Protocole inconnu : {0}"
+#: ../src/Engine/Config/ServerListController.cs:131
+msgid "Server hostname must not be empty."
+msgstr "Le nom d'hôte ne peut pas être vide."
+
+#: ../src/Engine/Config/ServerListController.cs:134
+msgid "Server hostname contains invalid characters (newline)."
+msgstr "Le nom d'hôte contient des caractères invalides."
+
+#: ../src/Engine/Config/ServerListController.cs:140
+#, csharp-format
+msgid "Server '{0}' already exists."
+msgstr "Le serveur \"{0}\" existe déjà."
+
+
diff --git a/po-Engine/it.po b/po-Engine/it.po
index e49b3b7..5ee70b0 100644
--- a/po-Engine/it.po
+++ b/po-Engine/it.po
@@ -1,15 +1,15 @@
 # Smuxi - IRC client for sophisticated users
 # Copyright (C) 2005-2010 Mirco Bauer <meebey at meebey.net>
 # This file is distributed under the same license as the Smuxi package.
-# David Paleino <d.paleino at gmail.com>, 2008.
 #
-# Vincenzo Campanella <vinz65 at gmail.com>, 2009-2010, 2010.
+# David Paleino <d.paleino at gmail.com>, 2008.
+# Vincenzo Campanella <vinz65 at gmail.com>, 2009, 2010.
 msgid ""
 msgstr ""
-"Project-Id-Version: smuxi 0.6.4\n"
+"Project-Id-Version: smuxi-engine\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-15 12:59+0200\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2010-09-11 09:33+0200\n"
 "Last-Translator: Vincenzo Campanella <vinz65 at gmail.com>\n"
 "Language-Team: Italian <tp at lists.linux.it>\n"
 "Language: it\n"
@@ -19,20 +19,30 @@ msgstr ""
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #
-#: ../src/Engine/FrontendManager.cs:219
+#: ../src/Engine/FrontendManager.cs:230
 msgid "No network connections"
 msgstr "Nessuna connessione di rete"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:146
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:161
 msgid "Not connected to server"
 msgstr "Non connesso a un server"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:158
-#: ../src/Engine/Session.cs:731
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:173
+#: ../src/Engine/Session.cs:751
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Non sono stati forniti abbastanza parametri per il comando {0}"
 
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
+#, csharp-format
+msgid "Connected to {0}"
+msgstr "Connesso a {0}"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:213
+#, csharp-format
+msgid "Disconnected from {0}"
+msgstr "Disconnesso da {0}"
+
 #: ../src/Engine/Session.cs:154
 msgid "Welcome to Smuxi"
 msgstr "Benvenuti in Smuxi"
@@ -59,82 +69,83 @@ msgstr "La connessione automatica a {0} non è riuscita."
 #
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Engine/Session.cs:407
+#: ../src/Engine/Session.cs:411
 msgid "Engine Commands"
 msgstr "Comandi del motore"
 
-#: ../src/Engine/Session.cs:510
+#: ../src/Engine/Session.cs:514
 msgid "Connect failed!"
 msgstr "La connessione non è riuscita."
 
-#: ../src/Engine/Session.cs:539
+#: ../src/Engine/Session.cs:544
 #, csharp-format
 msgid "Disconnect failed - could not find server: {0}"
 msgstr "La disconnessione non è riuscita, impossibile trovare il server: {0}"
 
-#: ../src/Engine/Session.cs:574
+#: ../src/Engine/Session.cs:583
 msgid "Reconnect failed!"
 msgstr "La riconnessione non è riuscita."
 
-#: ../src/Engine/Session.cs:593
+#: ../src/Engine/Session.cs:602
 msgid "Configuration reloaded"
 msgstr "Configurazione ricaricata"
 
-#: ../src/Engine/Session.cs:598
+#: ../src/Engine/Session.cs:607
 msgid "Configuration saved"
 msgstr "Configurazione salvata"
 
-#: ../src/Engine/Session.cs:602
+#: ../src/Engine/Session.cs:611
 msgid "Invalid parameter for config; use load or save"
 msgstr "Parametro non valido per la configurazione, utilizzare «load» o «save»"
 
-#: ../src/Engine/Session.cs:632
+#: ../src/Engine/Session.cs:641
 msgid "Invalid parameter for network; use list, switch, or close"
-msgstr "Parametro non valido per la rete, utilizzare «list», «switch» o «close»"
+msgstr ""
+"Parametro non valido per la rete, utilizzare «list», «switch» o «close»"
 
-#: ../src/Engine/Session.cs:643
+#: ../src/Engine/Session.cs:652
 msgid "Networks"
 msgstr "Reti"
 
-#: ../src/Engine/Session.cs:647
+#: ../src/Engine/Session.cs:656
 msgid "Type"
 msgstr "Tipo"
 
-#: ../src/Engine/Session.cs:648
+#: ../src/Engine/Session.cs:657
 msgid "Host"
 msgstr "Host"
 
-#: ../src/Engine/Session.cs:649
+#: ../src/Engine/Session.cs:658
 msgid "Port"
 msgstr "Porta"
 
-#: ../src/Engine/Session.cs:671
+#: ../src/Engine/Session.cs:680
 #, csharp-format
 msgid "Network close failed - could not find network with host: {0}"
 msgstr ""
 "La chiusura della rete non è riuscita, impossibile trovare la rete con "
 "l'host: {0}"
 
-#: ../src/Engine/Session.cs:705
+#: ../src/Engine/Session.cs:725
 #, csharp-format
 msgid "Network switch failed - could not find network with host: {0}"
 msgstr ""
 "Il cambio di rete non è riuscito, impossibile trovare la rete con l'host: {0}"
 
-#: ../src/Engine/Session.cs:720
+#: ../src/Engine/Session.cs:740
 msgid "Not connected to any network"
 msgstr "Non connesso ad alcuna rete"
 
 #. just in case the ProtocolManager is not setting the
 #. protocol chat
-#: ../src/Engine/Session.cs:1047
+#: ../src/Engine/Session.cs:1067
 msgid "Connect failed."
 msgstr "La connessione non è riuscita."
 
-#: ../src/Engine/Session.cs:1078
+#: ../src/Engine/Session.cs:1098
 #, csharp-format
 msgid "No protocol manager found for the protocol: {0}"
-msgstr "Nessun gestore trovato per il protocollo {0}"
+msgstr "Nessun gestore trovato per il protocollo: {0}"
 
 #: ../src/Engine/Config/UserListController.cs:117
 msgid "Username must not be empty."
@@ -154,5 +165,19 @@ msgstr "L'utente «{0}» non esiste."
 msgid "User \"{0}\" already exists."
 msgstr "L'utente «{0}» esiste già."
 
+#: ../src/Engine/Config/ServerListController.cs:131
+msgid "Server hostname must not be empty."
+msgstr "Il nome host del server non può essere vuoto."
+
+#: ../src/Engine/Config/ServerListController.cs:134
+msgid "Server hostname contains invalid characters (newline)."
+msgstr ""
+"Il nome host del server contiene caratteri non validi (ritorno a capo)."
+
+#: ../src/Engine/Config/ServerListController.cs:140
+#, csharp-format
+msgid "Server '{0}' already exists."
+msgstr "Il server «{0}» esiste già."
+
 #~ msgid "Unknown protocol: {0}"
 #~ msgstr "Protocollo sconosciuto: {0}"
diff --git a/po-Engine/pt.po b/po-Engine/pt.po
index 7f31ae9..368c498 100644
--- a/po-Engine/pt.po
+++ b/po-Engine/pt.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: smuxi-engine \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-15 01:35+0100\n"
+"POT-Creation-Date: 2010-09-11 11:54+0200\n"
+"PO-Revision-Date: 2010-09-08 01:27+0100\n"
 "Last-Translator: Américo Monteiro <a_monteiro at netcabo.pt>\n"
 "Language-Team: Portuguese <traduz at debianpt.org>\n"
 "Language: pt\n"
@@ -18,20 +18,30 @@ msgstr ""
 "X-Generator: Lokalize 1.0\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../src/Engine/FrontendManager.cs:219
+#: ../src/Engine/FrontendManager.cs:230
 msgid "No network connections"
 msgstr "Nenhuma ligação à rede"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:146
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:161
 msgid "Not connected to server"
 msgstr "Não ligado ao servidor"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:158
-#: ../src/Engine/Session.cs:731
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:173
+#: ../src/Engine/Session.cs:751
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Parâmetros insuficientes para o comando {0}"
 
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
+#, csharp-format
+msgid "Connected to {0}"
+msgstr "Ligado a {0}"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:213
+#, csharp-format
+msgid "Disconnected from {0}"
+msgstr "Desligado de {0}"
+
 #: ../src/Engine/Session.cs:154
 msgid "Welcome to Smuxi"
 msgstr "Bem vindo ao Smuxi"
@@ -55,76 +65,76 @@ msgstr "Falhou a ligação automática a {0}!"
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Engine/Session.cs:407
+#: ../src/Engine/Session.cs:411
 msgid "Engine Commands"
 msgstr "Comandos do Motor"
 
-#: ../src/Engine/Session.cs:510
+#: ../src/Engine/Session.cs:514
 msgid "Connect failed!"
 msgstr "Ligação falhada!"
 
-#: ../src/Engine/Session.cs:539
+#: ../src/Engine/Session.cs:544
 #, csharp-format
 msgid "Disconnect failed - could not find server: {0}"
 msgstr "Falha ao desligar - incapaz de encontrar o servidor: {0}"
 
-#: ../src/Engine/Session.cs:574
+#: ../src/Engine/Session.cs:583
 msgid "Reconnect failed!"
 msgstr "Re-ligação falhada!"
 
-#: ../src/Engine/Session.cs:593
+#: ../src/Engine/Session.cs:602
 msgid "Configuration reloaded"
 msgstr "Configuração recarregada"
 
-#: ../src/Engine/Session.cs:598
+#: ../src/Engine/Session.cs:607
 msgid "Configuration saved"
 msgstr "Configuração salvada"
 
-#: ../src/Engine/Session.cs:602
+#: ../src/Engine/Session.cs:611
 msgid "Invalid parameter for config; use load or save"
 msgstr "Parâmetro inválido para configuração; use load ou save"
 
-#: ../src/Engine/Session.cs:632
+#: ../src/Engine/Session.cs:641
 msgid "Invalid parameter for network; use list, switch, or close"
 msgstr "Parâmetro inválido para rede; use list, switch, ou close"
 
-#: ../src/Engine/Session.cs:643
+#: ../src/Engine/Session.cs:652
 msgid "Networks"
 msgstr "Redes"
 
-#: ../src/Engine/Session.cs:647
+#: ../src/Engine/Session.cs:656
 msgid "Type"
 msgstr "Tipo"
 
-#: ../src/Engine/Session.cs:648
+#: ../src/Engine/Session.cs:657
 msgid "Host"
 msgstr "Máquina"
 
-#: ../src/Engine/Session.cs:649
+#: ../src/Engine/Session.cs:658
 msgid "Port"
 msgstr "Porto"
 
-#: ../src/Engine/Session.cs:671
+#: ../src/Engine/Session.cs:680
 #, csharp-format
 msgid "Network close failed - could not find network with host: {0}"
 msgstr "Fecho de rede falhado - incapaz de encontrar a rede com a máquina: {0}"
 
-#: ../src/Engine/Session.cs:705
+#: ../src/Engine/Session.cs:725
 #, csharp-format
 msgid "Network switch failed - could not find network with host: {0}"
 msgstr "Troca de rede falhada - incapaz de encontrar a rede com a máquina: {0}"
 
-#: ../src/Engine/Session.cs:720
+#: ../src/Engine/Session.cs:740
 msgid "Not connected to any network"
 msgstr "Não ligado a nenhuma rede"
 
 #. just in case the ProtocolManager is not setting the
 #. protocol chat
-#: ../src/Engine/Session.cs:1047
+#: ../src/Engine/Session.cs:1067
 msgid "Connect failed."
 msgstr "Ligação falhada."
 
-#: ../src/Engine/Session.cs:1078
+#: ../src/Engine/Session.cs:1098
 #, csharp-format
 msgid "No protocol manager found for the protocol: {0}"
 msgstr "Nenhum gestor de protocolo encontrado para o protocolo: {0}"
@@ -147,5 +157,19 @@ msgstr "O utilizador \"{0}\" não existe."
 msgid "User \"{0}\" already exists."
 msgstr "O utilizador \"{0}\" já existe."
 
+#: ../src/Engine/Config/ServerListController.cs:131
+msgid "Server hostname must not be empty."
+msgstr "O nome de máquina do servidor não pode estar vazio."
+
+#: ../src/Engine/Config/ServerListController.cs:134
+msgid "Server hostname contains invalid characters (newline)."
+msgstr ""
+"O nome de máquina do servidor contém caracteres inválidos (nova linha)."
+
+#: ../src/Engine/Config/ServerListController.cs:140
+#, csharp-format
+msgid "Server '{0}' already exists."
+msgstr "O servidor \"{0}\" já existe."
+
 #~ msgid "Unknown protocol: {0}"
 #~ msgstr "Protocolo desconhecido: {0}"
diff --git a/po-Engine/ru.po b/po-Engine/ru.po
new file mode 100644
index 0000000..20db943
--- /dev/null
+++ b/po-Engine/ru.po
@@ -0,0 +1,167 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: smuxi 0.8\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2010-09-10 02:37+0600\n"
+"Last-Translator: Urmas <davian818 at gmail.com>\n"
+"Language-Team: None <->\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Country: RUSSIAN FEDERATION\n"
+"Plural-Forms: nplurals=4; plural=(n==1) ? 0 : (n%10==1 && n%100!=11 ? 3 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Poedit-Language: Russian\n"
+
+#: ../src/Engine/FrontendManager.cs:230
+msgid "No network connections"
+msgstr "Нет сетевых соединений"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:161
+msgid "Not connected to server"
+msgstr "Нет подключения к серверу"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:173
+#: ../src/Engine/Session.cs:751
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr "Недостаточно параметров для команды {0}"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
+#, csharp-format
+msgid "Connected to {0}"
+msgstr "Подключён к {0}"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:213
+#, csharp-format
+msgid "Disconnected from {0}"
+msgstr "Отключён от {0}"
+
+#: ../src/Engine/Session.cs:154
+msgid "Welcome to Smuxi"
+msgstr ""
+
+#: ../src/Engine/Session.cs:160
+msgid "Type /help to get a list of available commands."
+msgstr "Для получения списка команд введите /help"
+
+#: ../src/Engine/Session.cs:163
+msgid "After you have made a connection the list of available commands changes. Use the /help command again to see the extended command list."
+msgstr ""
+
+#: ../src/Engine/Session.cs:216
+#, csharp-format
+msgid "Automatic connect to {0} failed!"
+msgstr "Не удалось автоматически подключиться к {0}!"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine/Session.cs:411
+msgid "Engine Commands"
+msgstr "Команды ядра"
+
+#: ../src/Engine/Session.cs:514
+msgid "Connect failed!"
+msgstr ""
+
+#: ../src/Engine/Session.cs:544
+#, csharp-format
+msgid "Disconnect failed - could not find server: {0}"
+msgstr ""
+
+#: ../src/Engine/Session.cs:583
+msgid "Reconnect failed!"
+msgstr ""
+
+#: ../src/Engine/Session.cs:602
+msgid "Configuration reloaded"
+msgstr ""
+
+#: ../src/Engine/Session.cs:607
+msgid "Configuration saved"
+msgstr ""
+
+#: ../src/Engine/Session.cs:611
+msgid "Invalid parameter for config; use load or save"
+msgstr ""
+
+#: ../src/Engine/Session.cs:641
+msgid "Invalid parameter for network; use list, switch, or close"
+msgstr ""
+
+#: ../src/Engine/Session.cs:652
+msgid "Networks"
+msgstr "Сети"
+
+#: ../src/Engine/Session.cs:656
+msgid "Type"
+msgstr "Тип"
+
+#: ../src/Engine/Session.cs:657
+msgid "Host"
+msgstr "Сервер"
+
+#: ../src/Engine/Session.cs:658
+msgid "Port"
+msgstr "Порт"
+
+#: ../src/Engine/Session.cs:680
+#, csharp-format
+msgid "Network close failed - could not find network with host: {0}"
+msgstr ""
+
+#: ../src/Engine/Session.cs:725
+#, csharp-format
+msgid "Network switch failed - could not find network with host: {0}"
+msgstr ""
+
+#: ../src/Engine/Session.cs:740
+msgid "Not connected to any network"
+msgstr "Нет подключения к сетям"
+
+#. just in case the ProtocolManager is not setting the
+#. protocol chat
+#: ../src/Engine/Session.cs:1067
+msgid "Connect failed."
+msgstr "Сбой соединения."
+
+#: ../src/Engine/Session.cs:1098
+#, csharp-format
+msgid "No protocol manager found for the protocol: {0}"
+msgstr "Не найден обработчик протокола: {0}"
+
+#: ../src/Engine/Config/UserListController.cs:117
+msgid "Username must not be empty."
+msgstr "Требуется указать имя пользователя."
+
+#: ../src/Engine/Config/UserListController.cs:127
+msgid "Password must not be empty."
+msgstr "Требуется указать пароль."
+
+#: ../src/Engine/Config/UserListController.cs:136
+#, csharp-format
+msgid "User \"{0}\" doesn't exist."
+msgstr "Пользователя \"{0}\" не существует."
+
+#: ../src/Engine/Config/UserListController.cs:145
+#, csharp-format
+msgid "User \"{0}\" already exists."
+msgstr "Пользователь \"{0}\" уже существует."
+
+#: ../src/Engine/Config/ServerListController.cs:131
+msgid "Server hostname must not be empty."
+msgstr "Требуется указать имя сервера."
+
+#: ../src/Engine/Config/ServerListController.cs:134
+msgid "Server hostname contains invalid characters (newline)."
+msgstr "Имя сервера содержит недопустимые символы или перенос строки."
+
+#: ../src/Engine/Config/ServerListController.cs:140
+#, csharp-format
+msgid "Server '{0}' already exists."
+msgstr "Сервер '{0}' уже существует."
diff --git a/po-Engine/sk.po b/po-Engine/sk.po
new file mode 100644
index 0000000..1530ccb
--- /dev/null
+++ b/po-Engine/sk.po
@@ -0,0 +1,174 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Tomáš Vadina <kyberdev at gmail.com>, 2011.
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2011-09-30 08:39+0000\n"
+"Last-Translator: Tomáš Vadina <kyberdev at gmail.com>\n"
+"Language-Team: Slovak (http://www.transifex.net/projects/p/smuxi/team/sk/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: sk\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
+
+#: ../src/Engine/FrontendManager.cs:230
+msgid "No network connections"
+msgstr "Žiadne pripojenia k sieti"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:161
+msgid "Not connected to server"
+msgstr "Nie je pripojené k serveru"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:173
+#: ../src/Engine/Session.cs:751
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr "Pre príkaz {0} nie je vložený dostatok parametrov"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
+#, csharp-format
+msgid "Connected to {0}"
+msgstr "Pripojené k {0}"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:213
+#, csharp-format
+msgid "Disconnected from {0}"
+msgstr "Odpojené od {0}"
+
+#: ../src/Engine/Session.cs:154
+msgid "Welcome to Smuxi"
+msgstr "Vitajte v Smuxi"
+
+#: ../src/Engine/Session.cs:160
+msgid "Type /help to get a list of available commands."
+msgstr "Pre zobrazenie zoznamu dostupných príkazov zadajte príkaz /help."
+
+#: ../src/Engine/Session.cs:163
+msgid ""
+"After you have made a connection the list of available commands changes. Use"
+" the /help command again to see the extended command list."
+msgstr ""
+"Zoznam dostupných príkazov sa zmení po tom, ako sa prihlásite. Pre "
+"zobrazenie rozšíreného zoznamu dostupných príkazov znovu zadajte príkaz "
+"/help."
+
+#: ../src/Engine/Session.cs:216
+#, csharp-format
+msgid "Automatic connect to {0} failed!"
+msgstr "Automatické pripojenie k {0} zlyhalo!"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine/Session.cs:411
+msgid "Engine Commands"
+msgstr "Príkazy enginu"
+
+#: ../src/Engine/Session.cs:514
+msgid "Connect failed!"
+msgstr "Pripojenie zlyhalo!"
+
+#: ../src/Engine/Session.cs:544
+#, csharp-format
+msgid "Disconnect failed - could not find server: {0}"
+msgstr "Odpojenie zlyhalo - nepodarilo sa nájsť server: {0}"
+
+#: ../src/Engine/Session.cs:583
+msgid "Reconnect failed!"
+msgstr "Opätovné pripojenie zlyhalo!"
+
+#: ../src/Engine/Session.cs:602
+msgid "Configuration reloaded"
+msgstr "Nastavenie znova načítané"
+
+#: ../src/Engine/Session.cs:607
+msgid "Configuration saved"
+msgstr "Nastavenie uložené"
+
+#: ../src/Engine/Session.cs:611
+msgid "Invalid parameter for config; use load or save"
+msgstr "Neplatný parameter pre config; zadajte load alebo save"
+
+#: ../src/Engine/Session.cs:641
+msgid "Invalid parameter for network; use list, switch, or close"
+msgstr "Neplatný parameter pre network; zadajte list, switch alebo close"
+
+#: ../src/Engine/Session.cs:652
+msgid "Networks"
+msgstr "Siete"
+
+#: ../src/Engine/Session.cs:656
+msgid "Type"
+msgstr "Typ"
+
+#: ../src/Engine/Session.cs:657
+msgid "Host"
+msgstr "Hostiteľ"
+
+#: ../src/Engine/Session.cs:658
+msgid "Port"
+msgstr "Port"
+
+#: ../src/Engine/Session.cs:680
+#, csharp-format
+msgid "Network close failed - could not find network with host: {0}"
+msgstr "Uzatvorenie siete zlyhalo - nebolo možné nájsť hostiteľskú sieť: {0}"
+
+#: ../src/Engine/Session.cs:725
+#, csharp-format
+msgid "Network switch failed - could not find network with host: {0}"
+msgstr "Sieťový uzol zlyhal - nebolo možné nájsť hostiteľskú sieť: {0}"
+
+#: ../src/Engine/Session.cs:740
+msgid "Not connected to any network"
+msgstr "Nie je pripojené k žiadnej sieti"
+
+#. just in case the ProtocolManager is not setting the
+#. protocol chat
+#: ../src/Engine/Session.cs:1067
+msgid "Connect failed."
+msgstr "Pripojenie zlyhalo."
+
+#: ../src/Engine/Session.cs:1098
+#, csharp-format
+msgid "No protocol manager found for the protocol: {0}"
+msgstr "Pre protokol nebol nájdený žiadny správca protokolu: {0}"
+
+#: ../src/Engine/Config/UserListController.cs:117
+msgid "Username must not be empty."
+msgstr "Používateľské meno nemôže byť prázdne."
+
+#: ../src/Engine/Config/UserListController.cs:127
+msgid "Password must not be empty."
+msgstr "Heslo nemôže byť prázdne."
+
+#: ../src/Engine/Config/UserListController.cs:136
+#, csharp-format
+msgid "User \"{0}\" doesn't exist."
+msgstr "Používateľ \"{0}\" neexistuje."
+
+#: ../src/Engine/Config/UserListController.cs:145
+#, csharp-format
+msgid "User \"{0}\" already exists."
+msgstr "Používateľ \"{0}\" existuje."
+
+#: ../src/Engine/Config/ServerListController.cs:131
+msgid "Server hostname must not be empty."
+msgstr "Hostiteľský server nemôže byť prázdny."
+
+#: ../src/Engine/Config/ServerListController.cs:134
+msgid "Server hostname contains invalid characters (newline)."
+msgstr "Hostiteľský server obsahuje neplatné znaky (nový riadok)."
+
+#: ../src/Engine/Config/ServerListController.cs:140
+#, csharp-format
+msgid "Server '{0}' already exists."
+msgstr "Server '{0}' už existuje."
+
+
diff --git a/po-Engine/sv.po b/po-Engine/sv.po
index 13ac8b0..90abbe0 100644
--- a/po-Engine/sv.po
+++ b/po-Engine/sv.po
@@ -1,130 +1,179 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-#
-# Martin Bagge <brother at bsnet.se>, 2009
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+#   <flugsio at gmail.com>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: Smuxi Engine\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-15 13:12+0100\n"
-"Last-Translator: Martin Bagge / brother <brother at bsnet.se>\n"
-"Language-Team: Swedish <tp-sv at listor.tp-sv.se>\n"
-"Language: sv\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:19+0100\n"
+"PO-Revision-Date: 2011-12-31 11:11+0000\n"
+"Last-Translator: flugsio <flugsio at gmail.com>\n"
+"Language-Team: Swedish (http://www.transifex.net/projects/p/smuxi/team/sv/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: Swedish\n"
-"X-Poedit-Country: Sweden\n"
+"Language: sv\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Engine/FrontendManager.cs:219
+#: ../src/Engine/FrontendManager.cs:233
 msgid "No network connections"
 msgstr "Inga nätverksanslutningar"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:146
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:295
+#, csharp-format
+msgid "Optimizing: {0}..."
+msgstr "Optimerar: {0}..."
+
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:313
+#, csharp-format
+msgid "Failed to optimize: {0}. Reason: {1}"
+msgstr "Misslyckades att optimera: {0}. Anledning: {1}"
+
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:347
+msgid ""
+"Your chat history is no longer available because of an error but will be "
+"preserved from now on."
+msgstr ""
+"Din chatthistorik är inte längre tillgänglig på grund av ett fel, men kommer"
+" att bibehållas från och med nu."
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:170
 msgid "Not connected to server"
 msgstr "Inte ansluten till server"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:158
-#: ../src/Engine/Session.cs:731
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:178
+#: ../src/Engine/Session.cs:778
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Inte tillräckligt med parametrar för kommandot {0}"
 
-#: ../src/Engine/Session.cs:154
-msgid "Welcome to Smuxi"
-msgstr "Välkommen till Smuxi"
-
-#: ../src/Engine/Session.cs:160
-msgid "Type /help to get a list of available commands."
-msgstr "Skriv /help för en lista med tillgängliga kommandon."
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
+#, csharp-format
+msgid "Connected to {0}"
+msgstr "Ansluten till {0}"
 
-#: ../src/Engine/Session.cs:163
-msgid "After you have made a connection the list of available commands changes. Use the /help command again to see the extended command list."
-msgstr "När du har gjort en anslutning kommer listan med tillgängliga kommandon att ändras. Använd kommandot /help igen för att se den utökade kommandolistan."
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:207
+#, csharp-format
+msgid "Disconnected from {0}"
+msgstr "Frånkopplad från {0}"
 
-#: ../src/Engine/Session.cs:216
+#: ../src/Engine/Session.cs:218
 #, csharp-format
 msgid "Automatic connect to {0} failed!"
 msgstr "Automatisk anslutning till {0} misslyckades!"
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Engine/Session.cs:407
+#: ../src/Engine/Session.cs:416
 msgid "Engine Commands"
 msgstr "Kommandon för motorn"
 
-#: ../src/Engine/Session.cs:510
+#: ../src/Engine/Session.cs:527
 msgid "Connect failed!"
 msgstr "Anslutning misslyckades!"
 
-#: ../src/Engine/Session.cs:539
+#: ../src/Engine/Session.cs:550
 #, csharp-format
 msgid "Disconnect failed - could not find server: {0}"
 msgstr "Nedkoppling misslyckades - kunde inte hitta servern: {0}"
 
-#: ../src/Engine/Session.cs:574
+#: ../src/Engine/Session.cs:589
 msgid "Reconnect failed!"
 msgstr "Ã…teranslutning misslyckades!"
 
-#: ../src/Engine/Session.cs:593
+#: ../src/Engine/Session.cs:608
 msgid "Configuration reloaded"
 msgstr "Laddade om inställningar"
 
-#: ../src/Engine/Session.cs:598
+#: ../src/Engine/Session.cs:613
 msgid "Configuration saved"
 msgstr "Sparade inställningar"
 
-#: ../src/Engine/Session.cs:602
+#: ../src/Engine/Session.cs:617
 msgid "Invalid parameter for config; use load or save"
 msgstr "Ogiltig parameter för inställningar; använd load eller save"
 
-#: ../src/Engine/Session.cs:632
+#: ../src/Engine/Session.cs:676
 msgid "Invalid parameter for network; use list, switch, or close"
 msgstr "Ogiltig parameter för nätverk; använd list, switch eller close"
 
-#: ../src/Engine/Session.cs:643
+#: ../src/Engine/Session.cs:687
 msgid "Networks"
 msgstr "Nätverk"
 
-#: ../src/Engine/Session.cs:647
-msgid "Type"
-msgstr "Typ"
+#: ../src/Engine/Session.cs:691
+msgid "Protocol"
+msgstr "Protokoll"
+
+#: ../src/Engine/Session.cs:692
+msgid "Network"
+msgstr "Nätverk"
 
-#: ../src/Engine/Session.cs:648
+#: ../src/Engine/Session.cs:693
 msgid "Host"
 msgstr "Värd"
 
-#: ../src/Engine/Session.cs:649
+#: ../src/Engine/Session.cs:694
 msgid "Port"
 msgstr "Port"
 
-#: ../src/Engine/Session.cs:671
+#: ../src/Engine/Session.cs:709
 #, csharp-format
-msgid "Network close failed - could not find network with host: {0}"
-msgstr "Stängning av nätverk misslyckades - kunde inte hitta nätverk med värd: {0}"
+msgid "Network close failed - could not find network: {0}"
+msgstr ""
+"Stängning av nätverk misslyckades - kunde inte hitta nätverk med värd: {0}"
 
-#: ../src/Engine/Session.cs:705
+#: ../src/Engine/Session.cs:748
 #, csharp-format
-msgid "Network switch failed - could not find network with host: {0}"
-msgstr "Byte av nätverk misslyckades - kunde inte hitta nätverk med värden: {0}"
+msgid "Network switch failed - could not find network: {0}"
+msgstr ""
+"Byte av nätverk misslyckades - kunde inte hitta nätverk med värden: {0}"
 
-#: ../src/Engine/Session.cs:720
+#: ../src/Engine/Session.cs:767
 msgid "Not connected to any network"
 msgstr "Inte ansluten till något nätverk"
 
+#: ../src/Engine/Session.cs:1013
+#, csharp-format
+msgid ""
+"Failed to write to chat history. Your chat history will not be preserved. "
+"Reason: {0}"
+msgstr ""
+"Kunde inte spara chatthistorik. Din chatthistorik kommer inte att "
+"bibehållas. Anledning: {0}"
+
 #. just in case the ProtocolManager is not setting the
 #. protocol chat
-#: ../src/Engine/Session.cs:1047
+#: ../src/Engine/Session.cs:1185
 msgid "Connect failed."
 msgstr "Anslutning misslyckades."
 
-#: ../src/Engine/Session.cs:1078
+#: ../src/Engine/Session.cs:1216
 #, csharp-format
 msgid "No protocol manager found for the protocol: {0}"
 msgstr "Ingen protokollshanterare funnen för protokollet: {0}"
 
+#: ../src/Engine/Session.cs:1448
+msgid "Welcome to Smuxi"
+msgstr "Välkommen till Smuxi"
+
+#: ../src/Engine/Session.cs:1455
+msgid "Type /help to get a list of available commands."
+msgstr "Skriv /help för en lista med tillgängliga kommandon."
+
+#: ../src/Engine/Session.cs:1461
+msgid ""
+"After you have made a connection the list of available commands changes. Go "
+"to the newly opened connection tab and use the /help command again to see "
+"the extended command list."
+msgstr ""
+"Efter att du har kopplat upp dig så ändras listan med tillgängliga "
+"kommandon. Gå till den nyligen öppnade anslutningsfliken och använd /help "
+"kommandot igen för att se den utökade kommandolistan."
+
 #: ../src/Engine/Config/UserListController.cs:117
 msgid "Username must not be empty."
 msgstr "Användarnamnet får inte vara tomt."
@@ -143,6 +192,17 @@ msgstr "Användaren \"{0}\" finns inte."
 msgid "User \"{0}\" already exists."
 msgstr "Användaren \"{0}\" finns redan."
 
-#~ msgid "Unknown protocol: {0}"
-#~ msgstr "Okänt protokoll: {0}"
+#: ../src/Engine/Config/ServerListController.cs:131
+msgid "Server hostname must not be empty."
+msgstr "Servers värdnamn får inte lämnas tomt."
+
+#: ../src/Engine/Config/ServerListController.cs:134
+msgid "Server hostname contains invalid characters (newline)."
+msgstr "Serverns värdnamn innehåller ogiltiga tecken (ny rad)."
+
+#: ../src/Engine/Config/ServerListController.cs:140
+#, csharp-format
+msgid "Server '{0}' already exists."
+msgstr "Servern '{0}' finns redan."
+
 
diff --git a/po-Engine/tr.po b/po-Engine/tr.po
new file mode 100644
index 0000000..afded66
--- /dev/null
+++ b/po-Engine/tr.po
@@ -0,0 +1,171 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Umut Albayrak <umutmuh at gmail.com>, 2011.
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2011-03-22 15:43+0000\n"
+"Last-Translator: Umut Albayrak <umutmuh at gmail.com>\n"
+"Language-Team: Turkish (http://www.transifex.net/projects/p/smuxi/team/tr/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: tr\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ../src/Engine/FrontendManager.cs:230
+msgid "No network connections"
+msgstr ""
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:161
+msgid "Not connected to server"
+msgstr "Sunucuya bağlanılamadı"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:173
+#: ../src/Engine/Session.cs:751
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr ""
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
+#, csharp-format
+msgid "Connected to {0}"
+msgstr ""
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:213
+#, csharp-format
+msgid "Disconnected from {0}"
+msgstr ""
+
+#: ../src/Engine/Session.cs:154
+msgid "Welcome to Smuxi"
+msgstr "Smuxi'ye hoÅŸgeldiniz"
+
+#: ../src/Engine/Session.cs:160
+msgid "Type /help to get a list of available commands."
+msgstr "Yazılabilecek komutlar için /help yazın"
+
+#: ../src/Engine/Session.cs:163
+msgid ""
+"After you have made a connection the list of available commands changes. Use"
+" the /help command again to see the extended command list."
+msgstr ""
+
+#: ../src/Engine/Session.cs:216
+#, csharp-format
+msgid "Automatic connect to {0} failed!"
+msgstr ""
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine/Session.cs:411
+msgid "Engine Commands"
+msgstr ""
+
+#: ../src/Engine/Session.cs:514
+msgid "Connect failed!"
+msgstr ""
+
+#: ../src/Engine/Session.cs:544
+#, csharp-format
+msgid "Disconnect failed - could not find server: {0}"
+msgstr ""
+
+#: ../src/Engine/Session.cs:583
+msgid "Reconnect failed!"
+msgstr ""
+
+#: ../src/Engine/Session.cs:602
+msgid "Configuration reloaded"
+msgstr ""
+
+#: ../src/Engine/Session.cs:607
+msgid "Configuration saved"
+msgstr ""
+
+#: ../src/Engine/Session.cs:611
+msgid "Invalid parameter for config; use load or save"
+msgstr ""
+
+#: ../src/Engine/Session.cs:641
+msgid "Invalid parameter for network; use list, switch, or close"
+msgstr ""
+
+#: ../src/Engine/Session.cs:652
+msgid "Networks"
+msgstr ""
+
+#: ../src/Engine/Session.cs:656
+msgid "Type"
+msgstr ""
+
+#: ../src/Engine/Session.cs:657
+msgid "Host"
+msgstr ""
+
+#: ../src/Engine/Session.cs:658
+msgid "Port"
+msgstr ""
+
+#: ../src/Engine/Session.cs:680
+#, csharp-format
+msgid "Network close failed - could not find network with host: {0}"
+msgstr ""
+
+#: ../src/Engine/Session.cs:725
+#, csharp-format
+msgid "Network switch failed - could not find network with host: {0}"
+msgstr ""
+
+#: ../src/Engine/Session.cs:740
+msgid "Not connected to any network"
+msgstr ""
+
+#. just in case the ProtocolManager is not setting the
+#. protocol chat
+#: ../src/Engine/Session.cs:1067
+msgid "Connect failed."
+msgstr ""
+
+#: ../src/Engine/Session.cs:1098
+#, csharp-format
+msgid "No protocol manager found for the protocol: {0}"
+msgstr ""
+
+#: ../src/Engine/Config/UserListController.cs:117
+msgid "Username must not be empty."
+msgstr ""
+
+#: ../src/Engine/Config/UserListController.cs:127
+msgid "Password must not be empty."
+msgstr ""
+
+#: ../src/Engine/Config/UserListController.cs:136
+#, csharp-format
+msgid "User \"{0}\" doesn't exist."
+msgstr ""
+
+#: ../src/Engine/Config/UserListController.cs:145
+#, csharp-format
+msgid "User \"{0}\" already exists."
+msgstr ""
+
+#: ../src/Engine/Config/ServerListController.cs:131
+msgid "Server hostname must not be empty."
+msgstr ""
+
+#: ../src/Engine/Config/ServerListController.cs:134
+msgid "Server hostname contains invalid characters (newline)."
+msgstr ""
+
+#: ../src/Engine/Config/ServerListController.cs:140
+#, csharp-format
+msgid "Server '{0}' already exists."
+msgstr ""
+
+
diff --git a/po-Engine/ur.po b/po-Engine/ur.po
new file mode 100644
index 0000000..0223fdd
--- /dev/null
+++ b/po-Engine/ur.po
@@ -0,0 +1,170 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: Urdu (http://www.transifex.net/projects/p/smuxi/team/ur/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ur\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: ../src/Engine/FrontendManager.cs:230
+msgid "No network connections"
+msgstr ""
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:161
+msgid "Not connected to server"
+msgstr ""
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:173
+#: ../src/Engine/Session.cs:751
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr ""
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
+#, csharp-format
+msgid "Connected to {0}"
+msgstr ""
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:213
+#, csharp-format
+msgid "Disconnected from {0}"
+msgstr ""
+
+#: ../src/Engine/Session.cs:154
+msgid "Welcome to Smuxi"
+msgstr ""
+
+#: ../src/Engine/Session.cs:160
+msgid "Type /help to get a list of available commands."
+msgstr ""
+
+#: ../src/Engine/Session.cs:163
+msgid ""
+"After you have made a connection the list of available commands changes. Use"
+" the /help command again to see the extended command list."
+msgstr ""
+
+#: ../src/Engine/Session.cs:216
+#, csharp-format
+msgid "Automatic connect to {0} failed!"
+msgstr ""
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine/Session.cs:411
+msgid "Engine Commands"
+msgstr ""
+
+#: ../src/Engine/Session.cs:514
+msgid "Connect failed!"
+msgstr ""
+
+#: ../src/Engine/Session.cs:544
+#, csharp-format
+msgid "Disconnect failed - could not find server: {0}"
+msgstr ""
+
+#: ../src/Engine/Session.cs:583
+msgid "Reconnect failed!"
+msgstr ""
+
+#: ../src/Engine/Session.cs:602
+msgid "Configuration reloaded"
+msgstr ""
+
+#: ../src/Engine/Session.cs:607
+msgid "Configuration saved"
+msgstr ""
+
+#: ../src/Engine/Session.cs:611
+msgid "Invalid parameter for config; use load or save"
+msgstr ""
+
+#: ../src/Engine/Session.cs:641
+msgid "Invalid parameter for network; use list, switch, or close"
+msgstr ""
+
+#: ../src/Engine/Session.cs:652
+msgid "Networks"
+msgstr ""
+
+#: ../src/Engine/Session.cs:656
+msgid "Type"
+msgstr ""
+
+#: ../src/Engine/Session.cs:657
+msgid "Host"
+msgstr ""
+
+#: ../src/Engine/Session.cs:658
+msgid "Port"
+msgstr ""
+
+#: ../src/Engine/Session.cs:680
+#, csharp-format
+msgid "Network close failed - could not find network with host: {0}"
+msgstr ""
+
+#: ../src/Engine/Session.cs:725
+#, csharp-format
+msgid "Network switch failed - could not find network with host: {0}"
+msgstr ""
+
+#: ../src/Engine/Session.cs:740
+msgid "Not connected to any network"
+msgstr ""
+
+#. just in case the ProtocolManager is not setting the
+#. protocol chat
+#: ../src/Engine/Session.cs:1067
+msgid "Connect failed."
+msgstr ""
+
+#: ../src/Engine/Session.cs:1098
+#, csharp-format
+msgid "No protocol manager found for the protocol: {0}"
+msgstr ""
+
+#: ../src/Engine/Config/UserListController.cs:117
+msgid "Username must not be empty."
+msgstr ""
+
+#: ../src/Engine/Config/UserListController.cs:127
+msgid "Password must not be empty."
+msgstr ""
+
+#: ../src/Engine/Config/UserListController.cs:136
+#, csharp-format
+msgid "User \"{0}\" doesn't exist."
+msgstr ""
+
+#: ../src/Engine/Config/UserListController.cs:145
+#, csharp-format
+msgid "User \"{0}\" already exists."
+msgstr ""
+
+#: ../src/Engine/Config/ServerListController.cs:131
+msgid "Server hostname must not be empty."
+msgstr ""
+
+#: ../src/Engine/Config/ServerListController.cs:134
+msgid "Server hostname contains invalid characters (newline)."
+msgstr ""
+
+#: ../src/Engine/Config/ServerListController.cs:140
+#, csharp-format
+msgid "Server '{0}' already exists."
+msgstr ""
+
+
diff --git a/po-Engine/zh_CN.po b/po-Engine/zh_CN.po
new file mode 100644
index 0000000..87c5dc1
--- /dev/null
+++ b/po-Engine/zh_CN.po
@@ -0,0 +1,199 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Dean Lee <xslidian at gmail.com>, 2011.
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:19+0100\n"
+"PO-Revision-Date: 2011-12-30 16:01+0000\n"
+"Last-Translator: Dean Lee <xslidian at gmail.com>\n"
+"Language-Team: Chinese (China) (http://www.transifex.net/projects/p/smuxi/team/zh_CN/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: zh_CN\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ../src/Engine/FrontendManager.cs:233
+msgid "No network connections"
+msgstr "无网络连接"
+
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:295
+#, csharp-format
+msgid "Optimizing: {0}..."
+msgstr "正在优化: {0}..."
+
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:313
+#, csharp-format
+msgid "Failed to optimize: {0}. Reason: {1}"
+msgstr "优化失败: {0}。原因: {1}"
+
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:347
+msgid ""
+"Your chat history is no longer available because of an error but will be "
+"preserved from now on."
+msgstr "由于发生错误,您的聊天历史不再可用;但今后的聊天历史将会保留。"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:170
+msgid "Not connected to server"
+msgstr "未连接到服务器"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:178
+#: ../src/Engine/Session.cs:778
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr "{0} 命令参数不足"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
+#, csharp-format
+msgid "Connected to {0}"
+msgstr "已连接到 {0}"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:207
+#, csharp-format
+msgid "Disconnected from {0}"
+msgstr "已从 {0} 断开连接"
+
+#: ../src/Engine/Session.cs:218
+#, csharp-format
+msgid "Automatic connect to {0} failed!"
+msgstr "自动连接 {0} 失败!"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine/Session.cs:416
+msgid "Engine Commands"
+msgstr "引擎命令"
+
+#: ../src/Engine/Session.cs:527
+msgid "Connect failed!"
+msgstr "连接失败!"
+
+#: ../src/Engine/Session.cs:550
+#, csharp-format
+msgid "Disconnect failed - could not find server: {0}"
+msgstr "连接断开失败 - 找不到服务器: {0}"
+
+#: ../src/Engine/Session.cs:589
+msgid "Reconnect failed!"
+msgstr "重新连接失败!"
+
+#: ../src/Engine/Session.cs:608
+msgid "Configuration reloaded"
+msgstr "配置已重新载入"
+
+#: ../src/Engine/Session.cs:613
+msgid "Configuration saved"
+msgstr "配置已保存"
+
+#: ../src/Engine/Session.cs:617
+msgid "Invalid parameter for config; use load or save"
+msgstr "config 的参数无效; 使用 load 或 save"
+
+#: ../src/Engine/Session.cs:676
+msgid "Invalid parameter for network; use list, switch, or close"
+msgstr "network 的参数无效; 使用 list、switch 或 close"
+
+#: ../src/Engine/Session.cs:687
+msgid "Networks"
+msgstr "网络"
+
+#: ../src/Engine/Session.cs:691
+msgid "Protocol"
+msgstr "协议"
+
+#: ../src/Engine/Session.cs:692
+msgid "Network"
+msgstr "网络"
+
+#: ../src/Engine/Session.cs:693
+msgid "Host"
+msgstr "主机"
+
+#: ../src/Engine/Session.cs:694
+msgid "Port"
+msgstr "端口"
+
+#: ../src/Engine/Session.cs:709
+#, csharp-format
+msgid "Network close failed - could not find network: {0}"
+msgstr "网络关闭失败——无法找到网络: {0}"
+
+#: ../src/Engine/Session.cs:748
+#, csharp-format
+msgid "Network switch failed - could not find network: {0}"
+msgstr "网络切换失败——无法找到网络: {0}"
+
+#: ../src/Engine/Session.cs:767
+msgid "Not connected to any network"
+msgstr "未连接到任何网络"
+
+#: ../src/Engine/Session.cs:1013
+#, csharp-format
+msgid ""
+"Failed to write to chat history. Your chat history will not be preserved. "
+"Reason: {0}"
+msgstr "无法写入聊天历史。您的聊天历史将不会保存。原因: {0}"
+
+#. just in case the ProtocolManager is not setting the
+#. protocol chat
+#: ../src/Engine/Session.cs:1185
+msgid "Connect failed."
+msgstr "连接失败。"
+
+#: ../src/Engine/Session.cs:1216
+#, csharp-format
+msgid "No protocol manager found for the protocol: {0}"
+msgstr "未找到该协议的协议管理器: {0}"
+
+#: ../src/Engine/Session.cs:1448
+msgid "Welcome to Smuxi"
+msgstr "欢迎来到 Smuxi"
+
+#: ../src/Engine/Session.cs:1455
+msgid "Type /help to get a list of available commands."
+msgstr "输入 /help 获取可用命令列表。"
+
+#: ../src/Engine/Session.cs:1461
+msgid ""
+"After you have made a connection the list of available commands changes. Go "
+"to the newly opened connection tab and use the /help command again to see "
+"the extended command list."
+msgstr "连接后可用命令列表将有所变化。请访问新打开的连接页面,再次使用 /help 命令查看扩展后的命令列表。"
+
+#: ../src/Engine/Config/UserListController.cs:117
+msgid "Username must not be empty."
+msgstr "用户名不能为空。"
+
+#: ../src/Engine/Config/UserListController.cs:127
+msgid "Password must not be empty."
+msgstr "密码不能为空。"
+
+#: ../src/Engine/Config/UserListController.cs:136
+#, csharp-format
+msgid "User \"{0}\" doesn't exist."
+msgstr "用户 \"{0}\" 不存在。"
+
+#: ../src/Engine/Config/UserListController.cs:145
+#, csharp-format
+msgid "User \"{0}\" already exists."
+msgstr "用户名 \"{0}\" 已存在。"
+
+#: ../src/Engine/Config/ServerListController.cs:131
+msgid "Server hostname must not be empty."
+msgstr "服务器主机名不能为空。"
+
+#: ../src/Engine/Config/ServerListController.cs:134
+msgid "Server hostname contains invalid characters (newline)."
+msgstr "服务器主机名包含无效字符 (换行)。"
+
+#: ../src/Engine/Config/ServerListController.cs:140
+#, csharp-format
+msgid "Server '{0}' already exists."
+msgstr "服务器 '{0}' 已存在。"
+
+
diff --git a/po-Frontend-GNOME-IRC/LINGUAS b/po-Frontend-GNOME-IRC/LINGUAS
index c6a7441..2502b57 100644
--- a/po-Frontend-GNOME-IRC/LINGUAS
+++ b/po-Frontend-GNOME-IRC/LINGUAS
@@ -7,4 +7,6 @@ es_AR
 fr
 it
 pt
+ru
 sv
+zh_CN
diff --git a/po-Frontend-GNOME-IRC/POTFILES.skip b/po-Frontend-GNOME-IRC/POTFILES.skip
index 59dee6c..e193022 100644
--- a/po-Frontend-GNOME-IRC/POTFILES.skip
+++ b/po-Frontend-GNOME-IRC/POTFILES.skip
@@ -8,6 +8,8 @@ src/Engine-XMPP/
 src/Engine-Twitter/
 src/Frontend/
 src/Frontend-GNOME/
+src/Frontend-STFL/
 src/Frontend-SWF/
 src/Frontend-WPF/
 src/Server/
+lib/
diff --git a/po-Frontend-GNOME-IRC/da.po b/po-Frontend-GNOME-IRC/da.po
index 6f76318..875536e 100644
--- a/po-Frontend-GNOME-IRC/da.po
+++ b/po-Frontend-GNOME-IRC/da.po
@@ -1,69 +1,70 @@
-# Danish translation smuxi-frontend-gnome-irc.
-# Copyright (C) 2010 Mirco Bauer & nedenstående oversættere.
-# This file is distributed under the same license as the smuxi-frontend-gnome-irc package.
-# Joe Hansen (joedalton2 at yahoo.dk), 2010.
-#
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
 msgid ""
 msgstr ""
-"Project-Id-Version: smuxi-frontend-gnome-irc\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-16 12:42+0000\n"
-"Last-Translator: Joe Hansen <joedalton2 at yahoo.dk>\n"
-"Language-Team: Danish <debian-l10n-danish at lists.debian.org>\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:22+0100\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: Danish (http://www.transifex.net/projects/p/smuxi/team/da/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Language: da\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:340
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:381
 msgid "Op"
 msgstr "Op"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:344
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:385
 msgid "Deop"
 msgstr "Deop"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:348
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:389
 msgid "Voice"
 msgstr "Voice"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:352
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:393
 msgid "Devoice"
 msgstr "Devoice"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:356
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:397
 msgid "Kick"
 msgstr "Smid ud"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:360
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:401
 msgid "Kick + Ban"
 msgstr "Smid ud + giv karantæne"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:364
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:405
 msgid "Ban"
 msgstr "Giv karantæne"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:368
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:409
 msgid "Unban"
 msgstr "Fjern karantæne"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:374
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:415
 msgid "Query"
 msgstr "Forespørgsel"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:378
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:61
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:419
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:64
 msgid "Whois"
 msgstr "Hvem er"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:382
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:65
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:423
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:68
 msgid "CTCP"
 msgstr "CTCP"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:391
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:72
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:432
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:75
 msgid "Invite to"
 msgstr "Inviter til"
 
@@ -86,3 +87,5 @@ msgstr "Finger"
 #: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:92
 msgid "Userinfo"
 msgstr "Brugerinfo"
+
+
diff --git a/po-Frontend-GNOME-IRC/de.po b/po-Frontend-GNOME-IRC/de.po
index 9727bae..f2ad716 100644
--- a/po-Frontend-GNOME-IRC/de.po
+++ b/po-Frontend-GNOME-IRC/de.po
@@ -1,68 +1,70 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-# Mirco Bauer <meebey at meebey.net>, 2008-2009.
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
 # 
+# Translators:
 msgid ""
 msgstr ""
-"Project-Id-Version: 0.6.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-01-10 23:57+0100\n"
-"Last-Translator: Bianca Mix <heavydemon at freenet.de>\n"
-"Language-Team: German Localization <debian-l10n-german at lists.debian.org>\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:22+0100\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: German (http://www.transifex.net/projects/p/smuxi/team/de/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: de\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:340
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:381
 msgid "Op"
 msgstr "Op"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:344
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:385
 msgid "Deop"
 msgstr "Deop"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:348
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:389
 msgid "Voice"
 msgstr "Voice"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:352
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:393
 msgid "Devoice"
 msgstr "Devoice"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:356
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:397
 msgid "Kick"
 msgstr "Kick"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:360
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:401
 msgid "Kick + Ban"
 msgstr "Kick + Ban"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:364
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:405
 msgid "Ban"
 msgstr "Ban"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:368
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:409
 msgid "Unban"
 msgstr "Unban"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:374
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:415
 msgid "Query"
 msgstr "Query"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:378
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:61
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:419
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:64
 msgid "Whois"
 msgstr "Whois"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:382
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:65
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:423
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:68
 msgid "CTCP"
 msgstr "CTCP"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:391
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:72
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:432
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:75
 msgid "Invite to"
 msgstr "Einladen zu"
 
@@ -85,3 +87,5 @@ msgstr "Finger"
 #: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:92
 msgid "Userinfo"
 msgstr "Benutzerinformationen"
+
+
diff --git a/po-Frontend-GNOME-IRC/es.po b/po-Frontend-GNOME-IRC/es.po
index c3eee05..b9d6855 100644
--- a/po-Frontend-GNOME-IRC/es.po
+++ b/po-Frontend-GNOME-IRC/es.po
@@ -2,82 +2,86 @@
 # Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
 # This file is distributed under the same license as the Smuxi package.
 # Juan Miguel Carrero <streinleght at gmail.com>, 2008.
-#
+# 
 msgid ""
 msgstr ""
 "Project-Id-Version: 0.6.2\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-01-09 15:32+0100\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Juan Miguel Carrero <streinleght at gmail.com>\n"
-"Language-Team: Spanish Spanish Localization <debian-l10n-spanish at lists."
-"debian.org>\n"
+"Language-Team: Spanish Spanish Localization <debian-l10n-spanish at lists.debian.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:53
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:340
 msgid "Op"
 msgstr "Op"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:57
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:344
 msgid "Deop"
 msgstr "Deop"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:61
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:348
 msgid "Voice"
 msgstr "Voz"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:65
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:352
 msgid "Devoice"
 msgstr "Quitar Voz"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:69
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:356
 msgid "Kick"
 msgstr "Patada"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:73
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:360
 msgid "Kick + Ban"
 msgstr "Patada + Ban"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:77
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:364
 msgid "Ban"
 msgstr "Ban"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:81
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:368
 msgid "Unban"
 msgstr "Quitar Ban"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:87
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:374
 msgid "Query"
 msgstr "Privado"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:91
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:57
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:378
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:61
 msgid "Whois"
 msgstr "Whois"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:96
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:61
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:382
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:65
 msgid "CTCP"
-msgstr ""
+msgstr "CTCP"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:99
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:66
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:391
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:72
+msgid "Invite to"
+msgstr "Invitar a"
+
+#: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:72
 msgid "Ping"
-msgstr ""
+msgstr "Ping"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:103
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:70
+#: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:77
 msgid "Version"
-msgstr ""
+msgstr "Versión"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:107
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:74
+#: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:82
 msgid "Time"
-msgstr ""
+msgstr "Hora"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:111
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:78
+#: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:87
 msgid "Finger"
-msgstr ""
+msgstr "Finger"
+
+#: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:92
+msgid "Userinfo"
+msgstr "Información de Usuario"
diff --git a/po-Frontend-GNOME-IRC/fr.po b/po-Frontend-GNOME-IRC/fr.po
index ee18500..b5d6da2 100644
--- a/po-Frontend-GNOME-IRC/fr.po
+++ b/po-Frontend-GNOME-IRC/fr.po
@@ -1,70 +1,70 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-# Clement BOURGEOIS <moonpyk at gmail.com>, 2008.
-#
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
 msgid ""
 msgstr ""
-"Project-Id-Version: Smuxi 0.6.2\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-15 22:27+0100\n"
-"Last-Translator: Clément Bourgeois <moonpyk at gmail.com>\n"
-"Language-Team: French Localization <debian-l10n-french at lists.debian.org>\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:22+0100\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: French (http://www.transifex.net/projects/p/smuxi/team/fr/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: French\n"
-"X-Poedit-Country: FRANCE\n"
+"Language: fr\n"
+"Plural-Forms: nplurals=2; plural=(n > 1)\n"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:340
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:381
 msgid "Op"
 msgstr "Opper"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:344
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:385
 msgid "Deop"
 msgstr "Enlever l'Op"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:348
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:389
 msgid "Voice"
 msgstr "Voicer"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:352
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:393
 msgid "Devoice"
 msgstr "Enlever le Voice"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:356
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:397
 msgid "Kick"
 msgstr "Kicker"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:360
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:401
 msgid "Kick + Ban"
 msgstr "Kicker + Bannir"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:364
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:405
 msgid "Ban"
 msgstr "Bannir"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:368
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:409
 msgid "Unban"
 msgstr "Enlever le ban"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:374
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:415
 msgid "Query"
 msgstr "Chat privé"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:378
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:61
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:419
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:64
 msgid "Whois"
 msgstr "Whois"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:382
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:65
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:423
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:68
 msgid "CTCP"
 msgstr "CTCP"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:391
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:72
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:432
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:75
 msgid "Invite to"
 msgstr "Inviter à"
 
@@ -87,3 +87,5 @@ msgstr "Finger"
 #: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:92
 msgid "Userinfo"
 msgstr "Userinfo"
+
+
diff --git a/po-Frontend-GNOME-IRC/it.po b/po-Frontend-GNOME-IRC/it.po
index 88a1dda..4b8b7c1 100644
--- a/po-Frontend-GNOME-IRC/it.po
+++ b/po-Frontend-GNOME-IRC/it.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: smuxi-frontend-gnome-irc\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
 "PO-Revision-Date: 2010-07-15 13:28+0200\n"
 "Last-Translator: Vincenzo Campanella <vinz65 at gmail.com>\n"
 "Language-Team: Italian <tp at lists.linux.it>\n"
diff --git a/po-Frontend-GNOME-IRC/pt.po b/po-Frontend-GNOME-IRC/pt.po
index ee10276..5bab0f2 100644
--- a/po-Frontend-GNOME-IRC/pt.po
+++ b/po-Frontend-GNOME-IRC/pt.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: smuxi-frontend-gnome-irc \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
+"POT-Creation-Date: 2010-09-11 11:55+0200\n"
 "PO-Revision-Date: 2010-07-15 01:56+0100\n"
 "Last-Translator: Américo Monteiro <a_monteiro at netcabo.pt>\n"
 "Language-Team: Portuguese <traduz at debianpt.org>\n"
@@ -88,4 +88,3 @@ msgstr "Finger"
 #: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:92
 msgid "Userinfo"
 msgstr "Informação do utilizador"
-
diff --git a/po-Frontend-GNOME-IRC/ru.po b/po-Frontend-GNOME-IRC/ru.po
new file mode 100644
index 0000000..4d1f0a6
--- /dev/null
+++ b/po-Frontend-GNOME-IRC/ru.po
@@ -0,0 +1,86 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: smuxi 0.8\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: \n"
+"Last-Translator: Urmas <davian818 at gmail.com>\n"
+"Language-Team: None <->\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=(n==1) ? 0 : (n%10==1 && n%100!=11 ? 3 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Poedit-Language: Russian\n"
+"X-Poedit-Country: RUSSIAN FEDERATION\n"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:340
+msgid "Op"
+msgstr "Сделать оператором"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:344
+msgid "Deop"
+msgstr "Убрать статус оператора"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:348
+msgid "Voice"
+msgstr ""
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:352
+msgid "Devoice"
+msgstr ""
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:356
+msgid "Kick"
+msgstr "Выгнать"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:360
+msgid "Kick + Ban"
+msgstr "Выгнать и запретить"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:364
+msgid "Ban"
+msgstr "Запретить"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:368
+msgid "Unban"
+msgstr "Разрешить"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:374
+msgid "Query"
+msgstr ""
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:378
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:61
+msgid "Whois"
+msgstr ""
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:382
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:65
+msgid "CTCP"
+msgstr "CTCP"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:391
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:72
+msgid "Invite to"
+msgstr "Пригласить"
+
+#: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:72
+msgid "Ping"
+msgstr ""
+
+#: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:77
+msgid "Version"
+msgstr "Версия"
+
+#: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:82
+msgid "Time"
+msgstr "Время"
+
+#: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:87
+msgid "Finger"
+msgstr ""
+
+#: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:92
+msgid "Userinfo"
+msgstr ""
+
diff --git a/po-Frontend-GNOME-IRC/sv.po b/po-Frontend-GNOME-IRC/sv.po
index 0a7f926..28bc5f4 100644
--- a/po-Frontend-GNOME-IRC/sv.po
+++ b/po-Frontend-GNOME-IRC/sv.po
@@ -1,71 +1,70 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-#
-# Martin Bagge <brother at bsnet.se>, 2009
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
 msgid ""
 msgstr ""
-"Project-Id-Version: Smuxi GNOME IRC\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-15 13:11+0100\n"
-"Last-Translator: Martin Bagge / brother <brother at bsnet.se>\n"
-"Language-Team: Swedish <debian-l10n-swedish at lists.debian.org>\n"
-"Language: sv\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:22+0100\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: Swedish (http://www.transifex.net/projects/p/smuxi/team/sv/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: Swedish\n"
-"X-Poedit-Country: Sweden\n"
+"Language: sv\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:340
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:381
 msgid "Op"
 msgstr "Gör till operatör"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:344
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:385
 msgid "Deop"
 msgstr "Ta bort operatörsskap"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:348
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:389
 msgid "Voice"
 msgstr "Voice"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:352
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:393
 msgid "Devoice"
 msgstr "Ta bort voice"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:356
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:397
 msgid "Kick"
 msgstr "Sparka"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:360
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:401
 msgid "Kick + Ban"
 msgstr "Sparka och stäng ute"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:364
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:405
 msgid "Ban"
 msgstr "Stäng ute"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:368
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:409
 msgid "Unban"
 msgstr "Upphäv utestängning"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:374
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:415
 msgid "Query"
 msgstr "Privat"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:378
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:61
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:419
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:64
 msgid "Whois"
 msgstr "Användarinformation"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:382
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:65
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:423
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:68
 msgid "CTCP"
 msgstr "CTCP"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:391
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:72
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:432
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:75
 msgid "Invite to"
 msgstr "Inbjud till"
 
@@ -89,3 +88,4 @@ msgstr "Finger"
 msgid "Userinfo"
 msgstr "Användarinformation"
 
+
diff --git a/po-Frontend-GNOME-IRC/zh_CN.po b/po-Frontend-GNOME-IRC/zh_CN.po
new file mode 100644
index 0000000..83538c3
--- /dev/null
+++ b/po-Frontend-GNOME-IRC/zh_CN.po
@@ -0,0 +1,91 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:22+0100\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: Chinese (China) (http://www.transifex.net/projects/p/smuxi/team/zh_CN/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: zh_CN\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:381
+msgid "Op"
+msgstr "设为版主"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:385
+msgid "Deop"
+msgstr "撤销版主"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:389
+msgid "Voice"
+msgstr "设为认证用户"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:393
+msgid "Devoice"
+msgstr "撤销认证用户"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:397
+msgid "Kick"
+msgstr "踢除"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:401
+msgid "Kick + Ban"
+msgstr "踢除+ 封禁"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:405
+msgid "Ban"
+msgstr "封禁"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:409
+msgid "Unban"
+msgstr "解封"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:415
+msgid "Query"
+msgstr "私聊"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:419
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:64
+msgid "Whois"
+msgstr "详情"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:423
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:68
+msgid "CTCP"
+msgstr "CTCP"
+
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:432
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:75
+msgid "Invite to"
+msgstr "邀请加入"
+
+#: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:72
+msgid "Ping"
+msgstr "Ping"
+
+#: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:77
+msgid "Version"
+msgstr "版本"
+
+#: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:82
+msgid "Time"
+msgstr "用户时间"
+
+#: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:87
+msgid "Finger"
+msgstr "真实姓名与空闲时间"
+
+#: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:92
+msgid "Userinfo"
+msgstr "用户信息"
+
+
diff --git a/po-Frontend-GNOME/LINGUAS b/po-Frontend-GNOME/LINGUAS
index 54679b1..ba49383 100644
--- a/po-Frontend-GNOME/LINGUAS
+++ b/po-Frontend-GNOME/LINGUAS
@@ -8,4 +8,6 @@ en_GB
 fr
 it
 pt
+ru
 sv
+zh_CN
diff --git a/po-Frontend-GNOME/POTFILES.in b/po-Frontend-GNOME/POTFILES.in
index d22c286..416e9c7 100644
--- a/po-Frontend-GNOME/POTFILES.in
+++ b/po-Frontend-GNOME/POTFILES.in
@@ -1,4 +1,5 @@
 glade/smuxi-frontend-gnome.glade
+src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in
 src/Frontend-GNOME/AboutDialog.cs
 src/Frontend-GNOME/CrashDialog.cs
 src/Frontend-GNOME/EngineManagerDialog.cs
diff --git a/po-Frontend-GNOME/POTFILES.skip b/po-Frontend-GNOME/POTFILES.skip
index b026f1e..4ec6ba2 100644
--- a/po-Frontend-GNOME/POTFILES.skip
+++ b/po-Frontend-GNOME/POTFILES.skip
@@ -3,6 +3,7 @@ src/Common/
 src/Frontend/
 src/Frontend-GNOME/obj/
 src/Frontend-GNOME-IRC/
+src/Frontend-STFL/
 src/Frontend-SWF/
 src/Frontend-WPF/
 src/Engine/
@@ -12,3 +13,4 @@ src/Engine-OSCAR/
 src/Engine-XMPP/
 src/Engine-Twitter/
 src/Server/
+lib/
diff --git a/po-Frontend-GNOME/ca.po b/po-Frontend-GNOME/ca.po
index 931ed70..d2feca7 100644
--- a/po-Frontend-GNOME/ca.po
+++ b/po-Frontend-GNOME/ca.po
@@ -2,12 +2,12 @@
 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the PACKAGE package.
 # FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
-#
+# 
 msgid ""
 msgstr ""
 "Project-Id-Version: Smuxi\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:35+0200\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
 "PO-Revision-Date: 2010-07-18 19:35+0100\n"
 "Last-Translator: Siegfried-Angel Gevatter Pujals <rainct at ubuntu.com>\n"
 "Language-Team: Siegfried-Angel Gevatter Pujals <siegfried at gevatter.com>\n"
@@ -27,7 +27,7 @@ msgid "<b> Color </b>"
 msgstr "<b> Color </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:3
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1372
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1364
 msgid "<b> Entry Field </b>"
 msgstr "<b> Camp d'entrada </b>"
 
@@ -36,7 +36,7 @@ msgid "<b> Font </b>"
 msgstr "<b> Tipus de lletra </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:5
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1702
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1694
 msgid "<b> Highlighting </b>"
 msgstr "<b> Ressaltat </b>"
 
@@ -49,319 +49,359 @@ msgid "<b> Person List Position </b>"
 msgstr "<b> Posició de la llista de persones </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:8
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1209
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1201
 msgid "<b> Tab Colors </b>"
 msgstr "<b> Colors de les pestanyes </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:9
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1110
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1102
 msgid "<b> Tabs Position </b>"
 msgstr "<b> Posició de les pestanyes </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:10
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1515
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1507
 msgid "<b> Topic Position </b>"
 msgstr "<b> Posició del títol </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:11
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1161
+msgid "<b>General</b>"
+msgstr "<b>General</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:12
+msgid "<b>Global Commands</b>"
+msgstr "<b>Ordres globals</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:13
+msgid "<b>Messaging Menu</b>"
+msgstr "<b>Indicator de missatges</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:14
+msgid "<b>Network Proxy</b>"
+msgstr "<b>Servidor intermediari</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:15
+msgid "<b>Notification Popups</b>"
+msgstr "<b>Notificacions</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:16
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1153
 msgid "Activity"
 msgstr "Activitat"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:12
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:107
+#: ../glade/smuxi-frontend-gnome.glade.h:17
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:235
 msgid "Automatically connect to server at startup"
 msgstr "Connecta't automàticament al servidor a l'inici"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:13
+#: ../glade/smuxi-frontend-gnome.glade.h:18
 msgid "Background"
 msgstr "Fons"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:14
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1360
+#: ../glade/smuxi-frontend-gnome.glade.h:19
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1352
 msgid "Bash-Style Completion"
 msgstr "Completat semblant al del Bash"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:15
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1690
+#: ../glade/smuxi-frontend-gnome.glade.h:20
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1682
 msgid "Beep on highlight"
 msgstr "Fes un avís sonor en ressaltar una paraula"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:16
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:980
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1002
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1461
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1486
+#: ../glade/smuxi-frontend-gnome.glade.h:21
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:972
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:994
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1453
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1478
 msgid "Bottom"
 msgstr "A baix"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:17
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:746
+#: ../glade/smuxi-frontend-gnome.glade.h:22
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:738
 msgid "Buffer Lines:"
 msgstr "Línies a la memòria intermediària:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:18
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:671
+#: ../glade/smuxi-frontend-gnome.glade.h:23
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:663
 msgid "C_onnection"
 msgstr "_Connexió"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:19
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1312
+#: ../glade/smuxi-frontend-gnome.glade.h:24
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1304
 msgid "Command Character:"
 msgstr "Caràcter d'ordre:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:20
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1335
+#: ../glade/smuxi-frontend-gnome.glade.h:25
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1327
 msgid "Command History Size:"
 msgstr "Mida de l'historial d'ordres:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:21
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1292
+#: ../glade/smuxi-frontend-gnome.glade.h:26
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1284
 msgid "Completion Character:"
 msgstr "Caràcter de completat:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:22
+#: ../glade/smuxi-frontend-gnome.glade.h:27
 msgid "Enable"
 msgstr "Habilita"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:23
+#: ../glade/smuxi-frontend-gnome.glade.h:28
 msgid "Enabled"
 msgstr "Habilitat"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:24
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:559
+#: ../glade/smuxi-frontend-gnome.glade.h:29
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:551
 msgid "Encoding:"
 msgstr "Codificació:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:25
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:769
+#: ../glade/smuxi-frontend-gnome.glade.h:30
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:761
 msgid "Engine Buffer Lines:"
 msgstr "Línies a la memòria intermediària del motor:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:26
+#: ../glade/smuxi-frontend-gnome.glade.h:31
 msgid "Foreground"
 msgstr "Primer pla"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:27
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:925
+#: ../glade/smuxi-frontend-gnome.glade.h:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:917
 msgid "General"
 msgstr "General"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:28
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
+#: ../glade/smuxi-frontend-gnome.glade.h:33
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1173
 msgid "Highlight"
 msgstr "Ressaltat"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:29
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1666
+#: ../glade/smuxi-frontend-gnome.glade.h:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1658
 msgid "Highlight words:"
 msgstr "Paraules a ressaltar:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:30
+#: ../glade/smuxi-frontend-gnome.glade.h:35
+msgid "Host:"
+msgstr "Màquina:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:36
 msgid "Hostname:"
 msgstr "Nom de la màquina:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:31
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1381
+#: ../glade/smuxi-frontend-gnome.glade.h:37
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1373
 msgid "Input"
 msgstr "Entrada"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:32
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1171
+#: ../glade/smuxi-frontend-gnome.glade.h:38
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1163
 msgid "Join/Part/Mode"
 msgstr "Entra/Surt/Mode"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:33
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1016
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1041
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1535
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1561
+#: ../glade/smuxi-frontend-gnome.glade.h:39
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1008
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1033
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1527
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1553
 msgid "Left"
 msgstr "A l'esquerra"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:34
+#: ../glade/smuxi-frontend-gnome.glade.h:40
 msgid "Log Filtered Messages"
 msgstr "Enregistra els missatges filtrats"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:35
+#: ../glade/smuxi-frontend-gnome.glade.h:41
 msgid "Network:"
 msgstr "Xarxa:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:36
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1402
+#: ../glade/smuxi-frontend-gnome.glade.h:42
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1394
 msgid "Nick Colors"
 msgstr "Colors dels sobrenoms"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:37
+#: ../glade/smuxi-frontend-gnome.glade.h:43
 msgid "Nickname(s):"
 msgstr "Sobrenom(s):"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:38
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1153
+#: ../glade/smuxi-frontend-gnome.glade.h:44
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1145
 msgid "No Activity"
 msgstr "Sense activitat"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:39
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1096
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1501
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1616
+#: ../glade/smuxi-frontend-gnome.glade.h:45
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1088
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1493
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1608
 msgid "None"
 msgstr "Enlloc"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:40
+#: ../glade/smuxi-frontend-gnome.glade.h:46
 msgid "Notification"
 msgstr "Notificació"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:41
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:581
+#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:573
 msgid "On Connect Commands:"
 msgstr "Ordres al connectar:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:42
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:627
+#: ../glade/smuxi-frontend-gnome.glade.h:48
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:619
 msgid "On Startup Commands:"
 msgstr "Ordres a l'inici:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:43
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1714
+#: ../glade/smuxi-frontend-gnome.glade.h:49
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1706
 msgid "Output"
 msgstr "Sortida"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:44
+#: ../glade/smuxi-frontend-gnome.glade.h:50
 msgid "Override"
 msgstr "Sobreescriu"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:45
+#: ../glade/smuxi-frontend-gnome.glade.h:51
 msgid "Password:"
 msgstr "Contrasenya:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:46
+#: ../glade/smuxi-frontend-gnome.glade.h:52
 msgid "Port:"
 msgstr "Port:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../glade/smuxi-frontend-gnome.glade.h:53
 msgid "Protocol:"
 msgstr "Protocol:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:48
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:538
+#: ../glade/smuxi-frontend-gnome.glade.h:54
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:530
 msgid "Realname:"
 msgstr "Nom real:"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:49
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1056
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1081
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1576
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1601
+#: ../glade/smuxi-frontend-gnome.glade.h:55
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1048
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1073
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1568
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1593
 msgid "Right"
 msgstr "A la dreta"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:50
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:195
+#: ../glade/smuxi-frontend-gnome.glade.h:56
+msgid "Show Advanced Settings"
+msgstr "Mostra les opcions avançades"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:57
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:196
 msgid "Show Password"
 msgstr "Mostra la contrasenya"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:51
+#: ../glade/smuxi-frontend-gnome.glade.h:58
+msgid "Show Smuxi in the messaging menu"
+msgstr "Mostra el Smuxi a l'indicador de missatges"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:59
 msgid "Show always"
 msgstr "Sempre visible"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:52
+#: ../glade/smuxi-frontend-gnome.glade.h:60
+msgid "Show notification popups"
+msgstr "Mostra notificacions emergents"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:61
 msgid "Show when window is closed"
 msgstr "Visible quan la finestra està tancada"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:53
+#: ../glade/smuxi-frontend-gnome.glade.h:62
 msgid "Show when window is minimized"
 msgstr "Visible quan la finestra està minimitzada"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:54
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:406
+#: ../glade/smuxi-frontend-gnome.glade.h:63
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:398
 msgid "Smuxi - Preferences"
 msgstr "Smuxi - Preferències"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:55
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:26
+#: ../glade/smuxi-frontend-gnome.glade.h:64
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:18
 msgid "Smuxi - Server"
 msgstr "Smuxi - Servidor"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:56
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:828
+#: ../glade/smuxi-frontend-gnome.glade.h:65
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:820
 msgid "Strip Colors"
 msgstr "Elimina els colors"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:57
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:867
+#: ../glade/smuxi-frontend-gnome.glade.h:66
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:859
 msgid "Strip Formattings"
 msgstr "Elimina el format"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:58
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:907
+#: ../glade/smuxi-frontend-gnome.glade.h:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:899
 msgid "Strip UTF-8"
 msgstr "Elimina caràcters UTF-8"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:59
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1222
+#: ../glade/smuxi-frontend-gnome.glade.h:68
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1214
 msgid "Tabs"
 msgstr "Pestanyes"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:60
+#: ../glade/smuxi-frontend-gnome.glade.h:69
 msgid "The nickname to use. You can specify extra nicknames (separated by spaces) which will be used as fallbacks when the first choice is not available. By default $nick_ and $nick__ will be used as fallbacks."
 msgstr "El sobrenom a utilitzar. Podeu especificar sobrenoms addicionals (separats per comes) a utilitzar alternativament en cas que la primera tria no estigui disponible. Per omissió, s'utilitza $nick_ i $nick__ com a sobrenoms alternatius."
 
-#: ../glade/smuxi-frontend-gnome.glade.h:61
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:726
+#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:718
 msgid "Timestamp Format:"
 msgstr "Format de les marques horàries:"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:62
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:943
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:967
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1420
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1446
+#: ../glade/smuxi-frontend-gnome.glade.h:71
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:935
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:959
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1412
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1438
 msgid "Top"
 msgstr "A dalt"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:63
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:515
+#: ../glade/smuxi-frontend-gnome.glade.h:72
+msgid "Type:"
+msgstr "Tipus:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:73
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:507
 msgid "Username:"
 msgstr "Nom d'usuari:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:64
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1881
+#: ../glade/smuxi-frontend-gnome.glade.h:74
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1873
 msgid "_Filters"
 msgstr "_Filtres"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:65
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1723
+#: ../glade/smuxi-frontend-gnome.glade.h:75
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1715
 msgid "_Interface"
 msgstr "_Interfície"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:66
+#: ../glade/smuxi-frontend-gnome.glade.h:76
 msgid "_Logging"
 msgstr "_Registre"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:67
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1789
+#: ../glade/smuxi-frontend-gnome.glade.h:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1781
 msgid "_Servers"
 msgstr "_Servidors"
 
 #. This is a setting for character based line wrapping vs word based when
 #. showing messages
-#: ../glade/smuxi-frontend-gnome.glade.h:69
+#: ../glade/smuxi-frontend-gnome.glade.h:79
 msgid "_Wrap Mode:"
 msgstr "_Ajustament de línia:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../glade/smuxi-frontend-gnome.glade.h:80
 msgid ""
 "ss = seconds\n"
 "mm = minutes\n"
@@ -383,31 +423,23 @@ msgstr ""
 "MM = mes\n"
 "yy/yyyy = any"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:52
-msgid "translator-credits"
-msgstr "Siegfried-Angel Gevatter Pujals <rainct at ubuntu.com>"
-
-#: ../src/Frontend-GNOME/AboutDialog.cs:47
-msgid "German"
-msgstr "Alemany"
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:1
+msgid "Chat with other people on IRC"
+msgstr "Xategeu amb altres persones a l'IRC"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:48
-msgid "Spanish"
-msgstr "Castellà"
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:2
+msgid "IRC Chat"
+msgstr "_Xat a l'IRC"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:49
-msgid "British English"
-msgstr "Anglès britànic"
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:3
+msgid "Smuxi IRC Client"
+msgstr "Client d'IRC Smuxi"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:50
-msgid "French"
-msgstr "Francès"
-
-#: ../src/Frontend-GNOME/AboutDialog.cs:51
-msgid "Italian"
-msgstr "Italià"
+#: ../src/Frontend-GNOME/AboutDialog.cs:58
+msgid "translator-credits"
+msgstr "Siegfried-Angel Gevatter Pujals <rainct at ubuntu.com>"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:54
+#: ../src/Frontend-GNOME/AboutDialog.cs:61
 msgid "Smuxi Website"
 msgstr "Pàgina web del Smuxi"
 
@@ -435,142 +467,151 @@ msgstr "Gestor de motors"
 msgid "_Connect"
 msgstr "_Connecta"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:78
-msgid "_Edit"
-msgstr "_Modifica"
-
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:90
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:84
 msgid "Select which Smuxi engine you want to connect to"
 msgstr "Trieu a quin motor del Smuxi us voleu connectar"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:96
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:90
 msgid "Engine:"
 msgstr "Motor:"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:122
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:182
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:359
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:116
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:176
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:353
 msgid "Local Engine"
 msgstr "Motor local"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:174
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:168
 msgid "Please select an engine!"
 msgstr "Trieu un motor!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:195
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:189
 #, csharp-format
 msgid "Your frontend version ({0}) does not match the engine version ({1})!"
 msgstr "La versió del frontal ({0}) no coincideix amb la versió del motor ({1})."
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:222
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:216
 msgid "An error occurred while connecting to the engine!"
 msgstr "S'ha produït un error al intentar connectar al motor."
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:223
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:217
 #, csharp-format
 msgid "Engine URL: {0}"
 msgstr "URL del motor: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:226
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:220
 #, csharp-format
 msgid "Error: {0}"
 msgstr "Error: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:296
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:290
 #, csharp-format
 msgid "Are you sure you want to delete the engine \"{0}\"?"
 msgstr "Esteu segur que voleu esborrar el motor «{0}»?"
 
-#: ../src/Frontend-GNOME/Entry.cs:403
+#: ../src/Frontend-GNOME/Entry.cs:421
 #, csharp-format
 msgid "You are going to paste {0} lines. Do you want to continue?"
 msgstr "Esteu a punt d'enganxar {0} línies. Voleu continuar?"
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Frontend-GNOME/Entry.cs:506
+#: ../src/Frontend-GNOME/Entry.cs:524
 msgid "Frontend Commands"
 msgstr "Ordres del frontal"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:186
+#: ../src/Frontend-GNOME/MainWindow.cs:222
 msgid "_File"
 msgstr "_Fitxer"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:202
+#: ../src/Frontend-GNOME/MainWindow.cs:238
 msgid "_Server"
 msgstr "_Servidor"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:206
+#: ../src/Frontend-GNOME/MainWindow.cs:242
 msgid "_Quick Connect"
 msgstr "_Connexió ràpida"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:217
+#: ../src/Frontend-GNOME/MainWindow.cs:253
 msgid "_Manage"
 msgstr "_Gestiona"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:224
+#: ../src/Frontend-GNOME/MainWindow.cs:260
 msgid "_Chat"
 msgstr "_Xat"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:228
+#: ../src/Frontend-GNOME/MainWindow.cs:264
 msgid "Open / Join Chat"
 msgstr "Obre / Uneix-te a una sala de xat"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:233
+#: ../src/Frontend-GNOME/MainWindow.cs:269
 msgid "_Find Group Chat"
 msgstr "_Troba sales de xat en grup"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:238
+#: ../src/Frontend-GNOME/MainWindow.cs:274
 msgid "C_lear All Activity"
 msgstr "_Neteja totes les activitats"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:245
+#: ../src/Frontend-GNOME/MainWindow.cs:281
 msgid "_Next Chat"
 msgstr "Xat _següent"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:255
+#: ../src/Frontend-GNOME/MainWindow.cs:291
 msgid "_Previous Chat"
 msgstr "Xat _anterior"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:307
+#: ../src/Frontend-GNOME/MainWindow.cs:341
+msgid "Open Log"
+msgstr "Obre el registre"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:355
 msgid "_Engine"
 msgstr "_Motor"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:311
+#: ../src/Frontend-GNOME/MainWindow.cs:359
 msgid "_Use Local Engine"
 msgstr "_Utilitza el motor local"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:317
+#: ../src/Frontend-GNOME/MainWindow.cs:365
 msgid "_Add Remote Engine"
 msgstr "_Afegeix un motor remot"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:322
+#: ../src/Frontend-GNOME/MainWindow.cs:370
 msgid "_Switch Remote Engine"
 msgstr "_Canvia el motor remot"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:329
+#: ../src/Frontend-GNOME/MainWindow.cs:377
 msgid "_View"
 msgstr "_Mostra"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:333
+#: ../src/Frontend-GNOME/MainWindow.cs:381
 msgid "_Caret Mode"
 msgstr "Navega amb el _cursor"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:343
+#: ../src/Frontend-GNOME/MainWindow.cs:389
+msgid "_Browse Mode"
+msgstr "Mode d'_exploració"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:403
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:586
+msgid "Show _Menubar"
+msgstr "Mostra la barra de _menú"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:430
 msgid "_Help"
 msgstr "_Ajuda"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:567
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:222
+#: ../src/Frontend-GNOME/MainWindow.cs:691
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:225
 msgid "Unable to add server: "
 msgstr "No s'ha pogut afegir el servidor:"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:614
+#: ../src/Frontend-GNOME/MainWindow.cs:742
 #, csharp-format
 msgid "Unknown ChatType: {0}"
 msgstr "Tipus de xat desconegut: {0}"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:822
+#: ../src/Frontend-GNOME/MainWindow.cs:971
 msgid ""
 "Switching to local engine will disconnect you from the current engine!\n"
 "Are you sure you want to do this?"
@@ -578,7 +619,7 @@ msgstr ""
 "Si canvieu al motor local us desconnectareu del vostre motor actual!\n"
 "Esteu segur que voleu fer això?"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:864
+#: ../src/Frontend-GNOME/MainWindow.cs:1013
 msgid ""
 "Switching the remote engine will disconnect you from the current engine!\n"
 "Are you sure you want to do this?"
@@ -591,44 +632,48 @@ msgid "Sorry, not implemented yet!"
 msgstr "Això encara no ha estat implementat."
 
 #. fill ListStore
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:162
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:179
 msgid "Character"
 msgstr "Caràcter"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:163
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:180
 msgid "Word"
 msgstr "Paraula"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:173
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:198
+msgid "No Proxy"
+msgstr "Sense servidor intermediari"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:212
 #: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:139
 msgid "Connection"
 msgstr "Connexió"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:177
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:216
 msgid "Interface"
 msgstr "Interfície"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:181
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:220
 msgid "Servers"
 msgstr "Servidors"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:185
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:227
 msgid "Filters"
 msgstr "Filtres"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:189
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:231
 msgid "Logging"
 msgstr "Registre"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:238
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:281
 msgid "System Default"
 msgstr "Predeterminat del sistema"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:505
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:588
 msgid "Nicknames(s) field must not be empty."
 msgstr "Cal indicar un o més sobrenoms."
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:649
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:748
 #, csharp-format
 msgid "Invalid highlight regex: '{0}'. Reason: {1}"
 msgstr "Expressió regular de ressaltat no vàlida: '{0}'. Motiu: {1}"
@@ -655,12 +700,12 @@ msgstr ""
 msgid "Error while fetching the list of group chats from the server."
 msgstr "S'ha produït un error en recuperar la llista de xats en grup del servidor."
 
-#: ../src/Frontend-GNOME/Frontend.cs:394
+#: ../src/Frontend-GNOME/Frontend.cs:399
 #, csharp-format
 msgid "Cause: {0}"
 msgstr "Motiu: {0}"
 
-#: ../src/Frontend-GNOME/Frontend.cs:464
+#: ../src/Frontend-GNOME/Frontend.cs:469
 msgid ""
 "The frontend has lost the connection to the server.\n"
 "Do you want to reconnect now?"
@@ -668,7 +713,7 @@ msgstr ""
 "El frontal ha perdut la connexió amb el servidor.\n"
 "Voleu tornar a connectar-hi?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:479
+#: ../src/Frontend-GNOME/Frontend.cs:484
 msgid ""
 "Reconnecting to the server has failed.\n"
 "Do you want to try again?"
@@ -676,7 +721,7 @@ msgstr ""
 "L'intent de reconnexió amb el servidor ha fallat.\n"
 "Voleu tornar-ho a intentar?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:580
+#: ../src/Frontend-GNOME/Frontend.cs:585
 msgid ""
 "The server has lost the connection to the frontend.\n"
 "Do you want to reconnect now?"
@@ -684,6 +729,10 @@ msgstr ""
 "El servidor ha perdut la connexió al frontal.\n"
 "Voleu tornar a connectar-hi?"
 
+#: ../src/Frontend-GNOME/NotifyManager.cs:229
+msgid "Show"
+msgstr "Mostra"
+
 #: ../src/Frontend-GNOME/QuickConnectDialog.cs:62
 #: ../src/Frontend-GNOME/Views/FilterListWidget.cs:238
 #: ../src/Frontend-GNOME/Preferences/ServerListView.cs:70
@@ -737,7 +786,7 @@ msgstr "Gràcies"
 msgid "An engine with this name already exists! Please specify a different one."
 msgstr "Ja existeix un motor amb aquest nom! Especifique-ne un altre."
 
-#: ../src/Frontend-GNOME/Views/MessageTextView.cs:182
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:198
 #, csharp-format
 msgid "Day changed to {0}"
 msgstr "El dia ha canviat a {0}"
@@ -776,17 +825,17 @@ msgstr "_Tipus"
 msgid "Pattern"
 msgstr "Patró"
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:241
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:242
 #, csharp-format
 msgid "Retrieving user list for {0}..."
 msgstr "S'està obtenint el llistat d'usuari per a {0}..."
 
 #. TRANSLATOR: this string will be appended to the one above
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:286
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:289
 msgid "done."
 msgstr "fet."
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:301
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:304
 msgid "Person"
 msgstr "Persones"
 
@@ -798,145 +847,145 @@ msgstr ""
 "Si tanqueu la pestanya del protocol es tancaran també totes les sales de xat que en depenen.\n"
 "Esteu segur que voleu fer això?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:184
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:187
 msgid "Are you sure you want to delete the selected server?"
 msgstr "Esteu segur que voleu eliminar el servidor seleccionat?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:240
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:274
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:243
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:277
 msgid "Unable to edit server: "
 msgstr "No es pot modificar el servidor:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:42
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:34
 msgid "Find"
 msgstr "Troba"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:62
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:54
 msgid "_Search for:"
 msgstr "_Cerca:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:91
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:83
 msgid "_Match Case"
 msgstr "Sensible a _majúscules"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:103
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:95
 msgid "Search _Backwards"
 msgstr "Cerca cap endarrere"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:115
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:107
 msgid "_Wrap Around"
 msgstr "_Torna a començar pel principi en arribar al final"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:128
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:120
 msgid "Use _Regular Expressions"
 msgstr "Utilitza expressions _regulars"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:40
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:32
 msgid "Smuxi - Find Group Chat"
 msgstr "Smuxi - Troba sales de xat"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:64
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:87
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:56
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:79
 msgid "_Name:"
 msgstr "_Nom:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:24
 msgid "Smuxi - Quick Connect"
 msgstr "Smuxi - Connexió ràpida"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:495
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:487
 msgid "Nicknames:"
 msgstr "Sobrenoms:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1630
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1622
 msgid "<b> User List Position </b>"
 msgstr "<b> Posició de la llista d'usuaris </b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1641
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1633
 msgid "<b> Channel </b>"
 msgstr "<b> Sala </b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1852
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1844
 msgid "<b>Channel Filters</b>"
 msgstr "<b>Filtres de canal</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1869
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1861
 msgid "<b>User Filters</b>"
 msgstr "<b>Filtres d'usuari</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:64
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:56
 msgid "Use _SSH Tunnel"
 msgstr "Utilitza un _túnel SSH"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:78
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:70
 msgid "<span size=\"small\">Enables the use of SSH for the connection.  This has a small performance impact, but is more secure and required when using NAT or port-based firewalls</span>"
 msgstr "<span size=\"small\">Habilita l'ús de l'SSH per a la connexió. Això afectarà lleugerament el rendiment, però és més segur i és necessari quan s'utilitza NAT o tallafocs que bloquegin certs ports.</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:157
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:149
 msgid "SSH _Host:"
 msgstr "S_ervidor SSH:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:168
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:160
 msgid "<span size=\"small\">DNS or IP address and port of the SSH server</span>"
 msgstr "<span size=\"small\">DNS o adreça IP i port del servidor SSH</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:181
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:195
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:154
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:173
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:187
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:155
 msgid "_Port:"
 msgstr "_Port:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:208
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:200
 msgid "<span size=\"small\">DNS or IP address and port of the Smuxi server</span>"
 msgstr "<span size=\"small\">DNS o adreça IP i port del servidor del Smuxi</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:221
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:213
 msgid "_Smuxi Host:"
 msgstr "Servidor _Smuxi:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:76
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:68
 msgid "_SSH Username: (optional)"
 msgstr "Nom d'usuari de l'SSH: (opcional)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:99
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:91
 msgid "<span size=\"small\">Username which will be used to log into the SSH server</span>"
 msgstr "<span size=\"small\">Nom d'usuari que s'utilitzarà per iniciar sessió al servidor SSH</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:119
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:111
 msgid "_SSH Password: (optional)"
 msgstr "Contrasenya de l'SSH: (opcional)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:143
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:135
 msgid "<span size=\"small\">Password which will be used to log into the SSH server. The password is optional if SSH key authorization is used (via Pageant from the PuTTY tools).</span>"
 msgstr "<span size=\"small\">Contrasenya que s'utilitzarà per iniciar sessió al servidor SSH. La contrasenya és opcional si s'utilitza autenticació via claus SSH (mitjançant Pageant, de les eines PuTTY).</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:164
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:223
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:156
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:214
 msgid "_Username:"
 msgstr "_Sobrenom:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:187
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:179
 msgid "<span size=\"small\">Username which will be used to log into the Smuxi server</span>"
 msgstr "<span size=\"small\">Nom d'usuari que s'utilitzarà per iniciar sessió al servidor del Smuxi.</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:207
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:233
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:199
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:113
 msgid "_Password:"
 msgstr "_Contrasenya:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:231
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:223
 msgid "<span size=\"small\">Password of the user</span>"
 msgstr "<span size=\"small\">Contrasenya de l'usuari</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:251
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:243
 msgid "_Verify Password:"
 msgstr "_Repetiu la contrasenya:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:275
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:267
 msgid "<span size=\"small\">Repeat the password for verification</span>"
 msgstr "<span size=\"small\">Repetiu la contrasenya per assegurar que l'heu escrita correctament</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs:27
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs:19
 msgid ""
 "Welcome to the Smuxi Engine Configuration Assistant.\n"
 "You need to enter some information before you can use the engine.\n"
@@ -946,58 +995,85 @@ msgstr ""
 "Benvingut a l'assistent de configuració de motors dels Smuxi.\n"
 "Cal que introduïu una mica d'informació abans de començar a utilitzar el motor. Premeu «Endavant» per a començar."
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:52
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:44
 msgid "_Engine Name:"
 msgstr "Nom del _motor:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:75
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:67
 msgid "<span size=\"small\">Profile name of the new engine</span>"
 msgstr "<span size=\"small\">Nom per al nou perfil de motor</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:96
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:88
 msgid "_Default Engine:"
 msgstr "_Motor predeterminat:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:107
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:99
 msgid "Use as new default engine"
 msgstr "Utilitza'l com a nou motor predeterminat"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:120
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:112
 msgid "<span size=\"small\">If enabled, the current engine will be the default next time Smuxi is started</span>"
 msgstr "<span size=\"small\">Si marqueu la casella, la propera vegada que inicieu l'Smuxi el motor que esteu configurant s'utilitzarà de forma predeterminada.</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:26
 msgid "Smuxi - Open Chat"
 msgstr "Smuxi - Obre un xat"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:69
 msgid "_Type:"
 msgstr "_Tipus:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:95
-msgid "_Network:"
-msgstr "_Xarxa:"
-
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:213
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:80
 msgid "_Hostname:"
 msgstr "_Nom de la màquina:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:243
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:101
+msgid "_Network:"
+msgstr "_Xarxa:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:224
 msgid "_Protocol:"
 msgstr "_Protocol:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:262
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:248
+msgid "Use Encryption"
+msgstr "Utilitza xifratge"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:260
+msgid "Validate Server Certificate"
+msgstr "Valida el certificat del servidor"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:280
 msgid "_On Connect Commands:"
 msgstr "_Ordres al connectar:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:273
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:291
 msgid "_Ignore Commands"
 msgstr "_Ignora les ordres"
 
+#~ msgid "German"
+#~ msgstr "Alemany"
+
+#~ msgid "Spanish"
+#~ msgstr "Castellà"
+
+#~ msgid "British English"
+#~ msgstr "Anglès britànic"
+
+#~ msgid "French"
+#~ msgstr "Francès"
+
+#~ msgid "Italian"
+#~ msgstr "Italià"
+
+#~ msgid "_Edit"
+#~ msgstr "_Modifica"
+
 #~ msgid "Joins"
 #~ msgstr "Entrades"
+
 #~ msgid "Parts"
 #~ msgstr "Sortides"
+
 #~ msgid "Quits"
 #~ msgstr "Desconnexions"
-
diff --git a/po-Frontend-GNOME/da.po b/po-Frontend-GNOME/da.po
index 2aced6d..a83ead8 100644
--- a/po-Frontend-GNOME/da.po
+++ b/po-Frontend-GNOME/da.po
@@ -1,20 +1,22 @@
-# Danish translation smuxi-frontend-gnome.
-# Copyright (C) 2010 Mirco Bauer & nedenstående oversættere.
-# This file is distributed under the same license as the smuxi-frontend-gnome package.
-# Joe Hansen (joedalton2 at yahoo.dk), 2010.
-#
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Joe Hansen <joedalton2 at yahoo.dk>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: smuxi-frontend-gnome\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-08-10 19:14+0200\n"
-"PO-Revision-Date: 2010-08-14 12:42+0000\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:22+0100\n"
+"PO-Revision-Date: 2011-12-29 20:04+0000\n"
 "Last-Translator: Joe Hansen <joedalton2 at yahoo.dk>\n"
-"Language-Team: Danish <debian-l10n-danish at lists.debian.org>\n"
+"Language-Team: Danish (http://www.transifex.net/projects/p/smuxi/team/da/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Language: da\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:1
 msgid "<b> Chat </b>"
@@ -25,7 +27,7 @@ msgid "<b> Color </b>"
 msgstr "<b> Farve </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:3
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1364
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1172
 msgid "<b> Entry Field </b>"
 msgstr "<b> Indtastningsfelt </b>"
 
@@ -34,7 +36,7 @@ msgid "<b> Font </b>"
 msgstr "<b> Skrifttype </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:5
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1694
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1502
 msgid "<b> Highlighting </b>"
 msgstr "<b> Fremhævelse </b>"
 
@@ -47,288 +49,321 @@ msgid "<b> Person List Position </b>"
 msgstr "<b> Placering af personliste </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:8
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1201
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1009
 msgid "<b> Tab Colors </b>"
 msgstr "<b> Fanebladsfarver </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:9
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1102
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:910
 msgid "<b> Tabs Position </b>"
 msgstr "<b> Fanebladsplacering </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:10
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1507
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1315
 msgid "<b> Topic Position </b>"
 msgstr "<b> Emneplacering </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:11
+msgid "<b>Advanced</b>"
+msgstr "<b>Avanceret</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:12
+msgid "<b>General</b>"
+msgstr "<b>Generelt</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:13
+msgid "<b>Global Commands</b>"
+msgstr "<b>Globale kommandoer</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:14
+msgid "<b>Message Buffer</b>"
+msgstr "<b>Beskedmellemlager</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:15
 msgid "<b>Messaging Menu</b>"
 msgstr "<b>Beskedmenu</b>"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:12
+#: ../glade/smuxi-frontend-gnome.glade.h:16
+msgid "<b>Network Proxy</b>"
+msgstr "<b>Netværksproxy</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:17
 msgid "<b>Notification Popups</b>"
 msgstr "<b>PÃ¥mindelses-pop op'er</b>"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:13
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1153
+#: ../glade/smuxi-frontend-gnome.glade.h:18
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:961
 msgid "Activity"
 msgstr "Aktivitet"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:14
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:99
+#: ../glade/smuxi-frontend-gnome.glade.h:19
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:209
 msgid "Automatically connect to server at startup"
 msgstr "Tilslut automatisk til server ved opstart"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:15
+#: ../glade/smuxi-frontend-gnome.glade.h:20
 msgid "Background"
 msgstr "Baggrund"
 
-# yak, hvad er det her?
-#: ../glade/smuxi-frontend-gnome.glade.h:16
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1352
+#: ../glade/smuxi-frontend-gnome.glade.h:21
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1160
 msgid "Bash-Style Completion"
 msgstr "Bashagtig fuldførelse"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:17
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1682
+#: ../glade/smuxi-frontend-gnome.glade.h:22
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1490
 msgid "Beep on highlight"
 msgstr "Beep ved fremhævelse"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:18
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:972
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:994
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1453
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1478
+#: ../glade/smuxi-frontend-gnome.glade.h:23
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:780
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:802
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1261
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1286
 msgid "Bottom"
 msgstr "Bund"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:19
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:738
+#: ../glade/smuxi-frontend-gnome.glade.h:24
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:546
 msgid "Buffer Lines:"
 msgstr "Mellemlagerlinjer:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:20
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:663
+#: ../glade/smuxi-frontend-gnome.glade.h:25
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:471
 msgid "C_onnection"
 msgstr "_Tilslutning"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:21
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1304
+#: ../glade/smuxi-frontend-gnome.glade.h:26
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1112
 msgid "Command Character:"
 msgstr "Kommandotegn:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:22
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1327
+#: ../glade/smuxi-frontend-gnome.glade.h:27
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1135
 msgid "Command History Size:"
 msgstr "Historikstørrelse for kommando:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:23
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1284
+#: ../glade/smuxi-frontend-gnome.glade.h:28
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1092
 msgid "Completion Character:"
 msgstr "Afslutningstegn:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:24
+#: ../glade/smuxi-frontend-gnome.glade.h:29
 msgid "Enable"
 msgstr "Aktiver"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:25
+#: ../glade/smuxi-frontend-gnome.glade.h:30
 msgid "Enabled"
 msgstr "Aktiveret"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:26
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:551
+#: ../glade/smuxi-frontend-gnome.glade.h:31
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:359
 msgid "Encoding:"
 msgstr "Kodning:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:27
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:761
+#: ../glade/smuxi-frontend-gnome.glade.h:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:569
 msgid "Engine Buffer Lines:"
 msgstr "Mellemlagerlinjer for motor:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:28
+#: ../glade/smuxi-frontend-gnome.glade.h:33
 msgid "Foreground"
 msgstr "Forgrund"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:29
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:917
+#: ../glade/smuxi-frontend-gnome.glade.h:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:725
 msgid "General"
 msgstr "Generelt"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:30
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1173
+#: ../glade/smuxi-frontend-gnome.glade.h:35
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:981
 msgid "Highlight"
 msgstr "Fremhæv"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:31
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1658
+#: ../glade/smuxi-frontend-gnome.glade.h:36
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1466
 msgid "Highlight words:"
 msgstr "Fremhæv ord:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:32
+#: ../glade/smuxi-frontend-gnome.glade.h:37
+msgid "Host:"
+msgstr "Vært:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:38
 msgid "Hostname:"
 msgstr "Værtsnavn:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:33
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1373
+#: ../glade/smuxi-frontend-gnome.glade.h:39
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
 msgid "Input"
 msgstr "Inddata"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:34
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1163
+#: ../glade/smuxi-frontend-gnome.glade.h:40
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:971
 msgid "Join/Part/Mode"
 msgstr "Deltag/del/tilstand"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:35
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1008
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1033
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1527
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1553
+#: ../glade/smuxi-frontend-gnome.glade.h:41
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:816
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:841
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1335
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1361
 msgid "Left"
 msgstr "Venstre"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:36
+#: ../glade/smuxi-frontend-gnome.glade.h:42
 msgid "Log Filtered Messages"
 msgstr "Logfiltrerede beskeder"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:37
+#: ../glade/smuxi-frontend-gnome.glade.h:43
 msgid "Network:"
 msgstr "Netværk:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:38
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1394
+#: ../glade/smuxi-frontend-gnome.glade.h:44
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1202
 msgid "Nick Colors"
 msgstr "Farver for brugernavn"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:39
+#: ../glade/smuxi-frontend-gnome.glade.h:45
 msgid "Nickname(s):"
 msgstr "Brugernavne:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:40
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1145
+#: ../glade/smuxi-frontend-gnome.glade.h:46
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:953
 msgid "No Activity"
 msgstr "Ingen aktivitet"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:41
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1088
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1493
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1608
+#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:896
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1301
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1416
 msgid "None"
 msgstr "Ingen"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:42
+#: ../glade/smuxi-frontend-gnome.glade.h:48
 msgid "Notification"
 msgstr "PÃ¥mindelse"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:43
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:573
+#: ../glade/smuxi-frontend-gnome.glade.h:49
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:381
 msgid "On Connect Commands:"
 msgstr "Ingen tilslutningskommandoer:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:44
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:619
+#: ../glade/smuxi-frontend-gnome.glade.h:50
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:427
 msgid "On Startup Commands:"
 msgstr "Ingen opstartskommandoer:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:45
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1706
+#: ../glade/smuxi-frontend-gnome.glade.h:51
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1514
 msgid "Output"
 msgstr "Uddata"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:46
+#: ../glade/smuxi-frontend-gnome.glade.h:52
 msgid "Override"
 msgstr "Overskriv"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../glade/smuxi-frontend-gnome.glade.h:53
 msgid "Password:"
 msgstr "Adgangskode:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:48
+#: ../glade/smuxi-frontend-gnome.glade.h:54
+msgid "Persistency Type:"
+msgstr "Persistenstype:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:55
+msgid "Persistent Buffer Lines:"
+msgstr "Mellemlagerlinjer for persistens:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:56
 msgid "Port:"
 msgstr "Port:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:49
+#: ../glade/smuxi-frontend-gnome.glade.h:57
 msgid "Protocol:"
 msgstr "Protokol:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:50
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:530
+#: ../glade/smuxi-frontend-gnome.glade.h:58
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:338
 msgid "Realname:"
 msgstr "Navn:"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:51
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1048
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1073
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1568
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1593
+#: ../glade/smuxi-frontend-gnome.glade.h:59
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:856
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:881
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1376
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1401
 msgid "Right"
 msgstr "Højre"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:52
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:187
+#: ../glade/smuxi-frontend-gnome.glade.h:60
+msgid "Show Advanced Settings"
+msgstr "Vis avanceret opsætning"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:61
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:170
 msgid "Show Password"
 msgstr "Vis adgangskode"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:53
+#: ../glade/smuxi-frontend-gnome.glade.h:62
 msgid "Show Smuxi in the messaging menu"
 msgstr "Vis Smuxi i beskedmenuen"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:54
+#: ../glade/smuxi-frontend-gnome.glade.h:63
 msgid "Show always"
 msgstr "Vis altid"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:55
+#: ../glade/smuxi-frontend-gnome.glade.h:64
 msgid "Show notification popups"
 msgstr "Vis påmindelses-pop op'er"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:56
+#: ../glade/smuxi-frontend-gnome.glade.h:65
 msgid "Show when window is closed"
 msgstr "Vis når vinduet er lukket"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:57
+#: ../glade/smuxi-frontend-gnome.glade.h:66
 msgid "Show when window is minimized"
 msgstr "Vis når vinduet er minimeret"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:58
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:398
-msgid "Smuxi - Preferences"
-msgstr "Smuxi - indstillinger"
-
-# navn? derfor med stort.
-#: ../glade/smuxi-frontend-gnome.glade.h:59
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:18
+#: ../glade/smuxi-frontend-gnome.glade.h:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:16
 msgid "Smuxi - Server"
 msgstr "Smuxi - Server"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:60
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:820
+#: ../glade/smuxi-frontend-gnome.glade.h:68
+msgid "Smuxi Preferences"
+msgstr "Præferencer for Smuxi"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:69
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:628
 msgid "Strip Colors"
 msgstr "Fjern farver"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:61
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:859
+#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:667
 msgid "Strip Formattings"
 msgstr "Fjern formater"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:62
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:899
+#: ../glade/smuxi-frontend-gnome.glade.h:71
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:707
 msgid "Strip UTF-8"
 msgstr "Fjern UTF-8"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:63
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1214
+#: ../glade/smuxi-frontend-gnome.glade.h:72
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1022
 msgid "Tabs"
 msgstr "Faneblade"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:64
+#: ../glade/smuxi-frontend-gnome.glade.h:73
 msgid ""
 "The nickname to use. You can specify extra nicknames (separated by spaces) "
 "which will be used as fallbacks when the first choice is not available. By "
@@ -338,51 +373,60 @@ msgstr ""
 "som vil blive brugt hvis det første valg ikke er tilgængeligt. Som standard "
 "vil $nick_ og $nick__ blive anvendt."
 
-#: ../glade/smuxi-frontend-gnome.glade.h:65
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:718
+#: ../glade/smuxi-frontend-gnome.glade.h:74
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:526
 msgid "Timestamp Format:"
 msgstr "Tidsstempelformat:"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:66
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:935
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:959
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1412
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1438
+#: ../glade/smuxi-frontend-gnome.glade.h:75
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:743
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:767
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1220
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1246
 msgid "Top"
 msgstr "Øverst"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:67
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:507
+#: ../glade/smuxi-frontend-gnome.glade.h:76
+msgid "Type:"
+msgstr "Type:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:315
 msgid "Username:"
 msgstr "Brugernavn:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:68
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1873
+#: ../glade/smuxi-frontend-gnome.glade.h:78
+msgid "Volatile Buffer Lines:"
+msgstr "Ustabile mellemlagerlinjer:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:79
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1681
 msgid "_Filters"
 msgstr "_Filtre"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:69
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1715
+#: ../glade/smuxi-frontend-gnome.glade.h:80
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1523
 msgid "_Interface"
 msgstr "_Grænseflade"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../glade/smuxi-frontend-gnome.glade.h:81
 msgid "_Logging"
 msgstr "_Logning"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:71
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1781
+#: ../glade/smuxi-frontend-gnome.glade.h:82
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1589
 msgid "_Servers"
 msgstr "_Servere"
 
-#. This is a setting for character based line wrapping vs word based when showing messages
-#: ../glade/smuxi-frontend-gnome.glade.h:73
+#. This is a setting for character based line wrapping vs word based when
+#. showing messages
+#: ../glade/smuxi-frontend-gnome.glade.h:84
 msgid "_Wrap Mode:"
 msgstr "_Ombrydningstilstand:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:74
+#: ../glade/smuxi-frontend-gnome.glade.h:85
 msgid ""
 "ss = seconds\n"
 "mm = minutes\n"
@@ -413,33 +457,34 @@ msgid "IRC Chat"
 msgstr "IRC-snak"
 
 #: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:3
+msgid "Smuxi"
+msgstr "Smuxi"
+
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:4
 msgid "Smuxi IRC Client"
 msgstr "Smuxi - IRC-klient"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:58
+#: ../src/Frontend-GNOME/AboutDialog.cs:60
 msgid "translator-credits"
 msgstr "Joe Hansen <joedalton2 at yahoo.dk>"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:61
+#: ../src/Frontend-GNOME/AboutDialog.cs:65
 msgid "Smuxi Website"
 msgstr "Smuxis hjemmeside"
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:44
+#: ../src/Frontend-GNOME/CrashDialog.cs:46
 msgid "Oops, I did it again..."
 msgstr "Oops, jeg gjorde det igen..."
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:57
+#: ../src/Frontend-GNOME/CrashDialog.cs:59
 msgid "Smuxi crashed because an unhandled exception was thrown!"
 msgstr "Smuxi brød ned da en uhåndteret undtagelse opstod!"
 
-# A stack trace (also called stack backtrace or stack traceback) 
-# is a report of the active stack frames at a certain point in 
-# time during the execution of a program.
-#: ../src/Frontend-GNOME/CrashDialog.cs:61
+#: ../src/Frontend-GNOME/CrashDialog.cs:63
 msgid "Here is the stacktrace, please report this bug!"
 msgstr "Her er stacktracen, rapporter venligst denne fejl!"
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:81
+#: ../src/Frontend-GNOME/CrashDialog.cs:83
 msgid "_Report Bug"
 msgstr "_Rapporter fejl"
 
@@ -447,146 +492,155 @@ msgstr "_Rapporter fejl"
 msgid "Engine Manager"
 msgstr "Motorhåndtering"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:68
-msgid "_Connect"
-msgstr "_Tilslut"
-
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:84
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:80
 msgid "Select which Smuxi engine you want to connect to"
 msgstr "Vælg hvilken Smuximotor du ønsker at forbinde til"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:90
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:86
 msgid "Engine:"
 msgstr "Motor:"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:116
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:176
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:353
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:97
+msgid "Use Low Bandwidth Mode"
+msgstr "Brug tilstand for lav båndbredde"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:121
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:181
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:358
 msgid "Local Engine"
 msgstr "Lokal motor"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:168
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:173
 msgid "Please select an engine!"
 msgstr "Vælg venligst en motor!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:189
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:194
 #, csharp-format
 msgid "Your frontend version ({0}) does not match the engine version ({1})!"
 msgstr "Din grænsefladeversion ({0}) svarer ikke til motorversionen ({1})!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:216
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:221
 msgid "An error occurred while connecting to the engine!"
 msgstr "En fejl opstod under tilslutning til motoren!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:217
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:222
 #, csharp-format
 msgid "Engine URL: {0}"
 msgstr "Motor-URL: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:220
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:225
 #, csharp-format
 msgid "Error: {0}"
 msgstr "Fejl: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:290
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:295
 #, csharp-format
 msgid "Are you sure you want to delete the engine \"{0}\"?"
 msgstr "Er du sikker på, at du ønsker at slette motoren »{0}«?"
 
-#: ../src/Frontend-GNOME/Entry.cs:412
+#: ../src/Frontend-GNOME/Entry.cs:443
 #, csharp-format
 msgid "You are going to paste {0} lines. Do you want to continue?"
 msgstr "Du er ved at indsætte {0} linjer. Ønsker du at fortsætte?"
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Frontend-GNOME/Entry.cs:515
+#: ../src/Frontend-GNOME/Entry.cs:547
 msgid "Frontend Commands"
 msgstr "Grænsefladekommandoer"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:193
+#: ../src/Frontend-GNOME/MainWindow.cs:252
 msgid "_File"
 msgstr "_Fil"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:209
+#: ../src/Frontend-GNOME/MainWindow.cs:276
 msgid "_Server"
 msgstr "_Server"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:213
+#: ../src/Frontend-GNOME/MainWindow.cs:280
 msgid "_Quick Connect"
 msgstr "_Hurtig tilslutning"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:224
+#: ../src/Frontend-GNOME/MainWindow.cs:291
 msgid "_Manage"
 msgstr "_HÃ¥ndter"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:231
+#: ../src/Frontend-GNOME/MainWindow.cs:298
 msgid "_Chat"
 msgstr "_Snak"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:235
+#: ../src/Frontend-GNOME/MainWindow.cs:302
 msgid "Open / Join Chat"
 msgstr "Ã…bn / tilslut snak"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:240
+#: ../src/Frontend-GNOME/MainWindow.cs:308
 msgid "_Find Group Chat"
 msgstr "_Find gruppesnak"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:245
+#: ../src/Frontend-GNOME/MainWindow.cs:314
 msgid "C_lear All Activity"
 msgstr "_Ryd al aktivitet"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:252
+#: ../src/Frontend-GNOME/MainWindow.cs:321
 msgid "_Next Chat"
 msgstr "_Næste snak"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:262
+#: ../src/Frontend-GNOME/MainWindow.cs:335
 msgid "_Previous Chat"
 msgstr "_Forrige snak"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:312
+#: ../src/Frontend-GNOME/MainWindow.cs:389
 msgid "Open Log"
 msgstr "Ã…bn log"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:326
+#: ../src/Frontend-GNOME/MainWindow.cs:407
 msgid "_Engine"
 msgstr "_Motor"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:330
+#: ../src/Frontend-GNOME/MainWindow.cs:411
 msgid "_Use Local Engine"
 msgstr "_Brug lokal motor"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:336
+#: ../src/Frontend-GNOME/MainWindow.cs:417
 msgid "_Add Remote Engine"
 msgstr "_Tilføj ekstern motor"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:341
+#: ../src/Frontend-GNOME/MainWindow.cs:422
 msgid "_Switch Remote Engine"
 msgstr "_Skift ekstern motor"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:348
+#: ../src/Frontend-GNOME/MainWindow.cs:429
 msgid "_View"
 msgstr "_Vis"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:352
+#: ../src/Frontend-GNOME/MainWindow.cs:433
 msgid "_Caret Mode"
 msgstr "_Markørtilstand"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:362
+#: ../src/Frontend-GNOME/MainWindow.cs:445
+msgid "_Browse Mode"
+msgstr "_Navigeringstilstand"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:463
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:722
+msgid "Show _Menubar"
+msgstr "Vis _menubjælke"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:494
 msgid "_Help"
 msgstr "_Hjælp"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:616
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:222
+#: ../src/Frontend-GNOME/MainWindow.cs:768
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:225
 msgid "Unable to add server: "
 msgstr "Kunne ikke tilføje server: "
 
-#: ../src/Frontend-GNOME/MainWindow.cs:663
+#: ../src/Frontend-GNOME/MainWindow.cs:828
 #, csharp-format
 msgid "Unknown ChatType: {0}"
 msgstr "Ukendt snaktype: {0}"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:892
+#: ../src/Frontend-GNOME/MainWindow.cs:1097
 msgid ""
 "Switching to local engine will disconnect you from the current engine!\n"
 "Are you sure you want to do this?"
@@ -594,7 +648,7 @@ msgstr ""
 "Skift til lokal motor vil afbryde dig fra den aktuelle motor!\n"
 "Er du sikker på, at du ønsker at gøre dette?"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:934
+#: ../src/Frontend-GNOME/MainWindow.cs:1139
 msgid ""
 "Switching the remote engine will disconnect you from the current engine!\n"
 "Are you sure you want to do this?"
@@ -607,78 +661,98 @@ msgid "Sorry, not implemented yet!"
 msgstr "Beklager, ikke implementeret endnu!"
 
 #. fill ListStore
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:171
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:179
 msgid "Character"
 msgstr "Tegn"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:172
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:180
 msgid "Word"
 msgstr "Ord"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:182
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:139
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:197
+msgid "Volatile"
+msgstr "Ustabile"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:199
+msgid "Persistent"
+msgstr "Persistent"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:222
+msgid "No Proxy"
+msgstr "Ingen proxy"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:224
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:307
+msgid "System Default"
+msgstr "Systemstandard"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:238
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:140
 msgid "Connection"
 msgstr "Tilslutning"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:186
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:242
 msgid "Interface"
 msgstr "Grænseflade"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:190
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:246
 msgid "Servers"
 msgstr "Servere"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:197
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:253
 msgid "Filters"
 msgstr "Filtre"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:201
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:257
 msgid "Logging"
 msgstr "Logning"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:251
-msgid "System Default"
-msgstr "Systemstandard"
-
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:528
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:642
 msgid "Nicknames(s) field must not be empty."
 msgstr "Brugernavnsfelter må ikke være tomme."
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:672
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:823
 #, csharp-format
 msgid "Invalid highlight regex: '{0}'. Reason: {1}"
 msgstr "Ugyldigt fremhævet regulært udtryk: '{0}'. Årsag: {1}"
 
-#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:69
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:105
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:81
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:106
 #: ../src/Frontend-GNOME/Views/FilterListWidget.cs:271
 msgid "Name"
 msgstr "Navn"
 
-#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:74
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:86
 msgid "Topic"
 msgstr "Emne"
 
-#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:102
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:115
 msgid ""
-"Searching for group chats without a filter is not recommended.  This may "
-"take a while, or may not work at all.\n"
+"Searching for group chats without a filter is not recommended.  This may take a while, or may not work at all.\n"
 "Do you wish to continue?"
 msgstr ""
-"Søgning efter gruppesnak uden et filter kan ikke anbefales. Det kan tage "
-"lang tid eller slet ikke virke.\n"
+"Søgning efter gruppesnak uden et filter kan ikke anbefales. Det kan tage lang tid eller slet ikke virke.\n"
 "Ønsker du at fortsætte?"
 
-#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:143
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:156
 msgid "Error while fetching the list of group chats from the server."
 msgstr "Kunne ikke hente listen over gruppesnak fra serveren."
 
-#: ../src/Frontend-GNOME/Frontend.cs:394
+#: ../src/Frontend-GNOME/Frontend.cs:325
+msgid "Disconnected from engine."
+msgstr "Afbrudt fra motor."
+
+#: ../src/Frontend-GNOME/Frontend.cs:368
+#, csharp-format
+msgid "Reconnecting to engine... (attempt {0})"
+msgstr "Forbinder til motor igen... (forsøg {0})"
+
+#: ../src/Frontend-GNOME/Frontend.cs:465
 #, csharp-format
 msgid "Cause: {0}"
 msgstr "Ã…rsag: {0}"
 
-#: ../src/Frontend-GNOME/Frontend.cs:464
+#: ../src/Frontend-GNOME/Frontend.cs:583
 msgid ""
 "The frontend has lost the connection to the server.\n"
 "Do you want to reconnect now?"
@@ -686,7 +760,7 @@ msgstr ""
 "Grænsefladen har mistet forbindelsen til serveren.\n"
 "Ønsker du at tilslutte nu?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:479
+#: ../src/Frontend-GNOME/Frontend.cs:602
 msgid ""
 "Reconnecting to the server has failed.\n"
 "Do you want to try again?"
@@ -694,7 +768,7 @@ msgstr ""
 "Gentilslutning til serveren mislykkedes.\n"
 "Ønsker du at forsøge igen?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:580
+#: ../src/Frontend-GNOME/Frontend.cs:705
 msgid ""
 "The server has lost the connection to the frontend.\n"
 "Do you want to reconnect now?"
@@ -702,7 +776,7 @@ msgstr ""
 "Serveren har mistet forbindelsen til grænsefladen.\n"
 "Ønsker du at tilslutte igen?"
 
-#: ../src/Frontend-GNOME/NotifyManager.cs:229
+#: ../src/Frontend-GNOME/NotifyManager.cs:267
 msgid "Show"
 msgstr "Vis"
 
@@ -731,36 +805,41 @@ msgstr "Person / privat"
 msgid "Group / Public"
 msgstr "Gruppe / offenlig"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:70
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:71
 msgid "Engine Assistant - Smuxi"
 msgstr "Motorassisten - Smuxi"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:92
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:93
 msgid "Add Smuxi Engine"
 msgstr "Tilføj Smuximotor"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:94
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:95
 msgid "Edit Smuxi Engine"
 msgstr "Rediger Smuximotor"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:203
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:204
 msgid "Credentials"
 msgstr "Akkreditiver"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:265
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:284
 msgid "Now you can use the Smuxi Engine"
 msgstr "Nu kan du bruge Smuximotoren"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:268
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:287
 msgid "Thank you"
 msgstr "Mange tak"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:285
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:304
 msgid ""
 "An engine with this name already exists! Please specify a different one."
 msgstr "En motor med dette navn findes allerede! Angiv venligst et andet."
 
-#: ../src/Frontend-GNOME/Views/MessageTextView.cs:198
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:204
+#, csharp-format
+msgid "Day changed from {0} to {1}"
+msgstr "Dag ændret fra {0} til {1}"
+
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:210
 #, csharp-format
 msgid "Day changed to {0}"
 msgstr "Dag ændret til {0}"
@@ -799,100 +878,107 @@ msgstr "Type"
 msgid "Pattern"
 msgstr "Mønster"
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:241
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:506
+msgid "Low Bandwidth Mode is active: no messages synced."
+msgstr "Tilstand for lav båndbredde er aktiv: Ingen beskeder synkroniseret."
+
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:245
 #, csharp-format
 msgid "Retrieving user list for {0}..."
 msgstr "Henter brugerlsite for {0}..."
 
 #. TRANSLATOR: this string will be appended to the one above
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:288
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:279
 msgid "done."
 msgstr "færdig."
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:303
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:290
 msgid "Person"
 msgstr "Person"
 
-#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:68
+#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:69
 msgid ""
 "Closing the protocol chat will also close all open chats connected to it!\n"
 "Are you sure you want to do this?"
 msgstr ""
-"Lukning af protokolsamtalen vil også lukke alle åbne samtalerum der er "
-"forbundet til den!\n"
+"Lukning af protokolsamtalen vil også lukke alle åbne samtalerum der er forbundet til den!\n"
 "Er du sikker på, at du ønsker at gøre dette?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:184
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:187
 msgid "Are you sure you want to delete the selected server?"
 msgstr "Er du sikker på, at du ønsker at slette den valgte server?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:240
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:274
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:243
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:277
 msgid "Unable to edit server: "
 msgstr "Kunne ikke redigere server: "
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:24
 msgid "Find"
 msgstr "Find"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:54
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:44
 msgid "_Search for:"
 msgstr "_Søg efter:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:83
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:73
 msgid "_Match Case"
 msgstr "_Versalfølsom"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:95
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:85
 msgid "Search _Backwards"
 msgstr "Søg _baglæns"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:107
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:97
 msgid "_Wrap Around"
 msgstr "_Ombryd"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:120
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:110
 msgid "Use _Regular Expressions"
 msgstr "Brug _reuglære udtryk"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:23
 msgid "Smuxi - Find Group Chat"
 msgstr "Smuxi - Find gruppesnak"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:56
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:79
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:73
 msgid "_Name:"
 msgstr "_Navn:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:24
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:19
 msgid "Smuxi - Quick Connect"
 msgstr "Smuxi - hurtig tilslutning"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:487
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:206
+msgid "Smuxi - Preferences"
+msgstr "Smuxi - indstillinger"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:295
 msgid "Nicknames:"
 msgstr "Brugernavne:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1622
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1430
 msgid "<b> User List Position </b>"
 msgstr "<b> Placering af brugerliste</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1633
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1441
 msgid "<b> Channel </b>"
 msgstr "<b> Kanal </b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1844
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1652
 msgid "<b>Channel Filters</b>"
 msgstr "<b>Kanalfiltre</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1861
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1669
 msgid "<b>User Filters</b>"
 msgstr "<b>Brugerfiltre</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:56
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:42
 msgid "Use _SSH Tunnel"
 msgstr "Brug _SSH-tunnel"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:56
 msgid ""
 "<span size=\"small\">Enables the use of SSH for the connection.  This has a "
 "small performance impact, but is more secure and required when using NAT or "
@@ -902,64 +988,78 @@ msgstr ""
 "mindre ydelsespåvirkning, men er mere sikker og krævet med brug af NAT- "
 "eller portbaserede brandmure (firewalls)</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:149
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:135
 msgid "SSH _Host:"
 msgstr "SSH-_vært:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:160
-msgid ""
-"<span size=\"small\">DNS or IP address and port of the SSH server</span>"
-msgstr ""
-"<span size=\"small\">DNS- eller IP-adresse og port på SSH-serveren</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:146
+msgid "<span size=\"small\">DNS or IP address and port of the SSH server</span>"
+msgstr "<span size=\"small\">DNS- eller IP-adresse og port på SSH-serveren</span>"
 
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:159
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:173
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:187
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:146
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:129
 msgid "_Port:"
 msgstr "_Port:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:200
-msgid ""
-"<span size=\"small\">DNS or IP address and port of the Smuxi server</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:186
+msgid "<span size=\"small\">DNS or IP address and port of the Smuxi server</span>"
 msgstr ""
 "<span size=\"small\">DNS- eller IP-adresse og port på Smuxiserveren</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:213
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:199
 msgid "_Smuxi Host:"
 msgstr "_Smuxivært:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:68
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:52
 msgid "_SSH Username: (optional)"
 msgstr "_SSH-brugernavn: (valgfri)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:91
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:75
 msgid ""
-"<span size=\"small\">Username which will be used to log into the SSH server</"
-"span>"
+"<span size=\"small\">Username which will be used to log into the SSH "
+"server</span>"
 msgstr ""
 "<span size=\"small\">Brugernavn som vil blive brugt til at logge ind på SSH-"
 "serveren</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:111
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:95
 msgid "_SSH Password: (optional)"
 msgstr "_SSH-adgangskode: (valgfri)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:135
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:119
 msgid ""
-"<span size=\"small\">Password which will be used to log into the SSH server. "
-"The password is optional if SSH key authorization is used (via Pageant from "
-"the PuTTY tools).</span>"
+"<span size=\"small\">Password which will be used to log into the SSH server."
+" The password is optional if SSH key authorization is used (see "
+"below).</span>"
 msgstr ""
-"<span size=\"small\">Adgangskode som vil blive brugt til at logge ind på SSH-"
-"serveren. Adgangskoden er valgfri hvis SSH-nøglegodkendelse er anvendt (via "
-"Pageant fr PuTTY-værktøjene).</span>"
+"<span size=\"small\">Adgangskode vil blive brugt til at logge ind på SSH-"
+"serveren. Adgangskoden er valgfri hvis SSH-nøglegodkendelse anvendes (se "
+"nedenfor).</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:140
+msgid "_SSH Keyfile: (optional)"
+msgstr "_SSH-nøglefil: (valgfri)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:156
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:215
+#. Container child vbox17.Gtk.Box+BoxChild
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:148
+msgid "Select a File"
+msgstr "Vælg en fil"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:161
+msgid ""
+"<span size=\"small\">SSH private keyfile which will be used to log into the "
+"SSH server</span>"
+msgstr ""
+"<span size=\"small\">SSH-privatnøglefil vil blive brugt til at logge ind på "
+"SSH-serveren</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:181
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:188
 msgid "_Username:"
 msgstr "_Brugernavn:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:179
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:204
 msgid ""
 "<span size=\"small\">Username which will be used to log into the Smuxi "
 "server</span>"
@@ -967,20 +1067,20 @@ msgstr ""
 "<span size=\"small\">Brugernavn som vil blive brugt til at logge ind til "
 "Smuxiserveren</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:199
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:225
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:224
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:87
 msgid "_Password:"
 msgstr "_Adgangskode:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:223
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:248
 msgid "<span size=\"small\">Password of the user</span>"
 msgstr "<span size=\"small\">Brugerens adgangskode</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:243
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:268
 msgid "_Verify Password:"
 msgstr "_Bekræft adgangskode:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:267
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:292
 msgid "<span size=\"small\">Repeat the password for verification</span>"
 msgstr "<span size=\"small\">Gentag adgangskoden for bekræftelse</span>"
 
@@ -996,50 +1096,58 @@ msgstr ""
 "\n"
 "Klik »Fremad« for at begynde."
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:44
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:36
 msgid "_Engine Name:"
 msgstr "_Motornavn:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:59
 msgid "<span size=\"small\">Profile name of the new engine</span>"
 msgstr "<span size=\"small\">Profilnavn på den nye motor</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:88
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:80
 msgid "_Default Engine:"
 msgstr "_Standardmotor:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:99
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:91
 msgid "Use as new default engine"
 msgstr "Brug som ny standardmotor"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:112
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:104
 msgid ""
-"<span size=\"small\">If enabled, the current engine will be the default next "
-"time Smuxi is started</span>"
+"<span size=\"small\">If enabled, the current engine will be the default next"
+" time Smuxi is started</span>"
 msgstr ""
 "<span size=\"small\">Hvis aktiveret, vil den aktuelle motor være standard "
 "næste gang Smuxi startes</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:26
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:20
 msgid "Smuxi - Open Chat"
 msgstr "Smuxi - åben snak"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:69
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:63
 msgid "_Type:"
 msgstr "_Type:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:87
-msgid "_Network:"
-msgstr "_Netværk:"
-
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:205
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:54
 msgid "_Hostname:"
 msgstr "_Værtsnavn:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:235
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:75
+msgid "_Network:"
+msgstr "_Netværk:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:198
 msgid "_Protocol:"
 msgstr "_Protokol:"
 
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:222
+msgid "Use Encryption"
+msgstr "Brug kryptering"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:234
+msgid "Validate Server Certificate"
+msgstr "Valider servercertifikat"
+
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:254
 msgid "_On Connect Commands:"
 msgstr "Kommandoer _ved tilslutning:"
diff --git a/po-Frontend-GNOME/de.po b/po-Frontend-GNOME/de.po
index 9a4cc23..d9e7937 100644
--- a/po-Frontend-GNOME/de.po
+++ b/po-Frontend-GNOME/de.po
@@ -1,20 +1,22 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-# Mirco Bauer <meebey at meebey.net>, 2008-2009.
-# Bianca Mix <heavydemon at freenet.de>, 2010
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
 # 
+# Translators:
+# Bianca Mix <heavydemon at freenet.de>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: 0.6.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-08-10 19:14+0200\n"
-"PO-Revision-Date: 2010-07-07 22:48+0100\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:22+0100\n"
+"PO-Revision-Date: 2011-12-30 22:54+0000\n"
 "Last-Translator: Bianca Mix <heavydemon at freenet.de>\n"
-"Language-Team: German Localization <debian-l10n-german at lists.debian.org>\n"
+"Language-Team: German (http://www.transifex.net/projects/p/smuxi/team/de/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: de\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:1
 msgid "<b> Chat </b>"
@@ -25,7 +27,7 @@ msgid "<b> Color </b>"
 msgstr "<b> Farbe </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:3
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1364
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1172
 msgid "<b> Entry Field </b>"
 msgstr "<b> Eingabefeld </b>"
 
@@ -34,7 +36,7 @@ msgid "<b> Font </b>"
 msgstr "<b> Schrift </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:5
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1694
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1502
 msgid "<b> Highlighting </b>"
 msgstr "<b> Highlighting </b>"
 
@@ -47,335 +49,385 @@ msgid "<b> Person List Position </b>"
 msgstr "<b> Position der Personenliste </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:8
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1201
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1009
 msgid "<b> Tab Colors </b>"
 msgstr "<b> Farbe der Reiter </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:9
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1102
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:910
 msgid "<b> Tabs Position </b>"
 msgstr "<b> Position der Reiter </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:10
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1507
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1315
 msgid "<b> Topic Position </b>"
 msgstr "<b> Position des Themas </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:11
+msgid "<b>Advanced</b>"
+msgstr "Erweitert"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:12
+msgid "<b>General</b>"
+msgstr "Allgemein"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:13
+msgid "<b>Global Commands</b>"
+msgstr "übergreifende Kommandos"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:14
+msgid "<b>Message Buffer</b>"
+msgstr "Nachrichtenpuffer"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:15
 msgid "<b>Messaging Menu</b>"
 msgstr "Messaging-Menü"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:12
+#: ../glade/smuxi-frontend-gnome.glade.h:16
+msgid "<b>Network Proxy</b>"
+msgstr "Netzwerk Proxy"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:17
 msgid "<b>Notification Popups</b>"
 msgstr "<b>Beachrichtigungs-Pop-ups</b>"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:13
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1153
+#: ../glade/smuxi-frontend-gnome.glade.h:18
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:961
 msgid "Activity"
 msgstr "Aktivität"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:14
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:99
+#: ../glade/smuxi-frontend-gnome.glade.h:19
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:209
 msgid "Automatically connect to server at startup"
 msgstr "Beim Start automatisch zu diesem Server verbinden"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:15
+#: ../glade/smuxi-frontend-gnome.glade.h:20
 msgid "Background"
 msgstr "Hintergrund"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:16
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1352
+#: ../glade/smuxi-frontend-gnome.glade.h:21
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1160
 msgid "Bash-Style Completion"
 msgstr "Vervollständigung im Bash-Stil"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:17
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1682
+#: ../glade/smuxi-frontend-gnome.glade.h:22
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1490
 msgid "Beep on highlight"
 msgstr "Bei Highlight piepsen"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:18
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:972
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:994
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1453
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1478
+#: ../glade/smuxi-frontend-gnome.glade.h:23
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:780
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:802
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1261
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1286
 msgid "Bottom"
 msgstr "Unten"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:19
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:738
+#: ../glade/smuxi-frontend-gnome.glade.h:24
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:546
 msgid "Buffer Lines:"
 msgstr "Puffer-Zeilen:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:20
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:663
+#: ../glade/smuxi-frontend-gnome.glade.h:25
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:471
 msgid "C_onnection"
 msgstr "_Verbindung"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:21
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1304
+#: ../glade/smuxi-frontend-gnome.glade.h:26
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1112
 msgid "Command Character:"
 msgstr "Befehlszeichen:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:22
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1327
+#: ../glade/smuxi-frontend-gnome.glade.h:27
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1135
 msgid "Command History Size:"
 msgstr "Befehlsprotokollgröße:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:23
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1284
+#: ../glade/smuxi-frontend-gnome.glade.h:28
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1092
 msgid "Completion Character:"
 msgstr "Vervollständigungzeichen:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:24
+#: ../glade/smuxi-frontend-gnome.glade.h:29
 msgid "Enable"
 msgstr "Aktivieren"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:25
+#: ../glade/smuxi-frontend-gnome.glade.h:30
 msgid "Enabled"
 msgstr "Aktiviert"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:26
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:551
+#: ../glade/smuxi-frontend-gnome.glade.h:31
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:359
 msgid "Encoding:"
 msgstr "Kodierung:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:27
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:761
+#: ../glade/smuxi-frontend-gnome.glade.h:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:569
 msgid "Engine Buffer Lines:"
 msgstr "Engine-Puffer-Zeilen:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:28
+#: ../glade/smuxi-frontend-gnome.glade.h:33
 msgid "Foreground"
 msgstr "Vordergrund"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:29
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:917
+#: ../glade/smuxi-frontend-gnome.glade.h:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:725
 msgid "General"
 msgstr "Allgemein"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:30
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1173
+#: ../glade/smuxi-frontend-gnome.glade.h:35
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:981
 msgid "Highlight"
 msgstr "Highlight"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:31
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1658
+#: ../glade/smuxi-frontend-gnome.glade.h:36
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1466
 msgid "Highlight words:"
 msgstr "Highlight-Wörter:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:32
+#: ../glade/smuxi-frontend-gnome.glade.h:37
+msgid "Host:"
+msgstr "Host:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:38
 msgid "Hostname:"
 msgstr "Hostname:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:33
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1373
+#: ../glade/smuxi-frontend-gnome.glade.h:39
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
 msgid "Input"
-msgstr "Eingabe:"
+msgstr "Eingabe"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:34
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1163
+#: ../glade/smuxi-frontend-gnome.glade.h:40
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:971
 msgid "Join/Part/Mode"
 msgstr "Beitreten/Verlassen/Mode"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:35
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1008
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1033
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1527
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1553
+#: ../glade/smuxi-frontend-gnome.glade.h:41
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:816
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:841
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1335
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1361
 msgid "Left"
 msgstr "Links"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:36
+#: ../glade/smuxi-frontend-gnome.glade.h:42
 msgid "Log Filtered Messages"
 msgstr "Protokollierung gefilterter Nachrichten"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:37
+#: ../glade/smuxi-frontend-gnome.glade.h:43
 msgid "Network:"
 msgstr "Netzwerk:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:38
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1394
+#: ../glade/smuxi-frontend-gnome.glade.h:44
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1202
 msgid "Nick Colors"
 msgstr "Nick-Farben"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:39
+#: ../glade/smuxi-frontend-gnome.glade.h:45
 msgid "Nickname(s):"
 msgstr "Nickname(n):"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:40
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1145
+#: ../glade/smuxi-frontend-gnome.glade.h:46
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:953
 msgid "No Activity"
 msgstr "Keine Aktivität"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:41
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1088
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1493
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1608
+#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:896
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1301
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1416
 msgid "None"
 msgstr "Nichts"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:42
+#: ../glade/smuxi-frontend-gnome.glade.h:48
 msgid "Notification"
 msgstr "Benachrichtigung"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:43
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:573
+#: ../glade/smuxi-frontend-gnome.glade.h:49
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:381
 msgid "On Connect Commands:"
 msgstr "Befehle beim Verbinden:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:44
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:619
+#: ../glade/smuxi-frontend-gnome.glade.h:50
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:427
 msgid "On Startup Commands:"
 msgstr "Befehle beim Starten:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:45
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1706
+#: ../glade/smuxi-frontend-gnome.glade.h:51
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1514
 msgid "Output"
 msgstr "Ausgabe"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:46
+#: ../glade/smuxi-frontend-gnome.glade.h:52
 msgid "Override"
 msgstr "Ãœbersteuern"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../glade/smuxi-frontend-gnome.glade.h:53
 msgid "Password:"
 msgstr "Passwort:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:48
+#: ../glade/smuxi-frontend-gnome.glade.h:54
+msgid "Persistency Type:"
+msgstr "Persistenz-Typ"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:55
+msgid "Persistent Buffer Lines:"
+msgstr "Zeilen Persistenz-Puffer"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:56
 msgid "Port:"
 msgstr "Port:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:49
+#: ../glade/smuxi-frontend-gnome.glade.h:57
 msgid "Protocol:"
 msgstr "Protokoll:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:50
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:530
+#: ../glade/smuxi-frontend-gnome.glade.h:58
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:338
 msgid "Realname:"
 msgstr "Wirklicher Name:"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:51
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1048
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1073
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1568
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1593
+#: ../glade/smuxi-frontend-gnome.glade.h:59
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:856
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:881
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1376
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1401
 msgid "Right"
 msgstr "Rechts"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:52
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:187
+#: ../glade/smuxi-frontend-gnome.glade.h:60
+msgid "Show Advanced Settings"
+msgstr "Zeige erweiterte Einstellungen"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:61
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:170
 msgid "Show Password"
 msgstr "Passwort anzeigen"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:53
+#: ../glade/smuxi-frontend-gnome.glade.h:62
 msgid "Show Smuxi in the messaging menu"
 msgstr "Zeige Smuxi im Messaging-Menü"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:54
+#: ../glade/smuxi-frontend-gnome.glade.h:63
 msgid "Show always"
 msgstr "Immer anzeigen"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:55
+#: ../glade/smuxi-frontend-gnome.glade.h:64
 msgid "Show notification popups"
 msgstr "Zeige Benachrichtigungs-Pop-ups"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:56
+#: ../glade/smuxi-frontend-gnome.glade.h:65
 msgid "Show when window is closed"
 msgstr "Anzeigen, wenn Fenster geschlossen ist"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:57
+#: ../glade/smuxi-frontend-gnome.glade.h:66
 msgid "Show when window is minimized"
 msgstr "Zeigen, wenn Fenster minimiert ist"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:58
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:398
-msgid "Smuxi - Preferences"
-msgstr "Smuxi - Einstellungen"
-
-#: ../glade/smuxi-frontend-gnome.glade.h:59
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:18
+#: ../glade/smuxi-frontend-gnome.glade.h:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:16
 msgid "Smuxi - Server"
 msgstr "Smuxi - Server"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:60
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:820
+#: ../glade/smuxi-frontend-gnome.glade.h:68
+msgid "Smuxi Preferences"
+msgstr "Smuxi Einstellungen"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:69
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:628
 msgid "Strip Colors"
 msgstr "Farben entfernen"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:61
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:859
+#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:667
 msgid "Strip Formattings"
 msgstr "Formatierungen entfernen"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:62
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:899
+#: ../glade/smuxi-frontend-gnome.glade.h:71
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:707
 msgid "Strip UTF-8"
 msgstr "UTF-8 entfernen"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:63
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1214
+#: ../glade/smuxi-frontend-gnome.glade.h:72
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1022
 msgid "Tabs"
 msgstr "Reiter"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:64
-msgid "The nickname to use. You can specify extra nicknames (separated by spaces) which will be used as fallbacks when the first choice is not available. By default $nick_ and $nick__ will be used as fallbacks."
-msgstr "Der Nickname der verwendet werden soll. Sie können mehr als einen Nicknamen angeben, indem Sie Leerzeichen als Trenner verwenden. Diese werden als Ausweichmöglichkeit benutzt, wenn der Nickname nicht verfügbar ist. Standardmäßig wird $nick_ und $nick__ als Ausweichmöglichkeit verwendet."
+#: ../glade/smuxi-frontend-gnome.glade.h:73
+msgid ""
+"The nickname to use. You can specify extra nicknames (separated by spaces) "
+"which will be used as fallbacks when the first choice is not available. By "
+"default $nick_ and $nick__ will be used as fallbacks."
+msgstr ""
+"Der Nickname der verwendet werden soll. Sie können mehr als einen Nicknamen "
+"angeben, indem Sie Leerzeichen als Trenner verwenden. Diese werden als "
+"Ausweichmöglichkeit benutzt, wenn der Nickname nicht verfügbar ist. "
+"Standardmäßig wird $nick_ und $nick__ als Ausweichmöglichkeit verwendet."
 
-#: ../glade/smuxi-frontend-gnome.glade.h:65
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:718
+#: ../glade/smuxi-frontend-gnome.glade.h:74
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:526
 msgid "Timestamp Format:"
 msgstr "Zeitstempel-Format:"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:66
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:935
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:959
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1412
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1438
+#: ../glade/smuxi-frontend-gnome.glade.h:75
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:743
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:767
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1220
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1246
 msgid "Top"
 msgstr "Oben"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:67
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:507
+#: ../glade/smuxi-frontend-gnome.glade.h:76
+msgid "Type:"
+msgstr "Typ:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:315
 msgid "Username:"
 msgstr "Benutzername:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:68
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1873
+#: ../glade/smuxi-frontend-gnome.glade.h:78
+msgid "Volatile Buffer Lines:"
+msgstr "Zeilen Volatilitäts-Puffer"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:79
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1681
 msgid "_Filters"
 msgstr "_Filter"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:69
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1715
+#: ../glade/smuxi-frontend-gnome.glade.h:80
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1523
 msgid "_Interface"
 msgstr "_Anzeige"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../glade/smuxi-frontend-gnome.glade.h:81
 msgid "_Logging"
 msgstr "_Geprächsprotokollierung"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:71
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1781
+#: ../glade/smuxi-frontend-gnome.glade.h:82
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1589
 msgid "_Servers"
 msgstr "_Server"
 
 #. This is a setting for character based line wrapping vs word based when
 #. showing messages
-#: ../glade/smuxi-frontend-gnome.glade.h:73
+#: ../glade/smuxi-frontend-gnome.glade.h:84
 msgid "_Wrap Mode:"
 msgstr "_Umbruch-Modus"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:74
+#: ../glade/smuxi-frontend-gnome.glade.h:85
 msgid ""
 "ss = seconds\n"
 "mm = minutes\n"
@@ -406,32 +458,37 @@ msgid "IRC Chat"
 msgstr "IRC Chat"
 
 #: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:3
+msgid "Smuxi"
+msgstr "Smuxi"
+
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:4
 msgid "Smuxi IRC Client"
 msgstr "Smuxi - Chat Client"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:58
+#: ../src/Frontend-GNOME/AboutDialog.cs:60
 msgid "translator-credits"
 msgstr ""
 "Mirco Bauer <meebey at meebey.net>\n"
 "Bianca Mix <heavydemon at freenet.de>"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:61
+#: ../src/Frontend-GNOME/AboutDialog.cs:65
 msgid "Smuxi Website"
 msgstr "Smuxi Webseite"
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:44
+#: ../src/Frontend-GNOME/CrashDialog.cs:46
 msgid "Oops, I did it again..."
 msgstr "Ups, ich habe es wieder getan..."
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:57
+#: ../src/Frontend-GNOME/CrashDialog.cs:59
 msgid "Smuxi crashed because an unhandled exception was thrown!"
-msgstr "Smuxi ist abgestürtzt, weil eine unbehandelte Ausnahme aufgetreten ist!"
+msgstr ""
+"Smuxi ist abgestürtzt, weil eine unbehandelte Ausnahme aufgetreten ist!"
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:61
+#: ../src/Frontend-GNOME/CrashDialog.cs:63
 msgid "Here is the stacktrace, please report this bug!"
 msgstr "Hier ist der Stack-Trace, bitte berichten Sie diesen Fehler!"
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:81
+#: ../src/Frontend-GNOME/CrashDialog.cs:83
 msgid "_Report Bug"
 msgstr "_Fehler berichten"
 
@@ -439,146 +496,157 @@ msgstr "_Fehler berichten"
 msgid "Engine Manager"
 msgstr "Engine-Manager"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:68
-msgid "_Connect"
-msgstr "_Verbinden"
-
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:84
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:80
 msgid "Select which Smuxi engine you want to connect to"
 msgstr "Wählen Sie, zu welcher Smuxi-Engine Sie sich verbinden möchten"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:90
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:86
 msgid "Engine:"
 msgstr "Engine:"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:116
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:176
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:353
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:97
+msgid "Use Low Bandwidth Mode"
+msgstr "Benutze Geringe-Bandbreite-Modus"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:121
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:181
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:358
 msgid "Local Engine"
 msgstr "Lokale Engine"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:168
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:173
 msgid "Please select an engine!"
 msgstr "Bitte wählen Sie eine Engine aus!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:189
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:194
 #, csharp-format
 msgid "Your frontend version ({0}) does not match the engine version ({1})!"
-msgstr "Ihre Frontend-Version ({0}) stimmt nicht mit der Engine-Version ({1}) überein!"
+msgstr ""
+"Ihre Frontend-Version ({0}) stimmt nicht mit der Engine-Version ({1}) "
+"überein!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:216
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:221
 msgid "An error occurred while connecting to the engine!"
 msgstr "Ein Fehler ist beim Verbinden zur Engine aufgetreten!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:217
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:222
 #, csharp-format
 msgid "Engine URL: {0}"
 msgstr "Engine URL: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:220
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:225
 #, csharp-format
 msgid "Error: {0}"
 msgstr "Fehler: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:290
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:295
 #, csharp-format
 msgid "Are you sure you want to delete the engine \"{0}\"?"
 msgstr "Möchten Sie wirklich die Engine \"{0}\" löschen?"
 
-#: ../src/Frontend-GNOME/Entry.cs:412
+#: ../src/Frontend-GNOME/Entry.cs:443
 #, csharp-format
 msgid "You are going to paste {0} lines. Do you want to continue?"
 msgstr "Sie sind dabei, {0} Zeilen einzufügen. Möchten Sie fortfahren?"
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Frontend-GNOME/Entry.cs:515
+#: ../src/Frontend-GNOME/Entry.cs:547
 msgid "Frontend Commands"
 msgstr "Frontend Befehle"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:193
+#: ../src/Frontend-GNOME/MainWindow.cs:252
 msgid "_File"
 msgstr "_Datei"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:209
+#: ../src/Frontend-GNOME/MainWindow.cs:276
 msgid "_Server"
 msgstr "_Server"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:213
+#: ../src/Frontend-GNOME/MainWindow.cs:280
 msgid "_Quick Connect"
 msgstr "_Schnelles Verbinden"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:224
+#: ../src/Frontend-GNOME/MainWindow.cs:291
 msgid "_Manage"
 msgstr "_Verwalten"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:231
+#: ../src/Frontend-GNOME/MainWindow.cs:298
 msgid "_Chat"
 msgstr "_Chat"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:235
+#: ../src/Frontend-GNOME/MainWindow.cs:302
 msgid "Open / Join Chat"
 msgstr "Chat öffnen / beitreten"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:240
+#: ../src/Frontend-GNOME/MainWindow.cs:308
 msgid "_Find Group Chat"
 msgstr "_Finde Gruppen-Chat"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:245
+#: ../src/Frontend-GNOME/MainWindow.cs:314
 msgid "C_lear All Activity"
 msgstr "Alle Aktivitäten _löschen"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:252
+#: ../src/Frontend-GNOME/MainWindow.cs:321
 msgid "_Next Chat"
 msgstr "_Nächster Chat"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:262
+#: ../src/Frontend-GNOME/MainWindow.cs:335
 msgid "_Previous Chat"
 msgstr "_Vorheriger Chat"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:312
+#: ../src/Frontend-GNOME/MainWindow.cs:389
 msgid "Open Log"
 msgstr "Mitschnitt Öffnen"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:326
+#: ../src/Frontend-GNOME/MainWindow.cs:407
 msgid "_Engine"
 msgstr "_Engine"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:330
+#: ../src/Frontend-GNOME/MainWindow.cs:411
 msgid "_Use Local Engine"
 msgstr "_Verwende lokale Engine"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:336
+#: ../src/Frontend-GNOME/MainWindow.cs:417
 msgid "_Add Remote Engine"
 msgstr "_Füge entfernte Engine hinzu"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:341
+#: ../src/Frontend-GNOME/MainWindow.cs:422
 msgid "_Switch Remote Engine"
 msgstr "_Entfernte Engine wechseln"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:348
+#: ../src/Frontend-GNOME/MainWindow.cs:429
 msgid "_View"
 msgstr "_Anzeige"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:352
+#: ../src/Frontend-GNOME/MainWindow.cs:433
 msgid "_Caret Mode"
 msgstr "_Caret-Modus"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:362
+#: ../src/Frontend-GNOME/MainWindow.cs:445
+msgid "_Browse Mode"
+msgstr "_Durchstöber-Modus"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:463
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:722
+msgid "Show _Menubar"
+msgstr "Zeige Menüleiste"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:494
 msgid "_Help"
 msgstr "_Hilfe"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:616
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:222
+#: ../src/Frontend-GNOME/MainWindow.cs:768
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:225
 msgid "Unable to add server: "
 msgstr "Fehler beim Hinzufügen des Servers:"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:663
+#: ../src/Frontend-GNOME/MainWindow.cs:828
 #, csharp-format
 msgid "Unknown ChatType: {0}"
 msgstr "Unbekannter Chat-Typ: {0}"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:892
+#: ../src/Frontend-GNOME/MainWindow.cs:1097
 msgid ""
 "Switching to local engine will disconnect you from the current engine!\n"
 "Are you sure you want to do this?"
@@ -586,7 +654,7 @@ msgstr ""
 "Das Wechseln zur lokalen Engine wird Sie von der jetzigen Engine trennen!\n"
 "Möchten Sie fortfahren?"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:934
+#: ../src/Frontend-GNOME/MainWindow.cs:1139
 msgid ""
 "Switching the remote engine will disconnect you from the current engine!\n"
 "Are you sure you want to do this?"
@@ -599,59 +667,72 @@ msgid "Sorry, not implemented yet!"
 msgstr "Tut mir leid, das ist noch nicht implementiert!"
 
 #. fill ListStore
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:171
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:179
 msgid "Character"
 msgstr "Zeichen"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:172
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:180
 msgid "Word"
 msgstr "Wort"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:182
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:139
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:197
+msgid "Volatile"
+msgstr "Volatil"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:199
+msgid "Persistent"
+msgstr "Persistent"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:222
+msgid "No Proxy"
+msgstr "Kein Proxy"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:224
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:307
+msgid "System Default"
+msgstr "System-Standard"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:238
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:140
 msgid "Connection"
 msgstr "Verbindung"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:186
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:242
 msgid "Interface"
 msgstr "Anzeige"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:190
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:246
 msgid "Servers"
 msgstr "Server"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:197
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:253
 msgid "Filters"
 msgstr "Filter"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:201
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:257
 msgid "Logging"
 msgstr "Geprächsprotokollierung"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:251
-msgid "System Default"
-msgstr "System-Standard"
-
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:528
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:642
 msgid "Nicknames(s) field must not be empty."
 msgstr "Das Nickname(n)-Feld darf nicht leer sein."
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:672
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:823
 #, csharp-format
 msgid "Invalid highlight regex: '{0}'. Reason: {1}"
 msgstr "Ungültiger Highlight regex: '{0}'. Ursache: {1}"
 
-#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:69
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:105
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:81
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:106
 #: ../src/Frontend-GNOME/Views/FilterListWidget.cs:271
 msgid "Name"
 msgstr "Name"
 
-#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:74
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:86
 msgid "Topic"
 msgstr "Thema"
 
-#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:102
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:115
 msgid ""
 "Searching for group chats without a filter is not recommended.  This may take a while, or may not work at all.\n"
 "Do you wish to continue?"
@@ -659,16 +740,25 @@ msgstr ""
 "Vom Suchen nach Gruppen-Chats ohne einen Filter wird abgeraten. Es könnte eine Weile dauern, oder es funktioniert gar nicht.\n"
 "Möchten Sie fortfahren?"
 
-#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:143
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:156
 msgid "Error while fetching the list of group chats from the server."
 msgstr "Fehler beim Abrufen der Liste für Gruppen-Chats vom Server."
 
-#: ../src/Frontend-GNOME/Frontend.cs:394
+#: ../src/Frontend-GNOME/Frontend.cs:325
+msgid "Disconnected from engine."
+msgstr "Von der Engine getrennt."
+
+#: ../src/Frontend-GNOME/Frontend.cs:368
+#, csharp-format
+msgid "Reconnecting to engine... (attempt {0})"
+msgstr "Wiederverbinden zur Engine... (Versuch {0})"
+
+#: ../src/Frontend-GNOME/Frontend.cs:465
 #, csharp-format
 msgid "Cause: {0}"
 msgstr "Grund: {0}"
 
-#: ../src/Frontend-GNOME/Frontend.cs:464
+#: ../src/Frontend-GNOME/Frontend.cs:583
 msgid ""
 "The frontend has lost the connection to the server.\n"
 "Do you want to reconnect now?"
@@ -676,7 +766,7 @@ msgstr ""
 "Der Server hat die Verbindung zum Frontend verloren.\n"
 "Möchten Sie diese nun erneut aufbauen?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:479
+#: ../src/Frontend-GNOME/Frontend.cs:602
 msgid ""
 "Reconnecting to the server has failed.\n"
 "Do you want to try again?"
@@ -684,7 +774,7 @@ msgstr ""
 "Erneutes Verbindung zum Server ist fehlgeschlagen.\n"
 "Möchten Sie es nochmals versuchen?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:580
+#: ../src/Frontend-GNOME/Frontend.cs:705
 msgid ""
 "The server has lost the connection to the frontend.\n"
 "Do you want to reconnect now?"
@@ -692,7 +782,7 @@ msgstr ""
 "Der Server hat die Verbindung zum Frontend verloren.\n"
 "Möchten Sie diese nun erneut aufbauen?"
 
-#: ../src/Frontend-GNOME/NotifyManager.cs:229
+#: ../src/Frontend-GNOME/NotifyManager.cs:267
 msgid "Show"
 msgstr "Zeige"
 
@@ -721,35 +811,43 @@ msgstr "Person / Privat"
 msgid "Group / Public"
 msgstr "Gruppe / Öffentlich"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:70
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:71
 msgid "Engine Assistant - Smuxi"
 msgstr "Engine-Assistent - Smuxi"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:92
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:93
 msgid "Add Smuxi Engine"
 msgstr "Smuxi-Engine hinzufügen"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:94
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:95
 msgid "Edit Smuxi Engine"
-msgstr "Smuxi-Engine hinzufügen"
+msgstr "Smuxi-Engine bearbeiten"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:203
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:204
 msgid "Credentials"
 msgstr "Zugangsdaten"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:265
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:284
 msgid "Now you can use the Smuxi Engine"
 msgstr "Nun können Sie die Smuxi-Engine verwenden"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:268
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:287
 msgid "Thank you"
 msgstr "Vielen Dank"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:285
-msgid "An engine with this name already exists! Please specify a different one."
-msgstr "Es existiert bereits eine Engine mit diesem Namen! Bitte geben Sie einen anderen an."
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:304
+msgid ""
+"An engine with this name already exists! Please specify a different one."
+msgstr ""
+"Es existiert bereits eine Engine mit diesem Namen! Bitte geben Sie einen "
+"anderen an."
+
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:204
+#, csharp-format
+msgid "Day changed from {0} to {1}"
+msgstr "Tag wechselte vom {0} zum {1}"
 
-#: ../src/Frontend-GNOME/Views/MessageTextView.cs:198
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:210
 #, csharp-format
 msgid "Day changed to {0}"
 msgstr "Tageswechsel: {0}"
@@ -758,7 +856,7 @@ msgstr "Tageswechsel: {0}"
 #: ../src/Frontend-GNOME/Views/FilterListWidget.cs:133
 #, csharp-format
 msgid "Invalid filter regex: '{0}'. Reason: {1}"
-msgstr "Üngültige r Filter regex: '{0}'. Ursache: {1}"
+msgstr "Üngültiger Filter regex: '{0}'. Ursache: {1}"
 
 #: ../src/Frontend-GNOME/Views/FilterListWidget.cs:200
 msgid "Are you sure you want to delete the selected filter?"
@@ -788,21 +886,26 @@ msgstr "Typ"
 msgid "Pattern"
 msgstr "Muster"
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:241
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:506
+msgid "Low Bandwidth Mode is active: no messages synced."
+msgstr ""
+"Geringe-Bandbreite-Modus ist aktiviert: Keine Nachrichten synchronisiert."
+
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:245
 #, csharp-format
 msgid "Retrieving user list for {0}..."
 msgstr "Rufe die Benutzer-Liste für {0} ab..."
 
 #. TRANSLATOR: this string will be appended to the one above
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:288
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:279
 msgid "done."
 msgstr "abgeschlossen."
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:303
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:290
 msgid "Person"
 msgstr "Person"
 
-#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:68
+#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:69
 msgid ""
 "Closing the protocol chat will also close all open chats connected to it!\n"
 "Are you sure you want to do this?"
@@ -810,141 +913,181 @@ msgstr ""
 "Das Schließen des Protokoll-Chats wird alle dazugehörigen Chats ebenfalls schließen!\n"
 "Möchten Sie fortfahren?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:184
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:187
 msgid "Are you sure you want to delete the selected server?"
 msgstr "Möchten Sie den ausgewählten Server wirklich löschen?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:240
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:274
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:243
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:277
 msgid "Unable to edit server: "
 msgstr "Bearbeiten des Servers nicht möglich:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:24
 msgid "Find"
 msgstr "Suchen"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:54
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:44
 msgid "_Search for:"
 msgstr "_Suchen nach:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:83
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:73
 msgid "_Match Case"
 msgstr "_Groß-/Kleinschreibung berücksichtigen"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:95
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:85
 msgid "Search _Backwards"
 msgstr "_Rückwärts suchen"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:107
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:97
 msgid "_Wrap Around"
 msgstr "_Wieder am Anfang beginnen, wenn das Ende erreicht ist"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:120
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:110
 msgid "Use _Regular Expressions"
 msgstr "_Reguläre Ausdrücke anwenden"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:23
 msgid "Smuxi - Find Group Chat"
 msgstr "Smuxi - Finde Gruppen-Chat"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:56
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:79
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:73
 msgid "_Name:"
 msgstr "_Name:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:24
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:19
 msgid "Smuxi - Quick Connect"
 msgstr "Smuxi - Schnelles Verbinden"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:487
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:206
+msgid "Smuxi - Preferences"
+msgstr "Smuxi - Einstellungen"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:295
 msgid "Nicknames:"
 msgstr "Nicknamen:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1622
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1430
 msgid "<b> User List Position </b>"
 msgstr "<b> Position der Benutzer-Liste </b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1633
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1441
 msgid "<b> Channel </b>"
 msgstr "<b> Channel </b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1844
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1652
 msgid "<b>Channel Filters</b>"
 msgstr "<b>Channel-Filter</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1861
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1669
 msgid "<b>User Filters</b>"
 msgstr "<b>Benutzer-Filter</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:56
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:42
 msgid "Use _SSH Tunnel"
 msgstr "SSH-Tunnel verwenden"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:70
-msgid "<span size=\"small\">Enables the use of SSH for the connection.  This has a small performance impact, but is more secure and required when using NAT or port-based firewalls</span>"
-msgstr "<span size=\"small\">Aktiviert die Verwendung von SSH für die Verbindung. Dies hat Einfluss auf die Performanz, ist jedoch sicherer und notwendig, wenn NAT oder Port basierte Firewalls verwendet werden.</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:56
+msgid ""
+"<span size=\"small\">Enables the use of SSH for the connection.  This has a "
+"small performance impact, but is more secure and required when using NAT or "
+"port-based firewalls</span>"
+msgstr ""
+"<span size=\"small\">Aktiviert die Verwendung von SSH für die Verbindung. "
+"Dies hat Einfluss auf die Performanz, ist jedoch sicherer und notwendig, "
+"wenn NAT oder Port basierte Firewalls verwendet werden.</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:149
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:135
 msgid "SSH _Host:"
 msgstr "SSH-_Host:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:160
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:146
 msgid "<span size=\"small\">DNS or IP address and port of the SSH server</span>"
 msgstr "<span size=\"small\">DNS oder IP-Adresse und Port vom SSH-Server</span>"
 
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:159
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:173
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:187
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:146
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:129
 msgid "_Port:"
 msgstr "_Port:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:200
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:186
 msgid "<span size=\"small\">DNS or IP address and port of the Smuxi server</span>"
 msgstr "<span size=\"small\">DNS oder IP-Adresse und Port vom Smuxi-Server</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:213
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:199
 msgid "_Smuxi Host:"
 msgstr "_Smuxi-Host:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:68
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:52
 msgid "_SSH Username: (optional)"
 msgstr "_SSH-Benutzer: (optional)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:91
-msgid "<span size=\"small\">Username which will be used to log into the SSH server</span>"
-msgstr "<span size=\"small\">Benutzername, welcher zur Anmeldung beim SSH-Server verwendet werden soll</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:75
+msgid ""
+"<span size=\"small\">Username which will be used to log into the SSH "
+"server</span>"
+msgstr ""
+"<span size=\"small\">Benutzername, welcher zur Anmeldung beim SSH-Server "
+"verwendet werden soll</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:111
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:95
 msgid "_SSH Password: (optional)"
 msgstr "_SSH-Passwort: (optional)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:135
-msgid "<span size=\"small\">Password which will be used to log into the SSH server. The password is optional if SSH key authorization is used (via Pageant from the PuTTY tools).</span>"
-msgstr "<span size=\"small\">Passwort, welches zur Anmeldung am SSH-Server verwendet werden soll. Das Passwort ist optional, wenn SSH-Schlüsselautorisierung verwendet wird (mittels Pageant aus den PuTTY Werkzeugen).</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:119
+msgid ""
+"<span size=\"small\">Password which will be used to log into the SSH server."
+" The password is optional if SSH key authorization is used (see "
+"below).</span>"
+msgstr ""
+"Passwort welches zum Login in den SSH-Server benutzt wird. Das Passwort ist "
+"optional wenn Autorisation mit SSH-Schlüsseln benutzt wird (siehe unten). "
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:140
+msgid "_SSH Keyfile: (optional)"
+msgstr "_SSH Schlüssel-Datei: (optional)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:156
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:215
+#. Container child vbox17.Gtk.Box+BoxChild
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:148
+msgid "Select a File"
+msgstr "Datei auswählen"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:161
+msgid ""
+"<span size=\"small\">SSH private keyfile which will be used to log into the "
+"SSH server</span>"
+msgstr ""
+"SSH nicht-öffentliche Schlüssel-Datei, die für den Login am SSH-Server "
+"verwendet wird"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:181
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:188
 msgid "_Username:"
 msgstr "_Benutzer:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:179
-msgid "<span size=\"small\">Username which will be used to log into the Smuxi server</span>"
-msgstr "<span size=\"small\">Benutzername, welcher zur Anmeldung beim Smuxi-Server verwendet werden soll</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:204
+msgid ""
+"<span size=\"small\">Username which will be used to log into the Smuxi "
+"server</span>"
+msgstr ""
+"<span size=\"small\">Benutzername, welcher zur Anmeldung beim Smuxi-Server "
+"verwendet werden soll</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:199
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:225
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:224
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:87
 msgid "_Password:"
 msgstr "_Passwort:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:223
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:248
 msgid "<span size=\"small\">Password of the user</span>"
 msgstr "<span size=\"small\">Passwort des Benutzers</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:243
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:268
 msgid "_Verify Password:"
 msgstr "Passwort _bestätigen:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:267
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:292
 msgid "<span size=\"small\">Repeat the password for verification</span>"
 msgstr "<span size=\"small\">Wiederholen Sie das Passwort zur Überprüfung</span>"
 
@@ -960,46 +1103,58 @@ msgstr ""
 "\n"
 "Klicken Sie auf \"Weiter\" um anzufangen."
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:44
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:36
 msgid "_Engine Name:"
 msgstr "_Engine-Name:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:59
 msgid "<span size=\"small\">Profile name of the new engine</span>"
 msgstr "<span size=\"small\">Name des Profils für die neue Engine</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:88
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:80
 msgid "_Default Engine:"
 msgstr "_Standard-Engine:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:99
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:91
 msgid "Use as new default engine"
 msgstr "Als neue Standard-Engine verwenden"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:112
-msgid "<span size=\"small\">If enabled, the current engine will be the default next time Smuxi is started</span>"
-msgstr "<span size=\"small\">Wenn dies aktiviert ist, wird die Engine standardmäßig beim nächsten Start von Smuxi verwendet</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:104
+msgid ""
+"<span size=\"small\">If enabled, the current engine will be the default next"
+" time Smuxi is started</span>"
+msgstr ""
+"<span size=\"small\">Wenn dies aktiviert ist, wird die Engine standardmäßig "
+"beim nächsten Start von Smuxi verwendet</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:26
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:20
 msgid "Smuxi - Open Chat"
 msgstr "Smuxi - Chat Öffnen"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:69
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:63
 msgid "_Type:"
 msgstr "_Typ:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:87
-msgid "_Network:"
-msgstr "_Netzwerk:"
-
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:205
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:54
 msgid "_Hostname:"
 msgstr "_Hostname:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:235
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:75
+msgid "_Network:"
+msgstr "_Netzwerk:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:198
 msgid "_Protocol:"
 msgstr "_Protokoll:"
 
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:222
+msgid "Use Encryption"
+msgstr "Verschlüsselung verwenden"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:234
+msgid "Validate Server Certificate"
+msgstr "Serverzertifikat validieren"
+
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:254
 msgid "_On Connect Commands:"
 msgstr "Befehle beim Verbinden:"
@@ -1008,107 +1163,4 @@ msgstr "Befehle beim Verbinden:"
 msgid "_Ignore Commands"
 msgstr "Befehle ignorieren:"
 
-#~ msgid "German"
-#~ msgstr "Deutsch"
-
-#~ msgid "Spanish"
-#~ msgstr "Spanisch"
-
-#~ msgid "British English"
-#~ msgstr "Britisches English"
-
-#~ msgid "French"
-#~ msgstr "Französisch"
-
-#~ msgid "Italian"
-#~ msgstr "Italienisch"
-
-#~ msgid "_Edit"
-#~ msgstr "_Bearbeiten"
-
-#~ msgid "Joins"
-#~ msgstr "Betreten"
-
-#~ msgid "Parts"
-#~ msgstr "Verlassen"
-
-#~ msgid "Quits"
-#~ msgstr "Trennen"
-
-#~ msgid "Unknown Command: {0}"
-#~ msgstr "Unbekannter Befehl: {0}"
-
-#~ msgid "gtk-cancel"
-#~ msgstr "gtk-cancel"
-
-#~ msgid "gtk-ok"
-#~ msgstr "gtk-ok"
-
-#~ msgid "#"
-#~ msgstr "#"
-
-#~ msgid "Syncing chat persons of {0}..."
-#~ msgstr "Synchronisiere Chat-Personen von {0}..."
-
-#~ msgid "localhost"
-#~ msgstr "localhost"
-
-#~ msgid "smuxi - Preferences"
-#~ msgstr "smuxi - Einstellungen"
-
-#~ msgid "Smuxi's first start"
-#~ msgstr "Smuxis erster Start"
-
-#~ msgid ""
-#~ "Welcome to the smuxi\n"
-#~ "You started smuxi for the first time and it needs some answers from you.\n"
-#~ "\n"
-#~ "Click \"Forward\" to begin."
-#~ msgstr ""
-#~ "Willkommen bei smuxi\n"
-#~ "Sie haben smuxi zum ersten Mal gestartet und es braucht ein paar Antworten von Ihnen.\n"
-#~ "\n"
-#~ "Klicken Sie auf \"Weiter\" um anzufangen."
-
-#~ msgid "Local"
-#~ msgstr "Lokal"
-
-#~ msgid "Remote"
-#~ msgstr "Entfernt"
-
-#~ msgid "When smuxi is started which mode it should use by default"
-#~ msgstr "Wenn smuxi gestartet wurde, welchen Modus soll es verwenden"
-
-#~ msgid "Now you can use smuxi"
-#~ msgstr "Nun können Sie smuxi benutzen"
-
-#~ msgid "First Start Druid"
-#~ msgstr "Erster Start Druide"
-
-#~ msgid "DNS or IP address of the smuxi engine"
-#~ msgstr "DNS oder IP-Addresse der Smuxi-Engine:"
-
-#~ msgid "TCP port of the smuxi engine"
-#~ msgstr "TCP-Port der Smuxi-Engine"
-
-#~ msgid "_Channel:"
-#~ msgstr "_Channel:"
-
-#~ msgid ""
-#~ ".NET Remoting Channel which will be used for communication\n"
-#~ "between the frontend and the engine"
-#~ msgstr ""
-#~ ".NET Remoting Channel welcher verwendet werden soll zur\n"
-#~ "Kommunikation zwischen dem Frontend und der Engine"
-
-#~ msgid "_Formatter:"
-#~ msgstr "_Formatter:"
-
-#~ msgid ".NET Remoting Data Formatter"
-#~ msgstr ".NET Remoting Daten-Formatierer"
-
-#~ msgid "Opening URL ({0}) failed."
-#~ msgstr "Öffnen der URL ({0}) fehlgeschlagen."
 
-#~ msgid "Tray"
-#~ msgstr "Benachrichtigungsfeld"
diff --git a/po-Frontend-GNOME/es.po b/po-Frontend-GNOME/es.po
index de1cbea..6192ecd 100644
--- a/po-Frontend-GNOME/es.po
+++ b/po-Frontend-GNOME/es.po
@@ -2,16 +2,15 @@
 # Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
 # This file is distributed under the same license as the Smuxi package.
 # Juan Miguel Carrero <streinleght at gmail.com>, 2008-2009.
-#
+# 
 msgid ""
 msgstr ""
 "Project-Id-Version: 0.6.2\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-01-11 03:23+0100\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
 "PO-Revision-Date: 2009-08-12 16:47+0100\n"
 "Last-Translator: Juan Miguel Carrero <streinleght at gmail.com>\n"
-"Language-Team: Spanish Spanish Localization <debian-l10n-spanish at lists."
-"debian.org>\n"
+"Language-Team: Spanish Spanish Localization <debian-l10n-spanish at lists.debian.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -25,7 +24,7 @@ msgid "<b> Color </b>"
 msgstr "<b> Color </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:3
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1372
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1364
 msgid "<b> Entry Field </b>"
 msgstr "<b> Campo de Entrada </b>"
 
@@ -34,7 +33,7 @@ msgid "<b> Font </b>"
 msgstr "<b> Fuente </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:5
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1702
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1694
 msgid "<b> Highlighting </b>"
 msgstr "<b> Resaltar </b>"
 
@@ -47,320 +46,359 @@ msgid "<b> Person List Position </b>"
 msgstr "<b> Posición Lista de Personas </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:8
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1209
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1201
 msgid "<b> Tab Colors </b>"
 msgstr "<b> Colores de pestañas </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:9
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1110
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1102
 msgid "<b> Tabs Position </b>"
 msgstr "<b> Posicion de pestañas </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:10
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1515
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1507
 msgid "<b> Topic Position </b>"
 msgstr "<b> Posicion del topic </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:11
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1853
-msgid "<b>Channel Filters</b>"
-msgstr "<b>Filtro de canales</b>"
+msgid "<b>General</b>"
+msgstr "<b>General</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:12
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1870
-msgid "<b>User Filters</b>"
-msgstr "<b>Filtro de usuarios</b>"
+msgid "<b>Global Commands</b>"
+msgstr "<b>Comandos globales</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:13
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1161
+msgid "<b>Messaging Menu</b>"
+msgstr "<b>Menú de Mensajería</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:14
+msgid "<b>Network Proxy</b>"
+msgstr "<b>Red Proxy</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:15
+msgid "<b>Notification Popups</b>"
+msgstr "<b>Notificaciones emergentes</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:16
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1153
 msgid "Activity"
 msgstr "Actividad"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:14
-#, fuzzy
+#: ../glade/smuxi-frontend-gnome.glade.h:17
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:235
 msgid "Automatically connect to server at startup"
-msgstr "Conectar automaticamente al servidor al iniciar"
+msgstr "Conectar automáticamente al servidor al iniciar"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:15
+#: ../glade/smuxi-frontend-gnome.glade.h:18
 msgid "Background"
 msgstr "Fondo"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:16
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1360
+#: ../glade/smuxi-frontend-gnome.glade.h:19
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1352
 msgid "Bash-Style Completion"
 msgstr "Autocompletado  Bash"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:17
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1690
+#: ../glade/smuxi-frontend-gnome.glade.h:20
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1682
 msgid "Beep on highlight"
 msgstr "Beep al resaltar"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:18
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:980
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1002
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1461
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1486
+#: ../glade/smuxi-frontend-gnome.glade.h:21
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:972
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:994
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1453
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1478
 msgid "Bottom"
 msgstr "Abajo"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:19
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:746
+#: ../glade/smuxi-frontend-gnome.glade.h:22
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:738
 msgid "Buffer Lines:"
 msgstr "Lineas de buffer:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:20
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:671
+#: ../glade/smuxi-frontend-gnome.glade.h:23
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:663
 msgid "C_onnection"
 msgstr "C_onexión"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:21
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1312
+#: ../glade/smuxi-frontend-gnome.glade.h:24
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1304
 msgid "Command Character:"
 msgstr "Carácter de Comandos:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:22
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1335
+#: ../glade/smuxi-frontend-gnome.glade.h:25
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1327
 msgid "Command History Size:"
 msgstr "Tamaño Historial de Comandos:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:23
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1292
+#: ../glade/smuxi-frontend-gnome.glade.h:26
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1284
 msgid "Completion Character:"
 msgstr "Carácter de Auto-Completar"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:24
+#: ../glade/smuxi-frontend-gnome.glade.h:27
 msgid "Enable"
 msgstr "Habilitar"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:25
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:559
+#: ../glade/smuxi-frontend-gnome.glade.h:28
+msgid "Enabled"
+msgstr "Habilitado"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:29
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:551
 msgid "Encoding:"
 msgstr "Codificación:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:26
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:769
+#: ../glade/smuxi-frontend-gnome.glade.h:30
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:761
 msgid "Engine Buffer Lines:"
 msgstr "Lineas de buffer del motor"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:27
+#: ../glade/smuxi-frontend-gnome.glade.h:31
 msgid "Foreground"
 msgstr "Prioridad"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:28
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:925
+#: ../glade/smuxi-frontend-gnome.glade.h:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:917
 msgid "General"
 msgstr "General"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:29
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
+#: ../glade/smuxi-frontend-gnome.glade.h:33
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1173
 msgid "Highlight"
 msgstr "Resaltar"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:30
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1666
+#: ../glade/smuxi-frontend-gnome.glade.h:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1658
 msgid "Highlight words:"
 msgstr "Palabras resaltadas:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:31
+#: ../glade/smuxi-frontend-gnome.glade.h:35
+msgid "Host:"
+msgstr "Dominio:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:36
 msgid "Hostname:"
 msgstr "Nombre del Host:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:32
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1381
+#: ../glade/smuxi-frontend-gnome.glade.h:37
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1373
 msgid "Input"
 msgstr "Entrada"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:33
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1171
+#: ../glade/smuxi-frontend-gnome.glade.h:38
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1163
 msgid "Join/Part/Mode"
 msgstr "Entrar/Salir/Modo"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:34
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1016
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1041
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1535
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1561
+#: ../glade/smuxi-frontend-gnome.glade.h:39
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1008
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1033
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1527
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1553
 msgid "Left"
 msgstr "Izquierda"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:35
+#: ../glade/smuxi-frontend-gnome.glade.h:40
+msgid "Log Filtered Messages"
+msgstr "Registro de mensajes filtrados"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:41
 msgid "Network:"
 msgstr "Redes:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:36
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1402
+#: ../glade/smuxi-frontend-gnome.glade.h:42
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1394
 msgid "Nick Colors"
 msgstr "Colores del Nick"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:37
+#: ../glade/smuxi-frontend-gnome.glade.h:43
 msgid "Nickname(s):"
 msgstr "Nick(s):"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:38
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1153
+#: ../glade/smuxi-frontend-gnome.glade.h:44
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1145
 msgid "No Activity"
 msgstr "Sin Actividad"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:39
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1096
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1501
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1616
+#: ../glade/smuxi-frontend-gnome.glade.h:45
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1088
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1493
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1608
 msgid "None"
 msgstr "Ninguno"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:40
+#: ../glade/smuxi-frontend-gnome.glade.h:46
 msgid "Notification"
 msgstr "Notificación"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:41
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:581
+#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:573
 msgid "On Connect Commands:"
 msgstr "Comandos al conectar:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:42
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:627
+#: ../glade/smuxi-frontend-gnome.glade.h:48
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:619
 msgid "On Startup Commands:"
 msgstr "Comandos al arrancar:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:43
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1714
+#: ../glade/smuxi-frontend-gnome.glade.h:49
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1706
 msgid "Output"
 msgstr "Salida"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:44
+#: ../glade/smuxi-frontend-gnome.glade.h:50
 msgid "Override"
 msgstr "Anular"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:45
+#: ../glade/smuxi-frontend-gnome.glade.h:51
 msgid "Password:"
 msgstr "Contraseña:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:46
+#: ../glade/smuxi-frontend-gnome.glade.h:52
 msgid "Port:"
 msgstr "Puerto:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../glade/smuxi-frontend-gnome.glade.h:53
 msgid "Protocol:"
 msgstr "Protocolo:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:48
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:538
+#: ../glade/smuxi-frontend-gnome.glade.h:54
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:530
 msgid "Realname:"
 msgstr "Nombre Real:"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:49
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1056
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1081
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1576
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1601
+#: ../glade/smuxi-frontend-gnome.glade.h:55
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1048
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1073
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1568
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1593
 msgid "Right"
 msgstr "Derecha"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:50
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:186
+#: ../glade/smuxi-frontend-gnome.glade.h:56
+msgid "Show Advanced Settings"
+msgstr "Mostrar configuraciones avanzadas"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:57
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:196
 msgid "Show Password"
 msgstr "Mostrar Contraseña:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:51
+#: ../glade/smuxi-frontend-gnome.glade.h:58
+msgid "Show Smuxi in the messaging menu"
+msgstr "Mostrar Smuxi en el Menú de Mensajería"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:59
 msgid "Show always"
 msgstr "Mostrar siempre"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:52
+#: ../glade/smuxi-frontend-gnome.glade.h:60
+msgid "Show notification popups"
+msgstr "Mostrar notificaciones emergentes"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:61
 msgid "Show when window is closed"
 msgstr "Mostrar cuando la ventana se cierra"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:53
+#: ../glade/smuxi-frontend-gnome.glade.h:62
 msgid "Show when window is minimized"
 msgstr "Mostrar cuando la ventana se minimiza"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:54
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:406
+#: ../glade/smuxi-frontend-gnome.glade.h:63
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:398
 msgid "Smuxi - Preferences"
 msgstr "Smuxi - Preferencias"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:55
+#: ../glade/smuxi-frontend-gnome.glade.h:64
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:18
 msgid "Smuxi - Server"
 msgstr "Smuxi - Servidor"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:56
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:828
+#: ../glade/smuxi-frontend-gnome.glade.h:65
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:820
 msgid "Strip Colors"
 msgstr "Ocultar Colores"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:57
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:867
+#: ../glade/smuxi-frontend-gnome.glade.h:66
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:859
 msgid "Strip Formattings"
 msgstr "Ocultar Formatos"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:58
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:907
+#: ../glade/smuxi-frontend-gnome.glade.h:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:899
 msgid "Strip UTF-8"
 msgstr "Ocultar UTF-8"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:59
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1222
+#: ../glade/smuxi-frontend-gnome.glade.h:68
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1214
 msgid "Tabs"
 msgstr "Pestañas"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:60
-#, fuzzy
-msgid ""
-"The nickname to use. You can specify extra nicknames (separated by spaces) "
-"which will be used as fallbacks when the first choice is not available. By "
-"default $nick_ and $nick__ will be used as fallbacks."
-msgstr "El apodo "
+#: ../glade/smuxi-frontend-gnome.glade.h:69
+msgid "The nickname to use. You can specify extra nicknames (separated by spaces) which will be used as fallbacks when the first choice is not available. By default $nick_ and $nick__ will be used as fallbacks."
+msgstr "El apodo a usar. Puede especificar apodos extras (separados por espacios) que serán usados como segunda opción cuando la primera no está disponible. Por defecto $nick_ y $nick__ serán usados como segunda opción."
 
-#: ../glade/smuxi-frontend-gnome.glade.h:61
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:726
+#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:718
 msgid "Timestamp Format:"
 msgstr "Formato de Marca de Tiempo:"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:62
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:943
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:967
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1420
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1446
+#: ../glade/smuxi-frontend-gnome.glade.h:71
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:935
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:959
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1412
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1438
 msgid "Top"
 msgstr "Arriba"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:63
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:515
+#: ../glade/smuxi-frontend-gnome.glade.h:72
+msgid "Type:"
+msgstr "Escribir:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:73
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:507
 msgid "Username:"
 msgstr "Usuario:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:64
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1882
+#: ../glade/smuxi-frontend-gnome.glade.h:74
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1873
 msgid "_Filters"
 msgstr "_Filtros"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:65
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1723
+#: ../glade/smuxi-frontend-gnome.glade.h:75
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1715
 msgid "_Interface"
 msgstr "_Interfaz"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:66
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1789
+#: ../glade/smuxi-frontend-gnome.glade.h:76
+msgid "_Logging"
+msgstr "_Inicio de sesión"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1781
 msgid "_Servers"
 msgstr "_Servidores"
 
-#. This is a setting for character based line wrapping vs word based when showing messages
-#: ../glade/smuxi-frontend-gnome.glade.h:68
+#. This is a setting for character based line wrapping vs word based when
+#. showing messages
+#: ../glade/smuxi-frontend-gnome.glade.h:79
 msgid "_Wrap Mode:"
 msgstr "_Modo Caret"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:69
-#, fuzzy
+#: ../glade/smuxi-frontend-gnome.glade.h:80
 msgid ""
 "ss = seconds\n"
 "mm = minutes\n"
@@ -382,46 +420,42 @@ msgstr ""
 "MM = mes\n"
 "yy/yyyy = año"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:52
-msgid "translator-credits"
-msgstr "Juan Miguel Carrero <streinleght at gmail.com>"
-
-#: ../src/Frontend-GNOME/AboutDialog.cs:47
-msgid "German"
-msgstr "Alemán"
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:1
+msgid "Chat with other people on IRC"
+msgstr "Charla con otras personas en IRC"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:48
-msgid "Spanish"
-msgstr "Español"
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:2
+msgid "IRC Chat"
+msgstr "IRC Chat"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:49
-msgid "British English"
-msgstr "Inglés Británico"
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:3
+msgid "Smuxi IRC Client"
+msgstr "Cliente IRC Smuxi"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:50
-msgid "French"
-msgstr "Francés"
-
-#: ../src/Frontend-GNOME/AboutDialog.cs:51
-msgid "Italian"
-msgstr "Italiano"
+#: ../src/Frontend-GNOME/AboutDialog.cs:58
+msgid "translator-credits"
+msgstr "Juan Miguel Carrero <streinleght at gmail.com>"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:54
+#: ../src/Frontend-GNOME/AboutDialog.cs:61
 msgid "Smuxi Website"
 msgstr "Web de Smuxi"
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:39
+#: ../src/Frontend-GNOME/CrashDialog.cs:44
 msgid "Oops, I did it again..."
 msgstr "Opps, lo hice de nuevo..."
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:53
+#: ../src/Frontend-GNOME/CrashDialog.cs:57
 msgid "Smuxi crashed because an unhandled exception was thrown!"
 msgstr "Smuxi ha fallado porque una excepción incontrolada ocurrió! "
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:57
+#: ../src/Frontend-GNOME/CrashDialog.cs:61
 msgid "Here is the stacktrace, please report this bug!"
 msgstr "Aquí esta el stacktrace , por favor reporta este fallo!"
 
+#: ../src/Frontend-GNOME/CrashDialog.cs:81
+msgid "_Report Bug"
+msgstr "_Reportar Error"
+
 #: ../src/Frontend-GNOME/EngineManagerDialog.cs:61
 msgid "Engine Manager"
 msgstr "Gestor de Motor"
@@ -430,146 +464,151 @@ msgstr "Gestor de Motor"
 msgid "_Connect"
 msgstr "_Conectar"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:78
-msgid "_Edit"
-msgstr "_Editar"
-
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:90
-#, fuzzy
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:84
 msgid "Select which Smuxi engine you want to connect to"
-msgstr "Elegir motor con el cual deseas que Smuxi conecte"
+msgstr "Seleccione a qué motor Smuxi desea conectarse"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:96
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:90
 msgid "Engine:"
 msgstr "Motor:"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:122
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:182
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:360
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:116
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:176
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:353
 msgid "Local Engine"
 msgstr "Motor Local:"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:174
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:168
 msgid "Please select an engine!"
 msgstr "Seleccione un motor por favor!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:196
-#, fuzzy, csharp-format
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:189
+#, csharp-format
 msgid "Your frontend version ({0}) does not match the engine version ({1})!"
-msgstr ""
-"La version de tu frontend ({0}) no corresponde a la version del motor ({1})!"
+msgstr "Su versión de frontend ({0}) no corresponde a la versión del motor ({1})!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:223
-#, fuzzy
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:216
 msgid "An error occurred while connecting to the engine!"
 msgstr "Se ha producido un error al conectar al motor!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:224
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:217
 #, csharp-format
 msgid "Engine URL: {0}"
 msgstr "Dirección Motor: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:227
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:220
 #, csharp-format
 msgid "Error: {0}"
 msgstr "Error: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:297
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:290
 #, csharp-format
 msgid "Are you sure you want to delete the engine \"{0}\"?"
 msgstr "Estas seguro de que quieres borrar el motor \"{0}\"?"
 
-#: ../src/Frontend-GNOME/Entry.cs:403
-#, fuzzy, csharp-format
+#: ../src/Frontend-GNOME/Entry.cs:421
+#, csharp-format
 msgid "You are going to paste {0} lines. Do you want to continue?"
-msgstr "Vas a pegar {0} líneas , quieres continuar?"
+msgstr "Va a pegar {0} líneas. Desea continuar?"
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Frontend-GNOME/Entry.cs:505
-#, fuzzy
+#: ../src/Frontend-GNOME/Entry.cs:524
 msgid "Frontend Commands"
-msgstr "[Comandos Frontend]"
+msgstr "Comandos Frontend"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:179
+#: ../src/Frontend-GNOME/MainWindow.cs:222
 msgid "_File"
 msgstr "_Fichero"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:195
+#: ../src/Frontend-GNOME/MainWindow.cs:238
 msgid "_Server"
 msgstr "_Servidor"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:199
+#: ../src/Frontend-GNOME/MainWindow.cs:242
 msgid "_Quick Connect"
 msgstr "Conexión _Rapida"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:210
+#: ../src/Frontend-GNOME/MainWindow.cs:253
 msgid "_Manage"
 msgstr "_Administrar"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:217
+#: ../src/Frontend-GNOME/MainWindow.cs:260
 msgid "_Chat"
 msgstr "_Chat"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:221
+#: ../src/Frontend-GNOME/MainWindow.cs:264
 msgid "Open / Join Chat"
 msgstr "Abrir / Unirse a Chat"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:226
+#: ../src/Frontend-GNOME/MainWindow.cs:269
 msgid "_Find Group Chat"
 msgstr "_Encontrar Salas Chat"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:231
+#: ../src/Frontend-GNOME/MainWindow.cs:274
 msgid "C_lear All Activity"
 msgstr "Eliminar Toda Actividad"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:238
+#: ../src/Frontend-GNOME/MainWindow.cs:281
 msgid "_Next Chat"
 msgstr "_Siguiente Chat"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:248
+#: ../src/Frontend-GNOME/MainWindow.cs:291
 msgid "_Previous Chat"
 msgstr "_Chat Anterior"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:300
+#: ../src/Frontend-GNOME/MainWindow.cs:341
+msgid "Open Log"
+msgstr "Abrir Registro"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:355
 msgid "_Engine"
 msgstr "_Motor"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:304
+#: ../src/Frontend-GNOME/MainWindow.cs:359
 msgid "_Use Local Engine"
 msgstr "_Usar Motor Local"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:310
+#: ../src/Frontend-GNOME/MainWindow.cs:365
 msgid "_Add Remote Engine"
 msgstr "_Añadir Motor Remoto"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:315
+#: ../src/Frontend-GNOME/MainWindow.cs:370
 msgid "_Switch Remote Engine"
 msgstr "_Cambiar Motor Remoto"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:322
+#: ../src/Frontend-GNOME/MainWindow.cs:377
 msgid "_View"
 msgstr "_Ver"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:326
+#: ../src/Frontend-GNOME/MainWindow.cs:381
 msgid "_Caret Mode"
 msgstr "_Modo Caret"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:336
+#: ../src/Frontend-GNOME/MainWindow.cs:389
+msgid "_Browse Mode"
+msgstr "_Modo examinar"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:403
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:586
+msgid "Show _Menubar"
+msgstr "Mostrar _Barra de menú"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:430
 msgid "_Help"
 msgstr "_Ayuda"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:507
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:220
+#: ../src/Frontend-GNOME/MainWindow.cs:691
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:225
 msgid "Unable to add server: "
 msgstr "Imposible añadir el servidor: "
 
-#: ../src/Frontend-GNOME/MainWindow.cs:554
+#: ../src/Frontend-GNOME/MainWindow.cs:742
 #, csharp-format
 msgid "Unknown ChatType: {0}"
 msgstr "Comando desconocido: {0}"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:770
+#: ../src/Frontend-GNOME/MainWindow.cs:971
 msgid ""
 "Switching to local engine will disconnect you from the current engine!\n"
 "Are you sure you want to do this?"
@@ -577,7 +616,7 @@ msgstr ""
 "Cambiar al motor local te desconectará del engine actual!\n"
 "¿Estás seguro de que quieres hacer ésto?"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:812
+#: ../src/Frontend-GNOME/MainWindow.cs:1013
 msgid ""
 "Switching the remote engine will disconnect you from the current engine!\n"
 "Are you sure you want to do this?"
@@ -590,37 +629,55 @@ msgid "Sorry, not implemented yet!"
 msgstr "Lo siento , no está aún implementado!"
 
 #. fill ListStore
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:144
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:179
 msgid "Character"
 msgstr "Carácter de Comandos:"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:145
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:180
 msgid "Word"
 msgstr "Palabra"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:155
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:198
+msgid "No Proxy"
+msgstr "Sin proxy"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:212
 #: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:139
 msgid "Connection"
 msgstr "Conexión"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:159
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:216
 msgid "Interface"
 msgstr "Interfaz"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:163
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:220
 msgid "Servers"
 msgstr "Servidores"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:215
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:227
+msgid "Filters"
+msgstr "_Filtros"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:231
+msgid "Logging"
+msgstr "Inicio de sesión"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:281
 msgid "System Default"
 msgstr "Sistema por defecto"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:461
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:588
 msgid "Nicknames(s) field must not be empty."
 msgstr "El campo Nick(s) no debe estar vacío."
 
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:748
+#, csharp-format
+msgid "Invalid highlight regex: '{0}'. Reason: {1}"
+msgstr "Expresión regular inválida: '{0}'. Razón: {1}"
+
 #: ../src/Frontend-GNOME/FindGroupChatDialog.cs:69
 #: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:105
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:271
 msgid "Name"
 msgstr "Nombre"
 
@@ -630,44 +687,38 @@ msgstr "Topic"
 
 #: ../src/Frontend-GNOME/FindGroupChatDialog.cs:102
 msgid ""
-"Searching for group chats without a filter is not recommended.  This may "
-"take a while, or may not work at all.\n"
+"Searching for group chats without a filter is not recommended.  This may take a while, or may not work at all.\n"
 "Do you wish to continue?"
 msgstr ""
-"Buscar un grupo de canales sin filtrar no se recomienda.  Esto puede tardar "
-"un rato, o puede no funcionar.\n"
+"Buscar un grupo de canales sin filtrar no se recomienda.  Esto puede tardar un rato, o puede no funcionar.\n"
 "¿Desea continuar?"
 
 #: ../src/Frontend-GNOME/FindGroupChatDialog.cs:143
 msgid "Error while fetching the list of group chats from the server."
-msgstr ""
-"Se ha producido un error mientras se descargaba la lista salas del servidor."
+msgstr "Se ha producido un error mientras se descargaba la lista salas del servidor."
 
-#: ../src/Frontend-GNOME/Frontend.cs:415
+#: ../src/Frontend-GNOME/Frontend.cs:399
 #, csharp-format
 msgid "Cause: {0}"
 msgstr "Motivo: {0}"
 
-#: ../src/Frontend-GNOME/Frontend.cs:465
-#, fuzzy
+#: ../src/Frontend-GNOME/Frontend.cs:469
 msgid ""
 "The frontend has lost the connection to the server.\n"
 "Do you want to reconnect now?"
 msgstr ""
-"El servidor ha perdido la conexión con el frontend.\n"
-"¿Desea reconectar ahora?"
+"El frontend ha perdido la conexión con el servidor.\n"
+"¿Desea volver a conectar?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:479
-#, fuzzy
+#: ../src/Frontend-GNOME/Frontend.cs:484
 msgid ""
 "Reconnecting to the server has failed.\n"
 "Do you want to try again?"
 msgstr ""
-"El servidor ha perdido la conexión con el frontend.\n"
-"¿Desea reconectar ahora?"
+"La reconexión con el servidor ha fallado.\n"
+"¿Desea volver a intentarlo?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:628
-#, fuzzy
+#: ../src/Frontend-GNOME/Frontend.cs:585
 msgid ""
 "The server has lost the connection to the frontend.\n"
 "Do you want to reconnect now?"
@@ -675,7 +726,12 @@ msgstr ""
 "El servidor ha perdido la conexión con el frontend.\n"
 " ¿Quieres reconectar ahora?"
 
+#: ../src/Frontend-GNOME/NotifyManager.cs:229
+msgid "Show"
+msgstr "Mostrar"
+
 #: ../src/Frontend-GNOME/QuickConnectDialog.cs:62
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:238
 #: ../src/Frontend-GNOME/Preferences/ServerListView.cs:70
 msgid "Protocol"
 msgstr "Protocolo"
@@ -685,11 +741,17 @@ msgstr "Protocolo"
 msgid "Hostname"
 msgstr "Nombre del Host"
 
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:166
+msgid "Unable to load server: "
+msgstr "Imposible cargar el servidor:"
+
 #: ../src/Frontend-GNOME/ChatTypeWidget.cs:54
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:244
 msgid "Person / Private"
 msgstr "Persona / Privado"
 
 #: ../src/Frontend-GNOME/ChatTypeWidget.cs:55
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:245
 msgid "Group / Public"
 msgstr "Grupo / Público"
 
@@ -718,269 +780,303 @@ msgid "Thank you"
 msgstr "Gracias"
 
 #: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:285
-msgid ""
-"An engine with this name already exists! Please specify a different one."
-msgstr ""
+msgid "An engine with this name already exists! Please specify a different one."
+msgstr "Un motor con ese nombre ya existe. Por favor, especifique uno diferente."
 
-#: ../src/Frontend-GNOME/Views/MessageTextView.cs:162
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:198
 #, csharp-format
 msgid "Day changed to {0}"
 msgstr "El día ha cambiado a {0}"
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:241
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:123
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:133
+#, csharp-format
+msgid "Invalid filter regex: '{0}'. Reason: {1}"
+msgstr "Filtro de expresión regular inválido: '{0}'. Razón: {1}"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:200
+msgid "Are you sure you want to delete the selected filter?"
+msgstr "¿Está seguro de querer borrar el filtro seleccionado?"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:246
+msgid "Protocol / Server"
+msgstr "Protocolo / Servidor"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:253
+msgid "Chat Type"
+msgstr "Escribir Chat"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:287
+msgid "Normal"
+msgstr "Normal"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:288
+msgid "Event"
+msgstr "Evento"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:295
+msgid "Type"
+msgstr "_Tipo:"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:321
+msgid "Pattern"
+msgstr "Patrón"
+
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:242
 #, csharp-format
 msgid "Retrieving user list for {0}..."
-msgstr ""
+msgstr "Recuperando la lista de usuario para {0}"
 
 #. TRANSLATOR: this string will be appended to the one above
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:286
-#, fuzzy
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:289
 msgid "done."
 msgstr "hecho."
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:306
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:304
 msgid "Person"
 msgstr "Persona"
 
-#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:72
+#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:68
 msgid ""
 "Closing the protocol chat will also close all open chats connected to it!\n"
 "Are you sure you want to do this?"
 msgstr ""
-"Cerrar el protocolo también cerrará todos los canales abiertos que estés "
-"conectado!\n"
+"Cerrar el protocolo también cerrará todos los canales abiertos que estés conectado!\n"
 "¿Estás seguro de querer hacer ésto?"
 
-#: ../src/Frontend-GNOME/Preferences/ChannelFilterListView.cs:81
-msgid "Pattern"
-msgstr "Patrón"
-
-#: ../src/Frontend-GNOME/Preferences/ChannelFilterListView.cs:96
-msgid "Joins"
-msgstr "Entradas"
-
-#: ../src/Frontend-GNOME/Preferences/ChannelFilterListView.cs:111
-msgid "Parts"
-msgstr "Salidas"
-
-#: ../src/Frontend-GNOME/Preferences/ChannelFilterListView.cs:127
-msgid "Quits"
-msgstr "Cierres"
-
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:182
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:187
 msgid "Are you sure you want to delete the selected server?"
 msgstr "¿Estás seguro de que quieres borrar el servidor seleccionado?"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:42
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:243
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:277
+msgid "Unable to edit server: "
+msgstr "No se puede editar el servidor:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:34
 msgid "Find"
 msgstr "Buscar"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:62
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:54
 msgid "_Search for:"
 msgstr "_Buscar:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:91
-#, fuzzy
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:83
 msgid "_Match Case"
 msgstr "_Coincidir mayúsculas y minúsculas"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:103
-#, fuzzy
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:95
 msgid "Search _Backwards"
-msgstr "Buscar _anterior"
+msgstr "Buscar _hacia atrás"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:115
-#, fuzzy
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:107
 msgid "_Wrap Around"
-msgstr "_Volver Caret"
+msgstr "_Envolver"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:128
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:120
 msgid "Use _Regular Expressions"
 msgstr "Usar _Expresion Regular"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:40
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:32
 msgid "Smuxi - Find Group Chat"
 msgstr "Smuxi- Buscar Grupos de Chat"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:64
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:87
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:56
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:79
 msgid "_Name:"
 msgstr "_Nombre:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:74
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:24
 msgid "Smuxi - Quick Connect"
 msgstr "Smuxi - Conexión Rápida"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:145
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:181
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:195
-msgid "_Port:"
-msgstr "_Puerto"
-
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:204
-msgid "_Hostname:"
-msgstr "Nombre del _Host:"
-
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:214
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:164
-msgid "_Username:"
-msgstr "_Usuario:"
-
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:224
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:207
-msgid "_Password:"
-msgstr "_Contraseña:"
-
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:234
-msgid "_Protocol:"
-msgstr "_Protocolo:"
-
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:253
-#, fuzzy
-msgid "_On Connect Commands:"
-msgstr "Comandos al conectar:"
-
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:264
-#, fuzzy
-msgid "_Ignore Commands"
-msgstr "Comandos al conectar:"
-
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:495
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:487
 msgid "Nicknames:"
 msgstr "Nicks:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1630
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1622
 msgid "<b> User List Position </b>"
 msgstr "<b> Posición Lista de Usuarios </b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1641
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1633
 msgid "<b> Channel </b>"
 msgstr "<b> Canal </b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:64
-#, fuzzy
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1844
+msgid "<b>Channel Filters</b>"
+msgstr "<b>Filtro de canales</b>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1861
+msgid "<b>User Filters</b>"
+msgstr "<b>Filtro de usuarios</b>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:56
 msgid "Use _SSH Tunnel"
 msgstr "Usar Tunel _SSH"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:78
-msgid ""
-"<span size=\"small\">Enables the use of SSH for the connection.  This has a "
-"small performance impact, but is more secure and required when using NAT or "
-"port-based firewalls</span>"
-msgstr ""
-"<span size=\"small\">Permite el uso de SSH para la conexión. Esto conlleva a "
-"una pequeña bajada de rendimiento , pero se aumenta la seguridad y es un "
-"requisito para el uso de NAT o un cortafuegos </span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:70
+msgid "<span size=\"small\">Enables the use of SSH for the connection.  This has a small performance impact, but is more secure and required when using NAT or port-based firewalls</span>"
+msgstr "<span size=\"small\">Permite el uso de SSH para la conexión. Esto conlleva a una pequeña bajada de rendimiento , pero se aumenta la seguridad y es un requisito para el uso de NAT o un cortafuegos </span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:157
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:149
 msgid "SSH _Host:"
 msgstr "_Servidor SSH:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:168
-msgid ""
-"<span size=\"small\">DNS or IP address and port of the SSH server</span>"
-msgstr ""
-"<span size=\"small\">DNS o dirección IP y puerto del servidor SSH</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:160
+msgid "<span size=\"small\">DNS or IP address and port of the SSH server</span>"
+msgstr "<span size=\"small\">DNS o dirección IP y puerto del servidor SSH</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:208
-msgid ""
-"<span size=\"small\">DNS or IP address and port of the Smuxi server</span>"
-msgstr ""
-"<span size=\"small\">DNS o dirección IP y puerto del servidor Smuxi</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:173
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:187
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:155
+msgid "_Port:"
+msgstr "_Puerto"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:200
+msgid "<span size=\"small\">DNS or IP address and port of the Smuxi server</span>"
+msgstr "<span size=\"small\">DNS o dirección IP y puerto del servidor Smuxi</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:221
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:213
 msgid "_Smuxi Host:"
 msgstr "_Servidor Smuxi:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:76
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:68
 msgid "_SSH Username: (optional)"
 msgstr "_Usuario SSH: (opcional)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:99
-msgid ""
-"<span size=\"small\">Username which will be used to log into the SSH server</"
-"span>"
-msgstr ""
-"<span size=\"small\">Usuario que sere usado para logear en el servidor SSH</"
-"span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:91
+msgid "<span size=\"small\">Username which will be used to log into the SSH server</span>"
+msgstr "<span size=\"small\">Usuario que sere usado para logear en el servidor SSH</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:119
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:111
 msgid "_SSH Password: (optional)"
-msgstr ""
+msgstr "Contraseña _SSH: (opcional)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:143
-msgid ""
-"<span size=\"small\">Password which will be used to log into the SSH server. "
-"The password is optional if SSH key authorization is used (via Pageant from "
-"the PuTTY tools).</span>"
-msgstr ""
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:135
+msgid "<span size=\"small\">Password which will be used to log into the SSH server. The password is optional if SSH key authorization is used (via Pageant from the PuTTY tools).</span>"
+msgstr "<span size=\"small\">Contraseña que puede ser usada para iniciar sesión en el servidor SSH. La contraseña es opcional si la clave de autorización SSH es usada (via Pageant desde las utilidades de PuTTy).</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:187
-msgid ""
-"<span size=\"small\">Username which will be used to log into the Smuxi "
-"server</span>"
-msgstr ""
-"<span size=\"small\">Usuario que sere usado para logear en el servidor "
-"Smuxi</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:156
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:214
+msgid "_Username:"
+msgstr "_Usuario:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:179
+msgid "<span size=\"small\">Username which will be used to log into the Smuxi server</span>"
+msgstr "<span size=\"small\">Usuario que sere usado para logear en el servidor Smuxi</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:231
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:199
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:113
+msgid "_Password:"
+msgstr "_Contraseña:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:223
 msgid "<span size=\"small\">Password of the user</span>"
 msgstr "<span size=\"small\">Contraseña del usuario</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:251
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:243
 msgid "_Verify Password:"
 msgstr "_Verifica Contraseña:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:275
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:267
 msgid "<span size=\"small\">Repeat the password for verification</span>"
 msgstr "<span size=\"small\">Repetir contraseña para verificación</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs:27
-#, fuzzy
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs:19
 msgid ""
 "Welcome to the Smuxi Engine Configuration Assistant.\n"
 "You need to enter some information before you can use the engine.\n"
 "\n"
 "Click \"Forward\" to begin."
 msgstr ""
-"Bienvenido al Asistente de Configuración de  Motor de Smuxi.\n"
-"Necesita introducir alguna información antes de que puedas usar el engine.\n"
+"Bienvenido al asistente de configuración del motor de Smuxi.\n"
+"Necesita introducir alguna información antes de poder utilizar el motor.\n"
 "\n"
-"Click \"Avanzar\" para comenzar."
+"Haga click en \"Avanzar\" para empezar."
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:52
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:44
 msgid "_Engine Name:"
 msgstr "Nombre del _Motor:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:75
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:67
 msgid "<span size=\"small\">Profile name of the new engine</span>"
 msgstr "<span size=\"small\">Nombre del perfil del nuevo motor</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:96
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:88
 msgid "_Default Engine:"
 msgstr "Motor por _Defecto:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:107
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:99
 msgid "Use as new default engine"
 msgstr "Usar como motor por defecto"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:120
-#, fuzzy
-msgid ""
-"<span size=\"small\">If enabled, the current engine will be the default next "
-"time Smuxi is started</span>"
-msgstr ""
-"<span size=\"small\">Si se habilita modifica el motor actual por defecto "
-"cuando Smuxi arranque la próxima vez</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:112
+msgid "<span size=\"small\">If enabled, the current engine will be the default next time Smuxi is started</span>"
+msgstr "<span size=\"small\">Si está habilitada, el motor actual será utilizado como predeterminado por Smuxi la próxima vez que inicie</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:26
 msgid "Smuxi - Open Chat"
 msgstr "Smuxi - Chat Abierto"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:69
 msgid "_Type:"
 msgstr "_Tipo:"
 
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:80
+msgid "_Hostname:"
+msgstr "Nombre del _Host:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:101
+msgid "_Network:"
+msgstr "_Red:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:224
+msgid "_Protocol:"
+msgstr "_Protocolo:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:248
+msgid "Use Encryption"
+msgstr "Usar cifrado"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:260
+msgid "Validate Server Certificate"
+msgstr "Validar el certificado del servidor."
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:280
+msgid "_On Connect Commands:"
+msgstr "_Comandos al conectar:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:291
+msgid "_Ignore Commands"
+msgstr "_Ignorar comandos"
+
+#~ msgid "German"
+#~ msgstr "Alemán"
+
+#~ msgid "Spanish"
+#~ msgstr "Español"
+
+#~ msgid "British English"
+#~ msgstr "Inglés Británico"
+
+#~ msgid "French"
+#~ msgstr "Francés"
+
+#~ msgid "Italian"
+#~ msgstr "Italiano"
+
+#~ msgid "_Edit"
+#~ msgstr "_Editar"
+
+#~ msgid "Joins"
+#~ msgstr "Entradas"
+
+#~ msgid "Parts"
+#~ msgstr "Salidas"
+
+#~ msgid "Quits"
+#~ msgstr "Cierres"
+
 #~ msgid "Unknown Command: {0}"
 #~ msgstr "Comando desconocido: {0}"
 
diff --git a/po-Frontend-GNOME/fr.po b/po-Frontend-GNOME/fr.po
index 4fbec1c..80bfcb1 100644
--- a/po-Frontend-GNOME/fr.po
+++ b/po-Frontend-GNOME/fr.po
@@ -1,21 +1,22 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-# Clement BOURGEOIS <moonpyk at gmail.com>, 2008.
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
 # 
+# Translators:
+# Clément Bourgeois <moonpyk at gmail.com>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: Smuxi 0.6.4\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-08-10 19:14+0200\n"
-"PO-Revision-Date: 2010-07-28 18:05+0100\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:22+0100\n"
+"PO-Revision-Date: 2011-12-30 23:13+0000\n"
 "Last-Translator: Clément Bourgeois <moonpyk at gmail.com>\n"
-"Language-Team: French Localization <debian-l10n-french at lists.debian.org>\n"
+"Language-Team: French (http://www.transifex.net/projects/p/smuxi/team/fr/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: French\n"
-"X-Poedit-Country: FRANCE\n"
+"Language: fr\n"
+"Plural-Forms: nplurals=2; plural=(n > 1)\n"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:1
 msgid "<b> Chat </b>"
@@ -26,7 +27,7 @@ msgid "<b> Color </b>"
 msgstr "<b> Couleur </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:3
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1364
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1172
 msgid "<b> Entry Field </b>"
 msgstr "<b> Champ d'entrée </b>"
 
@@ -35,7 +36,7 @@ msgid "<b> Font </b>"
 msgstr "<b> Police </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:5
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1694
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1502
 msgid "<b> Highlighting </b>"
 msgstr "<b> Surlignement </b>"
 
@@ -48,335 +49,385 @@ msgid "<b> Person List Position </b>"
 msgstr "<b> Position de la liste des utilisateurs </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:8
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1201
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1009
 msgid "<b> Tab Colors </b>"
 msgstr "<b> Couleur des onglets </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:9
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1102
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:910
 msgid "<b> Tabs Position </b>"
 msgstr "<b> Position des onglets </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:10
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1507
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1315
 msgid "<b> Topic Position </b>"
 msgstr "<b> Position du sujet </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:11
+msgid "<b>Advanced</b>"
+msgstr "<b>Avancé</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:12
+msgid "<b>General</b>"
+msgstr "<b>Général</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:13
+msgid "<b>Global Commands</b>"
+msgstr "<b>Commandes globales</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:14
+msgid "<b>Message Buffer</b>"
+msgstr "<b>Tampon de messages</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:15
 msgid "<b>Messaging Menu</b>"
 msgstr "<b>Menu de messagerie</b>"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:12
+#: ../glade/smuxi-frontend-gnome.glade.h:16
+msgid "<b>Network Proxy</b>"
+msgstr "<b>Proxy réseau</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:17
 msgid "<b>Notification Popups</b>"
 msgstr "<b>Popups de notification</b>"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:13
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1153
+#: ../glade/smuxi-frontend-gnome.glade.h:18
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:961
 msgid "Activity"
 msgstr "Activité"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:14
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:99
+#: ../glade/smuxi-frontend-gnome.glade.h:19
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:209
 msgid "Automatically connect to server at startup"
 msgstr "Se connecter automatiquement au serveur à chaque démarrage"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:15
+#: ../glade/smuxi-frontend-gnome.glade.h:20
 msgid "Background"
 msgstr "Arrière plan"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:16
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1352
+#: ../glade/smuxi-frontend-gnome.glade.h:21
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1160
 msgid "Bash-Style Completion"
 msgstr "Complétion style Bash"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:17
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1682
+#: ../glade/smuxi-frontend-gnome.glade.h:22
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1490
 msgid "Beep on highlight"
 msgstr "Émettre un son en cas de surlignage"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:18
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:972
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:994
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1453
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1478
+#: ../glade/smuxi-frontend-gnome.glade.h:23
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:780
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:802
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1261
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1286
 msgid "Bottom"
 msgstr "Bas"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:19
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:738
+#: ../glade/smuxi-frontend-gnome.glade.h:24
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:546
 msgid "Buffer Lines:"
 msgstr "Lignes du tampon :"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:20
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:663
+#: ../glade/smuxi-frontend-gnome.glade.h:25
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:471
 msgid "C_onnection"
 msgstr "C_onnexion"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:21
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1304
+#: ../glade/smuxi-frontend-gnome.glade.h:26
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1112
 msgid "Command Character:"
 msgstr "Caractère des commandes :"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:22
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1327
+#: ../glade/smuxi-frontend-gnome.glade.h:27
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1135
 msgid "Command History Size:"
 msgstr "Taille de l'historique des commandes :"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:23
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1284
+#: ../glade/smuxi-frontend-gnome.glade.h:28
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1092
 msgid "Completion Character:"
 msgstr "Caractère de complétion :"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:24
+#: ../glade/smuxi-frontend-gnome.glade.h:29
 msgid "Enable"
 msgstr "Activer"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:25
+#: ../glade/smuxi-frontend-gnome.glade.h:30
 msgid "Enabled"
 msgstr "Activé"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:26
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:551
+#: ../glade/smuxi-frontend-gnome.glade.h:31
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:359
 msgid "Encoding:"
 msgstr "Encodage :"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:27
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:761
+#: ../glade/smuxi-frontend-gnome.glade.h:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:569
 msgid "Engine Buffer Lines:"
 msgstr "Lignes du tampon moteur"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:28
+#: ../glade/smuxi-frontend-gnome.glade.h:33
 msgid "Foreground"
 msgstr "Texte"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:29
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:917
+#: ../glade/smuxi-frontend-gnome.glade.h:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:725
 msgid "General"
 msgstr "Général"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:30
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1173
+#: ../glade/smuxi-frontend-gnome.glade.h:35
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:981
 msgid "Highlight"
 msgstr "Surligner"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:31
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1658
+#: ../glade/smuxi-frontend-gnome.glade.h:36
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1466
 msgid "Highlight words:"
 msgstr "Mots surlignés :"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:32
+#: ../glade/smuxi-frontend-gnome.glade.h:37
+msgid "Host:"
+msgstr "Nom d'hôte :"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:38
 msgid "Hostname:"
 msgstr "Nom d'hôte"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:33
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1373
+#: ../glade/smuxi-frontend-gnome.glade.h:39
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
 msgid "Input"
 msgstr "Entrée"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:34
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1163
+#: ../glade/smuxi-frontend-gnome.glade.h:40
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:971
 msgid "Join/Part/Mode"
 msgstr "Join/Part/Mode"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:35
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1008
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1033
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1527
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1553
+#: ../glade/smuxi-frontend-gnome.glade.h:41
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:816
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:841
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1335
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1361
 msgid "Left"
 msgstr "Gauche"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:36
+#: ../glade/smuxi-frontend-gnome.glade.h:42
 msgid "Log Filtered Messages"
 msgstr "Journaliser les messages filtrés"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:37
+#: ../glade/smuxi-frontend-gnome.glade.h:43
 msgid "Network:"
 msgstr "Réseau :"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:38
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1394
+#: ../glade/smuxi-frontend-gnome.glade.h:44
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1202
 msgid "Nick Colors"
 msgstr "Couleur du surnom"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:39
+#: ../glade/smuxi-frontend-gnome.glade.h:45
 msgid "Nickname(s):"
 msgstr "Surnom(s) :"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:40
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1145
+#: ../glade/smuxi-frontend-gnome.glade.h:46
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:953
 msgid "No Activity"
 msgstr "Aucune activité"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:41
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1088
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1493
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1608
+#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:896
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1301
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1416
 msgid "None"
 msgstr "Aucun"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:42
+#: ../glade/smuxi-frontend-gnome.glade.h:48
 msgid "Notification"
 msgstr "Notification"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:43
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:573
+#: ../glade/smuxi-frontend-gnome.glade.h:49
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:381
 msgid "On Connect Commands:"
 msgstr "Commandes de connexion :"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:44
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:619
+#: ../glade/smuxi-frontend-gnome.glade.h:50
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:427
 msgid "On Startup Commands:"
 msgstr "Commandes de démarrage :"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:45
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1706
+#: ../glade/smuxi-frontend-gnome.glade.h:51
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1514
 msgid "Output"
 msgstr "Sortie"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:46
+#: ../glade/smuxi-frontend-gnome.glade.h:52
 msgid "Override"
 msgstr "Ignorer"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../glade/smuxi-frontend-gnome.glade.h:53
 msgid "Password:"
 msgstr "Mot de passe :"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:48
+#: ../glade/smuxi-frontend-gnome.glade.h:54
+msgid "Persistency Type:"
+msgstr "Type de persistance :"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:55
+msgid "Persistent Buffer Lines:"
+msgstr "Lignes de tampon sauvegardées :"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:56
 msgid "Port:"
 msgstr "Port :"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:49
+#: ../glade/smuxi-frontend-gnome.glade.h:57
 msgid "Protocol:"
 msgstr "Protocole :"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:50
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:530
+#: ../glade/smuxi-frontend-gnome.glade.h:58
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:338
 msgid "Realname:"
 msgstr "Nom réel :"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:51
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1048
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1073
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1568
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1593
+#: ../glade/smuxi-frontend-gnome.glade.h:59
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:856
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:881
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1376
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1401
 msgid "Right"
 msgstr "Droite"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:52
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:187
+#: ../glade/smuxi-frontend-gnome.glade.h:60
+msgid "Show Advanced Settings"
+msgstr "Afficher les reglages avancés"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:61
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:170
 msgid "Show Password"
 msgstr "Afficher le mot de passe"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:53
+#: ../glade/smuxi-frontend-gnome.glade.h:62
 msgid "Show Smuxi in the messaging menu"
 msgstr "Afficher Smuxi dans le menu messagerie"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:54
+#: ../glade/smuxi-frontend-gnome.glade.h:63
 msgid "Show always"
 msgstr "Toujours montrer"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:55
+#: ../glade/smuxi-frontend-gnome.glade.h:64
 msgid "Show notification popups"
 msgstr "Afficher les popups de notification"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:56
+#: ../glade/smuxi-frontend-gnome.glade.h:65
 msgid "Show when window is closed"
 msgstr "Montrer quand la fenêtre est fermée"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:57
+#: ../glade/smuxi-frontend-gnome.glade.h:66
 msgid "Show when window is minimized"
 msgstr "Montrer quand la fenêtre est minimisée"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:58
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:398
-msgid "Smuxi - Preferences"
-msgstr "Smuxi - Préférences"
-
-#: ../glade/smuxi-frontend-gnome.glade.h:59
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:18
+#: ../glade/smuxi-frontend-gnome.glade.h:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:16
 msgid "Smuxi - Server"
 msgstr "Smuxi - Serveur"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:60
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:820
+#: ../glade/smuxi-frontend-gnome.glade.h:68
+msgid "Smuxi Preferences"
+msgstr "Préférences de Smuxi"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:69
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:628
 msgid "Strip Colors"
 msgstr "Ignorer les couleurs"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:61
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:859
+#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:667
 msgid "Strip Formattings"
 msgstr "Ignorer le formatage"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:62
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:899
+#: ../glade/smuxi-frontend-gnome.glade.h:71
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:707
 msgid "Strip UTF-8"
 msgstr "Ignorer l'UTF-8"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:63
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1214
+#: ../glade/smuxi-frontend-gnome.glade.h:72
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1022
 msgid "Tabs"
 msgstr "Onglets"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:64
-msgid "The nickname to use. You can specify extra nicknames (separated by spaces) which will be used as fallbacks when the first choice is not available. By default $nick_ and $nick__ will be used as fallbacks."
-msgstr "Le surnom est déjà en cours d'utilisation. Vous pouvez spécifier plus d'un seul surnom, séparés par des espaces. Ceux ci seront utilisés comme solution de repli si le premier surnom n'est pas disponible. Par défaut, $nick et $nick__ sont utilisés."
+#: ../glade/smuxi-frontend-gnome.glade.h:73
+msgid ""
+"The nickname to use. You can specify extra nicknames (separated by spaces) "
+"which will be used as fallbacks when the first choice is not available. By "
+"default $nick_ and $nick__ will be used as fallbacks."
+msgstr ""
+"Le surnom est déjà en cours d'utilisation. Vous pouvez spécifier plus d'un "
+"seul surnom, séparés par des espaces. Ceux ci seront utilisés comme solution"
+" de repli si le premier surnom n'est pas disponible. Par défaut, $nick et "
+"$nick__ sont utilisés."
 
-#: ../glade/smuxi-frontend-gnome.glade.h:65
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:718
+#: ../glade/smuxi-frontend-gnome.glade.h:74
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:526
 msgid "Timestamp Format:"
 msgstr "Format temporel :"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:66
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:935
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:959
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1412
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1438
+#: ../glade/smuxi-frontend-gnome.glade.h:75
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:743
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:767
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1220
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1246
 msgid "Top"
 msgstr "Haut"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:67
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:507
+#: ../glade/smuxi-frontend-gnome.glade.h:76
+msgid "Type:"
+msgstr "Type :"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:315
 msgid "Username:"
 msgstr "Nom d'utilisateur :"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:68
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1873
+#: ../glade/smuxi-frontend-gnome.glade.h:78
+msgid "Volatile Buffer Lines:"
+msgstr "Lignes de tampon volatiles"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:79
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1681
 msgid "_Filters"
 msgstr "_Filtres"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:69
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1715
+#: ../glade/smuxi-frontend-gnome.glade.h:80
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1523
 msgid "_Interface"
 msgstr "_Interface"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../glade/smuxi-frontend-gnome.glade.h:81
 msgid "_Logging"
 msgstr "_Journalisation"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:71
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1781
+#: ../glade/smuxi-frontend-gnome.glade.h:82
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1589
 msgid "_Servers"
 msgstr "_Serveurs"
 
 #. This is a setting for character based line wrapping vs word based when
 #. showing messages
-#: ../glade/smuxi-frontend-gnome.glade.h:73
+#: ../glade/smuxi-frontend-gnome.glade.h:84
 msgid "_Wrap Mode:"
 msgstr "Mode _circulaire :"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:74
+#: ../glade/smuxi-frontend-gnome.glade.h:85
 msgid ""
 "ss = seconds\n"
 "mm = minutes\n"
@@ -407,30 +458,34 @@ msgid "IRC Chat"
 msgstr "Chat IRC"
 
 #: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:3
+msgid "Smuxi"
+msgstr "Smuxi"
+
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:4
 msgid "Smuxi IRC Client"
 msgstr "Client IRC Smuxi"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:58
+#: ../src/Frontend-GNOME/AboutDialog.cs:60
 msgid "translator-credits"
 msgstr "Clément Bourgeois <moonpyk at gmail.com>"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:61
+#: ../src/Frontend-GNOME/AboutDialog.cs:65
 msgid "Smuxi Website"
 msgstr "Site web de Smuxi"
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:44
+#: ../src/Frontend-GNOME/CrashDialog.cs:46
 msgid "Oops, I did it again..."
 msgstr "OoOps, boulette..."
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:57
+#: ../src/Frontend-GNOME/CrashDialog.cs:59
 msgid "Smuxi crashed because an unhandled exception was thrown!"
 msgstr "Smuxi a planté en raison de la levée d'une exception non gérée !"
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:61
+#: ../src/Frontend-GNOME/CrashDialog.cs:63
 msgid "Here is the stacktrace, please report this bug!"
 msgstr "Voici la pile d'appels, envoyez le rapport de bug s'il-vous-plaît ! "
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:81
+#: ../src/Frontend-GNOME/CrashDialog.cs:83
 msgid "_Report Bug"
 msgstr "_Rapporter un bogue"
 
@@ -438,146 +493,159 @@ msgstr "_Rapporter un bogue"
 msgid "Engine Manager"
 msgstr "Gestionnaire de moteurs"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:68
-msgid "_Connect"
-msgstr "_Connexion"
-
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:84
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:80
 msgid "Select which Smuxi engine you want to connect to"
 msgstr "Sélectionnez le moteur Smuxi auquel vous voulez vous connecter"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:90
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:86
 msgid "Engine:"
 msgstr "Moteur :"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:116
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:176
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:353
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:97
+msgid "Use Low Bandwidth Mode"
+msgstr "Utiliser le mode bande passante faible"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:121
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:181
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:358
 msgid "Local Engine"
 msgstr "Moteur local"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:168
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:173
 msgid "Please select an engine!"
 msgstr "Sélectionnez un moteur s'il vous plaît !"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:189
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:194
 #, csharp-format
 msgid "Your frontend version ({0}) does not match the engine version ({1})!"
-msgstr "Votre version de l'interface utilisateur ({0}) ne correspond pas à celle du moteur ({1}) !"
+msgstr ""
+"Votre version de l'interface utilisateur ({0}) ne correspond pas à celle du "
+"moteur ({1}) !"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:216
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:221
 msgid "An error occurred while connecting to the engine!"
 msgstr "Une erreur est survenue durant la connexion au moteur !"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:217
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:222
 #, csharp-format
 msgid "Engine URL: {0}"
 msgstr "URL du moteur : {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:220
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:225
 #, csharp-format
 msgid "Error: {0}"
 msgstr "Erreur : {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:290
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:295
 #, csharp-format
 msgid "Are you sure you want to delete the engine \"{0}\"?"
 msgstr "Êtes vous sûr(e) de vouloir supprimer le moteur \"{0}\" ?"
 
-#: ../src/Frontend-GNOME/Entry.cs:412
+#: ../src/Frontend-GNOME/Entry.cs:443
 #, csharp-format
 msgid "You are going to paste {0} lines. Do you want to continue?"
-msgstr "Vous vous apprêtez à coller {0} lignes de texte, êtes vous sûr(e) de vouloir continuer ?"
+msgstr ""
+"Vous vous apprêtez à coller {0} lignes de texte, êtes vous sûr(e) de vouloir"
+" continuer ?"
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Frontend-GNOME/Entry.cs:515
+#: ../src/Frontend-GNOME/Entry.cs:547
 msgid "Frontend Commands"
 msgstr "Commandes Frontend"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:193
+#: ../src/Frontend-GNOME/MainWindow.cs:252
 msgid "_File"
 msgstr "_Fichier"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:209
+#: ../src/Frontend-GNOME/MainWindow.cs:276
 msgid "_Server"
 msgstr "_Serveur"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:213
+#: ../src/Frontend-GNOME/MainWindow.cs:280
 msgid "_Quick Connect"
 msgstr "_Connexion rapide"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:224
+#: ../src/Frontend-GNOME/MainWindow.cs:291
 msgid "_Manage"
 msgstr "_Gestion"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:231
+#: ../src/Frontend-GNOME/MainWindow.cs:298
 msgid "_Chat"
 msgstr "_Discussion"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:235
+#: ../src/Frontend-GNOME/MainWindow.cs:302
 msgid "Open / Join Chat"
 msgstr "Ouvrir / Rejoindre chat"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:240
+#: ../src/Frontend-GNOME/MainWindow.cs:308
 msgid "_Find Group Chat"
 msgstr "_Rechercher le groupe de discussion"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:245
+#: ../src/Frontend-GNOME/MainWindow.cs:314
 msgid "C_lear All Activity"
 msgstr "_Supprimer toute activité"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:252
+#: ../src/Frontend-GNOME/MainWindow.cs:321
 msgid "_Next Chat"
 msgstr "Discussion _suivante"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:262
+#: ../src/Frontend-GNOME/MainWindow.cs:335
 msgid "_Previous Chat"
 msgstr "Discussion _précédente"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:312
+#: ../src/Frontend-GNOME/MainWindow.cs:389
 msgid "Open Log"
 msgstr "Ouvrir le journal"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:326
+#: ../src/Frontend-GNOME/MainWindow.cs:407
 msgid "_Engine"
 msgstr "_Moteur"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:330
+#: ../src/Frontend-GNOME/MainWindow.cs:411
 msgid "_Use Local Engine"
 msgstr "_Utiliser le moteur local"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:336
+#: ../src/Frontend-GNOME/MainWindow.cs:417
 msgid "_Add Remote Engine"
 msgstr "_Ajouter un moteur distant"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:341
+#: ../src/Frontend-GNOME/MainWindow.cs:422
 msgid "_Switch Remote Engine"
 msgstr "_Changer de moteur distant"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:348
+#: ../src/Frontend-GNOME/MainWindow.cs:429
 msgid "_View"
 msgstr "_Vue"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:352
+#: ../src/Frontend-GNOME/MainWindow.cs:433
 msgid "_Caret Mode"
 msgstr "Mode _curseur"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:362
+#: ../src/Frontend-GNOME/MainWindow.cs:445
+msgid "_Browse Mode"
+msgstr "Mode _navigateur"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:463
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:722
+msgid "Show _Menubar"
+msgstr "Afficher la barre de _menus"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:494
 msgid "_Help"
 msgstr "_Aide"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:616
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:222
+#: ../src/Frontend-GNOME/MainWindow.cs:768
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:225
 msgid "Unable to add server: "
 msgstr "Impossible d'ajouter le serveur :"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:663
+#: ../src/Frontend-GNOME/MainWindow.cs:828
 #, csharp-format
 msgid "Unknown ChatType: {0}"
 msgstr "ChatType inconnu : {0}"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:892
+#: ../src/Frontend-GNOME/MainWindow.cs:1097
 msgid ""
 "Switching to local engine will disconnect you from the current engine!\n"
 "Are you sure you want to do this?"
@@ -585,7 +653,7 @@ msgstr ""
 "Changer de moteur vers le moteur local va vous déconnecter du moteur actuel !\n"
 "Êtes vous sûr(e) de vouloir continuer ?"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:934
+#: ../src/Frontend-GNOME/MainWindow.cs:1139
 msgid ""
 "Switching the remote engine will disconnect you from the current engine!\n"
 "Are you sure you want to do this?"
@@ -598,74 +666,98 @@ msgid "Sorry, not implemented yet!"
 msgstr "Désolé, fonctionnalité pas encore implémentée !"
 
 #. fill ListStore
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:171
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:179
 msgid "Character"
 msgstr "Caractère"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:172
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:180
 msgid "Word"
 msgstr "Mot"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:182
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:139
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:197
+msgid "Volatile"
+msgstr "Volatile"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:199
+msgid "Persistent"
+msgstr "Persistant"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:222
+msgid "No Proxy"
+msgstr "Pas de proxy"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:224
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:307
+msgid "System Default"
+msgstr "Défaut du système"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:238
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:140
 msgid "Connection"
 msgstr "Connexion"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:186
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:242
 msgid "Interface"
 msgstr "Interface"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:190
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:246
 msgid "Servers"
 msgstr "Serveurs"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:197
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:253
 msgid "Filters"
 msgstr "Filtres"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:201
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:257
 msgid "Logging"
-msgstr "_Journalisation"
-
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:251
-msgid "System Default"
-msgstr "Défaut du système"
+msgstr "Journalisation"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:528
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:642
 msgid "Nicknames(s) field must not be empty."
 msgstr "Le champ surnom(s) ne doit pas être vide."
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:672
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:823
 #, csharp-format
 msgid "Invalid highlight regex: '{0}'. Reason: {1}"
 msgstr "Expression régulière de surlignage invalide '{0}'. Raison : {1} "
 
-#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:69
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:105
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:81
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:106
 #: ../src/Frontend-GNOME/Views/FilterListWidget.cs:271
 msgid "Name"
 msgstr "Nom"
 
-#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:74
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:86
 msgid "Topic"
 msgstr "Sujet"
 
-#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:102
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:115
 msgid ""
 "Searching for group chats without a filter is not recommended.  This may take a while, or may not work at all.\n"
 "Do you wish to continue?"
 msgstr "Chercher des groupes de discussion"
 
-#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:143
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:156
 msgid "Error while fetching the list of group chats from the server."
-msgstr "Erreur durant la récupération de la liste des groupes de discussion du serveur."
+msgstr ""
+"Erreur durant la récupération de la liste des groupes de discussion du "
+"serveur."
+
+#: ../src/Frontend-GNOME/Frontend.cs:325
+msgid "Disconnected from engine."
+msgstr "Déconnecté du moteur."
+
+#: ../src/Frontend-GNOME/Frontend.cs:368
+#, csharp-format
+msgid "Reconnecting to engine... (attempt {0})"
+msgstr "Reconnexion au moteur... (essai {0})"
 
-#: ../src/Frontend-GNOME/Frontend.cs:394
+#: ../src/Frontend-GNOME/Frontend.cs:465
 #, csharp-format
 msgid "Cause: {0}"
 msgstr "Cause : {0}"
 
-#: ../src/Frontend-GNOME/Frontend.cs:464
+#: ../src/Frontend-GNOME/Frontend.cs:583
 msgid ""
 "The frontend has lost the connection to the server.\n"
 "Do you want to reconnect now?"
@@ -673,7 +765,7 @@ msgstr ""
 "Le serveur a perdu la connexion a l'interface.\n"
 "Voulez-vous vous reconnecter maintenant ?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:479
+#: ../src/Frontend-GNOME/Frontend.cs:602
 msgid ""
 "Reconnecting to the server has failed.\n"
 "Do you want to try again?"
@@ -681,7 +773,7 @@ msgstr ""
 "La reconnexion au serveur a échoué.\n"
 "Voulez-vous vous reconnecter maintenant ?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:580
+#: ../src/Frontend-GNOME/Frontend.cs:705
 msgid ""
 "The server has lost the connection to the frontend.\n"
 "Do you want to reconnect now?"
@@ -689,7 +781,7 @@ msgstr ""
 "Le serveur a perdu la connexion à l'interface.\n"
 "Voulez-vous vous reconnecter maintenant ?"
 
-#: ../src/Frontend-GNOME/NotifyManager.cs:229
+#: ../src/Frontend-GNOME/NotifyManager.cs:267
 msgid "Show"
 msgstr "Afficher"
 
@@ -718,35 +810,41 @@ msgstr "Personne / Privé"
 msgid "Group / Public"
 msgstr "Groupe / Public"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:70
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:71
 msgid "Engine Assistant - Smuxi"
 msgstr "Assistant moteur - Smuxi"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:92
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:93
 msgid "Add Smuxi Engine"
 msgstr "Ajouter un moteur Smuxi"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:94
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:95
 msgid "Edit Smuxi Engine"
 msgstr "Editer un moteur Smuxi"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:203
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:204
 msgid "Credentials"
 msgstr "Autorisations"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:265
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:284
 msgid "Now you can use the Smuxi Engine"
 msgstr "Vous êtes prêt à utiliser le moteur Smuxi"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:268
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:287
 msgid "Thank you"
 msgstr "Merci"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:285
-msgid "An engine with this name already exists! Please specify a different one."
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:304
+msgid ""
+"An engine with this name already exists! Please specify a different one."
 msgstr "Un moteur avec ce nom éxiste deja ! Veuillez en spécifier un autre."
 
-#: ../src/Frontend-GNOME/Views/MessageTextView.cs:198
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:204
+#, csharp-format
+msgid "Day changed from {0} to {1}"
+msgstr "Jour changé de {0} à {1}"
+
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:210
 #, csharp-format
 msgid "Day changed to {0}"
 msgstr "Jour changé à {0}"
@@ -785,21 +883,25 @@ msgstr "Type :"
 msgid "Pattern"
 msgstr "Motif"
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:241
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:506
+msgid "Low Bandwidth Mode is active: no messages synced."
+msgstr "Mode faible bande passante activé : aucun message synchronisé."
+
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:245
 #, csharp-format
 msgid "Retrieving user list for {0}..."
 msgstr "Téléchargement de la liste des utilisateurs pour {0}..."
 
 #. TRANSLATOR: this string will be appended to the one above
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:288
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:279
 msgid "done."
 msgstr "terminé."
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:303
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:290
 msgid "Person"
 msgstr "Personne"
 
-#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:68
+#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:69
 msgid ""
 "Closing the protocol chat will also close all open chats connected to it!\n"
 "Are you sure you want to do this?"
@@ -807,141 +909,183 @@ msgstr ""
 "Fermer la fenêtre de chat du protocole va aussi fermer toutes discussions connectées sur celui-ci !\n"
 "Êtes vous sûr(e) de vouloir continuer ?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:184
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:187
 msgid "Are you sure you want to delete the selected server?"
 msgstr "Êtes vous sûr(e) de vouloir supprimer le serveur sélectionné ?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:240
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:274
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:243
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:277
 msgid "Unable to edit server: "
 msgstr "Impossible d'editer le serveur :"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:24
 msgid "Find"
 msgstr "Rechercher"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:54
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:44
 msgid "_Search for:"
 msgstr "_Terme de recherche :"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:83
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:73
 msgid "_Match Case"
 msgstr "_Respecter la casse"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:95
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:85
 msgid "Search _Backwards"
 msgstr "Recherche en _arrière"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:107
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:97
 msgid "_Wrap Around"
 msgstr "Recherche _cyclique"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:120
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:110
 msgid "Use _Regular Expressions"
 msgstr "Utiliser des _expression régulières"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:23
 msgid "Smuxi - Find Group Chat"
 msgstr "Smuxi - Trouver un groupe de discussion"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:56
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:79
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:73
 msgid "_Name:"
 msgstr "_Nom :"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:24
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:19
 msgid "Smuxi - Quick Connect"
 msgstr "Smuxi - Connexion rapide"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:487
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:206
+msgid "Smuxi - Preferences"
+msgstr "Smuxi - Préférences"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:295
 msgid "Nicknames:"
 msgstr "Surnoms :"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1622
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1430
 msgid "<b> User List Position </b>"
 msgstr "<b> Position de la liste d'utilisateurs </b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1633
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1441
 msgid "<b> Channel </b>"
 msgstr "<b> Canal </b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1844
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1652
 msgid "<b>Channel Filters</b>"
 msgstr "<b>Filtres de canaux</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1861
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1669
 msgid "<b>User Filters</b>"
 msgstr "<b>Filtres d'utilisateurs</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:56
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:42
 msgid "Use _SSH Tunnel"
 msgstr "Utiliser un tunnel _SSH"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:70
-msgid "<span size=\"small\">Enables the use of SSH for the connection.  This has a small performance impact, but is more secure and required when using NAT or port-based firewalls</span>"
-msgstr "<span size=\"small\">Active l'utilisation de SSH pour la connexion.  Ceci a un leger impact négatif sur les performances, mais améliore la sécurité et est parfois nécéssaire en cas d'utilisation d'un systeme NAT ou d'un firewall régi par ports</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:56
+msgid ""
+"<span size=\"small\">Enables the use of SSH for the connection.  This has a "
+"small performance impact, but is more secure and required when using NAT or "
+"port-based firewalls</span>"
+msgstr ""
+"<span size=\"small\">Active l'utilisation de SSH pour la connexion.  Ceci a "
+"un leger impact négatif sur les performances, mais améliore la sécurité et "
+"est parfois nécéssaire en cas d'utilisation d'un systeme NAT ou d'un "
+"firewall régi par ports</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:149
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:135
 msgid "SSH _Host:"
 msgstr "SSH _Hôte:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:160
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:146
 msgid "<span size=\"small\">DNS or IP address and port of the SSH server</span>"
 msgstr "<span size=\"small\">Adresse IP ou DNS et port du serveur SSH</span>"
 
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:159
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:173
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:187
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:146
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:129
 msgid "_Port:"
 msgstr "_Port"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:200
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:186
 msgid "<span size=\"small\">DNS or IP address and port of the Smuxi server</span>"
 msgstr "<span size=\"small\">Adresse IP ou DNS et port du serveur Smuxi</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:213
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:199
 msgid "_Smuxi Host:"
 msgstr "_Smuxi Hôte:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:68
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:52
 msgid "_SSH Username: (optional)"
 msgstr "Nom d'utilisateur _SSH (optionnel) :"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:91
-msgid "<span size=\"small\">Username which will be used to log into the SSH server</span>"
-msgstr "<span size=\"small\">Nom d'utilisateur qui sera utilisé pour l'enregistrement auprès du moteur Smuxi</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:75
+msgid ""
+"<span size=\"small\">Username which will be used to log into the SSH "
+"server</span>"
+msgstr ""
+"<span size=\"small\">Nom d'utilisateur qui sera utilisé pour "
+"l'enregistrement auprès du moteur Smuxi</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:111
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:95
 msgid "_SSH Password: (optional)"
 msgstr "Mot de passe _SSH (optionnel) :"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:135
-msgid "<span size=\"small\">Password which will be used to log into the SSH server. The password is optional if SSH key authorization is used (via Pageant from the PuTTY tools).</span>"
-msgstr "<span size=\"small\">Mot de passe utilisé pour la connexion au serveur SSH. Le mot de passe est optionnel si un mécanisme d'autorisation par clé SSH est utilisé (via Pageant de la suite d'outils PuTTY).</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:119
+msgid ""
+"<span size=\"small\">Password which will be used to log into the SSH server."
+" The password is optional if SSH key authorization is used (see "
+"below).</span>"
+msgstr ""
+"<span size=\"small\">Le mot de passe qui sera utilisé pour la connexion au "
+"serveur SSH. Le mot de passe est optionnel si l'authentification par fichier"
+" de clé SSH est activé (voir ci-dessous)</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:140
+msgid "_SSH Keyfile: (optional)"
+msgstr "Fichier de clé_SSH : (optionnel)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:156
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:215
+#. Container child vbox17.Gtk.Box+BoxChild
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:148
+msgid "Select a File"
+msgstr "Choisissez un fichier"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:161
+msgid ""
+"<span size=\"small\">SSH private keyfile which will be used to log into the "
+"SSH server</span>"
+msgstr ""
+"<span size=\"small\">Le fichier de clé SSH sera utilisé pour "
+"l'authentification sur le serveur SSH</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:181
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:188
 msgid "_Username:"
 msgstr "_Nom d'utilisateur :"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:179
-msgid "<span size=\"small\">Username which will be used to log into the Smuxi server</span>"
-msgstr "<span size=\"small\">Nom d'utilisateur qui sera utilisé pour l'enregistrement auprès du moteur Smuxi</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:204
+msgid ""
+"<span size=\"small\">Username which will be used to log into the Smuxi "
+"server</span>"
+msgstr ""
+"<span size=\"small\">Nom d'utilisateur qui sera utilisé pour "
+"l'enregistrement auprès du moteur Smuxi</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:199
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:225
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:224
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:87
 msgid "_Password:"
 msgstr "Mot de _passe :"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:223
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:248
 msgid "<span size=\"small\">Password of the user</span>"
 msgstr "<span size=\"small\">Mot de passe de l'utilisateur</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:243
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:268
 msgid "_Verify Password:"
 msgstr "_Vérification du mot de passe :"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:267
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:292
 msgid "<span size=\"small\">Repeat the password for verification</span>"
 msgstr "<span size=\"small\">Retapez le mot de passe pour vérification</span>"
 
@@ -957,46 +1101,58 @@ msgstr ""
 "\n"
 "Cliquez sur \"Suivant\" pour commencer."
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:44
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:36
 msgid "_Engine Name:"
 msgstr "Nom du _moteur :"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:59
 msgid "<span size=\"small\">Profile name of the new engine</span>"
 msgstr "<span size=\"small\">Nom du profil pour l'entrée du nouveau moteur</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:88
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:80
 msgid "_Default Engine:"
 msgstr "Moteur par _défaut :"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:99
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:91
 msgid "Use as new default engine"
 msgstr "Utiliser comme moteur par défaut"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:112
-msgid "<span size=\"small\">If enabled, the current engine will be the default next time Smuxi is started</span>"
-msgstr "<span size=\"small\">Activé, cette fonctionnalité rend le moteur courant par défaut au prochain démarrage de Smuxi</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:104
+msgid ""
+"<span size=\"small\">If enabled, the current engine will be the default next"
+" time Smuxi is started</span>"
+msgstr ""
+"<span size=\"small\">Activé, cette fonctionnalité rend le moteur courant par"
+" défaut au prochain démarrage de Smuxi</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:26
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:20
 msgid "Smuxi - Open Chat"
 msgstr "Smuxi - Ouvrir un chat"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:69
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:63
 msgid "_Type:"
 msgstr "_Type :"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:87
-msgid "_Network:"
-msgstr "_Réseau :"
-
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:205
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:54
 msgid "_Hostname:"
 msgstr "_Nom d'hôte :"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:235
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:75
+msgid "_Network:"
+msgstr "_Réseau :"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:198
 msgid "_Protocol:"
 msgstr "_Protocole :"
 
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:222
+msgid "Use Encryption"
+msgstr "Utiliser le chiffrement"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:234
+msgid "Validate Server Certificate"
+msgstr "Valider le certificat du serveur"
+
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:254
 msgid "_On Connect Commands:"
 msgstr "Commandes de _connexion :"
@@ -1005,107 +1161,4 @@ msgstr "Commandes de _connexion :"
 msgid "_Ignore Commands"
 msgstr "_Ignorer les commandes"
 
-#~ msgid "_Edit"
-#~ msgstr "_Edition"
-
-#~ msgid "German"
-#~ msgstr "Allemand"
-
-#~ msgid "Spanish"
-#~ msgstr "Espagnol"
-
-#~ msgid "British English"
-#~ msgstr "Anglais (Grande-Bretagne)"
-
-#~ msgid "French"
-#~ msgstr "Français"
-
-#~ msgid "Italian"
-#~ msgstr "Italien"
-
-#~ msgid "Joins"
-#~ msgstr "Joins"
-
-#~ msgid "Parts"
-#~ msgstr "Parts"
-
-#~ msgid "Quits"
-#~ msgstr "Quits"
-
-#~ msgid "Unknown Command: {0}"
-#~ msgstr "Commande inconnue : {0}"
-
-#~ msgid "gtk-cancel"
-#~ msgstr "gtk-cancel"
-
-#~ msgid "gtk-ok"
-#~ msgstr "gtk-ok"
-
-#~ msgid "#"
-#~ msgstr "#"
-
-#~ msgid "Syncing chat persons of {0}..."
-#~ msgstr "Synchronisation des utilisateurs de la discussion {0}..."
-
-#~ msgid "localhost"
-#~ msgstr "localhost"
-
-#~ msgid "smuxi - Preferences"
-#~ msgstr "smuxi - Preferences"
-
-#~ msgid "Smuxi's first start"
-#~ msgstr "Premier démarrage de Smuxi"
-
-#~ msgid ""
-#~ "Welcome to the smuxi\n"
-#~ "You started smuxi for the first time and it needs some answers from you.\n"
-#~ "\n"
-#~ "Click \"Forward\" to begin."
-#~ msgstr ""
-#~ "Bienvenue sur Smuxi\n"
-#~ "Vous utilisez Smuxi pour la première fois et l'application a besoin de certaines réponses de votre part.\n"
-#~ "\n"
-#~ "Cliquez sur \"Suivant\" pour commencer."
-
-#~ msgid "Local"
-#~ msgstr "Local"
-
-#~ msgid "Remote"
-#~ msgstr "Distant"
-
-#~ msgid "When smuxi is started which mode it should use by default"
-#~ msgstr "Mode par défaut devant être utilisé quand Smuxi démarre"
-
-#~ msgid "Now you can use smuxi"
-#~ msgstr "Maintenant, vous pouvez commencer à utiliser Smuxi"
-
-#~ msgid "First Start Druid"
-#~ msgstr "Lancer d'abord Druid"
-
-#~ msgid "DNS or IP address of the smuxi engine"
-#~ msgstr "DNS ou adresse IP du moteur Smuxi"
-
-#~ msgid "TCP port of the smuxi engine"
-#~ msgstr "Port TCP du moteur Smuxi"
-
-#~ msgid "_Channel:"
-#~ msgstr "_Canal :"
-
-#~ msgid ""
-#~ ".NET Remoting Channel which will be used for communication\n"
-#~ "between the frontend and the engine"
-#~ msgstr ""
-#~ "Canal de contrôle .NET qui sera utilisé pour la communication\n"
-#~ "entre l'interface et le moteur"
-
-#~ msgid "_Formatter:"
-#~ msgstr "_Formateur :"
-
-#~ msgid ".NET Remoting Data Formatter"
-#~ msgstr "Moteur de formatage de données du canal de contrôle .NET"
-
-#~ msgid "Opening URL ({0}) failed."
-#~ msgstr "Ouverture de l'URL {0} impossible."
 
-#~ msgid "Tray"
-#~ msgstr "Barre des tâches"
diff --git a/po-Frontend-GNOME/it.po b/po-Frontend-GNOME/it.po
index 9a94136..376e8a9 100644
--- a/po-Frontend-GNOME/it.po
+++ b/po-Frontend-GNOME/it.po
@@ -8,8 +8,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: smuxi-frontend-gnome\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:35+0200\n"
-"PO-Revision-Date: 2010-07-15 13:26+0200\n"
+"POT-Creation-Date: 2010-09-11 11:52+0200\n"
+"PO-Revision-Date: 2010-09-11 09:50+0200\n"
 "Last-Translator: Vincenzo Campanella <vinz65 at gmail.com>\n"
 "Language-Team: Italian <tp at lists.linux.it>\n"
 "Language: it\n"
@@ -27,7 +27,7 @@ msgid "<b> Color </b>"
 msgstr "<b> Colore </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:3
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1372
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1364
 msgid "<b> Entry Field </b>"
 msgstr "<b> Campo d'inserimento </b>"
 
@@ -36,7 +36,7 @@ msgid "<b> Font </b>"
 msgstr "<b> Carattere </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:5
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1702
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1694
 msgid "<b> Highlighting </b>"
 msgstr "<b> Evidenziazione </b>"
 
@@ -49,272 +49,308 @@ msgid "<b> Person List Position </b>"
 msgstr "<b> Posizione dell'elenco persone </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:8
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1209
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1201
 msgid "<b> Tab Colors </b>"
 msgstr "<b> Colori delle schede </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:9
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1110
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1102
 msgid "<b> Tabs Position </b>"
 msgstr "<b> Posizione delle schede </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:10
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1515
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1507
 msgid "<b> Topic Position </b>"
 msgstr "<b> Posizione dell'argomento </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:11
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1161
+msgid "<b>General</b>"
+msgstr "<b>Generale</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:12
+msgid "<b>Global Commands</b>"
+msgstr "<b>Comandi globali</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:13
+msgid "<b>Messaging Menu</b>"
+msgstr "<b>Menu dei messaggi</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:14
+msgid "<b>Network Proxy</b>"
+msgstr "<b>Proxy di rete</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:15
+msgid "<b>Notification Popups</b>"
+msgstr "<b> Finestre a comparsa di notifica </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:16
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1153
 msgid "Activity"
 msgstr "Attività"
 
 #
-#: ../glade/smuxi-frontend-gnome.glade.h:12
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:107
+#: ../glade/smuxi-frontend-gnome.glade.h:17
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:235
 msgid "Automatically connect to server at startup"
 msgstr "Connessione automatica al server all'avvio"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:13
+#: ../glade/smuxi-frontend-gnome.glade.h:18
 msgid "Background"
 msgstr "Sfondo"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:14
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1360
+#: ../glade/smuxi-frontend-gnome.glade.h:19
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1352
 msgid "Bash-Style Completion"
 msgstr "Completamento in stile bash"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:15
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1690
+#: ../glade/smuxi-frontend-gnome.glade.h:20
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1682
 msgid "Beep on highlight"
 msgstr "Avviso acustico sull'evidenziazione"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:16
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:980
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1002
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1461
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1486
+#: ../glade/smuxi-frontend-gnome.glade.h:21
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:972
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:994
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1453
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1478
 msgid "Bottom"
 msgstr "Giù"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:17
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:746
+#: ../glade/smuxi-frontend-gnome.glade.h:22
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:738
 msgid "Buffer Lines:"
 msgstr "Righe di buffer:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:18
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:671
+#: ../glade/smuxi-frontend-gnome.glade.h:23
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:663
 msgid "C_onnection"
 msgstr "C_onnessione"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:19
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1312
+#: ../glade/smuxi-frontend-gnome.glade.h:24
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1304
 msgid "Command Character:"
 msgstr "Carattere di comando:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:20
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1335
+#: ../glade/smuxi-frontend-gnome.glade.h:25
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1327
 msgid "Command History Size:"
 msgstr "Dimensione della cronologia dei comandi:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:21
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1292
+#: ../glade/smuxi-frontend-gnome.glade.h:26
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1284
 msgid "Completion Character:"
 msgstr "Carattere di completamento:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:22
+#: ../glade/smuxi-frontend-gnome.glade.h:27
 msgid "Enable"
 msgstr "Abilita"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:23
+#: ../glade/smuxi-frontend-gnome.glade.h:28
 msgid "Enabled"
 msgstr "Abilitato"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:24
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:559
+#: ../glade/smuxi-frontend-gnome.glade.h:29
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:551
 msgid "Encoding:"
 msgstr "Codifica:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:25
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:769
+#: ../glade/smuxi-frontend-gnome.glade.h:30
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:761
 msgid "Engine Buffer Lines:"
 msgstr "Righe di buffer del motore:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:26
+#: ../glade/smuxi-frontend-gnome.glade.h:31
 msgid "Foreground"
 msgstr "In primo piano"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:27
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:925
+#: ../glade/smuxi-frontend-gnome.glade.h:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:917
 msgid "General"
 msgstr "Generale"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:28
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
+#: ../glade/smuxi-frontend-gnome.glade.h:33
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1173
 msgid "Highlight"
 msgstr "Evidenziazione"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:29
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1666
+#: ../glade/smuxi-frontend-gnome.glade.h:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1658
 msgid "Highlight words:"
 msgstr "Evidenzia parole:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:30
+#: ../glade/smuxi-frontend-gnome.glade.h:35
+msgid "Host:"
+msgstr "Host:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:36
 msgid "Hostname:"
 msgstr "Nome dell'host:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:31
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1381
+#: ../glade/smuxi-frontend-gnome.glade.h:37
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1373
 msgid "Input"
 msgstr "Input"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:32
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1171
+#: ../glade/smuxi-frontend-gnome.glade.h:38
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1163
 msgid "Join/Part/Mode"
 msgstr "Entra/Esci/Modo"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:33
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1016
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1041
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1535
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1561
+#: ../glade/smuxi-frontend-gnome.glade.h:39
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1008
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1033
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1527
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1553
 msgid "Left"
 msgstr "Sinistra"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:34
+#: ../glade/smuxi-frontend-gnome.glade.h:40
 msgid "Log Filtered Messages"
 msgstr "Messaggi di registro filtrati"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:35
+#: ../glade/smuxi-frontend-gnome.glade.h:41
 msgid "Network:"
 msgstr "Rete:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:36
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1402
+#: ../glade/smuxi-frontend-gnome.glade.h:42
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1394
 msgid "Nick Colors"
 msgstr "Colori dei soprannomi"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:37
+#: ../glade/smuxi-frontend-gnome.glade.h:43
 msgid "Nickname(s):"
 msgstr "Soprannomi:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:38
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1153
+#: ../glade/smuxi-frontend-gnome.glade.h:44
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1145
 msgid "No Activity"
 msgstr "Nessuna attività"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:39
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1096
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1501
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1616
+#: ../glade/smuxi-frontend-gnome.glade.h:45
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1088
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1493
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1608
 msgid "None"
 msgstr "Nessuna"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:40
+#: ../glade/smuxi-frontend-gnome.glade.h:46
 msgid "Notification"
 msgstr "Notifica"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:41
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:581
+#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:573
 msgid "On Connect Commands:"
 msgstr "Comandi alla connessione:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:42
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:627
+#: ../glade/smuxi-frontend-gnome.glade.h:48
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:619
 msgid "On Startup Commands:"
 msgstr "Comandi all'avvio:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:43
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1714
+#: ../glade/smuxi-frontend-gnome.glade.h:49
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1706
 msgid "Output"
 msgstr "Output"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:44
+#: ../glade/smuxi-frontend-gnome.glade.h:50
 msgid "Override"
 msgstr "Sovrascrivi"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:45
+#: ../glade/smuxi-frontend-gnome.glade.h:51
 msgid "Password:"
 msgstr "Password:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:46
+#: ../glade/smuxi-frontend-gnome.glade.h:52
 msgid "Port:"
 msgstr "Porta:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../glade/smuxi-frontend-gnome.glade.h:53
 msgid "Protocol:"
 msgstr "Protocollo:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:48
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:538
+#: ../glade/smuxi-frontend-gnome.glade.h:54
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:530
 msgid "Realname:"
 msgstr "Nome reale:"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:49
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1056
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1081
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1576
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1601
+#: ../glade/smuxi-frontend-gnome.glade.h:55
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1048
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1073
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1568
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1593
 msgid "Right"
 msgstr "Destra"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:50
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:195
+#: ../glade/smuxi-frontend-gnome.glade.h:56
+msgid "Show Advanced Settings"
+msgstr "Mostra impostazioni avanzate"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:57
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:196
 msgid "Show Password"
 msgstr "Mostra la password"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:51
+#: ../glade/smuxi-frontend-gnome.glade.h:58
+msgid "Show Smuxi in the messaging menu"
+msgstr "Mostra Smuxi nel menù dei messaggi"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:59
 msgid "Show always"
 msgstr "Mostra sempre"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:52
+#: ../glade/smuxi-frontend-gnome.glade.h:60
+msgid "Show notification popups"
+msgstr "Mostra finestre a comparsa di notifica"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:61
 msgid "Show when window is closed"
 msgstr "Mostra quando la finestra viene chiusa"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:53
+#: ../glade/smuxi-frontend-gnome.glade.h:62
 msgid "Show when window is minimized"
 msgstr "Mostra quando la finestra viene minimizzata"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:54
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:406
+#: ../glade/smuxi-frontend-gnome.glade.h:63
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:398
 msgid "Smuxi - Preferences"
 msgstr "Preferenze di Smuxi"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:55
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:26
+#: ../glade/smuxi-frontend-gnome.glade.h:64
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:18
 msgid "Smuxi - Server"
 msgstr "Server di Smuxi"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:56
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:828
+#: ../glade/smuxi-frontend-gnome.glade.h:65
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:820
 msgid "Strip Colors"
 msgstr "Rimuovi i colori"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:57
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:867
+#: ../glade/smuxi-frontend-gnome.glade.h:66
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:859
 msgid "Strip Formattings"
 msgstr "Rimuovi le formattazioni"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:58
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:907
+#: ../glade/smuxi-frontend-gnome.glade.h:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:899
 msgid "Strip UTF-8"
 msgstr "Rimuovi UTF-8"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:59
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1222
+#: ../glade/smuxi-frontend-gnome.glade.h:68
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1214
 msgid "Tabs"
 msgstr "Schede"
 
 #
-#: ../glade/smuxi-frontend-gnome.glade.h:60
+#: ../glade/smuxi-frontend-gnome.glade.h:69
 msgid ""
 "The nickname to use. You can specify extra nicknames (separated by spaces) "
 "which will be used as fallbacks when the first choice is not available. By "
@@ -325,52 +361,56 @@ msgstr ""
 "non sia disponibile. In modo predefinito verrà usato $nick_, mentre $nick__ "
 "viene usato come alternativa."
 
-#: ../glade/smuxi-frontend-gnome.glade.h:61
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:726
+#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:718
 msgid "Timestamp Format:"
 msgstr "Formato dell'ora:"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:62
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:943
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:967
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1420
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1446
+#: ../glade/smuxi-frontend-gnome.glade.h:71
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:935
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:959
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1412
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1438
 msgid "Top"
 msgstr "Su"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:63
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:515
+#: ../glade/smuxi-frontend-gnome.glade.h:72
+msgid "Type:"
+msgstr "Tipo:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:73
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:507
 msgid "Username:"
 msgstr "Nome utente:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:64
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1881
+#: ../glade/smuxi-frontend-gnome.glade.h:74
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1873
 msgid "_Filters"
 msgstr "_Filtri"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:65
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1723
+#: ../glade/smuxi-frontend-gnome.glade.h:75
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1715
 msgid "_Interface"
 msgstr "_Interfaccia"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:66
+#: ../glade/smuxi-frontend-gnome.glade.h:76
 msgid "_Logging"
 msgstr "_Registro"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:67
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1789
+#: ../glade/smuxi-frontend-gnome.glade.h:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1781
 msgid "_Servers"
 msgstr "_Server"
 
 #. This is a setting for character based line wrapping vs word based when showing messages
-#: ../glade/smuxi-frontend-gnome.glade.h:69
+#: ../glade/smuxi-frontend-gnome.glade.h:79
 msgid "_Wrap Mode:"
 msgstr "_Modalità a capo automatico:"
 
 #
-#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../glade/smuxi-frontend-gnome.glade.h:80
 msgid ""
 "ss = seconds\n"
 "mm = minutes\n"
@@ -392,31 +432,26 @@ msgstr ""
 "MM = mese\n"
 "yy/yyyy = anno"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:52
-msgid "translator-credits"
-msgstr "David Paleino <d.paleino at gmail.com>\nVincenzo Campanella <vinz65 at gmail.com>"
-
-#: ../src/Frontend-GNOME/AboutDialog.cs:47
-msgid "German"
-msgstr "Tedesco"
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:1
+msgid "Chat with other people on IRC"
+msgstr "Chiacchiera con altre persone su IRC"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:48
-msgid "Spanish"
-msgstr "Spagnolo"
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:2
+msgid "IRC Chat"
+msgstr "Chat IRC"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:49
-msgid "British English"
-msgstr "Inglese britannico"
-
-#: ../src/Frontend-GNOME/AboutDialog.cs:50
-msgid "French"
-msgstr "Francese"
+#
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:3
+msgid "Smuxi IRC Client"
+msgstr "Client di IRC Smuxi"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:51
-msgid "Italian"
-msgstr "Italiano"
+#: ../src/Frontend-GNOME/AboutDialog.cs:58
+msgid "translator-credits"
+msgstr ""
+"David Paleino <d.paleino at gmail.com>\n"
+"Vincenzo Campanella <vinz65 at gmail.com>"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:54
+#: ../src/Frontend-GNOME/AboutDialog.cs:61
 msgid "Smuxi Website"
 msgstr "Sito web di Smuxi"
 
@@ -444,56 +479,52 @@ msgstr "Gestore del motore"
 msgid "_Connect"
 msgstr "_Connetti"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:78
-msgid "_Edit"
-msgstr "_Modifica"
-
 #
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:90
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:84
 msgid "Select which Smuxi engine you want to connect to"
 msgstr "Selezionare il motore Smuxi a cui connettersi"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:96
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:90
 msgid "Engine:"
 msgstr "Motore:"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:122
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:182
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:359
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:116
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:176
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:353
 msgid "Local Engine"
 msgstr "Motore locale"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:174
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:168
 msgid "Please select an engine!"
 msgstr "Scegliere un motore."
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:195
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:189
 #, csharp-format
 msgid "Your frontend version ({0}) does not match the engine version ({1})!"
 msgstr ""
 "La versione dell'interfaccia in uso ({0}) non corrisponde a quella del "
 "motore ({1})."
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:222
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:216
 msgid "An error occurred while connecting to the engine!"
 msgstr "Errore durante la connessione al motore."
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:223
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:217
 #, csharp-format
 msgid "Engine URL: {0}"
 msgstr "URL del motore: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:226
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:220
 #, csharp-format
 msgid "Error: {0}"
 msgstr "Errore: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:296
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:290
 #, csharp-format
 msgid "Are you sure you want to delete the engine \"{0}\"?"
 msgstr "Si è sicuri di voler eliminare il motore «{0}»?"
 
-#: ../src/Frontend-GNOME/Entry.cs:403
+#: ../src/Frontend-GNOME/Entry.cs:421
 #, csharp-format
 msgid "You are going to paste {0} lines. Do you want to continue?"
 msgstr "Si stanno per incollare {0} righe. Continuare?"
@@ -501,89 +532,102 @@ msgstr "Si stanno per incollare {0} righe. Continuare?"
 #
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Frontend-GNOME/Entry.cs:506
+#: ../src/Frontend-GNOME/Entry.cs:524
 msgid "Frontend Commands"
 msgstr "Comandi dell'interfaccia"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:186
+#: ../src/Frontend-GNOME/MainWindow.cs:222
 msgid "_File"
 msgstr "_File"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:202
+#: ../src/Frontend-GNOME/MainWindow.cs:238
 msgid "_Server"
 msgstr "_Server"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:206
+#: ../src/Frontend-GNOME/MainWindow.cs:242
 msgid "_Quick Connect"
 msgstr "C_onnessione Rapida"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:217
+#: ../src/Frontend-GNOME/MainWindow.cs:253
 msgid "_Manage"
 msgstr "_Gestisci"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:224
+#: ../src/Frontend-GNOME/MainWindow.cs:260
 msgid "_Chat"
 msgstr "_Chat"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:228
+#: ../src/Frontend-GNOME/MainWindow.cs:264
 msgid "Open / Join Chat"
 msgstr "Apri / Partecipa alla chat"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:233
+#: ../src/Frontend-GNOME/MainWindow.cs:269
 msgid "_Find Group Chat"
-msgstr "_Trova il gruppo chat"
+msgstr "_Trova chat di gruppo"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:238
+#: ../src/Frontend-GNOME/MainWindow.cs:274
 msgid "C_lear All Activity"
 msgstr "Cance_lla tutte le attività"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:245
+#: ../src/Frontend-GNOME/MainWindow.cs:281
 msgid "_Next Chat"
 msgstr "Chat segue_nte"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:255
+#: ../src/Frontend-GNOME/MainWindow.cs:291
 msgid "_Previous Chat"
 msgstr "Chat p_recedente"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:307
+#: ../src/Frontend-GNOME/MainWindow.cs:341
+msgid "Open Log"
+msgstr "Apri il registro"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:355
 msgid "_Engine"
 msgstr "_Motore"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:311
+#: ../src/Frontend-GNOME/MainWindow.cs:359
 msgid "_Use Local Engine"
 msgstr "_Utilizza il motore locale"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:317
+#: ../src/Frontend-GNOME/MainWindow.cs:365
 msgid "_Add Remote Engine"
 msgstr "_Aggiungi motore remoto"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:322
+#: ../src/Frontend-GNOME/MainWindow.cs:370
 msgid "_Switch Remote Engine"
 msgstr "_Cambia motore remoto"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:329
+#: ../src/Frontend-GNOME/MainWindow.cs:377
 msgid "_View"
 msgstr "_Visualizza"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:333
+#: ../src/Frontend-GNOME/MainWindow.cs:381
 msgid "_Caret Mode"
-msgstr "_Modalità cursore"
+msgstr "Modalità _cursore"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:343
+#: ../src/Frontend-GNOME/MainWindow.cs:389
+msgid "_Browse Mode"
+msgstr "Modalità di _navigazione"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:403
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:586
+msgid "Show _Menubar"
+msgstr "Mostra la barra del _menù"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:430
 msgid "_Help"
 msgstr "A_iuto"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:567
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:222
+#: ../src/Frontend-GNOME/MainWindow.cs:691
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:225
 msgid "Unable to add server: "
 msgstr "Impossibile aggiungere il server: "
 
-#: ../src/Frontend-GNOME/MainWindow.cs:614
+#: ../src/Frontend-GNOME/MainWindow.cs:742
 #, csharp-format
 msgid "Unknown ChatType: {0}"
 msgstr "Tipo di chat sconosciuto: {0}"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:822
+#: ../src/Frontend-GNOME/MainWindow.cs:971
 msgid ""
 "Switching to local engine will disconnect you from the current engine!\n"
 "Are you sure you want to do this?"
@@ -592,7 +636,7 @@ msgstr ""
 "attuale.\n"
 "Si è sicuri di volerlo fare?"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:864
+#: ../src/Frontend-GNOME/MainWindow.cs:1013
 msgid ""
 "Switching the remote engine will disconnect you from the current engine!\n"
 "Are you sure you want to do this?"
@@ -606,47 +650,52 @@ msgid "Sorry, not implemented yet!"
 msgstr "Spiacente, non ancora implementato."
 
 #. fill ListStore
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:162
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:179
 msgid "Character"
 msgstr "Carattere"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:163
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:180
 msgid "Word"
 msgstr "Parola"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:173
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:198
+msgid "No Proxy"
+msgstr "Nessun proxy"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:212
 #: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:139
 msgid "Connection"
 msgstr "Connessione"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:177
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:216
 msgid "Interface"
 msgstr "Interfaccia"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:181
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:220
 msgid "Servers"
 msgstr "Server"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:185
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:227
 msgid "Filters"
 msgstr "Filtri"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:189
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:231
 msgid "Logging"
 msgstr "Registri"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:238
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:281
 msgid "System Default"
 msgstr "Predefinito dal sistema"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:505
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:588
 msgid "Nicknames(s) field must not be empty."
 msgstr "Il campo soprannomi non deve essere vuoto."
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:649
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:748
 #, csharp-format
 msgid "Invalid highlight regex: '{0}'. Reason: {1}"
-msgstr "Espressione regolare di evidenziazione non valida: «{0}». Motivo: «{1}»."
+msgstr ""
+"Espressione regolare di evidenziazione non valida: «{0}». Motivo: «{1}»."
 
 #: ../src/Frontend-GNOME/FindGroupChatDialog.cs:69
 #: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:105
@@ -670,15 +719,16 @@ msgstr ""
 
 #: ../src/Frontend-GNOME/FindGroupChatDialog.cs:143
 msgid "Error while fetching the list of group chats from the server."
-msgstr "Errore durante il recupero dell'elenco dei gruppi di chat dal server."
+msgstr ""
+"Errore durante il recupero dell'elenco delle chat di gruppo dal server."
 
-#: ../src/Frontend-GNOME/Frontend.cs:394
+#: ../src/Frontend-GNOME/Frontend.cs:399
 #, csharp-format
 msgid "Cause: {0}"
 msgstr "Causa: {0}"
 
 #
-#: ../src/Frontend-GNOME/Frontend.cs:464
+#: ../src/Frontend-GNOME/Frontend.cs:469
 msgid ""
 "The frontend has lost the connection to the server.\n"
 "Do you want to reconnect now?"
@@ -687,7 +737,7 @@ msgstr ""
 "Riconnettersi ora?"
 
 #
-#: ../src/Frontend-GNOME/Frontend.cs:479
+#: ../src/Frontend-GNOME/Frontend.cs:484
 msgid ""
 "Reconnecting to the server has failed.\n"
 "Do you want to try again?"
@@ -696,7 +746,7 @@ msgstr ""
 "Riprovare?"
 
 #
-#: ../src/Frontend-GNOME/Frontend.cs:580
+#: ../src/Frontend-GNOME/Frontend.cs:585
 msgid ""
 "The server has lost the connection to the frontend.\n"
 "Do you want to reconnect now?"
@@ -704,6 +754,10 @@ msgstr ""
 "Il server ha perso la connessione all'interfaccia.\n"
 "Riconnettersi ora?"
 
+#: ../src/Frontend-GNOME/NotifyManager.cs:229
+msgid "Show"
+msgstr "Mostra"
+
 #: ../src/Frontend-GNOME/QuickConnectDialog.cs:62
 #: ../src/Frontend-GNOME/Views/FilterListWidget.cs:238
 #: ../src/Frontend-GNOME/Preferences/ServerListView.cs:70
@@ -759,7 +813,7 @@ msgid ""
 "An engine with this name already exists! Please specify a different one."
 msgstr "Un motore con questo nome esiste già. Specificarne un altro."
 
-#: ../src/Frontend-GNOME/Views/MessageTextView.cs:182
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:198
 #, csharp-format
 msgid "Day changed to {0}"
 msgstr "Giorno modificato in {0}"
@@ -798,18 +852,18 @@ msgstr "Tipo"
 msgid "Pattern"
 msgstr "Modello"
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:241
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:242
 #, csharp-format
 msgid "Retrieving user list for {0}..."
 msgstr "Recupero dell'elenco degli utenti per {0} in corso"
 
 #
 #. TRANSLATOR: this string will be appended to the one above
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:286
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:289
 msgid "done."
 msgstr "eseguito."
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:301
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:304
 msgid "Person"
 msgstr "Persona"
 
@@ -822,77 +876,77 @@ msgstr ""
 "essa collegate.\n"
 "Si è sicuri di volerlo fare?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:184
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:187
 msgid "Are you sure you want to delete the selected server?"
 msgstr "Si è sicuri di voler eliminare il server selezionato?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:240
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:274
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:243
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:277
 msgid "Unable to edit server: "
 msgstr "Impossibile modificare il server: "
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:42
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:34
 msgid "Find"
 msgstr "Trova"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:62
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:54
 msgid "_Search for:"
 msgstr "_Cerca:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:91
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:83
 msgid "_Match Case"
 msgstr "_Distingui le maiuscole"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:103
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:95
 msgid "Search _Backwards"
 msgstr "Cerca all'_indietro"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:115
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:107
 msgid "_Wrap Around"
 msgstr "_A capo automatico"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:128
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:120
 msgid "Use _Regular Expressions"
 msgstr "Usa le espressioni _regolari"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:40
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:32
 msgid "Smuxi - Find Group Chat"
 msgstr "Smuxi - Trova chat di gruppo"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:64
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:87
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:56
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:79
 msgid "_Name:"
 msgstr "_Nome:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:24
 msgid "Smuxi - Quick Connect"
 msgstr "Smuxi - Connessione rapida"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:495
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:487
 msgid "Nicknames:"
 msgstr "Soprannomi:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1630
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1622
 msgid "<b> User List Position </b>"
 msgstr "<b> Posizione dell'elenco degli utenti </b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1641
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1633
 msgid "<b> Channel </b>"
 msgstr "<b> Canale </b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1852
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1844
 msgid "<b>Channel Filters</b>"
 msgstr "<b>Filtri del canale</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1869
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1861
 msgid "<b>User Filters</b>"
 msgstr "<b>Filtri dell'utente</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:64
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:56
 msgid "Use _SSH Tunnel"
 msgstr "Usa tunnel _SSH"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:78
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:70
 msgid ""
 "<span size=\"small\">Enables the use of SSH for the connection.  This has a "
 "small performance impact, but is more secure and required when using NAT or "
@@ -902,36 +956,36 @@ msgstr ""
 "impatto ridotto sulle prestazioni, ma è più sicuro ed è richiesto quando si "
 "usa NAT o firewall basati sulle porte</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:157
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:149
 msgid "SSH _Host:"
 msgstr "_Host SSH:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:168
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:160
 msgid ""
 "<span size=\"small\">DNS or IP address and port of the SSH server</span>"
 msgstr "<span size=\"small\">DNS o indirizzo IP e porta del server SSH</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:181
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:195
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:154
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:173
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:187
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:155
 msgid "_Port:"
 msgstr "_Porta:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:208
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:200
 msgid ""
 "<span size=\"small\">DNS or IP address and port of the Smuxi server</span>"
 msgstr ""
 "<span size=\"small\">DNS o indirizzo IP e porta del server Smuxi</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:221
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:213
 msgid "_Smuxi Host:"
 msgstr "Host _Smuxi:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:76
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:68
 msgid "_SSH Username: (optional)"
 msgstr "Nome utente _SSH: (facoltativo)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:99
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:91
 msgid ""
 "<span size=\"small\">Username which will be used to log into the SSH server</"
 "span>"
@@ -939,11 +993,11 @@ msgstr ""
 "<span size=\"small\">Nome utente che verrà utilizzato per accedere al server "
 "SSH</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:119
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:111
 msgid "_SSH Password: (optional)"
 msgstr "Password _SSH: (facoltativa)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:143
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:135
 msgid ""
 "<span size=\"small\">Password which will be used to log into the SSH server. "
 "The password is optional if SSH key authorization is used (via Pageant from "
@@ -953,12 +1007,12 @@ msgstr ""
 "SSH. La password è facoltativa se viene utilizzata una chiave di "
 "autorizzazione SSH (tramite Pageant dagli strumenti di PuTTY).</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:164
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:223
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:156
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:214
 msgid "_Username:"
 msgstr "Nome _utente:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:187
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:179
 msgid ""
 "<span size=\"small\">Username which will be used to log into the Smuxi "
 "server</span>"
@@ -966,25 +1020,25 @@ msgstr ""
 "<span size=\"small\">Nome utente che verrà utilizzato per accedere al server "
 "Smuxi</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:207
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:233
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:199
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:113
 msgid "_Password:"
 msgstr "_Password:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:231
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:223
 msgid "<span size=\"small\">Password of the user</span>"
 msgstr "<span size=\"small\"Password dell'utente</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:251
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:243
 msgid "_Verify Password:"
 msgstr "_Verifica password:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:275
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:267
 msgid "<span size=\"small\">Repeat the password for verification</span>"
-msgstr "<span size=\"small\"Ripetere la password per la verifica</span>"
+msgstr "<span size=\"small\">Ripetere la password per la verifica</span>"
 
 #
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs:27
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs:19
 msgid ""
 "Welcome to the Smuxi Engine Configuration Assistant.\n"
 "You need to enter some information before you can use the engine.\n"
@@ -997,26 +1051,26 @@ msgstr ""
 "\n"
 "Fare clic su «Avanti» per iniziare."
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:52
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:44
 msgid "_Engine Name:"
 msgstr "_Nome del motore:"
 
 #
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:75
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:67
 msgid "<span size=\"small\">Profile name of the new engine</span>"
 msgstr "<span size=\"small\">Nome del profilo del nuovo motore</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:96
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:88
 msgid "_Default Engine:"
 msgstr "Motore _predefinito:"
 
 #
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:107
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:99
 msgid "Use as new default engine"
 msgstr "Usa come motore predefinito"
 
 #
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:120
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:112
 msgid ""
 "<span size=\"small\">If enabled, the current engine will be the default next "
 "time Smuxi is started</span>"
@@ -1025,34 +1079,60 @@ msgstr ""
 "al prossimo avvio di Smuxi</span>"
 
 #
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:26
 msgid "Smuxi - Open Chat"
 msgstr "Smuxi - Apri chat"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:69
 msgid "_Type:"
 msgstr "_Tipo:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:95
-msgid "_Network:"
-msgstr "_Rete:"
-
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:213
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:80
 msgid "_Hostname:"
 msgstr "Nome dell'_host:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:243
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:101
+msgid "_Network:"
+msgstr "_Rete:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:224
 msgid "_Protocol:"
 msgstr "_Protocollo:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:262
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:248
+msgid "Use Encryption"
+msgstr "Usa la cifratura"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:260
+msgid "Validate Server Certificate"
+msgstr "Convalida il certificato del server"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:280
 msgid "_On Connect Commands:"
 msgstr "_Comandi alla connessione:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:273
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:291
 msgid "_Ignore Commands"
 msgstr "_Ignora comandi"
 
+#~ msgid "German"
+#~ msgstr "Tedesco"
+
+#~ msgid "Spanish"
+#~ msgstr "Spagnolo"
+
+#~ msgid "British English"
+#~ msgstr "Inglese britannico"
+
+#~ msgid "French"
+#~ msgstr "Francese"
+
+#~ msgid "Italian"
+#~ msgstr "Italiano"
+
+#~ msgid "_Edit"
+#~ msgstr "_Modifica"
+
 #~ msgid "Joins"
 #~ msgstr "Ingressi"
 
diff --git a/po-Frontend-GNOME/pt.po b/po-Frontend-GNOME/pt.po
index dc11158..b0a4805 100644
--- a/po-Frontend-GNOME/pt.po
+++ b/po-Frontend-GNOME/pt.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: smuxi-frontend-gnome \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:35+0200\n"
-"PO-Revision-Date: 2010-07-15 02:31+0100\n"
+"POT-Creation-Date: 2010-09-11 11:54+0200\n"
+"PO-Revision-Date: 2010-09-08 01:51+0100\n"
 "Last-Translator: Américo Monteiro <a_monteiro at netcabo.pt>\n"
 "Language-Team: Portuguese <traduz at debianpt.org>\n"
 "Language: pt\n"
@@ -27,7 +27,7 @@ msgid "<b> Color </b>"
 msgstr "<b> Cor </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:3
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1372
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1364
 msgid "<b> Entry Field </b>"
 msgstr "<b> Campo de Entrada </b>"
 
@@ -36,7 +36,7 @@ msgid "<b> Font </b>"
 msgstr "<b> Tipo de Letra </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:5
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1702
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1694
 msgid "<b> Highlighting </b>"
 msgstr "<b> Destaque </b>"
 
@@ -49,270 +49,306 @@ msgid "<b> Person List Position </b>"
 msgstr "<b> Posição da Lista de Pessoas </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:8
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1209
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1201
 msgid "<b> Tab Colors </b>"
 msgstr "<b> Cores do Separador </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:9
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1110
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1102
 msgid "<b> Tabs Position </b>"
 msgstr "<b> Posição dos Separadores </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:10
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1515
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1507
 msgid "<b> Topic Position </b>"
 msgstr "<b> Posição do Tópico </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:11
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1161
+msgid "<b>General</b>"
+msgstr "<b>Geral</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:12
+msgid "<b>Global Commands</b>"
+msgstr "<b>Comandos Globais</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:13
+msgid "<b>Messaging Menu</b>"
+msgstr "<b>Menu de Mensageiro</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:14
+msgid "<b>Network Proxy</b>"
+msgstr "<b>Proxy de Rede</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:15
+msgid "<b>Notification Popups</b>"
+msgstr "<b>Popups de Notificação</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:16
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1153
 msgid "Activity"
 msgstr "Actividade"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:12
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:107
+#: ../glade/smuxi-frontend-gnome.glade.h:17
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:235
 msgid "Automatically connect to server at startup"
 msgstr "Ligar automaticamente ao servidor no inicio"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:13
+#: ../glade/smuxi-frontend-gnome.glade.h:18
 msgid "Background"
 msgstr "Fundo"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:14
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1360
+#: ../glade/smuxi-frontend-gnome.glade.h:19
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1352
 msgid "Bash-Style Completion"
 msgstr "Acabamento ao Estilo Bash"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:15
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1690
+#: ../glade/smuxi-frontend-gnome.glade.h:20
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1682
 msgid "Beep on highlight"
 msgstr "Apitar no destaque"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:16
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:980
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1002
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1461
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1486
+#: ../glade/smuxi-frontend-gnome.glade.h:21
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:972
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:994
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1453
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1478
 msgid "Bottom"
 msgstr "Fundo"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:17
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:746
+#: ../glade/smuxi-frontend-gnome.glade.h:22
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:738
 msgid "Buffer Lines:"
 msgstr "Linhas do Buffer:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:18
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:671
+#: ../glade/smuxi-frontend-gnome.glade.h:23
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:663
 msgid "C_onnection"
 msgstr "Ligaçã_o"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:19
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1312
+#: ../glade/smuxi-frontend-gnome.glade.h:24
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1304
 msgid "Command Character:"
 msgstr "Caractere de Comandos:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:20
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1335
+#: ../glade/smuxi-frontend-gnome.glade.h:25
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1327
 msgid "Command History Size:"
 msgstr "Tamanho do Histórico de Comandos:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:21
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1292
+#: ../glade/smuxi-frontend-gnome.glade.h:26
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1284
 msgid "Completion Character:"
 msgstr "Caractere de Acabamento:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:22
+#: ../glade/smuxi-frontend-gnome.glade.h:27
 msgid "Enable"
 msgstr "Activar"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:23
+#: ../glade/smuxi-frontend-gnome.glade.h:28
 msgid "Enabled"
 msgstr "Activo"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:24
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:559
+#: ../glade/smuxi-frontend-gnome.glade.h:29
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:551
 msgid "Encoding:"
 msgstr "Codificar:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:25
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:769
+#: ../glade/smuxi-frontend-gnome.glade.h:30
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:761
 msgid "Engine Buffer Lines:"
 msgstr "Linhas do Buffer do Motor:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:26
+#: ../glade/smuxi-frontend-gnome.glade.h:31
 msgid "Foreground"
 msgstr "Primeiro plano"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:27
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:925
+#: ../glade/smuxi-frontend-gnome.glade.h:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:917
 msgid "General"
 msgstr "Geral"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:28
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
+#: ../glade/smuxi-frontend-gnome.glade.h:33
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1173
 msgid "Highlight"
 msgstr "Destacar"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:29
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1666
+#: ../glade/smuxi-frontend-gnome.glade.h:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1658
 msgid "Highlight words:"
 msgstr "Destacar palavras:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:30
+#: ../glade/smuxi-frontend-gnome.glade.h:35
+msgid "Host:"
+msgstr "Máquina:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:36
 msgid "Hostname:"
 msgstr "Nome da máquina:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:31
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1381
+#: ../glade/smuxi-frontend-gnome.glade.h:37
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1373
 msgid "Input"
 msgstr "Entrada"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:32
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1171
+#: ../glade/smuxi-frontend-gnome.glade.h:38
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1163
 msgid "Join/Part/Mode"
 msgstr "Juntar/Parte/Modo"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:33
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1016
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1041
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1535
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1561
+#: ../glade/smuxi-frontend-gnome.glade.h:39
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1008
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1033
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1527
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1553
 msgid "Left"
 msgstr "Esquerda"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:34
+#: ../glade/smuxi-frontend-gnome.glade.h:40
 msgid "Log Filtered Messages"
 msgstr "Registar Mensagens Filtradas"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:35
+#: ../glade/smuxi-frontend-gnome.glade.h:41
 msgid "Network:"
 msgstr "Rede:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:36
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1402
+#: ../glade/smuxi-frontend-gnome.glade.h:42
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1394
 msgid "Nick Colors"
 msgstr "Cores da Alcunha"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:37
+#: ../glade/smuxi-frontend-gnome.glade.h:43
 msgid "Nickname(s):"
 msgstr "Alcunha(s):"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:38
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1153
+#: ../glade/smuxi-frontend-gnome.glade.h:44
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1145
 msgid "No Activity"
 msgstr "Nenhuma Actividade"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:39
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1096
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1501
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1616
+#: ../glade/smuxi-frontend-gnome.glade.h:45
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1088
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1493
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1608
 msgid "None"
 msgstr "Nenhum"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:40
+#: ../glade/smuxi-frontend-gnome.glade.h:46
 msgid "Notification"
 msgstr "Notificação"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:41
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:581
+#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:573
 msgid "On Connect Commands:"
 msgstr "Comandos Ao Ligar:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:42
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:627
+#: ../glade/smuxi-frontend-gnome.glade.h:48
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:619
 msgid "On Startup Commands:"
 msgstr "Comandos Ao Arrancar:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:43
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1714
+#: ../glade/smuxi-frontend-gnome.glade.h:49
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1706
 msgid "Output"
 msgstr "Saída"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:44
+#: ../glade/smuxi-frontend-gnome.glade.h:50
 msgid "Override"
 msgstr "Sobrepor"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:45
+#: ../glade/smuxi-frontend-gnome.glade.h:51
 msgid "Password:"
 msgstr "Palavra-passe:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:46
+#: ../glade/smuxi-frontend-gnome.glade.h:52
 msgid "Port:"
 msgstr "Porto:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../glade/smuxi-frontend-gnome.glade.h:53
 msgid "Protocol:"
 msgstr "Protocolo:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:48
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:538
+#: ../glade/smuxi-frontend-gnome.glade.h:54
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:530
 msgid "Realname:"
 msgstr "Nome Real:"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:49
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1056
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1081
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1576
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1601
+#: ../glade/smuxi-frontend-gnome.glade.h:55
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1048
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1073
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1568
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1593
 msgid "Right"
 msgstr "Direita"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:50
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:195
+#: ../glade/smuxi-frontend-gnome.glade.h:56
+msgid "Show Advanced Settings"
+msgstr "Mostrar Definições Avançadas"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:57
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:196
 msgid "Show Password"
 msgstr "Mostrar a palavra-passe"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:51
+#: ../glade/smuxi-frontend-gnome.glade.h:58
+msgid "Show Smuxi in the messaging menu"
+msgstr "Mostrar Smuxi no menu de mensageiro"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:59
 msgid "Show always"
 msgstr "Mostrar sempre"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:52
+#: ../glade/smuxi-frontend-gnome.glade.h:60
+msgid "Show notification popups"
+msgstr "Mostrar popups de notificação"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:61
 msgid "Show when window is closed"
 msgstr "Mostrar quando a janela é fechada"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:53
+#: ../glade/smuxi-frontend-gnome.glade.h:62
 msgid "Show when window is minimized"
 msgstr "Mostrar quando a janela é minimizada"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:54
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:406
+#: ../glade/smuxi-frontend-gnome.glade.h:63
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:398
 msgid "Smuxi - Preferences"
 msgstr "Smuxi - Preferências"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:55
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:26
+#: ../glade/smuxi-frontend-gnome.glade.h:64
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:18
 msgid "Smuxi - Server"
 msgstr "Smuxi - Servidor"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:56
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:828
+#: ../glade/smuxi-frontend-gnome.glade.h:65
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:820
 msgid "Strip Colors"
 msgstr "Despojar Cores"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:57
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:867
+#: ../glade/smuxi-frontend-gnome.glade.h:66
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:859
 msgid "Strip Formattings"
 msgstr "Despojar Formatações"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:58
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:907
+#: ../glade/smuxi-frontend-gnome.glade.h:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:899
 msgid "Strip UTF-8"
 msgstr "Despojar UTF-8"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:59
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1222
+#: ../glade/smuxi-frontend-gnome.glade.h:68
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1214
 msgid "Tabs"
 msgstr "Separadores"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:60
+#: ../glade/smuxi-frontend-gnome.glade.h:69
 msgid ""
 "The nickname to use. You can specify extra nicknames (separated by spaces) "
 "which will be used as fallbacks when the first choice is not available. By "
@@ -322,51 +358,55 @@ msgstr ""
 "espaços) que serão usadas como apoios quando a primeira escolha não está "
 "disponível. Por predefinição $alcunha_ e $alcunha__ serão usadas como apoios."
 
-#: ../glade/smuxi-frontend-gnome.glade.h:61
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:726
+#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:718
 msgid "Timestamp Format:"
 msgstr "Formato de Marcas Temporais:"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:62
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:943
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:967
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1420
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1446
+#: ../glade/smuxi-frontend-gnome.glade.h:71
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:935
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:959
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1412
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1438
 msgid "Top"
 msgstr "Topo"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:63
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:515
+#: ../glade/smuxi-frontend-gnome.glade.h:72
+msgid "Type:"
+msgstr "Tipo:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:73
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:507
 msgid "Username:"
 msgstr "Nome de utilizador:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:64
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1881
+#: ../glade/smuxi-frontend-gnome.glade.h:74
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1873
 msgid "_Filters"
 msgstr "_Filtros"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:65
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1723
+#: ../glade/smuxi-frontend-gnome.glade.h:75
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1715
 msgid "_Interface"
 msgstr "_Interface"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:66
+#: ../glade/smuxi-frontend-gnome.glade.h:76
 msgid "_Logging"
 msgstr "Registo em _Log"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:67
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1789
+#: ../glade/smuxi-frontend-gnome.glade.h:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1781
 msgid "_Servers"
 msgstr "_Servidores"
 
 #. This is a setting for character based line wrapping vs word based when showing messages
-#: ../glade/smuxi-frontend-gnome.glade.h:69
+#: ../glade/smuxi-frontend-gnome.glade.h:79
 msgid "_Wrap Mode:"
 msgstr "Modo de _Wrap:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../glade/smuxi-frontend-gnome.glade.h:80
 msgid ""
 "ss = seconds\n"
 "mm = minutes\n"
@@ -388,31 +428,23 @@ msgstr ""
 "MM = mês\n"
 "yy/yyyy = ano"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:52
-msgid "translator-credits"
-msgstr "Américo Monteiro <a_monteiro at netcabo.pt>"
-
-#: ../src/Frontend-GNOME/AboutDialog.cs:47
-msgid "German"
-msgstr "Alemão"
-
-#: ../src/Frontend-GNOME/AboutDialog.cs:48
-msgid "Spanish"
-msgstr "Espanhol"
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:1
+msgid "Chat with other people on IRC"
+msgstr "Conversar com outra pessoa no IRC"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:49
-msgid "British English"
-msgstr "Inglês Britânico"
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:2
+msgid "IRC Chat"
+msgstr "Conversação de IRC"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:50
-msgid "French"
-msgstr "Francês"
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:3
+msgid "Smuxi IRC Client"
+msgstr "Smuxi Cliente de IRC"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:51
-msgid "Italian"
-msgstr "Italiano"
+#: ../src/Frontend-GNOME/AboutDialog.cs:58
+msgid "translator-credits"
+msgstr "Américo Monteiro <a_monteiro at netcabo.pt>"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:54
+#: ../src/Frontend-GNOME/AboutDialog.cs:61
 msgid "Smuxi Website"
 msgstr "Site web do Smuxi"
 
@@ -440,142 +472,151 @@ msgstr "Gestor do Motor"
 msgid "_Connect"
 msgstr "_Ligar"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:78
-msgid "_Edit"
-msgstr "_Editar"
-
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:90
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:84
 msgid "Select which Smuxi engine you want to connect to"
 msgstr "Seleccionar a qual motor Smuxi deseja ligar-se"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:96
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:90
 msgid "Engine:"
 msgstr "Motor:"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:122
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:182
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:359
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:116
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:176
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:353
 msgid "Local Engine"
 msgstr "Motor Local"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:174
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:168
 msgid "Please select an engine!"
 msgstr "Por favor seleccione um motor!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:195
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:189
 #, csharp-format
 msgid "Your frontend version ({0}) does not match the engine version ({1})!"
 msgstr "A sua versão de frontend {0} não equivale à versão do motor ({1})!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:222
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:216
 msgid "An error occurred while connecting to the engine!"
 msgstr "Ocorreu um erro ao ligar ao motor!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:223
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:217
 #, csharp-format
 msgid "Engine URL: {0}"
 msgstr "URL do Motor: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:226
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:220
 #, csharp-format
 msgid "Error: {0}"
 msgstr "Erro: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:296
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:290
 #, csharp-format
 msgid "Are you sure you want to delete the engine \"{0}\"?"
 msgstr "Tem certeza que deseja apagar o motor \"{0}\"?"
 
-#: ../src/Frontend-GNOME/Entry.cs:403
+#: ../src/Frontend-GNOME/Entry.cs:421
 #, csharp-format
 msgid "You are going to paste {0} lines. Do you want to continue?"
 msgstr "Você vai colar {0} linhas. Deseja continuar?"
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Frontend-GNOME/Entry.cs:506
+#: ../src/Frontend-GNOME/Entry.cs:524
 msgid "Frontend Commands"
 msgstr "Comandos do Frontend"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:186
+#: ../src/Frontend-GNOME/MainWindow.cs:222
 msgid "_File"
 msgstr "_Ficheiro"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:202
+#: ../src/Frontend-GNOME/MainWindow.cs:238
 msgid "_Server"
 msgstr "_Servidor"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:206
+#: ../src/Frontend-GNOME/MainWindow.cs:242
 msgid "_Quick Connect"
 msgstr "Ligação _Rápida"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:217
+#: ../src/Frontend-GNOME/MainWindow.cs:253
 msgid "_Manage"
 msgstr "_Gerir"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:224
+#: ../src/Frontend-GNOME/MainWindow.cs:260
 msgid "_Chat"
 msgstr "_Conversação"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:228
+#: ../src/Frontend-GNOME/MainWindow.cs:264
 msgid "Open / Join Chat"
 msgstr "Abrir / Juntar a Conversa"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:233
+#: ../src/Frontend-GNOME/MainWindow.cs:269
 msgid "_Find Group Chat"
 msgstr "_Procurar Grupo de Conversação"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:238
+#: ../src/Frontend-GNOME/MainWindow.cs:274
 msgid "C_lear All Activity"
 msgstr "_Limpar Toda a Actividade"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:245
+#: ../src/Frontend-GNOME/MainWindow.cs:281
 msgid "_Next Chat"
 msgstr "_Próxima Conversa"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:255
+#: ../src/Frontend-GNOME/MainWindow.cs:291
 msgid "_Previous Chat"
 msgstr "Conversa An_terior"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:307
+#: ../src/Frontend-GNOME/MainWindow.cs:341
+msgid "Open Log"
+msgstr "Abrir Relatório"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:355
 msgid "_Engine"
 msgstr "_Motor"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:311
+#: ../src/Frontend-GNOME/MainWindow.cs:359
 msgid "_Use Local Engine"
 msgstr "_Usar Motor Local"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:317
+#: ../src/Frontend-GNOME/MainWindow.cs:365
 msgid "_Add Remote Engine"
 msgstr "_Adicionar Motor Remoto"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:322
+#: ../src/Frontend-GNOME/MainWindow.cs:370
 msgid "_Switch Remote Engine"
 msgstr "_Trocar Motor Remoto"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:329
+#: ../src/Frontend-GNOME/MainWindow.cs:377
 msgid "_View"
 msgstr "_Ver"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:333
+#: ../src/Frontend-GNOME/MainWindow.cs:381
 msgid "_Caret Mode"
 msgstr "Modo _Caret"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:343
+#: ../src/Frontend-GNOME/MainWindow.cs:389
+msgid "_Browse Mode"
+msgstr "Modo de _Explorador"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:403
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:586
+msgid "Show _Menubar"
+msgstr "Mostrar Barra de _Menu"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:430
 msgid "_Help"
 msgstr "_Ajuda"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:567
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:222
+#: ../src/Frontend-GNOME/MainWindow.cs:691
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:225
 msgid "Unable to add server: "
 msgstr "Incapaz de adicionar servidor: "
 
-#: ../src/Frontend-GNOME/MainWindow.cs:614
+#: ../src/Frontend-GNOME/MainWindow.cs:742
 #, csharp-format
 msgid "Unknown ChatType: {0}"
 msgstr "Tipo de Conversação Desconhecida: {0}"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:822
+#: ../src/Frontend-GNOME/MainWindow.cs:971
 msgid ""
 "Switching to local engine will disconnect you from the current engine!\n"
 "Are you sure you want to do this?"
@@ -583,7 +624,7 @@ msgstr ""
 "Mudar para o motor local irá desligá-lo do motor actual!\n"
 "Tem certeza que deseja fazer isto?"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:864
+#: ../src/Frontend-GNOME/MainWindow.cs:1013
 msgid ""
 "Switching the remote engine will disconnect you from the current engine!\n"
 "Are you sure you want to do this?"
@@ -596,44 +637,48 @@ msgid "Sorry, not implemented yet!"
 msgstr "Desculpe, ainda não implementado!"
 
 #. fill ListStore
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:162
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:179
 msgid "Character"
 msgstr "Caractere"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:163
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:180
 msgid "Word"
 msgstr "Palavra"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:173
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:198
+msgid "No Proxy"
+msgstr "Nenhum Proxy"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:212
 #: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:139
 msgid "Connection"
 msgstr "Ligação"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:177
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:216
 msgid "Interface"
 msgstr "Interface"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:181
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:220
 msgid "Servers"
 msgstr "Servidores"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:185
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:227
 msgid "Filters"
 msgstr "Filtros"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:189
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:231
 msgid "Logging"
 msgstr "Registar em log"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:238
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:281
 msgid "System Default"
 msgstr "Predefinição do Sistema"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:505
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:588
 msgid "Nicknames(s) field must not be empty."
 msgstr "O campo da(s) alcunha(s) não pode estar vazio."
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:649
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:748
 #, csharp-format
 msgid "Invalid highlight regex: '{0}'. Reason: {1}"
 msgstr "Destaque regex inválido: '{0}'. Razão: {1}"
@@ -662,12 +707,12 @@ msgstr ""
 msgid "Error while fetching the list of group chats from the server."
 msgstr "Erro ao obter a lista de grupos de conversação a partir do servidor."
 
-#: ../src/Frontend-GNOME/Frontend.cs:394
+#: ../src/Frontend-GNOME/Frontend.cs:399
 #, csharp-format
 msgid "Cause: {0}"
 msgstr "Causa: {0}"
 
-#: ../src/Frontend-GNOME/Frontend.cs:464
+#: ../src/Frontend-GNOME/Frontend.cs:469
 msgid ""
 "The frontend has lost the connection to the server.\n"
 "Do you want to reconnect now?"
@@ -675,7 +720,7 @@ msgstr ""
 "O frontend perdeu a ligação ao servidor.\n"
 "Deseja re-ligar agora?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:479
+#: ../src/Frontend-GNOME/Frontend.cs:484
 msgid ""
 "Reconnecting to the server has failed.\n"
 "Do you want to try again?"
@@ -683,7 +728,7 @@ msgstr ""
 "A re-ligação ao servidor falhou.\n"
 "Deseja tentar de novo?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:580
+#: ../src/Frontend-GNOME/Frontend.cs:585
 msgid ""
 "The server has lost the connection to the frontend.\n"
 "Do you want to reconnect now?"
@@ -691,6 +736,10 @@ msgstr ""
 "O servidor perdeu a ligação ao frontend.\n"
 "Deseja re-ligar agora?"
 
+#: ../src/Frontend-GNOME/NotifyManager.cs:229
+msgid "Show"
+msgstr "Mostrar"
+
 #: ../src/Frontend-GNOME/QuickConnectDialog.cs:62
 #: ../src/Frontend-GNOME/Views/FilterListWidget.cs:238
 #: ../src/Frontend-GNOME/Preferences/ServerListView.cs:70
@@ -746,7 +795,7 @@ msgid ""
 msgstr ""
 "Já existe um engenho com este nome! Por favor especifique num nome diferente."
 
-#: ../src/Frontend-GNOME/Views/MessageTextView.cs:182
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:198
 #, csharp-format
 msgid "Day changed to {0}"
 msgstr "Dia alterado para {0}"
@@ -785,17 +834,17 @@ msgstr "Tipo"
 msgid "Pattern"
 msgstr "Padrão"
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:241
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:242
 #, csharp-format
 msgid "Retrieving user list for {0}..."
 msgstr "A obter lista de utilizadores para {0}..."
 
 #. TRANSLATOR: this string will be appended to the one above
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:286
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:289
 msgid "done."
 msgstr "feito."
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:301
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:304
 msgid "Person"
 msgstr "Pessoa"
 
@@ -808,77 +857,77 @@ msgstr ""
 "abertas ligadas a ele!\n"
 "Tem certeza que deseja fazer isto?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:184
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:187
 msgid "Are you sure you want to delete the selected server?"
 msgstr "Tem certeza que deseja apagar o servidor seleccionado?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:240
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:274
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:243
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:277
 msgid "Unable to edit server: "
 msgstr "Incapaz de editar o servidor: "
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:42
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:34
 msgid "Find"
 msgstr "Procurar"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:62
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:54
 msgid "_Search for:"
 msgstr "_Procurar por:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:91
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:83
 msgid "_Match Case"
 msgstr "Caso de _Equivalência"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:103
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:95
 msgid "Search _Backwards"
 msgstr "Procurar para _Trás"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:115
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:107
 msgid "_Wrap Around"
 msgstr "_Wrap em Volta"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:128
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:120
 msgid "Use _Regular Expressions"
 msgstr "Usar Expressões _Regulares"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:40
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:32
 msgid "Smuxi - Find Group Chat"
 msgstr "Smuxi - Procurar Grupo de Conversação"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:64
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:87
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:56
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:79
 msgid "_Name:"
 msgstr "_Nome:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:24
 msgid "Smuxi - Quick Connect"
 msgstr "Smuxi - Ligação Rápida"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:495
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:487
 msgid "Nicknames:"
 msgstr "Alcunhas:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1630
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1622
 msgid "<b> User List Position </b>"
 msgstr "<b> Posição da Lista de Utilizadores </b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1641
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1633
 msgid "<b> Channel </b>"
 msgstr "<b> Canal </b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1852
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1844
 msgid "<b>Channel Filters</b>"
 msgstr "<b>Filtros de Canais</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1869
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1861
 msgid "<b>User Filters</b>"
 msgstr "<b>Filtros de Utilizadores</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:64
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:56
 msgid "Use _SSH Tunnel"
 msgstr "Usar Túnel _SSH"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:78
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:70
 msgid ""
 "<span size=\"small\">Enables the use of SSH for the connection.  This has a "
 "small performance impact, but is more secure and required when using NAT or "
@@ -888,36 +937,36 @@ msgstr ""
 "impacto na performance, mas é mais seguro e necessário quando se usa NAT ou "
 "firewalls baseadas em portos.</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:157
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:149
 msgid "SSH _Host:"
 msgstr "_Máquina SSH:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:168
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:160
 msgid ""
 "<span size=\"small\">DNS or IP address and port of the SSH server</span>"
 msgstr "<span size=\"small\">DNS ou endereço IP e porto do servidor SSH</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:181
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:195
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:154
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:173
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:187
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:155
 msgid "_Port:"
 msgstr "_Porto:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:208
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:200
 msgid ""
 "<span size=\"small\">DNS or IP address and port of the Smuxi server</span>"
 msgstr ""
 "<span size=\"small\">DNS ou endereço IP e porto do servidor Smuxi</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:221
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:213
 msgid "_Smuxi Host:"
 msgstr "Máquina _Smuxi:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:76
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:68
 msgid "_SSH Username: (optional)"
 msgstr "Nome de utilizador _SSH: (opcional)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:99
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:91
 msgid ""
 "<span size=\"small\">Username which will be used to log into the SSH server</"
 "span>"
@@ -925,11 +974,11 @@ msgstr ""
 "<span size=\"small\">Nome de utilizador que será usado para login no "
 "servidor SSH</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:119
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:111
 msgid "_SSH Password: (optional)"
 msgstr "Palavra-passe de _SSH: (opcional)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:143
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:135
 msgid ""
 "<span size=\"small\">Password which will be used to log into the SSH server. "
 "The password is optional if SSH key authorization is used (via Pageant from "
@@ -939,12 +988,12 @@ msgstr ""
 "SSH. A palavra-passe é opcional se for usada uma chave de autenticação SSH "
 "(via Pageant a partir das ferramentas PuTTY).</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:164
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:223
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:156
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:214
 msgid "_Username:"
 msgstr "Nome de _Utilizador:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:187
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:179
 msgid ""
 "<span size=\"small\">Username which will be used to log into the Smuxi "
 "server</span>"
@@ -952,24 +1001,24 @@ msgstr ""
 "<span size=\"small\">Nome de utilizador que será usado para login no "
 "servidor Smuxi</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:207
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:233
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:199
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:113
 msgid "_Password:"
 msgstr "_Palavra-passe:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:231
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:223
 msgid "<span size=\"small\">Password of the user</span>"
 msgstr "<span size=\"small\">Palavra-passe do utilizador</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:251
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:243
 msgid "_Verify Password:"
 msgstr "_Verificar Palavra-passe:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:275
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:267
 msgid "<span size=\"small\">Repeat the password for verification</span>"
 msgstr "<span size=\"small\">Repita a palavra-passe para verificação</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs:27
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs:19
 msgid ""
 "Welcome to the Smuxi Engine Configuration Assistant.\n"
 "You need to enter some information before you can use the engine.\n"
@@ -981,23 +1030,23 @@ msgstr ""
 "\n"
 "Clique em \"Avançar\" para começar."
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:52
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:44
 msgid "_Engine Name:"
 msgstr "Nom_e do Motor:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:75
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:67
 msgid "<span size=\"small\">Profile name of the new engine</span>"
 msgstr "<span size=\"small\">Nome de perfil do novo motor</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:96
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:88
 msgid "_Default Engine:"
 msgstr "Motor Pre_definido:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:107
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:99
 msgid "Use as new default engine"
 msgstr "Usar como novo motor predefinido"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:120
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:112
 msgid ""
 "<span size=\"small\">If enabled, the current engine will be the default next "
 "time Smuxi is started</span>"
@@ -1005,34 +1054,60 @@ msgstr ""
 "<span size=\"small\">Se activo, o motor actual será o predefinido na próxima "
 "vez que o Smuxi for iniciado</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:26
 msgid "Smuxi - Open Chat"
 msgstr "Smuxi - Abrir Conversação"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:69
 msgid "_Type:"
 msgstr "_Tipo:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:95
-msgid "_Network:"
-msgstr "_Rede:"
-
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:213
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:80
 msgid "_Hostname:"
 msgstr "Nome de _Máquina:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:243
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:101
+msgid "_Network:"
+msgstr "_Rede:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:224
 msgid "_Protocol:"
 msgstr "_Protocolo:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:262
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:248
+msgid "Use Encryption"
+msgstr "Usar Encriptação"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:260
+msgid "Validate Server Certificate"
+msgstr "Validar Certificado do Servidor"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:280
 msgid "_On Connect Commands:"
 msgstr "C_omandos Ao Ligar:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:273
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:291
 msgid "_Ignore Commands"
 msgstr "Comandos de Ignorar:"
 
+#~ msgid "German"
+#~ msgstr "Alemão"
+
+#~ msgid "Spanish"
+#~ msgstr "Espanhol"
+
+#~ msgid "British English"
+#~ msgstr "Inglês Britânico"
+
+#~ msgid "French"
+#~ msgstr "Francês"
+
+#~ msgid "Italian"
+#~ msgstr "Italiano"
+
+#~ msgid "_Edit"
+#~ msgstr "_Editar"
+
 #~ msgid "Unknown Command: {0}"
 #~ msgstr "Comando Desconhecido: {0}"
 
diff --git a/po-Frontend-GNOME/ru.po b/po-Frontend-GNOME/ru.po
new file mode 100644
index 0000000..fa26992
--- /dev/null
+++ b/po-Frontend-GNOME/ru.po
@@ -0,0 +1,1038 @@
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: smuxi 0.8\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: \n"
+"Last-Translator: Алекс <davian818 at gmail.com>\n"
+"Language-Team: None <->\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=(n==1) ? 0 : (n%10==1 && n%100!=11 ? 3 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Poedit-Language: Russian\n"
+"X-Poedit-Country: RUSSIAN FEDERATION\n"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:1
+msgid "<b> Chat </b>"
+msgstr "<b> Разговор </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:2
+msgid "<b> Color </b>"
+msgstr "<b> Цвета </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:3
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1364
+msgid "<b> Entry Field </b>"
+msgstr "<b> Строка ввода </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:4
+msgid "<b> Font </b>"
+msgstr "<b> Шрифт </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:5
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1694
+msgid "<b> Highlighting </b>"
+msgstr "<b> Подсветка </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:6
+msgid "<b> Notification Area Icon </b>"
+msgstr "<b> Значок в области уведомлений </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:7
+msgid "<b> Person List Position </b>"
+msgstr "<b> Список участников </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:8
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1201
+msgid "<b> Tab Colors </b>"
+msgstr "<b> Цвета вкладок </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:9
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1102
+msgid "<b> Tabs Position </b>"
+msgstr "<b> Положение </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:10
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1507
+msgid "<b> Topic Position </b>"
+msgstr "<b> Тема </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:11
+msgid "<b>General</b>"
+msgstr "<b>Общие</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:12
+msgid "<b>Global Commands</b>"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:13
+msgid "<b>Messaging Menu</b>"
+msgstr "<b>Меню сообщений</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:14
+msgid "<b>Network Proxy</b>"
+msgstr "<b>Прокси-сервер</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:15
+msgid "<b>Notification Popups</b>"
+msgstr "<b>Вcплываюoщие cообщения</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:16
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1153
+msgid "Activity"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:17
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:235
+msgid "Automatically connect to server at startup"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:18
+msgid "Background"
+msgstr "Фон"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:19
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1352
+msgid "Bash-Style Completion"
+msgstr "Дополнение в стиле Bash"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:20
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1682
+msgid "Beep on highlight"
+msgstr "Звуковой сигнал"
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:21
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:972
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:994
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1453
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1478
+msgid "Bottom"
+msgstr "Снизу"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:22
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:738
+msgid "Buffer Lines:"
+msgstr "Раз_мер буфера:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:23
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:663
+msgid "C_onnection"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:24
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1304
+msgid "Command Character:"
+msgstr "Символ команды:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:25
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1327
+msgid "Command History Size:"
+msgstr "Размер журнала команд:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:26
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1284
+msgid "Completion Character:"
+msgstr "Символ дополнения:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:27
+msgid "Enable"
+msgstr "Включить"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:28
+msgid "Enabled"
+msgstr "Запись в журнал"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:29
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:551
+msgid "Encoding:"
+msgstr "Кодировка:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:30
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:761
+msgid "Engine Buffer Lines:"
+msgstr "Строк в буфере ядра:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:31
+msgid "Foreground"
+msgstr "Текст"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:917
+msgid "General"
+msgstr "Общие"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:33
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1173
+msgid "Highlight"
+msgstr "Подсветка"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1658
+msgid "Highlight words:"
+msgstr "Подсвечивать слова"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:35
+msgid "Host:"
+msgstr "Сервер:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:36
+msgid "Hostname:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:37
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1373
+msgid "Input"
+msgstr "Ввод"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:38
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1163
+msgid "Join/Part/Mode"
+msgstr "Служебные сообщения"
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:39
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1008
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1033
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1527
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1553
+msgid "Left"
+msgstr "Слева"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:40
+msgid "Log Filtered Messages"
+msgstr "Включать отфильтрованные сообщения"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:41
+msgid "Network:"
+msgstr "Сеть:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:42
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1394
+msgid "Nick Colors"
+msgstr "Цветные имена"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:43
+msgid "Nickname(s):"
+msgstr "Имена:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:44
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1145
+msgid "No Activity"
+msgstr "Без изменений"
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:45
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1088
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1493
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1608
+msgid "None"
+msgstr "Нет"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:46
+msgid "Notification"
+msgstr "Оповещения"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:573
+msgid "On Connect Commands:"
+msgstr "Команды при соединении:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:48
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:619
+msgid "On Startup Commands:"
+msgstr "Команды при запуске:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:49
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1706
+msgid "Output"
+msgstr "Вывод"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:50
+msgid "Override"
+msgstr "Изменить:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:51
+msgid "Password:"
+msgstr "Пароль:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:52
+msgid "Port:"
+msgstr "Порт:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:53
+msgid "Protocol:"
+msgstr "Протокол:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:54
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:530
+msgid "Realname:"
+msgstr "Полное имя:"
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:55
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1048
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1073
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1568
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1593
+msgid "Right"
+msgstr "Справа"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:56
+msgid "Show Advanced Settings"
+msgstr "Показывать расширенные настройки"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:57
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:196
+msgid "Show Password"
+msgstr "Отображать пароль"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:58
+msgid "Show Smuxi in the messaging menu"
+msgstr "Включать Smuxi в меню сообщений"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:59
+msgid "Show always"
+msgstr "Всегда"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:60
+msgid "Show notification popups"
+msgstr "Использовать всплывающие сообщения"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:61
+msgid "Show when window is closed"
+msgstr "Когда окно закрыто"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:62
+msgid "Show when window is minimized"
+msgstr "Когда окно свернуто"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:63
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:398
+msgid "Smuxi - Preferences"
+msgstr "Smuxi - параметры"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:64
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:18
+msgid "Smuxi - Server"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:65
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:820
+msgid "Strip Colors"
+msgstr "Убирать цвета"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:66
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:859
+msgid "Strip Formattings"
+msgstr "Убирать начертания"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:899
+msgid "Strip UTF-8"
+msgstr "Убирать символы UTF-8"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:68
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1214
+msgid "Tabs"
+msgstr "Вкладки"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:69
+msgid "The nickname to use. You can specify extra nicknames (separated by spaces) which will be used as fallbacks when the first choice is not available. By default $nick_ and $nick__ will be used as fallbacks."
+msgstr "Используемое имя. Можно указать дополнительные имена, разделенные пробелами, которые будут использоваться, если первое недоступно; по умолчанию для этого будут использоваться варианты $nick_ и $nick__."
+
+#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:718
+msgid "Timestamp Format:"
+msgstr "Формат метки времени:"
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:71
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:935
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:959
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1412
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1438
+msgid "Top"
+msgstr "Сверху"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:72
+msgid "Type:"
+msgstr "Тип:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:73
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:507
+msgid "Username:"
+msgstr "Имя пользователя:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:74
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1873
+msgid "_Filters"
+msgstr "_Фильтры"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:75
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1715
+msgid "_Interface"
+msgstr "_Вид"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:76
+msgid "_Logging"
+msgstr "_Журнал"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1781
+msgid "_Servers"
+msgstr "_Серверы"
+
+#. This is a setting for character based line wrapping vs word based when
+#. showing messages
+#: ../glade/smuxi-frontend-gnome.glade.h:79
+msgid "_Wrap Mode:"
+msgstr "Режим п_ереноса:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:80
+msgid ""
+"ss = seconds\n"
+"mm = minutes\n"
+"hh = hours (01 - 12)\n"
+"HH = hours (00 - 23)\n"
+"tt = AM/PM\n"
+"\n"
+"dd = day\n"
+"MM = month\n"
+"yy/yyyy = year"
+msgstr ""
+
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:1
+msgid "Chat with other people on IRC"
+msgstr "Разговор с людьми в сети IRC"
+
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:2
+msgid "IRC Chat"
+msgstr "IRC-чат"
+
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:3
+msgid "Smuxi IRC Client"
+msgstr "IRC-клиент Smuxi"
+
+#: ../src/Frontend-GNOME/AboutDialog.cs:58
+msgid "translator-credits"
+msgstr "Alexandr Ponomarenko, 2010"
+
+#: ../src/Frontend-GNOME/AboutDialog.cs:61
+msgid "Smuxi Website"
+msgstr "Сайт Smuxi"
+
+#: ../src/Frontend-GNOME/CrashDialog.cs:44
+msgid "Oops, I did it again..."
+msgstr "Опять двадцать пять..."
+
+#: ../src/Frontend-GNOME/CrashDialog.cs:57
+msgid "Smuxi crashed because an unhandled exception was thrown!"
+msgstr "Smuxi аварийно завершается из-за необработанного исключения!"
+
+#: ../src/Frontend-GNOME/CrashDialog.cs:61
+msgid "Here is the stacktrace, please report this bug!"
+msgstr "Сообщите об ошибке, приложив эту трассировку."
+
+#: ../src/Frontend-GNOME/CrashDialog.cs:81
+msgid "_Report Bug"
+msgstr "Сообщить об о_шибке"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:61
+msgid "Engine Manager"
+msgstr "Управление ядрами"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:68
+msgid "_Connect"
+msgstr "П_одключение"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:84
+msgid "Select which Smuxi engine you want to connect to"
+msgstr "Выберите ядро Smuxi, к которому следует подключиться"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:90
+msgid "Engine:"
+msgstr "Ядро:"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:116
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:176
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:353
+msgid "Local Engine"
+msgstr "Локальное ядро"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:168
+msgid "Please select an engine!"
+msgstr "Нужно выбрать ядро!"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:189
+#, csharp-format
+msgid "Your frontend version ({0}) does not match the engine version ({1})!"
+msgstr "Версия оболочки ({0}) не соответствует версии ядра ({1})!"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:216
+msgid "An error occurred while connecting to the engine!"
+msgstr "Ошибка при подключении к ядру!"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:217
+#, csharp-format
+msgid "Engine URL: {0}"
+msgstr "Адрес URL: {0}"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:220
+#, csharp-format
+msgid "Error: {0}"
+msgstr "Ошибка: {0}"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:290
+#, csharp-format
+msgid "Are you sure you want to delete the engine \"{0}\"?"
+msgstr "Вы действительно хотите удалить ядро \"{0}\"?"
+
+#: ../src/Frontend-GNOME/Entry.cs:421
+#, csharp-format
+msgid "You are going to paste {0} lines. Do you want to continue?"
+msgstr "Будут вставлены {0} строк текста. Продолжить?"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Frontend-GNOME/Entry.cs:524
+msgid "Frontend Commands"
+msgstr "Команды оболочки"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:222
+msgid "_File"
+msgstr "_Файл"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:238
+msgid "_Server"
+msgstr "_Сервер"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:242
+msgid "_Quick Connect"
+msgstr "_Быстрое соединение"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:253
+msgid "_Manage"
+msgstr "_Управление"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:260
+msgid "_Chat"
+msgstr "_Разговор"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:264
+msgid "Open / Join Chat"
+msgstr "_Начать или вступить..."
+
+#: ../src/Frontend-GNOME/MainWindow.cs:269
+msgid "_Find Group Chat"
+msgstr "Найти _конференцию"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:274
+msgid "C_lear All Activity"
+msgstr "У_брать метки активности"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:281
+msgid "_Next Chat"
+msgstr "С_ледующий"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:291
+msgid "_Previous Chat"
+msgstr "Пре_дыдущий"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:341
+msgid "Open Log"
+msgstr "Открыть _журнал"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:355
+msgid "_Engine"
+msgstr "_Ядро"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:359
+msgid "_Use Local Engine"
+msgstr "_Локальное ядро"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:365
+msgid "_Add Remote Engine"
+msgstr "_Добавить ядро в сети"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:370
+msgid "_Switch Remote Engine"
+msgstr "_Выбрать ядро в сети"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:377
+msgid "_View"
+msgstr "_Вид"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:381
+msgid "_Caret Mode"
+msgstr "Режим _выделения"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:389
+msgid "_Browse Mode"
+msgstr "Режим _обзора"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:403
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:586
+msgid "Show _Menubar"
+msgstr "Строка _меню"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:430
+msgid "_Help"
+msgstr "Спр_авка"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:691
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:225
+msgid "Unable to add server: "
+msgstr "Не удалось добавить сервер: "
+
+#: ../src/Frontend-GNOME/MainWindow.cs:742
+#, csharp-format
+msgid "Unknown ChatType: {0}"
+msgstr ""
+
+#: ../src/Frontend-GNOME/MainWindow.cs:971
+msgid ""
+"Switching to local engine will disconnect you from the current engine!\n"
+"Are you sure you want to do this?"
+msgstr ""
+"Переключение на локальное ядро отключит вас от текущего!\n"
+"Продолжить?"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:1013
+msgid ""
+"Switching the remote engine will disconnect you from the current engine!\n"
+"Are you sure you want to do this?"
+msgstr ""
+"Смена ядра в сети отключит вас от текущего!\n"
+"Продолжить?"
+
+#: ../src/Frontend-GNOME/NotImplementedMessageDialog.cs:40
+msgid "Sorry, not implemented yet!"
+msgstr "Функция не реализована."
+
+#. fill ListStore
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:179
+msgid "Character"
+msgstr "по символам"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:180
+msgid "Word"
+msgstr "по словам"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:198
+msgid "No Proxy"
+msgstr "Без прокси-сервера"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:212
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:139
+msgid "Connection"
+msgstr "Соединение"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:216
+msgid "Interface"
+msgstr "Вид"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:220
+msgid "Servers"
+msgstr "Серверы"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:227
+msgid "Filters"
+msgstr "Фильтры"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:231
+msgid "Logging"
+msgstr "Журнал"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:281
+msgid "System Default"
+msgstr "Системная"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:588
+msgid "Nicknames(s) field must not be empty."
+msgstr "Нужно указать хотя бы одно имя"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:748
+#, csharp-format
+msgid "Invalid highlight regex: '{0}'. Reason: {1}"
+msgstr "Неверное выражение для подсветки: '{0}'. Причина: {1}"
+
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:69
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:105
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:271
+msgid "Name"
+msgstr ""
+
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:74
+msgid "Topic"
+msgstr "Тема"
+
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:102
+msgid ""
+"Searching for group chats without a filter is not recommended.  This may take a while, or may not work at all.\n"
+"Do you wish to continue?"
+msgstr ""
+"Поиск конференций без указания фильтра не рекомендуется. Это может занять много времени, но не принести результата.\n"
+"Продолжить?"
+
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:143
+msgid "Error while fetching the list of group chats from the server."
+msgstr "Не удалось получить с сервера список конференций."
+
+#: ../src/Frontend-GNOME/Frontend.cs:399
+#, csharp-format
+msgid "Cause: {0}"
+msgstr "Причина: {0}"
+
+#: ../src/Frontend-GNOME/Frontend.cs:469
+msgid ""
+"The frontend has lost the connection to the server.\n"
+"Do you want to reconnect now?"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Frontend.cs:484
+msgid ""
+"Reconnecting to the server has failed.\n"
+"Do you want to try again?"
+msgstr ""
+"Не удалось возобновить подключение к серверу.\n"
+"Попробовать еще раз?"
+
+#: ../src/Frontend-GNOME/Frontend.cs:585
+msgid ""
+"The server has lost the connection to the frontend.\n"
+"Do you want to reconnect now?"
+msgstr ""
+
+#: ../src/Frontend-GNOME/NotifyManager.cs:229
+msgid "Show"
+msgstr ""
+
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:62
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:238
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:70
+msgid "Protocol"
+msgstr "Протокол"
+
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:63
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:71
+msgid "Hostname"
+msgstr "Имя"
+
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:166
+msgid "Unable to load server: "
+msgstr "Не удалось загрузить сервер: "
+
+#: ../src/Frontend-GNOME/ChatTypeWidget.cs:54
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:244
+msgid "Person / Private"
+msgstr "Личные"
+
+#: ../src/Frontend-GNOME/ChatTypeWidget.cs:55
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:245
+msgid "Group / Public"
+msgstr "Групповые и обществ."
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:70
+msgid "Engine Assistant - Smuxi"
+msgstr "Мастер настройки - Smuxi"
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:92
+msgid "Add Smuxi Engine"
+msgstr "Добавить ядро Smuxi"
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:94
+msgid "Edit Smuxi Engine"
+msgstr "Свойства ядра Smuxi"
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:203
+msgid "Credentials"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:265
+msgid "Now you can use the Smuxi Engine"
+msgstr "Ядро Smuxi готово к использованию"
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:268
+msgid "Thank you"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:285
+msgid "An engine with this name already exists! Please specify a different one."
+msgstr "Ядро под таким названием уже существует! Выберите другое."
+
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:198
+#, csharp-format
+msgid "Day changed to {0}"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:123
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:133
+#, csharp-format
+msgid "Invalid filter regex: '{0}'. Reason: {1}"
+msgstr "Неверное выражение фильтра: '{0}'. Причина: {1}"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:200
+msgid "Are you sure you want to delete the selected filter?"
+msgstr "Вы хотите удалить выбранный фильтр?"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:246
+msgid "Protocol / Server"
+msgstr "Протокол и сервер"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:253
+msgid "Chat Type"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:287
+msgid "Normal"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:288
+msgid "Event"
+msgstr "Событие"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:295
+msgid "Type"
+msgstr "Тип"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:321
+msgid "Pattern"
+msgstr "Шаблон"
+
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:242
+#, csharp-format
+msgid "Retrieving user list for {0}..."
+msgstr "Получение списка пользователей на {0}..."
+
+#. TRANSLATOR: this string will be appended to the one above
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:289
+msgid "done."
+msgstr "готово."
+
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:304
+msgid "Person"
+msgstr "Люди"
+
+#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:68
+msgid ""
+"Closing the protocol chat will also close all open chats connected to it!\n"
+"Are you sure you want to do this?"
+msgstr ""
+"Закрытие окна протокола прервет все разговоры по этому протоколу.\n"
+"Вы действительно хотите это сделать?"
+
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:187
+msgid "Are you sure you want to delete the selected server?"
+msgstr "Вы хотите удалить выбранный сервер?"
+
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:243
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:277
+msgid "Unable to edit server: "
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:34
+msgid "Find"
+msgstr "Поиск"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:54
+msgid "_Search for:"
+msgstr "_Искать:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:83
+msgid "_Match Case"
+msgstr "С _учетом регистра"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:95
+msgid "Search _Backwards"
+msgstr "На_зад"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:107
+msgid "_Wrap Around"
+msgstr "Во _всем тексте"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:120
+msgid "Use _Regular Expressions"
+msgstr "_Регулярные выражения"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:32
+msgid "Smuxi - Find Group Chat"
+msgstr "Smuxi - Поиск конференций"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:56
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:79
+msgid "_Name:"
+msgstr "_Название:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:24
+msgid "Smuxi - Quick Connect"
+msgstr "Smuxi - Быстрое соединение"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:487
+msgid "Nicknames:"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1622
+msgid "<b> User List Position </b>"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1633
+msgid "<b> Channel </b>"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1844
+msgid "<b>Channel Filters</b>"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1861
+msgid "<b>User Filters</b>"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:56
+msgid "Use _SSH Tunnel"
+msgstr "Использовать _туннелирование SSH"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:70
+msgid "<span size=\"small\">Enables the use of SSH for the connection.  This has a small performance impact, but is more secure and required when using NAT or port-based firewalls</span>"
+msgstr "<span size=\"small\">Использовать SSH для данного соединения. Это слегка снижает производительность, но обеспечивает безопасность и позволяет соединяться через  NAT и брандмауэры.</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:149
+msgid "SSH _Host:"
+msgstr "_Сервер SSH:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:160
+msgid "<span size=\"small\">DNS or IP address and port of the SSH server</span>"
+msgstr "<span size=\"small\">Имя или адрес, а так же порт сервера SSH</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:173
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:187
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:155
+msgid "_Port:"
+msgstr "_Порт:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:200
+msgid "<span size=\"small\">DNS or IP address and port of the Smuxi server</span>"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:213
+msgid "_Smuxi Host:"
+msgstr "_Адрес Smuxi:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:68
+msgid "_SSH Username: (optional)"
+msgstr "_Имя пользователя SSH Username: (необязательно)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:91
+msgid "<span size=\"small\">Username which will be used to log into the SSH server</span>"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:111
+msgid "_SSH Password: (optional)"
+msgstr "П_ароль SSH: (необязательно)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:135
+msgid "<span size=\"small\">Password which will be used to log into the SSH server. The password is optional if SSH key authorization is used (via Pageant from the PuTTY tools).</span>"
+msgstr "<span size=\"small\">Пароль для входа на сервер SSH. Необязательно, если используются сертификаты (напр. через Pageant из пакета PuTTY).</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:156
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:214
+msgid "_Username:"
+msgstr "И_мя пользователя:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:179
+msgid "<span size=\"small\">Username which will be used to log into the Smuxi server</span>"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:199
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:113
+msgid "_Password:"
+msgstr "_Пароль:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:223
+msgid "<span size=\"small\">Password of the user</span>"
+msgstr "<span size=\"small\">Пароль пользователя</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:243
+msgid "_Verify Password:"
+msgstr "Про_верка пароля:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:267
+msgid "<span size=\"small\">Repeat the password for verification</span>"
+msgstr "<span size=\"small\">Введите пароль еще раз для проверки</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs:19
+msgid ""
+"Welcome to the Smuxi Engine Configuration Assistant.\n"
+"You need to enter some information before you can use the engine.\n"
+"\n"
+"Click \"Forward\" to begin."
+msgstr ""
+"Добро пожаловать в мастер настройки ядра Smuxi.\n"
+"Перед его использованием потребуется указать некоторые сведения.\n"
+"\n"
+"Щелкните \"Вперёд\"."
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:44
+msgid "_Engine Name:"
+msgstr "_Название ядра:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:67
+msgid "<span size=\"small\">Profile name of the new engine</span>"
+msgstr "<span size=\"small\">Название профиля для нового ядра</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:88
+msgid "_Default Engine:"
+msgstr "По _умолчанию:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:99
+msgid "Use as new default engine"
+msgstr "Использовать как ядро по умолчанию"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:112
+msgid "<span size=\"small\">If enabled, the current engine will be the default next time Smuxi is started</span>"
+msgstr "<span size=\"small\">Использовать данное ядро по умолчанию при следующем запуске Smuxi</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:26
+msgid "Smuxi - Open Chat"
+msgstr "Smuxi - Выбор разговора"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:69
+msgid "_Type:"
+msgstr "_Тип:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:80
+msgid "_Hostname:"
+msgstr "_Сервер:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:101
+msgid "_Network:"
+msgstr "С_еть:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:224
+msgid "_Protocol:"
+msgstr "П_ротокол:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:248
+msgid "Use Encryption"
+msgstr "Использовать _шифрование"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:260
+msgid "Validate Server Certificate"
+msgstr "Проверять сертификат сервера"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:280
+msgid "_On Connect Commands:"
+msgstr "П_ри подключении:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:291
+msgid "_Ignore Commands"
+msgstr "И_гнорировать команды"
+
diff --git a/po-Frontend-GNOME/sv.po b/po-Frontend-GNOME/sv.po
index 5479d4d..62c5f84 100644
--- a/po-Frontend-GNOME/sv.po
+++ b/po-Frontend-GNOME/sv.po
@@ -1,22 +1,22 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-#
-# Martin Bagge <brother at bsnet.se>, 2009
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+#   <flugsio at gmail.com>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: Smuxi Frontend GNOME\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:35+0200\n"
-"PO-Revision-Date: 2010-07-15 13:15+0100\n"
-"Last-Translator: Martin Bagge / brother <brother at bsnet.se>\n"
-"Language-Team: Swedish <tp-sv at listor.tp-sv.se>\n"
-"Language: sv\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:22+0100\n"
+"PO-Revision-Date: 2011-12-31 10:33+0000\n"
+"Last-Translator: flugsio <flugsio at gmail.com>\n"
+"Language-Team: Swedish (http://www.transifex.net/projects/p/smuxi/team/sv/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: Swedish\n"
-"X-Poedit-Country: Sweden\n"
+"Language: sv\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:1
 msgid "<b> Chat </b>"
@@ -27,7 +27,7 @@ msgid "<b> Color </b>"
 msgstr "<b> Färg </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:3
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1372
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1172
 msgid "<b> Entry Field </b>"
 msgstr "<b> Inmatningsfält </b>"
 
@@ -36,7 +36,7 @@ msgid "<b> Font </b>"
 msgstr "<b> Teckensnitt </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:5
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1702
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1502
 msgid "<b> Highlighting </b>"
 msgstr "<b> Förstärkning </b>"
 
@@ -49,318 +49,384 @@ msgid "<b> Person List Position </b>"
 msgstr "<b> Position för personlista </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:8
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1209
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1009
 msgid "<b> Tab Colors </b>"
 msgstr "<b> Flikfärg </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:9
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1110
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:910
 msgid "<b> Tabs Position </b>"
 msgstr "<b> Position för flikar </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:10
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1515
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1315
 msgid "<b> Topic Position </b>"
 msgstr "<b> Position för rubrik </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:11
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1161
+msgid "<b>Advanced</b>"
+msgstr "<b>Avancerat</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:12
+msgid "<b>General</b>"
+msgstr "<b>Allmänt</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:13
+msgid "<b>Global Commands</b>"
+msgstr "<b>Allmänna kommandon</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:14
+msgid "<b>Message Buffer</b>"
+msgstr "<b>Meddelande-buffer</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:15
+msgid "<b>Messaging Menu</b>"
+msgstr "<b>Meddelandemenu</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:16
+msgid "<b>Network Proxy</b>"
+msgstr "<b>Nätverksproxy</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:17
+msgid "<b>Notification Popups</b>"
+msgstr "<b>Notifieringsmeddelanden</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:18
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:961
 msgid "Activity"
 msgstr "Aktivitet"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:12
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:107
+#: ../glade/smuxi-frontend-gnome.glade.h:19
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:209
 msgid "Automatically connect to server at startup"
 msgstr "Anslut automatiskt till server vid uppstart"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:13
+#: ../glade/smuxi-frontend-gnome.glade.h:20
 msgid "Background"
 msgstr "Bakgrund"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:14
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1360
+#: ../glade/smuxi-frontend-gnome.glade.h:21
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1160
 msgid "Bash-Style Completion"
 msgstr "Bash-liknande komplettering"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:15
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1690
+#: ../glade/smuxi-frontend-gnome.glade.h:22
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1490
 msgid "Beep on highlight"
 msgstr "Pip vid förstärkning"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:16
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:980
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1002
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1461
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1486
+#: ../glade/smuxi-frontend-gnome.glade.h:23
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:780
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:802
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1261
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1286
 msgid "Bottom"
 msgstr "Botten"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:17
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:746
+#: ../glade/smuxi-frontend-gnome.glade.h:24
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:546
 msgid "Buffer Lines:"
 msgstr "Buffrade rader:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:18
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:671
+#: ../glade/smuxi-frontend-gnome.glade.h:25
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:471
 msgid "C_onnection"
 msgstr "_Anslutning"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:19
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1312
+#: ../glade/smuxi-frontend-gnome.glade.h:26
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1112
 msgid "Command Character:"
 msgstr "Kommandotecken:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:20
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1335
+#: ../glade/smuxi-frontend-gnome.glade.h:27
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1135
 msgid "Command History Size:"
 msgstr "Antal kommandon i historik:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:21
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1292
+#: ../glade/smuxi-frontend-gnome.glade.h:28
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1092
 msgid "Completion Character:"
 msgstr "Kompletteringstecken:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:22
+#: ../glade/smuxi-frontend-gnome.glade.h:29
 msgid "Enable"
 msgstr "Aktivera"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:23
+#: ../glade/smuxi-frontend-gnome.glade.h:30
 msgid "Enabled"
 msgstr "Aktivera"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:24
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:559
+#: ../glade/smuxi-frontend-gnome.glade.h:31
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:359
 msgid "Encoding:"
 msgstr "Kodning:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:25
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:769
+#: ../glade/smuxi-frontend-gnome.glade.h:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:569
 msgid "Engine Buffer Lines:"
 msgstr "Buffrade rader i motorn"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:26
+#: ../glade/smuxi-frontend-gnome.glade.h:33
 msgid "Foreground"
 msgstr "Förgrund"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:27
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:925
+#: ../glade/smuxi-frontend-gnome.glade.h:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:725
 msgid "General"
 msgstr "Allmänt"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:28
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
+#: ../glade/smuxi-frontend-gnome.glade.h:35
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:981
 msgid "Highlight"
 msgstr "Förstärk"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:29
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1666
+#: ../glade/smuxi-frontend-gnome.glade.h:36
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1466
 msgid "Highlight words:"
 msgstr "Förstärk ord"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:30
+#: ../glade/smuxi-frontend-gnome.glade.h:37
+msgid "Host:"
+msgstr "Värd:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:38
 msgid "Hostname:"
 msgstr "Värdnamn:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:31
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1381
+#: ../glade/smuxi-frontend-gnome.glade.h:39
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
 msgid "Input"
 msgstr "Indata"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:32
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1171
+#: ../glade/smuxi-frontend-gnome.glade.h:40
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:971
 msgid "Join/Part/Mode"
 msgstr "Anslut/Lämna/Användartillstånd"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:33
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1016
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1041
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1535
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1561
+#: ../glade/smuxi-frontend-gnome.glade.h:41
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:816
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:841
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1335
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1361
 msgid "Left"
 msgstr "Vänster"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:34
+#: ../glade/smuxi-frontend-gnome.glade.h:42
 msgid "Log Filtered Messages"
 msgstr "Logga filtrerade meddelanden"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:35
+#: ../glade/smuxi-frontend-gnome.glade.h:43
 msgid "Network:"
 msgstr "Nätverk"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:36
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1402
+#: ../glade/smuxi-frontend-gnome.glade.h:44
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1202
 msgid "Nick Colors"
 msgstr "Färg på smekanmn"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:37
+#: ../glade/smuxi-frontend-gnome.glade.h:45
 msgid "Nickname(s):"
 msgstr "Smeknamn:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:38
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1153
+#: ../glade/smuxi-frontend-gnome.glade.h:46
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:953
 msgid "No Activity"
 msgstr "Ingen aktivitet"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:39
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1096
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1501
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1616
+#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:896
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1301
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1416
 msgid "None"
 msgstr "Ingen"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:40
+#: ../glade/smuxi-frontend-gnome.glade.h:48
 msgid "Notification"
 msgstr "Notifiering"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:41
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:581
+#: ../glade/smuxi-frontend-gnome.glade.h:49
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:381
 msgid "On Connect Commands:"
 msgstr "Kommando vid anslutning:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:42
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:627
+#: ../glade/smuxi-frontend-gnome.glade.h:50
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:427
 msgid "On Startup Commands:"
 msgstr "Kommando vid uppstart:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:43
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1714
+#: ../glade/smuxi-frontend-gnome.glade.h:51
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1514
 msgid "Output"
 msgstr "Utdata"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:44
+#: ../glade/smuxi-frontend-gnome.glade.h:52
 msgid "Override"
 msgstr "ÅSidosätt"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:45
+#: ../glade/smuxi-frontend-gnome.glade.h:53
 msgid "Password:"
 msgstr "Lösenord:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:46
+#: ../glade/smuxi-frontend-gnome.glade.h:54
+msgid "Persistency Type:"
+msgstr "Typ av persistens:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:55
+msgid "Persistent Buffer Lines:"
+msgstr "Beständiga buffer-rader:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:56
 msgid "Port:"
 msgstr "Port:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../glade/smuxi-frontend-gnome.glade.h:57
 msgid "Protocol:"
 msgstr "Protokoll:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:48
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:538
+#: ../glade/smuxi-frontend-gnome.glade.h:58
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:338
 msgid "Realname:"
 msgstr "Riktigt namn:"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox12.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:49
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1056
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1081
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1576
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1601
+#: ../glade/smuxi-frontend-gnome.glade.h:59
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:856
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:881
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1376
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1401
 msgid "Right"
 msgstr "Höger"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:50
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:195
+#: ../glade/smuxi-frontend-gnome.glade.h:60
+msgid "Show Advanced Settings"
+msgstr "Visa avancerade inställningar"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:61
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:170
 msgid "Show Password"
 msgstr "Visa lösenord"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:51
+#: ../glade/smuxi-frontend-gnome.glade.h:62
+msgid "Show Smuxi in the messaging menu"
+msgstr "Visa Smuxi i meddelandemenyn"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:63
 msgid "Show always"
 msgstr "Visa alltid"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:52
+#: ../glade/smuxi-frontend-gnome.glade.h:64
+msgid "Show notification popups"
+msgstr "Visa notifieringsmeddelanden"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:65
 msgid "Show when window is closed"
 msgstr "Visa när fönster är stängt"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:53
+#: ../glade/smuxi-frontend-gnome.glade.h:66
 msgid "Show when window is minimized"
 msgstr "Visa när fönster är minimerat"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:54
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:406
-msgid "Smuxi - Preferences"
-msgstr "Smuxi - Egenskaper"
-
-#: ../glade/smuxi-frontend-gnome.glade.h:55
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:26
+#: ../glade/smuxi-frontend-gnome.glade.h:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:16
 msgid "Smuxi - Server"
 msgstr "Smuxi - Server"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:56
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:828
+#: ../glade/smuxi-frontend-gnome.glade.h:68
+msgid "Smuxi Preferences"
+msgstr "Alternativ för Smuxi"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:69
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:628
 msgid "Strip Colors"
 msgstr "Kasta färger"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:57
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:867
+#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:667
 msgid "Strip Formattings"
 msgstr "Kasta formateringar"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:58
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:907
+#: ../glade/smuxi-frontend-gnome.glade.h:71
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:707
 msgid "Strip UTF-8"
 msgstr "Kasta UTF-8"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:59
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1222
+#: ../glade/smuxi-frontend-gnome.glade.h:72
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1022
 msgid "Tabs"
 msgstr "Flikar"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:60
-msgid "The nickname to use. You can specify extra nicknames (separated by spaces) which will be used as fallbacks when the first choice is not available. By default $nick_ and $nick__ will be used as fallbacks."
-msgstr "Smeknamn att använda. Du kan ange flera smeknamn (separerade med mellanslag) som ska användas som alternativ om det första valet inte är ledigt. Standardalternativ är $nick_ och $nick__."
+#: ../glade/smuxi-frontend-gnome.glade.h:73
+msgid ""
+"The nickname to use. You can specify extra nicknames (separated by spaces) "
+"which will be used as fallbacks when the first choice is not available. By "
+"default $nick_ and $nick__ will be used as fallbacks."
+msgstr ""
+"Smeknamn att använda. Du kan ange flera smeknamn (separerade med mellanslag)"
+" som ska användas som alternativ om det första valet inte är ledigt. "
+"Standardalternativ är $nick_ och $nick__."
 
-#: ../glade/smuxi-frontend-gnome.glade.h:61
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:726
+#: ../glade/smuxi-frontend-gnome.glade.h:74
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:526
 msgid "Timestamp Format:"
 msgstr "Format för tidsstämpel:"
 
 #. Container child vbox6.Gtk.Box+BoxChild
 #. Container child vbox11.Gtk.Box+BoxChild
-#: ../glade/smuxi-frontend-gnome.glade.h:62
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:943
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:967
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1420
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1446
+#: ../glade/smuxi-frontend-gnome.glade.h:75
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:743
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:767
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1220
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1246
 msgid "Top"
 msgstr "Topp"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:63
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:515
+#: ../glade/smuxi-frontend-gnome.glade.h:76
+msgid "Type:"
+msgstr "Typ:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:315
 msgid "Username:"
 msgstr "Användarnamn:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:64
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1881
+#: ../glade/smuxi-frontend-gnome.glade.h:78
+msgid "Volatile Buffer Lines:"
+msgstr "Flyktiga buffer-rader:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:79
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1681
 msgid "_Filters"
 msgstr "_Filter"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:65
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1723
+#: ../glade/smuxi-frontend-gnome.glade.h:80
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1523
 msgid "_Interface"
 msgstr "_Gränssnitt"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:66
+#: ../glade/smuxi-frontend-gnome.glade.h:81
 msgid "_Logging"
 msgstr "_Loggning"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:67
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1789
+#: ../glade/smuxi-frontend-gnome.glade.h:82
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1589
 msgid "_Servers"
 msgstr "_Servrar"
 
-#. This is a setting for character based line wrapping vs word based when showing messages
-#: ../glade/smuxi-frontend-gnome.glade.h:69
+#. This is a setting for character based line wrapping vs word based when
+#. showing messages
+#: ../glade/smuxi-frontend-gnome.glade.h:84
 msgid "_Wrap Mode:"
 msgstr "_Läge för radbrytning:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../glade/smuxi-frontend-gnome.glade.h:85
 msgid ""
 "ss = seconds\n"
 "mm = minutes\n"
@@ -382,47 +448,45 @@ msgstr ""
 "MM = månad\n"
 "yy/yyyy = år"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:52
-msgid "translator-credits"
-msgstr "Martin Bagge <brother at bsnet.se>"
-
-#: ../src/Frontend-GNOME/AboutDialog.cs:47
-msgid "German"
-msgstr "German"
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:1
+msgid "Chat with other people on IRC"
+msgstr "Chatta med andra människor på IRC"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:48
-msgid "Spanish"
-msgstr "Spanish"
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:2
+msgid "IRC Chat"
+msgstr "IRC chatt"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:49
-msgid "British English"
-msgstr "British English"
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:3
+msgid "Smuxi"
+msgstr "Smuxi"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:50
-msgid "French"
-msgstr "French"
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:4
+msgid "Smuxi IRC Client"
+msgstr "Smuxi IRC-klient"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:51
-msgid "Italian"
-msgstr "Italian"
+#: ../src/Frontend-GNOME/AboutDialog.cs:60
+msgid "translator-credits"
+msgstr "Martin Bagge <brother at bsnet.se>"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:54
+#: ../src/Frontend-GNOME/AboutDialog.cs:65
 msgid "Smuxi Website"
 msgstr "Smuxis webbplats"
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:44
+#: ../src/Frontend-GNOME/CrashDialog.cs:46
 msgid "Oops, I did it again..."
 msgstr "Oj. Nu gjorde vi sådär igen ja..."
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:57
+#: ../src/Frontend-GNOME/CrashDialog.cs:59
 msgid "Smuxi crashed because an unhandled exception was thrown!"
 msgstr "Smuxi krashade på grund av ett ohanterat fel."
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:61
+#: ../src/Frontend-GNOME/CrashDialog.cs:63
 msgid "Here is the stacktrace, please report this bug!"
-msgstr "Kan du vara bussig och rapportera denna bugg. Ta med utskriften från kraschen i felrapporten!"
+msgstr ""
+"Kan du vara bussig och rapportera denna bugg. Ta med utskriften från "
+"kraschen i felrapporten!"
 
-#: ../src/Frontend-GNOME/CrashDialog.cs:81
+#: ../src/Frontend-GNOME/CrashDialog.cs:83
 msgid "_Report Bug"
 msgstr "_Rapportera fel"
 
@@ -430,146 +494,157 @@ msgstr "_Rapportera fel"
 msgid "Engine Manager"
 msgstr "Motorhanterare"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:68
-msgid "_Connect"
-msgstr "_Anslut"
-
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:78
-msgid "_Edit"
-msgstr "_Redigera"
-
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:90
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:80
 msgid "Select which Smuxi engine you want to connect to"
 msgstr "Ange vilken Smuximotor du vill ansluta till"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:96
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:86
 msgid "Engine:"
 msgstr "Motor:"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:122
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:182
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:359
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:97
+msgid "Use Low Bandwidth Mode"
+msgstr "Använd låg bandbreddsläge"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:121
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:181
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:358
 msgid "Local Engine"
 msgstr "Lokal motor:"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:174
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:173
 msgid "Please select an engine!"
 msgstr "Välj en motor!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:195
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:194
 #, csharp-format
 msgid "Your frontend version ({0}) does not match the engine version ({1})!"
-msgstr "Versionen för din framdel ({0}) stämmer inte överrens med motorns version ({1})!"
+msgstr ""
+"Versionen för din framdel ({0}) stämmer inte överrens med motorns version "
+"({1})!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:222
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:221
 msgid "An error occurred while connecting to the engine!"
 msgstr "Ett fel uppstod vid anslutning till motorn!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:223
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:222
 #, csharp-format
 msgid "Engine URL: {0}"
 msgstr "URL till motorn: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:226
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:225
 #, csharp-format
 msgid "Error: {0}"
 msgstr "Fel: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:296
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:295
 #, csharp-format
 msgid "Are you sure you want to delete the engine \"{0}\"?"
 msgstr "Är du säker på att du vill radera motorn \"{0}\"?"
 
-#: ../src/Frontend-GNOME/Entry.cs:403
+#: ../src/Frontend-GNOME/Entry.cs:443
 #, csharp-format
 msgid "You are going to paste {0} lines. Do you want to continue?"
 msgstr "Du kommer att klistra in {0} rader. Vill du fortsätta?"
 
 #. TRANSLATOR: this line is used as a label / category for a
 #. list of commands below
-#: ../src/Frontend-GNOME/Entry.cs:506
+#: ../src/Frontend-GNOME/Entry.cs:547
 msgid "Frontend Commands"
 msgstr "Kommandon för framdelen"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:186
+#: ../src/Frontend-GNOME/MainWindow.cs:252
 msgid "_File"
 msgstr "_Arkiv"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:202
+#: ../src/Frontend-GNOME/MainWindow.cs:276
 msgid "_Server"
 msgstr "_Server"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:206
+#: ../src/Frontend-GNOME/MainWindow.cs:280
 msgid "_Quick Connect"
 msgstr "Snabb _anslutning"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:217
+#: ../src/Frontend-GNOME/MainWindow.cs:291
 msgid "_Manage"
 msgstr "_Hantera"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:224
+#: ../src/Frontend-GNOME/MainWindow.cs:298
 msgid "_Chat"
 msgstr "_Chatt"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:228
+#: ../src/Frontend-GNOME/MainWindow.cs:302
 msgid "Open / Join Chat"
 msgstr "Öppna / Anslut till chatt"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:233
+#: ../src/Frontend-GNOME/MainWindow.cs:308
 msgid "_Find Group Chat"
 msgstr "_Hitta gruppchatt"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:238
+#: ../src/Frontend-GNOME/MainWindow.cs:314
 msgid "C_lear All Activity"
 msgstr "_Rensa all aktivitet"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:245
+#: ../src/Frontend-GNOME/MainWindow.cs:321
 msgid "_Next Chat"
 msgstr "_Nästa chatt"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:255
+#: ../src/Frontend-GNOME/MainWindow.cs:335
 msgid "_Previous Chat"
 msgstr "_Föregående chatt"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:307
+#: ../src/Frontend-GNOME/MainWindow.cs:389
+msgid "Open Log"
+msgstr "Öppna logg"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:407
 msgid "_Engine"
 msgstr "_Motor"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:311
+#: ../src/Frontend-GNOME/MainWindow.cs:411
 msgid "_Use Local Engine"
 msgstr "_Använd lokal motor"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:317
+#: ../src/Frontend-GNOME/MainWindow.cs:417
 msgid "_Add Remote Engine"
 msgstr "_Lägg till fjärrmotor"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:322
+#: ../src/Frontend-GNOME/MainWindow.cs:422
 msgid "_Switch Remote Engine"
 msgstr "_Byt fjärrmotor"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:329
+#: ../src/Frontend-GNOME/MainWindow.cs:429
 msgid "_View"
 msgstr "_Visa"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:333
+#: ../src/Frontend-GNOME/MainWindow.cs:433
 msgid "_Caret Mode"
 msgstr "_Markörläge"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:343
+#: ../src/Frontend-GNOME/MainWindow.cs:445
+msgid "_Browse Mode"
+msgstr "Visningsläge"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:463
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:722
+msgid "Show _Menubar"
+msgstr "Visa Menu"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:494
 msgid "_Help"
 msgstr "_Hjälp"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:567
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:222
+#: ../src/Frontend-GNOME/MainWindow.cs:768
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:225
 msgid "Unable to add server: "
 msgstr "Kan inte lägga till server:"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:614
+#: ../src/Frontend-GNOME/MainWindow.cs:828
 #, csharp-format
 msgid "Unknown ChatType: {0}"
 msgstr "Okänd chattyp: {0}"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:822
+#: ../src/Frontend-GNOME/MainWindow.cs:1097
 msgid ""
 "Switching to local engine will disconnect you from the current engine!\n"
 "Are you sure you want to do this?"
@@ -577,7 +652,7 @@ msgstr ""
 "Byte till lokal motor kommer att koppla bort dig från den aktuella motorn!\n"
 "Är du säker på att du vill göra detta?"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:864
+#: ../src/Frontend-GNOME/MainWindow.cs:1139
 msgid ""
 "Switching the remote engine will disconnect you from the current engine!\n"
 "Are you sure you want to do this?"
@@ -590,59 +665,72 @@ msgid "Sorry, not implemented yet!"
 msgstr "Ursäkta, detta är inte implementerat än!"
 
 #. fill ListStore
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:162
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:179
 msgid "Character"
 msgstr "Tecken"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:163
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:180
 msgid "Word"
 msgstr "Ord"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:173
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:139
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:197
+msgid "Volatile"
+msgstr "Flyktig"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:199
+msgid "Persistent"
+msgstr "Beständig"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:222
+msgid "No Proxy"
+msgstr "Ingen Proxy"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:224
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:307
+msgid "System Default"
+msgstr "Systemstandard"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:238
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:140
 msgid "Connection"
 msgstr "Anslutning"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:177
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:242
 msgid "Interface"
 msgstr "Gränssnitt."
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:181
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:246
 msgid "Servers"
 msgstr "Servrar"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:185
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:253
 msgid "Filters"
 msgstr "Filter"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:189
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:257
 msgid "Logging"
 msgstr "Loggning"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:238
-msgid "System Default"
-msgstr "Systemstandard"
-
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:505
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:642
 msgid "Nicknames(s) field must not be empty."
 msgstr "Fältet för smeknamn kan inte lämnas tomt."
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:649
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:823
 #, csharp-format
 msgid "Invalid highlight regex: '{0}'. Reason: {1}"
 msgstr "Ogiltigt mönster för framhävande: \"{0}\". Anledning: {1}"
 
-#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:69
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:105
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:81
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:106
 #: ../src/Frontend-GNOME/Views/FilterListWidget.cs:271
 msgid "Name"
 msgstr "Namn"
 
-#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:74
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:86
 msgid "Topic"
 msgstr "Rubrik"
 
-#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:102
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:115
 msgid ""
 "Searching for group chats without a filter is not recommended.  This may take a while, or may not work at all.\n"
 "Do you wish to continue?"
@@ -650,16 +738,25 @@ msgstr ""
 "Sökning efter gruppchattar utan att använda filter är inte rekomenderat. Det kan ta lång tid eller inte fungera alls.\n"
 "Vill du verkligen fortsätta?"
 
-#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:143
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:156
 msgid "Error while fetching the list of group chats from the server."
 msgstr "Fel vid hämtning av lista för gruppchattar från servern."
 
-#: ../src/Frontend-GNOME/Frontend.cs:394
+#: ../src/Frontend-GNOME/Frontend.cs:325
+msgid "Disconnected from engine."
+msgstr "Frånkopplad från motorn."
+
+#: ../src/Frontend-GNOME/Frontend.cs:368
+#, csharp-format
+msgid "Reconnecting to engine... (attempt {0})"
+msgstr "Återkopplar till motorn... (försök {0})"
+
+#: ../src/Frontend-GNOME/Frontend.cs:465
 #, csharp-format
 msgid "Cause: {0}"
 msgstr "Anledning: {0}"
 
-#: ../src/Frontend-GNOME/Frontend.cs:464
+#: ../src/Frontend-GNOME/Frontend.cs:583
 msgid ""
 "The frontend has lost the connection to the server.\n"
 "Do you want to reconnect now?"
@@ -667,7 +764,7 @@ msgstr ""
 "Framdelen tappade anslutningen till server.\n"
 "Vill du återansluta?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:479
+#: ../src/Frontend-GNOME/Frontend.cs:602
 msgid ""
 "Reconnecting to the server has failed.\n"
 "Do you want to try again?"
@@ -675,7 +772,7 @@ msgstr ""
 "Återanslutningsförsöket fungerade inte.\n"
 "Vill du försöka igen?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:580
+#: ../src/Frontend-GNOME/Frontend.cs:705
 msgid ""
 "The server has lost the connection to the frontend.\n"
 "Do you want to reconnect now?"
@@ -683,6 +780,10 @@ msgstr ""
 "Servern har tappat anslutningen till framdelen.\n"
 "Vill du återansluta?"
 
+#: ../src/Frontend-GNOME/NotifyManager.cs:267
+msgid "Show"
+msgstr "Visa"
+
 #: ../src/Frontend-GNOME/QuickConnectDialog.cs:62
 #: ../src/Frontend-GNOME/Views/FilterListWidget.cs:238
 #: ../src/Frontend-GNOME/Preferences/ServerListView.cs:70
@@ -708,35 +809,41 @@ msgstr "Person / Privat"
 msgid "Group / Public"
 msgstr "Grupp / Publikt"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:70
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:71
 msgid "Engine Assistant - Smuxi"
 msgstr "Motorassistent - Smuxi"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:92
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:93
 msgid "Add Smuxi Engine"
 msgstr "Lägg till Smuxi-motor"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:94
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:95
 msgid "Edit Smuxi Engine"
 msgstr "Redigera Smuxi-motor"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:203
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:204
 msgid "Credentials"
 msgstr "Inloggningsuppgifter"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:265
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:284
 msgid "Now you can use the Smuxi Engine"
 msgstr "Nu kan du använda Smuxi-motorn"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:268
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:287
 msgid "Thank you"
 msgstr "Tack"
 
-#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:285
-msgid "An engine with this name already exists! Please specify a different one."
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:304
+msgid ""
+"An engine with this name already exists! Please specify a different one."
 msgstr "En motor med detta namn finns reda. Ange ett annat."
 
-#: ../src/Frontend-GNOME/Views/MessageTextView.cs:182
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:204
+#, csharp-format
+msgid "Day changed from {0} to {1}"
+msgstr "Dag ändrades från {0} till {1}"
+
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:210
 #, csharp-format
 msgid "Day changed to {0}"
 msgstr "Dygnsskifte, {0}"
@@ -775,21 +882,25 @@ msgstr "Typ"
 msgid "Pattern"
 msgstr "Mönster"
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:241
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:506
+msgid "Low Bandwidth Mode is active: no messages synced."
+msgstr "Låg bandbreddsläge är aktiverat: inga meddelanden synkroniserade."
+
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:245
 #, csharp-format
 msgid "Retrieving user list for {0}..."
 msgstr "Hämtar användarlistan för {0}..."
 
 #. TRANSLATOR: this string will be appended to the one above
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:286
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:279
 msgid "done."
 msgstr "klar"
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:301
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:290
 msgid "Person"
 msgstr "Person"
 
-#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:68
+#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:69
 msgid ""
 "Closing the protocol chat will also close all open chats connected to it!\n"
 "Are you sure you want to do this?"
@@ -797,145 +908,187 @@ msgstr ""
 "När protokollchatten stängs kommer även alla öppna chattar som är anslutna till den att stängas!\n"
 "Är du säker på att du vill göra detta?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:184
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:187
 msgid "Are you sure you want to delete the selected server?"
 msgstr "Är du säker på att du vill radera den valda servern?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:240
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:274
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:243
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:277
 msgid "Unable to edit server: "
 msgstr "Kan inte redigera server:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:42
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:24
 msgid "Find"
 msgstr "Sök"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:62
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:44
 msgid "_Search for:"
 msgstr "_Leta efter:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:91
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:73
 msgid "_Match Case"
 msgstr "S_kiftlägeskänslig"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:103
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:85
 msgid "Search _Backwards"
 msgstr "Sök bakåt"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:115
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:97
 msgid "_Wrap Around"
 msgstr "Börja _om från början"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:128
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:110
 msgid "Use _Regular Expressions"
 msgstr "Använd _reguljära uttryck"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:40
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:23
 msgid "Smuxi - Find Group Chat"
 msgstr "Smuxi - Hitta gruppchatt"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:64
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:87
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:73
 msgid "_Name:"
 msgstr "_Namn:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:19
 msgid "Smuxi - Quick Connect"
 msgstr "Smuxi - Snabbanslutning"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:495
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:206
+msgid "Smuxi - Preferences"
+msgstr "Smuxi - Egenskaper"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:295
 msgid "Nicknames:"
 msgstr "Smeknamn:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1630
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1430
 msgid "<b> User List Position </b>"
 msgstr "<b> Position för användarlista</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1641
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1441
 msgid "<b> Channel </b>"
 msgstr "<b> Kanal</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1852
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1652
 msgid "<b>Channel Filters</b>"
 msgstr "<b>Kanalfilter</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1869
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1669
 msgid "<b>User Filters</b>"
 msgstr "<b>Användarfilter</b>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:64
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:42
 msgid "Use _SSH Tunnel"
 msgstr "_Använd SSH-Tunnel"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:78
-msgid "<span size=\"small\">Enables the use of SSH for the connection.  This has a small performance impact, but is more secure and required when using NAT or port-based firewalls</span>"
-msgstr "<span size=\"small\">Aktiverar användning av SSH för anslutningen. Detta kan innebära en liten negativ inverka på hastigheten men är säkrare och krävs när NAT eller port-baserade brändväggar används</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:56
+msgid ""
+"<span size=\"small\">Enables the use of SSH for the connection.  This has a "
+"small performance impact, but is more secure and required when using NAT or "
+"port-based firewalls</span>"
+msgstr ""
+"<span size=\"small\">Aktiverar användning av SSH för anslutningen. Detta kan"
+" innebära en liten negativ inverka på hastigheten men är säkrare och krävs "
+"när NAT eller port-baserade brändväggar används</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:157
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:135
 msgid "SSH _Host:"
 msgstr "SS_H-värd:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:168
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:146
 msgid "<span size=\"small\">DNS or IP address and port of the SSH server</span>"
 msgstr "<span size=\"small\">DNS eller IP-adress och port för SSH-servern</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:181
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:195
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:154
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:159
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:173
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:129
 msgid "_Port:"
 msgstr "_Port"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:208
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:186
 msgid "<span size=\"small\">DNS or IP address and port of the Smuxi server</span>"
-msgstr "<span size=\"small\">DNS eller IP-adress och port för Smuxi-servern</span>"
+msgstr ""
+"<span size=\"small\">DNS eller IP-adress och port för Smuxi-servern</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:221
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:199
 msgid "_Smuxi Host:"
 msgstr "Smuxi-_värd;"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:76
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:52
 msgid "_SSH Username: (optional)"
 msgstr "_SSH-avnändarnamn: (valbart)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:99
-msgid "<span size=\"small\">Username which will be used to log into the SSH server</span>"
-msgstr "<span size=\"small\">Användarnamn som ska användas för att logga in i SSH-servern</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:75
+msgid ""
+"<span size=\"small\">Username which will be used to log into the SSH "
+"server</span>"
+msgstr ""
+"<span size=\"small\">Användarnamn som ska användas för att logga in i SSH-"
+"servern</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:119
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:95
 msgid "_SSH Password: (optional)"
 msgstr "SSH-_lösenord: (valbart)"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:143
-msgid "<span size=\"small\">Password which will be used to log into the SSH server. The password is optional if SSH key authorization is used (via Pageant from the PuTTY tools).</span>"
-msgstr "<span size=\"small\">Lösenord för att logga in i SSH-servern. Lösenordet är valbart om användarverifiering kan ske via SSH-nyckel (via Pageant i PuTTY-verktygen).</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:119
+msgid ""
+"<span size=\"small\">Password which will be used to log into the SSH server."
+" The password is optional if SSH key authorization is used (see "
+"below).</span>"
+msgstr ""
+"<span size=\"small\">Lösenord som kommer användas att logga in till SSH-"
+"servern. Lösenordet är valfritt om SSH nyckel-auktorisation används (se "
+"nedan).</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:140
+msgid "_SSH Keyfile: (optional)"
+msgstr "_SSH nyckelfil: (valfri)"
+
+#. Container child vbox17.Gtk.Box+BoxChild
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:148
+msgid "Select a File"
+msgstr "Välj en fil"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:161
+msgid ""
+"<span size=\"small\">SSH private keyfile which will be used to log into the "
+"SSH server</span>"
+msgstr ""
+"<span size=\"small\">SSH privat nyckelfil att användas för att logga in på "
+"SSH-servern</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:164
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:223
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:181
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:188
 msgid "_Username:"
 msgstr "_Användarnamn:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:187
-msgid "<span size=\"small\">Username which will be used to log into the Smuxi server</span>"
-msgstr "<span size=\"small\">Användarnamnet som ska användas för att logga in i Smuxi-server</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:204
+msgid ""
+"<span size=\"small\">Username which will be used to log into the Smuxi "
+"server</span>"
+msgstr ""
+"<span size=\"small\">Användarnamnet som ska användas för att logga in i "
+"Smuxi-server</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:207
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:233
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:224
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:87
 msgid "_Password:"
 msgstr "_Lösenord:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:231
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:248
 msgid "<span size=\"small\">Password of the user</span>"
 msgstr "<span size=\"small\">Lösenord för användaren</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:251
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:268
 msgid "_Verify Password:"
 msgstr "_Verifiera lösenord:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:275
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:292
 msgid "<span size=\"small\">Repeat the password for verification</span>"
 msgstr "<span size=\"small\">Upprepa lösenordet för att verifiera det</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs:27
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs:19
 msgid ""
 "Welcome to the Smuxi Engine Configuration Assistant.\n"
 "You need to enter some information before you can use the engine.\n"
@@ -947,60 +1100,64 @@ msgstr ""
 "\n"
 "Klicka \"Nästa\" för att böja."
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:52
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:36
 msgid "_Engine Name:"
 msgstr "_Motornamn:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:75
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:59
 msgid "<span size=\"small\">Profile name of the new engine</span>"
 msgstr "<span size=\"small\">Profilnamn för den nya motorn</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:96
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:80
 msgid "_Default Engine:"
 msgstr "_Standardmotor:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:107
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:91
 msgid "Use as new default engine"
 msgstr "Använd som ny standardmotor"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:120
-msgid "<span size=\"small\">If enabled, the current engine will be the default next time Smuxi is started</span>"
-msgstr "<span size=\"small\">Om detta väljs kommer den aktuella motorn att bli standardmotor nästa gång Smuxi startas</span>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:104
+msgid ""
+"<span size=\"small\">If enabled, the current engine will be the default next"
+" time Smuxi is started</span>"
+msgstr ""
+"<span size=\"small\">Om detta väljs kommer den aktuella motorn att bli "
+"standardmotor nästa gång Smuxi startas</span>"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:20
 msgid "Smuxi - Open Chat"
 msgstr "Smuxi - Öppen hatt"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:63
 msgid "_Type:"
 msgstr "_Typ:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:95
-msgid "_Network:"
-msgstr "_Nätverk:"
-
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:213
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:54
 msgid "_Hostname:"
 msgstr "_Värdnamn:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:243
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:75
+msgid "_Network:"
+msgstr "_Nätverk:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:198
 msgid "_Protocol:"
 msgstr "P_rotokoll:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:262
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:222
+msgid "Use Encryption"
+msgstr "Använd kryptering"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:234
+msgid "Validate Server Certificate"
+msgstr "Validera serverns certifikat"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:254
 msgid "_On Connect Commands:"
 msgstr "_Kommando vid anslutning:"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:273
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:265
 msgid "_Ignore Commands"
 msgstr "Kommando att _ignorera"
 
-#~ msgid "Joins"
-#~ msgstr "Anslutningar"
-#~ msgid "Parts"
-#~ msgstr "Lämnar"
-#~ msgid "Quits"
-#~ msgstr "Kopplar från"
-#~ msgid "Unknown Command: {0}"
-#~ msgstr "Okänt kommando: {0}"
 
diff --git a/po-Frontend-GNOME/zh_CN.po b/po-Frontend-GNOME/zh_CN.po
new file mode 100644
index 0000000..4962415
--- /dev/null
+++ b/po-Frontend-GNOME/zh_CN.po
@@ -0,0 +1,1141 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:22+0100\n"
+"PO-Revision-Date: 2010-11-30 04:12+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: Chinese (China) (http://www.transifex.net/projects/p/smuxi/team/zh_CN/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: zh_CN\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:1
+msgid "<b> Chat </b>"
+msgstr "<b> 聊天 </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:2
+msgid "<b> Color </b>"
+msgstr "<b> 颜色 </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:3
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1172
+msgid "<b> Entry Field </b>"
+msgstr "<b> 预留字段 </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:4
+msgid "<b> Font </b>"
+msgstr "<b> 字体 </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:5
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1502
+msgid "<b> Highlighting </b>"
+msgstr "<b> 高亮 </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:6
+msgid "<b> Notification Area Icon </b>"
+msgstr "<b> 通知区域图标 </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:7
+msgid "<b> Person List Position </b>"
+msgstr "<b> 成员列表位置 </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:8
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1009
+msgid "<b> Tab Colors </b>"
+msgstr "<b> 标签颜色 </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:9
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:910
+msgid "<b> Tabs Position </b>"
+msgstr "<b> 标签位置 </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:10
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1315
+msgid "<b> Topic Position </b>"
+msgstr "<b> 主题位置 </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:11
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:12
+msgid "<b>General</b>"
+msgstr "<b>全局</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:13
+msgid "<b>Global Commands</b>"
+msgstr "<b>全局命令</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:14
+msgid "<b>Message Buffer</b>"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:15
+msgid "<b>Messaging Menu</b>"
+msgstr "<b>消息菜单</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:16
+msgid "<b>Network Proxy</b>"
+msgstr "<b>网络代理</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:17
+msgid "<b>Notification Popups</b>"
+msgstr "<b>通知弹出</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:18
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:961
+msgid "Activity"
+msgstr "活动"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:19
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:209
+msgid "Automatically connect to server at startup"
+msgstr "启动时自动连接到服务器"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:20
+msgid "Background"
+msgstr "背景"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:21
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1160
+msgid "Bash-Style Completion"
+msgstr "Bash 式完成"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:22
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1490
+msgid "Beep on highlight"
+msgstr "高亮时鸣叫"
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:23
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:780
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:802
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1261
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1286
+msgid "Bottom"
+msgstr "底部"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:24
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:546
+msgid "Buffer Lines:"
+msgstr "缓冲行数:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:25
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:471
+msgid "C_onnection"
+msgstr "连接(_O)"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:26
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1112
+msgid "Command Character:"
+msgstr "命令字符:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:27
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1135
+msgid "Command History Size:"
+msgstr "命令历史数:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:28
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1092
+msgid "Completion Character:"
+msgstr "完成字符:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:29
+msgid "Enable"
+msgstr "启用"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:30
+msgid "Enabled"
+msgstr "启用"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:31
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:359
+msgid "Encoding:"
+msgstr "编码:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:32
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:569
+msgid "Engine Buffer Lines:"
+msgstr "引擎缓冲行数:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:33
+msgid "Foreground"
+msgstr "前景"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:725
+msgid "General"
+msgstr "全局"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:35
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:981
+msgid "Highlight"
+msgstr "高亮"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:36
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1466
+msgid "Highlight words:"
+msgstr "高亮单词:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:37
+msgid "Host:"
+msgstr "主机:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:38
+msgid "Hostname:"
+msgstr "主机名:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:39
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
+msgid "Input"
+msgstr "输入"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:40
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:971
+msgid "Join/Part/Mode"
+msgstr "加入/离开/模式"
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:41
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:816
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:841
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1335
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1361
+msgid "Left"
+msgstr "左边"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:42
+msgid "Log Filtered Messages"
+msgstr "记录经过滤的消息"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:43
+msgid "Network:"
+msgstr "网络:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:44
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1202
+msgid "Nick Colors"
+msgstr "昵称颜色"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:45
+msgid "Nickname(s):"
+msgstr "昵称:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:46
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:953
+msgid "No Activity"
+msgstr "无活动"
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:896
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1301
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1416
+msgid "None"
+msgstr "æ— "
+
+#: ../glade/smuxi-frontend-gnome.glade.h:48
+msgid "Notification"
+msgstr "通知"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:49
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:381
+msgid "On Connect Commands:"
+msgstr "连接时命令:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:50
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:427
+msgid "On Startup Commands:"
+msgstr "启动时命令:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:51
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1514
+msgid "Output"
+msgstr "输出"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:52
+msgid "Override"
+msgstr "覆盖"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:53
+msgid "Password:"
+msgstr "密码:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:54
+msgid "Persistency Type:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:55
+msgid "Persistent Buffer Lines:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:56
+msgid "Port:"
+msgstr "端口:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:57
+msgid "Protocol:"
+msgstr "协议:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:58
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:338
+msgid "Realname:"
+msgstr "真名:"
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:59
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:856
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:881
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1376
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1401
+msgid "Right"
+msgstr "右边"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:60
+msgid "Show Advanced Settings"
+msgstr "显示高级设置"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:61
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:170
+msgid "Show Password"
+msgstr "显示密码"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:62
+msgid "Show Smuxi in the messaging menu"
+msgstr "在消息菜单中显示 Smuxi"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:63
+msgid "Show always"
+msgstr "总是显示"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:64
+msgid "Show notification popups"
+msgstr "显示通知弹出"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:65
+msgid "Show when window is closed"
+msgstr "当窗口关闭时显示"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:66
+msgid "Show when window is minimized"
+msgstr "当窗口最小化时显示"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:16
+msgid "Smuxi - Server"
+msgstr "Smuxi - 服务器"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:68
+msgid "Smuxi Preferences"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:69
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:628
+msgid "Strip Colors"
+msgstr "去除颜色"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:667
+msgid "Strip Formattings"
+msgstr "去除格式"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:71
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:707
+msgid "Strip UTF-8"
+msgstr "去除 UTF-8"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:72
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1022
+msgid "Tabs"
+msgstr "标签"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:73
+msgid ""
+"The nickname to use. You can specify extra nicknames (separated by spaces) "
+"which will be used as fallbacks when the first choice is not available. By "
+"default $nick_ and $nick__ will be used as fallbacks."
+msgstr "要使用的昵称。您可以指定多个昵称(用空格分隔)作为首个选项不可用时的候选项。默认使用 $昵称_ 和 $昵称__ 作为候选项。"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:74
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:526
+msgid "Timestamp Format:"
+msgstr "时间戳格式:"
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:75
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:743
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:767
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1220
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1246
+msgid "Top"
+msgstr "顶部"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:76
+msgid "Type:"
+msgstr "类型:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:315
+msgid "Username:"
+msgstr "用户名:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:78
+msgid "Volatile Buffer Lines:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:79
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1681
+msgid "_Filters"
+msgstr "过滤器(_F)"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:80
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1523
+msgid "_Interface"
+msgstr "界面(_I)"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:81
+msgid "_Logging"
+msgstr "历史(_L)"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:82
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1589
+msgid "_Servers"
+msgstr "服务器(_S)"
+
+#. This is a setting for character based line wrapping vs word based when
+#. showing messages
+#: ../glade/smuxi-frontend-gnome.glade.h:84
+msgid "_Wrap Mode:"
+msgstr "_自动换行模式:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:85
+msgid ""
+"ss = seconds\n"
+"mm = minutes\n"
+"hh = hours (01 - 12)\n"
+"HH = hours (00 - 23)\n"
+"tt = AM/PM\n"
+"\n"
+"dd = day\n"
+"MM = month\n"
+"yy/yyyy = year"
+msgstr ""
+"ss = 秒数\n"
+"mm = 分数\n"
+"hh = 小时数 (01 - 12)\n"
+"HH = 小时数 (00 - 23)\n"
+"tt = AM/PM\n"
+"\n"
+"dd = day\n"
+"MM = month\n"
+"yy/yyyy = year"
+
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:1
+msgid "Chat with other people on IRC"
+msgstr "和 IRC 上的其他人聊天"
+
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:2
+msgid "IRC Chat"
+msgstr "IRC 聊天"
+
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:3
+msgid "Smuxi"
+msgstr ""
+
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:4
+msgid "Smuxi IRC Client"
+msgstr "Smuxi IRC 客户端"
+
+#: ../src/Frontend-GNOME/AboutDialog.cs:60
+msgid "translator-credits"
+msgstr "Dean Lee <xslidian+smuxi at gmail.com>"
+
+#: ../src/Frontend-GNOME/AboutDialog.cs:65
+msgid "Smuxi Website"
+msgstr "Smuxi 网站"
+
+#: ../src/Frontend-GNOME/CrashDialog.cs:46
+msgid "Oops, I did it again..."
+msgstr "Oops,我又做了一次..."
+
+#: ../src/Frontend-GNOME/CrashDialog.cs:59
+msgid "Smuxi crashed because an unhandled exception was thrown!"
+msgstr "Smuxi 崩溃了,因为遇到了未处理的意外!"
+
+#: ../src/Frontend-GNOME/CrashDialog.cs:63
+msgid "Here is the stacktrace, please report this bug!"
+msgstr "这是 stacktrace,请报告错误!"
+
+#: ../src/Frontend-GNOME/CrashDialog.cs:83
+msgid "_Report Bug"
+msgstr "报告错误(_R)"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:61
+msgid "Engine Manager"
+msgstr "引擎管理器"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:80
+msgid "Select which Smuxi engine you want to connect to"
+msgstr "选择希望连接到的 Smuxi 引擎"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:86
+msgid "Engine:"
+msgstr "引擎:"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:97
+msgid "Use Low Bandwidth Mode"
+msgstr ""
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:121
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:181
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:358
+msgid "Local Engine"
+msgstr "本地引擎"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:173
+msgid "Please select an engine!"
+msgstr "请选择一个引擎!"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:194
+#, csharp-format
+msgid "Your frontend version ({0}) does not match the engine version ({1})!"
+msgstr "您的前端版本 ({0}) 与引擎版本 ({1}) 不匹配!"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:221
+msgid "An error occurred while connecting to the engine!"
+msgstr "连接到引擎时出现了一个错误!"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:222
+#, csharp-format
+msgid "Engine URL: {0}"
+msgstr "引擎 URL: {0}"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:225
+#, csharp-format
+msgid "Error: {0}"
+msgstr "错误: {0}"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:295
+#, csharp-format
+msgid "Are you sure you want to delete the engine \"{0}\"?"
+msgstr "您确实要删除引擎 \"{0}\" 吗?"
+
+#: ../src/Frontend-GNOME/Entry.cs:443
+#, csharp-format
+msgid "You are going to paste {0} lines. Do you want to continue?"
+msgstr "您正在粘贴 {0} 行。是否继续?"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Frontend-GNOME/Entry.cs:547
+msgid "Frontend Commands"
+msgstr "前端命令"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:252
+msgid "_File"
+msgstr "文件(_F)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:276
+msgid "_Server"
+msgstr "服务器(_S)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:280
+msgid "_Quick Connect"
+msgstr "快速连接(_Q)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:291
+msgid "_Manage"
+msgstr "管理(_M)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:298
+msgid "_Chat"
+msgstr "聊天(_C)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:302
+msgid "Open / Join Chat"
+msgstr "打开 / 加入聊天"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:308
+msgid "_Find Group Chat"
+msgstr "查找群组聊天(_F)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:314
+msgid "C_lear All Activity"
+msgstr "清除所有活动(_L)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:321
+msgid "_Next Chat"
+msgstr "下一个聊天(_N)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:335
+msgid "_Previous Chat"
+msgstr "上一个聊天(_P)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:389
+msgid "Open Log"
+msgstr "打开聊天历史"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:407
+msgid "_Engine"
+msgstr "引擎(_E)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:411
+msgid "_Use Local Engine"
+msgstr "使用本地引擎(_U)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:417
+msgid "_Add Remote Engine"
+msgstr "添加远程引擎(_A)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:422
+msgid "_Switch Remote Engine"
+msgstr "切换远程引擎(_S)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:429
+msgid "_View"
+msgstr "视图(_V)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:433
+msgid "_Caret Mode"
+msgstr "插入模式(_C)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:445
+msgid "_Browse Mode"
+msgstr "浏览模式(_B)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:463
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:722
+msgid "Show _Menubar"
+msgstr "显示菜单栏(_M)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:494
+msgid "_Help"
+msgstr "帮助(_H)"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:768
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:225
+msgid "Unable to add server: "
+msgstr "无法添加服务器: "
+
+#: ../src/Frontend-GNOME/MainWindow.cs:828
+#, csharp-format
+msgid "Unknown ChatType: {0}"
+msgstr "未知聊天类型: {0}"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:1097
+msgid ""
+"Switching to local engine will disconnect you from the current engine!\n"
+"Are you sure you want to do this?"
+msgstr ""
+"切换到本地引擎会将您与当前引擎断开!\n"
+"您确实大赛这样做吗?"
+
+#: ../src/Frontend-GNOME/MainWindow.cs:1139
+msgid ""
+"Switching the remote engine will disconnect you from the current engine!\n"
+"Are you sure you want to do this?"
+msgstr ""
+"切换到远程引擎会将您与当前引擎断开!\n"
+"您确实大赛这样做吗?"
+
+#: ../src/Frontend-GNOME/NotImplementedMessageDialog.cs:40
+msgid "Sorry, not implemented yet!"
+msgstr "抱歉,尚未实现!"
+
+#. fill ListStore
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:179
+msgid "Character"
+msgstr "字符"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:180
+msgid "Word"
+msgstr "单词"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:197
+msgid "Volatile"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:199
+msgid "Persistent"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:222
+msgid "No Proxy"
+msgstr "无代理"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:224
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:307
+msgid "System Default"
+msgstr "系统默认"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:238
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:140
+msgid "Connection"
+msgstr "连接"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:242
+msgid "Interface"
+msgstr "界面"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:246
+msgid "Servers"
+msgstr "服务器"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:253
+msgid "Filters"
+msgstr "过滤器"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:257
+msgid "Logging"
+msgstr "历史"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:642
+msgid "Nicknames(s) field must not be empty."
+msgstr "昵称字段不能为空。"
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:823
+#, csharp-format
+msgid "Invalid highlight regex: '{0}'. Reason: {1}"
+msgstr "高亮正则表达式无效: '{0}'。原因: {1}"
+
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:81
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:106
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:271
+msgid "Name"
+msgstr "名称"
+
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:86
+msgid "Topic"
+msgstr "主题"
+
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:115
+msgid ""
+"Searching for group chats without a filter is not recommended.  This may take a while, or may not work at all.\n"
+"Do you wish to continue?"
+msgstr ""
+"不建议不用过滤器搜索群组聊天。可能要耗费一些时间,也可能无法完成搜索。\n"
+"您是否打算继续?"
+
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:156
+msgid "Error while fetching the list of group chats from the server."
+msgstr "从服务器装载群组聊天列表出错。"
+
+#: ../src/Frontend-GNOME/Frontend.cs:325
+msgid "Disconnected from engine."
+msgstr ""
+
+#: ../src/Frontend-GNOME/Frontend.cs:368
+#, csharp-format
+msgid "Reconnecting to engine... (attempt {0})"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Frontend.cs:465
+#, csharp-format
+msgid "Cause: {0}"
+msgstr "原因: {0}"
+
+#: ../src/Frontend-GNOME/Frontend.cs:583
+msgid ""
+"The frontend has lost the connection to the server.\n"
+"Do you want to reconnect now?"
+msgstr ""
+"前端与服务器之间的连接已丢失。\n"
+"是否希望现在重新连接?"
+
+#: ../src/Frontend-GNOME/Frontend.cs:602
+msgid ""
+"Reconnecting to the server has failed.\n"
+"Do you want to try again?"
+msgstr ""
+"重新连接到服务器失败。\n"
+"是否重试?"
+
+#: ../src/Frontend-GNOME/Frontend.cs:705
+msgid ""
+"The server has lost the connection to the frontend.\n"
+"Do you want to reconnect now?"
+msgstr ""
+"服务器与前端之间的连接已丢失。\n"
+"是否希望现在重新连接?"
+
+#: ../src/Frontend-GNOME/NotifyManager.cs:267
+msgid "Show"
+msgstr "显示"
+
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:62
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:238
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:70
+msgid "Protocol"
+msgstr "协议"
+
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:63
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:71
+msgid "Hostname"
+msgstr "主机名"
+
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:166
+msgid "Unable to load server: "
+msgstr "无法加载服务器: "
+
+#: ../src/Frontend-GNOME/ChatTypeWidget.cs:54
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:244
+msgid "Person / Private"
+msgstr "成员 / 私聊"
+
+#: ../src/Frontend-GNOME/ChatTypeWidget.cs:55
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:245
+msgid "Group / Public"
+msgstr "群组 / 公开"
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:71
+msgid "Engine Assistant - Smuxi"
+msgstr "引擎助手 - Smuxi"
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:93
+msgid "Add Smuxi Engine"
+msgstr "添加 Smuxi 引擎"
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:95
+msgid "Edit Smuxi Engine"
+msgstr "编辑 Smuxi 引擎"
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:204
+msgid "Credentials"
+msgstr "证书"
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:284
+msgid "Now you can use the Smuxi Engine"
+msgstr "现在您可以使用该 Smuxi 引擎了"
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:287
+msgid "Thank you"
+msgstr "谢谢您"
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:304
+msgid ""
+"An engine with this name already exists! Please specify a different one."
+msgstr "已存在同名引擎! 请另外指定一个。"
+
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:204
+#, csharp-format
+msgid "Day changed from {0} to {1}"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:210
+#, csharp-format
+msgid "Day changed to {0}"
+msgstr "日期已改为 {0}"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:123
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:133
+#, csharp-format
+msgid "Invalid filter regex: '{0}'. Reason: {1}"
+msgstr "无效的过滤器正则表达式: '{0}'。原因: {1}"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:200
+msgid "Are you sure you want to delete the selected filter?"
+msgstr "您确实要删除选中的过滤器?"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:246
+msgid "Protocol / Server"
+msgstr "协议 / 服务器"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:253
+msgid "Chat Type"
+msgstr "聊天类型"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:287
+msgid "Normal"
+msgstr "普通"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:288
+msgid "Event"
+msgstr "事件"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:295
+msgid "Type"
+msgstr "类型"
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:321
+msgid "Pattern"
+msgstr "匹配"
+
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:506
+msgid "Low Bandwidth Mode is active: no messages synced."
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:245
+#, csharp-format
+msgid "Retrieving user list for {0}..."
+msgstr "正在检索 {0} 的用户列表..."
+
+#. TRANSLATOR: this string will be appended to the one above
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:279
+msgid "done."
+msgstr "完成。"
+
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:290
+msgid "Person"
+msgstr "成员"
+
+#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:69
+msgid ""
+"Closing the protocol chat will also close all open chats connected to it!\n"
+"Are you sure you want to do this?"
+msgstr ""
+"关闭该协议将同时关闭所有连接到它的开放聊天!\n"
+"您确实希望这么做吗?"
+
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:187
+msgid "Are you sure you want to delete the selected server?"
+msgstr "您确实打算删除选中的服务器吗?"
+
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:243
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:277
+msgid "Unable to edit server: "
+msgstr "无法编辑服务器: "
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:24
+msgid "Find"
+msgstr "查找"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:44
+msgid "_Search for:"
+msgstr "搜索(_S):"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:73
+msgid "_Match Case"
+msgstr "匹配大小写(_M)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:85
+msgid "Search _Backwards"
+msgstr "向上搜索(_B)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:97
+msgid "_Wrap Around"
+msgstr "全文搜索(_W)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:110
+msgid "Use _Regular Expressions"
+msgstr "使用正则表达式(_R)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:23
+msgid "Smuxi - Find Group Chat"
+msgstr "Smuxi - 查找群组聊天"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:73
+msgid "_Name:"
+msgstr "名称(_N):"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:19
+msgid "Smuxi - Quick Connect"
+msgstr "Smuxi - 快速连接"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:206
+msgid "Smuxi - Preferences"
+msgstr "Smuxi - 首选项"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:295
+msgid "Nicknames:"
+msgstr "昵称:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1430
+msgid "<b> User List Position </b>"
+msgstr "<b> 用户列表位置 </b>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1441
+msgid "<b> Channel </b>"
+msgstr "<b> 频道 </b>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1652
+msgid "<b>Channel Filters</b>"
+msgstr "<b>频道过滤器</b>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1669
+msgid "<b>User Filters</b>"
+msgstr "<b>用户过滤器</b>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:42
+msgid "Use _SSH Tunnel"
+msgstr "使用 _SSH 隧道"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:56
+msgid ""
+"<span size=\"small\">Enables the use of SSH for the connection.  This has a "
+"small performance impact, but is more secure and required when using NAT or "
+"port-based firewalls</span>"
+msgstr ""
+"<span size=\"small\">为连接启用 SSH。这对性能有一定影响,但更安全,且使用 NAT 或者基于端口的防火墙时必需</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:135
+msgid "SSH _Host:"
+msgstr "SS_H 主机:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:146
+msgid "<span size=\"small\">DNS or IP address and port of the SSH server</span>"
+msgstr "<span size=\"small\">SSH 服务器的 DNS 或者 IP 地址与端口</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:159
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:173
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:129
+msgid "_Port:"
+msgstr "端口(_P):"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:186
+msgid "<span size=\"small\">DNS or IP address and port of the Smuxi server</span>"
+msgstr "<span size=\"small\">Smuxi 服务器的 DNS 或者 IP 地址与端口</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:199
+msgid "_Smuxi Host:"
+msgstr "_Smuxi 主机:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:52
+msgid "_SSH Username: (optional)"
+msgstr "_SSH 用户名: (可选)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:75
+msgid ""
+"<span size=\"small\">Username which will be used to log into the SSH "
+"server</span>"
+msgstr "<span size=\"small\">用于登录 SSH 服务器的用户名</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:95
+msgid "_SSH Password: (optional)"
+msgstr "_SSH 密码: (可选)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:119
+msgid ""
+"<span size=\"small\">Password which will be used to log into the SSH server."
+" The password is optional if SSH key authorization is used (see "
+"below).</span>"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:140
+msgid "_SSH Keyfile: (optional)"
+msgstr ""
+
+#. Container child vbox17.Gtk.Box+BoxChild
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:148
+msgid "Select a File"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:161
+msgid ""
+"<span size=\"small\">SSH private keyfile which will be used to log into the "
+"SSH server</span>"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:181
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:188
+msgid "_Username:"
+msgstr "用户名(_U):"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:204
+msgid ""
+"<span size=\"small\">Username which will be used to log into the Smuxi "
+"server</span>"
+msgstr "<span size=\"small\">将用于登录 Smuxi 服务器的用户名</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:224
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:87
+msgid "_Password:"
+msgstr "密码(_P):"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:248
+msgid "<span size=\"small\">Password of the user</span>"
+msgstr "<span size=\"small\">用户密码</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:268
+msgid "_Verify Password:"
+msgstr "验证密码(_V):"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:292
+msgid "<span size=\"small\">Repeat the password for verification</span>"
+msgstr "<span size=\"small\">请再次输入密码以供验证</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs:19
+msgid ""
+"Welcome to the Smuxi Engine Configuration Assistant.\n"
+"You need to enter some information before you can use the engine.\n"
+"\n"
+"Click \"Forward\" to begin."
+msgstr ""
+"欢迎使用 Smuxi 引擎配置助手。\n"
+"在您能够使用引擎之前,需要输入一些信息。\n"
+"\n"
+"点击“前进”开始。"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:36
+msgid "_Engine Name:"
+msgstr "引擎名称(_E):"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:59
+msgid "<span size=\"small\">Profile name of the new engine</span>"
+msgstr "<span size=\"small\">新引擎配置文件的名称</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:80
+msgid "_Default Engine:"
+msgstr "默认引擎(_D):"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:91
+msgid "Use as new default engine"
+msgstr "用作新的默认引擎"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:104
+msgid ""
+"<span size=\"small\">If enabled, the current engine will be the default next"
+" time Smuxi is started</span>"
+msgstr "<span size=\"small\">如果启用,Smuxi 下次启动时当前引擎将作为默认引擎</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:20
+msgid "Smuxi - Open Chat"
+msgstr "Smuxi - 开放聊天"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:63
+msgid "_Type:"
+msgstr "_类型:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:54
+msgid "_Hostname:"
+msgstr "_主机名:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:75
+msgid "_Network:"
+msgstr "_网络:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:198
+msgid "_Protocol:"
+msgstr "_协议:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:222
+msgid "Use Encryption"
+msgstr "使用加密"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:234
+msgid "Validate Server Certificate"
+msgstr "验证服务器证书"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:254
+msgid "_On Connect Commands:"
+msgstr "连接时命令(_O):"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:265
+msgid "_Ignore Commands"
+msgstr "忽略命令(_I)"
+
+
diff --git a/po-Frontend/LINGUAS b/po-Frontend/LINGUAS
index 54679b1..7dadc16 100644
--- a/po-Frontend/LINGUAS
+++ b/po-Frontend/LINGUAS
@@ -9,3 +9,4 @@ fr
 it
 pt
 sv
+zh_CN
diff --git a/po-Frontend/POTFILES.skip b/po-Frontend/POTFILES.skip
index 3862000..74a7646 100644
--- a/po-Frontend/POTFILES.skip
+++ b/po-Frontend/POTFILES.skip
@@ -2,6 +2,7 @@ glade/
 src/Common/
 src/Frontend-GNOME/
 src/Frontend-GNOME-IRC/
+src/Frontend-STFL/
 src/Frontend-SWF/
 src/Frontend-WPF/
 src/Engine/
@@ -11,3 +12,4 @@ src/Engine-OSCAR/
 src/Engine-XMPP/
 src/Engine-Twitter/
 src/Server/
+lib/
diff --git a/po-Frontend/da.po b/po-Frontend/da.po
index f18a132..880840c 100644
--- a/po-Frontend/da.po
+++ b/po-Frontend/da.po
@@ -1,31 +1,43 @@
-# Danish translation smuxi-frontend.
-# Copyright (C) 2010 Mirco Bauer & nedenstående oversættere.
-# This file is distributed under the same license as the smuxi-frontend package.
-# Joe Hansen (joedalton2 at yahoo.dk), 2010.
-#
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Joe Hansen <joedalton2 at yahoo.dk>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: smuxi-frontend\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-22 12:42+0000\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:21+0100\n"
+"PO-Revision-Date: 2011-12-29 20:06+0000\n"
 "Last-Translator: Joe Hansen <joedalton2 at yahoo.dk>\n"
-"Language-Team: Danish <debian-l10n-danish at lists.debian.org>\n"
+"Language-Team: Danish (http://www.transifex.net/projects/p/smuxi/team/da/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: da\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
 #: ../src/Frontend/CommandManager.cs:143
 #, csharp-format
 msgid "Unknown Command: {0}"
 msgstr "Ukendt kommando: {0}"
 
-#: ../src/Frontend/EngineManager.cs:292
+#: ../src/Frontend/EngineManager.cs:122
+msgid "Engine must not be empty."
+msgstr "Motor må ikke være tom."
+
+#: ../src/Frontend/EngineManager.cs:133
+msgid "Engine does not exist."
+msgstr "Motor findes ikke."
+
+#: ../src/Frontend/EngineManager.cs:318
 #, csharp-format
-msgid "Unknown channel ({0}) - only the following channel types are supported:"
+msgid ""
+"Unknown channel ({0}) - only the following channel types are supported:"
 msgstr "Ukendt kanal ({0}) - kun de følgende kanaltyper er understøttet:"
 
-#: ../src/Frontend/EngineManager.cs:301
+#: ../src/Frontend/EngineManager.cs:327
 msgid ""
 "Registration with engine failed!  The username and/or password were wrong - "
 "please verify them."
@@ -33,27 +45,27 @@ msgstr ""
 "Registrering med motor mislykkedes! Brugernavnet og/eller adgangskoden var "
 "forkert - bekræft dem venligst."
 
-#: ../src/Frontend/SshTunnelManager.cs:146
+#: ../src/Frontend/SshTunnelManager.cs:145
 msgid "SSH client application was not found: "
 msgstr "SSH-klientprogram blev ikke fundet: "
 
-#: ../src/Frontend/SshTunnelManager.cs:149
+#: ../src/Frontend/SshTunnelManager.cs:148
 msgid ""
 "SSH client must be either OpenSSH (ssh) or Plink (plink.exe, not putty.exe)"
 msgstr ""
-"SSH-klient skal enten være OpenSSH (ssh) eller Plink (plink.exe, ikke putty."
-"exe)"
+"SSH-klient skal enten være OpenSSH (ssh) eller Plink (plink.exe, ikke "
+"putty.exe)"
 
-#: ../src/Frontend/SshTunnelManager.cs:186
+#: ../src/Frontend/SshTunnelManager.cs:185
 #, csharp-format
 msgid ""
 "The local SSH forwarding port {0} is already in use. Is there an old SSH "
 "tunnel still active?"
 msgstr ""
-"Den lokale SSH-videresendelsesport {0} er allerede i brug. Er der en "
-"gammel SSH-tunnel, der stadig er aktiv?"
+"Den lokale SSH-videresendelsesport {0} er allerede i brug. Er der en gammel "
+"SSH-tunnel, der stadig er aktiv?"
 
-#: ../src/Frontend/SshTunnelManager.cs:210
+#: ../src/Frontend/SshTunnelManager.cs:209
 #, csharp-format
 msgid ""
 "SSH tunnel setup failed (exit code: {0})\n"
@@ -76,7 +88,17 @@ msgstr ""
 "Programuddata:\n"
 "{4}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:405
+#: ../src/Frontend/SshTunnelManager.cs:330
+#: ../src/Frontend/SshTunnelManager.cs:476
+msgid "SSH keyfile not found."
+msgstr "SSH-nøglefil blev ikke fundet."
+
+#: ../src/Frontend/SshTunnelManager.cs:336
+#: ../src/Frontend/SshTunnelManager.cs:482
+msgid "SSH keyfile could not be read."
+msgstr "SSH-nøglefil kunne ikke læses."
+
+#: ../src/Frontend/SshTunnelManager.cs:424
 #, csharp-format
 msgid ""
 "OpenSSH version number not found (exit code: {0})\n"
@@ -97,6 +119,29 @@ msgstr ""
 "Programuddata:\n"
 "{3}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:441
+#: ../src/Frontend/SshTunnelManager.cs:467
 msgid "PuTTY / Plink requires a username to be set."
 msgstr "PuTTY / Plink kræver at et brugernavn er angivet."
+
+#: ../src/Frontend/SshTunnelManager.cs:555
+#, csharp-format
+msgid ""
+"Plink version number not found (exit code: {0})\n"
+"\n"
+"SSH program: {1}\n"
+"\n"
+"Program Error:\n"
+"{2}\n"
+"Program Output:\n"
+"{3}\n"
+msgstr ""
+"Plink-versionsnummer blev ikke fundet (afslutningskode: {0})\n"
+"\n"
+"SSH-program: {1}\n"
+"\n"
+"Programfejl:\n"
+"{2}\n"
+"Programuddata:\n"
+"{3}\n"
+
+
diff --git a/po-Frontend/de.po b/po-Frontend/de.po
index 76e42b2..a8de363 100644
--- a/po-Frontend/de.po
+++ b/po-Frontend/de.po
@@ -1,35 +1,45 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-# Mirco Bauer <meebey at meebey.net>, 2009
-# Bianca Mix <heavydemon at freenet.de>, 2010
-#
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Bianca Mix <heavydemon at freenet.de>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: smuxi 0.6.4\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-01-09 21:43+0100\n"
-"PO-Revision-Date: 2010-01-10 23:55+0100\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:21+0100\n"
+"PO-Revision-Date: 2011-12-30 23:04+0000\n"
 "Last-Translator: Bianca Mix <heavydemon at freenet.de>\n"
-"Language-Team: German Localization <debian-l10n-german at lists.debian.org>\n"
+"Language-Team: German (http://www.transifex.net/projects/p/smuxi/team/de/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Language: de\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Frontend/CommandManager.cs:144
+#: ../src/Frontend/CommandManager.cs:143
 #, csharp-format
 msgid "Unknown Command: {0}"
 msgstr "Unbekannter Befehl: {0}"
 
-#: ../src/Frontend/EngineManager.cs:292
+#: ../src/Frontend/EngineManager.cs:122
+msgid "Engine must not be empty."
+msgstr "Engine darf nicht leer sein."
+
+#: ../src/Frontend/EngineManager.cs:133
+msgid "Engine does not exist."
+msgstr "Engine existiert nicht."
+
+#: ../src/Frontend/EngineManager.cs:318
 #, csharp-format
-msgid "Unknown channel ({0}) - only the following channel types are supported:"
+msgid ""
+"Unknown channel ({0}) - only the following channel types are supported:"
 msgstr ""
 "Unbekannter Channel ({0}) - nur die folgenden Channel-Typen werden "
 "unterstützt:"
 
-#: ../src/Frontend/EngineManager.cs:301
+#: ../src/Frontend/EngineManager.cs:327
 msgid ""
 "Registration with engine failed!  The username and/or password were wrong - "
 "please verify them."
@@ -37,18 +47,18 @@ msgstr ""
 "Registierung gegenüber der Engine ist fehlgeschlagen. Benutzer und/oder "
 "Passwort ist falsch, bitte überprüfen Sie Ihre Eingabe."
 
-#: ../src/Frontend/SshTunnelManager.cs:146
+#: ../src/Frontend/SshTunnelManager.cs:145
 msgid "SSH client application was not found: "
 msgstr "SSH-Client-Programm wurde nicht gefunden: "
 
-#: ../src/Frontend/SshTunnelManager.cs:149
+#: ../src/Frontend/SshTunnelManager.cs:148
 msgid ""
 "SSH client must be either OpenSSH (ssh) or Plink (plink.exe, not putty.exe)"
 msgstr ""
-"SSH-Client muss entweder OpenSSH (ssh) oder Plink (plink.exe, nicht putty."
-"exe) sein"
+"SSH-Client muss entweder OpenSSH (ssh) oder Plink (plink.exe, nicht "
+"putty.exe) sein"
 
-#: ../src/Frontend/SshTunnelManager.cs:186
+#: ../src/Frontend/SshTunnelManager.cs:185
 #, csharp-format
 msgid ""
 "The local SSH forwarding port {0} is already in use. Is there an old SSH "
@@ -57,7 +67,7 @@ msgstr ""
 "Der lokale SSH Weiterleitungs-Port {0} wird bereits verwendet. Ist noch ein "
 "alter SSH Tunnel aktiv?"
 
-#: ../src/Frontend/SshTunnelManager.cs:210
+#: ../src/Frontend/SshTunnelManager.cs:209
 #, csharp-format
 msgid ""
 "SSH tunnel setup failed (exit code: {0})\n"
@@ -80,7 +90,17 @@ msgstr ""
 "Programm-Ausgabe:\n"
 "{4}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:405
+#: ../src/Frontend/SshTunnelManager.cs:330
+#: ../src/Frontend/SshTunnelManager.cs:476
+msgid "SSH keyfile not found."
+msgstr "SSH Schlüssel-Datei nicht gefunden."
+
+#: ../src/Frontend/SshTunnelManager.cs:336
+#: ../src/Frontend/SshTunnelManager.cs:482
+msgid "SSH keyfile could not be read."
+msgstr "SSH Schlüssel-Datei konnte nicht gelesen werden."
+
+#: ../src/Frontend/SshTunnelManager.cs:424
 #, csharp-format
 msgid ""
 "OpenSSH version number not found (exit code: {0})\n"
@@ -101,6 +121,29 @@ msgstr ""
 "Programm-Ausgabe:\n"
 "{3}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:441
+#: ../src/Frontend/SshTunnelManager.cs:467
 msgid "PuTTY / Plink requires a username to be set."
 msgstr "PuTTY / Plink fordert einen gesetzten Benutzernamen."
+
+#: ../src/Frontend/SshTunnelManager.cs:555
+#, csharp-format
+msgid ""
+"Plink version number not found (exit code: {0})\n"
+"\n"
+"SSH program: {1}\n"
+"\n"
+"Program Error:\n"
+"{2}\n"
+"Program Output:\n"
+"{3}\n"
+msgstr ""
+"Plink Versionsnummer nicht gefunden (Rückgabewert: {0})\n"
+"\n"
+"SSH Programm: {1}\n"
+"\n"
+"Programm Fehler:\n"
+"{2}\n"
+"Programm Ausgabe:\n"
+"{3}\n"
+
+
diff --git a/po-Frontend/es.po b/po-Frontend/es.po
index 4f852f9..e824332 100644
--- a/po-Frontend/es.po
+++ b/po-Frontend/es.po
@@ -2,61 +2,48 @@
 # Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
 # This file is distributed under the same license as the Smuxi package.
 # Juan Miguel Carrero <streinleght at gmail.com>, 2008-2009.
-#
+# 
 msgid ""
 msgstr ""
 "Project-Id-Version: smuxi 0.6.4\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-01-09 21:43+0100\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
 "PO-Revision-Date: 2009-08-12 17:11+0100\n"
 "Last-Translator: Juan Miguel Carrero <streinleght at gmail.com>\n"
-"Language-Team: Spanish Spanish Localization <debian-l10n-spanish at lists."
-"debian.org>\n"
+"Language-Team: Spanish Spanish Localization <debian-l10n-spanish at lists.debian.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../src/Frontend/CommandManager.cs:144
+#: ../src/Frontend/CommandManager.cs:143
 #, csharp-format
 msgid "Unknown Command: {0}"
-msgstr ""
+msgstr "Comando desconocido: {0}"
 
 #: ../src/Frontend/EngineManager.cs:292
-#, fuzzy, csharp-format
+#, csharp-format
 msgid "Unknown channel ({0}) - only the following channel types are supported:"
-msgstr ""
-"Canal desconocido ({0}), solo los siguientes tipos de canales estan "
-"soportados:"
+msgstr "Canal desconocido ({0}), solo los siguientes tipos de canales están soportados:"
 
 #: ../src/Frontend/EngineManager.cs:301
-#, fuzzy
-msgid ""
-"Registration with engine failed!  The username and/or password were wrong - "
-"please verify them."
-msgstr ""
-"Registro en el motor fallido , usuario o contraseña inválidos, compruebe los "
-"datos gracias."
+msgid "Registration with engine failed!  The username and/or password were wrong - please verify them."
+msgstr "Registro en el motor fallido! El usuario y/o la contraseña son erróneos. Por favor, verifíquelos. "
 
 #: ../src/Frontend/SshTunnelManager.cs:146
 msgid "SSH client application was not found: "
 msgstr "El programa del cliente SSH no se ha encontrado:"
 
 #: ../src/Frontend/SshTunnelManager.cs:149
-#, fuzzy
-msgid ""
-"SSH client must be either OpenSSH (ssh) or Plink (plink.exe, not putty.exe)"
-msgstr ""
-"El cliente SSH debe ser o OpenSSH (ssh) o Plink (plink.exe, _no_ putty.exe)"
+msgid "SSH client must be either OpenSSH (ssh) or Plink (plink.exe, not putty.exe)"
+msgstr "El cliente SSH debe ser OpenSSH (ssh) o Plink (plink.exe, no putty.exe)"
 
 #: ../src/Frontend/SshTunnelManager.cs:186
 #, csharp-format
-msgid ""
-"The local SSH forwarding port {0} is already in use. Is there an old SSH "
-"tunnel still active?"
-msgstr ""
+msgid "The local SSH forwarding port {0} is already in use. Is there an old SSH tunnel still active?"
+msgstr "El puerto local SSH {0} está actualmente en uso. ¿Existe un tunel SSH antiguo activo aún?"
 
 #: ../src/Frontend/SshTunnelManager.cs:210
-#, fuzzy, csharp-format
+#, csharp-format
 msgid ""
 "SSH tunnel setup failed (exit code: {0})\n"
 "\n"
@@ -68,17 +55,18 @@ msgid ""
 "Program Output:\n"
 "{4}\n"
 msgstr ""
-"Configuración del tunel SSH fallida (código de salida: {0})\n"
+"Configuración del tunel SHH fallida (código de salida: {0})\n"
 "\n"
 "Programa SSH: {1}\n"
+"Parámetros SSH: {2}\n"
 "\n"
-"Error de aplicación:\n"
-"{2}\n"
-"Salida de aplicaciónt:\n"
+"Error:\n"
 "{3}\n"
+"Salida:\n"
+"{4}\n"
 
 #: ../src/Frontend/SshTunnelManager.cs:405
-#, fuzzy, csharp-format
+#, csharp-format
 msgid ""
 "OpenSSH version number not found (exit code: {0})\n"
 "\n"
diff --git a/po-Frontend/fr.po b/po-Frontend/fr.po
index 24a7282..4c0ef91 100644
--- a/po-Frontend/fr.po
+++ b/po-Frontend/fr.po
@@ -1,32 +1,44 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-# Clement BOURGEOIS <moonpyk at gmail.com>, 2009.
-#
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Clément Bourgeois <moonpyk at gmail.com>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: Smuxi 0.6.4\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-01-09 21:43+0100\n"
-"PO-Revision-Date: 2010-01-09 21:49+0100\n"
-"Last-Translator: Clement BOURGEOIS <moonpyk at gmail.com>\n"
-"Language-Team: French Localization <debian-l10n-french at lists.debian.org>\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:21+0100\n"
+"PO-Revision-Date: 2011-12-30 22:59+0000\n"
+"Last-Translator: Clément Bourgeois <moonpyk at gmail.com>\n"
+"Language-Team: French (http://www.transifex.net/projects/p/smuxi/team/fr/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: fr\n"
+"Plural-Forms: nplurals=2; plural=(n > 1)\n"
 
-#: ../src/Frontend/CommandManager.cs:144
+#: ../src/Frontend/CommandManager.cs:143
 #, csharp-format
 msgid "Unknown Command: {0}"
 msgstr "Commande inconnue : {0}"
 
-#: ../src/Frontend/EngineManager.cs:292
+#: ../src/Frontend/EngineManager.cs:122
+msgid "Engine must not be empty."
+msgstr "Le moteur ne doit pas être vide."
+
+#: ../src/Frontend/EngineManager.cs:133
+msgid "Engine does not exist."
+msgstr "Le moteur n'existe pas."
+
+#: ../src/Frontend/EngineManager.cs:318
 #, csharp-format
-msgid "Unknown channel ({0}) - only the following channel types are supported:"
+msgid ""
+"Unknown channel ({0}) - only the following channel types are supported:"
 msgstr ""
 "Canal inconnu ({0}), seuls les types de canaux suivants sont supportés :"
 
-#: ../src/Frontend/EngineManager.cs:301
+#: ../src/Frontend/EngineManager.cs:327
 msgid ""
 "Registration with engine failed!  The username and/or password were wrong - "
 "please verify them."
@@ -34,18 +46,18 @@ msgstr ""
 "Impossible de s'enregistrer auprès du moteur, le nom d'utilisateur et/ou le "
 "mot de passe était(ent) mauvais, veuillez le(s) vérifier."
 
-#: ../src/Frontend/SshTunnelManager.cs:146
+#: ../src/Frontend/SshTunnelManager.cs:145
 msgid "SSH client application was not found: "
 msgstr "L'application SSH client n'a pas été trouvée :"
 
-#: ../src/Frontend/SshTunnelManager.cs:149
+#: ../src/Frontend/SshTunnelManager.cs:148
 msgid ""
 "SSH client must be either OpenSSH (ssh) or Plink (plink.exe, not putty.exe)"
 msgstr ""
-"Le client SSH doit être soit OpenSSH (ssh) ou Plink (plink.exe, et non putty."
-"exe)"
+"Le client SSH doit être soit OpenSSH (ssh) ou Plink (plink.exe, et non "
+"putty.exe)"
 
-#: ../src/Frontend/SshTunnelManager.cs:186
+#: ../src/Frontend/SshTunnelManager.cs:185
 #, csharp-format
 msgid ""
 "The local SSH forwarding port {0} is already in use. Is there an old SSH "
@@ -54,7 +66,7 @@ msgstr ""
 "La redirection locale de port {0} est toujours en cours d'utilisation. "
 "L'ancien tunnel SSH est-il toujours actif ?"
 
-#: ../src/Frontend/SshTunnelManager.cs:210
+#: ../src/Frontend/SshTunnelManager.cs:209
 #, csharp-format
 msgid ""
 "SSH tunnel setup failed (exit code: {0})\n"
@@ -77,7 +89,17 @@ msgstr ""
 "Sortie du programme :\n"
 "{4}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:405
+#: ../src/Frontend/SshTunnelManager.cs:330
+#: ../src/Frontend/SshTunnelManager.cs:476
+msgid "SSH keyfile not found."
+msgstr "Fichier de clé SSH introuvable"
+
+#: ../src/Frontend/SshTunnelManager.cs:336
+#: ../src/Frontend/SshTunnelManager.cs:482
+msgid "SSH keyfile could not be read."
+msgstr "Impossible de lire le fichier de clé SSH."
+
+#: ../src/Frontend/SshTunnelManager.cs:424
 #, csharp-format
 msgid ""
 "OpenSSH version number not found (exit code: {0})\n"
@@ -98,6 +120,29 @@ msgstr ""
 "Sortie du programme:\n"
 "{3}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:441
+#: ../src/Frontend/SshTunnelManager.cs:467
 msgid "PuTTY / Plink requires a username to be set."
 msgstr "PuTTY ou Plink nécessitent un nom d'utilisateur pour fonctionner."
+
+#: ../src/Frontend/SshTunnelManager.cs:555
+#, csharp-format
+msgid ""
+"Plink version number not found (exit code: {0})\n"
+"\n"
+"SSH program: {1}\n"
+"\n"
+"Program Error:\n"
+"{2}\n"
+"Program Output:\n"
+"{3}\n"
+msgstr ""
+"Numéro de version Plink non trouvé (code de retour : {0})\n"
+"\n"
+"Programme SSH : {1}\n"
+"\n"
+"Erreur du programme : \n"
+"{2}\n"
+"Sortie du programme : \n"
+"{3}\n"
+
+
diff --git a/po-Frontend/it.po b/po-Frontend/it.po
index 96d4d30..5bd10ad 100644
--- a/po-Frontend/it.po
+++ b/po-Frontend/it.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: smuxi-frontend\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
 "PO-Revision-Date: 2010-07-15 13:15+0200\n"
 "Last-Translator: Vincenzo Campanella <vinz65 at gmail.com>\n"
 "Language-Team: Italian <tp at lists.linux.it>\n"
diff --git a/po-Frontend/pt.po b/po-Frontend/pt.po
index 363e347..dd4f267 100644
--- a/po-Frontend/pt.po
+++ b/po-Frontend/pt.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: smuxi-frontend \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
+"POT-Creation-Date: 2010-09-11 11:54+0200\n"
 "PO-Revision-Date: 2010-07-15 01:46+0100\n"
 "Last-Translator: Américo Monteiro <a_monteiro at netcabo.pt>\n"
 "Language-Team: Portuguese <traduz at debianpt.org>\n"
@@ -104,4 +104,3 @@ msgstr ""
 #: ../src/Frontend/SshTunnelManager.cs:441
 msgid "PuTTY / Plink requires a username to be set."
 msgstr "PuTTY / Plink requer que seja definido um nome de utilizador."
-
diff --git a/po-Frontend/sv.po b/po-Frontend/sv.po
index 17eb48e..e715ea2 100644
--- a/po-Frontend/sv.po
+++ b/po-Frontend/sv.po
@@ -1,50 +1,71 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-#
-# Martin Bagge <brother at bsnet.se>, 2009
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+#   <flugsio at gmail.com>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-01-09 21:43+0100\n"
-"PO-Revision-Date: 2010-07-08 00:40+0100\n"
-"Last-Translator: Martin Bagge <brother at bsnet.se>\n"
-"Language-Team: Swedish <debian-l10n-swedish at lists.debian.org>\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:21+0100\n"
+"PO-Revision-Date: 2011-12-31 10:56+0000\n"
+"Last-Translator: flugsio <flugsio at gmail.com>\n"
+"Language-Team: Swedish (http://www.transifex.net/projects/p/smuxi/team/sv/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: Swedish\n"
-"X-Poedit-Country: Sweden\n"
+"Language: sv\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Frontend/CommandManager.cs:144
+#: ../src/Frontend/CommandManager.cs:143
 #, csharp-format
 msgid "Unknown Command: {0}"
 msgstr "Okänt kommando: {0}"
 
-#: ../src/Frontend/EngineManager.cs:292
+#: ../src/Frontend/EngineManager.cs:122
+msgid "Engine must not be empty."
+msgstr "Motor får inte lämnas tom."
+
+#: ../src/Frontend/EngineManager.cs:133
+msgid "Engine does not exist."
+msgstr "Vald motor finns inte."
+
+#: ../src/Frontend/EngineManager.cs:318
 #, csharp-format
-msgid "Unknown channel ({0}) - only the following channel types are supported:"
+msgid ""
+"Unknown channel ({0}) - only the following channel types are supported:"
 msgstr "Okänd kanal ({0}) - endast följande kanaltyper stöds:"
 
-#: ../src/Frontend/EngineManager.cs:301
-msgid "Registration with engine failed!  The username and/or password were wrong - please verify them."
-msgstr "Kunde inte ansluta till motorn! Användarnamnet och/eller lösenordet var fel - kontrollera dessa."
+#: ../src/Frontend/EngineManager.cs:327
+msgid ""
+"Registration with engine failed!  The username and/or password were wrong - "
+"please verify them."
+msgstr ""
+"Kunde inte ansluta till motorn! Användarnamnet och/eller lösenordet var fel "
+"- kontrollera dessa."
 
-#: ../src/Frontend/SshTunnelManager.cs:146
+#: ../src/Frontend/SshTunnelManager.cs:145
 msgid "SSH client application was not found: "
 msgstr "SSH-klient-applikationen kunde inte hittas:"
 
-#: ../src/Frontend/SshTunnelManager.cs:149
-msgid "SSH client must be either OpenSSH (ssh) or Plink (plink.exe, not putty.exe)"
-msgstr "SSH-klienten måste vara antingen OpenSSH (ssh) eller Plink (plink.exe, inte putty.exe)"
+#: ../src/Frontend/SshTunnelManager.cs:148
+msgid ""
+"SSH client must be either OpenSSH (ssh) or Plink (plink.exe, not putty.exe)"
+msgstr ""
+"SSH-klienten måste vara antingen OpenSSH (ssh) eller Plink (plink.exe, inte "
+"putty.exe)"
 
-#: ../src/Frontend/SshTunnelManager.cs:186
+#: ../src/Frontend/SshTunnelManager.cs:185
 #, csharp-format
-msgid "The local SSH forwarding port {0} is already in use. Is there an old SSH tunnel still active?"
-msgstr "Den lokala porten för vidaresändning av SSH {0} används redan. Finns där en gammal SSH-tunnel som fortfarande är aktiv?"
+msgid ""
+"The local SSH forwarding port {0} is already in use. Is there an old SSH "
+"tunnel still active?"
+msgstr ""
+"Den lokala porten för vidaresändning av SSH {0} används redan. Finns där en "
+"gammal SSH-tunnel som fortfarande är aktiv?"
 
-#: ../src/Frontend/SshTunnelManager.cs:210
+#: ../src/Frontend/SshTunnelManager.cs:209
 #, csharp-format
 msgid ""
 "SSH tunnel setup failed (exit code: {0})\n"
@@ -67,7 +88,17 @@ msgstr ""
 "Utdata från applikation:\n"
 "{4}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:405
+#: ../src/Frontend/SshTunnelManager.cs:330
+#: ../src/Frontend/SshTunnelManager.cs:476
+msgid "SSH keyfile not found."
+msgstr "SSH-nyckelfil hittades inte."
+
+#: ../src/Frontend/SshTunnelManager.cs:336
+#: ../src/Frontend/SshTunnelManager.cs:482
+msgid "SSH keyfile could not be read."
+msgstr "SSH-nyckelfilen kunde inte läsas."
+
+#: ../src/Frontend/SshTunnelManager.cs:424
 #, csharp-format
 msgid ""
 "OpenSSH version number not found (exit code: {0})\n"
@@ -88,7 +119,29 @@ msgstr ""
 "Utdata från applikation:\n"
 "{3}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:441
+#: ../src/Frontend/SshTunnelManager.cs:467
 msgid "PuTTY / Plink requires a username to be set."
 msgstr "PuTTY/Plink kräver att ett användarnamn används."
 
+#: ../src/Frontend/SshTunnelManager.cs:555
+#, csharp-format
+msgid ""
+"Plink version number not found (exit code: {0})\n"
+"\n"
+"SSH program: {1}\n"
+"\n"
+"Program Error:\n"
+"{2}\n"
+"Program Output:\n"
+"{3}\n"
+msgstr ""
+"Plink versions-nummer hittades inte (avslutningskod: {0})\n"
+"\n"
+"SSH program: {1}\n"
+"\n"
+"Programfel:\n"
+"{2}\n"
+"Programutdata:\n"
+"{3}\n"
+
+
diff --git a/po-Frontend/zh_CN.po b/po-Frontend/zh_CN.po
new file mode 100644
index 0000000..5e167c5
--- /dev/null
+++ b/po-Frontend/zh_CN.po
@@ -0,0 +1,132 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:21+0100\n"
+"PO-Revision-Date: 2010-11-30 04:13+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: Chinese (China) (http://www.transifex.net/projects/p/smuxi/team/zh_CN/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: zh_CN\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ../src/Frontend/CommandManager.cs:143
+#, csharp-format
+msgid "Unknown Command: {0}"
+msgstr "未知命令: {0}"
+
+#: ../src/Frontend/EngineManager.cs:122
+msgid "Engine must not be empty."
+msgstr ""
+
+#: ../src/Frontend/EngineManager.cs:133
+msgid "Engine does not exist."
+msgstr ""
+
+#: ../src/Frontend/EngineManager.cs:318
+#, csharp-format
+msgid ""
+"Unknown channel ({0}) - only the following channel types are supported:"
+msgstr "未知频道 ({0}) - 仅支持下列频道类型:"
+
+#: ../src/Frontend/EngineManager.cs:327
+msgid ""
+"Registration with engine failed!  The username and/or password were wrong - "
+"please verify them."
+msgstr "引擎注册失败!  用户名和/或密码错误 - 请验证。"
+
+#: ../src/Frontend/SshTunnelManager.cs:145
+msgid "SSH client application was not found: "
+msgstr "未找到 SSH 客户端应用程序: "
+
+#: ../src/Frontend/SshTunnelManager.cs:148
+msgid ""
+"SSH client must be either OpenSSH (ssh) or Plink (plink.exe, not putty.exe)"
+msgstr "SSH 客户端必须为 OpenSSH (ssh) 或 Plink (plink.exe, 而非 putty.exe)"
+
+#: ../src/Frontend/SshTunnelManager.cs:185
+#, csharp-format
+msgid ""
+"The local SSH forwarding port {0} is already in use. Is there an old SSH "
+"tunnel still active?"
+msgstr "本地 SSH 转发端口 {0} 已被占用。是不是还有旧版 SSH 隧道处于活动状态?"
+
+#: ../src/Frontend/SshTunnelManager.cs:209
+#, csharp-format
+msgid ""
+"SSH tunnel setup failed (exit code: {0})\n"
+"\n"
+"SSH program: {1}\n"
+"SSH parameters: {2}\n"
+"\n"
+"Program Error:\n"
+"{3}\n"
+"Program Output:\n"
+"{4}\n"
+msgstr ""
+"SSH 隧道安装失败 (退出代码: {0})\n"
+"\n"
+"SSH 程序: {1}\n"
+"SSH 参数: {2}\n"
+"\n"
+"程序错误:\n"
+"{3}\n"
+"程序输出:\n"
+"{4}\n"
+
+#: ../src/Frontend/SshTunnelManager.cs:330
+#: ../src/Frontend/SshTunnelManager.cs:476
+msgid "SSH keyfile not found."
+msgstr ""
+
+#: ../src/Frontend/SshTunnelManager.cs:336
+#: ../src/Frontend/SshTunnelManager.cs:482
+msgid "SSH keyfile could not be read."
+msgstr ""
+
+#: ../src/Frontend/SshTunnelManager.cs:424
+#, csharp-format
+msgid ""
+"OpenSSH version number not found (exit code: {0})\n"
+"\n"
+"SSH program: {1}\n"
+"\n"
+"Program Error:\n"
+"{2}\n"
+"Program Output:\n"
+"{3}\n"
+msgstr ""
+"未发现 OpenSSH 版本号 (退出代码: {0})\n"
+"\n"
+"SSH 程序: {1}\n"
+"\n"
+"程序错误:\n"
+"{2}\n"
+"程序输出:\n"
+"{3}\n"
+
+#: ../src/Frontend/SshTunnelManager.cs:467
+msgid "PuTTY / Plink requires a username to be set."
+msgstr "PuTTY / Plink 需要设置用户名。"
+
+#: ../src/Frontend/SshTunnelManager.cs:555
+#, csharp-format
+msgid ""
+"Plink version number not found (exit code: {0})\n"
+"\n"
+"SSH program: {1}\n"
+"\n"
+"Program Error:\n"
+"{2}\n"
+"Program Output:\n"
+"{3}\n"
+msgstr ""
+
+
diff --git a/po-Server/LINGUAS b/po-Server/LINGUAS
index d1ab565..5cfa658 100644
--- a/po-Server/LINGUAS
+++ b/po-Server/LINGUAS
@@ -1,6 +1,9 @@
 cs
 da
 de
+es
 fr
+it
 pt
 sv
+zh_CN
diff --git a/po-Server/POTFILES.skip b/po-Server/POTFILES.skip
index 48a64d9..47eecc2 100644
--- a/po-Server/POTFILES.skip
+++ b/po-Server/POTFILES.skip
@@ -9,5 +9,7 @@ src/Engine-Twitter/
 src/Frontend/
 src/Frontend-GNOME-IRC/
 src/Frontend-GNOME/
+src/Frontend-STFL/
 src/Frontend-SWF/
 src/Frontend-WPF/
+lib/
diff --git a/po-Server/da.po b/po-Server/da.po
index b69e1e7..5c4cf60 100644
--- a/po-Server/da.po
+++ b/po-Server/da.po
@@ -1,111 +1,140 @@
-# Danish translation smuxi po-server.
-# Copyright (C) 2010 smuxi po-server & nedenstående oversættere.
-# This file is distributed under the same license as the smuxi po-server package.
-# Joe Hansen <joedalton2 at yahoo.dk>, 2010.
-#
-# NB: Server er et navn
-# hvorfor er de sidste strenge med lille s?
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Joe Hansen <joedalton2 at yahoo.dk>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: smuxi po-server\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-16 12:42+0000\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:21+0100\n"
+"PO-Revision-Date: 2011-12-29 19:58+0000\n"
 "Last-Translator: Joe Hansen <joedalton2 at yahoo.dk>\n"
-"Language-Team: Danish <debian-l10n-danish at lists.debian.org>\n"
+"Language-Team: Danish (http://www.transifex.net/projects/p/smuxi/team/da/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: da\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Server/Main.cs:69
+#: ../src/Server/Main.cs:71
 msgid "Add user to Server"
 msgstr "Tilføj bruger til Server"
 
-#: ../src/Server/Main.cs:78
+#: ../src/Server/Main.cs:80
 msgid "Modify existing user of Server"
 msgstr "Ændr eksisterende bruger af Server"
 
-#: ../src/Server/Main.cs:87
+#: ../src/Server/Main.cs:89
 msgid "Delete user from Server"
 msgstr "Slet bruger fra Server"
 
-#: ../src/Server/Main.cs:96
+#: ../src/Server/Main.cs:98
 msgid "List all existing users of Server"
 msgstr "Vis alle eksisterende brugere af Server"
 
-#: ../src/Server/Main.cs:105
+#: ../src/Server/Main.cs:107
 msgid "User to create, modify or delete"
 msgstr "Bruger at oprette, ændre eller slette"
 
-#: ../src/Server/Main.cs:114
+#: ../src/Server/Main.cs:116
 msgid "Password of the user when creating or modifying a user"
 msgstr "Adgangskode på brugeren når en bruger oprettes eller ændres"
 
-#: ../src/Server/Main.cs:123
+#: ../src/Server/Main.cs:125
 msgid "Enable debug output"
 msgstr "Aktiver fejlsøgningsuddata"
 
-#: ../src/Server/Main.cs:131
+#: ../src/Server/Main.cs:133
+msgid ""
+"Optimize message buffers and exit (valid values: none, defrag, index, all)"
+msgstr ""
+"Optimer mellemlager for beskeder og afslut (gyldige værdier: none, defrag, "
+"index, all)"
+
+#: ../src/Server/Main.cs:146
 msgid "Show this help"
 msgstr "Vis denne hjælp"
 
-#: ../src/Server/Main.cs:133
+#: ../src/Server/Main.cs:148
 msgid "Usage: smuxi-server [options]"
 msgstr "Brug: smuxi-server [tilvalg]"
 
-#: ../src/Server/Main.cs:135
+#: ../src/Server/Main.cs:150
 msgid "Options:"
 msgstr "Tilvalg:"
 
-#: ../src/Server/Main.cs:146
+#: ../src/Server/Main.cs:161
 #, csharp-format
 msgid "Unknown option: '{0}'"
 msgstr "Ukendt tilvalg: '{0}'"
 
-#: ../src/Server/Main.cs:170
+#: ../src/Server/Main.cs:188
 #, csharp-format
 msgid "Command line error: {0}"
 msgstr "Kommandolinjefejl: {0}"
 
-#: ../src/Server/Main.cs:214
+#: ../src/Server/Main.cs:232
 msgid ""
-"At most one of --add-user, --modify-user, and --delete-user may be used at a "
-"time."
+"At most one of --add-user, --modify-user, and --delete-user may be used at a"
+" time."
 msgstr ""
 "Kun en af brugerne --add-user, --modify-user eller --delete-user kan bruges "
 "på samme tid."
 
-#: ../src/Server/Main.cs:224
+#: ../src/Server/Main.cs:242
 msgid "You must specify a username with the --username option."
 msgstr "Du skal angive et brugernavn med tilvalget --username."
 
-#: ../src/Server/Main.cs:230
+#: ../src/Server/Main.cs:248
 msgid "Username must not be empty."
 msgstr "Brugernavn må ikke være tomt."
 
-#: ../src/Server/Main.cs:240
+#: ../src/Server/Main.cs:258
 msgid "You must specify a password with the --password option."
 msgstr "Du skal angive en adgangskode med tilvalget --password."
 
-#: ../src/Server/Main.cs:246
+#: ../src/Server/Main.cs:264
 msgid "Password must not be empty."
 msgstr "Adgangskode må ikke være tomt."
 
-#: ../src/Server/Main.cs:263
+#: ../src/Server/Main.cs:283
+#, csharp-format
+msgid ""
+"Invalid optimization value passed to --optimize-message-buffer, valid values"
+" are: {0}"
+msgstr ""
+"Ugyldig optimeringsværdi sendt til --optimize-message-buffer, gyldige "
+"værdier er: {0}"
+
+#: ../src/Server/Main.cs:303
 #, csharp-format
 msgid "User \"{0}\" successfully added to server."
 msgstr "Bruger »{0}« tilføjet til server."
 
-#: ../src/Server/Main.cs:272
+#: ../src/Server/Main.cs:312
 #, csharp-format
 msgid "User \"{0}\" successfully modified."
 msgstr "Bruger »{0}« ændret."
 
-#: ../src/Server/Main.cs:281
+#: ../src/Server/Main.cs:321
 #, csharp-format
 msgid "User \"{0}\" successfully deleted from server."
 msgstr "Bruger »{0}« slettet fra server."
 
-#: ../src/Server/Main.cs:288
+#: ../src/Server/Main.cs:328
 msgid "Users:"
 msgstr "Brugere:"
+
+#: ../src/Server/Main.cs:376
+#, csharp-format
+msgid "Successfully optimized {0} message buffers."
+msgstr "Lykkedes med optimering af {0} beskedmellemlagre."
+
+#: ../src/Server/Main.cs:389
+#, csharp-format
+msgid "Failed to optimize message buffers: {0}"
+msgstr "Kunne ikke optimere beskedmellemlagre: {0}"
+
+
diff --git a/po-Server/de.po b/po-Server/de.po
index ed5964d..0523759 100644
--- a/po-Server/de.po
+++ b/po-Server/de.po
@@ -1,105 +1,141 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2010 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-# Bianca Mix <heavydemon at freenet.de>, 2010.
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
 # 
+# Translators:
+# Bianca Mix <heavydemon at freenet.de>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: smuxi 0.7\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-01-11 00:47+0100\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:21+0100\n"
+"PO-Revision-Date: 2011-12-30 23:07+0000\n"
 "Last-Translator: Bianca Mix <heavydemon at freenet.de>\n"
-"Language-Team: German Localization <debian-l10n-german at lists.debian.org>\n"
+"Language-Team: German (http://www.transifex.net/projects/p/smuxi/team/de/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: de\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Server/Main.cs:69
+#: ../src/Server/Main.cs:71
 msgid "Add user to Server"
 msgstr "Benutzer zum Server hinzufügen"
 
-#: ../src/Server/Main.cs:78
+#: ../src/Server/Main.cs:80
 msgid "Modify existing user of Server"
 msgstr "Verändern eines bereits existierenden Benutzers des Servers"
 
-#: ../src/Server/Main.cs:87
+#: ../src/Server/Main.cs:89
 msgid "Delete user from Server"
 msgstr "Benutzer vom Server entfernen"
 
-#: ../src/Server/Main.cs:96
+#: ../src/Server/Main.cs:98
 msgid "List all existing users of Server"
 msgstr "Liste alle vorhandenen Benutzer des Servers"
 
-#: ../src/Server/Main.cs:105
+#: ../src/Server/Main.cs:107
 msgid "User to create, modify or delete"
 msgstr "Benutzer, der erstellt, verändert oder entfernt werden soll"
 
-#: ../src/Server/Main.cs:114
+#: ../src/Server/Main.cs:116
 msgid "Password of the user when creating or modifying a user"
-msgstr "Passwort für den Benutzer, wenn Benutzer erstellt oder verändert werden soll"
+msgstr ""
+"Passwort für den Benutzer, wenn Benutzer erstellt oder verändert werden soll"
 
-#: ../src/Server/Main.cs:123
+#: ../src/Server/Main.cs:125
 msgid "Enable debug output"
 msgstr "Aktivieren der Ausgabe zur Fehlerbeseitigung"
 
-#: ../src/Server/Main.cs:131
+#: ../src/Server/Main.cs:133
+msgid ""
+"Optimize message buffers and exit (valid values: none, defrag, index, all)"
+msgstr ""
+"Optimiere Nachrichtenpuffer und Verlassen (Gültige Werte: none, defrag, "
+"index, all)"
+
+#: ../src/Server/Main.cs:146
 msgid "Show this help"
 msgstr "Zeige diese Hilfe an"
 
-#: ../src/Server/Main.cs:133
+#: ../src/Server/Main.cs:148
 msgid "Usage: smuxi-server [options]"
 msgstr "Verwendung: smuxi-server [options]"
 
-#: ../src/Server/Main.cs:135
+#: ../src/Server/Main.cs:150
 msgid "Options:"
 msgstr "Optionen:"
 
-#: ../src/Server/Main.cs:146
+#: ../src/Server/Main.cs:161
 #, csharp-format
 msgid "Unknown option: '{0}'"
 msgstr "Unbekannte Auswahl: '{0}'"
 
-#: ../src/Server/Main.cs:170
+#: ../src/Server/Main.cs:188
 #, csharp-format
 msgid "Command line error: {0}"
 msgstr "Kommandozeilenfehler: {0}"
 
-#: ../src/Server/Main.cs:214
-msgid "At most one of --add-user, --modify-user, and --delete-user may be used at a time."
-msgstr "Höchstens einer der Optionen --add-user, --modify-user, und --delete-user darf gleichzeitig verwendet werden."
+#: ../src/Server/Main.cs:232
+msgid ""
+"At most one of --add-user, --modify-user, and --delete-user may be used at a"
+" time."
+msgstr ""
+"Höchstens einer der Optionen --add-user, --modify-user, und --delete-user "
+"darf gleichzeitig verwendet werden."
 
-#: ../src/Server/Main.cs:224
+#: ../src/Server/Main.cs:242
 msgid "You must specify a username with the --username option."
 msgstr "Sie müssen einen Benutzernamen mit der Option --username angeben."
 
-#: ../src/Server/Main.cs:230
+#: ../src/Server/Main.cs:248
 msgid "Username must not be empty."
 msgstr "Benutzername darf nicht leer sein."
 
-#: ../src/Server/Main.cs:240
+#: ../src/Server/Main.cs:258
 msgid "You must specify a password with the --password option."
 msgstr "Sie müssen ein Passwort mit der --password Option angeben."
 
-#: ../src/Server/Main.cs:246
+#: ../src/Server/Main.cs:264
 msgid "Password must not be empty."
 msgstr "Passwort darf nicht leer sein."
 
-#: ../src/Server/Main.cs:263
+#: ../src/Server/Main.cs:283
+#, csharp-format
+msgid ""
+"Invalid optimization value passed to --optimize-message-buffer, valid values"
+" are: {0}"
+msgstr ""
+"Ungültige Optimierungswerte übergeben an --optimize-message-buffer, gültige "
+"Werte sind: {0}"
+
+#: ../src/Server/Main.cs:303
 #, csharp-format
 msgid "User \"{0}\" successfully added to server."
 msgstr "Benutzer \"{0}\" wurde erfolgreich zum Server hinzugefügt."
 
-#: ../src/Server/Main.cs:272
+#: ../src/Server/Main.cs:312
 #, csharp-format
 msgid "User \"{0}\" successfully modified."
 msgstr "Benutzer \"{0}\" wurde erfolgreich verändert."
 
-#: ../src/Server/Main.cs:281
+#: ../src/Server/Main.cs:321
 #, csharp-format
 msgid "User \"{0}\" successfully deleted from server."
 msgstr "Benutzer \"{0}\" wurde erfolgreich vom Server entfernt."
 
-#: ../src/Server/Main.cs:288
+#: ../src/Server/Main.cs:328
 msgid "Users:"
 msgstr "Benutzer:"
+
+#: ../src/Server/Main.cs:376
+#, csharp-format
+msgid "Successfully optimized {0} message buffers."
+msgstr "Erfolgreich {0} Nachrichtenpuffer optimiert"
+
+#: ../src/Server/Main.cs:389
+#, csharp-format
+msgid "Failed to optimize message buffers: {0}"
+msgstr "Optimierung der Nachrichtenpuffer fehlgeschlagen: {0}"
+
+
diff --git a/po-Server/es.po b/po-Server/es.po
new file mode 100644
index 0000000..aeb0cb3
--- /dev/null
+++ b/po-Server/es.po
@@ -0,0 +1,109 @@
+# po-Server/smuxi-server.pot Spanish translation file
+# Copyright (C) 2010
+# This file is distributed under the same license as the Smuxi - IRC Client package.
+# Ricardo A. Hermosilla Carrillo <ra.hermosillac at gmail.com>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2010-09-12 23:30-0400\n"
+"Last-Translator: Ricardo A. Hermosilla Carrillo <ra.hermosillac at gmail.com>\n"
+"Language-Team: Spanish <ES at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../src/Server/Main.cs:69
+msgid "Add user to Server"
+msgstr "Agregar usuario al Servidor"
+
+#: ../src/Server/Main.cs:78
+msgid "Modify existing user of Server"
+msgstr "Modificar un usuario existente del Servidor"
+
+#: ../src/Server/Main.cs:87
+msgid "Delete user from Server"
+msgstr "Borrar usuario del Servidor"
+
+#: ../src/Server/Main.cs:96
+msgid "List all existing users of Server"
+msgstr "Listar todos los usuarios existentes del Servidor"
+
+#: ../src/Server/Main.cs:105
+msgid "User to create, modify or delete"
+msgstr "Usuario a crear, modificar o borrar"
+
+#: ../src/Server/Main.cs:114
+msgid "Password of the user when creating or modifying a user"
+msgstr "Contraseña del usuario que se está creando o modificando"
+
+#: ../src/Server/Main.cs:123
+msgid "Enable debug output"
+msgstr "Habilitar salida de depuración"
+
+#: ../src/Server/Main.cs:131
+msgid "Show this help"
+msgstr "Mostrar esta ayuda"
+
+#: ../src/Server/Main.cs:133
+msgid "Usage: smuxi-server [options]"
+msgstr "Modo de uso: smuxi-server [opciones]"
+
+#: ../src/Server/Main.cs:135
+msgid "Options:"
+msgstr "Opciones:"
+
+#: ../src/Server/Main.cs:146
+#, csharp-format
+msgid "Unknown option: '{0}'"
+msgstr "Opción desconocida: '{0}'"
+
+#: ../src/Server/Main.cs:170
+#, csharp-format
+msgid "Command line error: {0}"
+msgstr "Error de línea de comandos: {0}"
+
+#: ../src/Server/Main.cs:214
+msgid ""
+"At most one of --add-user, --modify-user, and --delete-user may be used at a "
+"time."
+msgstr ""
+"A lo más una de las opciones --add-user, --modify-user y --delete-user pueden "
+"ser usadas al mismo tiempo."
+
+#: ../src/Server/Main.cs:224
+msgid "You must specify a username with the --username option."
+msgstr "Debe especificar un nombre de usuario con la opción --username"
+
+#: ../src/Server/Main.cs:230
+msgid "Username must not be empty."
+msgstr "Nombre de Usuario no puede estar vacío."
+
+#: ../src/Server/Main.cs:240
+msgid "You must specify a password with the --password option."
+msgstr "Debe especificar una contraseña con la opción --password"
+
+#: ../src/Server/Main.cs:246
+msgid "Password must not be empty."
+msgstr "Contraseña no puede estar vacía."
+
+#: ../src/Server/Main.cs:263
+#, csharp-format
+msgid "User \"{0}\" successfully added to server."
+msgstr "El usuario \"{0}\" ha sido añadido satisfactoriamente al servidor."
+
+#: ../src/Server/Main.cs:272
+#, csharp-format
+msgid "User \"{0}\" successfully modified."
+msgstr "El usuario \"{0}\" ha sido modificado satisfactoriamente."
+
+#: ../src/Server/Main.cs:281
+#, csharp-format
+msgid "User \"{0}\" successfully deleted from server."
+msgstr "El usuario \"{0}\" ha sido borrado satisfactoriamente del servidor."
+
+#: ../src/Server/Main.cs:288
+msgid "Users:"
+msgstr "Usuarios:"
diff --git a/po-Server/fr.po b/po-Server/fr.po
index b346d09..6fd8ea5 100644
--- a/po-Server/fr.po
+++ b/po-Server/fr.po
@@ -1,135 +1,142 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2010 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-# Clement Bourgeois <moonpyk at gmail.com>, 2010.
-#
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Clément Bourgeois <moonpyk at gmail.com>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-15 22:28+0100\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:21+0100\n"
+"PO-Revision-Date: 2011-12-30 23:04+0000\n"
 "Last-Translator: Clément Bourgeois <moonpyk at gmail.com>\n"
-"Language-Team: LANGUAGE <LL at li.org>\n"
+"Language-Team: French (http://www.transifex.net/projects/p/smuxi/team/fr/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: fr\n"
+"Plural-Forms: nplurals=2; plural=(n > 1)\n"
 
-#: ../src/Server/Main.cs:69
+#: ../src/Server/Main.cs:71
 msgid "Add user to Server"
 msgstr "Ajouter un utilisateur au serveur"
 
-#: ../src/Server/Main.cs:78
+#: ../src/Server/Main.cs:80
 msgid "Modify existing user of Server"
 msgstr "Modifier un utilisateur existant du serveur"
 
-#: ../src/Server/Main.cs:87
+#: ../src/Server/Main.cs:89
 msgid "Delete user from Server"
 msgstr "Supprimer un utilisateur du serveur"
 
-#: ../src/Server/Main.cs:96
+#: ../src/Server/Main.cs:98
 msgid "List all existing users of Server"
 msgstr "Lister tous les utilisateurs existants du serveur"
 
-#: ../src/Server/Main.cs:105
+#: ../src/Server/Main.cs:107
 msgid "User to create, modify or delete"
 msgstr "Utilisateur à créer, modifier ou supprimer"
 
-#: ../src/Server/Main.cs:114
+#: ../src/Server/Main.cs:116
 msgid "Password of the user when creating or modifying a user"
 msgstr ""
-"Mot de passe utilisé pendant la création ou la modification d'un utilisateur."
+"Mot de passe utilisé pendant la création ou la modification d'un "
+"utilisateur."
 
-#: ../src/Server/Main.cs:123
+#: ../src/Server/Main.cs:125
 msgid "Enable debug output"
 msgstr "Activer la sortie de déboguage"
 
-#: ../src/Server/Main.cs:131
+#: ../src/Server/Main.cs:133
+msgid ""
+"Optimize message buffers and exit (valid values: none, defrag, index, all)"
+msgstr ""
+"Optimiser les tampons de messages et sortir (valeurs valides: none, defrag, "
+"index, all)"
+
+#: ../src/Server/Main.cs:146
 msgid "Show this help"
 msgstr "Affiche cette aide"
 
-#: ../src/Server/Main.cs:133
+#: ../src/Server/Main.cs:148
 msgid "Usage: smuxi-server [options]"
 msgstr "Usage : smuxi-server [options]"
 
-#: ../src/Server/Main.cs:135
+#: ../src/Server/Main.cs:150
 msgid "Options:"
 msgstr "Options :"
 
-#: ../src/Server/Main.cs:146
+#: ../src/Server/Main.cs:161
 #, csharp-format
 msgid "Unknown option: '{0}'"
 msgstr "Option inconnue : '{0}'"
 
-#: ../src/Server/Main.cs:170
+#: ../src/Server/Main.cs:188
 #, csharp-format
 msgid "Command line error: {0}"
 msgstr "Erreur de ligne de commande : {0}"
 
-#: ../src/Server/Main.cs:214
+#: ../src/Server/Main.cs:232
 msgid ""
-"At most one of --add-user, --modify-user, and --delete-user may be used at a "
-"time."
+"At most one of --add-user, --modify-user, and --delete-user may be used at a"
+" time."
 msgstr ""
 "Les options -a|--add-user ou -m|--modify-user et -d|-delete-user ne peuvent "
 "pas être utilisées en même temps."
 
-#: ../src/Server/Main.cs:224
+#: ../src/Server/Main.cs:242
 msgid "You must specify a username with the --username option."
 msgstr "Vous devez spécifier un nom d'utilisateur avec l'option --username."
 
-#: ../src/Server/Main.cs:230
+#: ../src/Server/Main.cs:248
 msgid "Username must not be empty."
 msgstr "Le nom d'utilisateur ne peut pas être vide."
 
-#: ../src/Server/Main.cs:240
+#: ../src/Server/Main.cs:258
 msgid "You must specify a password with the --password option."
 msgstr "Vous devez spécifier un mot de passe avec l'option --password."
 
-#: ../src/Server/Main.cs:246
+#: ../src/Server/Main.cs:264
 msgid "Password must not be empty."
 msgstr "Le mot de passe ne peut pas être vide."
 
-#: ../src/Server/Main.cs:263
+#: ../src/Server/Main.cs:283
+#, csharp-format
+msgid ""
+"Invalid optimization value passed to --optimize-message-buffer, valid values"
+" are: {0}"
+msgstr ""
+"Valeur d'optimisation passée à --optimize-message-buffer invalide, les "
+"valeurs valides sont : {0}"
+
+#: ../src/Server/Main.cs:303
 #, csharp-format
 msgid "User \"{0}\" successfully added to server."
 msgstr "L'utilisateur \"{0}\" a été ajouté avec succès au serveur."
 
-#: ../src/Server/Main.cs:272
+#: ../src/Server/Main.cs:312
 #, csharp-format
 msgid "User \"{0}\" successfully modified."
 msgstr "L'utilisateur \"{0}\" a été modifié avec succès."
 
-#: ../src/Server/Main.cs:281
+#: ../src/Server/Main.cs:321
 #, csharp-format
 msgid "User \"{0}\" successfully deleted from server."
-msgstr ""
-"L'utilisateur : \"{0}\" a été supprimé de la configuration avec succès."
+msgstr "L'utilisateur : \"{0}\" a été supprimé de la configuration avec succès."
 
-#: ../src/Server/Main.cs:288
+#: ../src/Server/Main.cs:328
 msgid "Users:"
 msgstr "Utilisateurs :"
 
-#~ msgid ""
-#~ "Error: -a|--add-user and -m|--modify-user options can't be used together"
-#~ msgstr ""
-#~ "Erreur : les options -a|--add-user and -m|--modify-user ne peuvent pas "
-#~ "être utilisées en même temps"
-
-#~ msgid ""
-#~ "Error: -a|--add-user and -m|--modify-user options require -u|--"
-#~ "username=VALUE and -p|--password=VALUE options to be set"
-#~ msgstr ""
-#~ "Erreur : les options -a|--add-user and -m|--modify-user nécessitent -u|--"
-#~ "username=VALEUR and -p|--password=VALEUR d'être précisées"
-
-#~ msgid ""
-#~ "User: \"{0}\" successfully added to configuration with password: \"{1}\""
-#~ msgstr ""
-#~ "L'utilisateur : \"{0}\", muni du mot de passe : \"{1}\" a été ajouté a la "
-#~ "configuration avec succès"
-
-#~ msgid "Error: -D|--delete-user option require -u|--username=VALUE option"
-#~ msgstr ""
-#~ "Erreur : l'option -D|--delete-user nécessite l'option -u|--"
-#~ "username=VALEUR d'être precisée"
+#: ../src/Server/Main.cs:376
+#, csharp-format
+msgid "Successfully optimized {0} message buffers."
+msgstr "Optimisation des tampons de messages {0} réalisée avec succès."
+
+#: ../src/Server/Main.cs:389
+#, csharp-format
+msgid "Failed to optimize message buffers: {0}"
+msgstr "Impossible d'optimiser les tampon de messages : {0}"
+
+
diff --git a/po-Server/it.po b/po-Server/it.po
new file mode 100644
index 0000000..2cf6cee
--- /dev/null
+++ b/po-Server/it.po
@@ -0,0 +1,113 @@
+# ITALIAN TRANSLATION OF SMUXI-SERVER.
+# COPYRIGHT (C) 2010 THE SMUXI-SERVER'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the smuxi-server package.
+#
+# Vincenzo Campanella <vinz65 at gmail.com>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: smuxi-server\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-09-02 15:23+0200\n"
+"PO-Revision-Date: 2010-09-11 12:19+0200\n"
+"Last-Translator: Vincenzo Campanella <vinz65 at gmail.com>\n"
+"Language-Team: Italian <tp at lists.linux.it>\n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../src/Server/Main.cs:69
+msgid "Add user to Server"
+msgstr "Aggiungi un utente al server"
+
+#: ../src/Server/Main.cs:78
+msgid "Modify existing user of Server"
+msgstr "Modifica un utente esistente del server"
+
+#: ../src/Server/Main.cs:87
+msgid "Delete user from Server"
+msgstr "Elimina un utente dal server"
+
+#: ../src/Server/Main.cs:96
+msgid "List all existing users of Server"
+msgstr "Elenca tutti gli utenti esistenti del server"
+
+#: ../src/Server/Main.cs:105
+msgid "User to create, modify or delete"
+msgstr "Utente da creare, modificare o eliminare"
+
+#: ../src/Server/Main.cs:114
+msgid "Password of the user when creating or modifying a user"
+msgstr "Password dell'utente durante la creazione o la modifica di un utente"
+
+#: ../src/Server/Main.cs:123
+msgid "Enable debug output"
+msgstr "Abilita l'output del debug"
+
+#: ../src/Server/Main.cs:131
+msgid "Show this help"
+msgstr "Mostra questo aiuto"
+
+#: ../src/Server/Main.cs:133
+msgid "Usage: smuxi-server [options]"
+msgstr "Utilizzo: smuxi-server [opzioni]"
+
+#: ../src/Server/Main.cs:135
+msgid "Options:"
+msgstr "Opzioni:"
+
+#: ../src/Server/Main.cs:146
+#, csharp-format
+msgid "Unknown option: '{0}'"
+msgstr "Opzione sconosciuta: «{0}»"
+
+#: ../src/Server/Main.cs:170
+#, csharp-format
+msgid "Command line error: {0}"
+msgstr "Errore da riga di comando: {0}"
+
+#: ../src/Server/Main.cs:214
+msgid ""
+"At most one of --add-user, --modify-user, and --delete-user may be used at a "
+"time."
+msgstr ""
+"È possibile utilizzare contemporaneamente al massimo uno fra «--add-user», "
+"«--modify-user» e «--delete-user»."
+
+#: ../src/Server/Main.cs:224
+msgid "You must specify a username with the --username option."
+msgstr ""
+"È necessario specificare un nome utente, mediante l'opzione «--username»."
+
+#: ../src/Server/Main.cs:230
+msgid "Username must not be empty."
+msgstr "Il nome utente non può essere vuoto."
+
+#: ../src/Server/Main.cs:240
+msgid "You must specify a password with the --password option."
+msgstr ""
+"È necessario specificare una password, mediante l'opzione «--password»."
+
+#: ../src/Server/Main.cs:246
+msgid "Password must not be empty."
+msgstr "La password non può essere vuota."
+
+#: ../src/Server/Main.cs:263
+#, csharp-format
+msgid "User \"{0}\" successfully added to server."
+msgstr "L'utente «{0}» è stato aggiunto al server."
+
+#: ../src/Server/Main.cs:272
+#, csharp-format
+msgid "User \"{0}\" successfully modified."
+msgstr "L'utente «{0}» è stato modificato."
+
+#: ../src/Server/Main.cs:281
+#, csharp-format
+msgid "User \"{0}\" successfully deleted from server."
+msgstr "L'utente «{0}» è stato eliminato dal server."
+
+#: ../src/Server/Main.cs:288
+msgid "Users:"
+msgstr "Utenti:"
diff --git a/po-Server/pt.po b/po-Server/pt.po
index 80cf9b8..4a16d78 100644
--- a/po-Server/pt.po
+++ b/po-Server/pt.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: smuxi-server \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
+"POT-Creation-Date: 2010-09-11 11:54+0200\n"
 "PO-Revision-Date: 2010-07-19 22:21+0100\n"
 "Last-Translator: Américo Monteiro <a_monteiro at netcabo.pt>\n"
 "Language-Team: Portuguese <traduz at debianpt.org>\n"
@@ -73,8 +73,8 @@ msgid ""
 "At most one of --add-user, --modify-user, and --delete-user may be used at a "
 "time."
 msgstr ""
-"No máximo pode ser usado apenas um de --add-user, --modify-user, e "
-"--delete-user de cada vez."
+"No máximo pode ser usado apenas um de --add-user, --modify-user, e --delete-"
+"user de cada vez."
 
 #: ../src/Server/Main.cs:224
 msgid "You must specify a username with the --username option."
@@ -110,5 +110,3 @@ msgstr "Utilizador \"{0}\" apagado com sucesso do servidor."
 #: ../src/Server/Main.cs:288
 msgid "Users:"
 msgstr "Utilizadores:"
-
-
diff --git a/po-Server/sv.po b/po-Server/sv.po
index e557fad..3ac9560 100644
--- a/po-Server/sv.po
+++ b/po-Server/sv.po
@@ -1,109 +1,140 @@
-# Smuxi - IRC client for sophisticated users
-# Copyright (C) 2005-2009 Mirco Bauer <meebey at meebey.net>
-# This file is distributed under the same license as the Smuxi package.
-#
-# Martin Bagge <brother at bsnet.se>, 2010
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+#   <flugsio at gmail.com>, 2011.
 msgid ""
 msgstr ""
-"Project-Id-Version: Smuxi Server\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-15 01:40+0200\n"
-"PO-Revision-Date: 2010-07-15 13:13+0100\n"
-"Last-Translator: Martin Bagge / brother <brother at bsnet.se>\n"
-"Language-Team: Swedish <tp-sv at listor.tp-sv.se>\n"
-"Language: sv\n"
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:21+0100\n"
+"PO-Revision-Date: 2011-12-31 11:01+0000\n"
+"Last-Translator: flugsio <flugsio at gmail.com>\n"
+"Language-Team: Swedish (http://www.transifex.net/projects/p/smuxi/team/sv/)\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: Swedish\n"
-"X-Poedit-Country: Sweden\n"
+"Language: sv\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/Server/Main.cs:69
+#: ../src/Server/Main.cs:71
 msgid "Add user to Server"
 msgstr "Lägg till användare till server"
 
-#: ../src/Server/Main.cs:78
+#: ../src/Server/Main.cs:80
 msgid "Modify existing user of Server"
 msgstr "Redigera existerande användare på server"
 
-#: ../src/Server/Main.cs:87
+#: ../src/Server/Main.cs:89
 msgid "Delete user from Server"
 msgstr "Radera användare från server"
 
-#: ../src/Server/Main.cs:96
+#: ../src/Server/Main.cs:98
 msgid "List all existing users of Server"
 msgstr "Visa alla existerande användare på Server"
 
-#: ../src/Server/Main.cs:105
+#: ../src/Server/Main.cs:107
 msgid "User to create, modify or delete"
 msgstr "Användare att skapa, redigera eller radera"
 
-#: ../src/Server/Main.cs:114
+#: ../src/Server/Main.cs:116
 msgid "Password of the user when creating or modifying a user"
 msgstr "Lösenord för användaren som skapas eller redigeras"
 
-#: ../src/Server/Main.cs:123
+#: ../src/Server/Main.cs:125
 msgid "Enable debug output"
 msgstr "Aktivera utskrift av fellogg"
 
-#: ../src/Server/Main.cs:131
+#: ../src/Server/Main.cs:133
+msgid ""
+"Optimize message buffers and exit (valid values: none, defrag, index, all)"
+msgstr ""
+"Optimera meddelandebuffertarna och avsluta (giltiga värden: none, defrag, "
+"index, all)"
+
+#: ../src/Server/Main.cs:146
 msgid "Show this help"
 msgstr "Visa den här hjälpen"
 
-#: ../src/Server/Main.cs:133
+#: ../src/Server/Main.cs:148
 msgid "Usage: smuxi-server [options]"
 msgstr "Använding: smuxi-server [flaggor]"
 
-#: ../src/Server/Main.cs:135
+#: ../src/Server/Main.cs:150
 msgid "Options:"
 msgstr "Flaggor:"
 
-#: ../src/Server/Main.cs:146
+#: ../src/Server/Main.cs:161
 #, csharp-format
 msgid "Unknown option: '{0}'"
 msgstr "Okänt alternativ: \"{0}\""
 
-#: ../src/Server/Main.cs:170
+#: ../src/Server/Main.cs:188
 #, csharp-format
 msgid "Command line error: {0}"
 msgstr "Komandoradsfel: {0}"
 
-#: ../src/Server/Main.cs:214
-msgid "At most one of --add-user, --modify-user, and --delete-user may be used at a time."
-msgstr "Endast en av --add-user, --modify-user eller --delete-user kan användas i taget."
+#: ../src/Server/Main.cs:232
+msgid ""
+"At most one of --add-user, --modify-user, and --delete-user may be used at a"
+" time."
+msgstr ""
+"Endast en av --add-user, --modify-user eller --delete-user kan användas i "
+"taget."
 
-#: ../src/Server/Main.cs:224
+#: ../src/Server/Main.cs:242
 msgid "You must specify a username with the --username option."
 msgstr "Du måste ange ett användarnamn med flaggan --username."
 
-#: ../src/Server/Main.cs:230
+#: ../src/Server/Main.cs:248
 msgid "Username must not be empty."
 msgstr "Användarnamnet får inte vara tomt."
 
-#: ../src/Server/Main.cs:240
+#: ../src/Server/Main.cs:258
 msgid "You must specify a password with the --password option."
 msgstr "Du måste ange ett lösenord med flaggan --pasword."
 
-#: ../src/Server/Main.cs:246
+#: ../src/Server/Main.cs:264
 msgid "Password must not be empty."
 msgstr "Lösenordet kan inte vara tomt."
 
-#: ../src/Server/Main.cs:263
+#: ../src/Server/Main.cs:283
+#, csharp-format
+msgid ""
+"Invalid optimization value passed to --optimize-message-buffer, valid values"
+" are: {0}"
+msgstr ""
+"Ogiltigt optimeringsvärde för --optimize-message-buffer, giltiga värden är: "
+"{0}"
+
+#: ../src/Server/Main.cs:303
 #, csharp-format
 msgid "User \"{0}\" successfully added to server."
 msgstr "Användaren \"{0}\" lades till korrekt i servern."
 
-#: ../src/Server/Main.cs:272
+#: ../src/Server/Main.cs:312
 #, csharp-format
 msgid "User \"{0}\" successfully modified."
 msgstr "Användaren \"{0}\" redigerades utan besvär."
 
-#: ../src/Server/Main.cs:281
+#: ../src/Server/Main.cs:321
 #, csharp-format
 msgid "User \"{0}\" successfully deleted from server."
 msgstr "Användaren \"{0}\" raderades från servern utan besvär."
 
-#: ../src/Server/Main.cs:288
+#: ../src/Server/Main.cs:328
 msgid "Users:"
 msgstr "Användare:"
 
+#: ../src/Server/Main.cs:376
+#, csharp-format
+msgid "Successfully optimized {0} message buffers."
+msgstr "Lyckades optimera {0} meddelandebufftertar."
+
+#: ../src/Server/Main.cs:389
+#, csharp-format
+msgid "Failed to optimize message buffers: {0}"
+msgstr "Misslyckades att optimera buffertar: {0}"
+
+
diff --git a/po-Server/zh_CN.po b/po-Server/zh_CN.po
new file mode 100644
index 0000000..0fd49f0
--- /dev/null
+++ b/po-Server/zh_CN.po
@@ -0,0 +1,133 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2011-12-29 09:21+0100\n"
+"PO-Revision-Date: 2010-11-30 04:13+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: Chinese (China) (http://www.transifex.net/projects/p/smuxi/team/zh_CN/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: zh_CN\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ../src/Server/Main.cs:71
+msgid "Add user to Server"
+msgstr "将用户添加到服务器"
+
+#: ../src/Server/Main.cs:80
+msgid "Modify existing user of Server"
+msgstr "修改服务器上现存的用户"
+
+#: ../src/Server/Main.cs:89
+msgid "Delete user from Server"
+msgstr "将用户从服务器删除"
+
+#: ../src/Server/Main.cs:98
+msgid "List all existing users of Server"
+msgstr "列出服务器上所有现存的用户"
+
+#: ../src/Server/Main.cs:107
+msgid "User to create, modify or delete"
+msgstr "要创建、修改或删除的用户"
+
+#: ../src/Server/Main.cs:116
+msgid "Password of the user when creating or modifying a user"
+msgstr "要创建或修改的用户的密码"
+
+#: ../src/Server/Main.cs:125
+msgid "Enable debug output"
+msgstr "启用调试输出"
+
+#: ../src/Server/Main.cs:133
+msgid ""
+"Optimize message buffers and exit (valid values: none, defrag, index, all)"
+msgstr ""
+
+#: ../src/Server/Main.cs:146
+msgid "Show this help"
+msgstr "显示本帮助"
+
+#: ../src/Server/Main.cs:148
+msgid "Usage: smuxi-server [options]"
+msgstr "用法: smuxi-server [选项]"
+
+#: ../src/Server/Main.cs:150
+msgid "Options:"
+msgstr "选项:"
+
+#: ../src/Server/Main.cs:161
+#, csharp-format
+msgid "Unknown option: '{0}'"
+msgstr "未知选项: '{0}'"
+
+#: ../src/Server/Main.cs:188
+#, csharp-format
+msgid "Command line error: {0}"
+msgstr "命令行错误: {0}"
+
+#: ../src/Server/Main.cs:232
+msgid ""
+"At most one of --add-user, --modify-user, and --delete-user may be used at a"
+" time."
+msgstr "--add-user、--modify-user 与 --delete-user 三者每次只能用一个。"
+
+#: ../src/Server/Main.cs:242
+msgid "You must specify a username with the --username option."
+msgstr "您必须通过 --username 选项指定用户名。"
+
+#: ../src/Server/Main.cs:248
+msgid "Username must not be empty."
+msgstr "用户名不能为空。"
+
+#: ../src/Server/Main.cs:258
+msgid "You must specify a password with the --password option."
+msgstr "您必须通过 --password 选项指定密码。"
+
+#: ../src/Server/Main.cs:264
+msgid "Password must not be empty."
+msgstr "密码不能为空。"
+
+#: ../src/Server/Main.cs:283
+#, csharp-format
+msgid ""
+"Invalid optimization value passed to --optimize-message-buffer, valid values"
+" are: {0}"
+msgstr ""
+
+#: ../src/Server/Main.cs:303
+#, csharp-format
+msgid "User \"{0}\" successfully added to server."
+msgstr "成功将用户 \"{0}\" 添加到服务器。"
+
+#: ../src/Server/Main.cs:312
+#, csharp-format
+msgid "User \"{0}\" successfully modified."
+msgstr "成功修改用户 \"{0}\"。"
+
+#: ../src/Server/Main.cs:321
+#, csharp-format
+msgid "User \"{0}\" successfully deleted from server."
+msgstr "成功将用户 \"{0}\" 从服务器删除。"
+
+#: ../src/Server/Main.cs:328
+msgid "Users:"
+msgstr "用户:"
+
+#: ../src/Server/Main.cs:376
+#, csharp-format
+msgid "Successfully optimized {0} message buffers."
+msgstr ""
+
+#: ../src/Server/Main.cs:389
+#, csharp-format
+msgid "Failed to optimize message buffers: {0}"
+msgstr ""
+
+
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
index 9fb353e..d44df2d 100644
--- a/po/POTFILES.skip
+++ b/po/POTFILES.skip
@@ -1,2 +1,3 @@
 src
 glade
+lib/
diff --git a/programs.m4 b/programs.m4
index 8273868..2bdacfe 100644
--- a/programs.m4
+++ b/programs.m4
@@ -7,7 +7,7 @@ AC_DEFUN([SHAMROCK_FIND_PROGRAM],
 AC_DEFUN([SHAMROCK_FIND_PROGRAM_OR_BAIL],
 [
 	SHAMROCK_FIND_PROGRAM($1, $2, no)
-	if test "x$1" = "xno"; then
+	if test "x$$1" = "xno"; then
 		AC_MSG_ERROR([You need to install '$2'])
 	fi
 ])
diff --git a/src/AssemblyVersion.cs b/src/AssemblyVersion.cs
index a3247a1..39ba5ed 100644
--- a/src/AssemblyVersion.cs
+++ b/src/AssemblyVersion.cs
@@ -36,5 +36,5 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 
-[assembly: AssemblyVersion("0.8")]
+[assembly: AssemblyVersion("0.8.9")]
 
diff --git a/src/Common/AssemblyInfo.cs b/src/Common/AssemblyInfo.cs
index bcabd49..72cf161 100644
--- a/src/Common/AssemblyInfo.cs
+++ b/src/Common/AssemblyInfo.cs
@@ -1,10 +1,4 @@
 /*
- * $Id: AssemblyInfo.cs 116 2006-04-22 22:14:09Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-Test/AssemblyInfo.cs $
- * $Rev: 116 $
- * $Author: meebey $
- * $Date: 2006-04-23 00:14:09 +0200 (Sun, 23 Apr 2006) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
  * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
@@ -32,7 +26,7 @@ using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 [assembly: AssemblyTitle("Smuxi - common library")]
-[assembly: AssemblyCopyright("2005-2010 (C) Mirco Bauer <meebey at meebey.net>")]
+[assembly: AssemblyCopyright("2005-2011 (C) Mirco Bauer <meebey at meebey.net>")]
 
 [assembly: AssemblyDelaySign(false)]
 [assembly: AssemblyKeyFile("")]
diff --git a/src/Common/AtomFeed.cs b/src/Common/AtomFeed.cs
new file mode 100644
index 0000000..d3e6a70
--- /dev/null
+++ b/src/Common/AtomFeed.cs
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2007 Carlos Martín Nieto <carlos at cmartin.tk>
+ *
+ * This file is released under the terms of the GNU GPLv2 or later
+ */
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml.Serialization;
+
+namespace Smuxi.Common
+{
+    [XmlType("feed")]
+    public class AtomFeed
+    {
+        [XmlElement("link")] public AtomLink[] Link = null;
+        
+        [XmlElement("updated")] public DateTime UpdateTime = DateTime.MinValue;
+        [XmlElement("modified")] public DateTime ModifyTime = DateTime.MinValue;
+        [XmlElement("title")] public AtomText Title = null;
+        [XmlElement("subtitle")] public string Subtitle = null;
+        [XmlElement("author")] public AtomAuthor Author = null;
+        
+        [XmlElement("entry")] public AtomEntry[] Entry;
+        
+        private static XmlSerializer ser = new XmlSerializer(typeof(AtomFeed),
+                                                             "http://www.w3.org/2005/Atom");
+
+        public static AtomFeed LoadFromXml(string file)
+        {
+            try {
+                FileStream fs = new FileStream(file, FileMode.Open);
+                return (AtomFeed)ser.Deserialize(fs);
+            } catch(FileNotFoundException){
+                Console.Error.WriteLine("Unable to open file");
+                return null;
+            }
+        }
+
+        public static AtomFeed Load(StringReader sr)
+        {
+            return (AtomFeed)ser.Deserialize(sr);
+        }
+
+        public static AtomFeed Load(Stream stream)
+        {
+            return (AtomFeed) ser.Deserialize(stream);
+        }
+
+        public DateTime Modified {
+            get {
+                if(UpdateTime != DateTime.MinValue){
+                    return UpdateTime;
+                } else {
+                    return ModifyTime;
+                }
+            }
+        }
+        
+        public DateTime Updated {
+            get {
+                return Modified;
+            }
+        }
+
+        public AtomLink LinkByType(string type)
+        {
+            foreach(AtomLink link in Link){
+                if(link.Type == type){
+                    return link;
+                }
+            }
+
+            return null;
+        }
+    }
+
+    [XmlType("author")]
+    public class AtomAuthor
+    {
+        [XmlElement("name")] public string Name;
+        [XmlElement("email")] public string Email;
+    }
+
+    [XmlType("link")]
+    public class AtomLink
+    {
+        [XmlAttribute("href")] public string Url = null;
+        [XmlAttribute("rel")] public string Rel = null;
+        [XmlAttribute("type")] public string Type = null;
+    }
+
+    [XmlType("entry")]
+    public class AtomEntry
+    {
+        [XmlElement("link")] public AtomLink[] Link = null;
+        [XmlElement("published")] public DateTime Published;
+        [XmlElement("updated")] public DateTime UpdateTime = DateTime.MinValue;
+        [XmlElement("modified")] public DateTime ModifyTime = DateTime.MinValue;
+        [XmlElement("title")] public AtomText Title;
+        [XmlElement("author")] public AtomAuthor Author = null;
+        [XmlElement("id")] public string Id;
+
+        [XmlElement("content")] public AtomText[] Content;
+        [XmlElement("summary")] public AtomText Summary;
+
+        public DateTime Modified {
+            get {
+                if(UpdateTime != DateTime.MinValue){
+                    return UpdateTime;
+                } else {
+                    return ModifyTime;
+                }
+            }
+        }
+        
+        public DateTime Updated {
+            get {
+                return Modified;
+            }
+        }
+
+        public AtomLink LinkByType(string type)
+        {
+            foreach(AtomLink link in Link){
+                if(link.Type == type){
+                        return link;
+                }
+            }
+            return null;
+        }
+
+        public AtomText ContentByType(string type)
+        {
+            foreach(AtomText text in Content){
+                if(text.Type == type){
+                    return text;
+                }
+            }
+
+            return null;
+        }
+    }
+
+    public class AtomText
+    {
+        [XmlText] public string Text = null;
+        [XmlAttribute("type")] public string Type = null;
+    }
+}
diff --git a/src/Common/Defines.cs b/src/Common/Defines.cs
index 5d1d5d4..1828932 100644
--- a/src/Common/Defines.cs
+++ b/src/Common/Defines.cs
@@ -1,10 +1,4 @@
 /*
- * $Id: Page.cs 111 2006-02-20 23:10:45Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-GtkGnome/Page.cs $
- * $Rev: 111 $
- * $Author: meebey $
- * $Date: 2006-02-21 00:10:45 +0100 (Tue, 21 Feb 2006) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
  * Copyright (c) 2008 Mirco Bauer <meebey at meebey.net>
@@ -32,8 +26,12 @@ namespace Smuxi.Common
 {
     public static class Defines
     {
+        public const string GitBranch   = "master";
+        public const string GitCommitHash = "b771b89";
+
         private static readonly string f_InstallPrefix = "/usr/local";
-        private static readonly string f_TwitterApiKey = "G0fxRfJqvcMPAuNat15YQ|j77MQDIuZJFa0CXehYzGPBZidF8DT3OXAi6sb5ucE";
+        private static readonly string f_DistVersion = "master/b771b89";
+        private static readonly string f_TwitterApiKey = "60QV2qQx9cS7y1BJDbgAA|2VgD6qQKddsF5HYQ0TrRgs3tFTnCwDONBmRlTmG658";
 
         public static string InstallPrefix {
             get {
@@ -46,5 +44,22 @@ namespace Smuxi.Common
                 return f_TwitterApiKey;
             }
         }
+
+        public static string GitVersion {
+            get {
+                if (String.IsNullOrEmpty(GitBranch) ||
+                    String.IsNullOrEmpty(GitCommitHash)) {
+                    return String.Empty;
+                }
+
+                return String.Format("{0}/{1}", GitBranch, GitCommitHash);
+            }
+        }
+
+        public static string DistVersion {
+            get {
+                return f_DistVersion;
+            }
+        }
     }
 }
diff --git a/src/Common/Defines.cs.in b/src/Common/Defines.cs.in
index b56231e..cc835ca 100644
--- a/src/Common/Defines.cs.in
+++ b/src/Common/Defines.cs.in
@@ -1,10 +1,4 @@
 /*
- * $Id: Page.cs 111 2006-02-20 23:10:45Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-GtkGnome/Page.cs $
- * $Rev: 111 $
- * $Author: meebey $
- * $Date: 2006-02-21 00:10:45 +0100 (Tue, 21 Feb 2006) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
  * Copyright (c) 2008 Mirco Bauer <meebey at meebey.net>
@@ -32,7 +26,11 @@ namespace Smuxi.Common
 {
     public static class Defines
     {
+        public const string GitBranch   = "@git_branch@";
+        public const string GitCommitHash = "@git_commit_hash@";
+
         private static readonly string f_InstallPrefix = "@prefix@";
+        private static readonly string f_DistVersion = "@dist_version@";
         private static readonly string f_TwitterApiKey = "@twitter_api_key@";
 
         public static string InstallPrefix {
@@ -46,5 +44,22 @@ namespace Smuxi.Common
                 return f_TwitterApiKey;
             }
         }
+
+        public static string GitVersion {
+            get {
+                if (String.IsNullOrEmpty(GitBranch) ||
+                    String.IsNullOrEmpty(GitCommitHash)) {
+                    return String.Empty;
+                }
+
+                return String.Format("{0}/{1}", GitBranch, GitCommitHash);
+            }
+        }
+
+        public static string DistVersion {
+            get {
+                return f_DistVersion;
+            }
+        }
     }
 }
diff --git a/src/Common/FastSerializer.cs b/src/Common/FastSerializer.cs
index ff4bbf5..e1a49fb 100644
--- a/src/Common/FastSerializer.cs
+++ b/src/Common/FastSerializer.cs
@@ -105,6 +105,10 @@ namespace Smuxi.Common
         /// send the length of the array which is needed when it is retrieved </summary>
 
         public override void Write(byte[] b) {
+            WriteBytes(b);
+        }
+
+        public void WriteBytes(byte[] b) {
          if (b==null) {
            Write(-1);
          } else {
@@ -253,9 +257,14 @@ namespace Smuxi.Common
         /// <summary> Adds the SerializationWriter buffer to the SerializationInfo at the end of GetObjectData(). </summary>
         public void AddToInfo(SerializationInfo info)
         {
-            byte[] b = ((MemoryStream) BaseStream).ToArray();
+            var b = GetData();
             info.AddValue("X", b, typeof(byte[]));
         }
+
+        public byte[] GetData()
+        {
+            return ((MemoryStream) BaseStream).ToArray();
+        }
     }
 
     /// <summary> SerializationReader.  Extends BinaryReader to add additional data types,
@@ -282,6 +291,12 @@ namespace Smuxi.Common
             return new SerializationReader(ms);
         }
 
+        public static SerializationReader GetReader(byte[] data)
+        {
+            MemoryStream ms = new MemoryStream(data);
+            return new SerializationReader(ms);
+        }
+
         /// <summary> Reads a string from the buffer.  Overrides the base implementation so it can cope with nulls. </summary>
         public override string ReadString()
         {
diff --git a/src/Common/IOSecurity.cs b/src/Common/IOSecurity.cs
new file mode 100644
index 0000000..9746315
--- /dev/null
+++ b/src/Common/IOSecurity.cs
@@ -0,0 +1,93 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2011 Mirco Bauer <meebey at meebey.net>
+//
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+//
+// 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
+
+using System;
+using System.IO;
+
+namespace Smuxi.Common
+{
+    public static class IOSecurity
+    {
+#if LOG4NET
+        private static readonly log4net.ILog f_Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+#endif
+
+        public static string GetFilteredPath(string path)
+        {
+            if (path == null) {
+                throw new ArgumentNullException("path");
+            }
+            if (path.Trim().Length == 0) {
+                throw new ArgumentException("Argument must not be empty.",
+                                            "path");
+            }
+
+            if (path.IndexOfAny(Path.GetInvalidPathChars()) != -1) {
+#if LOG4NET
+                f_Logger.Debug(
+                    "GetFilteredPath(): path: '" +
+                    path + "' contains invalid chars, removing them!"
+                );
+#endif
+                // remove invalid chars
+                foreach (char invalidChar in Path.GetInvalidPathChars()) {
+                    path = path.Replace(invalidChar.ToString(), String.Empty);
+                }
+            }
+            return path;
+        }
+
+        public static string GetFilteredFileName(string fileName)
+        {
+            return GetFilteredFileName(fileName, true);
+        }
+
+        public static string GetFilteredFileName(string fileName,
+                                                 bool filterSpaces)
+        {
+            if (fileName == null) {
+                throw new ArgumentNullException("fileName");
+            }
+            if (fileName.Trim().Length == 0) {
+                throw new ArgumentException("Argument must not be empty.",
+                                            "fileName");
+            }
+
+            if (filterSpaces) {
+                fileName = fileName.Replace(" ", "_");
+            }
+            if (fileName.IndexOfAny(Path.GetInvalidFileNameChars()) != -1) {
+#if LOG4NET
+                f_Logger.Debug(
+                    "GetValidFilename(): filename: '" + fileName + "' contains " +
+                     "invalid chars, removing them!"
+                );
+#endif
+                // remove invalid chars
+                foreach (char invalidChar in Path.GetInvalidFileNameChars()) {
+                    fileName = fileName.Replace(invalidChar.ToString(),
+                                                String.Empty);
+                }
+            }
+            fileName = fileName.Replace("..", String.Empty);
+            return fileName;
+        }
+    }
+}
diff --git a/src/Common/Makefile.am b/src/Common/Makefile.am
index 88927f3..c073d02 100644
--- a/src/Common/Makefile.am
+++ b/src/Common/Makefile.am
@@ -48,7 +48,9 @@ all: $(ASSEMBLY) $(PROGRAMFILES) $(LINUX_PKGCONFIG)
 FILES = \
 	$(top_srcdir)/src/AssemblyVersion.cs \
 	AssemblyInfo.cs \
+	AtomFeed.cs \
 	Crc32.cs \
+	IOSecurity.cs \
 	ITraceable.cs \
 	Trace.cs \
 	MD5.cs \
@@ -57,6 +59,7 @@ FILES = \
 	NDesk.Options.cs \
 	Defines.cs \
 	TaskQueue.cs \
+	ThreadPoolQueue.cs \
 	Platform.cs \
 	Pattern.cs 
 	
@@ -69,6 +72,8 @@ EXTRAS = \
 
 REFERENCES =  \
 	System \
+	System.Core \
+	System.Xml \
 	Mono.Posix
 
 DLL_REFERENCES = 
diff --git a/src/Common/Makefile.in b/src/Common/Makefile.in
index 034be96..1600f13 100644
--- a/src/Common/Makefile.in
+++ b/src/Common/Makefile.in
@@ -41,8 +41,11 @@ DIST_COMMON = $(srcdir)/Defines.cs.in $(srcdir)/Makefile.am \
 subdir = src/Common
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -83,6 +86,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -96,13 +100,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -143,13 +160,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -157,6 +176,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -167,13 +187,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -187,13 +216,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -201,7 +236,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -216,10 +253,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -284,7 +324,9 @@ LINUX_PKGCONFIG = \
 FILES = \
 	$(top_srcdir)/src/AssemblyVersion.cs \
 	AssemblyInfo.cs \
+	AtomFeed.cs \
 	Crc32.cs \
+	IOSecurity.cs \
 	ITraceable.cs \
 	Trace.cs \
 	MD5.cs \
@@ -293,6 +335,7 @@ FILES = \
 	NDesk.Options.cs \
 	Defines.cs \
 	TaskQueue.cs \
+	ThreadPoolQueue.cs \
 	Platform.cs \
 	Pattern.cs 
 
@@ -303,6 +346,8 @@ EXTRAS = \
 
 REFERENCES = \
 	System \
+	System.Core \
+	System.Xml \
 	Mono.Posix
 
 DLL_REFERENCES = 
@@ -338,7 +383,7 @@ build_references_ref = $(foreach ref, $(REFERENCES), $(if $(filter \
 	-pkg:%, $(ref)), $(ref), $(if $(filter -r:%, $(ref)), $(ref), \
 	-r:$(ref)))) $(foreach ref, $(DLL_REFERENCES), -r:$(ref)) \
 	$(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
 programfilesdir = @libdir@/@PACKAGE@
@@ -464,6 +509,12 @@ uninstall-pkglibSCRIPTS:
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(linuxdesktopapplicationsdir)" || $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)"
@@ -617,7 +668,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -671,7 +722,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-am
 
@@ -688,19 +739,21 @@ uninstall-am: uninstall-binSCRIPTS \
 
 .MAKE: install-am install-strip
 
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binSCRIPTS install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-linuxdesktopapplicationsDATA \
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binSCRIPTS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-man install-pdf \
 	install-pdf-am install-pkglibSCRIPTS install-programfilesDATA \
 	install-programfilesiconsDATA install-ps install-ps-am \
 	install-strip installcheck installcheck-am installdirs \
 	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
-	uninstall-binSCRIPTS uninstall-linuxdesktopapplicationsDATA \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am uninstall-binSCRIPTS \
+	uninstall-linuxdesktopapplicationsDATA \
 	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
 	uninstall-programfilesDATA uninstall-programfilesiconsDATA
 
diff --git a/src/Common/Platform.cs b/src/Common/Platform.cs
index 6e6998e..cb1b290 100644
--- a/src/Common/Platform.cs
+++ b/src/Common/Platform.cs
@@ -1,8 +1,6 @@
-// $Id$
-// 
 // Smuxi - Smart MUltipleXed Irc
 // 
-// Copyright (c) 2010 Mirco Bauer <meebey at meebey.net>
+// Copyright (c) 2010-2011 Mirco Bauer <meebey at meebey.net>
 // 
 // Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
 // 
@@ -152,9 +150,27 @@ namespace Smuxi.Common
                     Environment.SpecialFolder.LocalApplicationData
                 );
                 logPath = Path.Combine(logPath, "smuxi");
+                // FIXME: include session username
                 logPath = Path.Combine(logPath, "logs");
                 return logPath;
             }
         }
+
+        public static string GetBuffersPath(string username)
+        {
+            var dbPath = GetBuffersBasePath();
+            dbPath = Path.Combine(dbPath, IOSecurity.GetFilteredPath(username));
+            return dbPath;
+        }
+
+        public static string GetBuffersBasePath()
+        {
+            var dbPath = Environment.GetFolderPath(
+                Environment.SpecialFolder.LocalApplicationData
+            );
+            dbPath = Path.Combine(dbPath, "smuxi");
+            dbPath = Path.Combine(dbPath, "buffers");
+            return dbPath;
+        }
     }
 }
diff --git a/src/Common/ThreadPoolQueue.cs b/src/Common/ThreadPoolQueue.cs
new file mode 100644
index 0000000..e800d3d
--- /dev/null
+++ b/src/Common/ThreadPoolQueue.cs
@@ -0,0 +1,80 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2011 Mirco Bauer <meebey at meebey.net>
+//
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+//
+// 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
+
+using System;
+using System.Threading;
+using System.Collections.Generic;
+
+namespace Smuxi.Common
+{
+    public class ThreadPoolQueue
+    {
+        public int MaxWorkers { set; get; }
+        Queue<Action> ActionQueue { set; get; }
+        int ActiveWorkers;
+
+        public ThreadPoolQueue()
+        {
+            MaxWorkers = Environment.ProcessorCount;
+            ActionQueue = new Queue<Action>();
+        }
+
+        /// <remarks>
+        /// This method is thread safe.
+        /// </remarks>
+        public void Enqueue(Action action)
+        {
+            if (action == null) {
+                throw new ArgumentNullException("action");
+            }
+
+            lock (ActionQueue) {
+                ActionQueue.Enqueue(action);
+            }
+
+            CheckQueue();
+        }
+
+        void CheckQueue()
+        {
+            lock (ActionQueue) {
+                if (ActionQueue.Count == 0) {
+                    return;
+                }
+
+                if (ActiveWorkers >= MaxWorkers) {
+                    return;
+                }
+
+                var action = ActionQueue.Dequeue();
+                Interlocked.Increment(ref ActiveWorkers);
+
+                ThreadPool.QueueUserWorkItem(delegate {
+                    try {
+                        action();
+                    } finally {
+                        Interlocked.Decrement(ref ActiveWorkers);
+                        CheckQueue();
+                    }
+                });
+            }
+        }
+    }
+}
diff --git a/src/Common/Trace.cs b/src/Common/Trace.cs
index 4edae73..26ace5e 100644
--- a/src/Common/Trace.cs
+++ b/src/Common/Trace.cs
@@ -28,6 +28,7 @@
 
 using System;
 using System.Text;
+using System.Runtime.Remoting;
 using System.Reflection;
 using System.Collections;
 using System.Diagnostics;
@@ -115,37 +116,24 @@ namespace Smuxi.Common
         
         private static string _Parameterize(MethodBase method, params object[] parameters)
         {
-            StringBuilder res = new StringBuilder();
             ParameterInfo[] parameter_info = method.GetParameters();
-            if (parameter_info.Length > 0) {
-                res.Append(parameter_info[0].Name).Append(" = ");
+            if (parameter_info.Length == 0) {
+                return String.Empty;
+            }
+            StringBuilder res = new StringBuilder();
+            for (int i = 0; i < parameter_info.Length; i++) {
+                res.Append(parameter_info[i].Name).Append(" = ");
                 if (parameters == null) {
                     res.Append(_ParameterizeQuote(null));
-                } else if (parameters != null && parameters.Length > 0) {
-                    res.Append(_ParameterizeQuote(parameters[0]));
+                } else if (parameters != null && parameters.Length > i) {
+                    res.Append(_ParameterizeQuote(parameters[i]));
                 } else {
                     // empty array
                     res.Append("[]");
                 }
-                
-                for (int i = 1; i < parameter_info.Length; i++) {
-                    res.Append(", ");
-                    
-                    res.Append(parameter_info[i].Name).Append(" = ");
-                    if (parameters == null) {
-                        res.Append(_ParameterizeQuote(null));
-                    } else if (parameters != null && parameters.Length > i) {
-                        res.Append(_ParameterizeQuote(parameters[i]));
-                    } else {
-                        // empty array
-                        res.Append("[]");
-                    }
-                }
-            } else {
-                // no parameters
-                res.Append(String.Empty);
+                res.Append(", ");
             }
-
+            res.Remove(res.Length - 2, 2);
             return res.ToString();
         }
 
@@ -155,6 +143,11 @@ namespace Smuxi.Common
                 return "(null)";
             }
 
+            // OPT: tracing over remote objects is too expensive!
+            if (RemotingServices.IsTransparentProxy(obj)) {
+                return obj.GetType().ToString();
+            }
+
             StringBuilder line = new StringBuilder();
             if (obj is string) {
                 line.Append("'").Append(obj).Append("'");
diff --git a/src/Engine-IRC/AssemblyInfo.cs b/src/Engine-IRC/AssemblyInfo.cs
index a87f0e9..5fcb93d 100644
--- a/src/Engine-IRC/AssemblyInfo.cs
+++ b/src/Engine-IRC/AssemblyInfo.cs
@@ -1,10 +1,4 @@
 /*
- * $Id: AssemblyInfo.cs 211 2007-08-03 18:58:27Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Engine/AssemblyInfo.cs $
- * $Rev: 211 $
- * $Author: meebey $
- * $Date: 2007-08-03 20:58:27 +0200 (Fri, 03 Aug 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
  * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
@@ -32,7 +26,7 @@ using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 [assembly: AssemblyTitle("Smuxi - IRC protocol support for engine")]
-[assembly: AssemblyCopyright("2005-2010 (C) Mirco Bauer <meebey at meebey.net>")]
+[assembly: AssemblyCopyright("2005-2011 (C) Mirco Bauer <meebey at meebey.net>")]
 
 [assembly: AssemblyDelaySign(false)]
 [assembly: AssemblyKeyFile("")]
diff --git a/src/Engine-IRC/Config/IrcServerModel.cs b/src/Engine-IRC/Config/IrcServerModel.cs
new file mode 100644
index 0000000..6c254cc
--- /dev/null
+++ b/src/Engine-IRC/Config/IrcServerModel.cs
@@ -0,0 +1,34 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2011 Mirco Bauer <meebey at meebey.net>
+// 
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+// 
+// 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
+
+using System;
+using System.Collections.Generic;
+
+namespace Smuxi.Engine
+{
+    public class IrcServerModel : ServerModel
+    {
+        public List<string> Nicknames { get; set; }
+
+        public IrcServerModel()
+        {
+        }
+    }
+}
diff --git a/src/Engine-IRC/Makefile.am b/src/Engine-IRC/Makefile.am
index b45490b..c11ab2a 100644
--- a/src/Engine-IRC/Makefile.am
+++ b/src/Engine-IRC/Makefile.am
@@ -68,6 +68,7 @@ FILES = \
 	Protocols/Irc/IrcProtocolManager.cs \
 	Protocols/Irc/IrcPersonModel.cs \
 	Protocols/Irc/IrcTextColor.cs \
+	Config/IrcServerModel.cs \
 	$(top_srcdir)/src/AssemblyVersion.cs \
 	AssemblyInfo.cs 
 
diff --git a/src/Engine-IRC/Makefile.in b/src/Engine-IRC/Makefile.in
index f04e94a..a0e21c5 100644
--- a/src/Engine-IRC/Makefile.in
+++ b/src/Engine-IRC/Makefile.in
@@ -41,8 +41,11 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 subdir = src/Engine-IRC
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -83,6 +86,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -96,13 +100,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -143,13 +160,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -157,6 +176,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -167,13 +187,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -187,13 +216,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -201,7 +236,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -216,10 +253,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -309,6 +349,7 @@ FILES = \
 	Protocols/Irc/IrcProtocolManager.cs \
 	Protocols/Irc/IrcPersonModel.cs \
 	Protocols/Irc/IrcTextColor.cs \
+	Config/IrcServerModel.cs \
 	$(top_srcdir)/src/AssemblyVersion.cs \
 	AssemblyInfo.cs 
 
@@ -361,7 +402,7 @@ build_references_ref = $(foreach ref, $(REFERENCES), $(if $(filter \
 	-pkg:%, $(ref)), $(ref), $(if $(filter -r:%, $(ref)), $(ref), \
 	-r:$(ref)))) $(foreach ref, $(DLL_REFERENCES), -r:$(ref)) \
 	$(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
 programfilesdir = @libdir@/@PACKAGE@
@@ -486,6 +527,12 @@ uninstall-pkglibSCRIPTS:
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(linuxdesktopapplicationsdir)" || $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)"
@@ -639,7 +686,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -693,7 +740,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-am
 
@@ -710,19 +757,21 @@ uninstall-am: uninstall-binSCRIPTS \
 
 .MAKE: install-am install-strip
 
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binSCRIPTS install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-linuxdesktopapplicationsDATA \
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binSCRIPTS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-man install-pdf \
 	install-pdf-am install-pkglibSCRIPTS install-programfilesDATA \
 	install-programfilesiconsDATA install-ps install-ps-am \
 	install-strip installcheck installcheck-am installdirs \
 	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
-	uninstall-binSCRIPTS uninstall-linuxdesktopapplicationsDATA \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am uninstall-binSCRIPTS \
+	uninstall-linuxdesktopapplicationsDATA \
 	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
 	uninstall-programfilesDATA uninstall-programfilesiconsDATA
 
diff --git a/src/Engine-IRC/Protocols/Irc/IrcGroupPersonModel.cs b/src/Engine-IRC/Protocols/Irc/IrcGroupPersonModel.cs
index 9ca645b..7cb1e42 100644
--- a/src/Engine-IRC/Protocols/Irc/IrcGroupPersonModel.cs
+++ b/src/Engine-IRC/Protocols/Irc/IrcGroupPersonModel.cs
@@ -1,13 +1,7 @@
 /*
- * $Id: IrcChannelUser.cs 142 2007-01-02 22:19:08Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Engine/IrcChannelUser.cs $
- * $Rev: 142 $
- * $Author: meebey $
- * $Date: 2007-01-02 23:19:08 +0100 (Tue, 02 Jan 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2007, 2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -102,5 +96,35 @@ namespace Smuxi.Engine
             _IsOp    = sr.ReadBoolean();
             _IsVoice = sr.ReadBoolean();
         }
+
+        public override int CompareTo(ContactModel contact)
+        {
+            var ircContact = contact as IrcGroupPersonModel;
+            if (ircContact == null) {
+                return 1;
+            }
+
+            int status1 = 0;
+            if (IsOp) {
+                status1 += 2;
+            } else if (IsVoice) {
+                status1 += 1;
+            }
+
+            int status2 = 0;
+            if (ircContact.IsOp) {
+                status2 += 2;
+            } else if (ircContact.IsVoice) {
+                status2 += 1;
+            }
+
+            int res = status2.CompareTo(status1);
+            if (res != 0 ) {
+                return res;
+            }
+
+            // the status is equal, so the name decides
+            return base.CompareTo(contact);
+        }
     }
 }
diff --git a/src/Engine-IRC/Protocols/Irc/IrcMessageBuilder.cs b/src/Engine-IRC/Protocols/Irc/IrcMessageBuilder.cs
index f56a347..caabb6a 100644
--- a/src/Engine-IRC/Protocols/Irc/IrcMessageBuilder.cs
+++ b/src/Engine-IRC/Protocols/Irc/IrcMessageBuilder.cs
@@ -108,7 +108,7 @@ namespace Smuxi.Engine
                     string controlChars = controlChar.ToString();
                     switch (controlCode) {
                         case IrcControlCode.Clear:
-#if LOG4NET
+#if LOG4NET && MSG_DEBUG
                             Logger.Debug("AppendMessage(): found clear control character");
 #endif
                             bold = false;
@@ -120,30 +120,30 @@ namespace Smuxi.Engine
                             bg_color = IrcTextColor.Normal;
                             break;
                         case IrcControlCode.Bold:
-#if LOG4NET
+#if LOG4NET && MSG_DEBUG
                             Logger.Debug("AppendMessage(): found bold control character");
 #endif
                             bold = !bold;
                             break;
                         case IrcControlCode.Underline:
-#if LOG4NET
+#if LOG4NET && MSG_DEBUG
                             Logger.Debug("AppendMessage(): found underline control character");
 #endif
                             underline = !underline;
                             break;
                         case IrcControlCode.Italic:
-#if LOG4NET
+#if LOG4NET && MSG_DEBUG
                             Logger.Debug("AppendMessage(): found italic control character");
 #endif
                             italic = !italic;
                             break;
                         case IrcControlCode.Color:
-#if LOG4NET
+#if LOG4NET && MSG_DEBUG
                             Logger.Debug("AppendMessage(): found color control character");
 #endif
                             color = !color;
                             string colorMessage = msg.Substring(controlPos);
-#if LOG4NET
+#if LOG4NET && MSG_DEBUG
                             Logger.Debug("AppendMessage(): colorMessage: '" + colorMessage + "'");
 #endif
                             Match match = Regex.Match(colorMessage, (char)IrcControlCode.Color + "(?<fg>[0-9][0-9]?)(,(?<bg>[0-9][0-9]?))?");
@@ -151,7 +151,7 @@ namespace Smuxi.Engine
                                 controlChars = match.Value;
                                 int color_code;
                                 if (match.Groups["fg"] != null) {
-#if LOG4NET
+#if LOG4NET && MSG_DEBUG
                                     Logger.Debug("AppendMessage(): match.Groups[fg].Value: " + match.Groups["fg"].Value);
 #endif
                                     try {
@@ -162,7 +162,7 @@ namespace Smuxi.Engine
                                     }
                                 }
                                 if (match.Groups["bg"] != null) {
-#if LOG4NET
+#if LOG4NET && MSG_DEBUG
                                     Logger.Debug("AppendMessage(): match.Groups[bg].Value: " + match.Groups["bg"].Value);
 #endif
                                     try {
@@ -177,13 +177,13 @@ namespace Smuxi.Engine
                                 fg_color = IrcTextColor.Normal;
                                 bg_color = IrcTextColor.Normal;
                             }
-#if LOG4NET
+#if LOG4NET && MSG_DEBUG
                             Logger.Debug("AppendMessage(): fg_color.HexCode: " + String.Format("0x{0:X6}", fg_color.HexCode));
                             Logger.Debug("AppendMessage(): bg_color.HexCode: " + String.Format("0x{0:X6}", bg_color.HexCode));
 #endif
                             break;
                     }
-#if LOG4NET
+#if LOG4NET && MSG_DEBUG
                     Logger.Debug("AppendMessage(): controlChars.Length: " + controlChars.Length);
 #endif
 
diff --git a/src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs b/src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs
index 1744133..c246c19 100644
--- a/src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs
+++ b/src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs
@@ -1,7 +1,7 @@
 /*
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2010 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -30,6 +30,7 @@ using System.Collections;
 using System.Collections.Generic;
 using Meebey.SmartIrc4net;
 using Smuxi.Common;
+using IrcProxyType = Meebey.SmartIrc4net.ProxyType;
 
 namespace Smuxi.Engine
 {
@@ -61,6 +62,12 @@ namespace Smuxi.Engine
         private List<string>    _ActiveChannelJoinList = new List<string>();
         private AutoResetEvent  _ActiveChannelJoinHandle = new AutoResetEvent(false);
 
+        bool HasListMaskSearchSupport { get; set; }
+        bool HasSafeListSupport { get; set; }
+        IList<ChannelInfo> NetworkChannels { get; set; }
+        DateTime NetworkChannelsAge { get; set; }
+        TimeSpan NetworkChannelsMaxAge { get; set; }
+
         public override bool IsConnected {
             get {
                 if ((_IrcClient != null) &&
@@ -137,7 +144,9 @@ namespace Smuxi.Engine
         public IrcProtocolManager(Session session) : base(session)
         {
             Trace.Call(session);
-            
+
+            NetworkChannelsMaxAge = TimeSpan.FromMinutes(5);
+
             _IrcClient = new IrcFeatures();
             _IrcClient.AutoRetry = true;
             // keep retrying to connect forever
@@ -185,6 +194,8 @@ namespace Smuxi.Engine
             _IrcClient.OnCtcpReply      += new CtcpEventHandler(_OnCtcpReply);
             _IrcClient.OnWho            += OnWho;
             _IrcClient.OnInvite         += OnInvite;
+            _IrcClient.OnReadLine       += OnReadLine;
+            _IrcClient.OnWriteLine      += OnWriteLine;
 
             _IrcClient.CtcpUserInfo = (string) Session.UserConfig["Connection/Realname"];
             // disabled as we don't use / support DCC yet
@@ -238,6 +249,16 @@ namespace Smuxi.Engine
             Session.AddMessageToChat(_NetworkChat, builder.ToMessage());
         }
 
+        void OnReadLine(object sender, ReadLineEventArgs e)
+        {
+            DebugRead(e.Line);
+        }
+
+        void OnWriteLine(object sender, WriteLineEventArgs e)
+        {
+            DebugWrite(e.Line);
+        }
+
         public override string ToString()
         {
             string result = null;
@@ -270,24 +291,21 @@ namespace Smuxi.Engine
             return result;
         }
 
-        public override void Connect(FrontendManager fm, string server, int port, string user, string pass)
+        public override void Connect(FrontendManager fm, ServerModel server)
         {
-            Trace.Call(fm, server, port, user, pass);
+            Trace.Call(fm, server);
+
+            if (fm == null) {
+                throw new ArgumentNullException("fm");
+            }
+            if (server == null) {
+                throw new ArgumentNullException("server");
+            }
 
-            string[] nicks = (string[]) Session.UserConfig["Connection/Nicknames"];
-            Connect(fm, server, port, nicks, user, pass);
-        }
-        
-        public void Connect(FrontendManager fm, string server, int port, string[] nicks, string user, string pass)
-        {
-            Trace.Call(fm, server, port, nicks, user, pass);
-            
             _FrontendManager = fm;
-            _Host = server;
-            _Port = port;
-            _Nicknames = nicks;
-            _Username = user;
-            _Password = pass;
+            _ServerModel = server;
+
+            ApplyConfig(Session.UserConfig, server);
 
             // add fallbacks if only one nick was specified, else we get random
             // number nicks when nick collisions happen
@@ -296,21 +314,10 @@ namespace Smuxi.Engine
             }
 
             // TODO: use config for single network chat or once per network manager
-            var servers = new ServerListController(Session.UserConfig);
-            var serverModel = servers.GetServer(Protocol, server);
-            _ServerModel = serverModel;
-            ApplyConfig(Session.UserConfig, serverModel);
-
-            string network;
-            if (serverModel != null && !String.IsNullOrEmpty(serverModel.Network)) {
-                network = serverModel.Network;
-            } else {
-                network = server;
-            }
+            _NetworkChat = Session.CreateChat<ProtocolChatModel>(
+                _Network, "IRC " + _Network, this
+            );
 
-            _Network = network;
-            _NetworkChat = new ProtocolChatModel(network, "IRC " + network, this);
-            
             // BUG: race condition when we use Session.AddChat() as it pushes this already
             // to the connected frontend and the frontend will sync and get the page 2 times!
             //Session.Chats.Add(_NetworkChat);
@@ -320,11 +327,18 @@ namespace Smuxi.Engine
 
             _RunThread = new Thread(new ThreadStart(_Run));
             _RunThread.IsBackground = true;
-            _RunThread.Name = "IrcProtocolManager ("+server+":"+port+") listener";
+            _RunThread.Name = String.Format(
+                "IrcProtocolManager ({0}:{1}) listener",
+                server.Hostname, server.Port
+             );
             _RunThread.Start();
             
             _LagWatcherThread = new Thread(new ThreadStart(_LagWatcher));
-            _LagWatcherThread.Name = "IrcProtocolManager ("+server+":"+port+") lag watcher";
+            _LagWatcherThread.IsBackground = true;
+            _LagWatcherThread.Name = String.Format(
+                "IrcProtocolManager ({0}:{1}) lag watcher",
+                server.Hostname, server.Port
+             );
             _LagWatcherThread.Start();
         }
 
@@ -348,6 +362,17 @@ namespace Smuxi.Engine
                 if (realname.Trim().Length == 0) {
                     realname = "unset";
                 }
+                if (!Regex.IsMatch(_Username, "^[a-z0-9]+$", RegexOptions.IgnoreCase)) {
+                    var builder = CreateMessageBuilder();
+                    builder.AppendEventPrefix();
+                    builder.AppendWarningText(
+                        "Warning: Your username (ident) contains special " +
+                        "characters which the IRC server might refuse. " +
+                        "If this happens please change your username in the " +
+                        "server settings."
+                    );
+                    Session.AddMessageToChat(_NetworkChat, builder.ToMessage());
+                }
                 _IrcClient.Login(_Nicknames, realname, 0, _Username, _Password);
                 
                 foreach (string command in (string[]) Session.UserConfig["Connection/OnConnectCommands"]) {
@@ -466,20 +491,48 @@ namespace Smuxi.Engine
         public override IList<GroupChatModel> FindGroupChats(GroupChatModel filter)
         {
             Trace.Call(filter);
-            
-            string channel = null;
-            if (filter != null) {
-                if (!String.IsNullOrEmpty(filter.Name) &&
-                    !filter.Name.StartsWith("*") && !filter.Name.EndsWith("*")) {
-                    channel = String.Format("*{0}*", filter.Name);
+
+            // invalidate channel list cache when too old
+            if (NetworkChannels != null &&
+                (DateTime.UtcNow - NetworkChannelsAge) > NetworkChannelsMaxAge) {
+                NetworkChannels = null;
+            }
+
+            string searchPattern = null;
+            if (filter == null || String.IsNullOrEmpty(filter.Name)) {
+                // full channel list
+            } else {
+                if (!filter.Name.StartsWith("*") && !filter.Name.EndsWith("*")) {
+                    searchPattern = String.Format("*{0}*", filter.Name);
                 } else {
-                    channel = filter.Name;
+                    searchPattern = filter.Name;
+                }
+            }
+            var channels = NetworkChannels;
+            if (channels == null && HasSafeListSupport) {
+                // fetch and cache full channel list from server
+                channels = _IrcClient.GetChannelList(String.Empty);
+                NetworkChannels = channels;
+                NetworkChannelsAge = DateTime.UtcNow;
+            } else if (channels == null && searchPattern != null &&
+                HasListMaskSearchSupport) {
+                channels = _IrcClient.GetChannelList(searchPattern);
+            } else if (channels == null) {
+                // Houston, we have a problem
+                // no safelist and empty search pattern, the IRCd might kill us!
+                channels = _IrcClient.GetChannelList(String.Empty);
+                NetworkChannels = channels;
+                NetworkChannelsAge = DateTime.UtcNow;
+            }
+
+            List<GroupChatModel> chats = new List<GroupChatModel>(channels.Count);
+            foreach (ChannelInfo info in channels) {
+                if (channels == NetworkChannels &&
+                    searchPattern != null &&
+                    !Pattern.IsMatch(info.Channel, searchPattern)) {
+                    continue;
                 }
-            }
-            
-            IList<ChannelInfo> infos = _IrcClient.GetChannelList(channel);
-            List<GroupChatModel> chats = new List<GroupChatModel>(infos.Count);
-            foreach (ChannelInfo info in infos) {
+
                 GroupChatModel chat = new GroupChatModel(
                     info.Channel,
                     info.Channel,
@@ -512,22 +565,24 @@ namespace Smuxi.Engine
             }
         }
 
-        public override void CloseChat(FrontendManager fm, ChatModel chat)
+        public override void CloseChat(FrontendManager fm, ChatModel chatInfo)
         {
-            Trace.Call(fm, chat);
+            Trace.Call(fm, chatInfo);
 
             if (fm == null) {
-                throw new ArgumentNullException("chat");
+                throw new ArgumentNullException("fm");
             }
-            if (chat == null) {
-                throw new ArgumentNullException("chat");
+            if (chatInfo == null) {
+                throw new ArgumentNullException("chatInfo");
             }
 
             // get real chat object from session
-            chat = Session.GetChat(chat.ID, chat.ChatType, this);
+            var chat = GetChat(chatInfo.ID, chatInfo.ChatType);
             if (chat == null) {
 #if LOG4NET
-                _Logger.Error("CloseChat(): Session.GetChat(" + chat.ID + ", " + chat.ChatType + ", this) return null!");
+                _Logger.Error("CloseChat(): Session.GetChat(" +
+                              chatInfo.ID + ", " + chatInfo.ChatType + ")" +
+                              " returned null!");
 #endif
                 return;
             }
@@ -558,6 +613,10 @@ namespace Smuxi.Engine
 
             switch (status) {
                 case PresenceStatus.Online:
+                    if (!_IrcClient.IsAway) {
+                        // nothing to do
+                        return;
+                    }
                     _IrcClient.RfcAway();
                     break;
                 case PresenceStatus.Away:
@@ -813,9 +872,7 @@ namespace Smuxi.Engine
             var builder = CreateMessageBuilder();
             // TRANSLATOR: this line is used as label / category for a
             // list of commands below
-            var text = builder.CreateText("[{0}]", _("IrcProtocolManager Commands"));
-            text.Bold = true;
-            builder.AppendText(text);
+            builder.AppendHeader(_("IrcProtocolManager Commands"));
             cd.FrontendManager.AddMessageToChat(cd.Chat, builder.ToMessage());
 
             string[] help = {
@@ -867,18 +924,17 @@ namespace Smuxi.Engine
         public void CommandConnect(CommandModel cd)
         {
             FrontendManager fm = cd.FrontendManager;
-            
-            string server;
+
+            var server = new IrcServerModel();
             if (cd.DataArray.Length >= 3) {
-                server = cd.DataArray[2];
+                server.Hostname = cd.DataArray[2];
             } else {
-                server = "localhost";
+                server.Hostname = "localhost";
             }
             
-            int port;
             if (cd.DataArray.Length >= 4) {
                 try {
-                    port = Int32.Parse(cd.DataArray[3]);
+                    server.Port = Int32.Parse(cd.DataArray[3]);
                 } catch (FormatException) {
                     fm.AddTextToChat(
                         cd.Chat,
@@ -892,26 +948,20 @@ namespace Smuxi.Engine
                     return;
                 }
             } else {
-                port = 6667;
+                server.Port = 6667;
             }
             
-            string pass;                
-            if (cd.DataArray.Length >=5) {
-                pass = cd.DataArray[4];
-            } else {
-                pass = null;
+            if (cd.DataArray.Length >= 5) {
+                server.Password = cd.DataArray[4];
             }
             
-            string[] nicks;
             if (cd.DataArray.Length >= 6) {
-                nicks = new string[] {cd.DataArray[5]};
-            } else {
-                nicks = (string[])Session.UserConfig["Connection/Nicknames"];
+                var nicks = new List<string>(1);
+                nicks.Add(cd.DataArray[5]);
+                server.Nicknames = nicks;
             }
-            
-            string username = (string)Session.UserConfig["Connection/Username"];
-            
-            Connect(fm, server, port, nicks, username, pass);
+
+            Connect(fm, server);
         }
         
         public void CommandSay(CommandModel cd)
@@ -1194,7 +1244,8 @@ namespace Smuxi.Engine
                 chat = GetChat(nickname, ChatType.Person);
                 if (chat == null) {
                     var person = CreatePerson(nickname);
-                    chat = new PersonChatModel(person, nickname, nickname, this);
+                    chat = Session.CreatePersonChat(person, nickname,
+                                                    nickname, this);
                     Session.AddChat(chat);
                     Session.SyncChat(chat);
                 }
@@ -1819,7 +1870,7 @@ namespace Smuxi.Engine
             _IrcClient.SendMessage(SendType.Action, cd.Chat.ID, cd.Parameter);
 
             var builder = CreateMessageBuilder();
-            builder.AppendAction();
+            builder.AppendActionPrefix();
             builder.AppendIdendityName(MyPerson);
             builder.AppendText(" ");
             builder.AppendMessage(cd.Parameter);
@@ -1953,7 +2004,9 @@ namespace Smuxi.Engine
         {
             Regex regex;
             // First check to see if our current nick is in there.
-            regex = new Regex(String.Format("(^|\\W){0}($|\\W)", _IrcClient.Nickname), RegexOptions.IgnoreCase);
+            regex = new Regex(String.Format("(^|\\W){0}($|\\W)",
+                                            Regex.Escape(_IrcClient.Nickname)),
+                              RegexOptions.IgnoreCase);
             if (regex.Match(msg).Success) {
                 return true;
             } else {
@@ -2031,8 +2084,36 @@ namespace Smuxi.Engine
 
         private void ApplyConfig(UserConfig config, ServerModel server)
         {
-            if (String.IsNullOrEmpty(_Username)) {
+            _Host = server.Hostname;
+            _Port = server.Port;
+            if (String.IsNullOrEmpty(server.Network)) {
+                _Network = server.Hostname;
+            } else {
+                _Network = server.Network;
+            }
+            if (String.IsNullOrEmpty(server.Username)) {
                 _Username = (string) config["Connection/Username"];
+            } else {
+                _Username = server.Username;
+            }
+            _Password = server.Password;
+
+            // internal fallbacks
+            if (String.IsNullOrEmpty(_Username)) {
+                _Username = "smuxi";
+            }
+
+            // IRC specific settings
+            if (server is IrcServerModel) {
+                var ircServer = (IrcServerModel) server;
+                if (ircServer.Nicknames != null && ircServer.Nicknames.Count > 0) {
+                    _Nicknames = ircServer.Nicknames.ToArray();
+                }
+            }
+
+            // global fallbacks
+            if (_Nicknames == null) {
+                _Nicknames = (string[]) config["Connection/Nicknames"];
             }
 
             string encodingName = (string) config["Connection/Encoding"];
@@ -2050,29 +2131,33 @@ namespace Smuxi.Engine
                 }
             }
 
-            string proxyTypeStr = (string) config["Connection/ProxyType"];
-            if (!String.IsNullOrEmpty(proxyTypeStr)) {
-                var proxyType = ProxyType.None;
+            var proxySettings = new ProxySettings();
+            proxySettings.ApplyConfig(config);
+            var protocol = server.UseEncryption ? "ircs" : "irc";
+            var serverUri = String.Format("{0}://{1}:{2}", protocol,
+                                          server.Hostname, server.Port);
+            var proxy = proxySettings.GetWebProxy(serverUri);
+            if (proxy == null) {
+                _IrcClient.ProxyType = IrcProxyType.None;
+            } else {
+                var proxyScheme = proxy.Address.Scheme;
+                var ircProxyType = IrcProxyType.None;
                 try {
-                    proxyType = (ProxyType) Enum.Parse(typeof(ProxyType),
-                                                       proxyTypeStr);
+                    // HACK: map proxy scheme to SmartIrc4net's ProxyType
+                    ircProxyType = (IrcProxyType) Enum.Parse(
+                        typeof(IrcProxyType), proxyScheme, true
+                    );
                 } catch (ArgumentException ex) {
 #if LOG4NET
                     _Logger.Error("ApplyConfig(): Couldn't parse proxy type: " +
-                                  proxyType, ex);
+                                  proxyScheme, ex);
 #endif
                 }
-
-                // HACK: map our ProxyType to SmartIrc4net's ProxyType
-                var ircProxyType =
-                    (Meebey.SmartIrc4net.ProxyType) Enum.Parse(
-                        typeof(ProxyType), proxyType.ToString(), true
-                    );
                 _IrcClient.ProxyType = ircProxyType;
-                _IrcClient.ProxyHost = (string) config["Connection/ProxyHostname"];
-                _IrcClient.ProxyPort = (int) config["Connection/ProxyPort"];
-                _IrcClient.ProxyUsername = (string) config["Connection/ProxyUsername"];
-                _IrcClient.ProxyPassword = (string) config["Connection/ProxyPassword"];
+                _IrcClient.ProxyHost = proxy.Address.Host;
+                _IrcClient.ProxyPort = proxy.Address.Port;
+                _IrcClient.ProxyUsername = proxySettings.ProxyUsername;
+                _IrcClient.ProxyPassword = proxySettings.ProxyPassword;
             }
 
             if (server != null) {
@@ -2143,11 +2228,31 @@ namespace Smuxi.Engine
                     }
                     string[] supportList = line.Split(' ');
                     foreach (string support in supportList) {
-                        if (support.StartsWith("NETWORK=")) {
-                            _Network = support.Split('=')[1];
+                        string supportKey = null;
+                        string supportValue = null;
+                        if (support.Contains("=")) {
+                            supportKey = support.Split('=')[0];
+                            supportValue = support.Split('=')[1];
+                        } else {
+                            supportKey = support;
+                            supportValue = null;
+                        }
+                        switch (supportKey) {
+                            case "NETWORK":
+                                _Network = supportValue;
 #if LOG4NET
-                            _Logger.Debug("_OnRawMessage(): detected IRC network: '" + _Network + "'");
+                                _Logger.Debug(
+                                    "_OnRawMessage(): detected IRC network: " +
+                                    "'" + _Network + "'"
+                                );
 #endif
+                                break;
+                            case "ELIST":
+                                HasListMaskSearchSupport = supportValue.Contains("M");
+                                break;
+                            case "SAFELIST":
+                                HasSafeListSupport = true;
+                                break;
                         }
                     }
                     break;
@@ -2176,6 +2281,12 @@ namespace Smuxi.Engine
                     } else {
                         Session.AddTextToChat(_NetworkChat, msg);
                     }
+
+                    // if our own nick is temporarily not available then we
+                    // need to deal this like an already used nick
+                    if (chan == _IrcClient.Nickname) {
+                        AutoRenick();
+                    }
                     break;
                 case ReplyCode.ErrorBannedFromChannel:
                     _OnErrorBannedFromChannel(e);
@@ -2303,23 +2414,7 @@ namespace Smuxi.Engine
             builder.AppendText(_("is already in use"));
             Session.AddMessageToChat(_NetworkChat, builder.ToMessage());
 
-            if (!_IrcClient.AutoNickHandling &&
-                !_IrcClient.IsRegistered) {
-                // allright, we have to care then and try a different nick as
-                // we don't have a nick yet
-                string nick;
-                if (_CurrentNickname == _Nicknames.Length - 1) {
-                    // we tried all nicks already, so fallback to random
-                     Random rand = new Random();
-                    int number = rand.Next(999);
-                    nick = _Nicknames[_CurrentNickname].Substring(0, 5) + number;
-                } else {
-                    _CurrentNickname++;
-                    nick = _Nicknames[_CurrentNickname];
-                }
-                
-                _IrcClient.RfcNick(nick, Priority.Critical);
-            }
+            AutoRenick();
         }
         
         private void _OnErrorBannedFromChannel(IrcEventArgs e)
@@ -2450,7 +2545,7 @@ namespace Smuxi.Engine
 
         private void _OnChannelMessage(object sender, IrcEventArgs e)
         {
-            ChatModel chat = GetChat(e.Data.Channel, ChatType.Group);
+            ChatModel chat = GetChat(e.Data.Channel, ChatType.Group) ?? _NetworkChat;
 
             var builder = CreateMessageBuilder();
             builder.AppendMessage(GetPerson(chat, e.Data.Nick), e.Data.Message);
@@ -2465,7 +2560,7 @@ namespace Smuxi.Engine
             ChatModel chat = GetChat(e.Data.Channel, ChatType.Group);
 
             var builder = CreateMessageBuilder();
-            builder.AppendAction();
+            builder.AppendActionPrefix();
             builder.AppendIdendityName(GetPerson(chat, e.Data.Nick));
             builder.AppendText(" ");
             builder.AppendMessage(e.ActionMessage);
@@ -2496,7 +2591,8 @@ namespace Smuxi.Engine
                 var person = CreatePerson(e.Data.Nick);
                 person.Ident = e.Data.Ident;
                 person.Host = e.Data.Host;
-                chat = new PersonChatModel(person, e.Data.Nick, e.Data.Nick, this);
+                chat = Session.CreatePersonChat(person, e.Data.Nick,
+                                                e.Data.Nick, this);
                 newChat = true;
             }
 
@@ -2526,12 +2622,13 @@ namespace Smuxi.Engine
                 var person = CreatePerson(e.Data.Nick);
                 person.Ident = e.Data.Ident;
                 person.Host = e.Data.Host;
-                chat = new PersonChatModel(person, e.Data.Nick, e.Data.Nick, this);
+                chat = Session.CreatePersonChat(person, e.Data.Nick,
+                                                e.Data.Nick, this);
                 newChat = true;
             }
 
             var builder = CreateMessageBuilder();
-            builder.AppendAction();
+            builder.AppendActionPrefix();
             builder.AppendIdendityName(chat.Person, true);
             builder.AppendSpace();
             builder.AppendMessage(e.ActionMessage);
@@ -2553,25 +2650,35 @@ namespace Smuxi.Engine
         
         private void _OnQueryNotice(object sender, IrcEventArgs e)
         {
-            ChatModel chat = null;
-            bool newChat = false;
+            var targetChats = new List<ChatModel>();
             if (e.Data.Nick != null) {
-                chat = GetChat(e.Data.Nick, ChatType.Person);
+                var chat = (PersonChatModel) GetChat(e.Data.Nick, ChatType.Person);
+                if (chat != null) {
+                    targetChats.Add(chat);
+                }
+            }
+            if (targetChats.Count == 0 && e.Data.Nick != null) {
+                // always show on server chat
+                targetChats.Add(_NetworkChat);
+                // check if we share a channel with the sender
+                lock (Chats) {
+                    foreach (var chat in Chats) {
+                        if (!(chat is GroupChatModel)) {
+                            continue;
+                        }
+                        var groupChat = (GroupChatModel) chat;
+                        if (groupChat.Persons == null) {
+                            continue;
+                        }
+                        if (groupChat.Persons.ContainsKey(e.Data.Nick)) {
+                            targetChats.Add(groupChat);
+                        }
+                    }
+                }
             }
-            if (chat == null) {
+            if (targetChats.Count == 0) {
                 // use server chat as fallback
-                if (e.Data.Nick == null) {
-                    // this seems to be a notice from the server
-                    chat = _NetworkChat;
-                } else {
-                    // create new chat
-                    IrcPersonModel person = CreatePerson(e.Data.Nick,
-                                                         null,
-                                                         e.Data.Ident,
-                                                         e.Data.Host);
-                    chat = new PersonChatModel(person, e.Data.Nick, e.Data.Nick, this);
-                    newChat = true;
-                }
+                targetChats.Add(_NetworkChat);
             }
 
             var builder = CreateMessageBuilder();
@@ -2580,23 +2687,17 @@ namespace Smuxi.Engine
                 builder.AppendText("!{0} ", e.Data.From);
             } else {
                 builder.AppendText("-");
-                builder.AppendIdendityName(GetPerson(chat, e.Data.Nick));
+                builder.AppendIdendityName(GetPerson(targetChats[0],
+                                                     e.Data.Nick));
                 builder.AppendText(" ({0}@{1})- ", e.Data.Ident, e.Data.Host);
             }
             builder.AppendMessage(e.Data.Message);
             var msg = builder.ToMessage();
             MarkHighlights(msg);
 
-            if (newChat) {
-                // don't create chats for filtered messages
-                if (Session.IsFilteredMessage(chat, msg)) {
-                    Session.LogMessage(chat, msg, true);
-                    return;
-                }
-                Session.AddChat(chat);
-                Session.SyncChat(chat);
+            foreach (var targetChat in targetChats) {
+                Session.AddMessageToChat(targetChat, msg);
             }
-            Session.AddMessageToChat(chat, msg);
         }
 
         private void _OnJoin(object sender, JoinEventArgs e)
@@ -2609,7 +2710,10 @@ namespace Smuxi.Engine
                 }
 
                 if (groupChat == null) {
-                    groupChat = new GroupChatModel(e.Channel, e.Channel, this);
+                    groupChat = Session.CreateChat<GroupChatModel>(
+                        e.Channel, e.Channel, this
+                    );
+                    groupChat.UnsafePersonsComparer = StringComparer.OrdinalIgnoreCase;
                     Session.AddChat(groupChat);
                 } else {
                     // chat still exists, so we we only need to enable it
@@ -2890,9 +2994,10 @@ namespace Smuxi.Engine
                 builder.AppendIdendityName(GetPerson(cchat, e.Who));
             }
 
-            // TRANSLATOR: do NOT change the position of {0}!
+            // TRANSLATOR: do NOT change the position of {0} and {2}!
             builder.AppendText(_("{0} changed the topic of {1} to: {2}"),
-                             String.Empty, e.Channel, e.NewTopic);
+                             String.Empty, e.Channel, String.Empty);
+            builder.AppendMessage(e.NewTopic);
             Session.AddMessageToChat(cchat, builder.ToMessage());
         }
         
@@ -3172,11 +3277,11 @@ namespace Smuxi.Engine
                     TimeSpan lag = _IrcClient.Lag;
                     TimeSpan diff = lag - _LastLag;
                     int absDiff = Math.Abs((int) diff.TotalSeconds);
-#if LOG4NET
-                    _Logger.Debug("_LagWatcher(): lag: " + lag.TotalSeconds + " seconds, difference: " + absDiff + " seconds");
-#endif
                     // update network status if the lag changed over 5 seconds
                     if (absDiff > 5) {
+#if LOG4NET
+                        _Logger.Debug("_LagWatcher(): lag: " + lag.TotalSeconds + " seconds, difference: " + absDiff + " seconds");
+#endif
                         Session.UpdateNetworkStatus();
                     }
                     _LastLag = lag;
@@ -3293,6 +3398,29 @@ namespace Smuxi.Engine
             return builder;
         }
 
+        void AutoRenick()
+        {
+            if (_IrcClient.AutoNickHandling ||
+                _IrcClient.IsRegistered) {
+                return;
+            }
+
+            // allright, we have to care then and try a different nick as
+            // we don't have a nick yet
+            string nick;
+            if (_CurrentNickname == _Nicknames.Length - 1) {
+                // we tried all nicks already, so fallback to random
+                 Random rand = new Random();
+                int number = rand.Next(999);
+                nick = _Nicknames[_CurrentNickname].Substring(0, 5) + number;
+            } else {
+                _CurrentNickname++;
+                nick = _Nicknames[_CurrentNickname];
+            }
+
+            _IrcClient.RfcNick(nick, Priority.Critical);
+        }
+
         private static string _(string msg)
         {
             return LibraryCatalog.GetString(msg, _LibraryTextDomain);
diff --git a/src/Engine-MSNP/Makefile.in b/src/Engine-MSNP/Makefile.in
index a92bccc..7ce1a30 100644
--- a/src/Engine-MSNP/Makefile.in
+++ b/src/Engine-MSNP/Makefile.in
@@ -41,8 +41,11 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 subdir = src/Engine-MSNP
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -83,6 +86,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -96,13 +100,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -143,13 +160,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -157,6 +176,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -167,13 +187,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -187,13 +216,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -201,7 +236,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -216,10 +253,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -350,7 +390,7 @@ build_references_ref = $(foreach ref, $(REFERENCES), $(if $(filter \
 	-pkg:%, $(ref)), $(ref), $(if $(filter -r:%, $(ref)), $(ref), \
 	-r:$(ref)))) $(foreach ref, $(DLL_REFERENCES), -r:$(ref)) \
 	$(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
 programfilesdir = @libdir@/@PACKAGE@
@@ -478,6 +518,12 @@ uninstall-pkglibSCRIPTS:
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(linuxdesktopapplicationsdir)" || $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)"
@@ -631,7 +677,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -685,7 +731,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-am
 
@@ -702,19 +748,21 @@ uninstall-am: uninstall-binSCRIPTS \
 
 .MAKE: install-am install-strip
 
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binSCRIPTS install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-linuxdesktopapplicationsDATA \
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binSCRIPTS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-man install-pdf \
 	install-pdf-am install-pkglibSCRIPTS install-programfilesDATA \
 	install-programfilesiconsDATA install-ps install-ps-am \
 	install-strip installcheck installcheck-am installdirs \
 	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
-	uninstall-binSCRIPTS uninstall-linuxdesktopapplicationsDATA \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am uninstall-binSCRIPTS \
+	uninstall-linuxdesktopapplicationsDATA \
 	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
 	uninstall-programfilesDATA uninstall-programfilesiconsDATA
 
diff --git a/src/Engine-MSNP/Protocols/Msnp/MsnpProtocolManager.cs b/src/Engine-MSNP/Protocols/Msnp/MsnpProtocolManager.cs
index 38f47c3..befb934 100644
--- a/src/Engine-MSNP/Protocols/Msnp/MsnpProtocolManager.cs
+++ b/src/Engine-MSNP/Protocols/Msnp/MsnpProtocolManager.cs
@@ -106,22 +106,29 @@ namespace Smuxi.Engine
 //            _Conversation.Switchboard.ContactLeft   += new .ContactChangedEventHandler(ContactLeft);            
         }
         
-        public override void Connect(FrontendManager fm, string host, int port, string username, string password)
+        public override void Connect(FrontendManager fm, ServerModel server)
         {
-            Trace.Call(fm, host, port, username, password);
-            
-            _UsersAddress = username;
+            Trace.Call(fm, server);
+
+            if (fm == null) {
+                throw new ArgumentNullException("fm");
+            }
+            if (server == null) {
+                throw new ArgumentNullException("server");
+            }
+
             _FrontendManager = fm;
-            Host = host;
-            Port = port;
+            _UsersAddress = server.Username;
+            Host = server.Hostname;
+            Port = server.Port;
             
             // TODO: use config for single network chat or once per network manager
             _NetworkChat = new ProtocolChatModel(NetworkID, "MSN Messenger", this);
             Session.AddChat(_NetworkChat);
             Session.SyncChat(_NetworkChat);
             
-            _MsnClient.Credentials.Account = username;
-            _MsnClient.Credentials.Password = password;
+            _MsnClient.Credentials.Account = server.Username;
+            _MsnClient.Credentials.Password = server.Password;
             _MsnClient.Connect();
         }
         
@@ -256,23 +263,22 @@ namespace Smuxi.Engine
         {
             FrontendManager fm = cd.FrontendManager;
             
-            string user;
+            var server = new ServerModel();
             if (cd.DataArray.Length >= 1) {
-                user = cd.DataArray[2];
+                server.Username = cd.DataArray[2];
             } else {
                 NotEnoughParameters(cd);
                 return;
             }
             
-            string pass;
             if (cd.DataArray.Length >= 2) {
-                pass = cd.DataArray[3];
+                server.Password = cd.DataArray[3];
             } else {
                 NotEnoughParameters(cd);
                 return;
             }
             
-            Connect(fm, null, 0, user, pass);
+            Connect(fm, server);
         }
         
         private void _Say(CommandModel command, string text)
diff --git a/src/Engine-OSCAR/Makefile.in b/src/Engine-OSCAR/Makefile.in
index 6a7e709..bf18869 100644
--- a/src/Engine-OSCAR/Makefile.in
+++ b/src/Engine-OSCAR/Makefile.in
@@ -41,8 +41,11 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 subdir = src/Engine-OSCAR
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -83,6 +86,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -96,13 +100,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -143,13 +160,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -157,6 +176,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -167,13 +187,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -187,13 +216,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -201,7 +236,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -216,10 +253,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -347,7 +387,7 @@ build_references_ref = $(foreach ref, $(REFERENCES), $(if $(filter \
 	-pkg:%, $(ref)), $(ref), $(if $(filter -r:%, $(ref)), $(ref), \
 	-r:$(ref)))) $(foreach ref, $(DLL_REFERENCES), -r:$(ref)) \
 	$(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
 programfilesdir = @libdir@/@PACKAGE@
@@ -472,6 +512,12 @@ uninstall-pkglibSCRIPTS:
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(linuxdesktopapplicationsdir)" || $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)"
@@ -625,7 +671,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -679,7 +725,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-am
 
@@ -696,19 +742,21 @@ uninstall-am: uninstall-binSCRIPTS \
 
 .MAKE: install-am install-strip
 
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binSCRIPTS install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-linuxdesktopapplicationsDATA \
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binSCRIPTS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-man install-pdf \
 	install-pdf-am install-pkglibSCRIPTS install-programfilesDATA \
 	install-programfilesiconsDATA install-ps install-ps-am \
 	install-strip installcheck installcheck-am installdirs \
 	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
-	uninstall-binSCRIPTS uninstall-linuxdesktopapplicationsDATA \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am uninstall-binSCRIPTS \
+	uninstall-linuxdesktopapplicationsDATA \
 	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
 	uninstall-programfilesDATA uninstall-programfilesiconsDATA
 
diff --git a/src/Engine-OSCAR/Protocols/Oscar/OscarProtocolManager.cs b/src/Engine-OSCAR/Protocols/Oscar/OscarProtocolManager.cs
index 8090264..8593e69 100644
--- a/src/Engine-OSCAR/Protocols/Oscar/OscarProtocolManager.cs
+++ b/src/Engine-OSCAR/Protocols/Oscar/OscarProtocolManager.cs
@@ -96,10 +96,17 @@ namespace Smuxi.Engine
             Trace.Call(session);
         }
         
-        public override void Connect(FrontendManager fm, string host, int port, string username, string password)
+        public override void Connect(FrontendManager fm, ServerModel server)
         {
-            Trace.Call(fm, host, port, username, password);
+            Trace.Call(fm, server);
             
+            if (fm == null) {
+                throw new ArgumentNullException("fm");
+            }
+            if (server == null) {
+                throw new ArgumentNullException("server");
+            }
+
             _FrontendManager = fm;
             Host = "login.oscar.aol.com";
             Port = 5190;
@@ -109,7 +116,7 @@ namespace Smuxi.Engine
             Session.AddChat(_NetworkChat);
             Session.SyncChat(_NetworkChat);
             
-            _OscarSession = new OscarSession(username, password);
+            _OscarSession = new OscarSession(server.Username, server.Password);
             _OscarSession.ClientCapabilities = Capabilities.Chat | Capabilities.OscarLib;
             _OscarSession.LoginCompleted           += new LoginCompletedHandler(_OnLoginCompleted);
             _OscarSession.LoginFailed              += new LoginFailedHandler(_OnLoginFailed);
@@ -211,31 +218,22 @@ namespace Smuxi.Engine
         {
             FrontendManager fm = cd.FrontendManager;
             
-            string protocol;
-            if (cd.DataArray.Length >= 2) {
-                protocol = cd.DataArray[1];
-            } else {
-                NotEnoughParameters(cd);
-                return;
-            }
-            
-            string username;                
+            var server = new ServerModel();
             if (cd.DataArray.Length >= 3) {
-                username = cd.DataArray[2];
+                server.Username = cd.DataArray[2];
             } else {
                 NotEnoughParameters(cd);
                 return;
             }
             
-            string password;
             if (cd.DataArray.Length >= 4) {
-                password = cd.DataArray[3];
+                server.Password = cd.DataArray[3];
             } else {
                 NotEnoughParameters(cd);
                 return;
             }
             
-            Connect(fm, null, 0, username, password);
+            Connect(fm, server);
         }
         
         public void CommandHelp(CommandModel cd)
diff --git a/src/Engine-Twitter/AssemblyInfo.cs b/src/Engine-Twitter/AssemblyInfo.cs
index d3ab7c0..07837af 100644
--- a/src/Engine-Twitter/AssemblyInfo.cs
+++ b/src/Engine-Twitter/AssemblyInfo.cs
@@ -1,10 +1,4 @@
 /*
- * $Id: AssemblyInfo.cs 211 2007-08-03 18:58:27Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Engine/AssemblyInfo.cs $
- * $Rev: 211 $
- * $Author: meebey $
- * $Date: 2007-08-03 20:58:27 +0200 (Fri, 03 Aug 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
  * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
@@ -32,7 +26,7 @@ using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 [assembly: AssemblyTitle("Smuxi - Twitter support for engine")]
-[assembly: AssemblyCopyright("2009 (C) Mirco Bauer <meebey at meebey.net>")]
+[assembly: AssemblyCopyright("2009-2011 (C) Mirco Bauer <meebey at meebey.net>")]
 
 [assembly: AssemblyDelaySign(false)]
 [assembly: AssemblyKeyFile("")]
diff --git a/src/Engine-Twitter/Makefile.am b/src/Engine-Twitter/Makefile.am
index 4e63c57..cf70b4f 100644
--- a/src/Engine-Twitter/Makefile.am
+++ b/src/Engine-Twitter/Makefile.am
@@ -20,8 +20,7 @@ DLL_REFERENCES =	$(TARGET_DIR)/Twitterizer2.dll \
 SOURCES_BUILD = $(addprefix $(srcdir)/, $(SOURCES))
 
 # automake magic variables
-DIST_SOURCES = $(SOURCES_BUILD)
-EXTRA_DIST =
+EXTRA_DIST = $(SOURCES_BUILD)
 CLEANFILES = $(ASSEMBLY_TARGET)
 
 pkglib_DATA = $(ASSEMBLY_TARGET)
diff --git a/src/Engine-Twitter/Makefile.in b/src/Engine-Twitter/Makefile.in
index b7372d8..ce206e8 100644
--- a/src/Engine-Twitter/Makefile.in
+++ b/src/Engine-Twitter/Makefile.in
@@ -40,8 +40,11 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 subdir = src/Engine-Twitter
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -74,12 +77,14 @@ am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibdir)" \
 	"$(DESTDIR)$(programfilesdir)" \
 	"$(DESTDIR)$(programfilesiconsdir)"
 SCRIPTS = $(bin_SCRIPTS) $(pkglib_SCRIPTS)
+DIST_SOURCES =
 DATA = $(linuxdesktopapplications_DATA) $(linuxpkgconfig_DATA) \
 	$(pkglib_DATA) $(programfiles_DATA) $(programfilesicons_DATA)
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -93,13 +98,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -140,13 +158,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -154,6 +174,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -164,13 +185,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -184,13 +214,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -198,7 +234,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -213,10 +251,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -268,8 +309,7 @@ DLL_REFERENCES = $(TARGET_DIR)/Twitterizer2.dll \
 SOURCES_BUILD = $(addprefix $(srcdir)/, $(SOURCES))
 
 # automake magic variables
-DIST_SOURCES = $(SOURCES_BUILD)
-EXTRA_DIST = $(build_sources) $(build_resx_files) \
+EXTRA_DIST = $(SOURCES_BUILD) $(build_sources) $(build_resx_files) \
 	$(build_others_files) $(ASSEMBLY_WRAPPER_IN) $(EXTRAS) \
 	$(DATA_FILES) $(build_culture_res_files)
 CLEANFILES = $(ASSEMBLY_TARGET) $(ASSEMBLY) $(ASSEMBLY).mdb \
@@ -305,7 +345,7 @@ build_references_ref = $(foreach ref, $(REFERENCES), $(if $(filter \
 	-pkg:%, $(ref)), $(ref), $(if $(filter -r:%, $(ref)), $(ref), \
 	-r:$(ref)))) $(foreach ref, $(DLL_REFERENCES), -r:$(ref)) \
 	$(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
 programfilesdir = @libdir@/@PACKAGE@
@@ -425,6 +465,12 @@ uninstall-pkglibSCRIPTS:
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(linuxdesktopapplicationsdir)" || $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)"
@@ -598,7 +644,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -653,7 +699,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-am
 
@@ -671,20 +717,21 @@ uninstall-am: uninstall-binSCRIPTS \
 
 .MAKE: install-am install-strip
 
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binSCRIPTS install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-linuxdesktopapplicationsDATA \
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binSCRIPTS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-man install-pdf \
 	install-pdf-am install-pkglibDATA install-pkglibSCRIPTS \
 	install-programfilesDATA install-programfilesiconsDATA \
 	install-ps install-ps-am install-strip installcheck \
 	installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
-	pdf-am ps ps-am uninstall uninstall-am uninstall-binSCRIPTS \
-	uninstall-linuxdesktopapplicationsDATA \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \
+	uninstall-binSCRIPTS uninstall-linuxdesktopapplicationsDATA \
 	uninstall-linuxpkgconfigDATA uninstall-pkglibDATA \
 	uninstall-pkglibSCRIPTS uninstall-programfilesDATA \
 	uninstall-programfilesiconsDATA
diff --git a/src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs b/src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs
index 0b5193f..b3d65b1 100644
--- a/src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs
+++ b/src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs
@@ -1,6 +1,6 @@
 // Smuxi - Smart MUltipleXed Irc
 // 
-// Copyright (c) 2009-2010 Mirco Bauer <meebey at meebey.net>
+// Copyright (c) 2009-2011 Mirco Bauer <meebey at meebey.net>
 // 
 // Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
 // 
@@ -26,6 +26,7 @@ using System.Security.Cryptography.X509Certificates;
 using System.Threading;
 using System.Collections.Generic;
 using Twitterizer;
+using Twitterizer.Core;
 using Smuxi.Common;
 
 namespace Smuxi.Engine
@@ -102,10 +103,8 @@ namespace Smuxi.Engine
         protected bool HasTokens {
             get {
                 return f_OAuthTokens != null &&
-                       !String.IsNullOrEmpty(f_OAuthTokens.ConsumerKey) &&
-                       !String.IsNullOrEmpty(f_OAuthTokens.ConsumerSecret) &&
-                       !String.IsNullOrEmpty(f_OAuthTokens.AccessToken) &&
-                       !String.IsNullOrEmpty(f_OAuthTokens.AccessTokenSecret);
+                       f_OAuthTokens.HasConsumerToken &&
+                       f_OAuthTokens.HasAccessToken;
             }
         }
 
@@ -125,6 +124,10 @@ namespace Smuxi.Engine
                 _("Home Timeline"),
                 this
             );
+            f_FriendsTimelineChat.InitMessageBuffer(
+                MessageBufferPersistencyType.Volatile
+            );
+            f_FriendsTimelineChat.ApplyConfig(Session.UserConfig);
             f_GroupChats.Add(f_FriendsTimelineChat);
 
             f_RepliesChat = new GroupChatModel(
@@ -132,6 +135,10 @@ namespace Smuxi.Engine
                 _("Replies"),
                 this
             );
+            f_RepliesChat.InitMessageBuffer(
+                MessageBufferPersistencyType.Volatile
+            );
+            f_RepliesChat.ApplyConfig(Session.UserConfig);
             f_GroupChats.Add(f_RepliesChat);
 
             f_DirectMessagesChat = new GroupChatModel(
@@ -139,34 +146,42 @@ namespace Smuxi.Engine
                 _("Direct Messages"),
                 this
             );
+            f_DirectMessagesChat.InitMessageBuffer(
+                MessageBufferPersistencyType.Volatile
+            );
+            f_DirectMessagesChat.ApplyConfig(Session.UserConfig);
             f_GroupChats.Add(f_DirectMessagesChat);
         }
 
-        public override void Connect(FrontendManager fm, string host, int port,
-                                     string username, string password)
+        public override void Connect(FrontendManager fm, ServerModel server)
         {
-            Trace.Call(fm, host, port, username, "XXX");
-
-            f_Username = username;
+            Trace.Call(fm, server);
 
-            var proxyType = (string) Session.UserConfig["Connection/ProxyType"];
-            if (proxyType.ToLower() == "http") {
-                var uriBuilder = new UriBuilder();
-                uriBuilder.Scheme = "http";
-                uriBuilder.Host = (string) Session.UserConfig["Connection/ProxyHostname"];
-                uriBuilder.Port = (int) Session.UserConfig["Connection/ProxyPort"];
-                uriBuilder.UserName = (string) Session.UserConfig["Connection/ProxyUsername"];
-                uriBuilder.Password = (string) Session.UserConfig["Connection/ProxyPassword"];
-                var proxyUri = uriBuilder.ToString();
-                f_WebProxy = new WebProxy(proxyUri);
+            if (fm == null) {
+                throw new ArgumentNullException("fm");
             }
+            if (server == null) {
+                throw new ArgumentNullException("server");
+            }
+
+            f_Username = server.Username;
 
-            f_OptionalProperties = new OptionalProperties();
-            if (f_WebProxy != null) {
-                f_OptionalProperties.Proxy = f_WebProxy;
+            var proxySettings = new ProxySettings();
+            proxySettings.ApplyConfig(Session.UserConfig);
+            var twitterUrl = new OptionalProperties().APIBaseAddress;
+            f_WebProxy = proxySettings.GetWebProxy(twitterUrl);
+            // HACK: Twitterizer will always use the system proxy if set to null
+            // so explicitely override this by setting an empty proxy
+            if (f_WebProxy == null) {
+                f_WebProxy = new WebProxy();
             }
+            f_OptionalProperties = CreateOptions<OptionalProperties>();
 
-            f_ProtocolChat = new ProtocolChatModel(NetworkID, "Twitter " + username, this);
+            f_ProtocolChat = new ProtocolChatModel(NetworkID, "Twitter " + f_Username, this);
+            f_ProtocolChat.InitMessageBuffer(
+                MessageBufferPersistencyType.Volatile
+            );
+            f_ProtocolChat.ApplyConfig(Session.UserConfig);
             Session.AddChat(f_ProtocolChat);
             Session.SyncChat(f_ProtocolChat);
 
@@ -181,18 +196,28 @@ namespace Smuxi.Engine
                 f_OAuthTokens.ConsumerSecret = key[1];
 
                 MessageBuilder builder;
-                var servers = new ServerListController(Session.UserConfig);
-                var server = servers.GetServer(Protocol, username);
-                if (server != null) {
-                    if (password == null) {
-                        // no password passed, use server password
-                        password = server.Password;
+                var password = server.Password ?? String.Empty;
+                var access = password.Split('|');
+                if (access.Length == 2) {
+                    f_OAuthTokens.AccessToken = access[0];
+                    f_OAuthTokens.AccessTokenSecret = access[1];
+
+                    // verify access token
+                    var options = CreateOptions<VerifyCredentialsOptions>();
+                    var response = TwitterAccount.VerifyCredentials(
+                        f_OAuthTokens, options
+                    );
+                    if (response.Result == RequestResult.Unauthorized) {
+#if LOG4NET
+                        f_Logger.Warn("Connect(): Invalid access token, " +
+                                      "re-authorization required");
+#endif
+                        f_OAuthTokens.AccessToken = null;
+                        f_OAuthTokens.AccessTokenSecret = null;
                     }
                 }
 
-                password = password ?? String.Empty;
-                var access = password.Split('|');
-                if (password.Length == 0 || access.Length == 1) {
+                if (!f_OAuthTokens.HasAccessToken) {
                     // new account or basic auth user that needs to be migrated
                     var reqToken = OAuthUtility.GetRequestToken(key[0], key[1],
                                                             "oob", f_WebProxy);
@@ -202,14 +227,6 @@ namespace Smuxi.Engine
                     builder.AppendEventPrefix();
                     builder.AppendText(_("Twitter authorization required."));
                     Session.AddMessageToChat(f_ProtocolChat, builder.ToMessage());
-                    
-                    /*
-                        _("Twitter authorization required, please open the " +
-                          "following URL and enter the returned PIN using the " +
-                          "/pin command: {0}"),
-                        String.Empty
-                    );
-                    */
 
                     builder = CreateMessageBuilder();
                     builder.AppendEventPrefix();
@@ -240,9 +257,6 @@ namespace Smuxi.Engine
                     builder.AppendEventPrefix();
                     builder.AppendText(_("Please type: /pin PIN_FROM_TWITTER"));
                     Session.AddMessageToChat(f_ProtocolChat, builder.ToMessage());
-                } else {
-                    f_OAuthTokens.AccessToken = access[0];
-                    f_OAuthTokens.AccessTokenSecret = access[1];
                 }
             } catch (Exception ex) {
 #if LOG4NET
@@ -472,8 +486,10 @@ namespace Smuxi.Engine
                 return chat;
             }
 
-            TwitterUser user = TwitterUser.Show(f_OAuthTokens, userId,
-                                                f_OptionalProperties);
+            var response = TwitterUser.Show(f_OAuthTokens, userId,
+                                            f_OptionalProperties);
+            CheckResponse(response);
+            var user = response.ResponseObject;
             PersonModel person = CreatePerson(user);
             PersonChatModel personChat = new PersonChatModel(
                 person,
@@ -481,6 +497,10 @@ namespace Smuxi.Engine
                 user.ScreenName,
                 this
             );
+            personChat.InitMessageBuffer(
+                MessageBufferPersistencyType.Volatile
+            );
+            personChat.ApplyConfig(Session.UserConfig);
             Session.AddChat(personChat);
             Session.SyncChat(personChat);
             return personChat;
@@ -579,17 +599,11 @@ namespace Smuxi.Engine
 
         public void CommandHelp(CommandModel cd)
         {
-            MessageModel fmsg = new MessageModel();
-            TextMessagePartModel fmsgti;
-
-            fmsgti = new TextMessagePartModel();
+            var builder = CreateMessageBuilder();
             // TRANSLATOR: this line is used as a label / category for a
             // list of commands below
-            fmsgti.Text = "[" + _("Twitter Commands") + "]";
-            fmsgti.Bold = true;
-            fmsg.MessageParts.Add(fmsgti);
-
-            Session.AddMessageToChat(cd.Chat, fmsg);
+            builder.AppendHeader(_("Twitter Commands"));
+            cd.FrontendManager.AddMessageToChat(cd.Chat, builder.ToMessage());
 
             string[] help = {
                 "help",
@@ -598,32 +612,33 @@ namespace Smuxi.Engine
             };
 
             foreach (string line in help) {
-                cd.FrontendManager.AddTextToChat(cd.Chat, "-!- " + line);
+                builder = CreateMessageBuilder();
+                builder.AppendEventPrefix();
+                builder.AppendText(line);
+                cd.FrontendManager.AddMessageToChat(cd.Chat, builder.ToMessage());
             }
         }
 
         public void CommandConnect(CommandModel cd)
         {
-            string user;
+            var server = new ServerModel();
             if (cd.DataArray.Length >= 3) {
-                user = cd.DataArray[2];
+                server.Username = cd.DataArray[2];
             } else {
                 NotEnoughParameters(cd);
                 return;
             }
 
-            Connect(cd.FrontendManager, null, 0, user, null);
+            Connect(cd.FrontendManager, server);
         }
 
         public void CommandPin(CommandModel cd)
         {
-            string pin;
-            if (cd.DataArray.Length >= 2) {
-                pin = cd.DataArray[1];
-            } else {
+            if (String.IsNullOrEmpty(cd.Parameter)) {
                 NotEnoughParameters(cd);
                 return;
             }
+            var pin = cd.Parameter.Trim();
 
             MessageBuilder builder;
             if (String.IsNullOrEmpty(f_RequestToken)) {
@@ -670,6 +685,7 @@ namespace Smuxi.Engine
                       "the Twitter \"{0}\" account."),
                     f_Username
                 );
+                Session.AddMessageToChat(f_ProtocolChat, builder.ToMessage());
 
                 // allow the user to re-enter the pin
                 // LAME: An incorrect PIN invalidates the request token!
@@ -714,6 +730,7 @@ namespace Smuxi.Engine
                 // update token
                 server.Password = String.Format("{0}|{1}", response.Token,
                                                 response.TokenSecret);
+                servers.SetServer(server);
             }
             servers.Save();
 
@@ -783,15 +800,15 @@ namespace Smuxi.Engine
                 return;
             }
 
-            TwitterUser user = TwitterUser.Show(f_OAuthTokens, nickname,
-                                                f_OptionalProperties);
-            if (user.RequestStatus.Status != RequestResult.Success) {
+            var response = TwitterUser.Show(f_OAuthTokens, nickname,
+                                            f_OptionalProperties);
+            if (response.Result != RequestResult.Success) {
                 fm.AddTextToChat(cmd.Chat, "-!- " +
                     _("Could not send message - the specified user does not exist.")
                 );
                 return;
             }
-
+            var user = response.ResponseObject;
             var chat = OpenPrivateChat(user.Id);
 
             if (cmd.DataArray.Length >= 3) {
@@ -898,18 +915,22 @@ namespace Smuxi.Engine
 #if LOG4NET
             f_Logger.Debug("UpdateFriendsTimeline(): getting friend timeline from twitter...");
 #endif
-            var options = new TimelineOptions() {
-                Proxy = f_WebProxy,
-                SinceStatusId = f_LastFriendsTimelineStatusID,
-                Count = 50
-            };
-            var timeline = TwitterTimeline.HomeTimeline(f_OAuthTokens,
+            var options = CreateOptions<TimelineOptions>();
+            options.SinceStatusId = f_LastFriendsTimelineStatusID;
+            options.Count = 50;
+            var response = TwitterTimeline.HomeTimeline(f_OAuthTokens,
                                                         options);
+            // ignore temporarily issues
+            if (IsTemporilyErrorResponse(response)) {
+                return;
+            }
+            CheckResponse(response);
+            var timeline = response.ResponseObject;
 #if LOG4NET
             f_Logger.Debug("UpdateFriendsTimeline(): done. New tweets: " +
-                (timeline == null ? 0 : timeline.Count));
+                           timeline.Count);
 #endif
-            if (timeline == null || timeline.Count == 0) {
+            if (timeline.Count == 0) {
                 return;
             }
 
@@ -999,16 +1020,19 @@ namespace Smuxi.Engine
 #if LOG4NET
             f_Logger.Debug("UpdateReplies(): getting replies from twitter...");
 #endif
-            var options = new TimelineOptions() {
-                Proxy = f_WebProxy,
-                SinceStatusId = f_LastReplyStatusID
-            };
-            var timeline = TwitterTimeline.Mentions(f_OAuthTokens, options);
+            var options = CreateOptions<TimelineOptions>();
+            options.SinceStatusId = f_LastReplyStatusID;
+            var response = TwitterTimeline.Mentions(f_OAuthTokens, options);
+            // ignore temporarily issues
+            if (IsTemporilyErrorResponse(response)) {
+                return;
+            }
+            CheckResponse(response);
+            var timeline = response.ResponseObject;
 #if LOG4NET
-            f_Logger.Debug("UpdateReplies(): done. New replies: " +
-                (timeline == null ? 0 : timeline.Count));
+            f_Logger.Debug("UpdateReplies(): done. New replies: " + timeline.Count);
 #endif
-            if (timeline == null || timeline.Count == 0) {
+            if (timeline.Count == 0) {
                 return;
             }
 
@@ -1092,14 +1116,18 @@ namespace Smuxi.Engine
 #if LOG4NET
             f_Logger.Debug("UpdateDirectMessages(): getting received direct messages from twitter...");
 #endif
-            var options = new DirectMessagesOptions() {
-                Proxy = f_WebProxy,
-                SinceStatusId = f_LastDirectMessageReceivedStatusID,
-                Count = 50
-            };
-            var receivedTimeline = TwitterDirectMessage.DirectMessages(
+            var options = CreateOptions<DirectMessagesOptions>();
+            options.SinceStatusId = f_LastDirectMessageReceivedStatusID;
+            options.Count = 50;
+            var response = TwitterDirectMessage.DirectMessages(
                 f_OAuthTokens, options
             );
+            // ignore temporarily issues
+            if (IsTemporilyErrorResponse(response)) {
+                return;
+            }
+            CheckResponse(response);
+            var receivedTimeline = response.ResponseObject;
 #if LOG4NET
             f_Logger.Debug("UpdateDirectMessages(): done. New messages: " +
                 (receivedTimeline == null ? 0 : receivedTimeline.Count));
@@ -1108,14 +1136,18 @@ namespace Smuxi.Engine
 #if LOG4NET
             f_Logger.Debug("UpdateDirectMessages(): getting sent direct messages from twitter...");
 #endif
-            var sentOptions = new DirectMessagesSentOptions() {
-                Proxy = f_WebProxy,
-                SinceStatusId = f_LastDirectMessageSentStatusID,
-                Count = 50
-            };
-            var sentTimeline = TwitterDirectMessage.DirectMessagesSent(
+            var sentOptions = CreateOptions<DirectMessagesSentOptions>();
+            sentOptions.SinceStatusId = f_LastDirectMessageSentStatusID;
+            sentOptions.Count = 50;
+            response = TwitterDirectMessage.DirectMessagesSent(
                 f_OAuthTokens, sentOptions
             );
+            // ignore temporarily issues
+            if (IsTemporilyErrorResponse(response)) {
+                return;
+            }
+            CheckResponse(response);
+            var sentTimeline = response.ResponseObject;
 #if LOG4NET
             f_Logger.Debug("UpdateDirectMessages(): done. New messages: " +
                 (sentTimeline == null ? 0 : sentTimeline.Count));
@@ -1196,26 +1228,46 @@ namespace Smuxi.Engine
             }
 
 #if LOG4NET
-            f_Logger.Debug("UpdateFriends(): getting friends from twitter...");
+            f_Logger.Debug("UpdateFriends(): fetching friend IDs from twitter...");
 #endif
-            var options = new FriendsOptions() {
-                Proxy = f_WebProxy
-            };
-            TwitterUserCollection friends = TwitterFriendship.Friends(
+            var options = CreateOptions<UsersIdsOptions>();
+            options.UserId = f_TwitterUser.Id;
+            var response = TwitterFriendship.FriendsIds(
                 f_OAuthTokens, options
             );
+            CheckResponse(response);
+            var friendIds = response.ResponseObject;
 #if LOG4NET
-            f_Logger.Debug("UpdateFriends(): done. Friends: " +
-                (friends == null ? 0 : friends.Count));
+            f_Logger.Debug("UpdateFriends(): done. Fetched IDs: " + friendIds.Count);
 #endif
-            if (friends == null || friends.Count == 0) {
-                return;
-            }
 
-            var persons = new Dictionary<string, PersonModel>(friends.Count);
-            foreach (TwitterUser friend in friends) {
-                var person = CreatePerson(friend);
-                persons.Add(person.ID, person);
+            var persons = new Dictionary<string, PersonModel>(friendIds.Count);
+            // users/lookup only permits 100 users per call
+            var pageSize = 100;
+            var idList = new List<decimal>(friendIds);
+            var idPages = new List<List<decimal>>();
+            for (int offset = 0; offset < idList.Count; offset += pageSize) {
+                var count = Math.Min(pageSize, idList.Count - offset);
+                idPages.Add(idList.GetRange(offset, count));
+            }
+            foreach (var idPage in idPages) {
+#if LOG4NET
+                f_Logger.Debug("UpdateFriends(): fetching friends from twitter...");
+#endif
+                var userIds = new TwitterIdCollection(idPage);
+                var lookupOptions = CreateOptions<LookupUsersOptions>();
+                lookupOptions.UserIds = userIds;
+                lookupOptions.CacheOutput = true;
+                var lookupResponse = TwitterUser.Lookup(f_OAuthTokens, lookupOptions);
+                CheckResponse(lookupResponse);
+                var friends = lookupResponse.ResponseObject;
+#if LOG4NET
+                f_Logger.Debug("UpdateFriends(): done. Fetched friends: " + friends.Count);
+#endif
+                foreach (var friend in friends) {
+                    var person = CreatePerson(friend);
+                    persons.Add(person.ID, person);
+                }
             }
             f_Friends = persons;
         }
@@ -1225,11 +1277,10 @@ namespace Smuxi.Engine
 #if LOG4NET
             f_Logger.Debug("UpdateUser(): getting user details from twitter...");
 #endif
-            var user = TwitterUser.Show(f_OAuthTokens, f_Username,
-                                        f_OptionalProperties);
-            if (user == null || user.RequestStatus.Status != RequestResult.Success) {
-                throw new ApplicationException(user.RequestStatus.ErrorDetails.ErrorMessage);
-            }
+            var response = TwitterUser.Show(f_OAuthTokens, f_Username,
+                                            f_OptionalProperties);
+            CheckResponse(response);
+            var user = response.ResponseObject;
             f_TwitterUser = user;
 #if LOG4NET
             f_Logger.Debug("UpdateUser(): done.");
@@ -1259,17 +1310,19 @@ namespace Smuxi.Engine
             return builder.ToMessage();
         }
 
-        private void PostUpdate(string text)
+        private T CreateOptions<T>() where T : OptionalProperties, new()
         {
-            var options = new StatusUpdateOptions() {
+            var options = new T() {
                 Proxy = f_WebProxy
             };
+            return options;
+        }
+
+        private void PostUpdate(string text)
+        {
+            var options = CreateOptions<StatusUpdateOptions>();
             var res = TwitterStatus.Update(f_OAuthTokens, text, options);
-            if (res.RequestStatus.Status != RequestResult.Success) {
-                throw new ApplicationException(
-                    res.RequestStatus.ErrorDetails.ErrorMessage
-                );
-            }
+            CheckResponse(res);
             f_FriendsTimelineEvent.Set();
         }
 
@@ -1277,11 +1330,7 @@ namespace Smuxi.Engine
         {
             var res = TwitterDirectMessage.Send(f_OAuthTokens, target, text,
                                                 f_OptionalProperties);
-            if (res.RequestStatus.Status != RequestResult.Success) {
-                throw new ApplicationException(
-                    res.RequestStatus.ErrorDetails.ErrorMessage
-                );
-            }
+            CheckResponse(res);
             f_DirectMessageEvent.Set();
         }
         
@@ -1289,12 +1338,7 @@ namespace Smuxi.Engine
         {
             Trace.Call(exception == null ? null : exception.GetType());
 
-            /*
-            if (exception.RequestData != null &&
-                exception.RequestData.ResponseException != null) {
-                CheckWebException(exception.RequestData.ResponseException);
-                return;
-            } else */ if (exception.InnerException is WebException) {
+            if (exception.InnerException is WebException) {
                 CheckWebException((WebException) exception.InnerException);
                 return;
             } else if (exception.InnerException != null) {
@@ -1365,10 +1409,77 @@ namespace Smuxi.Engine
 #endif
                     return;
                 default:
+#if LOG4NET
+                    f_Logger.Error("CheckWebException(): " +
+                                   "Status: " + exception.Status + " " +
+                                   "ResponseUri: " + exception.Response.ResponseUri);
+#endif
                     throw exception;
             }
         }
 
+        private void CheckResponse<T>(TwitterResponse<T> response) where T : ITwitterObject
+        {
+            if (response == null) {
+                throw new ArgumentNullException("response");
+            }
+
+            if (response.Result == RequestResult.Success) {
+                return;
+            }
+
+#if LOG4NET
+            f_Logger.Error("CheckResponse(): " +
+                           "RequestUrl: " + response.RequestUrl + " " +
+                           "Result: " + response.Result + " " +
+                           "Content:\n" + response.Content);
+#endif
+
+            // HACK: Twitter returns HTML code saying they are overloaded o_O
+            if (response.Result == RequestResult.Unknown &&
+                response.ErrorMessage == null) {
+                response.ErrorMessage = _("Twitter didn't send a valid response, they're probably overloaded");
+            }
+            throw new TwitterizerException(response.ErrorMessage);
+        }
+
+        private bool IsTemporilyErrorResponse<T>(TwitterResponse<T> response)
+                                        where T : ITwitterObject
+        {
+            if (response == null) {
+                throw new ArgumentNullException("response");
+            }
+
+            switch (response.Result) {
+                case RequestResult.Success:
+                    // no error at all
+                    return false;
+                case RequestResult.ConnectionFailure:
+                case RequestResult.RateLimited:
+                case RequestResult.TwitterIsDown:
+                case RequestResult.TwitterIsOverloaded:
+                // probably "Twitter is over capacity"
+                case RequestResult.Unknown:
+#if LOG4NET
+                    f_Logger.Debug("IsTemporilyErrorResponse(): " +
+                                   "Detected temporily error " +
+                                   "RequestUrl: " + response.RequestUrl + " " +
+                                   "Result: " + response.Result + " " +
+                                   "Content:\n" + response.Content);
+#endif
+                    return true;
+            }
+
+#if LOG4NET
+            f_Logger.Debug("IsTemporilyErrorResponse(): " +
+                           "Detected permanent error " +
+                           "RequestUrl: " + response.RequestUrl + " " +
+                           "Result: " + response.Result + " " +
+                           "Content:\n" + response.Content);
+#endif
+            return false;
+        }
+
         private PersonModel GetPerson(TwitterUser user)
         {
             if (user == null) {
@@ -1382,6 +1493,14 @@ namespace Smuxi.Engine
             return person;
         }
 
+        private PersonModel CreatePerson(decimal userId)
+        {
+            var res = TwitterUser.Show(f_OAuthTokens, userId, f_OptionalProperties);
+            CheckResponse(res);
+            var user = res.ResponseObject;
+            return CreatePerson(user);
+        }
+
         private PersonModel CreatePerson(TwitterUser user)
         {
             if (user == null) {
@@ -1424,8 +1543,7 @@ namespace Smuxi.Engine
             if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors &&
                 sender is HttpWebRequest) {
                 var request = (HttpWebRequest) sender;
-                if (request.RequestUri.Host == "api.twitter.com" &&
-                    certificate.Issuer == "OU=Equifax Secure Certificate Authority, O=Equifax, C=US") {
+                if (request.RequestUri.Host == "api.twitter.com") {
                     return true;
                 }
             }
diff --git a/src/Engine-XMPP/AssemblyInfo.cs b/src/Engine-XMPP/AssemblyInfo.cs
index e29c3b2..148958d 100644
--- a/src/Engine-XMPP/AssemblyInfo.cs
+++ b/src/Engine-XMPP/AssemblyInfo.cs
@@ -1,10 +1,4 @@
 /*
- * $Id: AssemblyInfo.cs 211 2007-08-03 18:58:27Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Engine/AssemblyInfo.cs $
- * $Rev: 211 $
- * $Author: meebey $
- * $Date: 2007-08-03 20:58:27 +0200 (Fri, 03 Aug 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
  * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
@@ -32,7 +26,7 @@ using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 [assembly: AssemblyTitle("Smuxi - XMPP protocol support for engine")]
-[assembly: AssemblyCopyright("2005-2008 (C) Mirco Bauer <meebey at meebey.net>")]
+[assembly: AssemblyCopyright("2007-2011 (C) Mirco Bauer <meebey at meebey.net>, 2011 (C) Tuukka Hastrup <Tuukka.Hastrup at iki.fi>")]
 
 [assembly: AssemblyDelaySign(false)]
 [assembly: AssemblyKeyFile("")]
diff --git a/src/Engine-XMPP/Config/XmppServerModel.cs b/src/Engine-XMPP/Config/XmppServerModel.cs
new file mode 100644
index 0000000..24b9bf5
--- /dev/null
+++ b/src/Engine-XMPP/Config/XmppServerModel.cs
@@ -0,0 +1,33 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2011 Mirco Bauer <meebey at meebey.net>
+// 
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+// 
+// 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
+
+using System;
+
+namespace Smuxi.Engine
+{
+    public class XmppServerModel : ServerModel
+    {
+        public string Resource { get; set; }
+
+        public XmppServerModel()
+        {
+        }
+    }
+}
diff --git a/src/Engine-XMPP/Makefile.am b/src/Engine-XMPP/Makefile.am
index ce4ccec..2a53726 100644
--- a/src/Engine-XMPP/Makefile.am
+++ b/src/Engine-XMPP/Makefile.am
@@ -1,111 +1,37 @@
+TARGET_DIR = $(top_builddir)/bin/$(PROFILE)
+ASSEMBLY_NAME = smuxi-engine-xmpp
+ASSEMBLY_FILENAME = $(ASSEMBLY_NAME).dll
+ASSEMBLY_TARGET = $(TARGET_DIR)/$(ASSEMBLY_FILENAME)
 
-EXTRA_DIST =  
-
-# Warning: This is an automatically generated file, do not edit!
-
-if ENABLE_RELEASE
-ASSEMBLY_COMPILER_COMMAND = @MCS@
-ASSEMBLY_COMPILER_FLAGS =  -noconfig -codepage:utf8 -warn:4 -optimize+
-ASSEMBLY = ../../bin/release/smuxi-engine-xmpp.dll
-ASSEMBLY_MDB = 
-COMPILE_TARGET = library
-PROJECT_REFERENCES =  \
-	../../bin/release/smuxi-common.dll \
-	../../bin/release/smuxi-engine.dll
-BUILD_DIR = ../../bin/release
-
-SMUXI_ENGINE_DLL_MDB=
-LOG4NET_DLL_SOURCE=../../lib/log4net.dll
-NINI_DLL_SOURCE=../../lib/Nini.dll
-SMUXI_ENGINE_DLL_SOURCE=../../bin/release/smuxi-engine.dll
-JABBER_NET_DLL_SOURCE=../../lib/jabber-net.dll
-SMUXI_COMMON_DLL_SOURCE=../../bin/release/smuxi-common.dll
-
-endif
-
-if ENABLE_DEBUG
-ASSEMBLY_COMPILER_COMMAND = @MCS@
-ASSEMBLY_COMPILER_FLAGS =  -noconfig -codepage:utf8 -warn:4 -optimize+ -debug -define:DEBUG "-define:DEBUG,TRACE,LOG4NET"
-
-ASSEMBLY = ../../bin/debug/smuxi-engine-xmpp.dll
-ASSEMBLY_MDB = $(ASSEMBLY).mdb
-COMPILE_TARGET = library
-PROJECT_REFERENCES =  \
-	../../bin/debug/smuxi-common.dll \
-	../../bin/debug/smuxi-engine.dll
-BUILD_DIR = ../../bin/debug
-
-SMUXI_ENGINE_DLL_MDB_SOURCE=../../bin/debug/smuxi-engine.dll.mdb
-SMUXI_ENGINE_DLL_MDB=$(BUILD_DIR)/smuxi-engine.dll.mdb
-LOG4NET_DLL_SOURCE=../../lib/log4net.dll
-NINI_DLL_SOURCE=../../lib/Nini.dll
-SMUXI_ENGINE_DLL_SOURCE=../../bin/debug/smuxi-engine.dll
-JABBER_NET_DLL_SOURCE=../../lib/jabber-net.dll
-SMUXI_COMMON_DLL_SOURCE=../../bin/debug/smuxi-common.dll
-
-endif
-
-AL=al2
-SATELLITE_ASSEMBLY_NAME=.resources.dll
-
-PROGRAMFILES = \
-	$(SMUXI_ENGINE_DLL_MDB) \
-	$(LOG4NET_DLL) \
-	$(NINI_DLL) \
-	$(SMUXI_ENGINE_DLL) \
-	$(JABBER_NET_DLL) \
-	$(SMUXI_COMMON_DLL)  
-
-LINUX_PKGCONFIG = \
-	$(ENGINE_XMPP_PC)  
-
-
-	
-all: $(ASSEMBLY) $(PROGRAMFILES) $(LINUX_PKGCONFIG) 
-
-FILES = \
-	Protocols/Xmpp/XmppProtocolManager.cs \
+SOURCES = \
 	$(top_srcdir)/src/AssemblyVersion.cs \
-	AssemblyInfo.cs 
-
-DATA_FILES = 
-
-RESOURCES = 
-
-EXTRAS = \
-	smuxi-engine-xmpp.pc.in 
+	AssemblyInfo.cs \
+	Config/XmppServerModel.cs \
+	Protocols/Xmpp/XmppGroupChatModel.cs \
+	Protocols/Xmpp/XmppProtocolManager.cs \
+	Protocols/Xmpp/IQ/OwnMessage.cs
 
-REFERENCES =  \
+REFERENCES = \
 	System \
 	Mono.Posix \
-	$(JABBER_NET_LIBS) \
 	$(LOG4NET_LIBS)
 
-DLL_REFERENCES =  
-
-CLEANFILES = $(PROGRAMFILES) $(LINUX_PKGCONFIG) 
+DLL_REFERENCES = \
+	$(TARGET_DIR)/smuxi-common.dll \
+	$(TARGET_DIR)/smuxi-engine.dll \
+	$(TARGET_DIR)/jabber-net.dll
 
-include $(top_srcdir)/Makefile.include
+SOURCES_BUILD = $(addprefix $(srcdir)/, $(SOURCES))
 
-LOG4NET_DLL = $(BUILD_DIR)/log4net.dll
-NINI_DLL = $(BUILD_DIR)/Nini.dll
-SMUXI_ENGINE_DLL = $(BUILD_DIR)/smuxi-engine.dll
-JABBER_NET_DLL = $(BUILD_DIR)/jabber-net.dll
-ENGINE_XMPP_PC = $(BUILD_DIR)/smuxi-engine-xmpp.pc
-SMUXI_COMMON_DLL = $(BUILD_DIR)/smuxi-common.dll
+# automake magic variables
+EXTRA_DIST = $(SOURCES_BUILD)
+CLEANFILES = $(ASSEMBLY_TARGET) $(ASSEMBLY_TARGET).mdb
 
-$(eval $(call emit-deploy-target,SMUXI_ENGINE_DLL_MDB))
-$(eval $(call emit-deploy-target,SMUXI_ENGINE_DLL))
-$(eval $(call emit-deploy-wrapper,ENGINE_XMPP_PC,smuxi-engine-xmpp.pc))
-$(eval $(call emit-deploy-target,SMUXI_COMMON_DLL))
+pkglib_DATA = $(ASSEMBLY_TARGET) $(ASSEMBLY_TARGET).mdb
 
+include $(top_srcdir)/Makefile.include
 
-$(build_xamlg_list): %.xaml.g.cs: %.xaml
-	xamlg '$<'
-
-$(build_resx_resources) : %.resources: %.resx
-	resgen2 '$<' '$@'
+all: $(ASSEMBLY_TARGET)
 
-$(ASSEMBLY) $(ASSEMBLY_MDB): $(build_sources) $(build_resources) $(build_datafiles) $(DLL_REFERENCES) $(PROJECT_REFERENCES) $(build_xamlg_list) $(build_satellite_assembly_list)
-	mkdir -p $(dir $(ASSEMBLY))
-	$(ASSEMBLY_COMPILER_COMMAND) $(ASSEMBLY_COMPILER_FLAGS) -out:$(ASSEMBLY) -target:$(COMPILE_TARGET) $(build_sources_embed) $(build_resources_embed) $(build_references_ref)
+$(ASSEMBLY_TARGET) $(ASSEMBLY_TARGET).mdb: $(SOURCES) $(DLL_REFERENCES)
+	$(CSC) $(CSC_FLAGS) $(build_references_ref) -target:library -out:$@ $(SOURCES_BUILD)
diff --git a/src/Engine-XMPP/Makefile.in b/src/Engine-XMPP/Makefile.in
index f378238..873fb16 100644
--- a/src/Engine-XMPP/Makefile.in
+++ b/src/Engine-XMPP/Makefile.in
@@ -41,8 +41,11 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 subdir = src/Engine-XMPP
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -71,18 +74,18 @@ am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
 am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibdir)" \
 	"$(DESTDIR)$(linuxdesktopapplicationsdir)" \
-	"$(DESTDIR)$(linuxpkgconfigdir)" \
+	"$(DESTDIR)$(linuxpkgconfigdir)" "$(DESTDIR)$(pkglibdir)" \
 	"$(DESTDIR)$(programfilesdir)" \
 	"$(DESTDIR)$(programfilesiconsdir)"
 SCRIPTS = $(bin_SCRIPTS) $(pkglib_SCRIPTS)
-SOURCES =
 DIST_SOURCES =
 DATA = $(linuxdesktopapplications_DATA) $(linuxpkgconfig_DATA) \
-	$(programfiles_DATA) $(programfilesicons_DATA)
+	$(pkglib_DATA) $(programfiles_DATA) $(programfilesicons_DATA)
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -96,13 +99,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -143,13 +159,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -157,6 +175,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -167,13 +186,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -187,13 +215,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -201,7 +235,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -216,10 +252,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -250,77 +289,38 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 twitter_api_key = @twitter_api_key@
-EXTRA_DIST = $(build_sources) $(build_resx_files) \
-	$(build_others_files) $(ASSEMBLY_WRAPPER_IN) $(EXTRAS) \
-	$(DATA_FILES) $(build_culture_res_files)
- at ENABLE_DEBUG_TRUE@ASSEMBLY_COMPILER_COMMAND = @MCS@
-
-# Warning: This is an automatically generated file, do not edit!
- at ENABLE_RELEASE_TRUE@ASSEMBLY_COMPILER_COMMAND = @MCS@
- at ENABLE_DEBUG_TRUE@ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+ -debug -define:DEBUG "-define:DEBUG,TRACE,LOG4NET"
- at ENABLE_RELEASE_TRUE@ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+
- at ENABLE_DEBUG_TRUE@ASSEMBLY = ../../bin/debug/smuxi-engine-xmpp.dll
- at ENABLE_RELEASE_TRUE@ASSEMBLY = ../../bin/release/smuxi-engine-xmpp.dll
- at ENABLE_DEBUG_TRUE@ASSEMBLY_MDB = $(ASSEMBLY).mdb
- at ENABLE_RELEASE_TRUE@ASSEMBLY_MDB = 
- at ENABLE_DEBUG_TRUE@COMPILE_TARGET = library
- at ENABLE_RELEASE_TRUE@COMPILE_TARGET = library
- at ENABLE_DEBUG_TRUE@PROJECT_REFERENCES = \
- at ENABLE_DEBUG_TRUE@	../../bin/debug/smuxi-common.dll \
- at ENABLE_DEBUG_TRUE@	../../bin/debug/smuxi-engine.dll
-
- at ENABLE_RELEASE_TRUE@PROJECT_REFERENCES = \
- at ENABLE_RELEASE_TRUE@	../../bin/release/smuxi-common.dll \
- at ENABLE_RELEASE_TRUE@	../../bin/release/smuxi-engine.dll
-
- at ENABLE_DEBUG_TRUE@BUILD_DIR = ../../bin/debug
- at ENABLE_RELEASE_TRUE@BUILD_DIR = ../../bin/release
- at ENABLE_DEBUG_TRUE@SMUXI_ENGINE_DLL_MDB = $(BUILD_DIR)/smuxi-engine.dll.mdb
- at ENABLE_RELEASE_TRUE@SMUXI_ENGINE_DLL_MDB = 
- at ENABLE_DEBUG_TRUE@LOG4NET_DLL_SOURCE = ../../lib/log4net.dll
- at ENABLE_RELEASE_TRUE@LOG4NET_DLL_SOURCE = ../../lib/log4net.dll
- at ENABLE_DEBUG_TRUE@NINI_DLL_SOURCE = ../../lib/Nini.dll
- at ENABLE_RELEASE_TRUE@NINI_DLL_SOURCE = ../../lib/Nini.dll
- at ENABLE_DEBUG_TRUE@SMUXI_ENGINE_DLL_SOURCE = ../../bin/debug/smuxi-engine.dll
- at ENABLE_RELEASE_TRUE@SMUXI_ENGINE_DLL_SOURCE = ../../bin/release/smuxi-engine.dll
- at ENABLE_DEBUG_TRUE@JABBER_NET_DLL_SOURCE = ../../lib/jabber-net.dll
- at ENABLE_RELEASE_TRUE@JABBER_NET_DLL_SOURCE = ../../lib/jabber-net.dll
- at ENABLE_DEBUG_TRUE@SMUXI_COMMON_DLL_SOURCE = ../../bin/debug/smuxi-common.dll
- at ENABLE_RELEASE_TRUE@SMUXI_COMMON_DLL_SOURCE = ../../bin/release/smuxi-common.dll
- at ENABLE_DEBUG_TRUE@SMUXI_ENGINE_DLL_MDB_SOURCE = ../../bin/debug/smuxi-engine.dll.mdb
-AL = al2
-SATELLITE_ASSEMBLY_NAME = .resources.dll
-PROGRAMFILES = \
-	$(SMUXI_ENGINE_DLL_MDB) \
-	$(LOG4NET_DLL) \
-	$(NINI_DLL) \
-	$(SMUXI_ENGINE_DLL) \
-	$(JABBER_NET_DLL) \
-	$(SMUXI_COMMON_DLL)  
-
-LINUX_PKGCONFIG = \
-	$(ENGINE_XMPP_PC)  
-
-FILES = \
-	Protocols/Xmpp/XmppProtocolManager.cs \
+TARGET_DIR = $(top_builddir)/bin/$(PROFILE)
+ASSEMBLY_NAME = smuxi-engine-xmpp
+ASSEMBLY_FILENAME = $(ASSEMBLY_NAME).dll
+ASSEMBLY_TARGET = $(TARGET_DIR)/$(ASSEMBLY_FILENAME)
+SOURCES = \
 	$(top_srcdir)/src/AssemblyVersion.cs \
-	AssemblyInfo.cs 
-
-DATA_FILES = 
-RESOURCES = 
-EXTRAS = \
-	smuxi-engine-xmpp.pc.in 
+	AssemblyInfo.cs \
+	Config/XmppServerModel.cs \
+	Protocols/Xmpp/XmppGroupChatModel.cs \
+	Protocols/Xmpp/XmppProtocolManager.cs \
+	Protocols/Xmpp/IQ/OwnMessage.cs
 
 REFERENCES = \
 	System \
 	Mono.Posix \
-	$(JABBER_NET_LIBS) \
 	$(LOG4NET_LIBS)
 
-DLL_REFERENCES = 
-CLEANFILES = $(PROGRAMFILES) $(LINUX_PKGCONFIG) $(ASSEMBLY) \
+DLL_REFERENCES = \
+	$(TARGET_DIR)/smuxi-common.dll \
+	$(TARGET_DIR)/smuxi-engine.dll \
+	$(TARGET_DIR)/jabber-net.dll
+
+SOURCES_BUILD = $(addprefix $(srcdir)/, $(SOURCES))
+
+# automake magic variables
+EXTRA_DIST = $(SOURCES_BUILD) $(build_sources) $(build_resx_files) \
+	$(build_others_files) $(ASSEMBLY_WRAPPER_IN) $(EXTRAS) \
+	$(DATA_FILES) $(build_culture_res_files)
+CLEANFILES = $(ASSEMBLY_TARGET) $(ASSEMBLY_TARGET).mdb $(ASSEMBLY) \
 	$(ASSEMBLY).mdb $(BINARIES) $(build_resx_resources) \
 	$(build_satellite_assembly_list)
+pkglib_DATA = $(ASSEMBLY_TARGET) $(ASSEMBLY_TARGET).mdb
 VALID_CULTURES = ar bg ca zh-CHS cs da de el en es fi fr he hu is it ja ko nl no pl pt ro ru hr sk sq sv th tr id uk be sl et lv lt fa vi hy eu mk af fo hi sw gu ta te kn mr gl kok ar-SA bg-BG ca-ES zh-TW cs-CZ da-DK de-DE el-GR en-US fi-FI fr-FR he-IL hu-HU is-IS it-IT ja-JP ko-KR nl-NL nb-NO pl-PL pt-BR ro-RO ru-RU hr-HR sk-SK sq-AL sv-SE th-TH tr-TR id-ID uk-UA be-BY sl-SI et-EE lv-LV lt-LT fa-IR vi-VN hy-AM eu-ES mk-MK af-ZA fo-FO hi-IN sw-KE gu-IN ta-IN te-IN kn-IN mr-IN gl-ES kok-IN ar-IQ zh-CN de-CH en-GB es-MX fr-BE it-CH nl-BE nn-NO pt-PT sv-FI ar-EG zh-HK de-AT en-AU es-ES fr-CA ar-LY zh-SG de-LU en-CA es-GT fr-CH ar-DZ zh-MO en-NZ es-CR fr-LU ar-MA en-IE es-PA ar-TN en-ZA es-DO ar-OM es-VE ar-YE es-CO ar-SY es-PE ar-JO es-AR ar-LB en-ZW es-EC ar-KW en-PH es-CL ar-AE es-UY ar-BH es-PY ar-QA es-BO es-SV es-HN es-NI es-PR zh-CHT
 build_sources = $(FILES) $(GENERATED_FILES)
 build_sources_embed = $(build_sources:%='$(srcdir)/%')
@@ -350,7 +350,7 @@ build_references_ref = $(foreach ref, $(REFERENCES), $(if $(filter \
 	-pkg:%, $(ref)), $(ref), $(if $(filter -r:%, $(ref)), $(ref), \
 	-r:$(ref)))) $(foreach ref, $(DLL_REFERENCES), -r:$(ref)) \
 	$(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
 programfilesdir = @libdir@/@PACKAGE@
@@ -369,12 +369,6 @@ culture_resource_dependencies = $(BUILD_DIR)/$1/$(SATELLITE_ASSEMBLY_NAME): $(su
 culture_resource_commandlines = cmd_line_satellite_$1 += '/embed:$(subst .resx,.resources,$2)'
 build_satellite_assembly_list = $(cultures:%=$(BUILD_DIR)/%/$(SATELLITE_ASSEMBLY_NAME))
 build_culture_res_files = $(foreach res, $(culture_resources),$(call get_resource_name,$(res)))
-LOG4NET_DLL = $(BUILD_DIR)/log4net.dll
-NINI_DLL = $(BUILD_DIR)/Nini.dll
-SMUXI_ENGINE_DLL = $(BUILD_DIR)/smuxi-engine.dll
-JABBER_NET_DLL = $(BUILD_DIR)/jabber-net.dll
-ENGINE_XMPP_PC = $(BUILD_DIR)/smuxi-engine-xmpp.pc
-SMUXI_COMMON_DLL = $(BUILD_DIR)/smuxi-common.dll
 all: all-am
 
 .SUFFIXES:
@@ -478,6 +472,12 @@ uninstall-pkglibSCRIPTS:
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(linuxdesktopapplicationsdir)" || $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)"
@@ -518,6 +518,26 @@ uninstall-linuxpkgconfigDATA:
 	test -n "$$files" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(linuxpkgconfigdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(linuxpkgconfigdir)" && rm -f $$files
+install-pkglibDATA: $(pkglib_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)"
+	@list='$(pkglib_DATA)'; test -n "$(pkglibdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkglibdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(pkglibdir)" || exit $$?; \
+	done
+
+uninstall-pkglibDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkglib_DATA)'; test -n "$(pkglibdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
 install-programfilesDATA: $(programfiles_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(programfilesdir)" || $(MKDIR_P) "$(DESTDIR)$(programfilesdir)"
@@ -599,7 +619,7 @@ check-am: all-am
 check: check-am
 all-am: Makefile $(SCRIPTS) $(DATA)
 installdirs:
-	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(linuxdesktopapplicationsdir)" "$(DESTDIR)$(linuxpkgconfigdir)" "$(DESTDIR)$(programfilesdir)" "$(DESTDIR)$(programfilesiconsdir)"; do \
+	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(linuxdesktopapplicationsdir)" "$(DESTDIR)$(linuxpkgconfigdir)" "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(programfilesdir)" "$(DESTDIR)$(programfilesiconsdir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
 install: install-am
@@ -631,7 +651,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -657,7 +677,8 @@ install-dvi: install-dvi-am
 
 install-dvi-am:
 
-install-exec-am: install-binSCRIPTS install-pkglibSCRIPTS
+install-exec-am: install-binSCRIPTS install-pkglibDATA \
+	install-pkglibSCRIPTS
 
 install-html: install-html-am
 
@@ -685,7 +706,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-am
 
@@ -697,30 +718,32 @@ ps-am:
 
 uninstall-am: uninstall-binSCRIPTS \
 	uninstall-linuxdesktopapplicationsDATA \
-	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
-	uninstall-programfilesDATA uninstall-programfilesiconsDATA
+	uninstall-linuxpkgconfigDATA uninstall-pkglibDATA \
+	uninstall-pkglibSCRIPTS uninstall-programfilesDATA \
+	uninstall-programfilesiconsDATA
 
 .MAKE: install-am install-strip
 
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binSCRIPTS install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-linuxdesktopapplicationsDATA \
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binSCRIPTS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-man install-pdf \
-	install-pdf-am install-pkglibSCRIPTS install-programfilesDATA \
-	install-programfilesiconsDATA install-ps install-ps-am \
-	install-strip installcheck installcheck-am installdirs \
-	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
+	install-pdf-am install-pkglibDATA install-pkglibSCRIPTS \
+	install-programfilesDATA install-programfilesiconsDATA \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \
 	uninstall-binSCRIPTS uninstall-linuxdesktopapplicationsDATA \
-	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
-	uninstall-programfilesDATA uninstall-programfilesiconsDATA
+	uninstall-linuxpkgconfigDATA uninstall-pkglibDATA \
+	uninstall-pkglibSCRIPTS uninstall-programfilesDATA \
+	uninstall-programfilesiconsDATA
 
 
-all: $(ASSEMBLY) $(PROGRAMFILES) $(LINUX_PKGCONFIG) 
-
 # macros
 
 # $(call emit-deploy-target,deploy-variable-name)
@@ -748,20 +771,10 @@ $(build_satellite_assembly_list): $(BUILD_DIR)/%/$(SATELLITE_ASSEMBLY_NAME):
 	mkdir -p '$(@D)'
 	$(AL) -out:'$@' -culture:$* -t:lib $(cmd_line_satellite_$*)
 
-$(eval $(call emit-deploy-target,SMUXI_ENGINE_DLL_MDB))
-$(eval $(call emit-deploy-target,SMUXI_ENGINE_DLL))
-$(eval $(call emit-deploy-wrapper,ENGINE_XMPP_PC,smuxi-engine-xmpp.pc))
-$(eval $(call emit-deploy-target,SMUXI_COMMON_DLL))
-
-$(build_xamlg_list): %.xaml.g.cs: %.xaml
-	xamlg '$<'
-
-$(build_resx_resources) : %.resources: %.resx
-	resgen2 '$<' '$@'
+all: $(ASSEMBLY_TARGET)
 
-$(ASSEMBLY) $(ASSEMBLY_MDB): $(build_sources) $(build_resources) $(build_datafiles) $(DLL_REFERENCES) $(PROJECT_REFERENCES) $(build_xamlg_list) $(build_satellite_assembly_list)
-	mkdir -p $(dir $(ASSEMBLY))
-	$(ASSEMBLY_COMPILER_COMMAND) $(ASSEMBLY_COMPILER_FLAGS) -out:$(ASSEMBLY) -target:$(COMPILE_TARGET) $(build_sources_embed) $(build_resources_embed) $(build_references_ref)
+$(ASSEMBLY_TARGET) $(ASSEMBLY_TARGET).mdb: $(SOURCES) $(DLL_REFERENCES)
+	$(CSC) $(CSC_FLAGS) $(build_references_ref) -target:library -out:$@ $(SOURCES_BUILD)
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/Engine-XMPP/Protocols/Xmpp/IQ/OwnMessage.cs b/src/Engine-XMPP/Protocols/Xmpp/IQ/OwnMessage.cs
new file mode 100644
index 0000000..c1fbab5
--- /dev/null
+++ b/src/Engine-XMPP/Protocols/Xmpp/IQ/OwnMessage.cs
@@ -0,0 +1,99 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2011 <meebey at meebey.net>
+//
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+//
+// 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
+
+using System;
+using System.Xml;
+using jabber;
+using jabber.protocol;
+using jabber.protocol.client;
+
+namespace Smuxi.Engine
+{
+    /*
+     * <iq from="chat.facebook.com" type="set" id="fbiq4B035BDF6E005" to="username at chat.facebook.com/resource" xmlns="jabber:client">
+     *   <own-message xmlns="http://www.facebook.com/xmpp/messages" to="user_id at chat.facebook.com" self="false">
+     *     <body>message goes here</body>
+     *   </own-message>
+     * </iq>
+     */
+    internal class OwnMessageIQ : TypedIQ<OwnMessageQuery>
+    {
+        public OwnMessageIQ(XmlDocument doc) : base(doc)
+        {
+        }
+    }
+
+    internal class OwnMessageQuery : Element
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="doc"></param>
+        public OwnMessageQuery(XmlDocument doc)
+                        : base("own-message",
+                               "http://www.facebook.com/xmpp/messages",
+                               doc)
+        {
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prefix"></param>
+        /// <param name="qname"></param>
+        /// <param name="doc"></param>
+        public OwnMessageQuery(string prefix, XmlQualifiedName qname, XmlDocument doc) :
+                          base(prefix, qname, doc)
+        {
+        }
+
+        public JID To {
+            get {
+                return (JID) GetAttr("to");
+            }
+            set {
+                SetAttr("to", value);
+            }
+        }
+
+        public bool Self {
+            get {
+                var value = true;
+                Boolean.TryParse(GetAttr("self"), out value);
+                return value;
+            }
+            set {
+                SetAttr("self", value.ToString());
+            }
+        }
+
+        /// <summary>
+        /// Message body
+        /// </summary>
+        public string Body {
+            get {
+                return GetElem("body");
+            }
+            set {
+                SetElem("body", value);
+            }
+        }
+    }
+}
diff --git a/src/Engine-XMPP/Protocols/Xmpp/XmppGroupChatModel.cs b/src/Engine-XMPP/Protocols/Xmpp/XmppGroupChatModel.cs
new file mode 100644
index 0000000..d628f00
--- /dev/null
+++ b/src/Engine-XMPP/Protocols/Xmpp/XmppGroupChatModel.cs
@@ -0,0 +1,35 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2011 tuukka
+// 
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+// 
+// 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
+
+using System;
+
+namespace Smuxi.Engine
+{
+    public class XmppGroupChatModel : GroupChatModel
+    {
+        public string LatestSeenStamp { get; set; }
+        public bool SeenNewMessages { get; set; }
+
+        public XmppGroupChatModel(string id, string name, IProtocolManager networkManager) :
+                         base(id, name, networkManager)
+        {
+        }
+    }
+}
diff --git a/src/Engine-XMPP/Protocols/Xmpp/XmppProtocolManager.cs b/src/Engine-XMPP/Protocols/Xmpp/XmppProtocolManager.cs
index 24c8a73..da447d1 100644
--- a/src/Engine-XMPP/Protocols/Xmpp/XmppProtocolManager.cs
+++ b/src/Engine-XMPP/Protocols/Xmpp/XmppProtocolManager.cs
@@ -1,13 +1,8 @@
 /*
- * $Id: IrcProtocolManager.cs 149 2007-04-11 16:47:52Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Engine/IrcProtocolManager.cs $
- * $Rev: 149 $
- * $Author: meebey $
- * $Date: 2007-04-11 18:47:52 +0200 (Wed, 11 Apr 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2011 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2011 Tuukka Hastrup <Tuukka.Hastrup at iki.fi>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -27,17 +22,24 @@
  */
 
 using System;
+using System.IO;
+using System.Net.Security;
+using System.Xml;
 using System.Text;
 using System.Text.RegularExpressions;
+using System.Security.Cryptography.X509Certificates;
 using System.Threading;
 using System.Collections;
 using System.Collections.Generic;
 using System.Globalization;
 
+using jabber;
 using jabber.client;
 using jabber.connection;
+using jabber.protocol;
 using jabber.protocol.client;
-using jabberMessageType = jabber.protocol.client.MessageType;
+using jabber.protocol.iq;
+using XmppMessageType = jabber.protocol.client.MessageType;
 
 using Smuxi.Common;
 
@@ -58,6 +60,8 @@ namespace Smuxi.Engine
         private static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 #endif
         private JabberClient    _JabberClient;
+        private RosterManager   _RosterManager;
+        private ConferenceManager _ConferenceManager;
         private FrontendManager _FrontendManager;
         private ChatModel       _NetworkChat;
         
@@ -82,55 +86,83 @@ namespace Smuxi.Engine
         public XmppProtocolManager(Session session) : base(session)
         {
             Trace.Call(session);
-            
+
             _JabberClient = new JabberClient();
-            _JabberClient.Resource = Engine.VersionString;
+            _JabberClient.Resource = "Smuxi";
             _JabberClient.AutoLogin = true;
-            _JabberClient.AutoPresence = true;
-            _JabberClient.OnMessage += new MessageHandler(_OnMessage);
-            _JabberClient.OnConnect += new StanzaStreamHandler(_OnConnect);
-            _JabberClient.OnDisconnect += new bedrock.ObjectHandler(_OnDisconnect);
+            _JabberClient.AutoPresence = false;
+            _JabberClient.OnStreamInit += OnStreamInit;
+            _JabberClient.OnMessage += OnMessage;
+            _JabberClient.OnConnect += OnConnect;
+            _JabberClient.OnDisconnect += OnDisconnect;
+            _JabberClient.OnAuthenticate += OnAuthenticate;
+            _JabberClient.OnError += OnError;
+            _JabberClient.OnProtocol += OnProtocol;
+            _JabberClient.OnWriteText += OnWriteText;
+            _JabberClient.OnIQ += OnIQ;
 
-            _JabberClient.OnReadText += new bedrock.TextHandler(_OnReadText);
-            _JabberClient.OnWriteText += new bedrock.TextHandler(_OnWriteText);
-        }
-        
-        public override void Connect(FrontendManager fm, string host, int port, string username, string password)
-        {
-            Connect(fm, host, port, username, password, "smuxi");
+            _RosterManager = new RosterManager();
+            _RosterManager.Stream = _JabberClient;
+
+            _ConferenceManager = new ConferenceManager();
+            _ConferenceManager.Stream = _JabberClient;
+            _ConferenceManager.OnJoin += OnJoin;
+            _ConferenceManager.OnLeave += OnLeave;
+            _ConferenceManager.OnParticipantJoin += OnParticipantJoin;
+            _ConferenceManager.OnParticipantLeave += OnParticipantLeave;
         }
-        
-        public void Connect(FrontendManager fm, string host, int port, string username, string password, string resource)
+
+        public override void Connect(FrontendManager fm, ServerModel server)
         {
-            Trace.Call(fm, host, port, username, password);
-            
+            Trace.Call(fm, server);
+
+            if (fm == null) {
+                throw new ArgumentNullException("fm");
+            }
+            if (server == null) {
+                throw new ArgumentNullException("server");
+            }
+
             _FrontendManager = fm;
-            Host = host;
-            Port = port;
-            
+            Host = server.Hostname;
+            Port = server.Port;
+
             // TODO: use config for single network chat or once per network manager
-            _NetworkChat = new ProtocolChatModel(NetworkID, "Jabber " + host, this);
+            _NetworkChat = Session.CreateChat<ProtocolChatModel>(
+                NetworkID, "Jabber " + Host, this
+            );
             Session.AddChat(_NetworkChat);
             Session.SyncChat(_NetworkChat);
-            
-            _JabberClient.Server = host;
-            _JabberClient.Port = port;
-            _JabberClient.User = username;
-            _JabberClient.Password = password;
-            _JabberClient.Resource = resource;
+
+            ApplyConfig(Session.UserConfig, server);
+
             _JabberClient.Connect();
         }
         
         public override void Reconnect(FrontendManager fm)
         {
             Trace.Call(fm);
+
+            _JabberClient.Close();
+            _JabberClient.Connect();
         }
         
         public override void Disconnect(FrontendManager fm)
         {
             Trace.Call(fm);
+
+            _JabberClient.Close(false);
         }
-        
+
+        public override void Dispose()
+        {
+            Trace.Call();
+
+            base.Dispose();
+
+            _JabberClient.Dispose();
+        }
+
         public override string ToString()
         {
             string result = "Jabber ";
@@ -161,8 +193,12 @@ namespace Smuxi.Engine
         public override void CloseChat(FrontendManager fm, ChatModel chat)
         {
             Trace.Call(fm, chat);
-            
-            throw new NotImplementedException();
+
+            if (chat.ChatType == ChatType.Group) {
+                _ConferenceManager.GetRoom(chat.ID+"/"+_JabberClient.User).Leave("Closed");
+            } else {
+                Session.RemoveChat(chat);
+            }
         }
 
         public override void SetPresenceStatus(PresenceStatus status,
@@ -170,7 +206,30 @@ namespace Smuxi.Engine
         {
             Trace.Call(status, message);
 
-            // TODO: implement me
+            if (!IsConnected || !_JabberClient.IsAuthenticated) {
+                return;
+            }
+
+            PresenceType? xmppType = null;
+            string xmppShow = null;
+            switch (status) {
+                case PresenceStatus.Online:
+                    xmppType = PresenceType.available;
+                    break;
+                case PresenceStatus.Away:
+                    xmppType = PresenceType.available;
+                    xmppShow = "away";
+                    break;
+                case PresenceStatus.Offline:
+                    xmppType = PresenceType.unavailable;
+                    break;
+            }
+            if (xmppType == null) {
+                return;
+            }
+
+            _JabberClient.Presence(xmppType.Value, message, xmppShow,
+                                   _JabberClient.Priority);
         }
 
         public override bool Command(CommandModel command)
@@ -178,8 +237,32 @@ namespace Smuxi.Engine
             bool handled = false;
             if (IsConnected) {
                 if (command.IsCommand) {
+                    switch (command.Command) {
+                        case "help":
+                            CommandHelp(command);
+                            handled = true;
+                            break;
+                        case "msg":
+                        case "query":
+                            CommandMessageQuery(command);
+                            handled = true;
+                            break;
+                        case "say":
+                            CommandSay(command);
+                            handled = true;
+                            break;
+                        case "join":
+                            CommandJoin(command);
+                            handled = true;
+                            break;
+                        case "part":
+                        case "leave":
+                            CommandPart(command);
+                            handled = true;
+                            break;
+                    }
                 } else {
-                    _Say(command, command.Data);
+                    _Say(command.Chat, command.Data);
                     handled = true;
                 }
             } else {
@@ -221,7 +304,7 @@ namespace Smuxi.Engine
             
             string[] help = {
             "help",
-            "connect xmpp/jabber server port username passwort [resource]",
+            "connect xmpp/jabber server port username password [resource]",
             };
             
             foreach (string line in help) { 
@@ -233,18 +316,17 @@ namespace Smuxi.Engine
         {
             FrontendManager fm = cd.FrontendManager;
             
-            string server;
+            var server = new XmppServerModel();
             if (cd.DataArray.Length >= 3) {
-                server = cd.DataArray[2];
+                server.Hostname = cd.DataArray[2];
             } else {
                 NotEnoughParameters(cd);
                 return;
             }
             
-            int port;
             if (cd.DataArray.Length >= 4) {
                 try {
-                    port = Int32.Parse(cd.DataArray[3]);
+                    server.Port = Int32.Parse(cd.DataArray[3]);
                 } catch (FormatException) {
                     fm.AddTextToChat(
                         cd.Chat,
@@ -258,42 +340,119 @@ namespace Smuxi.Engine
                 return;
             }
             
-            string username;                
             if (cd.DataArray.Length >= 5) {
-                username = cd.DataArray[4];
+                server.Username = cd.DataArray[4];
             } else {
                 NotEnoughParameters(cd);
                 return;
             }
             
-            string password;
             if (cd.DataArray.Length >= 6) {
-                password = cd.DataArray[5];
+                server.Password = cd.DataArray[5];
             } else {
                 NotEnoughParameters(cd);
                 return;
             }
             
-            string resource;
             if (cd.DataArray.Length >= 7) {
-                resource = cd.DataArray[6];
-            } else {
-                resource = "smuxi";
+                server.Resource = cd.DataArray[6];
+            }
+
+            Connect(fm, server);
+        }
+        
+        public void CommandMessageQuery(CommandModel cd)
+        {
+            ChatModel chat = null;
+            if (cd.DataArray.Length >= 2) {
+                string nickname = cd.DataArray[1];
+                JID jid = null;
+                foreach (JID j in _RosterManager) {
+                    Item item = _RosterManager[j];
+                    if (item.Nickname != null &&
+                        item.Nickname.Replace(" ", "_") == nickname) {
+                        jid = item.JID;
+                        break;
+                    }
+                }
+                if (jid == null) {
+                    jid = nickname; // TODO check validity
+                }
+
+                chat = GetChat(jid, ChatType.Person);
+                if (chat == null) {
+                    PersonModel person = new PersonModel(jid, nickname,
+                                                         NetworkID, Protocol,
+                                                         this);
+                    chat = Session.CreatePersonChat(person, jid, nickname, this);
+                    Session.AddChat(chat);
+                    Session.SyncChat(chat);
+                }
             }
             
-            Connect(fm, server, port, username, password, resource);
+            if (cd.DataArray.Length >= 3) {
+                string message = String.Join(" ", cd.DataArray, 2, cd.DataArray.Length-2);
+                // ignore empty messages
+                if (message.TrimEnd(' ').Length > 0) {
+                    _Say(chat, message);
+                }
+            }
+        }
+        
+        public void CommandJoin(CommandModel cd)
+        {
+            string jid = cd.DataArray[1];
+            ChatModel chat = GetChat(jid, ChatType.Group);
+            if (chat == null) {
+                _ConferenceManager.GetRoom(jid+"/"+_JabberClient.User).Join();
+            }
+        }
+
+        public void CommandPart(CommandModel cd)
+        {
+            string jid;
+            if (cd.DataArray.Length >= 2)
+                jid = cd.DataArray[1];
+            else
+                jid = cd.Chat.ID;
+            ChatModel chat = GetChat(jid, ChatType.Group);
+            if (chat != null) {
+                _ConferenceManager.GetRoom(jid+"/"+_JabberClient.User).Leave("Part");
+            }
         }
+
+        public void CommandSay(CommandModel cd)
+        {
+            _Say(cd.Chat, cd.Parameter);
+        }  
         
-        private void _Say(CommandModel command, string text)
+        private void _Say(ChatModel chat, string text)
         {
-            if (!command.Chat.IsEnabled) {
+            _Say(chat, text, true);
+        }
+
+        private void _Say(ChatModel chat, string text, bool send)
+        {
+            if (!chat.IsEnabled) {
                 return;
             }
             
-            string target = command.Chat.ID;
-            
-            _JabberClient.Message(target, text);
-            
+            if (send) {
+                string target = chat.ID;
+                if (chat.ChatType == ChatType.Person) {
+                    _JabberClient.Message(target, text);
+                } else if (chat.ChatType == ChatType.Group) {
+                    var room = _ConferenceManager.GetRoom(
+                        String.Format(
+                            "{0}/{1}",
+                            target, _JabberClient.User
+                        )
+                    );
+                    room.PublicMessage(text);
+                    return; // don't show now. the message will be echoed back if it's sent successfully
+                }
+            }
+
             MessageModel msg = new MessageModel();
             TextMessagePartModel msgPart;
             
@@ -315,55 +474,348 @@ namespace Smuxi.Engine
             msgPart.Text = text;
             msg.MessageParts.Add(msgPart);
             
-            this.Session.AddMessageToChat(command.Chat, msg);
+            this.Session.AddMessageToChat(chat, msg);
         }
         
-        private void _OnReadText(object sender, string text)
+        void OnStreamInit(object sender, ElementStream stream)
         {
-            this.Session.AddTextToChat(_NetworkChat, "-!- RECV: " + text);
+            Trace.Call(sender, stream);
+
+            stream.AddType("own-message", "http://www.facebook.com/xmpp/messages", typeof(OwnMessageQuery));
         }
-        
-        private void _OnWriteText(object sender, string text)
+
+        void OnProtocol(object sender, XmlElement tag)
         {
-            this.Session.AddTextToChat(_NetworkChat, "-!- SENT: " + text);
+            if (!DebugProtocol) {
+                return;
+            }
+
+            try {
+                var strWriter = new StringWriter();
+                var xmlWriter = new XmlTextWriter(strWriter);
+                xmlWriter.Formatting = Formatting.Indented;
+                xmlWriter.Indentation = 2;
+                xmlWriter.IndentChar =  ' ';
+                tag.WriteTo(xmlWriter);
+
+                DebugRead("\n" + strWriter.ToString());
+            } catch (Exception ex) {
+#if LOG4NET
+                _Logger.Error("OnProtocol(): Exception", ex);
+#endif
+            }
         }
-        
-        private void _OnMessage(object sender, Message xmppMsg)
+
+        void OnWriteText(object sender, string text)
         {
-            // TODO: implement group chat
-            if (xmppMsg.Type == jabberMessageType.chat) {
-                string jid = xmppMsg.From.ToString();
-                string user = xmppMsg.From.User;
-                ChatModel chat = Session.GetChat(user, ChatType.Person, this);
-                if (chat == null) {
-                    PersonModel person = new PersonModel(jid, user, 
-                                                NetworkID, Protocol, this);
-                    chat = new PersonChatModel(person, jid, user, this);
-                    Session.AddChat(chat);
+            if (!DebugProtocol) {
+                return;
+            }
+
+            try {
+                if (text != null && text.Trim().Length == 0) {
+                    DebugWrite(text);
+                    return;
                 }
-                
-                MessageModel msg = new MessageModel();
-                TextMessagePartModel msgPart;
-                
-                // TODO: parse possible markup in body
-                msgPart = new TextMessagePartModel();
-                msgPart.Text = String.Format("<{0}> {1}", xmppMsg.From.User, xmppMsg.Body);
-                msg.MessageParts.Add(msgPart);
-                
-                Session.AddMessageToChat(chat, msg);
+
+                var strWriter = new StringWriter();
+                var xmlWriter = new XmlTextWriter(strWriter);
+                xmlWriter.Formatting = Formatting.Indented;
+                xmlWriter.Indentation = 2;
+                xmlWriter.IndentChar =  ' ';
+
+                var document = new XmlDocument();
+                document.LoadXml(text);
+                document.WriteContentTo(xmlWriter);
+
+                DebugWrite("\n" + strWriter.ToString());
+            } catch (XmlException) {
+                // HACK: in case of an invalid doucment fallback to
+                // plain string logging
+                DebugWrite("\n" + text);
+            } catch (Exception ex) {
+#if LOG4NET
+                _Logger.Error("OnWriteText(): Exception", ex);
+#endif
             }
         }
-        
-        private void _OnConnect(object sender, StanzaStream stream)
+
+        private void OnMessage(object sender, Message msg)
         {
-            IsConnected = true;
+            if (msg.Body == null) {
+                return;
+            }
+
+            var delay = msg["delay"];
+            string stamp = null;
+            if (delay != null) {
+                stamp = delay.Attributes["stamp"].Value;
+            }
+            bool display = true;
+
+            ChatModel chat = null;
+            PersonModel person = null;
+            if (msg.Type != XmppMessageType.groupchat) {
+                string jid = msg.From.Bare;
+                var contact = _RosterManager[jid];
+                string nickname = null;
+                if (contact == null || String.IsNullOrEmpty(contact.Nickname)) {
+                    nickname = jid;
+                } else {
+                    nickname = contact.Nickname;
+                }
+                PersonChatModel personChat = (PersonChatModel) Session.GetChat(jid, ChatType.Person, this);
+                if (personChat == null) {
+                    person = new PersonModel(jid, nickname, NetworkID,
+                                             Protocol, this);
+                    personChat = Session.CreatePersonChat(
+                        person, jid, nickname, this
+                    );
+                    Session.AddChat(personChat);
+                    Session.SyncChat(personChat);
+                } else {
+                    person = personChat.Person;
+                }
+                chat = personChat;
+            } else {
+                string group_jid = msg.From.Bare;
+                string group_name = group_jid;
+                string sender_jid = msg.From.ToString();
+                XmppGroupChatModel groupChat = (XmppGroupChatModel) Session.GetChat(group_jid, ChatType.Group, this);
+                if (groupChat == null) {
+                    // FIXME shouldn't happen?
+                    groupChat = Session.CreateChat<XmppGroupChatModel>(
+                        group_jid, group_name, this
+                    );
+                    Session.AddChat(groupChat);
+                    Session.SyncChat(groupChat);
+                }
+                person = groupChat.GetPerson(msg.From.Resource);
+                if (person == null) {
+                    // happens in case of a delayed message if the participant has left meanwhile
+                    person = new PersonModel(msg.From.Resource,
+                                             msg.From.Resource,
+                                             NetworkID, Protocol, this);
+                }
+
+                // XXX maybe only a Google Talk bug requires this:
+                if (stamp != null) {
+                    // XXX can't use > because of seconds precision :-(
+                    if (stamp.CompareTo(groupChat.LatestSeenStamp) >= 0) {
+                        groupChat.LatestSeenStamp = stamp;
+                    } else {
+                        display = false; // already seen newer delayed message
+                    }
+                    if (groupChat.SeenNewMessages) {
+                        display = false; // already seen newer messages
+                    }
+                } else {
+                    groupChat.SeenNewMessages = true;
+                }
+
+                chat = groupChat;
+            }
+
+            if (display) {
+                var builder = CreateMessageBuilder();
+                if (msg.Type != XmppMessageType.error) {
+                    builder.AppendMessage(person, msg.Body);
+                } else {
+                    // TODO: nicer formatting
+                    builder.AppendMessage(msg.Error.ToString());
+                }
+                if (stamp != null) {
+                    string format = DateTimeFormatInfo.InvariantInfo.UniversalSortableDateTimePattern.Replace(" ", "T");
+                    builder.TimeStamp = DateTime.ParseExact(stamp, format, null);
+                }
+                Session.AddMessageToChat(chat, builder.ToMessage());
+            }
+        }
+
+        void OnIQ(object sender, IQ iq)
+        {
+            Trace.Call(sender, iq);
+
+            if (iq.Query is OwnMessageQuery) {
+                OnIQOwnMessage((OwnMessageQuery) iq.Query);
+                iq.Handled = true;
+            }
+        }
+
+        void OnIQOwnMessage(OwnMessageQuery query)
+        {
+            if (query.Self) {
+                // we send this message from Smuxi, nothing to do...
+                return;
+            }
+
+            var target_jid = query.To.Bare;
+            var contact = _RosterManager[target_jid];
+            string nickname = null;
+            if (contact == null || String.IsNullOrEmpty(contact.Nickname)) {
+                nickname = target_jid;
+            } else {
+                nickname = contact.Nickname;
+            }
+            var chat = (PersonChatModel) Session.GetChat(target_jid,
+                                                         ChatType.Person, this);
+            if (chat == null) {
+                var person = new PersonModel(target_jid, nickname, NetworkID,
+                                             Protocol, this);
+                chat = Session.CreatePersonChat(
+                    person, target_jid, nickname, this
+                );
+                Session.AddChat(chat);
+                Session.SyncChat(chat);
+            }
+
+            _Say(chat, query.Body, false);
+        }
+
+        void OnJoin(Room room)
+        {
+            AddPersonToGroup(room, room.Nickname);
+        }
+
+        void OnLeave(Room room, Presence presence)
+        {
+            var chat = Session.GetChat(room.JID.Bare, ChatType.Group, this);
+            if (chat.IsEnabled)
+                Session.RemoveChat(chat);
+        }
+
+        void OnParticipantJoin(Room room, RoomParticipant roomParticipant)
+        {
+            AddPersonToGroup(room, roomParticipant.Nick);
+        }
+
+        private void AddPersonToGroup(Room room, string nickname)
+        {
+            string jid = room.JID.Bare;
+            var chat = (GroupChatModel) Session.GetChat(jid, ChatType.Group, this);
+            // first notice we're joining a group chat is the participant info:
+            if (chat == null) {
+                chat = Session.CreateChat<XmppGroupChatModel>(jid, jid, this);
+                Session.AddChat(chat);
+                Session.SyncChat(chat);
+            }
+
+            PersonModel person;
+            lock(chat.UnsafePersons) {
+                person = chat.GetPerson(nickname);
+                if (person != null) {
+                    return;
+                }
+
+                person = new PersonModel(nickname, nickname,
+                                         NetworkID, Protocol, this);
+                chat.UnsafePersons.Add(nickname, person);
+                Session.AddPersonToGroupChat(chat, person);
+            }
         }
         
-        private void _OnDisconnect(object sender)
+        public void OnParticipantLeave(Room room, RoomParticipant roomParticipant)
         {
+            string jid = room.JID.Bare;
+            var chat = (GroupChatModel) Session.GetChat(jid, ChatType.Group, this);
+            string nickname = roomParticipant.Nick;
+
+            PersonModel person;
+            lock(chat.UnsafePersons) {
+                person = chat.GetPerson(nickname);
+                if (person == null) {
+                    return;
+                }
+
+                chat.UnsafePersons.Remove(nickname);
+                Session.RemovePersonFromGroupChat(chat, person);
+            }
+        }
+
+        void OnConnect(object sender, StanzaStream stream)
+        {
+            Trace.Call(sender, stream);
+        }
+
+        void OnDisconnect(object sender)
+        {
+            Trace.Call(sender);
+
             IsConnected = false;
+            OnDisconnected(EventArgs.Empty);
         }
-        
+
+        void OnError(object sender, Exception ex)
+        {
+            Trace.Call(sender);
+
+#if LOG4NET
+            _Logger.Error("OnError(): Exception", ex);
+#endif
+
+            var builder = CreateMessageBuilder();
+            builder.AppendEventPrefix();
+            builder.AppendText(_("Error: {0}"), String.Empty);
+            builder.AppendMessage(ex.Message);
+            Session.AddMessageToChat(_NetworkChat, builder.ToMessage());
+        }
+
+        void OnAuthenticate(object sender)
+        {
+            Trace.Call(sender);
+
+            IsConnected = true;
+
+            Session.AddTextToChat(_NetworkChat, "Authenticated");
+
+            // send initial presence
+            SetPresenceStatus(PresenceStatus.Online, null);
+
+            OnConnected(EventArgs.Empty);
+        }
+
+        private void ApplyConfig(UserConfig config, ServerModel server)
+        {
+            if (server.Username.Contains("@")) {
+                var jid_user = server.Username.Split('@')[0];
+                var jid_host = server.Username.Split('@')[1];
+                _JabberClient.NetworkHost = server.Hostname;
+                _JabberClient.User = jid_user;
+                _JabberClient.Server = jid_host;
+            } else {
+                _JabberClient.Server = server.Hostname;
+                _JabberClient.User = server.Username;
+            }
+            _JabberClient.Port = server.Port;
+            _JabberClient.Password = server.Password;
+
+            // XMPP specific settings
+            if (server is XmppServerModel) {
+                var xmppServer = (XmppServerModel) server;
+                _JabberClient.Resource = xmppServer.Resource;
+            }
+
+            // fallback
+            if (String.IsNullOrEmpty(_JabberClient.Resource)) {
+                _JabberClient.Resource = "smuxi";
+            }
+
+            _JabberClient.OnInvalidCertificate -= ValidateCertificate;
+
+            _JabberClient.AutoStartTLS = server.UseEncryption;
+            if (!server.ValidateServerCertificate) {
+                _JabberClient.OnInvalidCertificate += ValidateCertificate;
+            }
+        }
+
+        private static bool ValidateCertificate(object sender,
+                                         X509Certificate certificate,
+                                         X509Chain chain,
+                                         SslPolicyErrors sslPolicyErrors)
+        {
+            return true;
+        }
+
         private static string _(string msg)
         {
             return Mono.Unix.Catalog.GetString(msg);
diff --git a/src/Engine/AssemblyInfo.cs b/src/Engine/AssemblyInfo.cs
index 8148fb4..0d8c490 100644
--- a/src/Engine/AssemblyInfo.cs
+++ b/src/Engine/AssemblyInfo.cs
@@ -1,10 +1,4 @@
 /*
- * $Id$
- * $URL$
- * $Rev$
- * $Author$
- * $Date$
- *
  * Smuxi - Smart MUltipleXed Irc
  *
  * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
@@ -32,7 +26,7 @@ using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 [assembly: AssemblyTitle("Smuxi - engine")]
-[assembly: AssemblyCopyright("2005-2010 (C) Mirco Bauer <meebey at meebey.net>")]
+[assembly: AssemblyCopyright("2005-2012 (C) Mirco Bauer <meebey at meebey.net>")]
 
 [assembly: AssemblyDelaySign(false)]
 [assembly: AssemblyKeyFile("")]
diff --git a/src/Engine/Chats/ChatModel.cs b/src/Engine/Chats/ChatModel.cs
index 8b3e3d7..9a861cb 100644
--- a/src/Engine/Chats/ChatModel.cs
+++ b/src/Engine/Chats/ChatModel.cs
@@ -1,7 +1,7 @@
 /*
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2008, 2010 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2008, 2010-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -33,15 +33,20 @@ namespace Smuxi.Engine
 #if LOG4NET
         private static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 #endif
+        const string LibraryTextDomain = "smuxi-engine";
         private string               _ID;
         private string               _Name;
         private ChatType             _ChatType;
         private IProtocolManager     _ProtocolManager;
-        private List<MessageModel>   _Messages = new List<MessageModel>();
+        //private List<MessageModel>   _Messages = new List<MessageModel>();
         private bool                 _IsEnabled = true;
+        // TODO: make persistent
         private DateTime             _LastSeenHighlight;
         private string               _LogFile;
+        // TODO: make persistent
         public  int                  Position { get; set; }
+        public  IMessageBuffer       MessageBuffer { get; private set; }
+        public  int                  MessagesSyncCount { get; set; }
 
         public string ID {
             get {
@@ -66,20 +71,46 @@ namespace Smuxi.Engine
                 return _ProtocolManager;
             }
         }
-        
+
+        [Obsolete("Use ChatModel.MessageBuffer instead.")]
         public IList<MessageModel> Messages {
             get {
-                lock (_Messages) {
-                    // during cloning, someone could modify it and break the enumerator
-                    return new List<MessageModel>(_Messages);
-                }
-            }
-        }
-        
-        internal IList<MessageModel> UnsafeMessages {
-            get {
-                lock (_Messages) {
-                    return _Messages;
+                try {
+                    return GetSyncMessages();
+                } catch (Exception ex) {
+#if LOG4NET
+                    _Logger.Error(
+                        String.Format(
+                            "{0}.get_Messages(): " +
+                            "GetSyncMessages() threw exception!", this
+                        ), ex
+                    );
+#endif
+                    if (MessageBuffer is Db4oMessageBuffer) {
+#if LOG4NET
+                        _Logger.Error(
+                            String.Format(
+                                "{0}.get_Messages(): " +
+                                "Falling back to volatile message buffer...",
+                                this
+                            )
+                        );
+#endif
+                        ResetMessageBuffer();
+                        InitMessageBuffer(MessageBufferPersistencyType.Volatile);
+
+                        var builder = new MessageBuilder();
+                        builder.AppendEventPrefix();
+                        builder.AppendErrorText(
+                            _("Failed to load chat history. " +
+                              "Your chat history will not be preserved. " +
+                              "Reason: {0}"),
+                            ex.Message
+                        );
+                        MessageBuffer.Add(builder.ToMessage());
+                        return GetSyncMessages();
+                    }
+                    throw;
                 }
             }
         }
@@ -118,14 +149,56 @@ namespace Smuxi.Engine
             _ChatType = chatType;
             _ProtocolManager = networkManager;
             Position = -1;
+            if (ProtocolManager == null) {
+                InitMessageBuffer(MessageBufferPersistencyType.Volatile);
+            }
         }
-        
+
+        public override string ToString()
+        {
+            return String.Format("<{0}>", ToTraceString());
+        }
+
         public string ToTraceString()
         {
             string nm = (_ProtocolManager != null) ? _ProtocolManager.ToString() : "(null)";  
             return  nm + "/" + _Name; 
         }
-        
+
+        public void ApplyConfig(UserConfig config)
+        {
+            if (config == null) {
+                throw new ArgumentNullException("config");
+            }
+
+            MessagesSyncCount =
+                (int) config["Interface/Notebook/EngineBufferLines"];
+
+            var enumStr = (string) config["MessageBuffer/PersistencyType"];
+            MessageBufferPersistencyType persistency;
+            try {
+                persistency = (MessageBufferPersistencyType) Enum.Parse(
+                    typeof(MessageBufferPersistencyType), enumStr, true
+                );
+            } catch (ArgumentException ex) {
+#if LOG4NET
+                _Logger.Error("ApplyConfig(): failed to parse " +
+                              "PersistencyType: " + enumStr, ex);
+#endif
+                persistency = MessageBufferPersistencyType.Volatile;
+            }
+            InitMessageBuffer(persistency);
+
+            var maxCapacityKey = String.Format("MessageBuffer/{0}/MaxCapacity",
+                                               persistency.ToString());
+            MessageBuffer.MaxCapacity = (int) config[maxCapacityKey];
+        }
+
+        public void Close()
+        {
+            MessageBuffer.Dispose();
+        }
+
         private string GetLogFile()
         {
             if (_ProtocolManager == null) {
@@ -139,41 +212,119 @@ namespace Smuxi.Engine
             if (network != protocol) {
                 logPath = Path.Combine(logPath, network);
             }
-            if (logPath.IndexOfAny(Path.GetInvalidPathChars()) != -1) {
+            logPath = IOSecurity.GetFilteredPath(logPath);
+            if (!Directory.Exists(logPath)) {
+                Directory.CreateDirectory(logPath);
+            }
+
+            var chatId = IOSecurity.GetFilteredFileName(ID.ToLower());
+            logPath = Path.Combine(logPath, String.Format("{0}.log", chatId));
+            return logPath;
+        }
+
+        IList<MessageModel> GetSyncMessages()
+        {
+            // during cloning, someone could modify it and break the enumerator
+            lock (MessageBuffer) {
+                if (MessageBuffer.Count == 0) {
+                    return new List<MessageModel>(0);
+                }
+                if (MessagesSyncCount <= 0) {
+                    return new List<MessageModel>(MessageBuffer);
+                } else {
+                    var offset = MessageBuffer.Count - MessagesSyncCount;
+                    if (offset < 0) {
+                        offset = 0;
+                    }
+                    return MessageBuffer.GetRange(offset, MessagesSyncCount);
+                }
+            }
+        }
+
+        public void InitMessageBuffer(MessageBufferPersistencyType persistency)
+        {
+            Trace.Call(persistency);
+
+            if (MessageBuffer != null) {
+                return;
+            }
+
+            switch (persistency) {
+                case MessageBufferPersistencyType.Volatile:
+                    MessageBuffer = new ListMessageBuffer();
+                    break;
+                case MessageBufferPersistencyType.Persistent:
+                    try {
+                        var start = DateTime.UtcNow;
+                        MessageBuffer = new Db4oMessageBuffer(
+                            ProtocolManager.Session.Username,
+                            ProtocolManager.Protocol,
+                            ProtocolManager.NetworkID,
+                            ID
+                        );
+                        var stop = DateTime.UtcNow;
 #if LOG4NET
-                _Logger.Warn(
-                    "GetLogFile(): logPath '" + logPath + "' contains " +
-                     "invalid chars, removing them!"
-                );
+                        _Logger.DebugFormat(
+                            "InitMessageBuffer(): initializing " +
+                            "Db4oMessageBuffer({0}, {1}, {2}, {3}) " +
+                            "took: {4:0.00} ms",
+                            ProtocolManager.Session.Username,
+                            ProtocolManager.Protocol,
+                            ProtocolManager.NetworkID,
+                            ID,
+                            (stop - start).TotalMilliseconds
+                        );
 #endif
-                // remove invalid chars
-                foreach (char invalidChar in Path.GetInvalidPathChars()) {
-                    logPath = logPath.Replace(invalidChar.ToString(),
-                                              String.Empty);
-                }
+                    } catch (Exception ex) {
+#if LOG4NET
+                        _Logger.Error(
+                            "InitMessageBuffer(): Db4oMessageBuffer() threw " +
+                            "exception, falling back to memory backend!", ex
+                        );
+#endif
+                        MessageBuffer = new ListMessageBuffer();
+
+                        var builder = new MessageBuilder();
+                        builder.AppendEventPrefix();
+                        builder.AppendErrorText(
+                            _("Failed to open chat history for writing. " +
+                              "Your chat history will not be preserved. " +
+                              "Reason: {0}"),
+                            ex.Message
+                        );
+                        MessageBuffer.Add(builder.ToMessage());
+                    }
+                    break;
             }
+        }
 
-            if (!Directory.Exists(logPath)) {
-                Directory.CreateDirectory(logPath);
+        public void ResetMessageBuffer()
+        {
+            Trace.Call();
+
+            if (MessageBuffer == null) {
+                // nothing to reset
+                return;
             }
-            
-            var chatId = ID.Replace(" ", "_").ToLower();
-            if (chatId.IndexOfAny(Path.GetInvalidFileNameChars()) != -1) {
+
+            lock (MessageBuffer) {
+                try {
+                    MessageBuffer.Dispose();
+                } catch (Exception ex) {
 #if LOG4NET
-                _Logger.Warn(
-                    "GetLogFile(): chatId '" + logPath + "' contains " +
-                     "invalid chars, removing them!"
-                );
+                    _Logger.Warn(
+                        "ResetMessageBuffer(): MessageBuffer.Dispose() " +
+                        "threw exception!", ex
+                    );
 #endif
-                // remove invalid chars
-                foreach (char invalidChar in Path.GetInvalidFileNameChars()) {
-                    chatId = chatId.Replace(invalidChar.ToString(),
-                                            String.Empty);
                 }
             }
-            logPath = Path.Combine(logPath, String.Format("{0}.log", chatId));
-            logPath = logPath.Replace("..", String.Empty);
-            return logPath;
+            MessageBuffer = null;
+        }
+
+        static string _(string msg)
+        {
+            return LibraryCatalog.GetString(msg, LibraryTextDomain);
         }
     }
 }
diff --git a/src/Engine/Chats/GroupChatModel.cs b/src/Engine/Chats/GroupChatModel.cs
index ec52eb8..cc54cd1 100644
--- a/src/Engine/Chats/GroupChatModel.cs
+++ b/src/Engine/Chats/GroupChatModel.cs
@@ -1,13 +1,7 @@
 /*
- * $Id: ChannelPage.cs 137 2006-11-06 18:49:57Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Engine/ChannelPage.cs $
- * $Rev: 137 $
- * $Author: meebey $
- * $Date: 2006-11-06 19:49:57 +0100 (Mon, 06 Nov 2006) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2009, 2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -40,7 +34,7 @@ namespace Smuxi.Engine
 #endif
         //private Hashtable _Persons = Hashtable.Synchronized(new Hashtable());
         // shouldn't need threadsafe wrapper, only the "owning" IRC thread should write to it
-        private IDictionary<string, PersonModel> _Persons = new Dictionary<string, PersonModel>();
+        private Dictionary<string, PersonModel>  _Persons = new Dictionary<string, PersonModel>();
         private bool                             _IsSynced;
         // HACK: IRC specific?
         private MessageModel _Topic;
@@ -80,7 +74,7 @@ namespace Smuxi.Engine
                     if (_Persons.Count == 0) {
                         return null;
                     }
-                    return new Dictionary<string, PersonModel>(_Persons);
+                    return new Dictionary<string, PersonModel>(_Persons, _Persons.Comparer);
                 }
             }
         }
@@ -94,6 +88,23 @@ namespace Smuxi.Engine
             }
         }
         
+        public IEqualityComparer<string> UnsafePersonsComparer {
+            get {
+                lock (_Persons) {
+                    return _Persons.Comparer;
+                }
+            }
+            set {
+                if (value == null) {
+                    return;
+                }
+
+                lock (_Persons) {
+                    _Persons = new Dictionary<string, PersonModel>(_Persons, value);
+                }
+            }
+        }
+
         public int PersonCount {
             get {
                 if (_PersonCount != -1) {
@@ -128,7 +139,7 @@ namespace Smuxi.Engine
             }
             
             PersonModel personModel;
-            _Persons.TryGetValue(id.ToLower(), out personModel);
+            _Persons.TryGetValue(id, out personModel);
             return personModel;
         }
         
diff --git a/src/Engine/Chats/SessionChatModel.cs b/src/Engine/Chats/SessionChatModel.cs
index 681efe1..b85945d 100644
--- a/src/Engine/Chats/SessionChatModel.cs
+++ b/src/Engine/Chats/SessionChatModel.cs
@@ -1,13 +1,7 @@
 /*
- * $Id: ChannelPage.cs 137 2006-11-06 18:49:57Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Engine/ChannelPage.cs $
- * $Rev: 137 $
- * $Author: meebey $
- * $Date: 2006-11-06 19:49:57 +0100 (Mon, 06 Nov 2006) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2008 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2008, 2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -39,7 +33,7 @@ namespace Smuxi.Engine
         public SessionChatModel(string id, string name) :
                            base(id, name, ChatType.Session, null)
         {
+            Position = 0;
         }
     }
 }
-
diff --git a/src/Engine/Config/Config.cs b/src/Engine/Config/Config.cs
index 7366a31..abe7e90 100644
--- a/src/Engine/Config/Config.cs
+++ b/src/Engine/Config/Config.cs
@@ -29,6 +29,7 @@
 using System;
 using System.IO;
 using System.Collections;
+using System.Collections.Generic;
 using Mono.Unix.Native;
 #if CONFIG_NINI
 using Nini.Config;
@@ -283,8 +284,8 @@ namespace Smuxi.Engine
             Get(prefix+"BeepOnHighlight", false);
             
             prefix = "Engine/Users/DEFAULT/Connection/";
-            Get(prefix+"Encoding", String.Empty);
-            Get(prefix+"ProxyType", "None");
+            Get(prefix+"Encoding", "UTF-8");
+            Get(prefix+"ProxyType", "System");
             Get(prefix+"ProxyHostname", String.Empty);
             Get(prefix+"ProxyPort", -1);
             Get(prefix+"ProxyUsername", String.Empty);
@@ -294,6 +295,13 @@ namespace Smuxi.Engine
             Get(prefix+"Enabled", false);
             Get(prefix+"LogFilteredMessages", false);
 
+            prefix = "Engine/Users/DEFAULT/MessageBuffer/";
+            Get(prefix+"PersistencyType", "Volatile");
+            prefix = "Engine/Users/DEFAULT/MessageBuffer/Volatile/";
+            Get(prefix+"MaxCapacity", 200);
+            prefix = "Engine/Users/DEFAULT/MessageBuffer/Persistent/";
+            Get(prefix+"MaxCapacity", 50 * 1000);
+
             prefix = "Engine/Users/DEFAULT/Servers/";
             Get(prefix + "Servers", new string[] {
                 "IRC/irc.oftc.net",
@@ -404,6 +412,9 @@ namespace Smuxi.Engine
                 string realname = null;
                 try {
                     string gecos = Mono.Unix.UnixUserInfo.GetRealUser().RealName;
+                    if (gecos == null) {
+                        gecos = String.Empty;
+                    }
                     int pos = gecos.IndexOf(",");
                     if (pos != -1) {
                         realname = gecos.Substring(0, pos);
@@ -421,7 +432,7 @@ namespace Smuxi.Engine
                 LoadUserEntry(user, "Connection/Realname", realname);
                 LoadUserEntry(user, "Connection/Encoding", String.Empty);
 
-                LoadUserEntry(user, "Connection/ProxyType", "None");
+                LoadUserEntry(user, "Connection/ProxyType", "System");
                 LoadUserEntry(user, "Connection/ProxyHostname", String.Empty);
                 LoadUserEntry(user, "Connection/ProxyPort", -1);
                 LoadUserEntry(user, "Connection/ProxyUsername", null);
@@ -474,6 +485,10 @@ namespace Smuxi.Engine
                 LoadUserEntry(user, "Logging/Enabled", null);
                 LoadUserEntry(user, "Logging/LogFilteredMessages", null);
 
+                LoadUserEntry(user, "MessageBuffer/PersistencyType", null);
+                LoadUserEntry(user, "MessageBuffer/Volatile/MaxCapacity", null);
+                LoadUserEntry(user, "MessageBuffer/Persistent/MaxCapacity", null);
+
                 string[] servers = null;
                 string sprefix = prefix + user + "/Servers/";
                 servers = GetList(sprefix + "Servers");
@@ -518,7 +533,7 @@ namespace Smuxi.Engine
                     sprefix = prefix + user + "/Servers/" + server + "/";
                     LoadEntry(sprefix+"Hostname", null);
                     LoadEntry(sprefix+"Port", null);
-                    LoadEntry(sprefix+"Network", null);
+                    LoadEntry(sprefix+"Network", String.Empty);
                     LoadEntry(sprefix+"Encoding", null);
                     LoadEntry(sprefix+"Username", String.Empty);
                     LoadEntry(sprefix+"Password", String.Empty);
@@ -554,6 +569,17 @@ namespace Smuxi.Engine
             }
         }
 
+        public IDictionary<string, object> GetAll()
+        {
+            lock (m_Preferences) {
+                var dict = new Dictionary<string, object>(m_Preferences.Count);
+                foreach (DictionaryEntry entry in m_Preferences) {
+                    dict.Add((string) entry.Key, entry.Value);
+                }
+                return dict;
+            }
+        }
+
         public void Save()
         {
             Trace.Call();
diff --git a/src/Engine/Config/EntrySettings.cs b/src/Engine/Config/EntrySettings.cs
new file mode 100644
index 0000000..0e556f1
--- /dev/null
+++ b/src/Engine/Config/EntrySettings.cs
@@ -0,0 +1,57 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2011 Mirco Bauer <meebey at meebey.net>
+// 
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+// 
+// 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
+
+using System;
+
+namespace Smuxi.Engine
+{
+    public class EntrySettings
+    {
+        public string CommandCharacter { get; set; }
+        public string CompletionCharacter { get; set; }
+        public bool BashStyleCompletion { get; set; }
+        public int CommandHistorySize { get; set; }
+
+        public EntrySettings()
+        {
+            // internal defaults
+            CommandCharacter = "/";
+            CompletionCharacter = ":";
+            BashStyleCompletion = false;
+            CommandHistorySize = 30;
+        }
+
+        public void ApplyConfig(UserConfig config)
+        {
+            if (config == null) {
+                throw new ArgumentNullException("config");
+            }
+
+            CommandCharacter = (string)
+                config["Interface/Entry/CommandCharacter"];
+            CompletionCharacter = (string)
+                config["Interface/Entry/CompletionCharacter"];
+            BashStyleCompletion = (bool)
+                config["Interface/Entry/BashStyleCompletion"];
+            CommandHistorySize = (int)
+                config["Interface/Entry/CommandHistorySize"];
+        }
+    }
+}
diff --git a/src/Engine/Config/FrontendConfig.cs b/src/Engine/Config/FrontendConfig.cs
index 33a6ed3..024d936 100644
--- a/src/Engine/Config/FrontendConfig.cs
+++ b/src/Engine/Config/FrontendConfig.cs
@@ -79,6 +79,9 @@ namespace Smuxi.Engine
 #endif
             
             // setting required default values
+            prefix = "Frontend/";
+            LoadEntry(prefix+"UseLowBandwidthMode", false);
+
             prefix = "Frontend/Engines/";
             Get<string[]>(prefix+"Engines", new string[] {});
             Get(prefix+"Default", String.Empty);
@@ -104,6 +107,7 @@ namespace Smuxi.Engine
                 LoadEntry(eprefix+"SshPort", 22);
                 LoadEntry(eprefix+"SshUsername", String.Empty);
                 LoadEntry(eprefix+"SshPassword", String.Empty);
+                LoadEntry(eprefix+"SshKeyfile", String.Empty);
             }
             
             LoadAllEntries("Frontend/"+_UIName);
diff --git a/src/Engine/Config/ProxySettings.cs b/src/Engine/Config/ProxySettings.cs
new file mode 100644
index 0000000..f38f669
--- /dev/null
+++ b/src/Engine/Config/ProxySettings.cs
@@ -0,0 +1,156 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2011 Mirco Bauer <meebey at meebey.net>
+// 
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+// 
+// 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
+
+using System;
+using System.Net;
+using System.Text.RegularExpressions;
+using System.Collections.Generic;
+
+namespace Smuxi.Engine
+{
+    public class ProxySettings
+    {
+#if LOG4NET
+        private static readonly log4net.ILog f_Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+#endif
+        public ProxyType ProxyType { get; set; }
+        public string ProxyHostname { get; set; }
+        public int ProxyPort { get; set; }
+        public string ProxyUsername { get; set; }
+        public string ProxyPassword { get; set; }
+        public IWebProxy SystemWebProxy { get; set; }
+        public WebProxy DefaultWebProxy { get; set; }
+
+        public ProxySettings()
+        {
+            ProxyType = ProxyType.None;
+        }
+
+        public WebProxy GetWebProxy(Uri destination)
+        {
+            if (destination == null) {
+                throw new ArgumentNullException("destination");
+            }
+
+            if (SystemWebProxy == null &&
+                DefaultWebProxy == null) {
+#if LOG4NET
+                f_Logger.DebugFormat("GetWebProxy(<{0}>): returning no proxy",
+                                     destination);
+#endif
+                // no proxy
+                return null;
+            }
+
+            if (SystemWebProxy == null) {
+#if LOG4NET
+                f_Logger.DebugFormat("GetWebProxy(<{0}>): returning default proxy: {1}",
+                                     destination, DefaultWebProxy.Address);
+#endif
+                return DefaultWebProxy;
+            }
+            var proxyUri = SystemWebProxy.GetProxy(destination);
+            if (proxyUri == destination) {
+#if LOG4NET
+                f_Logger.DebugFormat("GetWebProxy(<{0}>): returning no proxy",
+                                     destination);
+#endif
+                // no proxy
+                return null;
+            }
+#if LOG4NET
+            f_Logger.DebugFormat("GetWebProxy(<{0}>): returning system proxy: {1}",
+                                 destination, proxyUri);
+#endif
+            return new WebProxy(proxyUri);
+        }
+
+        public WebProxy GetWebProxy(string destination)
+        {
+            if (destination == null) {
+                throw new ArgumentNullException("destination");
+            }
+            return GetWebProxy(new Uri(destination));
+        }
+
+        public void ApplyConfig(UserConfig config)
+        {
+            if (config == null) {
+                throw new ArgumentNullException("config");
+            }
+
+            var proxyType = (string) config["Connection/ProxyType"];
+            ProxyType = (ProxyType) Enum.Parse(typeof(ProxyType), proxyType, true);
+            ProxyHostname = (string) config["Connection/ProxyHostname"];
+            ProxyPort = (int) config["Connection/ProxyPort"];
+            ProxyUsername = (string) config["Connection/ProxyUsername"];
+            ProxyPassword = (string) config["Connection/ProxyPassword"];
+
+            switch (ProxyType) {
+                case ProxyType.None:
+                    DefaultWebProxy = null;
+                    SystemWebProxy = null;
+                    break;
+                case ProxyType.System:
+                    var proxy = WebRequest.GetSystemWebProxy();
+                    // TODO: add GNOME (gconf) support
+                    var no_proxy = Environment.GetEnvironmentVariable("no_proxy");
+                    if (!String.IsNullOrEmpty(no_proxy) && proxy is WebProxy) {
+                        var webProxy = (WebProxy) proxy;
+                        // BypassArrayList expects regexes while no_proxy
+                        // contains domains
+                        var bypassUriRegexes = new List<string>();
+                        foreach (var domain in no_proxy.Split(',')) {
+                            string domainRegex = null;
+                            if (domain.StartsWith(".")) {
+                                domainRegex = String.Format(
+                                    @"^[a-z]+://(.+\.)?{0}",
+                                    Regex.Escape(domain.Substring(1))
+                                );
+                            } else if (!Regex.IsMatch(domain, @"^[a-z]+://")) {
+                                domainRegex = String.Format(
+                                    @"^[a-z]+://{0}",
+                                    Regex.Escape(domain)
+                                );
+                            } else {
+                                domainRegex = Regex.Escape(domain);
+                            }
+                            bypassUriRegexes.Add(domainRegex);
+                        }
+                        webProxy.BypassArrayList.AddRange(bypassUriRegexes);
+                    }
+                    DefaultWebProxy = null;
+                    SystemWebProxy = proxy;
+                    break;
+                case ProxyType.Http:
+                    var uriBuilder = new UriBuilder();
+                    uriBuilder.Scheme = "http";
+                    uriBuilder.Host = ProxyHostname;
+                    uriBuilder.Port = ProxyPort;
+                    uriBuilder.UserName = ProxyUsername;
+                    uriBuilder.Password = ProxyPassword;
+                    var proxyUri = uriBuilder.ToString();
+                    DefaultWebProxy = new WebProxy(proxyUri);
+                    SystemWebProxy = null;
+                    break;
+            }
+        }
+    }
+}
diff --git a/src/Engine/Config/ProxyType.cs b/src/Engine/Config/ProxyType.cs
index 4ea9b7b..3b9d68a 100644
--- a/src/Engine/Config/ProxyType.cs
+++ b/src/Engine/Config/ProxyType.cs
@@ -24,6 +24,7 @@ namespace Smuxi.Engine
 {
     public enum ProxyType {
         None,
+        System,
         Http,
         Socks4,
         Socks4a,
diff --git a/src/Engine/Config/ServerModel.cs b/src/Engine/Config/ServerModel.cs
index ac7669e..4ecc83d 100644
--- a/src/Engine/Config/ServerModel.cs
+++ b/src/Engine/Config/ServerModel.cs
@@ -1,13 +1,7 @@
 /*
- * $Id: PreferencesDialog.cs 142 2007-01-02 22:19:08Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-GNOME/PreferencesDialog.cs $
- * $Rev: 142 $
- * $Author: meebey $
- * $Date: 2007-01-02 23:19:08 +0100 (Tue, 02 Jan 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2007, 2010 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
diff --git a/src/Engine/Config/UserConfig.cs b/src/Engine/Config/UserConfig.cs
index c252419..7b77a27 100644
--- a/src/Engine/Config/UserConfig.cs
+++ b/src/Engine/Config/UserConfig.cs
@@ -29,6 +29,8 @@
 using System;
 using System.Runtime.Remoting;
 using System.Collections;
+using System.Collections.Generic;
+using Smuxi.Common;
 
 namespace Smuxi.Engine
 {
@@ -89,6 +91,7 @@ namespace Smuxi.Engine
                 return obj;
             }
             set {
+                // TODO: make remoting calls after a timeout and batch the update
                 _Config[_UserPrefix + key] = value;
                 
                 // update entry in cache
@@ -134,10 +137,21 @@ namespace Smuxi.Engine
         public void Remove(string key)
         {
             _Config.Remove(_UserPrefix + key);
-            
-            // invalidate cache when this is a complete section
+
+            if (!IsCaching) {
+                return;
+            }
             if (key.EndsWith("/")) {
-                ClearCache();
+                // invalidate all cache keys of this section
+                var cachedKeys = new List<string>();
+                foreach (string cacheKey in _Cache.Keys) {
+                    if (cacheKey.StartsWith(key)) {
+                        cachedKeys.Add(cacheKey);
+                    }
+                }
+                foreach (string cacheKey in cachedKeys) {
+                    _Cache.Remove(cacheKey);
+                }
             } else {
                 // deleting the single entry is enough
                 _Cache.Remove(key);
@@ -149,6 +163,38 @@ namespace Smuxi.Engine
             _Config.Save();
         }
 
+        public void SyncCache()
+        {
+            Trace.Call();
+
+            if (!IsCaching) {
+                return;
+            }
+
+            var start = DateTime.UtcNow;
+            var conf = _Config.GetAll();
+            var cache = new Hashtable(conf.Count);
+            foreach (var entry in conf) {
+                if (!entry.Key.StartsWith(_UserPrefix)) {
+                    // no need to cache values of other users
+                    continue;
+                }
+                // remove user prefix from key
+                var userKey = entry.Key.Substring(_UserPrefix.Length);
+                cache.Add(userKey, entry.Value);
+            }
+            var stop = DateTime.UtcNow;
+#if LOG4NET
+            _Logger.Debug(
+                String.Format(
+                    "SyncCache(): syncing config took: {0:0.00} ms",
+                    (stop - start).TotalMilliseconds
+                )
+            );
+#endif
+            _Cache = cache;
+        }
+
         void OnConfigChanged(object sender, ConfigChangedEventArgs e)
         {
             if (Changed == null) {
diff --git a/src/Engine/Engine.cs b/src/Engine/Engine.cs
index 152b13b..2fa1881 100644
--- a/src/Engine/Engine.cs
+++ b/src/Engine/Engine.cs
@@ -91,8 +91,20 @@ namespace Smuxi.Engine
             AssemblyProductAttribute pr = (AssemblyProductAttribute)asm.GetCustomAttributes(typeof(AssemblyProductAttribute), false)[0];
             _Version = asm_name.Version;
             _VersionNumber = asm_name.Version.ToString();
-            _VersionString = String.Format("{0} {1} - running on {2} {3}", pr.Product, _Version, Platform.OperatingSystem, Platform.Architecture);
-            
+
+            var distVersion = Defines.DistVersion;
+            if (!String.IsNullOrEmpty(distVersion)) {
+                distVersion = String.Format(" ({0})", distVersion);
+            }
+            _VersionString = String.Format(
+                "{0} {1}{2} - running on {3} {4}",
+                pr.Product,
+                _Version,
+                distVersion,
+                Platform.OperatingSystem,
+                Platform.Architecture
+            );
+
             _Config = new Config();
             _Config.Load();
             _Config.Save();
diff --git a/src/Engine/FrontendManager.cs b/src/Engine/FrontendManager.cs
index e530312..41ebd21 100644
--- a/src/Engine/FrontendManager.cs
+++ b/src/Engine/FrontendManager.cs
@@ -1,13 +1,7 @@
 /*
- * $Id$
- * $URL$
- * $Rev$
- * $Author$
- * $Date$
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2008 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -51,7 +45,9 @@ namespace Smuxi.Engine
         private bool             _IsFrontendSynced;
         private IList<ChatModel> _SyncedChats = new List<ChatModel>();
         private TaskQueue        f_TaskQueue;
-        
+
+        DateTime LastConfigChange;
+
         public int Version {
             get {
                 return 0;
@@ -113,10 +109,9 @@ namespace Smuxi.Engine
             f_TaskQueue = new TaskQueue("FrontendManager");
             f_TaskQueue.ExceptionEvent += OnTaskQueueExceptionEvent;
             f_TaskQueue.AbortedEvent   += OnTaskQueueAbortedEvent;
-            
+
             // register event for config invalidation
-            // BUG: when the frontend disconnects there are dangling methods registered!
-            //_Session.Config.Changed += new EventHandler(_OnConfigChanged);
+            _Session.Config.Changed += _OnConfigChanged;
         }
         
         ~FrontendManager()
@@ -140,6 +135,7 @@ namespace Smuxi.Engine
             
             if (disposing) {
                 f_TaskQueue.Dispose();
+                _Session.Config.Changed -= _OnConfigChanged;
             }
         }
         
@@ -182,7 +178,10 @@ namespace Smuxi.Engine
 
             _Session.CheckPresenceStatus();
         }
-        
+
+        /// <remarks>
+        /// This method is thread safe.
+        /// </remarks>
         public void AddSyncedChat(ChatModel chatModel)
         {
             Trace.Call(chatModel);
@@ -197,7 +196,11 @@ namespace Smuxi.Engine
                 return;
             }
 
-            _SyncedChats.Add(chatModel);
+            // this method must be thread-safe as the frontend might sync
+            // multiple chats at the same time
+            lock (_SyncedChats) {
+                _SyncedChats.Add(chatModel);
+            }
         }
         
         public void NextProtocolManager()
@@ -233,7 +236,7 @@ namespace Smuxi.Engine
         
         public void AddChat(ChatModel chat)
         {
-            if (!_SyncedChats.Contains(chat) && _IsFrontendSynced) {
+            if (!IsSynced(chat) && _IsFrontendSynced) {
                 _AddChat(chat);
             }
         }
@@ -265,7 +268,7 @@ namespace Smuxi.Engine
         
         public void DisableChat(ChatModel chat)
         {
-            if (_SyncedChats.Contains(chat)) {
+            lock (_SyncedChats) {
                 _SyncedChats.Remove(chat);
             }
             f_TaskQueue.Queue(delegate {
@@ -275,7 +278,7 @@ namespace Smuxi.Engine
         
         public void AddMessageToChat(ChatModel chat, MessageModel msg)
         {
-            if (!_SyncedChats.Contains(chat)) {
+            if (!IsSynced(chat)) {
 #if LOG4NET
                 // too much logging noise
                 //_Logger.Warn("AddMessageToChat(): chat: " + chat + " is not synced yet, ignoring call...");
@@ -302,7 +305,7 @@ namespace Smuxi.Engine
         
         public void RemoveChat(ChatModel chat)
         {
-            if (_SyncedChats.Contains(chat)) {
+            lock (_SyncedChats) {
                 _SyncedChats.Remove(chat);
             }
             f_TaskQueue.Queue(delegate {
@@ -312,7 +315,7 @@ namespace Smuxi.Engine
         
         public void SyncChat(ChatModel chat)
         {
-            if (!_SyncedChats.Contains(chat) && _IsFrontendSynced) {
+            if (!IsSynced(chat) && _IsFrontendSynced) {
                 _SyncChat(chat);
             }
         }
@@ -326,7 +329,7 @@ namespace Smuxi.Engine
         
         public void AddPersonToGroupChat(GroupChatModel groupChat, PersonModel person)
         {
-            if (!_SyncedChats.Contains(groupChat)) {
+            if (!IsSynced(groupChat)) {
                 return;
             }
             
@@ -342,7 +345,7 @@ namespace Smuxi.Engine
         
         public void UpdatePersonInGroupChat(GroupChatModel groupChat, PersonModel oldPerson, PersonModel newPerson)
         {
-            if (!_SyncedChats.Contains(groupChat)) {
+            if (!IsSynced(groupChat)) {
                 return;
             }
             
@@ -358,7 +361,7 @@ namespace Smuxi.Engine
     
         public void UpdateTopicInGroupChat(GroupChatModel groupChat, MessageModel topic)
         {
-            if (!_SyncedChats.Contains(groupChat)) {
+            if (!IsSynced(groupChat)) {
                 return;
             }
             
@@ -374,7 +377,7 @@ namespace Smuxi.Engine
     
         public void RemovePersonFromGroupChat(GroupChatModel groupChat, PersonModel person)
         {
-            if (!_SyncedChats.Contains(groupChat)) {
+            if (!IsSynced(groupChat)) {
                 return;
             }
             
@@ -405,21 +408,42 @@ namespace Smuxi.Engine
         private void _OnConfigChanged(object sender, EventArgs e)
         {
             Trace.Call(sender, e);
-            
-            // BUG: we should use some timeout here and only call the delegate
-            // when the timeout is reached, else we flood the frontend for each
-            // changed value in the config!
+
+            // only push config changes once per 30 seconds
+            if ((DateTime.UtcNow - LastConfigChange).TotalSeconds < 30) {
+                return;
+            }
+
             try {
+                // DISABLED: delegate is not reliable enough, this needs to be
+                // replaced with an IChatConfig API
+                /*
                 if (_ConfigChangedDelegate != null) {
                     _ConfigChangedDelegate();
                 }
+                */
             } catch (Exception ex) {
 #if LOG4NET
                 _Logger.Error(ex);
 #endif
             }
+            LastConfigChange = DateTime.UtcNow;
         }
-        
+
+        /// <remarks>
+        /// This method is thread safe.
+        /// </remarks>
+        bool IsSynced(ChatModel chatModel)
+        {
+            if (chatModel == null) {
+                throw new ArgumentNullException("chatModel");
+            }
+
+            lock (_SyncedChats) {
+                return _SyncedChats.Contains(chatModel);
+            }
+        }
+
         protected virtual void OnTaskQueueExceptionEvent(object sender, TaskQueueExceptionEventArgs e)
         {
             Trace.Call(sender, e);
diff --git a/src/Engine/Makefile.am b/src/Engine/Makefile.am
index 3174dfd..9d7cfa7 100644
--- a/src/Engine/Makefile.am
+++ b/src/Engine/Makefile.am
@@ -1,11 +1,11 @@
-
+TARGET_DIR = $(top_builddir)/bin/$(PROFILE)
 EXTRA_DIST =  
 
 # Warning: This is an automatically generated file, do not edit!
 
 if ENABLE_RELEASE
 ASSEMBLY_COMPILER_COMMAND = @MCS@
-ASSEMBLY_COMPILER_FLAGS =  -noconfig -codepage:utf8 -warn:4 -optimize+ "-define:CONFIG_NINI"
+ASSEMBLY_COMPILER_FLAGS =  -noconfig -codepage:utf8 -warn:4 -optimize+ "-define:CONFIG_NINI" -define:DB4O,DB4O_8_0
 
 ASSEMBLY = ../../bin/release/smuxi-engine.dll
 ASSEMBLY_MDB = 
@@ -21,7 +21,7 @@ endif
 
 if ENABLE_DEBUG
 ASSEMBLY_COMPILER_COMMAND = @MCS@
-ASSEMBLY_COMPILER_FLAGS =  -noconfig -codepage:utf8 -warn:4 -optimize- -debug -define:DEBUG "-define:DEBUG,TRACE,LOG4NET,CONFIG_NINI"
+ASSEMBLY_COMPILER_FLAGS =  -noconfig -codepage:utf8 -warn:4 -optimize- -debug -define:DEBUG "-define:DEBUG,TRACE,LOG4NET,CONFIG_NINI" -define:DB4O,DB4O_8_0
 
 ASSEMBLY = ../../bin/debug/smuxi-engine.dll
 ASSEMBLY_MDB = $(ASSEMBLY).mdb
@@ -58,8 +58,16 @@ FILES = \
 	Session.cs \
 	SessionManager.cs \
 	TextColor.cs \
+	TextColorContrast.cs \
+	TextColorTools.cs \
 	UICommand.cs \
 	UICommandContainer.cs \
+	MessageBuffers/Db4oMessageBuffer.cs \
+	MessageBuffers/IMessageBuffer.cs \
+	MessageBuffers/ListMessageBuffer.cs \
+	MessageBuffers/MessageBufferBase.cs \
+	MessageBuffers/MessageBufferPersistencyType.cs \
+	Messages/FeedMessageBuilder.cs \
 	Messages/MessageBuilder.cs \
 	Messages/MessageModel.cs \
 	Messages/MessageParser.cs \
@@ -83,7 +91,9 @@ FILES = \
 	Config/UserListController.cs \
 	Config/FilterListController.cs \
 	Config/FilterModel.cs \
+	Config/ProxySettings.cs \
 	Config/ProxyType.cs \
+	Config/EntrySettings.cs \
 	Protocols/ProtocolManagerBase.cs \
 	Protocols/ProtocolManagerFactory.cs \
 	Protocols/ProtocolManagerInfoModel.cs \
@@ -102,11 +112,14 @@ EXTRAS = \
 REFERENCES =  \
 	System.Runtime.Remoting \
 	System \
+	System.Core \
 	Mono.Posix \
 	$(NINI_LIBS) \
-	$(LOG4NET_LIBS)
+	$(LOG4NET_LIBS) \
+	$(DB4O_LIBS) \
+	$(DB4O_INCLUDED_LIBS)
 
-DLL_REFERENCES = 
+DLL_REFERENCES =
 
 CLEANFILES = $(PROGRAMFILES) $(LINUX_PKGCONFIG) 
 
@@ -125,6 +138,11 @@ PROGRAMFILES += $(NINI_DLL)
 $(eval $(call emit-deploy-target,NINI_DLL))
 endif
 
+if BUNDLE_DB4O
+DB4O_INCLUDED_LIBS := $(foreach file, $(DB4O_FILES), $(TARGET_DIR)/$(file))
+PROGRAMFILES += $(DB4O_INCLUDED_LIBS)
+endif
+
 $(build_xamlg_list): %.xaml.g.cs: %.xaml
 	xamlg '$<'
 
diff --git a/src/Engine/Makefile.in b/src/Engine/Makefile.in
index 4b6ca93..f8dc5d9 100644
--- a/src/Engine/Makefile.in
+++ b/src/Engine/Makefile.in
@@ -39,11 +39,15 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 	$(srcdir)/smuxi-engine.pc.in $(top_srcdir)/Makefile.include \
 	ChangeLog
 @BUNDLE_NINI_TRUE at am__append_1 = $(NINI_DLL)
+ at BUNDLE_DB4O_TRUE@am__append_2 = $(DB4O_INCLUDED_LIBS)
 subdir = src/Engine
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -84,6 +88,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -97,13 +102,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -144,13 +162,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -158,6 +178,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -168,13 +189,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -188,13 +218,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -202,7 +238,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -217,10 +255,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -251,6 +292,7 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 twitter_api_key = @twitter_api_key@
+TARGET_DIR = $(top_builddir)/bin/$(PROFILE)
 EXTRA_DIST = $(build_sources) $(build_resx_files) \
 	$(build_others_files) $(ASSEMBLY_WRAPPER_IN) $(EXTRAS) \
 	$(DATA_FILES) $(build_culture_res_files)
@@ -258,8 +300,8 @@ EXTRA_DIST = $(build_sources) $(build_resx_files) \
 
 # Warning: This is an automatically generated file, do not edit!
 @ENABLE_RELEASE_TRUE at ASSEMBLY_COMPILER_COMMAND = @MCS@
- at ENABLE_DEBUG_TRUE@ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize- -debug -define:DEBUG "-define:DEBUG,TRACE,LOG4NET,CONFIG_NINI"
- at ENABLE_RELEASE_TRUE@ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+ "-define:CONFIG_NINI"
+ at ENABLE_DEBUG_TRUE@ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize- -debug -define:DEBUG "-define:DEBUG,TRACE,LOG4NET,CONFIG_NINI" -define:DB4O,DB4O_8_0
+ at ENABLE_RELEASE_TRUE@ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+ "-define:CONFIG_NINI" -define:DB4O,DB4O_8_0
 @ENABLE_DEBUG_TRUE at ASSEMBLY = ../../bin/debug/smuxi-engine.dll
 @ENABLE_RELEASE_TRUE at ASSEMBLY = ../../bin/release/smuxi-engine.dll
 @ENABLE_DEBUG_TRUE at ASSEMBLY_MDB = $(ASSEMBLY).mdb
@@ -280,7 +322,7 @@ EXTRA_DIST = $(build_sources) $(build_resx_files) \
 @ENABLE_RELEASE_TRUE at SMUXI_COMMON_DLL_SOURCE = ../../bin/release/smuxi-common.dll
 AL = al2
 SATELLITE_ASSEMBLY_NAME = .resources.dll
-PROGRAMFILES = $(SMUXI_COMMON_DLL) $(am__append_1)
+PROGRAMFILES = $(SMUXI_COMMON_DLL) $(am__append_1) $(am__append_2)
 LINUX_PKGCONFIG = \
 	$(ENGINE_PC)  
 
@@ -296,8 +338,16 @@ FILES = \
 	Session.cs \
 	SessionManager.cs \
 	TextColor.cs \
+	TextColorContrast.cs \
+	TextColorTools.cs \
 	UICommand.cs \
 	UICommandContainer.cs \
+	MessageBuffers/Db4oMessageBuffer.cs \
+	MessageBuffers/IMessageBuffer.cs \
+	MessageBuffers/ListMessageBuffer.cs \
+	MessageBuffers/MessageBufferBase.cs \
+	MessageBuffers/MessageBufferPersistencyType.cs \
+	Messages/FeedMessageBuilder.cs \
 	Messages/MessageBuilder.cs \
 	Messages/MessageModel.cs \
 	Messages/MessageParser.cs \
@@ -321,7 +371,9 @@ FILES = \
 	Config/UserListController.cs \
 	Config/FilterListController.cs \
 	Config/FilterModel.cs \
+	Config/ProxySettings.cs \
 	Config/ProxyType.cs \
+	Config/EntrySettings.cs \
 	Protocols/ProtocolManagerBase.cs \
 	Protocols/ProtocolManagerFactory.cs \
 	Protocols/ProtocolManagerInfoModel.cs \
@@ -338,9 +390,12 @@ EXTRAS = \
 REFERENCES = \
 	System.Runtime.Remoting \
 	System \
+	System.Core \
 	Mono.Posix \
 	$(NINI_LIBS) \
-	$(LOG4NET_LIBS)
+	$(LOG4NET_LIBS) \
+	$(DB4O_LIBS) \
+	$(DB4O_INCLUDED_LIBS)
 
 DLL_REFERENCES = 
 CLEANFILES = $(PROGRAMFILES) $(LINUX_PKGCONFIG) $(ASSEMBLY) \
@@ -375,7 +430,7 @@ build_references_ref = $(foreach ref, $(REFERENCES), $(if $(filter \
 	-pkg:%, $(ref)), $(ref), $(if $(filter -r:%, $(ref)), $(ref), \
 	-r:$(ref)))) $(foreach ref, $(DLL_REFERENCES), -r:$(ref)) \
 	$(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
 programfilesdir = @libdir@/@PACKAGE@
@@ -398,6 +453,7 @@ ENGINE_PC = $(BUILD_DIR)/smuxi-engine.pc
 SMUXI_COMMON_DLL = $(BUILD_DIR)/smuxi-common.dll
 @BUNDLE_NINI_TRUE at NINI_DLL = $(BUILD_DIR)/Nini.dll
 @BUNDLE_NINI_TRUE at NINI_DLL_SOURCE = $(NINI_LIBS)
+ at BUNDLE_DB4O_TRUE@DB4O_INCLUDED_LIBS := $(foreach file, $(DB4O_FILES), $(TARGET_DIR)/$(file))
 all: all-am
 
 .SUFFIXES:
@@ -501,6 +557,12 @@ uninstall-pkglibSCRIPTS:
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(linuxdesktopapplicationsdir)" || $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)"
@@ -654,7 +716,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -708,7 +770,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-am
 
@@ -725,19 +787,21 @@ uninstall-am: uninstall-binSCRIPTS \
 
 .MAKE: install-am install-strip
 
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binSCRIPTS install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-linuxdesktopapplicationsDATA \
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binSCRIPTS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-man install-pdf \
 	install-pdf-am install-pkglibSCRIPTS install-programfilesDATA \
 	install-programfilesiconsDATA install-ps install-ps-am \
 	install-strip installcheck installcheck-am installdirs \
 	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
-	uninstall-binSCRIPTS uninstall-linuxdesktopapplicationsDATA \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am uninstall-binSCRIPTS \
+	uninstall-linuxdesktopapplicationsDATA \
 	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
 	uninstall-programfilesDATA uninstall-programfilesiconsDATA
 
diff --git a/src/Engine/MessageBuffers/Db4oMessageBuffer.cs b/src/Engine/MessageBuffers/Db4oMessageBuffer.cs
new file mode 100644
index 0000000..138621c
--- /dev/null
+++ b/src/Engine/MessageBuffers/Db4oMessageBuffer.cs
@@ -0,0 +1,694 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2011 Mirco Bauer <meebey at meebey.net>
+// 
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+// 
+// 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
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Config;
+using Db4objects.Db4o.Defragment;
+using Db4objects.Db4o.Diagnostic;
+using Smuxi.Common;
+
+namespace Smuxi.Engine
+{
+    public class Db4oMessageBuffer : MessageBufferBase
+    {
+#if LOG4NET
+        static readonly log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+#endif
+        const string     LibraryTextDomain = "smuxi-engine";
+        const int        DefaultFlushInterval = 16;
+        List<Int64>      f_Index;
+        int              FlushInterval { get; set; }
+        int              FlushCounter { get; set; }
+        IObjectContainer Database { get; set; }
+        string           DatabaseFile { get; set; }
+        bool             IsEmptyDatabase { get; set; }
+        string           SessionUsername { get; set; }
+        bool             AggressiveGC { get; set; }
+#if DB4O_8_0
+        IEmbeddedConfiguration DatabaseConfiguration { get; set; }
+#else
+        IConfiguration         DatabaseConfiguration { get; set; }
+#endif
+
+        private List<Int64> Index {
+            get {
+                InitIndex();
+                return f_Index;
+            }
+        }
+
+        public override MessageModel this[int index] {
+            get {
+                var dbId = Index[index];
+                return GetMessage(dbId);
+            }
+            set {
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int Count {
+            get {
+                return Index.Count;
+            }
+        }
+
+        private Db4oMessageBuffer()
+        {
+            FlushInterval = DefaultFlushInterval;
+        }
+
+        public Db4oMessageBuffer(string sessionUsername, string protocol,
+                                 string networkId, string chatId) : this()
+        {
+            if (sessionUsername == null) {
+                throw new ArgumentNullException("sessionUsername");
+            }
+            if (protocol == null) {
+                throw new ArgumentNullException("protocol");
+            }
+            if (networkId == null) {
+                throw new ArgumentNullException("networkId");
+            }
+            if (chatId == null) {
+                throw new ArgumentNullException("chatId");
+            }
+
+            SessionUsername = sessionUsername;
+            Protocol = protocol;
+            NetworkID = networkId;
+            ChatID = chatId;
+
+            AggressiveGC = true;
+            DatabaseFile = GetDatabaseFile();
+            InitDatabase();
+        }
+
+        public Db4oMessageBuffer(string dbPath) : this()
+        {
+            if (dbPath == null) {
+                throw new ArgumentNullException("dbPath");
+            }
+
+            DatabaseFile = dbPath;
+            InitDatabase();
+        }
+
+        ~Db4oMessageBuffer()
+        {
+            Dispose(false);
+        }
+
+        public override void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        protected void Dispose(bool disposing)
+        {
+            if (Database == null) {
+                return;
+            }
+
+            CloseDatabase();
+            Database = null;
+            ResetIndex();
+        }
+
+        public override void Add(MessageModel item)
+        {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+
+            // make sure the index is initialized at this point else we will
+            // load the 1st added item of db4o and end up with a duplicate here
+            InitIndex();
+
+            if (MaxCapacity > 0 && Index.Count >= MaxCapacity) {
+                RemoveAt(0);
+            }
+
+            // TODO: auto-flush every 60 seconds
+            var dbMsg = new MessageModel(item);
+            Database.Store(dbMsg);
+            Database.Deactivate(dbMsg, 5);
+            var dbId = Database.Ext().GetID(dbMsg);
+            Index.Add(dbId);
+            FlushCounter++;
+            if (FlushCounter >= FlushInterval) {
+                Flush();
+            }
+        }
+
+        public override void Clear()
+        {
+            foreach (var dbId in Index) {
+                var dbMsg = Database.Ext().GetByID(dbId);
+                Database.Delete(dbMsg);
+            }
+            ResetIndex();
+        }
+
+        public override bool Contains(MessageModel item)
+        {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+
+            // TODO: benchmark me!
+            //return Database.Query<MessageModel>().Contains(item);
+            return IndexOf(item) != -1;
+        }
+
+        public override void CopyTo(MessageModel[] array, int arrayIndex)
+        {
+            if (array == null) {
+                throw new ArgumentNullException("array");
+            }
+
+            int i = arrayIndex;
+            foreach (var msg in this) {
+                array[i++] = msg;
+            }
+        }
+
+        public override IEnumerator<MessageModel> GetEnumerator()
+        {
+            foreach (var dbId in Index) {
+                yield return GetMessage(dbId);
+            }
+        }
+
+        public override int IndexOf(MessageModel item)
+        {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+
+            var res = Database.QueryByExample(item);
+            // return -1 if not found
+            if (res.Count == 0) {
+                return -1;
+            }
+            var dbMsg = (MessageModel) res[0];
+            var dbId = Database.Ext().GetID(dbMsg);
+            return Index.IndexOf(dbId);
+        }
+
+        public override void Insert(int index, MessageModel item)
+        {
+            throw new NotSupportedException();
+        }
+
+        public override void RemoveAt(int index)
+        {
+            if (index < 0 || index >= Index.Count) {
+                throw new ArgumentOutOfRangeException("index");
+            }
+
+            var dbId = Index[index];
+            Index.RemoveAt(index);
+
+            var dbMsg = Database.Ext().GetByID(dbId);
+            if (dbMsg == null) {
+#if LOG4NET
+                Logger.Error(
+                    String.Format("RemoveAt(): Database.Ext().GetByID({0}) " +
+                                  "with index {1} returned null!", dbId, index)
+                );
+#endif
+                return;
+            }
+            Database.Delete(dbMsg);
+            // TODO: auto-commit after some timeout
+        }
+
+        public override bool Remove(MessageModel item)
+        {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+
+            if (!Contains(item)) {
+                return false;
+            }
+            var dbId = Database.Ext().GetID(item);
+            Index.Remove(dbId);
+            Database.Delete(item);
+            return true;
+        }
+
+        public override IList<MessageModel> GetRange(int offset, int limit)
+        {
+            if (offset < 0) {
+                throw new ArgumentException(
+                    "offset must be greater than or equal to 0.", "offset"
+                );
+            }
+            // Neither Count nor the Indexer have to be synchronized as the
+            // messages might move from the buffer to the db4o index but that
+            // doesn't change the Count neither affects the combined indexer
+            // BUG?: but what about MaxCapacity which will remove oldest items
+            // when new messages are added, our loop here would become
+            // inconsistent!
+            // Session.AddMessageToChat() and ChatModel.get_Messages lock()s
+            // us though thus newly added messages are waiting for us to finish
+            var bufferCount = Count;
+            var rangeCount = Math.Min(bufferCount, limit);
+            var range = new List<MessageModel>(rangeCount);
+            for (int i = offset; i < offset + limit && i < bufferCount; i++) {
+                range.Add(this[i]);
+            }
+            return range;
+        }
+
+        public static int OptimizeAllBuffers(Db4oMessageBufferOptimizationTypes opts)
+        {
+            DateTime start = DateTime.UtcNow, stop;
+            var dbPath = Platform.GetBuffersBasePath();
+            var dbFiles = Directory.GetFiles(dbPath, "*.db4o",
+                                             SearchOption.AllDirectories);
+            foreach (var dbFile in dbFiles) {
+#if LOG4NET
+                Logger.Info(String.Format(_("Optimizing: {0}..."), dbFile));
+#endif
+                try {
+                    using (var buffer = new Db4oMessageBuffer(dbFile)) {
+                        buffer.AggressiveGC = false;
+                        if ((opts & Db4oMessageBufferOptimizationTypes.Defrag) != 0) {
+                            buffer.CloseDatabase();
+                            buffer.DefragDatabase();
+                            buffer.InitDatabase();
+                        }
+                        if ((opts & Db4oMessageBufferOptimizationTypes.Index) != 0) {
+                            buffer.RebuildIndex();
+                        }
+                    }
+                } catch (Exception ex) {
+#if LOG4NET
+                    Logger.Debug("OptimizeAllBuffers(): Failed to optimize: " +
+                                 dbFile + " Exception: ", ex);
+                    Logger.InfoFormat(_("Failed to optimize: {0}. Reason: {1}"),
+                                      dbFile, ex.Message);
+#endif
+                }
+            }
+            stop = DateTime.UtcNow;
+#if LOG4NET
+            Logger.Debug(
+                String.Format(
+                    "OptimizeAllBuffers(): optimizing buffers took: {0:0} second(s)",
+                    (stop - start).TotalSeconds
+                )
+            );
+#endif
+            return dbFiles.Length;
+        }
+
+        private void InitDatabase()
+        {
+            ConfigureDatabase();
+            try {
+                OpenDatabase();
+            } catch (Exception ex) {
+#if LOG4NET
+                Logger.Error("InitDatabase(): failed to open message " +
+                             "database: " + DatabaseFile, ex);
+#endif
+                FixDatabase(ex);
+                // WORXNOWPLX
+                OpenDatabase();
+
+                var builder = new MessageBuilder();
+                builder.AppendEventPrefix();
+                builder.AppendErrorText(
+                    _("Your chat history is no longer available because of " +
+                      "an error but will be preserved from now on.")
+                );
+                Add(builder.ToMessage());
+            }
+        }
+
+        void ConfigureDatabase()
+        {
+#if DB4O_8_0
+            DatabaseConfiguration = Db4oEmbedded.NewConfiguration();
+            DatabaseConfiguration.Common.AllowVersionUpdates = true;
+            DatabaseConfiguration.Common.ActivationDepth = 0;
+            //DatabaseConfiguration.Common.Queries.EvaluationMode(QueryEvaluationMode.Lazy);
+            DatabaseConfiguration.Common.WeakReferenceCollectionInterval = 60 * 1000;
+            //DatabaseConfiguration.Common.Diagnostic.AddListener(new DiagnosticToConsole());
+            var msgConf = DatabaseConfiguration.Common.ObjectClass(typeof(MessageModel));
+            msgConf.CascadeOnActivate(true);
+            msgConf.CascadeOnDelete(true);
+            msgConf.Indexed(true);
+            msgConf.ObjectField("f_TimeStamp").Indexed(true);
+#else
+            DatabaseConfiguration = Db4oFactory.Configure();
+            DatabaseConfiguration.AllowVersionUpdates(true);
+            DatabaseConfiguration.ObjectClass(typeof(MessageModel)).
+                                  ObjectField("f_TimeStamp").Indexed(true);
+#endif
+        }
+
+        string GetDatabaseFile()
+        {
+            var dbPath = Platform.GetBuffersPath(SessionUsername);
+            var protocol = Protocol.ToLower();
+            var network = NetworkID.ToLower();
+            dbPath = Path.Combine(dbPath, protocol);
+            if (network != protocol) {
+                dbPath = Path.Combine(dbPath, network);
+            }
+            dbPath = IOSecurity.GetFilteredPath(dbPath);
+            if (!Directory.Exists(dbPath)) {
+                Directory.CreateDirectory(dbPath);
+            }
+
+            var chatId = IOSecurity.GetFilteredFileName(ChatID.ToLower());
+            dbPath = Path.Combine(dbPath, String.Format("{0}.db4o", chatId));
+            return dbPath;
+        }
+
+        void OpenDatabase()
+        {
+            IsEmptyDatabase = !File.Exists(DatabaseFile);
+#if DB4O_8_0
+            Database = Db4oEmbedded.OpenFile(DatabaseConfiguration,
+                                             DatabaseFile);
+#else
+            Database = Db4oFactory.OpenFile(DatabaseConfiguration,
+                                            DatabaseFile);
+#endif
+        }
+
+        void CloseDatabase()
+        {
+            if (Database.Ext().IsClosed()) {
+                return;
+            }
+
+            Flush();
+            FlushIndex();
+
+            Database.Close();
+            Database.Dispose();
+        }
+
+        void FixDatabase(Exception ex)
+        {
+            try {
+                CloseDatabase();
+            } catch {
+            }
+
+            // do some sanity checks before we assume the database is
+            // really broken
+            if (!File.Exists(DatabaseFile)) {
+                throw new FileNotFoundException(DatabaseFile);
+            }
+            try {
+                using (File.OpenWrite(DatabaseFile));
+            } catch {
+                throw;
+            }
+
+            var timestamp = DateTime.Now.ToString("s");
+            timestamp = timestamp.Replace("T", "_").Replace(":", "_");
+            var brokenDbFile = String.Format("{0}_{1}_broken",
+                                           DatabaseFile, timestamp);
+            var brokenLogFile = String.Format("{0}.log", brokenDbFile);
+            File.WriteAllText(brokenLogFile, ex.ToString());
+#if LOG4NET
+            Logger.DebugFormat("FixDatabase(): moving broken database " +
+                               "from: {0} to: {1}", DatabaseFile,
+                               brokenDbFile);
+#endif
+            File.Move(DatabaseFile, brokenDbFile);
+
+            ConfigureDatabase();
+        }
+
+        void DefragDatabase()
+        {
+            if (!File.Exists(DatabaseFile)) {
+                return;
+            }
+
+            DateTime start = DateTime.UtcNow, stop;
+            var backupFile = String.Format(
+                "{0}.bak_{1}.{2}",
+                DatabaseFile,
+                Db4oVersion.Major,
+                Db4oVersion.Minor
+            );
+            var defragConfig = new DefragmentConfig(
+                DatabaseFile,
+                backupFile
+            );
+            defragConfig.ForceBackupDelete(true);
+            Defragment.Defrag(defragConfig);
+            stop = DateTime.UtcNow;
+#if LOG4NET
+            Logger.Debug(
+                String.Format(
+                    "DefragDatabase(): defrag took: {0:0.0} ms",
+                    (stop - start).TotalMilliseconds
+                )
+            );
+#endif
+        }
+
+        MessageModel GetMessage(MessageModel dbMsg)
+        {
+            Database.Activate(dbMsg, 10);
+            var msg = new MessageModel(dbMsg);
+            Database.Deactivate(dbMsg, 10);
+            return msg;
+        }
+
+        MessageModel GetMessage(Int64 dbId)
+        {
+            var dbMsg = (MessageModel) Database.Ext().GetByID(dbId);
+            return GetMessage(dbMsg);
+        }
+
+        void InitIndex()
+        {
+            if (f_Index != null) {
+                return;
+            }
+
+            if (IsEmptyDatabase) {
+#if LOG4NET
+                Logger.Debug("InitIndex(): Creating initial index...");
+#endif
+                f_Index = new List<Int64>(MaxCapacity);
+                return;
+            }
+
+            var index = FetchIndex();
+            if (index == null) {
+#if LOG4NET
+                Logger.Info("InitIndex(): No index found, building...");
+#endif
+                RebuildIndex();
+                return;
+            }
+
+            f_Index = index;
+        }
+
+        List<Int64> FetchIndex()
+        {
+            DateTime start = DateTime.UtcNow, stop;
+            var indexes = Database.Query<List<Int64>>();
+            if (indexes.Count == 0) {
+                return null;
+            }
+            if (indexes.Count > 1) {
+#if LOG4NET
+                Logger.Warn(
+                    "FetchIndex(): found multiple indexes, dropping them..."
+                );
+#endif
+                // we can't deal with multiple indexes, so drop them all
+                foreach (var idx in indexes) {
+                    Database.Delete(idx);
+                }
+                Database.Commit();
+                return null;
+            }
+
+            var index = indexes[0];
+            Database.Activate(index, 10);
+            var msgCount = Database.Query<MessageModel>().Count;
+            if (index.Count != msgCount) {
+#if LOG4NET
+                Logger.Warn(
+                    String.Format(
+                        "FetchIndex(): index out of sync! index count: {0} " +
+                        "vs message count: {1}",
+                        index.Count, msgCount
+                    )
+                );
+#endif
+                Database.Delete(index);
+                return null;
+            }
+            stop = DateTime.UtcNow;
+#if LOG4NET
+            Logger.Debug(
+                String.Format(
+                    "FetchIndex(): query, activation and validation took: " +
+                    "{0:0.00} ms, items: {1}",
+                    (stop - start).TotalMilliseconds, index.Count
+                )
+            );
+#endif
+            return index;
+        }
+
+        List<Int64> BuildIndex()
+        {
+            DateTime start = DateTime.UtcNow, stop;
+            var query = Database.Query();
+            query.Constrain(typeof(MessageModel));
+            query.Descend("f_TimeStamp").OrderAscending();
+            var dbIndex = query.Execute();
+            stop = DateTime.UtcNow;
+#if LOG4NET
+            Logger.Debug(
+                String.Format(
+                    "BuildIndex(): query took: {0:0.00} ms, items: {1}",
+                    (stop - start).TotalMilliseconds, dbIndex.Count
+                )
+            );
+#endif
+            start = DateTime.UtcNow;
+            var indexCapacity = Math.Max(dbIndex.Count, MaxCapacity);
+            var index = new List<Int64>(indexCapacity);
+            int purgeCounter = 0;
+            int purgeInterval = 1000;
+            foreach (var dbMsg in dbIndex) {
+                var dbId = Database.Ext().GetID(dbMsg);
+                index.Add(dbId);
+                if (purgeCounter++ >= purgeInterval) {
+                    purgeCounter = 0;
+                    if (AggressiveGC) {
+                        Database.Ext().Purge();
+                    }
+                }
+            }
+            Database.Ext().Purge();
+            stop = DateTime.UtcNow;
+#if LOG4NET
+            Logger.Debug(
+                String.Format(
+                    "BuildIndex(): building index took: {0:0.00} ms",
+                    (stop - start).TotalMilliseconds
+                )
+            );
+#endif
+            return index;
+        }
+
+        void RebuildIndex()
+        {
+            var indexes = Database.Query<List<Int64>>();
+            if (indexes.Count > 0) {
+                // we can't deal with multiple indexes, so drop them all
+                foreach (var idx in indexes) {
+                    Database.Delete(idx);
+                }
+                Database.Commit();
+            }
+
+            f_Index = BuildIndex();
+            FlushIndex();
+        }
+
+        void ResetIndex()
+        {
+            f_Index = null;
+        }
+
+        void FlushIndex()
+        {
+            if (f_Index == null || f_Index.Count == 0) {
+                // don't waste our time
+                return;
+            }
+
+            DateTime start = DateTime.UtcNow, stop;
+            Database.Store(f_Index);
+            Database.Commit();
+            stop = DateTime.UtcNow;
+#if LOG4NET
+            Logger.Debug(
+                String.Format(
+                    "FlushIndex(): flushing index with {0} items took: {1} ms",
+                    f_Index.Count, (stop - start).TotalMilliseconds
+                )
+            );
+#endif
+        }
+
+        void Flush()
+        {
+            var counter = FlushCounter;
+            if (counter == 0) {
+                // nothing to flush
+                return;
+            }
+
+            DateTime start = DateTime.UtcNow, stop;
+            FlushCounter = 0;
+            Database.Commit();
+            stop = DateTime.UtcNow;
+#if LOG4NET
+            Logger.Debug(
+                String.Format(
+                    "Flush(): flushing {0} items took: {1} ms",
+                    counter, (stop - start).TotalMilliseconds
+                )
+            );
+#endif
+        }
+
+        static string _(string msg)
+        {
+            return LibraryCatalog.GetString(msg, LibraryTextDomain);
+        }
+    }
+
+    [Flags]
+    public enum Db4oMessageBufferOptimizationTypes : ushort {
+        None   = ushort.MinValue,
+        Defrag = 0x1,
+        Index  = 0x2,
+        All    = ushort.MaxValue
+    }
+}
diff --git a/src/Engine/MessageBuffers/IMessageBuffer.cs b/src/Engine/MessageBuffers/IMessageBuffer.cs
new file mode 100644
index 0000000..65d8961
--- /dev/null
+++ b/src/Engine/MessageBuffers/IMessageBuffer.cs
@@ -0,0 +1,31 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2010-2011 Mirco Bauer <meebey at meebey.net>
+//
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+//
+// 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
+
+using System;
+using System.Collections.Generic;
+
+namespace Smuxi.Engine
+{
+    public interface IMessageBuffer : IList<MessageModel>, IDisposable
+    {
+        IList<MessageModel> GetRange(int offset, int limit);
+        int                 MaxCapacity { get; set; }
+    }
+}
diff --git a/src/Engine/MessageBuffers/ListMessageBuffer.cs b/src/Engine/MessageBuffers/ListMessageBuffer.cs
new file mode 100644
index 0000000..03a1206
--- /dev/null
+++ b/src/Engine/MessageBuffers/ListMessageBuffer.cs
@@ -0,0 +1,66 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2010-2011 Mirco Bauer <meebey at meebey.net>
+//
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+//
+// 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
+
+using System;
+using System.Collections.Generic;
+
+namespace Smuxi.Engine
+{
+    public class ListMessageBuffer : List<MessageModel>, IMessageBuffer
+    {
+        int f_MaxCapacity;
+
+        public int MaxCapacity {
+            get {
+                return f_MaxCapacity;
+            }
+            set {
+                f_MaxCapacity = value;
+                Capacity = f_MaxCapacity;
+            }
+        }
+
+        public ListMessageBuffer()
+        {
+        }
+
+        public new void Add(MessageModel item)
+        {
+            if (MaxCapacity > 0 && Count >= MaxCapacity) {
+                RemoveAt(0);
+            }
+            base.Add(item);
+        }
+
+        IList<MessageModel> IMessageBuffer.GetRange(int offset, int limit)
+        {
+            // clamp limit to count
+            if (offset + limit > Count) {
+                limit = Count - offset;
+            }
+            return base.GetRange(offset, limit);
+        }
+
+        public void Dispose()
+        {
+            // NOOP
+        }
+    }
+}
diff --git a/src/Engine/MessageBuffers/MessageBufferBase.cs b/src/Engine/MessageBuffers/MessageBufferBase.cs
new file mode 100644
index 0000000..4ca9793
--- /dev/null
+++ b/src/Engine/MessageBuffers/MessageBufferBase.cs
@@ -0,0 +1,65 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2011 Mirco Bauer <meebey at meebey.net>
+//
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+//
+// 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
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using Smuxi.Common;
+
+namespace Smuxi.Engine
+{
+    public abstract class MessageBufferBase : IMessageBuffer
+    {
+        protected string Protocol { get; set; }
+        protected string NetworkID { get; set; }
+        protected string ChatID { get; set; }
+        public    int    MaxCapacity { get; set; }
+
+        public bool IsReadOnly {
+            get {
+                return false;
+            }
+        }
+
+        protected MessageBufferBase()
+        {
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return GetEnumerator();
+        }
+
+        public abstract int Count { get; }
+        public abstract MessageModel this[int index] { get; set; }
+
+        public abstract void Add(MessageModel item);
+        public abstract void Clear();
+        public abstract bool Contains(MessageModel item);
+        public abstract void CopyTo(MessageModel[] array, int arrayIndex);
+        public abstract bool Remove(MessageModel item);
+        public abstract IEnumerator<MessageModel> GetEnumerator();
+        public abstract int IndexOf(MessageModel item);
+        public abstract void Insert(int index, MessageModel item);
+        public abstract void RemoveAt(int index);
+        public abstract IList<MessageModel> GetRange(int offset, int limit);
+        public abstract void Dispose();
+    }
+}
diff --git a/src/Engine/MessageBuffers/MessageBufferPersistencyType.cs b/src/Engine/MessageBuffers/MessageBufferPersistencyType.cs
new file mode 100644
index 0000000..d2aacb7
--- /dev/null
+++ b/src/Engine/MessageBuffers/MessageBufferPersistencyType.cs
@@ -0,0 +1,30 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2011 Mirco Bauer <meebey at meebey.net>
+//
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+//
+// 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
+
+using System;
+
+namespace Smuxi.Engine
+{
+    public enum MessageBufferPersistencyType
+    {
+        Volatile,
+        Persistent
+    }
+}
diff --git a/src/Engine/Messages/FeedMessageBuilder.cs b/src/Engine/Messages/FeedMessageBuilder.cs
new file mode 100644
index 0000000..8183eac
--- /dev/null
+++ b/src/Engine/Messages/FeedMessageBuilder.cs
@@ -0,0 +1,72 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2011 Mirco Bauer <meebey at meebey.net>
+// 
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+// 
+// 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
+
+using System;
+using System.Text;
+using System.Text.RegularExpressions;
+using Smuxi.Common;
+
+namespace Smuxi.Engine
+{
+    public class FeedMessageBuilder : MessageBuilder
+    {
+        public FeedMessageBuilder() : base()
+        {
+        }
+
+        public MessageBuilder Append(AtomEntry entry)
+        {
+            AppendEventPrefix();
+            AppendUrl(entry.Link[0].Url, entry.Title.Text);
+            AppendText(" ({0})\n", entry.Published.ToShortDateString());
+            foreach (var content in entry.Content) {
+                // TODO: convert HTML: <h*> to AppendHeader, and more
+                // HACK: align with action prefix
+                AppendText("    ");
+                AppendMessage(HtmlToText(content.Text));
+            }
+            return this;
+        }
+
+        string HtmlToText(string html)
+        {
+            if (html.Contains("\n")) {
+                var normalized = new StringBuilder(html.Length);
+                html = html.Replace("\r\n", "\n");
+                foreach (var htmlPart in html.Split('\n')) {
+                    var trimmed = htmlPart.TrimEnd(' ');
+                    if (trimmed.Length == 0) {
+                        // skip empty lines
+                        continue;
+                    }
+                    normalized.AppendFormat("{0} ", trimmed);
+                }
+                // remove trailing space
+                normalized.Length--;
+                html = normalized.ToString();
+            }
+            // strip all HTML tags
+            var text = Regex.Replace(html, "<[^>]+>", String.Empty);
+            // strip leading and trailing whitespace
+            text = text.Trim();
+            return text;
+        }
+    }
+}
diff --git a/src/Engine/Messages/MessageBuilder.cs b/src/Engine/Messages/MessageBuilder.cs
index fca22ee..9498f31 100644
--- a/src/Engine/Messages/MessageBuilder.cs
+++ b/src/Engine/Messages/MessageBuilder.cs
@@ -48,6 +48,12 @@ namespace Smuxi.Engine
             }
         }
 
+        public bool IsEmpty {
+            get {
+                return Message.IsEmpty;
+            }
+        }
+
         public MessageBuilder()
         {
             Message = new MessageModel();
@@ -161,14 +167,14 @@ namespace Smuxi.Engine
             return AppendText(CreateEventPrefix());
         }
 
-        public virtual TextMessagePartModel CreateAction()
+        public virtual TextMessagePartModel CreateActionPrefix()
         {
             return CreateText(" * ");
         }
 
-        public virtual MessageBuilder AppendAction()
+        public virtual MessageBuilder AppendActionPrefix()
         {
-            return AppendText(CreateAction());
+            return AppendText(CreateActionPrefix());
         }
 
         public virtual UrlMessagePartModel CreateUrl(string url, string text)
@@ -195,6 +201,33 @@ namespace Smuxi.Engine
             return AppendUrl(url, null);
         }
 
+        public virtual IList<TextMessagePartModel> CreateHeader(string text,
+                                                                params object[] args)
+        {
+            if (text == null) {
+                throw new ArgumentNullException("text");
+            }
+
+            var prefix = CreateText("[");
+            var suffix = CreateText("]");
+            var headerText = CreateText(text, args);
+            headerText.Bold = true;
+
+            var header = new List<TextMessagePartModel>(3);
+            header.Add(prefix);
+            header.Add(headerText);
+            header.Add(suffix);
+            return header;
+        }
+
+        public virtual MessageBuilder AppendHeader(string text,
+                                                   params object[] args)
+        {
+            text = text ?? String.Empty;
+
+            return AppendText(CreateHeader(text, args));
+        }
+
         public virtual MessageBuilder AppendMessage(string msg)
         {
             return AppendText(msg);
@@ -208,6 +241,24 @@ namespace Smuxi.Engine
             return AppendMessage(msg);
         }
 
+        public virtual MessageBuilder AppendWarningText(string errorText,
+                                                        params string[] args)
+        {
+            var text = CreateText(errorText, args);
+            text.Bold = true;
+            return AppendText(text);
+        }
+
+        public virtual MessageBuilder AppendErrorText(string errorText,
+                                                      params string[] args)
+        {
+            var text = CreateText(errorText, args);
+            text.ForegroundColor = new TextColor(255, 0, 0);
+            text.Bold = true;
+            text.IsHighlight = true;
+            return AppendText(text);
+        }
+
         public virtual TextMessagePartModel CreateIdendityName(ContactModel identity)
         {
             if (identity == null) {
diff --git a/src/Engine/Messages/MessageModel.cs b/src/Engine/Messages/MessageModel.cs
index c4353b5..f2ba948 100644
--- a/src/Engine/Messages/MessageModel.cs
+++ b/src/Engine/Messages/MessageModel.cs
@@ -35,7 +35,8 @@ namespace Smuxi.Engine
         private DateTime                f_TimeStamp;
         private IList<MessagePartModel> f_MessageParts;
         private MessageType             f_MessageType;
-        public  bool                    IsCompactable { get; set; }
+        [NonSerialized]
+        private bool                    f_IsCompactable;
 
         public DateTime TimeStamp {
             get {
@@ -51,6 +52,12 @@ namespace Smuxi.Engine
                 return f_MessageParts;
             }
         }
+
+        public bool IsEmpty {
+            get {
+                return f_MessageParts.Count == 0;
+            }
+        }
         
         public MessageType MessageType {
             get {
@@ -61,6 +68,15 @@ namespace Smuxi.Engine
             }
         }
         
+        public bool IsCompactable {
+            get {
+                return f_IsCompactable;
+            }
+            set {
+                f_IsCompactable = value;
+            }
+        }
+
         public MessageModel()
         {
             f_TimeStamp    = DateTime.UtcNow;
@@ -78,6 +94,19 @@ namespace Smuxi.Engine
         {
         }
         
+        public MessageModel(MessageModel msg) : this()
+        {
+            if (msg == null) {
+                throw new ArgumentNullException("msg");
+            }
+
+            var writer = SerializationWriter.GetWriter();
+            msg.GetObjectData(writer);
+            var data = writer.GetData();
+            var reader = SerializationReader.GetReader(data);
+            SetObjectData(reader);
+        }
+
         protected MessageModel(SerializationInfo info, StreamingContext ctx)
         {
             SerializationReader sr = SerializationReader.GetReader(info);
@@ -122,6 +151,11 @@ namespace Smuxi.Engine
             return sb.ToString();
         }
 
+        public override int GetHashCode()
+        {
+            return f_TimeStamp.GetHashCode();
+        }
+
         public override bool Equals(object obj)
         {
             if (!(obj is MessageModel)) {
diff --git a/src/Engine/Messages/MessageParser.cs b/src/Engine/Messages/MessageParser.cs
index 9e47f2a..ec7f09a 100644
--- a/src/Engine/Messages/MessageParser.cs
+++ b/src/Engine/Messages/MessageParser.cs
@@ -26,21 +26,36 @@ namespace Smuxi.Engine
 {
     public static class MessageParser
     {
-        public static void ParseUrls(MessageModel msg)
+        static Regex UrlRegex { get; set; }
+        static Regex SimleyRegex { get; set; }
+
+        static MessageParser()
         {
-            string urlRegex;
             //urlRegex = "((([a-zA-Z][0-9a-zA-Z+\\-\\.]*:)?/{0,2}[0-9a-zA-Z;/?:@&=+$\\.\\-_!~*'()%]+)?(#[0-9a-zA-Z;/?:@&=+$\\.\\-_!~*'()%]+)?)");
             // It was constructed according to the BNF grammar given in RFC 2396 (http://www.ietf.org/rfc/rfc2396.txt).
-            
             /*
-            urlRegex = @"^(?<s1>(?<s0>[^:/\?#]+):)?(?<a1>" + 
-                                  @"//(?<a0>[^/\?#]*))?(?<p0>[^\?#]*)" + 
-                                  @"(?<q1>\?(?<q0>[^#]*))?" + 
+            urlRegex = @"^(?<s1>(?<s0>[^:/\?#]+):)?(?<a1>" +
+                                  @"//(?<a0>[^/\?#]*))?(?<p0>[^\?#]*)" +
+                                  @"(?<q1>\?(?<q0>[^#]*))?" +
                                   @"(?<f1>#(?<f0>.*))?");
-            */ 
+            */
+            UrlRegex = new Regex(
+                @"(^| )(((https?|ftp):\/\/)|www\.)" +
+                @"(" +
+                    @"([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)|" +
+                    @"localhost|" +
+                    @"([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\." +
+                        @"(com|net|org|info|biz|gov|name|edu|[a-zA-Z][a-zA-Z])" +
+                @")" +
+                @"(:[0-9]+)?((\/|\?)[^ ""]*[^ ,;\.:"">)])?",
+                RegexOptions.IgnoreCase
+            );
+
+            SimleyRegex = new Regex(@":-?(\(|\))");
+        }
 
-            urlRegex = @"(^| )(((https?|ftp):\/\/)|www\.)(([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|net|org|info|biz|gov|name|edu|[a-zA-Z][a-zA-Z]))(:[0-9]+)?((\/|\?)[^ ""]*[^ ,;\.:"">)])?";
-            Regex reg = new Regex(urlRegex, RegexOptions.IgnoreCase);
+        public static void ParseUrls(MessageModel msg)
+        {
             // clone MessageParts
             IList<MessagePartModel> parts = new List<MessagePartModel>(msg.MessageParts);
             foreach (MessagePartModel part in parts) {
@@ -53,7 +68,7 @@ namespace Smuxi.Engine
                 }
                 
                 TextMessagePartModel textPart = (TextMessagePartModel) part;
-                Match urlMatch = reg.Match(textPart.Text);
+                Match urlMatch = UrlRegex.Match(textPart.Text);
                 // OPT: fast regex scan
                 if (!urlMatch.Success) {
                     // no URLs in this MessagePart, nothing to do
@@ -68,7 +83,7 @@ namespace Smuxi.Engine
                 string[] textPartParts = textPart.Text.Split(new char[] {' '});
                 for (int i = 0; i < textPartParts.Length; i++) {
                     string textPartPart = textPartParts[i];
-                    urlMatch = reg.Match(textPartPart);
+                    urlMatch = UrlRegex.Match(textPartPart);
                     if (urlMatch.Success) {
                         UrlMessagePartModel urlPart = new UrlMessagePartModel(textPartPart);
                         //urlPart.ForegroundColor = new TextColor();
@@ -92,9 +107,6 @@ namespace Smuxi.Engine
 
         public static void ParseSmileys(MessageModel msg)
         {
-            string simleyRegex;
-            simleyRegex = @":-?(\(|\))";
-            Regex reg = new Regex(simleyRegex);
             // clone MessageParts
             IList<MessagePartModel> parts = new List<MessagePartModel>(msg.MessageParts);
             foreach (MessagePartModel part in parts) {
@@ -103,7 +115,7 @@ namespace Smuxi.Engine
                 }
                 
                 TextMessagePartModel textPart = (TextMessagePartModel) part;
-                Match simleyMatch = reg.Match(textPart.Text);
+                Match simleyMatch = SimleyRegex.Match(textPart.Text);
                 // OPT: fast regex scan
                 if (!simleyMatch.Success) {
                     // no smileys in this MessagePart, nothing to do
@@ -118,7 +130,7 @@ namespace Smuxi.Engine
                 string[] textPartParts = textPart.Text.Split(new char[] {' '});
                 for (int i = 0; i < textPartParts.Length; i++) {
                     string textPartPart = textPartParts[i];
-                    simleyMatch = reg.Match(textPartPart);
+                    simleyMatch = SimleyRegex.Match(textPartPart);
                     if (simleyMatch.Success) {
                         string filename = null;
                         if (textPartPart == ":-)") {
diff --git a/src/Engine/Messages/MessagePartModel.cs b/src/Engine/Messages/MessagePartModel.cs
index b8afa07..ae74432 100644
--- a/src/Engine/Messages/MessagePartModel.cs
+++ b/src/Engine/Messages/MessagePartModel.cs
@@ -78,6 +78,11 @@ namespace Smuxi.Engine
             sw.AddToInfo(info);
         }
 
+        public override int GetHashCode()
+        {
+            return f_IsHighlight.GetHashCode();
+        }
+
         public override bool Equals(object obj)
         {
             if (!(obj is MessagePartModel)) {
diff --git a/src/Engine/Messages/TextMessagePartModel.cs b/src/Engine/Messages/TextMessagePartModel.cs
index b5ce59a..bcb2945 100644
--- a/src/Engine/Messages/TextMessagePartModel.cs
+++ b/src/Engine/Messages/TextMessagePartModel.cs
@@ -177,6 +177,20 @@ namespace Smuxi.Engine
             return Text;
         }
 
+        public override int GetHashCode()
+        {
+            int hash = base.GetHashCode();
+            hash ^= ForegroundColor.GetHashCode();
+            hash ^= BackgroundColor.GetHashCode();
+            hash ^= Underline.GetHashCode();
+            hash ^= Bold.GetHashCode();
+            hash ^= Italic.GetHashCode();
+            if (Text != null) {
+                hash ^= Text.GetHashCode();
+            }
+            return hash;
+        }
+
         public override bool Equals(object obj)
         {
             if (!(obj is TextMessagePartModel)) {
diff --git a/src/Engine/Messages/UrlMessagePartModel.cs b/src/Engine/Messages/UrlMessagePartModel.cs
index 19b1cfd..9f97618 100644
--- a/src/Engine/Messages/UrlMessagePartModel.cs
+++ b/src/Engine/Messages/UrlMessagePartModel.cs
@@ -42,6 +42,7 @@ namespace Smuxi.Engine
         Ftp,
         Ftps,
         Telnet,
+        MailTo
     }
     
     [Serializable]
@@ -85,7 +86,13 @@ namespace Smuxi.Engine
         {
             _Protocol = ParseProtocol(url);
             if (_Protocol == UrlProtocol.None) {
+                // assume http if no protocol was specified
                 _Protocol = UrlProtocol.Http;
+                // text should stay pristine
+                if (Text == null) {
+                    Text = _Url;
+                }
+                _Url = String.Format("http://{0}", _Url);
             }
         }
         
@@ -119,7 +126,7 @@ namespace Smuxi.Engine
 
         protected static UrlProtocol ParseProtocol(string url)
         {
-            Match match = Regex.Match(url, @"^([a-zA-Z0-9\-]+):\/\/");
+            Match match = Regex.Match(url, @"^([a-zA-Z0-9\-]+):");
             if (!match.Success) {
                 return UrlProtocol.None;
             }
@@ -134,5 +141,20 @@ namespace Smuxi.Engine
             }
             return UrlProtocol.Unknown;
         }
+
+        public override string ToString()
+        {
+            if (Text == null) {
+                return _Url;
+            } else if (_Url == null) {
+                return Text;
+            } else if (Text == _Url) {
+                return _Url;
+            } else if (Text.Contains(_Url)) {
+                return Text;
+            } else {
+                return "[" + _Url + " " + Text + "]";
+            }
+        }
     }
 }
diff --git a/src/Engine/Persons/ContactModel.cs b/src/Engine/Persons/ContactModel.cs
index be30eef..44cf136 100644
--- a/src/Engine/Persons/ContactModel.cs
+++ b/src/Engine/Persons/ContactModel.cs
@@ -1,13 +1,7 @@
 /*
- * $Id: User.cs 142 2007-01-02 22:19:08Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Engine/User.cs $
- * $Rev: 142 $
- * $Author: meebey $
- * $Date: 2007-01-02 23:19:08 +0100 (Tue, 02 Jan 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2006, 2010 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2007, 2010-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -30,12 +24,13 @@ using System;
 using System.Text;
 using System.Runtime.Serialization;
 using System.Security.Cryptography;
+using System.Globalization;
 using Smuxi.Common;
 
 namespace Smuxi.Engine
 {
     [Serializable]
-    public class ContactModel : ITraceable, ISerializable
+    public class ContactModel : ITraceable, ISerializable, IComparable<ContactModel>
     {
         private string          _ID;
         private string          _IdentityName;
@@ -190,5 +185,60 @@ namespace Smuxi.Engine
         {
             return _NetworkID + "/" + _IdentityName; 
         }
+
+        public virtual int CompareTo(ContactModel contact)
+        {
+            if (contact == null) {
+                return 1;
+            }
+
+            return String.Compare(IdentityName, contact.IdentityName,
+                                  true, CultureInfo.InvariantCulture);
+
+        }
+
+        public override bool Equals(object obj)
+        {
+            var value = obj as ContactModel;
+            if (value == null) {
+                return false;
+            }
+            return Equals(value);
+        }
+
+        public virtual bool Equals(ContactModel model)
+        {
+            if (model == null) {
+                return false;
+            }
+            if (ID != model.ID) {
+                return false;
+            }
+            if (NetworkID != model.NetworkID) {
+                return false;
+            }
+            if (NetworkProtocol != model.NetworkProtocol) {
+                return false;
+            }
+            return true;
+        }
+
+        public static bool operator ==(ContactModel a, ContactModel b)
+        {
+            if (System.Object.ReferenceEquals(a, b)) {
+                return true;
+            }
+
+            if ((object) a == null || (object) b == null) {
+                return false;
+            }
+
+            return a.Equals(b);
+        }
+
+        public static bool operator !=(ContactModel a, ContactModel b)
+        {
+            return !(a == b);
+        }
     }
 }
diff --git a/src/Engine/Persons/PersonModel.cs b/src/Engine/Persons/PersonModel.cs
index a01f2c1..4a10e62 100644
--- a/src/Engine/Persons/PersonModel.cs
+++ b/src/Engine/Persons/PersonModel.cs
@@ -27,6 +27,7 @@
  */
  
 using System;
+using System.Runtime.Remoting;
 using System.Runtime.Serialization;
 using Smuxi.Common;
 
@@ -79,8 +80,13 @@ namespace Smuxi.Engine
                                       
         public override string ToTraceString()
         {
-            string nm = (_ProtocolManager != null) ? _ProtocolManager.ToString() : "(null)";  
-            return  nm + "/" + IdentityName; 
+            if (_ProtocolManager == null ||
+                RemotingServices.IsTransparentProxy(_ProtocolManager)) {
+                // avoids remoting call
+                return base.ToTraceString();
+            }
+            // REMOTING CALL
+            return _ProtocolManager.ToString() + "/" + IdentityName;
         }
     }
 }
diff --git a/src/Engine/Protocols/IProtocolManager.cs b/src/Engine/Protocols/IProtocolManager.cs
index 3a413d2..9596c6d 100644
--- a/src/Engine/Protocols/IProtocolManager.cs
+++ b/src/Engine/Protocols/IProtocolManager.cs
@@ -33,6 +33,10 @@ namespace Smuxi.Engine
 {
     public interface IProtocolManager : IDisposable
     {
+        Session Session {
+            get;
+        }
+
         string NetworkID {
             get;
         }
@@ -65,7 +69,7 @@ namespace Smuxi.Engine
             get;
         }
 
-        void Connect(FrontendManager frontendManager, string hostname, int port, string username, string password);
+        void Connect(FrontendManager frontendManager, ServerModel server);
         void Disconnect(FrontendManager frontendManager);
         void Reconnect(FrontendManager frontendManager);
         
diff --git a/src/Engine/Protocols/ProtocolManagerBase.cs b/src/Engine/Protocols/ProtocolManagerBase.cs
index 6b78421..f487ab0 100644
--- a/src/Engine/Protocols/ProtocolManagerBase.cs
+++ b/src/Engine/Protocols/ProtocolManagerBase.cs
@@ -1,13 +1,7 @@
 /*
- * $Id: IrcProtocolManager.cs 149 2007-04-11 16:47:52Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Engine/IrcProtocolManager.cs $
- * $Rev: 149 $
- * $Author: meebey $
- * $Date: 2007-04-11 18:47:52 +0200 (Wed, 11 Apr 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2007-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -112,11 +106,23 @@ namespace Smuxi.Engine
             }
         }
         
-        protected Session Session {
+        public virtual Session Session {
             get {
                 return _Session;
             }
         }
+
+        protected bool DebugProtocol {
+            get {
+#if LOG4NET
+                var repo = log4net.LogManager.GetRepository();
+                // info is higher than debug
+                return repo.Threshold <= log4net.Core.Level.Debug;
+#else
+                return false;
+#endif
+            }
+        }
         
         protected ProtocolManagerBase(Session session)
         {
@@ -140,8 +146,7 @@ namespace Smuxi.Engine
         
         public abstract bool Command(CommandModel cmd);
         public abstract void Connect(FrontendManager fm,
-                                     string hostname, int port,
-                                     string username, string password);
+                                     ServerModel server);
         public abstract void Reconnect(FrontendManager fm);
         public abstract void Disconnect(FrontendManager fm);
         
@@ -154,43 +159,29 @@ namespace Smuxi.Engine
 
         protected void NotConnected(CommandModel cmd)
         {
-            cmd.FrontendManager.AddTextToChat(
-                cmd.Chat,
-                String.Format(
-                    "-!- {0}",
-                    _("Not connected to server")
-                )
-            );
+            var msg = CreateMessageBuilder();
+            msg.AppendEventPrefix();
+            msg.AppendText(_("Not connected to server"));
+            cmd.FrontendManager.AddMessageToChat(cmd.Chat, msg.ToMessage());
         }
 
         protected void NotEnoughParameters(CommandModel cmd)
         {
-            cmd.FrontendManager.AddTextToChat(
-                cmd.Chat,
-                String.Format(
-                    "-!- {0}",
-                    String.Format(
-                        _("Not enough parameters for {0} command"),
-                        cmd.Command
-                    )
-                )
-            );
+            var msg = CreateMessageBuilder();
+            msg.AppendEventPrefix();
+            msg.AppendText(_("Not enough parameters for {0} command"),
+                           cmd.Command);
+            cmd.FrontendManager.AddMessageToChat(cmd.Chat, msg.ToMessage());
         }
         
         protected virtual void OnConnected(EventArgs e)
         {
             Trace.Call(e);
 
-            Session.AddTextToChat(
-                Chat,
-                String.Format(
-                    "-!- {0}",
-                    String.Format(
-                        _("Connected to {0}"),
-                        NetworkID
-                    )
-                )
-            );
+            var msg = CreateMessageBuilder();
+            msg.AppendEventPrefix();
+            msg.AppendText(_("Connected to {0}"), NetworkID);
+            Session.AddMessageToChat(Chat, msg.ToMessage());
 
             _PresenceStatus = PresenceStatus.Online;
 
@@ -205,16 +196,10 @@ namespace Smuxi.Engine
         {
             Trace.Call(e);
 
-            Session.AddTextToChat(
-                Chat,
-                String.Format(
-                    "-!- {0}",
-                    String.Format(
-                        _("Disconnected from {0}"),
-                        NetworkID
-                    )
-                )
-            );
+            var msg = CreateMessageBuilder();
+            msg.AppendEventPrefix();
+            msg.AppendText(_("Disconnected from {0}"), NetworkID);
+            Session.AddMessageToChat(Chat, msg.ToMessage());
 
             _PresenceStatus = PresenceStatus.Offline;
 
@@ -267,5 +252,46 @@ namespace Smuxi.Engine
             
             return false;
         }
+
+        protected virtual void DebugRead(string data)
+        {
+            if (data == null) {
+                throw new ArgumentNullException("data");
+            }
+            if (Chat == null) {
+                return;
+            }
+            if (!DebugProtocol) {
+                return;
+            }
+
+            var msgBuilder = CreateMessageBuilder();
+            msgBuilder.MessageType = MessageType.Event;
+            // HACK: extra leading space to align with "-!- "
+            // HACK: extra trailing space to align with "WRITE: "
+            msgBuilder.AppendText("    READ:  ");
+            msgBuilder.AppendText(data);
+            Session.AddMessageToChat(Chat, msgBuilder.ToMessage());
+        }
+
+        protected virtual void DebugWrite(string data)
+        {
+            if (data == null) {
+                throw new ArgumentNullException("data");
+            }
+            if (Chat == null) {
+                return;
+            }
+            if (!DebugProtocol) {
+                return;
+            }
+
+            var msgBuilder = CreateMessageBuilder();
+            msgBuilder.MessageType = MessageType.Event;
+            // HACK: extra leading space to align with "-!- "
+            msgBuilder.AppendText("    WRITE: ");
+            msgBuilder.AppendText(data);
+            Session.AddMessageToChat(Chat, msgBuilder.ToMessage());
+        }
     }
 }
diff --git a/src/Engine/Session.cs b/src/Engine/Session.cs
index 0484ec8..8865802 100644
--- a/src/Engine/Session.cs
+++ b/src/Engine/Session.cs
@@ -1,7 +1,7 @@
 /*
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2010 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2012 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -22,6 +22,8 @@
 
 using System;
 using System.IO;
+using System.Net;
+using System.Linq;
 using System.Text;
 using System.Text.RegularExpressions;
 using System.Collections;
@@ -41,7 +43,7 @@ namespace Smuxi.Engine
         private int                                   _Version = 0;
         private IDictionary<string, FrontendManager>  _FrontendManagers;
         private IList<IProtocolManager>               _ProtocolManagers;
-        private IList<ChatModel>                      _Chats;
+        private List<ChatModel>                       _Chats;
         private SessionChatModel                      _SessionChat;
         private Config                                _Config;
         private string                                _Username;
@@ -50,7 +52,12 @@ namespace Smuxi.Engine
         private FilterListController                  _FilterListController;
         private ICollection<FilterModel>              _Filters;
         private bool                                  _OnStartupCommandsProcessed;
-        
+        Timer NewsFeedTimer { get; set; }
+        List<string> SeenNewsFeedIds { get; set; }
+        DateTime NewsFeedLastModified { get; set; }
+        TimeSpan NewsFeedUpdateInterval { get; set; }
+        TimeSpan NewsFeedRetryInterval { get; set; }
+
         public IList<IProtocolManager> ProtocolManagers {
             get {
                 return _ProtocolManagers;
@@ -87,6 +94,12 @@ namespace Smuxi.Engine
             }
         }
         
+        public string Username {
+            get {
+                return _Username;
+            }
+        }
+
         public bool IsLocal {
             get {
                 return _Username == "local";
@@ -119,9 +132,21 @@ namespace Smuxi.Engine
             _FilterListController = new FilterListController(_UserConfig);
             _Filters = _FilterListController.GetFilterList().Values;
             _Chats = new List<ChatModel>();
-            
-            _SessionChat = new SessionChatModel("smuxi", "Smuxi");
-            _Chats.Add(_SessionChat);
+
+            InitSessionChat();
+
+            SeenNewsFeedIds = new List<string>();
+            NewsFeedUpdateInterval = TimeSpan.FromHours(12);
+            NewsFeedRetryInterval = TimeSpan.FromMinutes(5);
+            NewsFeedTimer = new Timer(delegate { UpdateNewsFeed(); }, null,
+                                      TimeSpan.Zero, NewsFeedUpdateInterval);
+        }
+
+        protected MessageBuilder CreateMessageBuilder()
+        {
+            var builder = new MessageBuilder();
+            builder.ApplyConfig(UserConfig);
+            return builder;
         }
 
         public void RegisterFrontendUI(IFrontendUI ui)
@@ -146,29 +171,6 @@ namespace Smuxi.Engine
             if (!_OnStartupCommandsProcessed) {
                 _OnStartupCommandsProcessed = true;
 
-                string str;
-                MessageModel msg;
-                msg = new MessageModel();
-                msg.MessageParts.Add(
-                    new TextMessagePartModel(new TextColor(0xFF0000), null, false,
-                            true, false, _("Welcome to Smuxi")));
-                AddMessageToChat(_SessionChat, msg);
-
-                msg = new MessageModel();
-                msg.MessageParts.Add(
-                    new TextMessagePartModel(null, null, false,
-                            true, false, _("Type /help to get a list of available commands.")));
-                AddMessageToChat(_SessionChat, msg);
-
-                str = _("After you have made a connection the list of " +
-                        "available commands changes. Use the /help command " +
-                        "again to see the extended command list.");
-                msg = new MessageModel();
-                msg.MessageParts.Add(
-                    new TextMessagePartModel(null, null, false,
-                            true, false, str));
-                AddMessageToChat(_SessionChat, msg);
-                
                 foreach (string command in (string[])_UserConfig["OnStartupCommands"]) {
                     if (command.Length == 0) {
                         continue;
@@ -359,6 +361,9 @@ namespace Smuxi.Engine
                 switch (cd.Command) {
                     case "help":
                         CommandHelp(cd);
+                        if (cd.Chat.ChatType == ChatType.Session) {
+                            handled = true;
+                        }
                         break;
                     case "server":
                     case "connect":
@@ -381,6 +386,10 @@ namespace Smuxi.Engine
                         CommandConfig(cd);
                         handled = true;
                         break;
+                    case "shutdown":
+                        CommandShutdown(cd);
+                        handled = true;
+                        break;
                 }
             } else {
                 // normal text
@@ -401,31 +410,28 @@ namespace Smuxi.Engine
             if (cd == null) {
                 throw new ArgumentNullException("cd");
             }
-            
-            MessageModel msg = new MessageModel();
-            TextMessagePartModel msgPart;
-            
-            msgPart = new TextMessagePartModel();
+            var builder = CreateMessageBuilder();
             // TRANSLATOR: this line is used as a label / category for a
             // list of commands below
-            msgPart.Text = "[" + _("Engine Commands") + "]";
-            msgPart.Bold = true;
-            msg.MessageParts.Add(msgPart);
-
-            cd.FrontendManager.AddMessageToChat(cd.Chat, msg);
+            builder.AppendHeader(_("Engine Commands"));
+            cd.FrontendManager.AddMessageToChat(cd.Chat, builder.ToMessage());
 
             string[] help = {
                 "help",
                 "connect/server protocol [protocol-parameters]",
-                "disconnect",
+                "disconnect [server]",
                 "network list",
-                "network close [server]",
-                "network switch [server]",
+                "network close [network]",
+                "network switch [network]",
                 "config (save|load)",
+                "shutdown"
             };
-            
-            foreach (string line in help) { 
-                cd.FrontendManager.AddTextToChat(cd.Chat, "-!- " + line);
+
+            foreach (string line in help) {
+                builder = CreateMessageBuilder();
+                builder.AppendEventPrefix();
+                builder.AppendText(line);
+                cd.FrontendManager.AddMessageToChat(cd.Chat, builder.ToMessage());
             }
         }
         
@@ -440,8 +446,15 @@ namespace Smuxi.Engine
             FrontendManager fm = cd.FrontendManager;
             
             string protocol;
-            if (cd.DataArray.Length >= 2) {
+            if (cd.DataArray.Length >= 3) {
                 protocol = cd.DataArray[1];
+            } else if (cd.DataArray.Length >= 2) {
+                // HACK: simply assume the user meant irc if not specified as
+                // Smuxi is still primarly an IRC client
+                protocol = "irc";
+                string cmd = String.Format("{0}connect irc {1}",
+                                           cd.CommandCharacter, cd.Parameter);
+                cd = new CommandModel(fm, cd.Chat, cd.CommandCharacter, cmd);
             } else {
                 _NotEnoughParameters(cd);
                 return;
@@ -528,14 +541,7 @@ namespace Smuxi.Engine
             IProtocolManager victim = null;
             if (cd.DataArray.Length >= 2) {
                 string server = cd.DataArray[1];
-                lock (_ProtocolManagers) {
-                    foreach (IProtocolManager nm in _ProtocolManagers) {
-                        if (nm.Host.ToLower() == server.ToLower()) {
-                            victim = nm;
-                            break;
-                        }
-                    }
-                }
+                victim = GetProtocolManagerByHost(server);
                 if (victim == null) {
                     fm.AddTextToChat(
                         cd.Chat,
@@ -616,6 +622,35 @@ namespace Smuxi.Engine
             }
         }
         
+        public void CommandShutdown(CommandModel cmd)
+        {
+            Trace.Call(cmd);
+
+            if (cmd == null) {
+                throw new ArgumentNullException("cmd");
+            }
+
+#if LOG4NET
+            f_Logger.Info("Shutting down...");
+#endif
+            lock (_ProtocolManagers) {
+                foreach (var protocolManager in _ProtocolManagers) {
+                    protocolManager.Disconnect(cmd.FrontendManager);
+                    protocolManager.Dispose();
+                }
+            }
+
+            if (IsLocal) {
+                // allow the frontend to cleanly terminate
+                return;
+            }
+
+#if LOG4NET
+            f_Logger.Debug("Terminating process...");
+#endif
+            Environment.Exit(0);
+        }
+
         public void CommandNetwork(CommandModel cd)
         {
             Trace.Call(cd);
@@ -653,8 +688,9 @@ namespace Smuxi.Engine
             lock (_ProtocolManagers) {
                 foreach (IProtocolManager nm in _ProtocolManagers) {
                     fm.AddTextToChat(cd.Chat, "-!- " +
-                        _("Type") + ": " + nm.Protocol + " " +
-                        _("Host") + ": " + nm.Host + " " + 
+                        _("Protocol") + ": " + nm.Protocol + " " +
+                        _("Network") + ": " + nm.NetworkID + " " +
+                        _("Host") + ": " + nm.Host + " " +
                         _("Port") + ": " + nm.Port);
                 }
             }
@@ -666,19 +702,12 @@ namespace Smuxi.Engine
             IProtocolManager pm = null;
             if (cd.DataArray.Length >= 3) {
                 // named protocol manager
-                string host = cd.DataArray[2].ToLower();
-                lock (_ProtocolManagers) {
-                    foreach (IProtocolManager protocolManager in _ProtocolManagers) {
-                        if (protocolManager.Host.ToLower() == host) {
-                            pm = protocolManager;
-                            break;
-                        }
-                    }
-                }
+                string network = cd.DataArray[2];
+                pm = GetProtocolManagerByNetwork(network);
                 if (pm == null) {
                     fm.AddTextToChat(cd.Chat, "-!- " +
-                        String.Format(_("Network close failed - could not find network with host: {0}"),
-                                      host));
+                        String.Format(_("Network close failed - could not find network: {0}"),
+                                      network));
                     return;
                 }
             } else if (cd.DataArray.Length >= 2) {
@@ -711,19 +740,17 @@ namespace Smuxi.Engine
             FrontendManager fm = cd.FrontendManager;
             if (cd.DataArray.Length >= 3) {
                 // named network manager
-                string host = cd.DataArray[2].ToLower();
-                lock (_ProtocolManagers) {
-                    foreach (IProtocolManager nm in _ProtocolManagers) {
-                        if (nm.Host.ToLower() == host) {
-                            fm.CurrentProtocolManager = nm;
-                            fm.UpdateNetworkStatus();
-                            return;
-                        }
-                    }
+                string network = cd.DataArray[2];
+                var pm = GetProtocolManagerByNetwork(network);
+                if (pm == null) {
+                    fm.AddTextToChat(cd.Chat, "-!- " +
+                        String.Format(
+                            _("Network switch failed - could not find network: {0}"),
+                                  network));
+                    return;
                 }
-                fm.AddTextToChat(cd.Chat, "-!- " +
-                    String.Format(_("Network switch failed - could not find network with host: {0}"),
-                                  host));
+                fm.CurrentProtocolManager = pm;
+                fm.UpdateNetworkStatus();
             } else if (cd.DataArray.Length >= 2) {
                 // next network manager
                 fm.NextProtocolManager();
@@ -765,7 +792,42 @@ namespace Smuxi.Engine
                 }
             }
         }
-        
+
+        public T CreateChat<T>(string id,
+                               string name,
+                               IProtocolManager protocolManager)
+                              where T : ChatModel
+        {
+            Trace.Call(id, name, protocolManager);
+
+            T chat;
+            Type chatType = typeof(T);
+            if (chatType == typeof(SessionChatModel)) {
+                chat = (T) Activator.CreateInstance(chatType, id, name);
+            } else if (chatType == typeof(PersonChatModel)) {
+                throw new NotSupportedException(
+                    "PersonModel is not supported, use " +
+                    "Session.CreatePersionChat() instead"
+                );
+            } else {
+                chat = (T) Activator.CreateInstance(chatType,
+                                                    id, name, protocolManager);
+            }
+            chat.ApplyConfig(UserConfig);
+            return chat;
+        }
+
+        public PersonChatModel CreatePersonChat(PersonModel person,
+                                                string id, string name,
+                                                IProtocolManager protocolManager)
+        {
+            Trace.Call(person, id, name, protocolManager);
+
+            var chat = new PersonChatModel(person, id, name, protocolManager);
+            chat.ApplyConfig(UserConfig);
+            return chat;
+        }
+
         public void AddChat(ChatModel chat)
         {
             Trace.Call(chat);
@@ -773,11 +835,17 @@ namespace Smuxi.Engine
             if (chat == null) {
                 throw new ArgumentNullException("chat");
             }
-            
+
+            chat.Position = GetSortedChatPosition(chat);
             lock (_Chats) {
                 _Chats.Add(chat);
+                if (chat.Position == -1) {
+                    chat.Position = _Chats.IndexOf(chat);
+                } else {
+                    MoveChat(chat, chat.Position);
+                }
             }
-            
+
             lock (_FrontendManagers) {
                 foreach (FrontendManager fm in _FrontendManagers.Values) {
                     fm.AddChat(chat);
@@ -798,8 +866,15 @@ namespace Smuxi.Engine
 #if LOG4NET
                     f_Logger.Warn("RemoveChat(): _Chats.Remove(" + chat + ") failed, ignoring...");
 #endif
+                    chat.Close();
                     return;
                 }
+                chat.Close();
+
+                // refresh chat positions
+                foreach (var schat in _Chats) {
+                    schat.Position = _Chats.IndexOf(schat);
+                }
             }
             
             lock (_FrontendManagers) {
@@ -856,6 +931,23 @@ namespace Smuxi.Engine
             }
         }
         
+        public void MoveChat(ChatModel chat, int newPosition)
+        {
+            Trace.Call(chat, newPosition);
+
+            if (chat == null) {
+                throw new ArgumentNullException("chat");
+            }
+
+            lock (_Chats) {
+                _Chats.Remove(chat);
+                _Chats.Insert(newPosition, chat);
+                foreach (var schat in _Chats) {
+                    schat.Position = _Chats.IndexOf(schat);
+                }
+            }
+        }
+
         public void AddTextToChat(ChatModel chat, string text)
         {
             AddTextToChat(chat, text, false);
@@ -894,14 +986,41 @@ namespace Smuxi.Engine
                 return;
             }
 
-            int buffer_lines = (int) UserConfig["Interface/Notebook/EngineBufferLines"];
-            if (buffer_lines > 0) {
-                chat.UnsafeMessages.Add(msg);
-                if (chat.UnsafeMessages.Count > buffer_lines) {
-                    chat.UnsafeMessages.RemoveAt(0);
+            lock (chat.MessageBuffer) {
+                try {
+                    chat.MessageBuffer.Add(msg);
+                } catch (Exception ex) {
+#if LOG4NET
+                    Trace.Call(chat, msg, ignoreFilters);
+                    f_Logger.Error(
+                        "AddMessageToChat(): " +
+                        "chat.MessageBuffer.Add() threw exception!", ex
+                    );
+#endif
+                    if (chat.MessageBuffer is Db4oMessageBuffer) {
+#if LOG4NET
+                        f_Logger.Error(
+                            "AddMessageToChat(): " +
+                            "Falling back to volatile message buffer..."
+                        );
+#endif
+                        chat.ResetMessageBuffer();
+                        chat.InitMessageBuffer(MessageBufferPersistencyType.Volatile);
+
+                        var builder = new MessageBuilder();
+                        builder.AppendEventPrefix();
+                        builder.AppendErrorText(
+                            _("Failed to write to chat history. " +
+                              "Your chat history will not be preserved. " +
+                              "Reason: {0}"),
+                            ex.Message
+                        );
+                        chat.MessageBuffer.Add(builder.ToMessage());
+
+                        chat.MessageBuffer.Add(msg);
+                    }
                 }
             }
-            
             lock (_FrontendManagers) {
                 foreach (FrontendManager fm in _FrontendManagers.Values) {
                     fm.AddMessageToChat(chat, msg);
@@ -1059,8 +1178,7 @@ namespace Smuxi.Engine
             if (!String.IsNullOrEmpty(server.Password)) {
                 password = server.Password;
             }
-            protocolManager.Connect(frontendManager, server.Hostname,
-                                    server.Port, server.Username, password);
+            protocolManager.Connect(frontendManager, server);
             if (protocolManager.Chat == null) {
                 // just in case the ProtocolManager is not setting the
                 // protocol chat
@@ -1256,6 +1374,172 @@ namespace Smuxi.Engine
             }
         }
 
+        IProtocolManager GetProtocolManagerByHost(string network)
+        {
+            lock (_ProtocolManagers) {
+                foreach (var manager in _ProtocolManagers) {
+                    if (String.Compare(manager.Host, network, true) == 0) {
+                        return manager;
+                    }
+                }
+            }
+            return null;
+        }
+
+        IProtocolManager GetProtocolManagerByNetwork(string network)
+        {
+            lock (_ProtocolManagers) {
+                foreach (var manager in _ProtocolManagers) {
+                    if (String.Compare(manager.NetworkID, network, true) == 0) {
+                        return manager;
+                    }
+                }
+            }
+            return null;
+        }
+
+        int GetSortedChatPosition(ChatModel chatModel)
+        {
+            int position = chatModel.Position;
+            if (position != -1) {
+                return position;
+            }
+
+            ChatType type = chatModel.ChatType;
+            if (type != ChatType.Person &&
+                type != ChatType.Group) {
+                return position;
+            }
+
+            // new group person and group chats behind their protocol chat
+            IProtocolManager pm = chatModel.ProtocolManager;
+            lock (_Chats) {
+                foreach (var chat in _Chats) {
+                    if (chat.ChatType == ChatType.Protocol &&
+                        chat.ProtocolManager == pm) {
+                        position = _Chats.IndexOf(chat) + 1;
+                        break;
+                    }
+                }
+
+                if (position == -1) {
+                    return position;
+                }
+
+                // now find the first chat with a different protocol manager
+                foreach (var chat in _Chats.Skip(position)) {
+                    if (chat.ProtocolManager != pm) {
+                        return _Chats.IndexOf(chat);
+                    }
+                }
+            }
+
+            // if there was no next protocol manager, simply append
+            // the chat way to the end
+            return -1;
+        }
+
+        void InitSessionChat()
+        {
+            _SessionChat = new SessionChatModel("smuxi", "Smuxi");
+            _Chats.Add(_SessionChat);
+
+            var builder = CreateMessageBuilder();
+            var text = builder.CreateText(_("Welcome to Smuxi"));
+            text.ForegroundColor = new TextColor(255, 0, 0);
+            text.Bold = true;
+            builder.AppendText(text);
+            builder.AppendText(Environment.NewLine);
+
+            text = builder.CreateText(
+                _("Type /help to get a list of available commands.")
+            );
+            text.Bold = true;
+            builder.AppendText(text);
+            builder.AppendText(Environment.NewLine);
+
+            text = builder.CreateText(_("After you have made a connection " +
+                "the list of available commands changes. Go to the newly " +
+                "opened connection tab and use the /help command again to " +
+                "see the extended command list."));
+            text.Bold = true;
+            builder.AppendText(text);
+            builder.AppendText(Environment.NewLine);
+
+            builder.AppendText(Environment.NewLine);
+
+            builder.AppendHeader("Smuxi News");
+            AddMessageToChat(_SessionChat,builder.ToMessage());
+        }
+
+        void UpdateNewsFeed()
+        {
+            Trace.Call();
+
+            try {
+                var url = "http://news.smuxi.org/feed.php";
+                var req = WebRequest.Create(url);
+                var proxySettings = new ProxySettings();
+                proxySettings.ApplyConfig(UserConfig);
+                req.Proxy = proxySettings.GetWebProxy(url);
+                if (req is HttpWebRequest) {
+                    var httpReq = (HttpWebRequest) req;
+                    httpReq.UserAgent = Engine.VersionString;
+                    if (NewsFeedLastModified != DateTime.MinValue) {
+                        httpReq.IfModifiedSince = NewsFeedLastModified;
+                    }
+                }
+                var res = req.GetResponse();
+                if (res is HttpWebResponse) {
+                    var httpRes = (HttpWebResponse) res;
+                    if (httpRes.StatusCode == HttpStatusCode.NotModified) {
+                        return;
+                    }
+                    NewsFeedLastModified = httpRes.LastModified;
+                }
+                var feed = AtomFeed.Load(res.GetResponseStream());
+                var sortedEntries = feed.Entry.OrderBy(x => x.Published);
+                foreach (var entry in sortedEntries) {
+                    if (SeenNewsFeedIds.Contains(entry.Id)) {
+                        continue;
+                    }
+                    SeenNewsFeedIds.Add(entry.Id);
+
+                    var msg = new FeedMessageBuilder();
+                    msg.Append(entry);
+                    if (!msg.IsEmpty) {
+                        msg.AppendText("\n");
+                        AddMessageToChat(SessionChat, msg.ToMessage());
+                    }
+                }
+            } catch (WebException ex) {
+                switch (ex.Status) {
+                    case WebExceptionStatus.ConnectFailure:
+                    case WebExceptionStatus.ConnectionClosed:
+                    case WebExceptionStatus.Timeout:
+                    case WebExceptionStatus.ReceiveFailure:
+                    case WebExceptionStatus.NameResolutionFailure:
+                    case WebExceptionStatus.ProxyNameResolutionFailure:
+#if LOG4NET
+                        f_Logger.Warn(
+                            String.Format(
+                                "UpdateNewsFeed(): Temporarily issue " +
+                                "detected, retrying in {0} min...",
+                                NewsFeedRetryInterval.Minutes
+                            ),
+                            ex
+                        );
+#endif
+                        NewsFeedTimer.Change(NewsFeedRetryInterval, NewsFeedUpdateInterval);
+                        break;
+                }
+            } catch (Exception ex) {
+#if LOG4NET
+                f_Logger.Error("UpdateNewsFeed(): Exception, ignored...", ex);
+#endif
+            }
+        }
+
         private static string _(string msg)
         {
             return LibraryCatalog.GetString(msg, _LibraryTextDomain);
diff --git a/src/Engine/TextColorContrast.cs b/src/Engine/TextColorContrast.cs
new file mode 100644
index 0000000..dc1f210
--- /dev/null
+++ b/src/Engine/TextColorContrast.cs
@@ -0,0 +1,34 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2010 Mirco Bauer <meebey at meebey.net>
+// 
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+// 
+// 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
+
+using System;
+
+namespace Smuxi.Engine
+{
+    public enum TextColorContrast : int
+    {
+        None     = 0,
+        VeryLow  = 10,
+        Low      = 20,
+        Medium   = 35,
+        High     = 50,
+        VeryHigh = 60
+    }
+}
diff --git a/src/Engine/TextColorTools.cs b/src/Engine/TextColorTools.cs
new file mode 100644
index 0000000..df6f542
--- /dev/null
+++ b/src/Engine/TextColorTools.cs
@@ -0,0 +1,171 @@
+/*
+ * Smuxi - Smart MUltipleXed Irc
+ *
+ * Copyright (c) 2008-2011 Mirco Bauer <meebey at meebey.net>
+ *
+ * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+ *
+ * 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
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using Smuxi.Common;
+
+namespace Smuxi.Engine
+{
+    public static class TextColorTools
+    {
+#if LOG4NET
+        private static readonly log4net.ILog f_Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+#endif
+        private static Dictionary<int, TextColor> f_BestContrastColors;
+
+        static TextColorTools()
+        {
+            f_BestContrastColors = new Dictionary<int, TextColor>(1024);
+        }
+
+        public static TextColor GetBestTextColor(TextColor fgColor, TextColor bgColor)
+        {
+            return GetBestTextColor(fgColor, bgColor, TextColorContrast.Medium);
+        }
+
+        public static TextColor GetBestTextColor(TextColor fgColor,
+                                                 TextColor bgColor,
+                                                 TextColorContrast neededContrast)
+        {
+            if (fgColor == null) {
+                throw new ArgumentNullException("fgColor");
+            }
+            if (bgColor == null) {
+                throw new ArgumentNullException("bgColor");
+            }
+
+            TextColor bestColor;
+            int key = fgColor.Value ^ bgColor.Value ^ (int) neededContrast;
+            if (f_BestContrastColors.TryGetValue(key, out bestColor)) {
+                return bestColor;
+            }
+
+            double brDiff = GetBritnessDifference(bgColor, TextColor.White);
+            int modifier = 0;
+            // for bright backgrounds we need to go from bright to dark colors
+            // for better contrast and for dark backgrounds the opposite
+            if (brDiff < 127) {
+                // bright background
+                modifier = -10;
+            } else {
+                // dark background
+                modifier = 10;
+            }
+
+            double lastDifference = 0;
+            bestColor = fgColor;
+            int attempts = 1;
+            while (true) {
+                double difference = GetLuminanceDifference(bestColor, bgColor);
+                double needed = ((int) neededContrast) / 10d;
+                if (difference > needed) {
+                    break;
+                }
+
+#if LOG4NET && COLOR_DEBUG
+                f_Logger.Debug("GetBestTextColor(): color has bad contrast: " +
+                               bestColor + " difference: " + difference +
+                               " needed: " + needed);
+#endif
+
+                // change the fg color
+                int red   = bestColor.Red   + modifier;
+                int green = bestColor.Green + modifier;
+                int blue  = bestColor.Blue  + modifier;
+
+                // cap to allowed values
+                if (modifier > 0) {
+                    if (red > 255) {
+                        red = 255;
+                    }
+                    if (green > 255) {
+                        green = 255;
+                    }
+                    if (blue > 255) {
+                        blue = 255;
+                    }
+                } else {
+                    if (red < 0) {
+                        red = 0;
+                    }
+                    if (green < 0) {
+                        green = 0;
+                    }
+                    if (blue < 0) {
+                        blue = 0;
+                    }
+                }
+
+                bestColor = new TextColor((byte) red, (byte) green, (byte) blue);
+                
+                // in case we found no good color
+                if (bestColor == TextColor.White ||
+                    bestColor == TextColor.Black) {
+                    break;
+                }
+                attempts++;
+            }
+#if LOG4NET && COLOR_DEBUG
+            f_Logger.Debug(
+                String.Format(
+                    "GetBestTextColor(): found good contrast: {0}|{1}={2} " +
+                    "({3}) attempts: {4}", fgColor, bgColor,  bestColor,
+                    neededContrast, attempts
+                )
+            );
+#endif
+            f_BestContrastColors.Add(key, bestColor);
+
+            return bestColor;
+        }
+
+        // algorithm ported from PHP to C# from:
+        // http://www.splitbrain.org/blog/2008-09/18-calculating_color_contrast_with_php
+        public static double GetLuminanceDifference(TextColor color1, TextColor color2)
+        {
+            double L1 = 0.2126d * Math.Pow(color1.Red   / 255d, 2.2d) +
+                        0.7152d * Math.Pow(color1.Green / 255d, 2.2d) +
+                        0.0722d * Math.Pow(color1.Blue  / 255d, 2.2d);
+            double L2 = 0.2126d * Math.Pow(color2.Red   / 255d, 2.2d) +
+                        0.7152d * Math.Pow(color2.Green / 255d, 2.2d) +
+                        0.0722d * Math.Pow(color2.Blue  / 255d, 2.2d);
+            if (L1 > L2) {
+                return (L1 + 0.05d) / (L2 + 0.05d);
+            } else {
+                return (L2 + 0.05d) / (L1 + 0.05d);
+            }
+        }
+
+        public static double GetBritnessDifference(TextColor color1, TextColor color2)
+        {
+            double br1 = (299d * color1.Red +
+                          587d * color1.Green +
+                          114d * color1.Blue) / 1000d;
+            double br2 = (299d * color2.Red +
+                          587d * color2.Green +
+                          114d * color2.Blue) / 1000d;
+            return Math.Abs(br1 - br2);
+        }
+    }
+}
diff --git a/src/Frontend-Curses/Makefile.in b/src/Frontend-Curses/Makefile.in
index a4e5a98..de1e41c 100644
--- a/src/Frontend-Curses/Makefile.in
+++ b/src/Frontend-Curses/Makefile.in
@@ -41,8 +41,11 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 subdir = src/Frontend-Curses
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -83,6 +86,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -96,13 +100,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -143,13 +160,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -157,6 +176,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -167,13 +187,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -187,13 +216,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -201,7 +236,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -216,10 +253,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -365,7 +405,7 @@ build_references_ref = $(foreach ref, $(REFERENCES), $(if $(filter \
 	-pkg:%, $(ref)), $(ref), $(if $(filter -r:%, $(ref)), $(ref), \
 	-r:$(ref)))) $(foreach ref, $(DLL_REFERENCES), -r:$(ref)) \
 	$(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
 programfilesdir = @libdir@/@PACKAGE@
@@ -494,6 +534,12 @@ uninstall-pkglibSCRIPTS:
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(linuxdesktopapplicationsdir)" || $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)"
@@ -647,7 +693,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -701,7 +747,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-am
 
@@ -718,19 +764,21 @@ uninstall-am: uninstall-binSCRIPTS \
 
 .MAKE: install-am install-strip
 
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binSCRIPTS install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-linuxdesktopapplicationsDATA \
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binSCRIPTS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-man install-pdf \
 	install-pdf-am install-pkglibSCRIPTS install-programfilesDATA \
 	install-programfilesiconsDATA install-ps install-ps-am \
 	install-strip installcheck installcheck-am installdirs \
 	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
-	uninstall-binSCRIPTS uninstall-linuxdesktopapplicationsDATA \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am uninstall-binSCRIPTS \
+	uninstall-linuxdesktopapplicationsDATA \
 	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
 	uninstall-programfilesDATA uninstall-programfilesiconsDATA
 
diff --git a/src/Frontend-GNOME-IRC/AssemblyInfo.cs b/src/Frontend-GNOME-IRC/AssemblyInfo.cs
index 583dcb6..5afed5b 100644
--- a/src/Frontend-GNOME-IRC/AssemblyInfo.cs
+++ b/src/Frontend-GNOME-IRC/AssemblyInfo.cs
@@ -1,10 +1,4 @@
 /*
- * $Id: AssemblyInfo.cs 167 2007-04-17 21:17:37Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-GNOME/AssemblyInfo.cs $
- * $Rev: 167 $
- * $Author: meebey $
- * $Date: 2007-04-17 23:17:37 +0200 (Tue, 17 Apr 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
  * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
@@ -30,7 +24,7 @@ using System.Reflection;
 using System.Runtime.CompilerServices;
 
 [assembly: AssemblyTitle("Smuxi - IRC support for GNOME frontend")]
-[assembly: AssemblyCopyright("2005-2008 (C) Mirco Bauer <meebey at meebey.net>")]
+[assembly: AssemblyCopyright("2005-2011 (C) Mirco Bauer <meebey at meebey.net>")]
 
 [assembly: AssemblyDelaySign(false)]
 [assembly: AssemblyKeyFile("")]
diff --git a/src/Frontend-GNOME-IRC/IrcGroupChatView.cs b/src/Frontend-GNOME-IRC/IrcGroupChatView.cs
index da2d8fb..9b38778 100644
--- a/src/Frontend-GNOME-IRC/IrcGroupChatView.cs
+++ b/src/Frontend-GNOME-IRC/IrcGroupChatView.cs
@@ -1,13 +1,7 @@
 /*
- * $Id: GroupChatView.cs 188 2007-04-21 22:03:54Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-GNOME/GroupChatView.cs $
- * $Rev: 188 $
- * $Author: meebey $
- * $Date: 2007-04-22 00:03:54 +0200 (Sun, 22 Apr 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2007 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -27,6 +21,7 @@
  */
 
 using System;
+using System.Threading;
 using System.Collections.Generic;
 using System.Globalization;
 using Smuxi.Engine;
@@ -47,8 +42,6 @@ namespace Smuxi.Frontend.Gnome
         {
             Trace.Call(groupChat);
 
-            _IrcProtocolManager = (IrcProtocolManager) groupChat.ProtocolManager;
-            
             if (PersonTreeView != null) {
                 Gtk.CellRendererText cellr = new Gtk.CellRendererText();
                 // HACK: for some reason GTK is giving the space of 2 chars which
@@ -65,6 +58,15 @@ namespace Smuxi.Frontend.Gnome
             }
         }
 
+        public override void Sync()
+        {
+            Trace.Call();
+
+            base.Sync();
+
+            _IrcProtocolManager = (IrcProtocolManager) ProtocolManager;
+        }
+
         private void _RenderIrcGroupPersonMode(Gtk.TreeViewColumn column,
                                                Gtk.CellRenderer cellr,
                                                Gtk.TreeModel model, Gtk.TreeIter iter)
@@ -102,14 +104,20 @@ namespace Smuxi.Frontend.Gnome
             foreach (PersonModel person in persons) {
                 nicks.Add(person.ID);
             }
-            _IrcProtocolManager.CommandOp(
-                new CommandModel(
-                    Frontend.FrontendManager,
-                    ChatModel,
-                    String.Join(" ", nicks.ToArray())
-                )
-            );
-        } 
+            ThreadPool.QueueUserWorkItem(delegate {
+                try {
+                    _IrcProtocolManager.CommandOp(
+                        new CommandModel(
+                            Frontend.FrontendManager,
+                            ChatModel,
+                            String.Join(" ", nicks.ToArray())
+                        )
+                    );
+                } catch (Exception ex) {
+                    Frontend.ShowException(ex);
+                }
+            });
+        }
         
         private void _OnUserListMenuDeopActivated(object sender, EventArgs e)
         {
@@ -125,13 +133,19 @@ namespace Smuxi.Frontend.Gnome
             foreach (PersonModel person in persons) {
                 nicks.Add(person.ID);
             }
-            _IrcProtocolManager.CommandDeop(
-                new CommandModel(
-                    Frontend.FrontendManager,
-                    ChatModel,
-                    String.Join(" ", nicks.ToArray())
-                )
-            );
+            ThreadPool.QueueUserWorkItem(delegate {
+                try {
+                    _IrcProtocolManager.CommandDeop(
+                        new CommandModel(
+                            Frontend.FrontendManager,
+                            ChatModel,
+                            String.Join(" ", nicks.ToArray())
+                        )
+                    );
+                } catch (Exception ex) {
+                    Frontend.ShowException(ex);
+                }
+            });
         }
         
         private void _OnUserListMenuVoiceActivated(object sender, EventArgs e)
@@ -148,13 +162,19 @@ namespace Smuxi.Frontend.Gnome
             foreach (PersonModel person in persons) {
                 nicks.Add(person.ID);
             }
-            _IrcProtocolManager.CommandVoice(
-                new CommandModel(
-                    Frontend.FrontendManager,
-                    ChatModel,
-                    String.Join(" ", nicks.ToArray())
-                )
-            );
+            ThreadPool.QueueUserWorkItem(delegate {
+                try {
+                    _IrcProtocolManager.CommandVoice(
+                        new CommandModel(
+                            Frontend.FrontendManager,
+                            ChatModel,
+                            String.Join(" ", nicks.ToArray())
+                        )
+                    );
+                } catch (Exception ex) {
+                    Frontend.ShowException(ex);
+                }
+            });
         }
         
         private void _OnUserListMenuDevoiceActivated(object sender, EventArgs e)
@@ -171,13 +191,19 @@ namespace Smuxi.Frontend.Gnome
             foreach (PersonModel person in persons) {
                 nicks.Add(person.ID);
             }
-            _IrcProtocolManager.CommandDevoice(
-                new CommandModel(
-                    Frontend.FrontendManager,
-                    ChatModel,
-                    String.Join(" ", nicks.ToArray())
-                )
-            );
+            ThreadPool.QueueUserWorkItem(delegate {
+                try {
+                    _IrcProtocolManager.CommandDevoice(
+                        new CommandModel(
+                            Frontend.FrontendManager,
+                            ChatModel,
+                            String.Join(" ", nicks.ToArray())
+                        )
+                    );
+                } catch (Exception ex) {
+                    Frontend.ShowException(ex);
+                }
+            });
         }
         
         private void _OnUserListMenuKickActivated(object sender, EventArgs e)
@@ -190,13 +216,19 @@ namespace Smuxi.Frontend.Gnome
             }
 
             foreach (PersonModel person in persons) {
-                _IrcProtocolManager.CommandKick(
-                    new CommandModel(
-                        Frontend.FrontendManager,
-                        ChatModel,
-                        person.ID
-                    )
-                );
+                ThreadPool.QueueUserWorkItem(delegate {
+                    try {
+                        _IrcProtocolManager.CommandKick(
+                            new CommandModel(
+                                Frontend.FrontendManager,
+                                ChatModel,
+                                person.ID
+                            )
+                        );
+                    } catch (Exception ex) {
+                        Frontend.ShowException(ex);
+                    }
+                });
             }
         }
         
@@ -210,13 +242,19 @@ namespace Smuxi.Frontend.Gnome
             }
 
             foreach (PersonModel person in persons) {
-                _IrcProtocolManager.CommandKickban(
-                    new CommandModel(
-                        Frontend.FrontendManager,
-                        ChatModel,
-                        person.ID
-                    )
-                );
+                ThreadPool.QueueUserWorkItem(delegate {
+                    try {
+                        _IrcProtocolManager.CommandKickban(
+                            new CommandModel(
+                                Frontend.FrontendManager,
+                                ChatModel,
+                                person.ID
+                            )
+                        );
+                    } catch (Exception ex) {
+                        Frontend.ShowException(ex);
+                    }
+                });
             }
         }
         
@@ -234,13 +272,19 @@ namespace Smuxi.Frontend.Gnome
             foreach (PersonModel person in persons) {
                 nicks.Add(person.ID);
             }
-            _IrcProtocolManager.CommandBan(
-                new CommandModel(
-                    Frontend.FrontendManager,
-                    ChatModel,
-                    String.Join(" ", nicks.ToArray())
-                )
-            );
+            ThreadPool.QueueUserWorkItem(delegate {
+                try {
+                    _IrcProtocolManager.CommandBan(
+                        new CommandModel(
+                            Frontend.FrontendManager,
+                            ChatModel,
+                            String.Join(" ", nicks.ToArray())
+                        )
+                    );
+                } catch (Exception ex) {
+                    Frontend.ShowException(ex);
+                }
+            });
         }
         
         private void _OnUserListMenuUnbanActivated(object sender, EventArgs e)
@@ -256,13 +300,19 @@ namespace Smuxi.Frontend.Gnome
             foreach (PersonModel person in persons) {
                 nicks.Add(person.ID);
             }
-            _IrcProtocolManager.CommandUnban(
-                new CommandModel(
-                    Frontend.FrontendManager,
-                    ChatModel,
-                    String.Join(" ", nicks.ToArray())
-                )
-            );
+            ThreadPool.QueueUserWorkItem(delegate {
+                try {
+                    _IrcProtocolManager.CommandUnban(
+                        new CommandModel(
+                            Frontend.FrontendManager,
+                            ChatModel,
+                            String.Join(" ", nicks.ToArray())
+                        )
+                    );
+                } catch (Exception ex) {
+                    Frontend.ShowException(ex);
+                }
+            });
         }
         
         private void _OnUserListMenuQueryActivated(object sender, EventArgs e)
@@ -275,13 +325,19 @@ namespace Smuxi.Frontend.Gnome
             }
 
             foreach (PersonModel person in persons) {
-                _IrcProtocolManager.CommandMessageQuery(
-                    new CommandModel(
-                        Frontend.FrontendManager,
-                        ChatModel,
-                        person.ID
-                    )
-                );
+                ThreadPool.QueueUserWorkItem(delegate {
+                    try {
+                        _IrcProtocolManager.CommandMessageQuery(
+                            new CommandModel(
+                                Frontend.FrontendManager,
+                                ChatModel,
+                                person.ID
+                            )
+                        );
+                    } catch (Exception ex) {
+                        Frontend.ShowException(ex);
+                    }
+                });
             }
         }
 
@@ -295,35 +351,19 @@ namespace Smuxi.Frontend.Gnome
             }
 
             foreach (PersonModel person in persons) {
-                _IrcProtocolManager.CommandWhoIs(
-                    new CommandModel(
-                        Frontend.FrontendManager,
-                        ChatModel,
-                        person.ID
-                    )
-                );
-            }
-        }
-
-        protected override void OnPersonsRowActivated(object sender, Gtk.RowActivatedArgs e)
-        {
-            Trace.Call(sender, e);
-
-            base.OnPersonsRowActivated(sender, e);
-
-            IList<PersonModel> persons = GetSelectedPersons();
-            if (persons == null) {
-                return;
-            }
-
-            foreach (PersonModel person in persons) {
-                _IrcProtocolManager.CommandMessageQuery(
-                    new CommandModel(
-                        Frontend.FrontendManager,
-                        ChatModel,
-                        person.ID
-                    )
-                );
+                ThreadPool.QueueUserWorkItem(delegate {
+                    try {
+                        _IrcProtocolManager.CommandWhoIs(
+                            new CommandModel(
+                                Frontend.FrontendManager,
+                                ChatModel,
+                                person.ID
+                            )
+                        );
+                    } catch (Exception ex) {
+                        Frontend.ShowException(ex);
+                    }
+                });
             }
         }
 
@@ -396,38 +436,8 @@ namespace Smuxi.Frontend.Gnome
             );
             invite_to_item.Submenu = invite_to_menu_item;
             PersonMenu.Append(invite_to_item);
-        }
 
-        protected override int SortPersonListStore(Gtk.TreeModel model,
-                                                   Gtk.TreeIter iter1,
-                                                   Gtk.TreeIter iter2)
-        {
-            Gtk.ListStore liststore = (Gtk.ListStore) model;
-            
-            IrcGroupPersonModel person1 = (IrcGroupPersonModel) liststore.GetValue(iter1, 0);
-            IrcGroupPersonModel person2 = (IrcGroupPersonModel) liststore.GetValue(iter2, 0);
-            
-            int status1 = 0;
-            if (person1.IsOp) {
-                status1 += 2;
-            } else if (person1.IsVoice) {
-                status1 += 1;
-            }
-            
-            int status2 = 0;
-            if (person2.IsOp) {
-                status2 += 2;
-            } else if (person2.IsVoice) {
-                status2 += 1;
-            }
-            
-            int res = status2.CompareTo(status1);
-            if (res == 0 ) {
-                // the mode is equal, so the name decides
-                return base.SortPersonListStore(model, iter1, iter2);
-            }
-            
-            return res;
+            PersonMenu.ShowAll();
         }
 
         private static string _(string msg)
diff --git a/src/Frontend-GNOME-IRC/IrcPersonChatView.cs b/src/Frontend-GNOME-IRC/IrcPersonChatView.cs
index 88c580f..19b7df1 100644
--- a/src/Frontend-GNOME-IRC/IrcPersonChatView.cs
+++ b/src/Frontend-GNOME-IRC/IrcPersonChatView.cs
@@ -1,13 +1,7 @@
 /*
- * $Id: GroupChatView.cs 188 2007-04-21 22:03:54Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-GNOME/GroupChatView.cs $
- * $Rev: 188 $
- * $Author: meebey $
- * $Date: 2007-04-22 00:03:54 +0200 (Sun, 22 Apr 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2008 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2008, 2010-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -27,6 +21,7 @@
  */
 
 using System;
+using System.Threading;
 using System.Globalization;
 using Smuxi.Engine;
 using Smuxi.Common;
@@ -43,11 +38,18 @@ namespace Smuxi.Frontend.Gnome
         {
             Trace.Call(personChat);
 
-            _IrcProtocolManager = (IrcProtocolManager)personChat.ProtocolManager;
-
             OutputMessageTextView.PopulatePopup += _OnOutputMessageTextViewPopulatePopup;
         }
-        
+
+        public override void Sync()
+        {
+            Trace.Call();
+
+            base.Sync();
+
+            _IrcProtocolManager = (IrcProtocolManager) ProtocolManager;
+        }
+
         private void _OnOutputMessageTextViewPopulatePopup (object o, Gtk.PopulatePopupArgs args)
         {
             if (OutputMessageTextView.IsAtUrlTag) {
@@ -83,13 +85,19 @@ namespace Smuxi.Frontend.Gnome
         {
             Trace.Call(sender, e);
 
-            _IrcProtocolManager.CommandWhoIs(
-                new CommandModel(
-                    Frontend.FrontendManager,
-                    ChatModel,
-                    ChatModel.ID
-                )
-             );
+            ThreadPool.QueueUserWorkItem(delegate {
+                try {
+                    _IrcProtocolManager.CommandWhoIs(
+                        new CommandModel(
+                            Frontend.FrontendManager,
+                            ChatModel,
+                            ChatModel.ID
+                        )
+                     );
+                } catch (Exception ex) {
+                    Frontend.ShowException(ex);
+                }
+            });
         }
 
         private static string _(string msg)
diff --git a/src/Frontend-GNOME-IRC/Makefile.in b/src/Frontend-GNOME-IRC/Makefile.in
index 9c13cb7..909f680 100644
--- a/src/Frontend-GNOME-IRC/Makefile.in
+++ b/src/Frontend-GNOME-IRC/Makefile.in
@@ -40,8 +40,11 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 subdir = src/Frontend-GNOME-IRC
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -82,6 +85,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -95,13 +99,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -142,13 +159,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -156,6 +175,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -166,13 +186,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -186,13 +215,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -200,7 +235,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -215,10 +252,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -373,7 +413,7 @@ build_references_ref = $(foreach ref, $(REFERENCES), $(if $(filter \
 	-pkg:%, $(ref)), $(ref), $(if $(filter -r:%, $(ref)), $(ref), \
 	-r:$(ref)))) $(foreach ref, $(DLL_REFERENCES), -r:$(ref)) \
 	$(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
 programfilesdir = @libdir@/@PACKAGE@
@@ -501,6 +541,12 @@ uninstall-pkglibSCRIPTS:
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(linuxdesktopapplicationsdir)" || $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)"
@@ -654,7 +700,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -708,7 +754,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-am
 
@@ -725,19 +771,21 @@ uninstall-am: uninstall-binSCRIPTS \
 
 .MAKE: install-am install-strip
 
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binSCRIPTS install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-linuxdesktopapplicationsDATA \
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binSCRIPTS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-man install-pdf \
 	install-pdf-am install-pkglibSCRIPTS install-programfilesDATA \
 	install-programfilesiconsDATA install-ps install-ps-am \
 	install-strip installcheck installcheck-am installdirs \
 	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
-	uninstall-binSCRIPTS uninstall-linuxdesktopapplicationsDATA \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am uninstall-binSCRIPTS \
+	uninstall-linuxdesktopapplicationsDATA \
 	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
 	uninstall-programfilesDATA uninstall-programfilesiconsDATA
 
diff --git a/src/Frontend-GNOME-XMPP/Makefile.in b/src/Frontend-GNOME-XMPP/Makefile.in
index b1c40df..fdd9b98 100644
--- a/src/Frontend-GNOME-XMPP/Makefile.in
+++ b/src/Frontend-GNOME-XMPP/Makefile.in
@@ -40,8 +40,11 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 subdir = src/Frontend-GNOME-XMPP
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -82,6 +85,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -95,13 +99,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -142,13 +159,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -156,6 +175,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -166,13 +186,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -186,13 +215,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -200,7 +235,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -215,10 +252,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -363,7 +403,7 @@ build_references_ref = $(foreach ref, $(REFERENCES), $(if $(filter \
 	-pkg:%, $(ref)), $(ref), $(if $(filter -r:%, $(ref)), $(ref), \
 	-r:$(ref)))) $(foreach ref, $(DLL_REFERENCES), -r:$(ref)) \
 	$(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
 programfilesdir = @libdir@/@PACKAGE@
@@ -491,6 +531,12 @@ uninstall-pkglibSCRIPTS:
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(linuxdesktopapplicationsdir)" || $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)"
@@ -644,7 +690,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -698,7 +744,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-am
 
@@ -715,19 +761,21 @@ uninstall-am: uninstall-binSCRIPTS \
 
 .MAKE: install-am install-strip
 
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binSCRIPTS install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-linuxdesktopapplicationsDATA \
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binSCRIPTS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-man install-pdf \
 	install-pdf-am install-pkglibSCRIPTS install-programfilesDATA \
 	install-programfilesiconsDATA install-ps install-ps-am \
 	install-strip installcheck installcheck-am installdirs \
 	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
-	uninstall-binSCRIPTS uninstall-linuxdesktopapplicationsDATA \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am uninstall-binSCRIPTS \
+	uninstall-linuxdesktopapplicationsDATA \
 	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
 	uninstall-programfilesDATA uninstall-programfilesiconsDATA
 
diff --git a/src/Frontend-GNOME/AboutDialog.cs b/src/Frontend-GNOME/AboutDialog.cs
index ba10586..d4d1f0a 100644
--- a/src/Frontend-GNOME/AboutDialog.cs
+++ b/src/Frontend-GNOME/AboutDialog.cs
@@ -1,13 +1,7 @@
 /*
- * $Id$
- * $URL$
- * $Rev$
- * $Author$
- * $Date$
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2006-2012 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -27,6 +21,8 @@
  */
 
 using System;
+using System.Linq;
+using Smuxi.Common;
 
 namespace Smuxi.Frontend.Gnome
 {
@@ -40,14 +36,21 @@ namespace Smuxi.Frontend.Gnome
             
             TransientFor = parent;
             Name = Frontend.Name;
-            Version = "\n Frontend: " + Frontend.UIName + " " + Frontend.Version +
+            var version = Frontend.Version.ToString();
+            var distVersion = Defines.DistVersion;
+            if (!String.IsNullOrEmpty(distVersion)) {
+                version = String.Format("{0} ({1})", version, distVersion);
+            }
+            Version = "\n Frontend: " + Frontend.UIName + " " + version  +
                       "\n Engine: " + Frontend.EngineVersion;
-            Copyright = "Copyright © 2005-2010 Mirco Bauer <meebey at meebey.net>";
+            Copyright = "Copyright © 2005-2012 Mirco Bauer <meebey at meebey.net>";
             Authors = new string[] {
                 "Mirco Bauer <meebey at meebey.net>",
                 "David Paleino <dapal at debian.org>",
                 "Clément Bourgeois <moonpyk at gmail.com>",
-                "Chris Le Sueur <c.m.lesueur at gmail.com>"
+                "Chris Le Sueur <c.m.lesueur at gmail.com>",
+                "Tuukka Hastrup <Tuukka.Hastrup at iki.fi>",
+                "Bianca Mix <heavydemon at freenet.de>"
             };
             Artists = new string[] {
                 "Jakub Steiner <jimmac at ximian.com>",
@@ -56,7 +59,9 @@ namespace Smuxi.Frontend.Gnome
                 "Ahmed Abdellah <a3dman1 at gmail.com>"
             };
             TranslatorCredits = _("translator-credits");
-            Logo = new Gdk.Pixbuf(null, "icon.svg", 256, 256);
+            Logo = Frontend.LoadIcon(
+                Frontend.IconName, 256, "icon_256x256.png"
+            );
             Website = "http://www.smuxi.org/";
             WebsiteLabel = _("Smuxi Website");
         }
diff --git a/src/Frontend-GNOME/AssemblyInfo.cs b/src/Frontend-GNOME/AssemblyInfo.cs
index 93f415a..49eefaf 100644
--- a/src/Frontend-GNOME/AssemblyInfo.cs
+++ b/src/Frontend-GNOME/AssemblyInfo.cs
@@ -1,10 +1,4 @@
 /*
- * $Id$
- * $URL$
- * $Rev$
- * $Author$
- * $Date$
- *
  * Smuxi - Smart MUltipleXed Irc
  *
  * Copyright (c) 2005-2009 Mirco Bauer <meebey at meebey.net>
@@ -30,7 +24,7 @@ using System.Reflection;
 using System.Runtime.CompilerServices;
 
 [assembly: AssemblyTitle("Smuxi - GNOME frontend")]
-[assembly: AssemblyCopyright("2005-2010 (C) Mirco Bauer <meebey at meebey.net>")]
+[assembly: AssemblyCopyright("2005-2012 (C) Mirco Bauer <meebey at meebey.net>")]
 
 [assembly: AssemblyDelaySign(false)]
 [assembly: AssemblyKeyFile("")]
diff --git a/src/Frontend-GNOME/ChatViewManager.cs b/src/Frontend-GNOME/ChatViewManager.cs
index 85f4784..be5c9cd 100644
--- a/src/Frontend-GNOME/ChatViewManager.cs
+++ b/src/Frontend-GNOME/ChatViewManager.cs
@@ -1,13 +1,7 @@
 /*
- * $Id: ChannelPage.cs 138 2006-12-23 17:11:57Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-GNOME/ChannelPage.cs $
- * $Rev: 138 $
- * $Author: meebey $
- * $Date: 2006-12-23 18:11:57 +0100 (Sat, 23 Dec 2006) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -44,94 +38,88 @@ namespace Smuxi.Frontend.Gnome
         private static readonly log4net.ILog f_Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 #endif
         private List<ChatView> f_Chats = new List<ChatView>();
+        public  IList<ChatView> SyncedChats { get; private set; }
         private Notebook       f_Notebook;
         private Gtk.TreeView   f_TreeView;
         private UserConfig     f_Config;
-        
+        ChatViewSyncManager    SyncManager { get; set; }
+
         public event ChatViewManagerChatAddedEventHandler   ChatAdded;
         public event ChatViewManagerChatRemovedEventHandler ChatRemoved;
-            
+        public event EventHandler<ChatViewManagerChatSyncedEventArgs> ChatSynced;
+
         public override IChatView ActiveChat {
             get {
+                return CurrentChatView;
+            }
+        }
+
+        public ChatView CurrentChatView {
+            get {
                 return f_Notebook.CurrentChatView;
             }
+            set {
+                if (value == null) {
+                    return;
+                }
+                f_Notebook.CurrentChatView = value;
+            }
         }
-        
+
+        public int CurrentChatNumber {
+            get {
+                if (CurrentChatView == null) {
+                    return -1;
+                }
+                return f_Notebook.CurrentPage;
+            }
+            set {
+                if (value < 0 || value >= f_Notebook.NPages) {
+                    return;
+                }
+
+                f_Notebook.CurrentPage = value;
+            }
+        }
+
         public IList<ChatView> Chats {
             get {
                 return f_Chats;
             }
         }
-        
+
+        public bool IsSensitive {
+            set {
+                f_Notebook.Sensitive = value;
+                Frontend.MainWindow.MenuBar.Sensitive = value;
+                Frontend.MainWindow.Entry.Sensitive = value;
+            }
+            get {
+                return f_Notebook.Sensitive;
+            }
+        }
+
         public ChatViewManager(Notebook notebook, Gtk.TreeView treeView)
         {
             f_Notebook = notebook;
             f_TreeView = treeView;
+            SyncedChats = new List<ChatView>();
+            SyncManager = new ChatViewSyncManager();
+            SyncManager.ChatAdded += OnChatAdded;
+            SyncManager.ChatSynced += OnChatSynced;
+            SyncManager.WorkerException += OnWorkerException;
         }
-        
+
+        /// <remarks>
+        /// This method is thread safe.
+        /// </remarks>
         public override void AddChat(ChatModel chat)
         {
-            ChatView chatView = (ChatView) CreateChatView(chat);
-            f_Chats.Add(chatView);
-            
-            if (f_Config != null) {
-                chatView.ApplyConfig(f_Config);
-            }
-            
-            int idx = chat.Position;
-            ChatType type = chat.ChatType;
-            // new group person and group chats behind their protocol chat
-            if (idx == -1 &&
-                (type == ChatType.Person ||
-                 type == ChatType.Group)) {
-                IProtocolManager pm = chat.ProtocolManager;
-                for (int i = 0; i < f_Notebook.NPages; i++) {
-                    ChatView page = (ChatView) f_Notebook.GetNthPage(i);
-                    ChatModel pageChat = page.ChatModel;
-                    if (pageChat.ChatType == ChatType.Protocol &&
-                        pageChat.ProtocolManager == pm) {
-                        idx = i + 1;
-                        break;
-                    }
-                }
-                
-                if (idx != -1) {
-                    // now find the first chat with a different protocol manager
-                    bool found = false;
-                    for (int i = idx; i < f_Notebook.NPages; i++) {
-                        ChatView page = (ChatView) f_Notebook.GetNthPage(i);
-                        ChatModel pageChat = page.ChatModel;
-                        if (pageChat.ProtocolManager != pm) {
-                            found = true;
-                            idx = i;
-                            break;
-                        }
-                    }
-                    if (!found) {
-                        // if there was no next protocol manager, simply append 
-                        // the chat way to the end
-                        idx = -1;
-                    }
-                }
-            }
-
-            if (idx == -1) {
-                f_Notebook.AppendPage(chatView, chatView.LabelWidget);
-            } else {
-#if LOG4NET
-                f_Logger.Debug("AddChat(): adding chat at: " + idx);
-#endif
-                f_Notebook.InsertPage(chatView, chatView.LabelWidget, idx);
+            if (chat == null) {
+                throw new ArgumentNullException("chat");
             }
 
-#if GTK_SHARP_2_10
-            f_Notebook.SetTabReorderable(chatView, true);
-#endif
-            chatView.ShowAll();
-
-            if (ChatAdded != null) {
-                ChatAdded(this, new ChatViewManagerChatAddedEventArgs(chatView));
-            }
+            SyncManager.QueueAdd(chat);
         }
 
         public override void RemoveChat(ChatModel chat)
@@ -146,6 +134,7 @@ namespace Smuxi.Frontend.Gnome
 
             f_Notebook.RemovePage(f_Notebook.PageNum(chatView));
             f_Chats.Remove(chatView);
+            SyncedChats.Remove(chatView);
 
             if (ChatRemoved != null) {
                 ChatRemoved(this, new ChatViewManagerChatRemovedEventArgs(chatView));
@@ -177,9 +166,22 @@ namespace Smuxi.Frontend.Gnome
                 return;
             }
 
+            SyncedChats.Remove(chatView);
             chatView.Disable();
         }
 
+        /// <remarks>
+        /// This method is thread safe.
+        /// </remarks>
+        public void SyncChat(ChatModel chat)
+        {
+            if (chat == null) {
+                throw new ArgumentNullException("chat");
+            }
+
+            SyncManager.QueueSync(chat);
+        }
+
         public ChatView GetChat(ChatModel chatModel)
         {
             return f_Notebook.GetChat(chatModel);
@@ -198,8 +200,177 @@ namespace Smuxi.Frontend.Gnome
                 chat.ApplyConfig(f_Config);
             }
         }
-    }   
-    
+
+        public void Clear()
+        {
+            Trace.Call();
+
+            f_Config = null;
+            f_Chats.Clear();
+            f_Notebook.RemoveAllPages();
+            SyncedChats.Clear();
+            SyncManager.Clear();
+        }
+
+        void OnChatAdded(object sender, ChatViewAddedEventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            GLib.Idle.Add(delegate {
+                var chatView = (ChatView) CreateChatView(e.ChatModel,
+                                                         e.ChatType,
+                                                         e.ProtocolManagerType);
+                chatView.ID = e.ChatID;
+                chatView.Name = e.ChatID;
+                chatView.Position = e.ChatPosition;
+                f_Chats.Add(chatView);
+
+                if (f_Config != null) {
+                    chatView.ApplyConfig(f_Config);
+                }
+
+                // POSSIBLE REMOTING CALL
+                int idx = GetSortedChatPosition(chatView);
+#if LOG4NET
+                f_Logger.Debug("OnChatAdded(): adding " +
+                               "<" + chatView.ID + "> at: " + idx);
+#endif
+                if (idx == -1) {
+                    f_Notebook.AppendPage(chatView, chatView.LabelWidget);
+                } else {
+                    f_Notebook.InsertPage(chatView, chatView.LabelWidget, idx);
+                }
+
+                // notify the sync manager that the ChatView is ready to be synced
+                SyncManager.ReleaseSync(chatView);
+
+#if GTK_SHARP_2_10
+                f_Notebook.SetTabReorderable(chatView, true);
+#endif
+                chatView.ShowAll();
+
+                if (ChatAdded != null) {
+                    ChatAdded(this, new ChatViewManagerChatAddedEventArgs(chatView));
+                }
+                return false;
+            });
+        }
+
+        void OnChatSynced(object sender, ChatViewSyncedEventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            // FIXME: should we tell the FrontendManager before we sync?
+            // no problem making remoting calls here as this event is called
+            // from worker threads
+            // REMOTING CALL 1
+            Frontend.FrontendManager.AddSyncedChat(e.ChatView.ChatModel);
+
+            GLib.Idle.Add(delegate {
+                var chatView = (ChatView) e.ChatView;
+
+                // we need to bailt out in case the chat was closed during the sync
+                // else chatView.Populate() will die hard, see #635
+                if (!Chats.Contains(chatView)) {
+#if LOG4NET
+                    f_Logger.Debug("OnChatSynced(): detected closed chat: " +
+                                   chatView.ID + " during sync, bailing out...");
+#endif
+                    return false;
+                }
+
+                // HACK: patch chat position as OnChatAdded is not honoring the
+                // AddChat order nor the complete range of chats
+                if (chatView.Position != -1) {
+                    f_Notebook.ReorderChild(chatView, chatView.Position);
+                }
+
+#if LOG4NET
+                DateTime start = DateTime.UtcNow;
+#endif
+                chatView.Populate();
+#if LOG4NET
+                DateTime stop = DateTime.UtcNow;
+                double duration = stop.Subtract(start).TotalMilliseconds;
+                f_Logger.Debug("OnChatSynced(): " +
+                               "<" + chatView.ID + ">.Populate() " +
+                               "Position: " + chatView.Position +
+                               " done, took: " + Math.Round(duration) + " ms");
+#endif
+
+                chatView.ScrollToEnd();
+
+                SyncedChats.Add(chatView);
+                if (ChatSynced != null) {
+                    ChatSynced(this, new ChatViewManagerChatSyncedEventArgs(chatView));
+                }
+                return false;
+            });
+        }
+
+        void OnWorkerException(object sender, WorkerExceptionEventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            Frontend.ShowException(e.Exception);
+        }
+
+        int GetSortedChatPosition(ChatView chatView)
+        {
+            // starting with > 0.8 the Engine supplies ChatModel.Position for us
+            if (Frontend.EngineVersion > new Version("0.8")) {
+                return chatView.Position;
+            }
+
+            // COMPAT: Engine <= 0.8 doesn't populate ChatModel.Position thus
+            // _we_ have to find a good position
+            var chat = chatView.ChatModel;
+            // REMOTING CALL 1
+            int idx = chat.Position;
+            // REMOTING CALL 2
+            ChatType type = chat.ChatType;
+            // new group person and group chats behind their protocol chat
+            if (idx == -1 &&
+                (type == ChatType.Person ||
+                 type == ChatType.Group)) {
+                // REMOTING CALL 3
+                IProtocolManager pm = chat.ProtocolManager;
+                for (int i = 0; i < f_Notebook.NPages; i++) {
+                    ChatView page = (ChatView) f_Notebook.GetNthPage(i);
+                    ChatModel pageChat = page.ChatModel;
+                    // REMOTING CALL 4 and 5
+                    if (pageChat.ChatType == ChatType.Protocol &&
+                        pageChat.ProtocolManager == pm) {
+                        idx = i + 1;
+                        break;
+                    }
+                }
+
+                if (idx != -1) {
+                    // now find the first chat with a different protocol manager
+                    bool found = false;
+                    for (int i = idx; i < f_Notebook.NPages; i++) {
+                        ChatView page = (ChatView) f_Notebook.GetNthPage(i);
+                        ChatModel pageChat = page.ChatModel;
+                        // REMOTING CALL 6
+                        if (pageChat.ProtocolManager != pm) {
+                            found = true;
+                            idx = i;
+                            break;
+                        }
+                    }
+                    if (!found) {
+                        // if there was no next protocol manager, simply append
+                        // the chat way to the end
+                        idx = -1;
+                    }
+                }
+            }
+
+            return idx;
+        }
+    }
+
     public delegate void ChatViewManagerChatAddedEventHandler(object sender, ChatViewManagerChatAddedEventArgs e);
     
     public class ChatViewManagerChatAddedEventArgs : EventArgs
@@ -235,4 +406,14 @@ namespace Smuxi.Frontend.Gnome
             f_ChatView = chatView;
         }
     }
+
+    public class ChatViewManagerChatSyncedEventArgs : EventArgs
+    {
+        public ChatView ChatView { get; private set; }
+
+        public ChatViewManagerChatSyncedEventArgs(ChatView chatView)
+        {
+            ChatView = chatView;
+        }
+    }
 }
diff --git a/src/Frontend-GNOME/ColorContrast.cs b/src/Frontend-GNOME/ColorContrast.cs
deleted file mode 100644
index 02816e7..0000000
--- a/src/Frontend-GNOME/ColorContrast.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// $Id$
-// 
-// Smuxi - Smart MUltipleXed Irc
-// 
-// Copyright (c) 2010 Mirco Bauer <meebey at meebey.net>
-// 
-// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
-// 
-// 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
-
-using System;
-
-namespace Smuxi.Frontend.Gnome
-{
-    public enum ColorContrast : int
-    {
-        None     = 0,
-        VeryLow  = 10,
-        Low      = 20,
-        Medium   = 35,
-        High     = 50,
-        VeryHigh = 60
-    }
-}
diff --git a/src/Frontend-GNOME/ColorConverter.cs b/src/Frontend-GNOME/ColorConverter.cs
new file mode 100644
index 0000000..fce3c78
--- /dev/null
+++ b/src/Frontend-GNOME/ColorConverter.cs
@@ -0,0 +1,73 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2011 Mirco Bauer
+// 
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+// 
+// 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
+
+using System;
+using System.Globalization;
+using Smuxi.Engine;
+
+namespace Smuxi.Frontend.Gnome
+{
+    public static class ColorConverter
+    {
+        public static string GetHexCode(Gdk.Color color)
+        {
+            /*
+            // this approach is changing the color instead of converting it, as byte wraps
+            string hexcode = String.Format("{0}{1}{2}",
+                                           ((byte) color.Red).ToString("X2"),
+                                           ((byte) color.Green).ToString("X2"),
+                                           ((byte) color.Blue).ToString("X2"));
+            */
+            string hexcode = String.Format("#{0}{1}{2}",
+                                           (color.Red >> 8).ToString("X2"),
+                                           (color.Green >> 8).ToString("X2"),
+                                           (color.Blue >> 8).ToString("X2"));
+            return hexcode;
+        }
+
+        public static Gdk.Color GetGdkColor(string hexCode)
+        {
+            if (hexCode == null) {
+                throw new ArgumentNullException("hexCode");
+            }
+
+            var color = TextColor.Parse(hexCode);
+            return new Gdk.Color(color.Red, color.Green, color.Blue);
+        }
+
+        public static TextColor GetTextColor(Gdk.Color color)
+        {
+            string hexcode = GetHexCode(color);
+            // remove leading "#" character
+            hexcode = hexcode.Substring(1);
+            int value  = Int32.Parse(hexcode, NumberStyles.HexNumber);
+            return new TextColor(value);
+        }
+
+        public static Gdk.Color GetGdkColor(TextColor textColor)
+        {
+            if (textColor == null) {
+                throw new ArgumentNullException("textColor");
+            }
+
+            return GetGdkColor(textColor.HexCode);
+        }
+    }
+}
diff --git a/src/Frontend-GNOME/ColorTools.cs b/src/Frontend-GNOME/ColorTools.cs
deleted file mode 100644
index df935b6..0000000
--- a/src/Frontend-GNOME/ColorTools.cs
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * $Id: ChannelPage.cs 138 2006-12-23 17:11:57Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-GNOME/ChannelPage.cs $
- * $Rev: 138 $
- * $Author: meebey $
- * $Date: 2006-12-23 18:11:57 +0100 (Sat, 23 Dec 2006) $
- *
- * Smuxi - Smart MUltipleXed Irc
- *
- * Copyright (c) 2008 Mirco Bauer <meebey at meebey.net>
- *
- * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
- *
- * 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
- */
-
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using Smuxi.Common;
-using Smuxi.Engine;
-
-namespace Smuxi.Frontend.Gnome
-{
-    public static class ColorTools
-    {
-#if LOG4NET
-        private static readonly log4net.ILog f_Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-#endif
-        private static Dictionary<int, TextColor> f_BestContrastColors;
-
-        static ColorTools() {
-            f_BestContrastColors = new Dictionary<int, TextColor>(1024);
-        }
-
-        public static string GetHexCodeColor(Gdk.Color color)
-        {
-            /*
-            // this approach is changing the color instead of converting it, as byte wraps
-            string hexcode = String.Format("{0}{1}{2}",
-                                           ((byte) color.Red).ToString("X2"),
-                                           ((byte) color.Green).ToString("X2"),
-                                           ((byte) color.Blue).ToString("X2"));
-            */
-            string hexcode = String.Format("#{0}{1}{2}",
-                                           (color.Red >> 8).ToString("X2"),
-                                           (color.Green >> 8).ToString("X2"),
-                                           (color.Blue >> 8).ToString("X2"));
-            return hexcode;
-        }
-        
-        public static TextColor GetTextColor(Gdk.Color color)
-        {
-            string hexcode = GetHexCodeColor(color);
-            // remove leading "#" character
-            hexcode = hexcode.Substring(1);
-            int value  = Int32.Parse(hexcode, NumberStyles.HexNumber);
-            return new TextColor(value);
-        }
-        
-        public static Gdk.Color GetGdkColor(TextColor textColor)
-        {
-            if (textColor == null) {
-                throw new ArgumentNullException("textColor");
-            }
-
-            return GetGdkColor(textColor.HexCode);
-        }
-
-        public static Gdk.Color GetGdkColor(string hexCode)
-        {
-            Trace.Call(hexCode);
-
-            var color = TextColor.Parse(hexCode);
-            return new Gdk.Color(color.Red, color.Green, color.Blue);
-        }
-
-        public static TextColor GetBestTextColor(TextColor fgColor, TextColor bgColor)
-        {
-            return GetBestTextColor(fgColor, bgColor, ColorContrast.Medium);
-        }
-
-        public static TextColor GetBestTextColor(TextColor fgColor,
-                                                 TextColor bgColor,
-                                                 ColorContrast neededContrast)
-        {
-            // logging noise
-            //Trace.Call(fgColor, bgColor, neededContrast);
-
-            if (fgColor == null) {
-                throw new ArgumentNullException("fgColor");
-            }
-            if (bgColor == null) {
-                throw new ArgumentNullException("bgColor");
-            }
-
-            TextColor bestColor;
-            int key = fgColor.Value ^ bgColor.Value ^ (int) neededContrast;
-            if (f_BestContrastColors.TryGetValue(key, out bestColor)) {
-                return bestColor;
-            }
-
-            double brDiff = GetBritnessDifference(bgColor, TextColor.White);
-            int modifier = 0;
-            // for bright backgrounds we need to go from bright to dark colors
-            // for better contrast and for dark backgrounds the opposite
-            if (brDiff < 127) {
-                // bright background
-                modifier = -10;
-            } else {
-                // dark background
-                modifier = 10;
-            }
-
-            double lastDifference = 0;
-            bestColor = fgColor;
-            int attempts = 1;
-            while (true) {
-                double difference = GetLuminanceDifference(bestColor, bgColor);
-                double needed = ((int) neededContrast) / 10d;
-                if (difference > needed) {
-                    break;
-                }
-
-#if LOG4NET
-                /* logging noise
-                f_Logger.Debug("GetBestTextColor(): color has bad contrast: " +
-                               bestColor + " difference: " + difference +
-                               " needed: " + needed);
-                */
-#endif
-
-                // change the fg color
-                int red   = bestColor.Red   + modifier;
-                int green = bestColor.Green + modifier;
-                int blue  = bestColor.Blue  + modifier;
-
-                // cap to allowed values
-                if (modifier > 0) {
-                    if (red > 255) {
-                        red = 255;
-                    }
-                    if (green > 255) {
-                        green = 255;
-                    }
-                    if (blue > 255) {
-                        blue = 255;
-                    }
-                } else {
-                    if (red < 0) {
-                        red = 0;
-                    }
-                    if (green < 0) {
-                        green = 0;
-                    }
-                    if (blue < 0) {
-                        blue = 0;
-                    }
-                }
-
-                bestColor = new TextColor((byte) red, (byte) green, (byte) blue);
-                
-                // in case we found no good color
-                if (bestColor == TextColor.White ||
-                    bestColor == TextColor.Black) {
-                    break;
-                }
-                attempts++;
-            }
-#if LOG4NET
-            f_Logger.Debug(
-                String.Format(
-                    "GetBestTextColor(): found good contrast: {0}|{1}={2} " +
-                    "({3}) attempts: {4}", fgColor, bgColor,  bestColor,
-                    neededContrast, attempts
-                )
-            );
-#endif
-            f_BestContrastColors.Add(key, bestColor);
-
-            return bestColor;
-        }
-
-        // algorithm ported from PHP to C# from:
-        // http://www.splitbrain.org/blog/2008-09/18-calculating_color_contrast_with_php
-        public static double GetLuminanceDifference(TextColor color1, TextColor color2)
-        {
-            double L1 = 0.2126d * Math.Pow(color1.Red   / 255d, 2.2d) +
-                        0.7152d * Math.Pow(color1.Green / 255d, 2.2d) +
-                        0.0722d * Math.Pow(color1.Blue  / 255d, 2.2d);
-            double L2 = 0.2126d * Math.Pow(color2.Red   / 255d, 2.2d) +
-                        0.7152d * Math.Pow(color2.Green / 255d, 2.2d) +
-                        0.0722d * Math.Pow(color2.Blue  / 255d, 2.2d);
-            if (L1 > L2) {
-                return (L1 + 0.05d) / (L2 + 0.05d);
-            } else {
-                return (L2 + 0.05d) / (L1 + 0.05d);
-            }
-        }
-
-        public static double GetBritnessDifference(TextColor color1, TextColor color2)
-        {
-            double br1 = (299d * color1.Red +
-                          587d * color1.Green +
-                          114d * color1.Blue) / 1000d;
-            double br2 = (299d * color2.Red +
-                          587d * color2.Green +
-                          114d * color2.Blue) / 1000d;
-            return Math.Abs(br1 - br2);
-        }
-    }
-}
diff --git a/src/Frontend-GNOME/CrashDialog.cs b/src/Frontend-GNOME/CrashDialog.cs
index bbc9cb9..0c49af1 100644
--- a/src/Frontend-GNOME/CrashDialog.cs
+++ b/src/Frontend-GNOME/CrashDialog.cs
@@ -37,6 +37,8 @@ namespace Smuxi.Frontend.Gnome
 #if LOG4NET
         private static readonly log4net.ILog f_Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 #endif
+        string ReportSubject { get; set; }
+        string ReportDescription { get; set; }
 
         public CrashDialog(Gtk.Window parent, Exception e) : base(null, parent, Gtk.DialogFlags.Modal)
         {
@@ -85,15 +87,41 @@ namespace Smuxi.Frontend.Gnome
             if (e.InnerException != null) {
                 message = "Inner-Exception Type:\n"+e.InnerException.GetType()+"\n\n"+
                           "Inner-Exception Message:\n"+e.InnerException.Message+"\n\n"+
-                          "Inner-Exception StackTrace:\n"+e.InnerException.StackTrace+"\n";
+                          "Inner-Exception StackTrace:\n"+e.InnerException.StackTrace+"\n\n";
+                if (e.StackTrace != null &&
+                    e.InnerException.StackTrace.Contains("System.Runtime.Remoting")) {
+                    message += "Inner-Exception.ToString():\n"+e.InnerException.ToString()+"\n\n";
+                }
             }
             message += "Exception Type:\n"+e.GetType()+"\n\n"+
                        "Exception Message:\n"+e.Message+"\n\n"+
-                       "Exception StackTrace:\n"+e.StackTrace;
+                       "Exception StackTrace:\n"+e.StackTrace+"\n\n";
+            if (e.StackTrace != null &&
+                e.StackTrace.Contains("System.Runtime.Remoting")) {
+                message += "Exception.ToString():\n"+e.ToString()+"\n\n";
+            }
             tv.Buffer.Text = message;
+            ReportSubject = "Exception: " + HtmlEncodeLame(e.Message);
+            ReportDescription = String.Format(
+                "<pre>{0}</pre>",
+                HtmlEncodeLame("\n" + message)
+            );
             
             ShowAll();
-       }
+        }
+
+        private string HtmlEncodeLame(string text)
+        {
+            if (text == null) {
+                return String.Empty;
+            }
+
+            return text.Replace("&", "%26").
+                        Replace(" ", "%20").
+                        Replace("\n", "%0A").
+                        Replace("<", "%3C").
+                        Replace(">", "%3E");
+        }
        
         public static void Show(Gtk.Window parent, Exception ex)
         {
@@ -109,7 +137,16 @@ namespace Smuxi.Frontend.Gnome
                 res = base.Run();
                 if (res == -1) {
                     try {
-                        System.Diagnostics.Process.Start("http://www.smuxi.org/newticket");
+                        System.Diagnostics.Process.Start(
+                            String.Format(
+                                "http://www.smuxi.org/issues/new" +
+                                    "?issue[tracker_id]=1" +
+                                    "&issue[subject]={0}" +
+                                    "&issue[description]={1}",
+                                ReportSubject,
+                                ReportDescription
+                            )
+                        );
                     } catch (Exception ex) {
 #if LOG4NET
                         f_Logger.Error(ex);
diff --git a/src/Frontend-GNOME/EngineManagerDialog.cs b/src/Frontend-GNOME/EngineManagerDialog.cs
index ac30068..11c96ec 100644
--- a/src/Frontend-GNOME/EngineManagerDialog.cs
+++ b/src/Frontend-GNOME/EngineManagerDialog.cs
@@ -61,12 +61,8 @@ namespace Smuxi.Frontend.Gnome
             Title = "Smuxi - " + _("Engine Manager");
             SetPosition(Gtk.WindowPosition.CenterAlways);
 
-            Gtk.HBox connect_hbox = new Gtk.HBox();
-            Gtk.Image connect_image = new Gtk.Image(
-                new Gdk.Pixbuf(null, "connect-button.svg", 22, 22));
-            connect_hbox.Add(connect_image);
-            connect_hbox.Add(new Gtk.Label(_("_Connect")));
-            AddActionWidget(new Gtk.Button(connect_hbox), 1);
+            var connect_button = new Gtk.Button(Gtk.Stock.Connect);
+            AddActionWidget(connect_button, 1);
             
             AddActionWidget(new Gtk.Button(Gtk.Stock.New), 3);
             
@@ -98,9 +94,18 @@ namespace Smuxi.Frontend.Gnome
             _ComboBox.Model = _ListStore;
             _InitEngineList();
 
-            hbox.PackStart(_ComboBox, true, true, 10); 
-            
+            var lowBandWidthCheckBox = new Gtk.CheckButton(_("Use Low Bandwidth Mode"));
+            lowBandWidthCheckBox.Active = (bool) Frontend.FrontendConfig["UseLowBandwidthMode"];
+            lowBandWidthCheckBox.Clicked += delegate {
+                Frontend.FrontendConfig["UseLowBandwidthMode"] =
+                    lowBandWidthCheckBox.Active;
+                Frontend.FrontendConfig.Save();
+            };
+
+            hbox.PackStart(_ComboBox, true, true, 10);
+
             vbox.PackStart(hbox, false, false, 10);
+            vbox.PackStart(lowBandWidthCheckBox);
             
             VBox.Add(vbox);
             
@@ -183,8 +188,13 @@ namespace Smuxi.Frontend.Gnome
             string engine = _SelectedEngine;
             try {
                 _EngineManager.Connect(engine);
-                if (_EngineManager.EngineVersion.Major != Frontend.Version.Major ||
-                    _EngineManager.EngineVersion.Minor != Frontend.Version.Minor) {
+                var engineVersion = _EngineManager.EngineVersion;
+                var frontendVersion = Frontend.Version;
+                if ((engineVersion >= new Version("0.8") &&
+                     engineVersion.Major != frontendVersion.Major) ||
+                    (engineVersion < new Version("0.8") &&
+                     (engineVersion.Major != frontendVersion.Major ||
+                      engineVersion.Minor != frontendVersion.Minor))) {
                     throw new ApplicationException(String.Format(
                                 _("Your frontend version ({0}) does not match the engine version ({1})!"),
                                 Frontend.Version, _EngineManager.EngineVersion));
diff --git a/src/Frontend-GNOME/Entry.cs b/src/Frontend-GNOME/Entry.cs
index 2ea57eb..296d0b6 100644
--- a/src/Frontend-GNOME/Entry.cs
+++ b/src/Frontend-GNOME/Entry.cs
@@ -44,9 +44,11 @@ namespace Smuxi.Frontend.Gnome
         private StringCollection _History = new StringCollection();
         private int              _HistoryPosition;
         private bool             _HistoryChangedLine;
-        private Notebook         _Notebook;
         private CommandManager   _CommandManager;
-        
+        private new EntrySettings Settings { get; set; }
+
+        ChatViewManager ChatViewManager;
+
         /*
         public StringCollection History {
             get {
@@ -77,17 +79,18 @@ namespace Smuxi.Frontend.Gnome
         }
         */
 
-        public Entry(Notebook notebook)
+        public Entry(ChatViewManager chatViewManager)
         {
-            Trace.Call(notebook);
+            Trace.Call(chatViewManager);
 
-            if (notebook == null) {
-                throw new ArgumentNullException("notebook");
+            if (chatViewManager == null) {
+                throw new ArgumentNullException("chatViewManager");
             }
 
             _History.Add(String.Empty);
             
-            _Notebook = notebook;
+            ChatViewManager = chatViewManager;
+            Settings = new EntrySettings();
 
             InitCommandManager();
             Frontend.SessionPropertyChanged += delegate {
@@ -135,7 +138,7 @@ namespace Smuxi.Frontend.Gnome
              _Logger.Debug("added: '"+data+"' to history");
 #endif
 
-            if (_History.Count > (int)Frontend.UserConfig["Interface/Entry/CommandHistorySize"]) {
+            if (_History.Count > Settings.CommandHistorySize) {
                 _History.RemoveAt(0);
             } else {
                 _HistoryPosition += positiondiff;
@@ -225,20 +228,40 @@ namespace Smuxi.Frontend.Gnome
                 e.RetVal = true;
                 switch (key) {
                     case Gdk.Key.x:
-                        if (_Notebook.CurrentChatView.ChatModel.ChatType == ChatType.Session) {
+                    case Gdk.Key.X:
+                        if (ChatViewManager.CurrentChatView is SessionChatView) {
                             Frontend.FrontendManager.NextProtocolManager();
                         } else {
                             // don't break cut
                             e.RetVal = false;
                         }
                         break;
+                    case Gdk.Key.p:
+                    case Gdk.Key.P:
+                        ChatViewManager.CurrentChatNumber--;
+                        break;
+                    case Gdk.Key.n:
+                    case Gdk.Key.N:
+                        ChatViewManager.CurrentChatNumber++;
+                        break;
+                    case Gdk.Key.Tab:
+                    case Gdk.Key.ISO_Left_Tab:
+                        if ((e.Event.State & Gdk.ModifierType.ShiftMask) != 0) {
+                            ChatViewManager.CurrentChatNumber--;
+                        } else {
+                            ChatViewManager.CurrentChatNumber++;
+                        }
+                        break;
                     // don't break unicode input
                     case Gdk.Key.U:
                     // don't break copy/paste
                     case Gdk.Key.c:
+                    case Gdk.Key.C:
                     case Gdk.Key.v:
+                    case Gdk.Key.V:
                     // don't break select all
                     case Gdk.Key.a:
+                    case Gdk.Key.A:
                     // don't break jump one word left/right
                     case Gdk.Key.Right:
                     case Gdk.Key.Left:
@@ -247,10 +270,10 @@ namespace Smuxi.Frontend.Gnome
                         e.RetVal = false;
                         break;
                     case Gdk.Key.Home:
-                        _Notebook.CurrentChatView.ScrollToStart();
+                        ChatViewManager.CurrentChatView.ScrollToStart();
                         break;
                     case Gdk.Key.End:
-                        _Notebook.CurrentChatView.ScrollToEnd();
+                        ChatViewManager.CurrentChatView.ScrollToEnd();
                         break;
                 }
             }
@@ -305,9 +328,8 @@ namespace Smuxi.Frontend.Gnome
                         break;
                 }
 
-                if (pagenumber != -1 &&
-                    _Notebook.NPages >= pagenumber + 1) {
-                    _Notebook.Page = pagenumber;
+                if (pagenumber != -1) {
+                    ChatViewManager.CurrentChatNumber = pagenumber;
                 }
             }
 
@@ -325,7 +347,7 @@ namespace Smuxi.Frontend.Gnome
                     e.RetVal = true;
                     if (Frontend.MainWindow.CaretMode) {
                         // when we are in caret-mode change focus to output textview
-                        _Notebook.CurrentChatView.HasFocus = true;
+                        ChatViewManager.CurrentChatView.HasFocus = true;
                     } else {
                         if (Text.Length > 0) {
                             _NickCompletion();
@@ -345,10 +367,10 @@ namespace Smuxi.Frontend.Gnome
                     HistoryNext();
                     break;
                 case Gdk.Key.Page_Up:
-                    _Notebook.CurrentChatView.ScrollUp();
+                    ChatViewManager.CurrentChatView.ScrollUp();
                     break;
                 case Gdk.Key.Page_Down:
-                    _Notebook.CurrentChatView.ScrollDown();
+                    ChatViewManager.CurrentChatView.ScrollDown();
                     break;
             }
         }
@@ -378,7 +400,7 @@ namespace Smuxi.Frontend.Gnome
                     return true;
                 }
 
-                ChatView chat = Frontend.MainWindow.Notebook.CurrentChatView;
+                ChatView chat = ChatViewManager.CurrentChatView;
                 if (chat == null) {
                     return false;
                 }
@@ -462,11 +484,10 @@ namespace Smuxi.Frontend.Gnome
                 return;
             }
 
-            // BUG? REMOTING CALLs here?!? (would block GUI!)
             CommandModel cd = new CommandModel(
                 Frontend.FrontendManager,
-                _Notebook.CurrentChatView.ChatModel,
-                (string) Frontend.UserConfig["Interface/Entry/CommandCharacter"],
+                ChatViewManager.CurrentChatView.ChatModel,
+                Settings.CommandCharacter,
                 cmd
             );
 
@@ -507,6 +528,10 @@ namespace Smuxi.Frontend.Gnome
                         _CommandClear(cd);
                         handled = true;
                         break;
+                    case "list":
+                        _CommandList(cd);
+                        handled = true;
+                        break;
                 }
             }
             
@@ -515,18 +540,13 @@ namespace Smuxi.Frontend.Gnome
         
         private void _CommandHelp(CommandModel cd)
         {
-            MessageModel msg = new MessageModel();
-            TextMessagePartModel msgPart;
-            
-            msgPart = new TextMessagePartModel();
+            var chatView = ChatViewManager.GetChat(cd.Chat);
+            var builder = new MessageBuilder();
             // TRANSLATOR: this line is used as a label / category for a
             // list of commands below
-            msgPart.Text = "[" + _("Frontend Commands") + "]";
-            msgPart.Bold = true;
-            msg.MessageParts.Add(msgPart);
-            
-            cd.FrontendManager.AddMessageToChat(cd.Chat, msg);
-            
+            builder.AppendHeader(_("Frontend Commands"));
+            chatView.AddMessage(builder.ToMessage());
+
             string[] help = {
             "help",
             "window (number|channelname|queryname|close)",
@@ -534,16 +554,22 @@ namespace Smuxi.Frontend.Gnome
             "echo data",
             "exec command",
             "detach",
+            "list [search key]",
             };
-            
-            foreach (string line in help) { 
-                cd.FrontendManager.AddTextToChat(
-                    cd.Chat,
-                    String.Format("-!- {0}", line)
-                );
+
+            foreach (string line in help) {
+                builder = new MessageBuilder();
+                builder.AppendEventPrefix();
+                builder.AppendText(line);
+                chatView.AddMessage(builder.ToMessage());
             }
         }
-        
+
+        private void _CommandList(CommandModel cd)
+        {
+            Frontend.MainWindow.OpenFindGroupChatWindow(cd.Parameter);
+        }
+
         private void _CommandDetach(CommandModel cd)
         {
             Frontend.Quit();
@@ -584,62 +610,59 @@ namespace Smuxi.Frontend.Gnome
         {
             FrontendManager fm = cd.FrontendManager;
             if (cd.DataArray.Length >= 2) {
-                ChatModel currentChatModel = _Notebook.CurrentChatView.ChatModel;
-                string name;
-                if (cd.DataArray[1].ToLower() == "close") {
-                    cd.Chat.ProtocolManager.CloseChat(fm, cd.Chat);
+                var currentChat = ChatViewManager.CurrentChatView;
+                if (cd.Parameter.ToLower() == "close") {
+                    currentChat.Close();
                 } else {
-                    bool is_number = false;
-                    int pagecount = _Notebook.NPages;
                     try {
                         int number = Int32.Parse(cd.DataArray[1]);
-                        is_number = true;
-                        if (number <= pagecount) {
-                            _Notebook.CurrentPage = number - 1;
+                        if (number > ChatViewManager.Chats.Count) {
+                            return;
                         }
+                        ChatViewManager.CurrentChatNumber = number - 1;
+                        return;
                     } catch (FormatException) {
                     }
                     
-                    if (!is_number) {
-                        // seems to be query- or channelname
-                        // let's see if we find something
-                        ArrayList candidates = new ArrayList();
-                        for (int i = 0; i < pagecount; i++) {
-                            ChatView chatView = _Notebook.GetChat(i);
-                            ChatModel chatModel = chatView.ChatModel;
-                            
-                            if (chatModel.Name.ToLower() == cd.DataArray[1].ToLower()) {
-                                // name matches
-                                // first let's see if there is an exact match, if so, take it
-                                if ((chatModel.ChatType == currentChatModel.ChatType) &&
-                                    (chatModel.ProtocolManager == currentChatModel.ProtocolManager)) {
-                                    _Notebook.CurrentPage = i;
-                                    break;
-                                } else {
-                                    // there was no exact match
-                                    candidates.Add(i);
-                                }
-                            }
+                    // seems to be query- or channelname
+                    // let's see if we find something
+                    var seachKey = cd.Parameter.ToLower();
+                    var candidates = new List<ChatView>();
+                    foreach (var chatView in ChatViewManager.Chats) {
+
+                        if (chatView.Name.ToLower() != seachKey) {
+                            continue;
                         }
-                        
-                        if (candidates.Count > 0) {
-                            _Notebook.CurrentPage = (int)candidates[0];
+                        // name matches
+                        // let's see if there is an exact match, if so, take it
+                        if ((chatView.GetType() == currentChat.GetType()) &&
+                            (chatView.ProtocolManager == currentChat.ProtocolManager)) {
+                            candidates.Add(chatView);
+                            break;
+                        } else {
+                            // there was no exact match
+                            candidates.Add(chatView);
                         }
                     }
+
+                    if (candidates.Count == 0) {
+                        return;
+                    }
+                    ChatViewManager.CurrentChatView = candidates[0];
                 }
             }
         }
     
         private void _CommandClear(CommandModel cd)
         {
-            _Notebook.CurrentChatView.Clear();
+            ChatViewManager.CurrentChatView.Clear();
         }
 
         private void _NickCompletion()
         {
             // return if we don't support the current ChatView
-            if (!(_Notebook.CurrentChatView is GroupChatView) &&
-                !(_Notebook.CurrentChatView is PersonChatView)) {
+            if (!(ChatViewManager.CurrentChatView is GroupChatView) &&
+                !(ChatViewManager.CurrentChatView is PersonChatView)) {
                 return;
             }
 
@@ -690,10 +713,10 @@ namespace Smuxi.Frontend.Gnome
             bool partial_found = false;
             string nick = null;
 
-            ChatModel chat = _Notebook.CurrentChatView.ChatModel;
-            if (chat.ChatType == ChatType.Group) {
-                GroupChatModel cp = (GroupChatModel) chat;
-                if ((bool)Frontend.UserConfig["Interface/Entry/BashStyleCompletion"]) {
+            ChatView view = ChatViewManager.CurrentChatView;
+            if (view is GroupChatView) {
+                GroupChatView cp = (GroupChatView) view;
+                if (Settings.BashStyleCompletion) {
                     IList<string> result = cp.PersonLookupAll(word);
                     if (result == null || result.Count == 0) {
                         // no match
@@ -704,7 +727,7 @@ namespace Smuxi.Frontend.Gnome
                         string[] nickArray = new string[result.Count];
                         result.CopyTo(nickArray, 0);
                         string nicks = String.Join(" ", nickArray, 1, nickArray.Length - 1);
-                        _Notebook.CurrentChatView.AddMessage(
+                        ChatViewManager.CurrentChatView.AddMessage(
                             new MessageModel(String.Format("-!- {0}", nicks))
                         );
                         found = true;
@@ -719,17 +742,16 @@ namespace Smuxi.Frontend.Gnome
                      }
                 }
             } else {
-                PersonChatModel cp = (PersonChatModel) chat;
-                PersonModel person = cp.Person;
-
-                if (person.IdentityName.StartsWith(word, StringComparison.InvariantCultureIgnoreCase)) {
+                var personChat = (PersonChatView) ChatViewManager.CurrentChatView;
+                var personModel = personChat.PersonModel;
+                if (personModel.IdentityName.StartsWith(word,
+                        StringComparison.InvariantCultureIgnoreCase)) {
                     found = true;
-                    nick = cp.Person.IdentityName;
+                    nick = personModel.IdentityName;
                 }
             }
 
-            string completionChar = (string)
-                Frontend.UserConfig["Interface/Entry/CompletionCharacter"];
+            string completionChar = Settings.CompletionCharacter;
             // add leading @ back and supress completion character
             if (leadingAt) {
                 word = String.Format("@{0}", word);
@@ -802,6 +824,8 @@ namespace Smuxi.Frontend.Gnome
                 ModifyText(Gtk.StateType.Normal, theme.ForegroundColor.Value);
             }
             ModifyFont(theme.FontDescription);
+
+            Settings.ApplyConfig(config);
         }
 
         private void InitCommandManager()
diff --git a/src/Frontend-GNOME/FindGroupChatDialog.cs b/src/Frontend-GNOME/FindGroupChatDialog.cs
index 83519bd..8784819 100644
--- a/src/Frontend-GNOME/FindGroupChatDialog.cs
+++ b/src/Frontend-GNOME/FindGroupChatDialog.cs
@@ -51,6 +51,18 @@ namespace Smuxi.Frontend.Gnome
             }
         }
 
+        public Gtk.Entry NameEntry {
+            get {
+                return f_NameEntry;
+            }
+        }
+
+        public Gtk.Button FindButton {
+            get {
+                return f_FindButton;
+            }
+        }
+
         public FindGroupChatDialog(Gtk.Window parent, IProtocolManager protocolManager) :
                               base(null, parent, Gtk.DialogFlags.DestroyWithParent)
         {
@@ -93,7 +105,8 @@ namespace Smuxi.Frontend.Gnome
             
             try {
                 string nameFilter = f_NameEntry.Text.Trim();
-                if (String.IsNullOrEmpty(nameFilter)) {
+                if (!(Frontend.EngineVersion >= new Version("0.8.1")) &&
+                    String.IsNullOrEmpty(nameFilter)) {
                     Gtk.MessageDialog md = new Gtk.MessageDialog(
                         this,
                         Gtk.DialogFlags.Modal,
@@ -150,6 +163,7 @@ namespace Smuxi.Frontend.Gnome
                         });
                     }
                 }));
+                f_FindThread.IsBackground = true;
                 f_FindThread.Start();
             } catch (Exception ex) {
                 Frontend.ShowException(ex);
diff --git a/src/Frontend-GNOME/Frontend.cs b/src/Frontend-GNOME/Frontend.cs
index 717640b..fc8647f 100644
--- a/src/Frontend-GNOME/Frontend.cs
+++ b/src/Frontend-GNOME/Frontend.cs
@@ -1,13 +1,7 @@
 /*
- * $Id$
- * $URL$
- * $Rev$
- * $Author$
- * $Date$
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2008 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -28,8 +22,10 @@
 
 using System;
 using System.IO;
+using System.Linq;
 using System.Threading;
 using System.Reflection;
+using SysDiag = System.Diagnostics;
 using Smuxi.Engine;
 using Smuxi.Common;
 
@@ -63,6 +59,10 @@ namespace Smuxi.Frontend.Gnome
         private static bool               _InCrashHandler;
         private static bool               _InReconnectHandler;
 
+        public static string IconName { get; private set; }
+        public static bool HasSystemIconTheme { get; private set; }
+        public static bool HadSession { get; private set; }
+
         public static event EventHandler  SessionPropertyChanged;
 
         public static string Name {
@@ -117,6 +117,10 @@ namespace Smuxi.Frontend.Gnome
             set {
                 _Session = value;
 
+                if (value != null) {
+                    HadSession = true;
+                }
+
                 if (SessionPropertyChanged != null) {
                     SessionPropertyChanged(value, EventArgs.Empty);
                 }
@@ -125,7 +129,7 @@ namespace Smuxi.Frontend.Gnome
 
         public static bool IsLocalEngine {
             get {
-                return _Session == _LocalSession;
+                return _LocalSession != null && _Session == _LocalSession;
             }
         }
 
@@ -155,7 +159,16 @@ namespace Smuxi.Frontend.Gnome
                 return _FrontendConfig;
             }
         }
-        
+
+        public static bool UseLowBandwidthMode {
+            get {
+                if (_FrontendConfig == null) {
+                    return false;
+                }
+                return (bool) _FrontendConfig["UseLowBandwidthMode"];
+            }
+        }
+
         public static void Init(string[] args)
         {
             System.Threading.Thread.CurrentThread.Name = "Main";
@@ -171,46 +184,16 @@ namespace Smuxi.Frontend.Gnome
 #if LOG4NET
             _Logger.Info(_VersionString + " starting");
 #endif
-            
-#if GTK_SHARP_2_8 || GTK_SHARP_2_10
-            if (!GLib.Thread.Supported) {
-                GLib.Thread.Init();
-            }
-            _UIThreadID = System.Threading.Thread.CurrentThread.ManagedThreadId;
-#else
-            // with GTK# 2.8 we can do this better, see above
-            // GTK# 2.7.1 for MS .NET doesn't support that though.
-            if (Type.GetType("Mono.Runtime") == null) {
-                // when we don't run on Mono, we need to initialize glib ourself
-                GLib.Thread.Init();
-            }
-#endif
 
-            string appDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
-            string localeDir = Path.Combine(appDir, "locale");
-            if (!Directory.Exists(localeDir)) {
-                localeDir = Path.Combine(Defines.InstallPrefix, "share");
-                localeDir = Path.Combine(localeDir, "locale");
-            }
+            InitGtk(args);
 
-            LibraryCatalog.Init("smuxi-frontend-gnome", localeDir);
-#if LOG4NET
-            _Logger.Debug("Using locale data from: " + localeDir);
-#endif
-            
-            Gtk.Application.Init(Name, ref args);
-#if GTK_SHARP_2_10
-            GLib.ExceptionManager.UnhandledException += _OnUnhandledException;
-#endif
             //_SplashScreenWindow = new SplashScreenWindow();
 
             _FrontendConfig = new FrontendConfig(UIName);
             // loading and setting defaults
             _FrontendConfig.Load();
             _FrontendConfig.Save();
-            
-            Gtk.Window.DefaultIcon = new Gdk.Pixbuf(null, "icon.svg");
- 
+
             _MainWindow = new MainWindow();
 
             if (((string[]) FrontendConfig["Engines/Engines"]).Length == 0) {
@@ -253,20 +236,22 @@ namespace Smuxi.Frontend.Gnome
                 // HACK: SessionManager.Register() is not used for local engines
                 _LocalSession.RegisterFrontendUI(_MainWindow.UI);
             }
+
+            SyncConfig();
+
             _FrontendManager = _Session.GetFrontendManager(_MainWindow.UI);
             _FrontendManager.Sync();
-            
+
             // MS .NET doesn't like this with Remoting?
             if (Type.GetType("Mono.Runtime") != null) {
                 // when are running on Mono, all should be good
                 if (_UserConfig.IsCaching) {
                     // when our UserConfig is cached, we need to invalidate the cache
-                    _FrontendManager.ConfigChangedDelegate = new SimpleDelegate(_UserConfig.ClearCache);
+                    // DISABLED: see FrontendManager._OnConfigChanged
+                    //_FrontendManager.ConfigChangedDelegate = SyncConfig;
                 }
             }
-            
-            ApplyConfig(_UserConfig);
-            
+
             _MainWindow.ShowAll();
             // make sure entry got attention :-P
             _MainWindow.Entry.HasFocus = true;
@@ -292,6 +277,9 @@ namespace Smuxi.Frontend.Gnome
                 _FrontendManagerCheckerQueue.Queue(delegate {
                     // keep looping as long as the checker returns true
                     while (CheckFrontendManagerStatus()) {
+                        // FIXME: bail out somehow when we lost the connection
+                        // without an exception in the meantime
+
                         // only check once per minute
                         Thread.Sleep(60 * 1000);
                     }
@@ -302,45 +290,116 @@ namespace Smuxi.Frontend.Gnome
 #endif
                 });
             }
+            MainWindow.ChatViewManager.IsSensitive = true;
         }
         
         public static void DisconnectEngineFromGUI()
         {
-            Trace.Call();
+            DisconnectEngineFromGUI(true);
+        }
 
-            try {
-                // sync tab positions
-                if (!IsLocalEngine) {
-                    _MainWindow.Notebook.SyncPagePositions();
-                }
+        public static void DisconnectEngineFromGUI(bool cleanly)
+        {
+            Trace.Call(cleanly);
+
+            MainWindow.ChatViewManager.IsSensitive = false;
+            if (cleanly) {
+                try {
+                    // sync tab positions
+                    if (!IsLocalEngine && !UseLowBandwidthMode) {
+                        _MainWindow.Notebook.SyncPagePositions();
+                    }
 
-                if (_FrontendManager != null) {
-                    _FrontendManager.IsFrontendDisconnecting = true;
+                    if (_FrontendManager != null) {
+                        _FrontendManager.IsFrontendDisconnecting = true;
+                    }
+                    if (_Session != null) {
+                        _Session.DeregisterFrontendUI(_MainWindow.UI);
+                    }
+                } catch (System.Net.Sockets.SocketException) {
+                    // ignore as the connection is maybe already broken
+                } catch (System.Runtime.Remoting.RemotingException) {
+                    // ignore as the connection is maybe already broken
                 }
-                _Session.DeregisterFrontendUI(_MainWindow.UI);
-            } catch (System.Net.Sockets.SocketException ex) {
-                // ignore as the connection is maybe already broken
-            } catch (System.Runtime.Remoting.RemotingException ex) {
-                // ignore as the connection is maybe already broken
-            }
-            _MainWindow.Hide();
-            _MainWindow.Notebook.RemoveAllPages();
+            }
+            if (_FrontendManagerCheckerQueue != null) {
+                _FrontendManagerCheckerQueue.Dispose();
+            }
+            _MainWindow.ChatViewManager.Clear();
+            _MainWindow.UpdateProgressBar();
             // make sure no stray SSH tunnel leaves behind
             _MainWindow.EngineManager.Disconnect();
-            
+            _MainWindow.NetworkStatus = null;
+            _MainWindow.Status = _("Disconnected from engine.");
+
             _FrontendManager = null;
             Session = null;
         }
 
         public static void ReconnectEngineToGUI()
         {
-            Trace.Call();
+            ReconnectEngineToGUI(true);
+        }
+
+        public static void ReconnectEngineToGUI(bool cleanly)
+        {
+            Trace.Call(cleanly);
+
+            if (_InReconnectHandler) {
+#if LOG4NET
+                _Logger.Debug("ReconnectEngineToGUI(): already in reconnect " +
+                              "handler, ignoring reconnect...");
+#endif
+                return;
+            }
 
-            Frontend.DisconnectEngineFromGUI();
-            _MainWindow.EngineManager.Reconnect();
-            Session = _MainWindow.EngineManager.Session;
-            _UserConfig = _MainWindow.EngineManager.UserConfig;
-            Frontend.ConnectEngineToGUI();
+            _InReconnectHandler = true;
+            var disconnectedEvent = new AutoResetEvent(false);
+            ThreadPool.QueueUserWorkItem(delegate {
+                try {
+                    // delay the disconnect to give the reconnect some extra
+                    // time as NetworkManager is not accurate about when the
+                    // network is really ready
+                    GLib.Timeout.Add(5 * 1000, delegate {
+                        Frontend.DisconnectEngineFromGUI(cleanly);
+                        disconnectedEvent.Set();
+                        return false;
+                    });
+
+                    var successful = false;
+                    var attempt = 1;
+                    while (!successful) {
+                        Gtk.Application.Invoke(delegate {
+                            MainWindow.NetworkStatus = null;
+                            MainWindow.Status = String.Format(
+                                _("Reconnecting to engine... (attempt {0})"),
+                                attempt++
+                            );
+                        });
+                        try {
+                            disconnectedEvent.WaitOne();
+                            _MainWindow.EngineManager.Reconnect();
+                            successful = true;
+                        } catch (Exception ex) {
+#if LOG4NET
+                            _Logger.Debug("ReconnectEngineToGUI(): Exception", ex);
+#endif
+                            disconnectedEvent.Set();
+                            Thread.Sleep(30 * 1000);
+                        }
+                    }
+                    Session = _MainWindow.EngineManager.Session;
+                    _UserConfig = _MainWindow.EngineManager.UserConfig;
+
+                    Gtk.Application.Invoke(delegate {
+                        Frontend.ConnectEngineToGUI();
+                    });
+                } catch (Exception ex) {
+                    Frontend.ShowException(ex);
+                } finally {
+                    _InReconnectHandler = false;
+                }
+            });
         }
 
         public static void Quit()
@@ -368,6 +427,21 @@ namespace Smuxi.Frontend.Gnome
             }
 
             if (_FrontendManager != null) {
+                if (IsLocalEngine) {
+                    try {
+                        var cmd = new CommandModel(
+                            _FrontendManager,
+                            MainWindow.ChatViewManager.CurrentChatView.ChatModel,
+                            null
+                        );
+                        Session.CommandShutdown(cmd);
+                    } catch (Exception ex) {
+#if LOG4NET
+                        _Logger.Error("Quit(): Exception", ex);
+#endif
+                    }
+                }
+
                 DisconnectEngineFromGUI();
             }
             
@@ -375,8 +449,8 @@ namespace Smuxi.Frontend.Gnome
             
             Environment.Exit(0);
         }
-        
-        private static bool IsGuiThread()
+
+        public static bool IsGuiThread()
         {
             return System.Threading.Thread.CurrentThread.ManagedThreadId == _UIThreadID;
         }
@@ -462,47 +536,8 @@ namespace Smuxi.Frontend.Gnome
                     // one reconnect is good enough and a crash we won't survive
                     return;
                 }
-                _InReconnectHandler = true;
 
-                Gtk.MessageDialog md = new Gtk.MessageDialog(parent,
-                    Gtk.DialogFlags.Modal, Gtk.MessageType.Error,
-                    Gtk.ButtonsType.OkCancel, _("The frontend has lost the connection to the server.\nDo you want to reconnect now?"));
-                Gtk.ResponseType res = (Gtk.ResponseType) md.Run();
-                md.Destroy();
-                
-                if (res == Gtk.ResponseType.Ok) {
-                    while (true) {
-                        try {
-                            Frontend.ReconnectEngineToGUI();
-                            // yay, we made it
-                            _InReconnectHandler = false;
-                            break;
-                        } catch (Exception e) {
-#if LOG4NET
-                             _Logger.Error("ShowException(): Reconnect failed, exception:", e);
-#endif
-                            var msg = _("Reconnecting to the server has failed.\nDo you want to try again?");
-                            // the parent window is hidden (MainWindow) at this
-                            // point thus modal doesn't make sense here
-                            md = new Gtk.MessageDialog(parent,
-                                Gtk.DialogFlags.DestroyWithParent,
-                                Gtk.MessageType.Error,
-                                Gtk.ButtonsType.OkCancel, msg);
-                            md.SetPosition(Gtk.WindowPosition.CenterAlways);
-                            res = (Gtk.ResponseType) md.Run();
-                            md.Destroy();
-
-                            if (res != Gtk.ResponseType.Ok) {
-                                // give up
-                                Quit();
-                                return;
-                            }
-                        }
-                    }
-                    return;
-                }
-                
-                Quit();
+                Frontend.ReconnectEngineToGUI();
                 return;
             }
 
@@ -516,7 +551,14 @@ namespace Smuxi.Frontend.Gnome
             CrashDialog cd = new CrashDialog(parent, ex);
             cd.Run();
             cd.Destroy();
-            
+
+            if (SysDiag.Debugger.IsAttached) {
+                // allow the debugger to examine the situation
+                //SysDiag.Debugger.Break();
+                // HACK: Break() would be nicer but crashes the runtime
+                throw ex;
+            }
+
             Quit();
         }
         
@@ -535,7 +577,53 @@ namespace Smuxi.Frontend.Gnome
             diag.Run();
             diag.Destroy();
         }
-        
+
+        public static bool ShowReconnectDialog(Gtk.Window parent)
+        {
+            Trace.Call(parent);
+
+            Gtk.MessageDialog md = new Gtk.MessageDialog(parent,
+                Gtk.DialogFlags.Modal, Gtk.MessageType.Error,
+                Gtk.ButtonsType.OkCancel, _("The frontend has lost the connection to the server.\nDo you want to reconnect now?"));
+            Gtk.ResponseType res = (Gtk.ResponseType) md.Run();
+            md.Destroy();
+
+            if (res != Gtk.ResponseType.Ok) {
+                Quit();
+                return false;
+            }
+
+            while (true) {
+                try {
+                    Frontend.ReconnectEngineToGUI();
+                    // yay, we made it
+                    _InReconnectHandler = false;
+                    break;
+                } catch (Exception e) {
+#if LOG4NET
+                     _Logger.Error("ShowReconnectDialog(): Reconnect failed, exception:", e);
+#endif
+                    var msg = _("Reconnecting to the server has failed.\nDo you want to try again?");
+                    // the parent window is hidden (MainWindow) at this
+                    // point thus modal doesn't make sense here
+                    md = new Gtk.MessageDialog(parent,
+                        Gtk.DialogFlags.DestroyWithParent,
+                        Gtk.MessageType.Error,
+                        Gtk.ButtonsType.OkCancel, msg);
+                    md.SetPosition(Gtk.WindowPosition.CenterAlways);
+                    res = (Gtk.ResponseType) md.Run();
+                    md.Destroy();
+
+                    if (res != Gtk.ResponseType.Ok) {
+                        // give up
+                        Quit();
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+
         public static void ApplyConfig(UserConfig userConfig)
         {
             Trace.Call(userConfig);
@@ -547,16 +635,52 @@ namespace Smuxi.Frontend.Gnome
             _MainWindow.ApplyConfig(userConfig);
         }
 
+        public static Gdk.Pixbuf LoadIcon(string iconName, int size,
+                                          string resourceName)
+        {
+            Trace.Call(iconName, size, resourceName);
+
+            if (iconName == null) {
+                throw new ArgumentNullException("iconName");
+            }
+            if (resourceName == null) {
+                throw new ArgumentNullException("resourceName");
+            }
+
+            try {
+                // we use this method from type initializers so it has to deal
+                // with GDK/GTK thread locking
+                Gdk.Threads.Enter();
+                var theme = Gtk.IconTheme.Default;
+                if (!theme.HasIcon(iconName) ||
+                    !theme.GetIconSizes(iconName).Contains(size)) {
+                    Gtk.IconTheme.AddBuiltinIcon(
+                        iconName,
+                        size,
+                        new Gdk.Pixbuf(null, resourceName, size, size)
+                    );
+#if LOG4NET
+                    _Logger.DebugFormat(
+                        "LoadIcon(): Added '{0}' to built-in icon theme",
+                        resourceName
+                    );
+#endif
+                }
+                return theme.LoadIcon(iconName, size,
+                                      Gtk.IconLookupFlags.UseBuiltin);
+            } finally {
+                Gdk.Threads.Leave();
+            }
+        }
+
 #if GTK_SHARP_2_10
         private static void _OnUnhandledException(GLib.UnhandledExceptionArgs e)
         {
-            Trace.Call(e);
+            Trace.CallFull(e);
             
             lock (_UnhandledExceptionSyncRoot) {
                 if (e.ExceptionObject is Exception) {
                     ShowException((Exception) e.ExceptionObject);
-                    
-                    Quit();
                 }
             }
         }
@@ -597,7 +721,121 @@ namespace Smuxi.Frontend.Gnome
 
             return false;
         }
-        
+
+        private static void InitGtk(string[] args)
+        {
+            if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
+                InitGtkPathWin();
+            }
+
+#if GTK_SHARP_2_8 || GTK_SHARP_2_10
+            if (!GLib.Thread.Supported) {
+                GLib.Thread.Init();
+            }
+#else
+            // with GTK# 2.8 we can do this better, see above
+            // GTK# 2.7.1 for MS .NET doesn't support that though.
+            if (Type.GetType("Mono.Runtime") == null) {
+                // when we don't run on Mono, we need to initialize glib ourself
+                GLib.Thread.Init();
+            }
+#endif
+            _UIThreadID = System.Threading.Thread.CurrentThread.ManagedThreadId;
+
+            string appDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
+            string localeDir = Path.Combine(appDir, "locale");
+            if (!Directory.Exists(localeDir)) {
+                localeDir = Path.Combine(Defines.InstallPrefix, "share");
+                localeDir = Path.Combine(localeDir, "locale");
+            }
+
+            LibraryCatalog.Init("smuxi-frontend-gnome", localeDir);
+#if LOG4NET
+            _Logger.Debug("InitGtk(): Using locale data from: " + localeDir);
+#endif
+            Gtk.Application.Init(Name, ref args);
+#if GTK_SHARP_2_10
+            GLib.ExceptionManager.UnhandledException += _OnUnhandledException;
+#endif
+
+            IconName = "smuxi-frontend-gnome";
+            var iconPath = Path.Combine(Defines.InstallPrefix, "share");
+            iconPath = Path.Combine(iconPath, "icons");
+            var theme = Gtk.IconTheme.Default;
+            var iconInfo = theme.LookupIcon(IconName, -1, 0);
+            HasSystemIconTheme = iconInfo != null &&
+                                 iconInfo.Filename != null &&
+                                 iconInfo.Filename.StartsWith(iconPath);
+#if LOG4NET
+            _Logger.DebugFormat("InitGtk(): Using {0} icon theme",
+                                HasSystemIconTheme ? "system" : "built-in");
+#endif
+
+            if (HasSystemIconTheme) {
+                Gtk.Window.DefaultIconName = "smuxi-frontend-gnome";
+            } else {
+                Gtk.Window.DefaultIcon = Frontend.LoadIcon(
+                    "smuxi-frontend-gnome", 256, "icon_256x256.png"
+                );
+            }
+        }
+
+        private static void InitGtkPathWin()
+        {
+            // HACK: Force GTK# to use the right GTK+ install as the PATH
+            // environment variable might contain other GTK+ installs
+            var installPath = (string) Microsoft.Win32.Registry.GetValue(
+                "HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\GtkSharp\\InstallFolder",
+                "", null
+            );
+            if (installPath == null) {
+#if LOG4NET
+                _Logger.Error("InitGtkPathWin(): couldn't obtain GTK# installation folder from registry. GTK# is probably incorrectly installed!");
+                return;
+#endif
+            }
+
+            var binPath = Path.Combine(installPath, "bin");
+            var currentPath = Environment.GetEnvironmentVariable("PATH");
+            var newPath = String.Format("{0}{1}{2}", binPath, Path.PathSeparator, currentPath);
+#if LOG4NET
+            _Logger.Debug("InitGtkPathWin(): current PATH: " + currentPath);
+            _Logger.Debug("InitGtkPathWin(): new PATH: " + newPath);
+#endif
+            Environment.SetEnvironmentVariable("PATH", newPath);
+        }
+
+        static void SyncConfig()
+        {
+            Trace.Call();
+
+            if (EngineVersion >= new Version("0.8.1.1")) {
+                var config = UserConfig;
+                ThreadPool.QueueUserWorkItem(delegate {
+                    try {
+                        config.SyncCache();
+                    } catch (Exception ex) {
+#if LOG4NET
+                        _Logger.Error("SyncConfig(): " +
+                                      "Exception during config sync", ex);
+#endif
+                    } finally {
+                        Gtk.Application.Invoke(delegate {
+                            ApplyConfig(config);
+                        });
+                    }
+                });
+            } else {
+                if (!IsGuiThread()) {
+                    Gtk.Application.Invoke(delegate {
+                        SyncConfig();
+                    });
+                    return;
+                }
+                ApplyConfig(UserConfig);
+            }
+        }
+
         private static string _(string msg)
         {
             return Mono.Unix.Catalog.GetString(msg);
diff --git a/src/Frontend-GNOME/GnomeUI.cs b/src/Frontend-GNOME/GnomeUI.cs
index 339e103..2101f74 100644
--- a/src/Frontend-GNOME/GnomeUI.cs
+++ b/src/Frontend-GNOME/GnomeUI.cs
@@ -1,7 +1,7 @@
 /*
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2010 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -55,17 +55,12 @@ namespace Smuxi.Frontend.Gnome
         public void AddChat(ChatModel chat)
         {
             TraceRemotingCall(chat);
-            
-            MethodBase mb = Trace.GetMethodBase();
-            Gtk.Application.Invoke(delegate {
-                TraceRemotingCall(mb, chat);
 
-                try {
-                    _ChatViewManager.AddChat(chat);
-                } catch (Exception ex) {
-                    Frontend.ShowException(ex);
-                }
-            });
+            try {
+                _ChatViewManager.AddChat(chat);
+            } catch (Exception ex) {
+                Frontend.ShowException(ex);
+            }
         }
         
         private void _AddMessageToChat(ChatModel chatModel, MessageModel msg)
@@ -89,7 +84,7 @@ namespace Smuxi.Frontend.Gnome
             start = DateTime.UtcNow;
             chatView.AddMessage(msg);
             stop = DateTime.UtcNow;
-#if LOG4NET
+#if LOG4NET && MSG_DEBUG
             _Logger.Debug(
                 String.Format(
                     "_AddMessageToChat(): chatView.AddMessage() took: {0:0.00} ms",
@@ -167,54 +162,11 @@ namespace Smuxi.Frontend.Gnome
         {
             TraceRemotingCall(chatModel);
 
-            MethodBase mb = Trace.GetMethodBase();
-            Gtk.Application.Invoke(delegate {
-                TraceRemotingCall(mb, chatModel);
-
-                try {
-                    ChatView chatView = _ChatViewManager.GetChat(chatModel);
-                    if (chatView == null) {
-#if LOG4NET
-                        _Logger.Fatal(
-                            String.Format(
-                                "SyncChat(): " +
-                                "_ChatViewManager.GetChat(chatModel) " +
-                                "chatModel.Name: {0} returned null!",
-                                chatModel.Name
-                            )
-                        );
-#endif
-                        return;
-                    }
-
-#if LOG4NET
-                    DateTime syncStart = DateTime.UtcNow;
-#endif
-                    chatView.Sync();
-#if LOG4NET
-                    DateTime syncStop = DateTime.UtcNow;
-                    double duration = syncStop.Subtract(syncStart).TotalMilliseconds;
-                    _Logger.Debug("SyncChat() done, syncing took: " + Math.Round(duration) + " ms");
-#endif
-
-                    // maybe a BUG here? should be tell the FrontendManager before we sync?
-                    Frontend.FrontendManager.AddSyncedChat(chatModel);
-
-                    // BUG: doesn't work?!?
-                    chatView.ScrollToEnd();
-
-                    /*
-                    // this hack is bad for local engine users, and doesn't really
-                    // make things better for remote engine users, so it stays disabled for now
-                    // BUG: clearing highlight here is a bad idea, highlight in
-                    // person chats for the first message go lost here!
-                    // no better way currently to fix this, see trac bug #50
-                    chatView.HasHighlight = false;
-                    */
-                } catch (Exception ex) {
-                    Frontend.ShowException(ex);
-                }
-            });
+            try {
+                _ChatViewManager.SyncChat(chatModel);
+            } catch (Exception ex) {
+                Frontend.ShowException(ex);
+            }
         }
         
         public void AddPersonToGroupChat(GroupChatModel groupChat, PersonModel person)
@@ -346,7 +298,7 @@ namespace Smuxi.Frontend.Gnome
                 TraceRemotingCall(mb, status);
 
                 try {
-                    Frontend.MainWindow.NetworkStatusbar.Push(0, status);
+                    Frontend.MainWindow.NetworkStatus = status;
                     Frontend.MainWindow.UpdateTitle(null, status);
                 } catch (Exception ex) {
                     Frontend.ShowException(ex);
@@ -363,7 +315,7 @@ namespace Smuxi.Frontend.Gnome
                 TraceRemotingCall(mb, status);
 
                 try {
-                    Frontend.MainWindow.Statusbar.Push(0, status);
+                    Frontend.MainWindow.Status = status;
                 } catch (Exception ex) {
                     Frontend.ShowException(ex);
                 }
diff --git a/src/Frontend-GNOME/IndicateManager.cs b/src/Frontend-GNOME/IndicateManager.cs
index ba452cd..3ea1544 100644
--- a/src/Frontend-GNOME/IndicateManager.cs
+++ b/src/Frontend-GNOME/IndicateManager.cs
@@ -1,6 +1,6 @@
 // Smuxi - Smart MUltipleXed Irc
 // 
-// Copyright (c) 2010 Mirco Bauer <meebey at meebey.net>
+// Copyright (c) 2010-2011 Mirco Bauer <meebey at meebey.net>
 // 
 // Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
 // 
@@ -43,6 +43,8 @@ namespace Smuxi.Frontend.Gnome
         ChatViewManager ChatViewManager { get; set; }
         Dictionary<ChatView, Indicator> Indicators { get; set; }
         Dictionary<ChatView, MessageTextViewMessageHighlightedEventHandler> HighlightEventHandlers { get; set; }
+        bool IsInitialized { get; set; }
+        bool IsEnabled { get; set; }
 
         static IndicateManager()
         {
@@ -73,7 +75,13 @@ namespace Smuxi.Frontend.Gnome
                 <ChatView,
                  MessageTextViewMessageHighlightedEventHandler>();
 
-            Init();
+            try {
+                Init();
+            } catch (Exception ex) {
+#if LOG4NET
+                Logger.Error("IndicateManager(): initialization failed: ", ex);
+#endif
+            }
         }
         
         public void Dispose()
@@ -98,10 +106,18 @@ namespace Smuxi.Frontend.Gnome
                 throw new ArgumentNullException("userConfig");
             }
 
+            if (!IsInitialized) {
+                return;
+            }
+
             if ((bool) userConfig["Interface/Notification/MessagingMenuEnabled"]) {
                 Server.Show();
+                IsEnabled = true;
+                // hide the main window instead of closing it
+                MainWindow.NotificationAreaIconMode = NotificationAreaIconMode.Closed;
             } else {
                 Server.Hide();
+                IsEnabled = false;
             }
         }
 
@@ -125,9 +141,24 @@ namespace Smuxi.Frontend.Gnome
             }
             */
 
-            var desktopFile = Path.Combine(Defines.InstallPrefix, "share");
-            desktopFile = Path.Combine(desktopFile, "applications");
-            desktopFile = Path.Combine(desktopFile, "smuxi-frontend-gnome.desktop");
+            var partialPath = "share";
+            partialPath = Path.Combine(partialPath, "applications");
+            partialPath = Path.Combine(partialPath, "smuxi-frontend-gnome.desktop");
+
+            var insDesktopFile = Path.Combine(Defines.InstallPrefix, partialPath);
+            var sysDesktopFile = Path.Combine("/usr", partialPath);
+            string desktopFile = null;
+            if (File.Exists(insDesktopFile)) {
+                desktopFile = insDesktopFile;
+            } else if (File.Exists(sysDesktopFile)) {
+                desktopFile = sysDesktopFile;
+            } else {
+#if LOG4NET
+                Logger.Error("Init(): smuxi-frontend-gnome.desktop could not " +
+                             " be found, thus no messaging menu :/");
+#endif
+                return;
+            }
 
             Server.SetType("message.im");
             Server.DesktopFile(desktopFile);
@@ -138,21 +169,33 @@ namespace Smuxi.Frontend.Gnome
 
             ChatViewManager.ChatAdded   += OnChatViewManagerChatAdded;
             ChatViewManager.ChatRemoved += OnChatViewManagerChatRemoved;
+
+            IsInitialized = true;
         }
 
         void OnMainWindowFocusInEvent(object sender, Gtk.FocusInEventArgs e)
         {
-            Trace.Call(sender, e);
+            if (MainWindow.Notebook.IsBrowseModeEnabled) {
+                return;
+            }
 
             var currentChatView = MainWindow.Notebook.CurrentChatView;
+            if (currentChatView == null) {
+                return;
+            }
             DisposeIndicator(currentChatView);
         }
 
         void OnMainWindowNotebookSwitchPage(object sender, Gtk.SwitchPageArgs e)
         {
-            Trace.Call(sender, e);
+            if (MainWindow.Notebook.IsBrowseModeEnabled) {
+                return;
+            }
 
             var currentChatView = MainWindow.Notebook.CurrentChatView;
+            if (currentChatView == null) {
+                return;
+            }
             DisposeIndicator(currentChatView);
         }
 
@@ -160,9 +203,7 @@ namespace Smuxi.Frontend.Gnome
         {
             Trace.Call(sender, e);
 
-            MainWindow.PresentWithTime(
-                (uint) (DateTime.UtcNow - UnixEpoch).TotalSeconds
-            );
+            MainWindow.PresentWithTime(e.Timestamp);
         }
 
         void OnChatViewManagerChatAdded(object sender, ChatViewManagerChatAddedEventArgs e)
@@ -192,15 +233,18 @@ namespace Smuxi.Frontend.Gnome
             }
 
             e.ChatView.OutputMessageTextView.MessageHighlighted -= handler;
+
+            // close possibly active indicator
+            DisposeIndicator(e.ChatView);
         }
 
         void OnChatViewMessageHighlighted(object sender,
                                           MessageTextViewMessageHighlightedEventArgs e,
                                           ChatView chatView)
         {
-            Trace.Call(sender, e, chatView);
-
-            if (MainWindow.HasToplevelFocus) {
+            if (!IsEnabled ||
+                e.Message.TimeStamp <= chatView.SyncedLastSeenHighlight ||
+                MainWindow.HasToplevelFocus) {
                 return;
             }
 
@@ -241,9 +285,7 @@ namespace Smuxi.Frontend.Gnome
             indicator.SetPropertyBool("draw-attention", true);
             indicator.UserDisplay += delegate {
                 try {
-                    MainWindow.PresentWithTime(
-                        (uint) (DateTime.UtcNow - UnixEpoch).TotalSeconds
-                    );
+                    MainWindow.Present();
                     MainWindow.Notebook.CurrentChatView = chatView;
                     DisposeIndicator(chatView);
                 } catch (Exception ex) {
@@ -267,15 +309,25 @@ namespace Smuxi.Frontend.Gnome
 
         void DisposeIndicator(ChatView chatView)
         {
-            Trace.Call(chatView);
-
             Indicator indicator;
             if (!Indicators.TryGetValue(chatView, out indicator)) {
                 return;
             }
+#if LOG4NET
+            Logger.Debug("DisposeIndicator(): disposing indicator for: " +
+                         chatView.Name);
+#endif
 
-            indicator.Hide();
-            Indicators.Remove(chatView);
+            try {
+                indicator.Hide();
+            } catch (Exception ex) {
+#if LOG4NET
+                Logger.Error("DisposeIndicator(): " +
+                             "indicator.Hide() thew exception", ex);
+#endif
+            } finally {
+                Indicators.Remove(chatView);
+            }
         }
 
         string GetNick(MessageModel msg)
diff --git a/src/Frontend-GNOME/LinkTag.cs b/src/Frontend-GNOME/LinkTag.cs
new file mode 100644
index 0000000..efcd5d6
--- /dev/null
+++ b/src/Frontend-GNOME/LinkTag.cs
@@ -0,0 +1,38 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2011 Mirco Bauer <meebey at meebey.net>
+// 
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+// 
+// 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
+
+using System;
+
+namespace Smuxi.Frontend.Gnome
+{
+    public class LinkTag : Gtk.TextTag
+    {
+        public Uri Link { get; set; }
+
+        public LinkTag(Uri link) : base(null)
+        {
+            if (link == null) {
+                throw new ArgumentNullException("link");
+            }
+
+            Link = link;
+        }
+    }
+}
diff --git a/src/Frontend-GNOME/MainWindow.cs b/src/Frontend-GNOME/MainWindow.cs
index dce70f3..1313867 100644
--- a/src/Frontend-GNOME/MainWindow.cs
+++ b/src/Frontend-GNOME/MainWindow.cs
@@ -1,13 +1,7 @@
 /*
- * $Id$
- * $URL$
- * $Rev$
- * $Author$
- * $Date$
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2008 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -53,8 +47,10 @@ namespace Smuxi.Frontend.Gnome
         private ChatViewManager  _ChatViewManager;
         private IFrontendUI      _UI;
         private EngineManager    _EngineManager;
+        private Gtk.ImageMenuItem _OpenChatMenuItem;
         private Gtk.MenuItem     _CloseChatMenuItem;
         private Gtk.ImageMenuItem _OpenLogChatMenuItem;
+        private Gtk.ImageMenuItem _FindGroupChatMenuItem;
         private NotificationAreaIconMode _NotificationAreaIconMode;
 #if GTK_SHARP_2_10
         private StatusIconManager _StatusIconManager;
@@ -65,10 +61,19 @@ namespace Smuxi.Frontend.Gnome
 #if NOTIFY_SHARP
         private NotifyManager    _NotifyManager;
 #endif
+#if IPC_DBUS
+        private NetworkManager   _NetworkManager;
+#endif
         private bool             _IsMinimized;
         private bool             _IsMaximized;
         private bool             _IsFullscreen;
-        
+
+        public Gtk.MenuBar MenuBar {
+            get {
+                return _MenuBar;
+            }
+        }
+
         public bool ShowMenuBar {
             get {
                 return _MenuBar.Visible;
@@ -108,17 +113,25 @@ namespace Smuxi.Frontend.Gnome
             }
         }
         
-        public new Gtk.Statusbar NetworkStatusbar {
-            get {
-                return _NetworkStatusbar;
+        public string NetworkStatus {
+            set {
+                if (value == null) {
+                    value = String.Empty;
+                }
+                _NetworkStatusbar.Pop(0);
+                _NetworkStatusbar.Push(0, value);
             }
         } 
 
-        public new Gtk.Statusbar Statusbar {
-            get {
-                return _Statusbar;
+        public string Status {
+            set {
+                if (value == null) {
+                    value = String.Empty;
+                }
+                _Statusbar.Pop(0);
+                _Statusbar.Push(0, value);
             }
-        } 
+        }
 
         public Gtk.ProgressBar ProgressBar {
             get {
@@ -158,6 +171,15 @@ namespace Smuxi.Frontend.Gnome
             }
         }
 
+        public NotificationAreaIconMode NotificationAreaIconMode {
+            get {
+                return _NotificationAreaIconMode;
+            }
+            set {
+                _NotificationAreaIconMode = value;
+            }
+        }
+
         public EventHandler Minimized;
         public EventHandler Unminimized;
 
@@ -175,6 +197,10 @@ namespace Smuxi.Frontend.Gnome
             } else {
                 heigth = 600;
             }
+            if (width < -1 || heigth < -1) {
+                width = -1;
+                heigth = -1;
+            }
             if (width == -1 && heigth == -1) {
                 SetDefaultSize(800, 600);
                 Maximize();
@@ -196,12 +222,16 @@ namespace Smuxi.Frontend.Gnome
             } else {
                 y = 0;
             }
+            if (x < 0 || y < 0) {
+                x = 0;
+                y = 0;
+            }
             if (x == 0 && y == 0) {
                 SetPosition(Gtk.WindowPosition.Center);
             } else {
                 Move(x, y);
             }
-            
+
             DeleteEvent += OnDeleteEvent;
             FocusInEvent += OnFocusInEvent;
             FocusOutEvent += OnFocusOutEvent;
@@ -225,12 +255,20 @@ namespace Smuxi.Frontend.Gnome
 
             item = new Gtk.ImageMenuItem(Gtk.Stock.Preferences, agrp);
             item.Activated += new EventHandler(_OnPreferencesButtonClicked);
+            item.AccelCanActivate += delegate(object o, Gtk.AccelCanActivateArgs args) {
+                // allow the accelerator to be used even when the menu bar is hidden
+                args.RetVal = true;
+            };
             menu.Append(item);
             
             menu.Append(new Gtk.SeparatorMenuItem());
             
             item = new Gtk.ImageMenuItem(Gtk.Stock.Quit, agrp);
             item.Activated += new EventHandler(_OnQuitButtonClicked);
+            item.AccelCanActivate += delegate(object o, Gtk.AccelCanActivateArgs args) {
+                // allow the accelerator to be used even when the menu bar is hidden
+                args.RetVal = true;
+            };
             menu.Append(item);
             
             // Menu - Server
@@ -261,15 +299,17 @@ namespace Smuxi.Frontend.Gnome
             item.Submenu = menu;
             _MenuBar.Append(item);
             
-            image_item = new Gtk.ImageMenuItem(_("Open / Join Chat"));
-            image_item.Image = new Gtk.Image(Gtk.Stock.Open, Gtk.IconSize.Menu);
-            image_item.Activated += OnChatOpenChatButtonClicked;
-            menu.Append(image_item);
+            _OpenChatMenuItem = new Gtk.ImageMenuItem(_("Open / Join Chat"));
+            _OpenChatMenuItem.Image = new Gtk.Image(Gtk.Stock.Open, Gtk.IconSize.Menu);
+            _OpenChatMenuItem.Activated += OnChatOpenChatButtonClicked;
+            _OpenChatMenuItem.Sensitive = false;
+            menu.Append(_OpenChatMenuItem);
                     
-            image_item = new Gtk.ImageMenuItem(_("_Find Group Chat"));
-            image_item.Image = new Gtk.Image(Gtk.Stock.Find, Gtk.IconSize.Menu);
-            image_item.Activated += OnChatFindGroupChatButtonClicked;
-            menu.Append(image_item);
+            _FindGroupChatMenuItem = new Gtk.ImageMenuItem(_("_Find Group Chat"));
+            _FindGroupChatMenuItem.Image = new Gtk.Image(Gtk.Stock.Find, Gtk.IconSize.Menu);
+            _FindGroupChatMenuItem.Activated += OnChatFindGroupChatButtonClicked;
+            _FindGroupChatMenuItem.Sensitive = false;
+            menu.Append(_FindGroupChatMenuItem);
             
             image_item = new Gtk.ImageMenuItem(_("C_lear All Activity"));
             image_item.Image = new Gtk.Image(Gtk.Stock.Clear, Gtk.IconSize.Menu);
@@ -286,6 +326,10 @@ namespace Smuxi.Frontend.Gnome
             akey.AccelMods = Gdk.ModifierType.ControlMask;
             akey.Key = Gdk.Key.Page_Down;
             image_item.AddAccelerator("activate", agrp, akey);
+            image_item.AccelCanActivate += delegate(object o, Gtk.AccelCanActivateArgs args) {
+                // allow the accelerator to be used even when the menu bar is hidden
+                args.RetVal = true;
+            };
             menu.Append(image_item);
             
             image_item = new Gtk.ImageMenuItem(_("_Previous Chat"));
@@ -296,6 +340,10 @@ namespace Smuxi.Frontend.Gnome
             akey.AccelMods = Gdk.ModifierType.ControlMask;
             akey.Key = Gdk.Key.Page_Up;
             image_item.AddAccelerator("activate", agrp, akey);
+            image_item.AccelCanActivate += delegate(object o, Gtk.AccelCanActivateArgs args) {
+                // allow the accelerator to be used even when the menu bar is hidden
+                args.RetVal = true;
+            };
             menu.Append(image_item);
             
             menu.Append(new Gtk.SeparatorMenuItem());
@@ -348,6 +396,10 @@ namespace Smuxi.Frontend.Gnome
 
             _CloseChatMenuItem = new Gtk.ImageMenuItem(Gtk.Stock.Close, agrp);
             _CloseChatMenuItem.Activated += OnCloseChatMenuItemActivated;
+            _CloseChatMenuItem.AccelCanActivate += delegate(object o, Gtk.AccelCanActivateArgs args) {
+                // allow the accelerator to be used even when the menu bar is hidden
+                args.RetVal = true;
+            };
             menu.Append(_CloseChatMenuItem);
 
             // Menu - Engine
@@ -384,6 +436,10 @@ namespace Smuxi.Frontend.Gnome
             akey.AccelFlags = Gtk.AccelFlags.Visible;
             akey.Key = Gdk.Key.F7;
             item.AddAccelerator("activate", agrp, akey);
+            item.AccelCanActivate += delegate(object o, Gtk.AccelCanActivateArgs args) {
+                // allow the accelerator to be used even when the menu bar is hidden
+                args.RetVal = true;
+            };
             menu.Append(item);
             
             item = new Gtk.CheckMenuItem(_("_Browse Mode"));
@@ -398,6 +454,10 @@ namespace Smuxi.Frontend.Gnome
             akey.AccelFlags = Gtk.AccelFlags.Visible;
             akey.Key = Gdk.Key.F8;
             item.AddAccelerator("activate", agrp, akey);
+            item.AccelCanActivate += delegate(object o, Gtk.AccelCanActivateArgs args) {
+                // allow the accelerator to be used even when the menu bar is hidden
+                args.RetVal = true;
+            };
             menu.Append(item);
 
             _ShowMenuBarItem = new Gtk.CheckMenuItem(_("Show _Menubar"));
@@ -423,6 +483,10 @@ namespace Smuxi.Frontend.Gnome
             akey.AccelFlags = Gtk.AccelFlags.Visible;
             akey.Key = Gdk.Key.F11;
             item.AddAccelerator("activate", agrp, akey);
+            item.AccelCanActivate += delegate(object o, Gtk.AccelCanActivateArgs args) {
+                // allow the accelerator to be used even when the menu bar is hidden
+                args.RetVal = true;
+            };
             menu.Append(item);
 
             // Menu - Help
@@ -445,6 +509,7 @@ namespace Smuxi.Frontend.Gnome
             _ChatViewManager.LoadAll(System.IO.Path.GetDirectoryName(asm.Location),
                                      "smuxi-frontend-gnome-*.dll");
             _ChatViewManager.ChatAdded += OnChatViewManagerChatAdded;
+            _ChatViewManager.ChatSynced += OnChatViewManagerChatSynced;
             _ChatViewManager.ChatRemoved += OnChatViewManagerChatRemoved;
             
 #if GTK_SHARP_2_10
@@ -456,16 +521,20 @@ namespace Smuxi.Frontend.Gnome
 #if NOTIFY_SHARP
             _NotifyManager = new NotifyManager(this, _ChatViewManager);
 #endif
+#if IPC_DBUS
+            _NetworkManager = new NetworkManager(_ChatViewManager);
+#endif
 
             _UI = new GnomeUI(_ChatViewManager);
             
             // HACK: Frontend.FrontendConfig out of scope
             _EngineManager = new EngineManager(Frontend.FrontendConfig, _UI);
 
-            _Entry = new Entry(_Notebook);
+            _Entry = new Entry(_ChatViewManager);
             
             _ProgressBar = new Gtk.ProgressBar();
-            
+            _ProgressBar.BarStyle = Gtk.ProgressBarStyle.Continuous;
+
             Gtk.VBox vbox = new Gtk.VBox();
             vbox.PackStart(_MenuBar, false, false, 0);
             vbox.PackStart(_Notebook, true, true, 0);
@@ -593,13 +662,17 @@ namespace Smuxi.Frontend.Gnome
             
             try {
                 UrgencyHint = false;
+                if (_Notebook.IsBrowseModeEnabled) {
+                    return;
+                }
+
                 ChatView chatView = _Notebook.CurrentChatView;
                 if (chatView != null) {
                     // clear activity and highlight
                     chatView.HasHighlight = false;
                     chatView.HasActivity = false;
                     var lastMsg = chatView.OutputMessageTextView.LastMessage;
-                    if (lastMsg == null) {
+                    if (lastMsg == null || Frontend.UseLowBandwidthMode) {
                         return;
                     }
                     // update last seen highlight
@@ -624,6 +697,10 @@ namespace Smuxi.Frontend.Gnome
             Trace.Call(sender, e);
 
             try {
+                if (_Notebook.IsBrowseModeEnabled) {
+                    return;
+                }
+
                 var chatView = _Notebook.CurrentChatView;
                 if (chatView == null) {
                     return;
@@ -717,15 +794,24 @@ namespace Smuxi.Frontend.Gnome
             try {
                 OpenChatDialog dialog = new OpenChatDialog(this);
                 int res = dialog.Run();
-                
-                IProtocolManager manager = Frontend.FrontendManager.CurrentProtocolManager;
+
+                var chatView = Notebook.CurrentChatView;
+                if (chatView == null) {
+                    return;
+                }
+
+                // FIXME: REMOTING CALL
+                var manager = chatView.ChatModel.ProtocolManager;
+                if (manager == null) {
+                    return;
+                }
                 ChatModel chat;
                 switch (dialog.ChatType) {
                     case ChatType.Group:
                         chat = new GroupChatModel(
                             dialog.ChatName, 
                             dialog.ChatName,
-                            manager
+                            null
                         );
                         break;
                     case ChatType.Person:
@@ -733,7 +819,7 @@ namespace Smuxi.Frontend.Gnome
                             null,
                             dialog.ChatName, 
                             dialog.ChatName,
-                            manager
+                            null
                         );
                         break;
                     default:
@@ -750,7 +836,13 @@ namespace Smuxi.Frontend.Gnome
                     return;
                 }
                 
-                manager.OpenChat(Frontend.FrontendManager, chat);
+                ThreadPool.QueueUserWorkItem(delegate {
+                    try {
+                        manager.OpenChat(Frontend.FrontendManager, chat);
+                    } catch (Exception ex) {
+                        Frontend.ShowException(this, ex);
+                    }
+                });
             } catch (Exception ex) {
                 Frontend.ShowException(this, ex);
             }
@@ -759,24 +851,53 @@ namespace Smuxi.Frontend.Gnome
         protected virtual void OnChatFindGroupChatButtonClicked(object sender, EventArgs e)
         {
             Trace.Call(sender, e);
-            
             try {
-                IProtocolManager manager = Frontend.FrontendManager.CurrentProtocolManager;
-                FindGroupChatDialog dialog = new FindGroupChatDialog(
-                    this, manager
-                );
-                int res = dialog.Run();
-                GroupChatModel groupChat = dialog.GroupChat;
-                dialog.Destroy();
-                if (res != (int) Gtk.ResponseType.Ok) {
-                    return;
-                }
-                
-                manager.OpenChat(Frontend.FrontendManager, groupChat);
+                OpenFindGroupChatWindow();
             } catch (Exception ex) {
                 Frontend.ShowException(this, ex);
             }
         }
+
+        public void OpenFindGroupChatWindow()
+        {
+            OpenFindGroupChatWindow(null);
+        }
+
+        public void OpenFindGroupChatWindow(string searchKey)
+        {
+            var chatView = Notebook.CurrentChatView;
+            if (chatView == null) {
+                return;
+            }
+
+            // FIXME: REMOTING CALL
+            var manager = chatView.ChatModel.ProtocolManager;
+            if (manager == null) {
+                return;
+            }
+
+            FindGroupChatDialog dialog = new FindGroupChatDialog(
+                this, manager
+            );
+            if (!String.IsNullOrEmpty(searchKey)) {
+                dialog.NameEntry.Text = searchKey;
+                dialog.FindButton.Click();
+            }
+            int res = dialog.Run();
+            GroupChatModel groupChat = dialog.GroupChat;
+            dialog.Destroy();
+            if (res != (int) Gtk.ResponseType.Ok) {
+                return;
+            }
+
+            ThreadPool.QueueUserWorkItem(delegate {
+                try {
+                    manager.OpenChat(Frontend.FrontendManager, groupChat);
+                } catch (Exception ex) {
+                    Frontend.ShowException(this, ex);
+                }
+            });
+        }
         
         protected virtual void OnChatClearAllActivityButtonClicked(object sender, EventArgs e)
         {
@@ -917,13 +1038,18 @@ namespace Smuxi.Frontend.Gnome
         
         protected virtual void OnNotebookSwitchPage(object sender, EventArgs e)
         {
-            Trace.Call(sender, e);
-            
             try {
-                _CloseChatMenuItem.Sensitive = !(_Notebook.CurrentChatView is SessionChatView);
+                var chatView = Notebook.CurrentChatView;
+                if (chatView == null) {
+                    return;
+                }
+
+                _OpenChatMenuItem.Sensitive = !(chatView is SessionChatView);
+                _CloseChatMenuItem.Sensitive = !(chatView is SessionChatView);
+                _FindGroupChatMenuItem.Sensitive = !(chatView is SessionChatView);
                 if (Frontend.IsLocalEngine) {
                     _OpenLogChatMenuItem.Sensitive =
-                        File.Exists(_Notebook.CurrentChatView.ChatModel.LogFile);
+                        File.Exists(chatView.ChatModel.LogFile);
                 }
             } catch (Exception ex) {
                 Frontend.ShowException(this, ex);
@@ -1049,26 +1175,51 @@ namespace Smuxi.Frontend.Gnome
         protected void OnChatViewManagerChatAdded(object sender, ChatViewManagerChatAddedEventArgs e)
         {
             Trace.Call(sender, e);
-            
-            e.ChatView.OutputMessageTextView.MessageHighlighted += OnChatViewMessageHighlighted;
+
+            e.ChatView.MessageHighlighted += OnChatViewMessageHighlighted;
+            UpdateProgressBar();
         }
         
+        protected void OnChatViewManagerChatSynced(object sender, ChatViewManagerChatSyncedEventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            UpdateProgressBar();
+        }
+
         protected void OnChatViewManagerChatRemoved(object sender, ChatViewManagerChatRemovedEventArgs e)
         {
             Trace.Call(sender, e);
             
-            e.ChatView.OutputMessageTextView.MessageHighlighted -= OnChatViewMessageHighlighted;
+            e.ChatView.MessageHighlighted -= OnChatViewMessageHighlighted;
         }
         
-        protected void OnChatViewMessageHighlighted(object sender, MessageTextViewMessageHighlightedEventArgs e)
+        protected void OnChatViewMessageHighlighted(object sender, ChatViewMessageHighlightedEventArgs e)
         {
+#if MSG_DEBUG
             Trace.Call(sender, e);
-            
+#endif
+
             if (!HasToplevelFocus) {
                 UrgencyHint = true;
             }
         }
 
+        public void UpdateProgressBar()
+        {
+            var totalChatCount = _ChatViewManager.Chats.Count;
+            var syncedChatCount =  _ChatViewManager.SyncedChats.Count;
+            _ProgressBar.Fraction = (double)syncedChatCount / totalChatCount;
+            _ProgressBar.Text = String.Format("{0} / {1}",
+                                              syncedChatCount,
+                                              totalChatCount);
+            if (syncedChatCount >= totalChatCount) {
+                _ProgressBar.Hide();
+            } else {
+                _ProgressBar.Show();
+            }
+        }
+
         private static string _(string msg)
         {
             return Mono.Unix.Catalog.GetString(msg);
diff --git a/src/Frontend-GNOME/Makefile.am b/src/Frontend-GNOME/Makefile.am
index 0656d23..026b466 100644
--- a/src/Frontend-GNOME/Makefile.am
+++ b/src/Frontend-GNOME/Makefile.am
@@ -1,11 +1,39 @@
 
-EXTRA_DIST =  
-
-ICON = smuxi-frontend-gnome.svg
+EXTRA_DIST = $(WIN_ICON) $(DESKTOP_FILE).in
+
+ICON_NAME = smuxi-frontend-gnome
+ICON_NAME_PNG = $(ICON_NAME).png
+ICON_SVG = $(ICON_NAME).svg
+ICON_16 = $(top_builddir)/images/16/$(ICON_NAME_PNG)
+ICON_22 = $(top_builddir)/images/22/$(ICON_NAME_PNG)
+ICON_24 = $(top_builddir)/images/24/$(ICON_NAME_PNG)
+ICON_32 = $(top_builddir)/images/32/$(ICON_NAME_PNG)
+ICON_48 = $(top_builddir)/images/48/$(ICON_NAME_PNG)
+ICON_128 = $(top_builddir)/images/128/$(ICON_NAME_PNG)
+ICON_256 = $(top_builddir)/images/256/$(ICON_NAME_PNG)
+
+WIN_ICON = $(top_srcdir)/images/icon.ico
 DESKTOP_FILE = smuxi-frontend-gnome.desktop
 
-pixmapdir =  $(datadir)/pixmaps
-pixmap_DATA = $(ICON)
+THEME_DIR = $(datadir)/icons/hicolor
+svgicondir = $(THEME_DIR)/scalable/apps
+svgicon_DATA = $(ICON_SVG)
+icon16dir = $(THEME_DIR)/16x16/apps
+icon16_DATA = $(ICON_16)
+icon22dir = $(THEME_DIR)/22x22/apps
+icon22_DATA = $(ICON_22)
+icon24dir = $(THEME_DIR)/24x24/apps
+icon24_DATA = $(ICON_24)
+icon32dir = $(THEME_DIR)/32x32/apps
+icon32_DATA = $(ICON_32)
+icon48dir = $(THEME_DIR)/48x48/apps
+icon48_DATA = $(ICON_48)
+icon128dir = $(THEME_DIR)/128x128/apps
+icon128_DATA = $(ICON_128)
+icon256dir = $(THEME_DIR)/256x256/apps
+icon256_DATA = $(ICON_256)
+
+gtk_update_icon_cache = gtk-update-icon-cache -f -t $(THEME_DIR)
 
 desktopdir = $(datadir)/applications
 desktop_in_files = $(DESKTOP_FILE).in
@@ -15,38 +43,12 @@ build_datafiles = $(DESKTOP_FILE)
 FRONTEND_GNOME_EXE_CONFIG_SOURCE = smuxi-frontend-gnome.exe.config
 FRONTEND_GNOME_EXE_CONFIG = $(BUILD_DIR)/smuxi-frontend-gnome.exe.config
 
-# Warning: This is an automatically generated file, do not edit!
-
-if ENABLE_RELEASE
 ASSEMBLY_COMPILER_COMMAND = @MCS@
-ASSEMBLY_COMPILER_FLAGS =  -noconfig -codepage:utf8 -warn:4 -optimize+ "-define:CONFIG_NINI,UI_GNOME,GTK_SHARP_2_8" @FRONTEND_GNOME_COMPILER_FLAGS@
-
-ASSEMBLY = ../../bin/release/smuxi-frontend-gnome.exe
-ASSEMBLY_MDB = 
-COMPILE_TARGET = exe
-PROJECT_REFERENCES =  \
-	../../bin/release/smuxi-engine.dll \
-	../../bin/release/smuxi-common.dll \
-	../../bin/release/smuxi-frontend.dll
-BUILD_DIR = ../../bin/release
-
-LOG4NET_DLL_SOURCE=../../lib/log4net.dll
-SMUXI_ENGINE_DLL_MDB=
-NINI_DLL_SOURCE=../../lib/Nini.dll
-SMUXI_ENGINE_DLL_SOURCE=../../bin/release/smuxi-engine.dll
-SMUXI_FRONTEND_DLL_MDB=
-SMUXI_FRONTEND_DLL_SOURCE=../../bin/release/smuxi-frontend.dll
-SMUXI_COMMON_DLL_SOURCE=../../bin/release/smuxi-common.dll
-
-endif
-
-if ENABLE_DEBUG
-ASSEMBLY_COMPILER_COMMAND = @MCS@
-ASSEMBLY_COMPILER_FLAGS =  -noconfig -codepage:utf8 -warn:4 -optimize- -debug -define:DEBUG "-define:DEBUG,TRACE,LOG4NET,CONFIG_NINI,UI_GNOME,GTK_SHARP_2_8" @FRONTEND_GNOME_COMPILER_FLAGS@
+ASSEMBLY_COMPILER_FLAGS =  @CSC_FLAGS@ -noconfig -codepage:utf8 -warn:4 -optimize- -debug -define:DEBUG "-define:DEBUG,TRACE,LOG4NET,CONFIG_NINI,UI_GNOME,GTK_SHARP_2_8" -win32icon:$(WIN_ICON) @FRONTEND_GNOME_COMPILER_FLAGS@
 
 ASSEMBLY = ../../bin/debug/smuxi-frontend-gnome.exe
 ASSEMBLY_MDB = $(ASSEMBLY).mdb
-COMPILE_TARGET = exe
+COMPILE_TARGET = winexe
 PROJECT_REFERENCES =  \
 	../../bin/debug/smuxi-engine.dll \
 	../../bin/debug/smuxi-common.dll \
@@ -63,8 +65,6 @@ SMUXI_FRONTEND_DLL_MDB=$(BUILD_DIR)/smuxi-frontend.dll.mdb
 SMUXI_FRONTEND_DLL_SOURCE=../../bin/debug/smuxi-frontend.dll
 SMUXI_COMMON_DLL_SOURCE=../../bin/debug/smuxi-common.dll
 
-endif
-
 AL=al2
 SATELLITE_ASSEMBLY_NAME=.resources.dll
 
@@ -82,10 +82,24 @@ LINUX_DESKTOPAPPLICATIONS = \
 BINARIES = \
 	$(FRONTEND_GNOME)  
 
-all: $(ASSEMBLY) $(PROGRAMFILES) $(LINUX_DESKTOPAPPLICATIONS) $(BINARIES) $(ICON)
-
-$(ICON):
-	cp $(top_srcdir)/images/icon.svg $(ICON)
+all: $(ASSEMBLY) $(PROGRAMFILES) $(LINUX_DESKTOPAPPLICATIONS) $(BINARIES)
+
+$(ICON_SVG):
+	$(INSTALL) -m644 $(top_srcdir)/images/icon.svg $@
+$(ICON_16):
+	$(INSTALL) -D -m644 $(top_srcdir)/images/icon_16x16.png $@
+$(ICON_22):
+	$(INSTALL) -D -m644 $(top_srcdir)/images/icon_22x22.png $@
+$(ICON_24):
+	$(INSTALL) -D -m644 $(top_srcdir)/images/icon_24x24.png $@
+$(ICON_32):
+	$(INSTALL) -D -m644 $(top_srcdir)/images/icon_32x32.png $@
+$(ICON_48):
+	$(INSTALL) -D -m644 $(top_srcdir)/images/icon_48x48.png $@
+$(ICON_128):
+	$(INSTALL) -D -m644 $(top_srcdir)/images/icon_128x128.png $@
+$(ICON_256):
+	$(INSTALL) -D -m644 $(top_srcdir)/images/icon_256x256.png $@
 
 FILES = \
 	$(top_srcdir)/src/AssemblyVersion.cs \
@@ -97,15 +111,16 @@ FILES = \
 	Frontend.cs \
 	GnomeUI.cs \
 	IndicateManager.cs \
+	LinkTag.cs \
 	Main.cs \
 	MainWindow.cs \
+	NetworkManager.cs \
 	NotImplementedMessageDialog.cs \
 	Notebook.cs \
 	SplashScreenWindow.cs \
 	ChatTypeWidget.cs \
 	ChatViewManager.cs \
-	ColorTools.cs \
-	ColorContrast.cs \
+	ColorConverter.cs \
 	NotifyManager.cs \
 	PangoTools.cs \
 	Preferences/ServerListView.cs \
@@ -147,17 +162,24 @@ FILES = \
 	gtk-gui/Smuxi.Frontend.Gnome.FilterListWidget.cs
 	
 DATA_FILES = \
-	$(DESKTOP_FILE)
+	$(DESKTOP_FILE) \
+	$(ICON_SVG) \
+	$(ICON_16) \
+	$(ICON_22) \
+	$(ICON_24) \
+	$(ICON_32) \
+	$(ICON_48) \
+	$(ICON_128) \
+	$(ICON_256)
 
 RESOURCES = \
 	gtk-gui/gui.stetic \
 	$(top_srcdir)/glade/smuxi-frontend-gnome.glade \
-	$(top_srcdir)/images/connect-button.svg \
-	$(top_srcdir)/images/icon.svg \
-	$(top_srcdir)/images/group-chat.svg \
-	$(top_srcdir)/images/person-chat.svg \
-	$(top_srcdir)/images/protocol-chat.svg \
-	$(top_srcdir)/images/session-chat.svg 
+	$(top_srcdir)/images/icon_256x256.png \
+	$(top_srcdir)/images/group-chat_256x256.png \
+	$(top_srcdir)/images/person-chat_256x256.png \
+	$(top_srcdir)/images/protocol-chat_256x256.png \
+	$(top_srcdir)/images/session-chat_256x256.png 
 
 EXTRAS = \
 	smuxi-frontend-gnome.in \
@@ -166,6 +188,7 @@ EXTRAS = \
 REFERENCES =  \
 	System.Runtime.Remoting \
 	System \
+    System.Core \
 	Mono.Posix \
 	System.Drawing \
 	$(GLIB_SHARP_20_LIBS) \
@@ -173,11 +196,12 @@ REFERENCES =  \
 	$(GTK_SHARP_20_LIBS) \
 	$(LOG4NET_LIBS) \
 	$(INDICATE_SHARP_LIBS) \
-	$(NOTIFY_SHARP_LIBS)
+	$(NOTIFY_SHARP_LIBS) \
+	$(DBUS_LIBS)
 
 DLL_REFERENCES = 
 
-CLEANFILES = $(LINUX_DESKTOPAPPLICATIONS) $(PROGRAMFILES) $(BINARIES) $(ICON)
+CLEANFILES = $(LINUX_DESKTOPAPPLICATIONS) $(PROGRAMFILES) $(BINARIES)
 
 include $(top_srcdir)/Makefile.include
 
@@ -208,3 +232,14 @@ $(ASSEMBLY) $(ASSEMBLY_MDB): $(build_sources) $(build_resources) $(build_datafil
 
 %.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po-Frontend-GNOME/*.po)
 	LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po-Frontend-GNOME/.intltool-merge-cache $(top_srcdir)/po-Frontend-GNOME $< $@
+
+install-data-hook: update-icon-cache
+uninstall-hook: update-icon-cache
+update-icon-cache:
+	@-if test -z "$(DESTDIR)"; then \
+		echo "Updating Gtk icon cache."; \
+		$(gtk_update_icon_cache); \
+	else \
+		echo "*** Icon cache not updated.  After (un)install, run this:"; \
+		echo "***   $(gtk_update_icon_cache)"; \
+	fi
diff --git a/src/Frontend-GNOME/Makefile.in b/src/Frontend-GNOME/Makefile.in
index d4bcbb1..e419dae 100644
--- a/src/Frontend-GNOME/Makefile.in
+++ b/src/Frontend-GNOME/Makefile.in
@@ -41,8 +41,11 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 subdir = src/Frontend-GNOME
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -70,21 +73,26 @@ am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
 am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibdir)" \
-	"$(DESTDIR)$(desktopdir)" \
+	"$(DESTDIR)$(desktopdir)" "$(DESTDIR)$(icon128dir)" \
+	"$(DESTDIR)$(icon16dir)" "$(DESTDIR)$(icon22dir)" \
+	"$(DESTDIR)$(icon24dir)" "$(DESTDIR)$(icon256dir)" \
+	"$(DESTDIR)$(icon32dir)" "$(DESTDIR)$(icon48dir)" \
 	"$(DESTDIR)$(linuxdesktopapplicationsdir)" \
-	"$(DESTDIR)$(linuxpkgconfigdir)" "$(DESTDIR)$(pixmapdir)" \
+	"$(DESTDIR)$(linuxpkgconfigdir)" \
 	"$(DESTDIR)$(programfilesdir)" \
-	"$(DESTDIR)$(programfilesiconsdir)"
+	"$(DESTDIR)$(programfilesiconsdir)" "$(DESTDIR)$(svgicondir)"
 SCRIPTS = $(bin_SCRIPTS) $(pkglib_SCRIPTS)
 SOURCES =
 DIST_SOURCES =
-DATA = $(desktop_DATA) $(linuxdesktopapplications_DATA) \
-	$(linuxpkgconfig_DATA) $(pixmap_DATA) $(programfiles_DATA) \
-	$(programfilesicons_DATA)
+DATA = $(desktop_DATA) $(icon128_DATA) $(icon16_DATA) $(icon22_DATA) \
+	$(icon24_DATA) $(icon256_DATA) $(icon32_DATA) $(icon48_DATA) \
+	$(linuxdesktopapplications_DATA) $(linuxpkgconfig_DATA) \
+	$(programfiles_DATA) $(programfilesicons_DATA) $(svgicon_DATA)
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -98,13 +106,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -145,13 +166,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -159,6 +182,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -169,13 +193,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -189,13 +222,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -203,7 +242,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -218,10 +259,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -252,59 +296,66 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 twitter_api_key = @twitter_api_key@
-EXTRA_DIST = $(build_sources) $(build_resx_files) \
-	$(build_others_files) $(ASSEMBLY_WRAPPER_IN) $(EXTRAS) \
-	$(DATA_FILES) $(build_culture_res_files)
-ICON = smuxi-frontend-gnome.svg
+EXTRA_DIST = $(WIN_ICON) $(DESKTOP_FILE).in $(build_sources) \
+	$(build_resx_files) $(build_others_files) \
+	$(ASSEMBLY_WRAPPER_IN) $(EXTRAS) $(DATA_FILES) \
+	$(build_culture_res_files)
+ICON_NAME = smuxi-frontend-gnome
+ICON_NAME_PNG = $(ICON_NAME).png
+ICON_SVG = $(ICON_NAME).svg
+ICON_16 = $(top_builddir)/images/16/$(ICON_NAME_PNG)
+ICON_22 = $(top_builddir)/images/22/$(ICON_NAME_PNG)
+ICON_24 = $(top_builddir)/images/24/$(ICON_NAME_PNG)
+ICON_32 = $(top_builddir)/images/32/$(ICON_NAME_PNG)
+ICON_48 = $(top_builddir)/images/48/$(ICON_NAME_PNG)
+ICON_128 = $(top_builddir)/images/128/$(ICON_NAME_PNG)
+ICON_256 = $(top_builddir)/images/256/$(ICON_NAME_PNG)
+WIN_ICON = $(top_srcdir)/images/icon.ico
 DESKTOP_FILE = smuxi-frontend-gnome.desktop
-pixmapdir = $(datadir)/pixmaps
-pixmap_DATA = $(ICON)
+THEME_DIR = $(datadir)/icons/hicolor
+svgicondir = $(THEME_DIR)/scalable/apps
+svgicon_DATA = $(ICON_SVG)
+icon16dir = $(THEME_DIR)/16x16/apps
+icon16_DATA = $(ICON_16)
+icon22dir = $(THEME_DIR)/22x22/apps
+icon22_DATA = $(ICON_22)
+icon24dir = $(THEME_DIR)/24x24/apps
+icon24_DATA = $(ICON_24)
+icon32dir = $(THEME_DIR)/32x32/apps
+icon32_DATA = $(ICON_32)
+icon48dir = $(THEME_DIR)/48x48/apps
+icon48_DATA = $(ICON_48)
+icon128dir = $(THEME_DIR)/128x128/apps
+icon128_DATA = $(ICON_128)
+icon256dir = $(THEME_DIR)/256x256/apps
+icon256_DATA = $(ICON_256)
+gtk_update_icon_cache = gtk-update-icon-cache -f -t $(THEME_DIR)
 desktopdir = $(datadir)/applications
 desktop_in_files = $(DESKTOP_FILE).in
 desktop_DATA = $(DESKTOP_FILE)
 build_datafiles = $(DESKTOP_FILE)
 FRONTEND_GNOME_EXE_CONFIG_SOURCE = smuxi-frontend-gnome.exe.config
 FRONTEND_GNOME_EXE_CONFIG = $(BUILD_DIR)/smuxi-frontend-gnome.exe.config
- at ENABLE_DEBUG_TRUE@ASSEMBLY_COMPILER_COMMAND = @MCS@
-
-# Warning: This is an automatically generated file, do not edit!
- at ENABLE_RELEASE_TRUE@ASSEMBLY_COMPILER_COMMAND = @MCS@
- at ENABLE_DEBUG_TRUE@ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize- -debug -define:DEBUG "-define:DEBUG,TRACE,LOG4NET,CONFIG_NINI,UI_GNOME,GTK_SHARP_2_8" @FRONTEND_GNOME_COMPILER_FLAGS@
- at ENABLE_RELEASE_TRUE@ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+ "-define:CONFIG_NINI,UI_GNOME,GTK_SHARP_2_8" @FRONTEND_GNOME_COMPILER_FLAGS@
- at ENABLE_DEBUG_TRUE@ASSEMBLY = ../../bin/debug/smuxi-frontend-gnome.exe
- at ENABLE_RELEASE_TRUE@ASSEMBLY = ../../bin/release/smuxi-frontend-gnome.exe
- at ENABLE_DEBUG_TRUE@ASSEMBLY_MDB = $(ASSEMBLY).mdb
- at ENABLE_RELEASE_TRUE@ASSEMBLY_MDB = 
- at ENABLE_DEBUG_TRUE@COMPILE_TARGET = exe
- at ENABLE_RELEASE_TRUE@COMPILE_TARGET = exe
- at ENABLE_DEBUG_TRUE@PROJECT_REFERENCES = \
- at ENABLE_DEBUG_TRUE@	../../bin/debug/smuxi-engine.dll \
- at ENABLE_DEBUG_TRUE@	../../bin/debug/smuxi-common.dll \
- at ENABLE_DEBUG_TRUE@	../../bin/debug/smuxi-frontend.dll
-
- at ENABLE_RELEASE_TRUE@PROJECT_REFERENCES = \
- at ENABLE_RELEASE_TRUE@	../../bin/release/smuxi-engine.dll \
- at ENABLE_RELEASE_TRUE@	../../bin/release/smuxi-common.dll \
- at ENABLE_RELEASE_TRUE@	../../bin/release/smuxi-frontend.dll
-
- at ENABLE_DEBUG_TRUE@BUILD_DIR = ../../bin/debug
- at ENABLE_RELEASE_TRUE@BUILD_DIR = ../../bin/release
- at ENABLE_DEBUG_TRUE@LOG4NET_DLL_SOURCE = ../../lib/log4net.dll
- at ENABLE_RELEASE_TRUE@LOG4NET_DLL_SOURCE = ../../lib/log4net.dll
- at ENABLE_DEBUG_TRUE@SMUXI_ENGINE_DLL_MDB = $(BUILD_DIR)/smuxi-engine.dll.mdb
- at ENABLE_RELEASE_TRUE@SMUXI_ENGINE_DLL_MDB = 
- at ENABLE_DEBUG_TRUE@NINI_DLL_SOURCE = ../../lib/Nini.dll
- at ENABLE_RELEASE_TRUE@NINI_DLL_SOURCE = ../../lib/Nini.dll
- at ENABLE_DEBUG_TRUE@SMUXI_ENGINE_DLL_SOURCE = ../../bin/debug/smuxi-engine.dll
- at ENABLE_RELEASE_TRUE@SMUXI_ENGINE_DLL_SOURCE = ../../bin/release/smuxi-engine.dll
- at ENABLE_DEBUG_TRUE@SMUXI_FRONTEND_DLL_MDB = $(BUILD_DIR)/smuxi-frontend.dll.mdb
- at ENABLE_RELEASE_TRUE@SMUXI_FRONTEND_DLL_MDB = 
- at ENABLE_DEBUG_TRUE@SMUXI_FRONTEND_DLL_SOURCE = ../../bin/debug/smuxi-frontend.dll
- at ENABLE_RELEASE_TRUE@SMUXI_FRONTEND_DLL_SOURCE = ../../bin/release/smuxi-frontend.dll
- at ENABLE_DEBUG_TRUE@SMUXI_COMMON_DLL_SOURCE = ../../bin/debug/smuxi-common.dll
- at ENABLE_RELEASE_TRUE@SMUXI_COMMON_DLL_SOURCE = ../../bin/release/smuxi-common.dll
- at ENABLE_DEBUG_TRUE@SMUXI_ENGINE_DLL_MDB_SOURCE = ../../bin/debug/smuxi-engine.dll.mdb
- at ENABLE_DEBUG_TRUE@SMUXI_FRONTEND_DLL_MDB_SOURCE = ../../bin/debug/smuxi-frontend.dll.mdb
+ASSEMBLY_COMPILER_COMMAND = @MCS@
+ASSEMBLY_COMPILER_FLAGS = @CSC_FLAGS@ -noconfig -codepage:utf8 -warn:4 -optimize- -debug -define:DEBUG "-define:DEBUG,TRACE,LOG4NET,CONFIG_NINI,UI_GNOME,GTK_SHARP_2_8" -win32icon:$(WIN_ICON) @FRONTEND_GNOME_COMPILER_FLAGS@
+ASSEMBLY = ../../bin/debug/smuxi-frontend-gnome.exe
+ASSEMBLY_MDB = $(ASSEMBLY).mdb
+COMPILE_TARGET = winexe
+PROJECT_REFERENCES = \
+	../../bin/debug/smuxi-engine.dll \
+	../../bin/debug/smuxi-common.dll \
+	../../bin/debug/smuxi-frontend.dll
+
+BUILD_DIR = ../../bin/debug
+LOG4NET_DLL_SOURCE = ../../lib/log4net.dll
+SMUXI_ENGINE_DLL_MDB_SOURCE = ../../bin/debug/smuxi-engine.dll.mdb
+SMUXI_ENGINE_DLL_MDB = $(BUILD_DIR)/smuxi-engine.dll.mdb
+NINI_DLL_SOURCE = ../../lib/Nini.dll
+SMUXI_ENGINE_DLL_SOURCE = ../../bin/debug/smuxi-engine.dll
+SMUXI_FRONTEND_DLL_MDB_SOURCE = ../../bin/debug/smuxi-frontend.dll.mdb
+SMUXI_FRONTEND_DLL_MDB = $(BUILD_DIR)/smuxi-frontend.dll.mdb
+SMUXI_FRONTEND_DLL_SOURCE = ../../bin/debug/smuxi-frontend.dll
+SMUXI_COMMON_DLL_SOURCE = ../../bin/debug/smuxi-common.dll
 AL = al2
 SATELLITE_ASSEMBLY_NAME = .resources.dll
 PROGRAMFILES = \
@@ -331,15 +382,16 @@ FILES = \
 	Frontend.cs \
 	GnomeUI.cs \
 	IndicateManager.cs \
+	LinkTag.cs \
 	Main.cs \
 	MainWindow.cs \
+	NetworkManager.cs \
 	NotImplementedMessageDialog.cs \
 	Notebook.cs \
 	SplashScreenWindow.cs \
 	ChatTypeWidget.cs \
 	ChatViewManager.cs \
-	ColorTools.cs \
-	ColorContrast.cs \
+	ColorConverter.cs \
 	NotifyManager.cs \
 	PangoTools.cs \
 	Preferences/ServerListView.cs \
@@ -381,17 +433,24 @@ FILES = \
 	gtk-gui/Smuxi.Frontend.Gnome.FilterListWidget.cs
 
 DATA_FILES = \
-	$(DESKTOP_FILE)
+	$(DESKTOP_FILE) \
+	$(ICON_SVG) \
+	$(ICON_16) \
+	$(ICON_22) \
+	$(ICON_24) \
+	$(ICON_32) \
+	$(ICON_48) \
+	$(ICON_128) \
+	$(ICON_256)
 
 RESOURCES = \
 	gtk-gui/gui.stetic \
 	$(top_srcdir)/glade/smuxi-frontend-gnome.glade \
-	$(top_srcdir)/images/connect-button.svg \
-	$(top_srcdir)/images/icon.svg \
-	$(top_srcdir)/images/group-chat.svg \
-	$(top_srcdir)/images/person-chat.svg \
-	$(top_srcdir)/images/protocol-chat.svg \
-	$(top_srcdir)/images/session-chat.svg 
+	$(top_srcdir)/images/icon_256x256.png \
+	$(top_srcdir)/images/group-chat_256x256.png \
+	$(top_srcdir)/images/person-chat_256x256.png \
+	$(top_srcdir)/images/protocol-chat_256x256.png \
+	$(top_srcdir)/images/session-chat_256x256.png 
 
 EXTRAS = \
 	smuxi-frontend-gnome.in \
@@ -400,6 +459,7 @@ EXTRAS = \
 REFERENCES = \
 	System.Runtime.Remoting \
 	System \
+    System.Core \
 	Mono.Posix \
 	System.Drawing \
 	$(GLIB_SHARP_20_LIBS) \
@@ -407,11 +467,12 @@ REFERENCES = \
 	$(GTK_SHARP_20_LIBS) \
 	$(LOG4NET_LIBS) \
 	$(INDICATE_SHARP_LIBS) \
-	$(NOTIFY_SHARP_LIBS)
+	$(NOTIFY_SHARP_LIBS) \
+	$(DBUS_LIBS)
 
 DLL_REFERENCES = 
 CLEANFILES = $(LINUX_DESKTOPAPPLICATIONS) $(PROGRAMFILES) $(BINARIES) \
-	$(ICON) $(ASSEMBLY) $(ASSEMBLY).mdb $(BINARIES) \
+	$(ASSEMBLY) $(ASSEMBLY).mdb $(BINARIES) \
 	$(build_resx_resources) $(build_satellite_assembly_list)
 VALID_CULTURES = ar bg ca zh-CHS cs da de el en es fi fr he hu is it ja ko nl no pl pt ro ru hr sk sq sv th tr id uk be sl et lv lt fa vi hy eu mk af fo hi sw gu ta te kn mr gl kok ar-SA bg-BG ca-ES zh-TW cs-CZ da-DK de-DE el-GR en-US fi-FI fr-FR he-IL hu-HU is-IS it-IT ja-JP ko-KR nl-NL nb-NO pl-PL pt-BR ro-RO ru-RU hr-HR sk-SK sq-AL sv-SE th-TH tr-TR id-ID uk-UA be-BY sl-SI et-EE lv-LV lt-LT fa-IR vi-VN hy-AM eu-ES mk-MK af-ZA fo-FO hi-IN sw-KE gu-IN ta-IN te-IN kn-IN mr-IN gl-ES kok-IN ar-IQ zh-CN de-CH en-GB es-MX fr-BE it-CH nl-BE nn-NO pt-PT sv-FI ar-EG zh-HK de-AT en-AU es-ES fr-CA ar-LY zh-SG de-LU en-CA es-GT fr-CH ar-DZ zh-MO en-NZ es-CR fr-LU ar-MA en-IE es-PA ar-TN en-ZA es-DO ar-OM es-VE ar-YE es-CO ar-SY es-PE ar-JO es-AR ar-LB en-ZW es-EC ar-KW en-PH es-CL ar-AE es-UY ar-BH es-PY ar-QA es-BO es-SV es-HN es-NI es-PR zh-CHT
 build_sources = $(FILES) $(GENERATED_FILES)
@@ -442,7 +503,7 @@ build_references_ref = $(foreach ref, $(REFERENCES), $(if $(filter \
 	-pkg:%, $(ref)), $(ref), $(if $(filter -r:%, $(ref)), $(ref), \
 	-r:$(ref)))) $(foreach ref, $(DLL_REFERENCES), -r:$(ref)) \
 	$(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
 programfilesdir = @libdir@/@PACKAGE@
@@ -569,6 +630,12 @@ uninstall-pkglibSCRIPTS:
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-desktopDATA: $(desktop_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(desktopdir)" || $(MKDIR_P) "$(DESTDIR)$(desktopdir)"
@@ -589,6 +656,146 @@ uninstall-desktopDATA:
 	test -n "$$files" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(desktopdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(desktopdir)" && rm -f $$files
+install-icon128DATA: $(icon128_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(icon128dir)" || $(MKDIR_P) "$(DESTDIR)$(icon128dir)"
+	@list='$(icon128_DATA)'; test -n "$(icon128dir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(icon128dir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(icon128dir)" || exit $$?; \
+	done
+
+uninstall-icon128DATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(icon128_DATA)'; test -n "$(icon128dir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(icon128dir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(icon128dir)" && rm -f $$files
+install-icon16DATA: $(icon16_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(icon16dir)" || $(MKDIR_P) "$(DESTDIR)$(icon16dir)"
+	@list='$(icon16_DATA)'; test -n "$(icon16dir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(icon16dir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(icon16dir)" || exit $$?; \
+	done
+
+uninstall-icon16DATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(icon16_DATA)'; test -n "$(icon16dir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(icon16dir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(icon16dir)" && rm -f $$files
+install-icon22DATA: $(icon22_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(icon22dir)" || $(MKDIR_P) "$(DESTDIR)$(icon22dir)"
+	@list='$(icon22_DATA)'; test -n "$(icon22dir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(icon22dir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(icon22dir)" || exit $$?; \
+	done
+
+uninstall-icon22DATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(icon22_DATA)'; test -n "$(icon22dir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(icon22dir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(icon22dir)" && rm -f $$files
+install-icon24DATA: $(icon24_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(icon24dir)" || $(MKDIR_P) "$(DESTDIR)$(icon24dir)"
+	@list='$(icon24_DATA)'; test -n "$(icon24dir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(icon24dir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(icon24dir)" || exit $$?; \
+	done
+
+uninstall-icon24DATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(icon24_DATA)'; test -n "$(icon24dir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(icon24dir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(icon24dir)" && rm -f $$files
+install-icon256DATA: $(icon256_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(icon256dir)" || $(MKDIR_P) "$(DESTDIR)$(icon256dir)"
+	@list='$(icon256_DATA)'; test -n "$(icon256dir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(icon256dir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(icon256dir)" || exit $$?; \
+	done
+
+uninstall-icon256DATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(icon256_DATA)'; test -n "$(icon256dir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(icon256dir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(icon256dir)" && rm -f $$files
+install-icon32DATA: $(icon32_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(icon32dir)" || $(MKDIR_P) "$(DESTDIR)$(icon32dir)"
+	@list='$(icon32_DATA)'; test -n "$(icon32dir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(icon32dir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(icon32dir)" || exit $$?; \
+	done
+
+uninstall-icon32DATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(icon32_DATA)'; test -n "$(icon32dir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(icon32dir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(icon32dir)" && rm -f $$files
+install-icon48DATA: $(icon48_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(icon48dir)" || $(MKDIR_P) "$(DESTDIR)$(icon48dir)"
+	@list='$(icon48_DATA)'; test -n "$(icon48dir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(icon48dir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(icon48dir)" || exit $$?; \
+	done
+
+uninstall-icon48DATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(icon48_DATA)'; test -n "$(icon48dir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(icon48dir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(icon48dir)" && rm -f $$files
 install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(linuxdesktopapplicationsdir)" || $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)"
@@ -629,26 +836,6 @@ uninstall-linuxpkgconfigDATA:
 	test -n "$$files" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(linuxpkgconfigdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(linuxpkgconfigdir)" && rm -f $$files
-install-pixmapDATA: $(pixmap_DATA)
-	@$(NORMAL_INSTALL)
-	test -z "$(pixmapdir)" || $(MKDIR_P) "$(DESTDIR)$(pixmapdir)"
-	@list='$(pixmap_DATA)'; test -n "$(pixmapdir)" || list=; \
-	for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  echo "$$d$$p"; \
-	done | $(am__base_list) | \
-	while read files; do \
-	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pixmapdir)'"; \
-	  $(INSTALL_DATA) $$files "$(DESTDIR)$(pixmapdir)" || exit $$?; \
-	done
-
-uninstall-pixmapDATA:
-	@$(NORMAL_UNINSTALL)
-	@list='$(pixmap_DATA)'; test -n "$(pixmapdir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(pixmapdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(pixmapdir)" && rm -f $$files
 install-programfilesDATA: $(programfiles_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(programfilesdir)" || $(MKDIR_P) "$(DESTDIR)$(programfilesdir)"
@@ -689,6 +876,26 @@ uninstall-programfilesiconsDATA:
 	test -n "$$files" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(programfilesiconsdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(programfilesiconsdir)" && rm -f $$files
+install-svgiconDATA: $(svgicon_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(svgicondir)" || $(MKDIR_P) "$(DESTDIR)$(svgicondir)"
+	@list='$(svgicon_DATA)'; test -n "$(svgicondir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(svgicondir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(svgicondir)" || exit $$?; \
+	done
+
+uninstall-svgiconDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(svgicon_DATA)'; test -n "$(svgicondir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(svgicondir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(svgicondir)" && rm -f $$files
 tags: TAGS
 TAGS:
 
@@ -730,7 +937,7 @@ check-am: all-am
 check: check-am
 all-am: Makefile $(SCRIPTS) $(DATA)
 installdirs:
-	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(desktopdir)" "$(DESTDIR)$(linuxdesktopapplicationsdir)" "$(DESTDIR)$(linuxpkgconfigdir)" "$(DESTDIR)$(pixmapdir)" "$(DESTDIR)$(programfilesdir)" "$(DESTDIR)$(programfilesiconsdir)"; do \
+	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(desktopdir)" "$(DESTDIR)$(icon128dir)" "$(DESTDIR)$(icon16dir)" "$(DESTDIR)$(icon22dir)" "$(DESTDIR)$(icon24dir)" "$(DESTDIR)$(icon256dir)" "$(DESTDIR)$(icon32dir)" "$(DESTDIR)$(icon48dir)" "$(DESTDIR)$(linuxdesktopapplicationsdir)" "$(DESTDIR)$(linuxpkgconfigdir)" "$(DESTDIR)$(programfilesdir)" "$(DESTDIR)$(programfilesiconsdir)" "$(DESTDIR)$(svgicondir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
 install: install-am
@@ -762,7 +969,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -780,11 +987,14 @@ info: info-am
 
 info-am:
 
-install-data-am: install-desktopDATA \
+install-data-am: install-desktopDATA install-icon128DATA \
+	install-icon16DATA install-icon22DATA install-icon24DATA \
+	install-icon256DATA install-icon32DATA install-icon48DATA \
 	install-linuxdesktopapplicationsDATA \
-	install-linuxpkgconfigDATA install-pixmapDATA \
-	install-programfilesDATA install-programfilesiconsDATA
-
+	install-linuxpkgconfigDATA install-programfilesDATA \
+	install-programfilesiconsDATA install-svgiconDATA
+	@$(NORMAL_INSTALL)
+	$(MAKE) $(AM_MAKEFLAGS) install-data-hook
 install-dvi: install-dvi-am
 
 install-dvi-am:
@@ -817,7 +1027,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-am
 
@@ -828,37 +1038,61 @@ ps: ps-am
 ps-am:
 
 uninstall-am: uninstall-binSCRIPTS uninstall-desktopDATA \
-	uninstall-linuxdesktopapplicationsDATA \
-	uninstall-linuxpkgconfigDATA uninstall-pixmapDATA \
-	uninstall-pkglibSCRIPTS uninstall-programfilesDATA \
-	uninstall-programfilesiconsDATA
-
-.MAKE: install-am install-strip
-
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binSCRIPTS install-data \
-	install-data-am install-desktopDATA install-dvi install-dvi-am \
-	install-exec install-exec-am install-html install-html-am \
-	install-info install-info-am \
-	install-linuxdesktopapplicationsDATA \
+	uninstall-icon128DATA uninstall-icon16DATA \
+	uninstall-icon22DATA uninstall-icon24DATA \
+	uninstall-icon256DATA uninstall-icon32DATA \
+	uninstall-icon48DATA uninstall-linuxdesktopapplicationsDATA \
+	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
+	uninstall-programfilesDATA uninstall-programfilesiconsDATA \
+	uninstall-svgiconDATA
+	@$(NORMAL_INSTALL)
+	$(MAKE) $(AM_MAKEFLAGS) uninstall-hook
+.MAKE: install-am install-data-am install-strip uninstall-am
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binSCRIPTS install-data install-data-am \
+	install-data-hook install-desktopDATA install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-icon128DATA install-icon16DATA \
+	install-icon22DATA install-icon24DATA install-icon256DATA \
+	install-icon32DATA install-icon48DATA install-info \
+	install-info-am install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-man install-pdf \
-	install-pdf-am install-pixmapDATA install-pkglibSCRIPTS \
-	install-programfilesDATA install-programfilesiconsDATA \
-	install-ps install-ps-am install-strip installcheck \
-	installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
-	pdf-am ps ps-am uninstall uninstall-am uninstall-binSCRIPTS \
-	uninstall-desktopDATA uninstall-linuxdesktopapplicationsDATA \
-	uninstall-linuxpkgconfigDATA uninstall-pixmapDATA \
-	uninstall-pkglibSCRIPTS uninstall-programfilesDATA \
-	uninstall-programfilesiconsDATA
-
-
-all: $(ASSEMBLY) $(PROGRAMFILES) $(LINUX_DESKTOPAPPLICATIONS) $(BINARIES) $(ICON)
-
-$(ICON):
-	cp $(top_srcdir)/images/icon.svg $(ICON)
+	install-pdf-am install-pkglibSCRIPTS install-programfilesDATA \
+	install-programfilesiconsDATA install-ps install-ps-am \
+	install-strip install-svgiconDATA installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am uninstall uninstall-am uninstall-binSCRIPTS \
+	uninstall-desktopDATA uninstall-hook uninstall-icon128DATA \
+	uninstall-icon16DATA uninstall-icon22DATA uninstall-icon24DATA \
+	uninstall-icon256DATA uninstall-icon32DATA \
+	uninstall-icon48DATA uninstall-linuxdesktopapplicationsDATA \
+	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
+	uninstall-programfilesDATA uninstall-programfilesiconsDATA \
+	uninstall-svgiconDATA
+
+
+all: $(ASSEMBLY) $(PROGRAMFILES) $(LINUX_DESKTOPAPPLICATIONS) $(BINARIES)
+
+$(ICON_SVG):
+	$(INSTALL) -m644 $(top_srcdir)/images/icon.svg $@
+$(ICON_16):
+	$(INSTALL) -D -m644 $(top_srcdir)/images/icon_16x16.png $@
+$(ICON_22):
+	$(INSTALL) -D -m644 $(top_srcdir)/images/icon_22x22.png $@
+$(ICON_24):
+	$(INSTALL) -D -m644 $(top_srcdir)/images/icon_24x24.png $@
+$(ICON_32):
+	$(INSTALL) -D -m644 $(top_srcdir)/images/icon_32x32.png $@
+$(ICON_48):
+	$(INSTALL) -D -m644 $(top_srcdir)/images/icon_48x48.png $@
+$(ICON_128):
+	$(INSTALL) -D -m644 $(top_srcdir)/images/icon_128x128.png $@
+$(ICON_256):
+	$(INSTALL) -D -m644 $(top_srcdir)/images/icon_256x256.png $@
 
 # macros
 
@@ -909,6 +1143,17 @@ $(ASSEMBLY) $(ASSEMBLY_MDB): $(build_sources) $(build_resources) $(build_datafil
 %.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po-Frontend-GNOME/*.po)
 	LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po-Frontend-GNOME/.intltool-merge-cache $(top_srcdir)/po-Frontend-GNOME $< $@
 
+install-data-hook: update-icon-cache
+uninstall-hook: update-icon-cache
+update-icon-cache:
+	@-if test -z "$(DESTDIR)"; then \
+		echo "Updating Gtk icon cache."; \
+		$(gtk_update_icon_cache); \
+	else \
+		echo "*** Icon cache not updated.  After (un)install, run this:"; \
+		echo "***   $(gtk_update_icon_cache)"; \
+	fi
+
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
diff --git a/src/Frontend-GNOME/NetworkManager.cs b/src/Frontend-GNOME/NetworkManager.cs
new file mode 100644
index 0000000..87a35f1
--- /dev/null
+++ b/src/Frontend-GNOME/NetworkManager.cs
@@ -0,0 +1,142 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2011 Mirco Bauer <meebey at meebey.net>
+// 
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+// 
+// 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
+
+#if IPC_DBUS
+using System;
+    #if DBUS_SHARP
+using DBus;
+    #else
+using NDesk.DBus;
+    #endif
+using Smuxi.Common;
+
+namespace Smuxi.Frontend.Gnome
+{
+    public enum StateNM8 : int {
+        Unknown = 0,
+        Asleep,
+        Connecting,
+        Connected,
+        Disconnected
+    }
+
+    public enum StateNM9 : int {
+        Unknown         = 0,
+        Asleep          = 10,
+        Disconnected    = 20,
+        Disconnecting   = 30,
+        Connecting      = 40,
+        ConnectedLocal  = 50,
+        ConnectedSite   = 60,
+        ConnectedGlobal = 70
+    }
+
+    public delegate void StateChangedEventHandler(int state);
+
+    [Interface("org.freedesktop.NetworkManager")]
+    public interface INetworkManager
+    {
+        string Version();
+        event StateChangedEventHandler StateChanged;
+    }
+
+    public class NetworkManager
+    {
+#if LOG4NET
+        private static readonly log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+#endif
+        const string BusName = "org.freedesktop.NetworkManager";
+        const string ObjectPath = "/org/freedesktop/NetworkManager";
+        INetworkManager Manager { get; set; }
+        ChatViewManager ChatViewManager { get; set; }
+        bool IsInitialized { get; set; }
+        bool WasLocalEngine { get; set; }
+
+        public NetworkManager(ChatViewManager chatViewManager)
+        {
+            if (chatViewManager == null) {
+                throw new ArgumentNullException("mainWindow");
+            }
+
+            ChatViewManager = chatViewManager;
+
+            try {
+                Init();
+            } catch (Exception ex) {
+#if LOG4NET
+                Logger.Error("NetworkManager(): initialization failed: ", ex);
+#endif
+            }
+        }
+
+        void Init()
+        {
+            BusG.Init();
+
+            if (!Bus.System.NameHasOwner(BusName)) {
+                return;
+            }
+
+            Manager = Bus.System.GetObject<INetworkManager>(
+                BusName, new ObjectPath(ObjectPath)
+            );
+            Manager.StateChanged += OnStateChanged;
+
+            IsInitialized = true;
+        }
+
+        void OnStateChanged(int state)
+        {
+            Trace.Call(state);
+
+            if (!Frontend.HadSession) {
+                return;
+            }
+
+            switch (state) {
+                case (int) StateNM9.Disconnecting:
+                    if (!Frontend.IsLocalEngine) {
+                        Frontend.DisconnectEngineFromGUI(true);
+                    }
+                    break;
+                case (int) StateNM8.Disconnected:
+                case (int) StateNM9.Disconnected:
+                    WasLocalEngine = Frontend.IsLocalEngine;
+                    if (!Frontend.IsLocalEngine) {
+                        Frontend.DisconnectEngineFromGUI(false);
+                    }
+                    break;
+                case (int) StateNM8.Connected:
+                case (int) StateNM9.ConnectedSite:
+                case (int) StateNM9.ConnectedGlobal:
+                    if (WasLocalEngine) {
+                        // reconnect local protocol managers
+                        foreach (var protocolManager in Frontend.Session.ProtocolManagers) {
+                            protocolManager.Reconnect(Frontend.FrontendManager);
+                        }
+                    } else {
+                        Frontend.ReconnectEngineToGUI(false);
+                    }
+                    break;
+            }
+        }
+    }
+}
+#endif
diff --git a/src/Frontend-GNOME/Notebook.cs b/src/Frontend-GNOME/Notebook.cs
index 34ddb89..c67312b 100644
--- a/src/Frontend-GNOME/Notebook.cs
+++ b/src/Frontend-GNOME/Notebook.cs
@@ -1,13 +1,7 @@
 /*
- * $Id$
- * $URL$
- * $Rev$
- * $Author$
- * $Date$
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2007-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -27,7 +21,7 @@
  */
 
 using System;
-
+using System.Threading;
 using Smuxi.Common;
 using Smuxi.Engine;
 
@@ -60,26 +54,21 @@ namespace Smuxi.Frontend.Gnome
                 return f_IsBrowseModeEnabled;
             }
             set {
-                if (value && !f_IsBrowseModeEnabled) {
+                f_IsBrowseModeEnabled = value;
+                if (value) {
 #if LOG4NET
                     f_Logger.Debug("set_IsBrowseModeEnabled(): enabling browse mode");
 #endif
-                    SwitchPage -= OnBeforeSwitchPage;
-                    SwitchPage -= OnSwitchPage;
-                }
-                if (!value && f_IsBrowseModeEnabled) {
+                } else {
 #if LOG4NET
                     f_Logger.Debug("set_IsBrowseModeEnabled(): disabling browse mode");
 #endif
-                    SwitchPage += OnBeforeSwitchPage;
-                    SwitchPage += OnSwitchPage;
-
-                    // HACK: force switch page event
+                    // HACK: force switch page event to clear activity and
+                    // update the markerline
                     var chat = CurrentChatView;
                     CurrentChatView = null;
                     CurrentChatView = chat;
                 }
-                f_IsBrowseModeEnabled = value;
             }
         }
 
@@ -94,8 +83,9 @@ namespace Smuxi.Frontend.Gnome
             Scrollable = true;
             SwitchPage += OnSwitchPage;
             SwitchPage += OnBeforeSwitchPage;
+            PageReordered += OnPageReordered;
         }
-        
+
         public void ApplyConfig(UserConfig userConfig)
         {
             switch ((string) userConfig["Interface/Notebook/TabPosition"]) {
@@ -160,7 +150,8 @@ namespace Smuxi.Frontend.Gnome
             // this also breaks the Frontend.ReconnectEngineToGUI() as that one
             // has to cleanup all chats regardless of a working network
             // connection
-            IsBrowseModeEnabled = true;
+            SwitchPage -= OnBeforeSwitchPage;
+            SwitchPage -= OnSwitchPage;
 
             int npages = NPages;
             CurrentPage = 0;
@@ -174,13 +165,20 @@ namespace Smuxi.Frontend.Gnome
             }
 
             // reconnect the event handler
-            IsBrowseModeEnabled = false;
+            SwitchPage += OnBeforeSwitchPage;
+            SwitchPage += OnSwitchPage;
         }
 
         public void SyncPagePositions()
         {
             Trace.Call();
 
+            if (Frontend.EngineVersion >= new Version("0.8.1.2")) {
+                // no need to sync chat positions with 0.8.1.2 as they get
+                // updated via Session.MoveChat()
+                return;
+            }
+
             for (int i = 0; i < NPages; i++) {
                 var chatView = (ChatView) GetNthPage(i);
                 chatView.ChatModel.Position = i;
@@ -214,13 +212,17 @@ namespace Smuxi.Frontend.Gnome
             Trace.Call(sender, e);
 
 #if LOG4NET
-            f_Logger.Debug("OnSwitchPageQueueAbortedEvent(): task queue aborted!");
+            f_Logger.Fatal("OnSwitchPageQueueAbortedEvent(): task queue aborted!");
 #endif
         }
 
         [GLib.ConnectBefore]
         protected virtual void OnBeforeSwitchPage(object sender, Gtk.SwitchPageArgs e)
         {
+            if (f_IsBrowseModeEnabled) {
+                return;
+            }
+
             var chatView = CurrentChatView;
             chatView.OutputMessageTextView.UpdateMarkerline();
         }
@@ -228,7 +230,11 @@ namespace Smuxi.Frontend.Gnome
         protected virtual void OnSwitchPage(object sender, Gtk.SwitchPageArgs e)
         {
             Trace.Call(sender, e);
-            
+
+            if (f_IsBrowseModeEnabled) {
+                return;
+            }
+
             // synchronize FrontManager.CurrenPage
             ChatView chatView = GetChat((int)e.PageNum);
             if (chatView == null) {
@@ -248,38 +254,67 @@ namespace Smuxi.Frontend.Gnome
                 // a non-main (GUI) thread!
                 Trace.Call(method, null, null);
 
-                DateTime start = DateTime.UtcNow, stop;
-                // OPT-TODO: we could use here a TaskStack instead which
-                // would make sure only the newest task gets executed
-                // instead of every task in the FIFO sequence!
-                // REMOTING CALL 1
-                IProtocolManager nmanager = chatModel.ProtocolManager;
-
-                // TODO: only set the protocol manager and update network
-                // status if the protocol manager differs from the old one
-
-                // REMOTING CALL 2
-                Frontend.FrontendManager.CurrentChat = chatModel;
-                if (nmanager != null) {
-                    // REMOTING CALL 3
-                    Frontend.FrontendManager.CurrentProtocolManager = nmanager;
+                try {
+                    DateTime start = DateTime.UtcNow, stop;
+                    // OPT-TODO: we could use here a TaskStack instead which
+                    // would make sure only the newest task gets executed
+                    // instead of every task in the FIFO sequence!
+                    // REMOTING CALL 1
+                    IProtocolManager nmanager = chatModel.ProtocolManager;
+
+                    // TODO: only set the protocol manager and update network
+                    // status if the protocol manager differs from the old one
+
+                    // REMOTING CALL 2
+                    Frontend.FrontendManager.CurrentChat = chatModel;
+                    if (nmanager != null) {
+                        // REMOTING CALL 3
+                        Frontend.FrontendManager.CurrentProtocolManager = nmanager;
+                    }
+
+                    // even when we have no network manager, we still want to update
+                    // the network status and title
+                    // REMOTING CALL 4
+                    Frontend.FrontendManager.UpdateNetworkStatus();
+
+                    // update last seen highlight
+                    // REMOTING CALL 5
+                    if (lastMsg != null && !Frontend.UseLowBandwidthMode) {
+                        chatModel.LastSeenHighlight = lastMsg.TimeStamp;
+                    }
+
+                    stop = DateTime.UtcNow;
+#if LOG4NET
+                    f_Logger.Debug("OnSwitchPage(): task took: " + (stop - start).Milliseconds + " ms");
+#endif
+                } catch (Exception ex) {
+#if LOG4NET
+                    f_Logger.Error("OnSwitchPage(): Exception", ex);
+#endif
+                    Frontend.ShowException(ex);
                 }
+            });
+        }
 
-                // even when we have no network manager, we still want to update
-                // the network status and title
-                // REMOTING CALL 4
-                Frontend.FrontendManager.UpdateNetworkStatus();
+        protected virtual void OnPageReordered(object sender, Gtk.PageReorderedArgs e)
+        {
+            Trace.Call(sender, e);
 
-                // update last seen highlight
-                // REMOTING CALL 5
-                if (lastMsg != null) {
-                    chatModel.LastSeenHighlight = lastMsg.TimeStamp;
-                }
+            if (Frontend.EngineVersion < new Version("0.8.1.2")) {
+                // Session.MoveChat() was added in >= 0.8.1.2
+                return;
+            }
 
-                stop = DateTime.UtcNow;
+            var chatView = (ChatView) e.P0;
+            var newPosition = (int) e.P1;
+            ThreadPool.QueueUserWorkItem(delegate {
+                try {
+                    Frontend.Session.MoveChat(chatView.ChatModel, newPosition);
+                } catch (Exception ex) {
 #if LOG4NET
-                f_Logger.Debug("OnSwitchPage(): task took: " + (stop - start).Milliseconds + " ms");
+                    f_Logger.Error("OnPageReordered(): Exception", ex);
 #endif
+                }
             });
         }
     }
diff --git a/src/Frontend-GNOME/NotifyManager.cs b/src/Frontend-GNOME/NotifyManager.cs
index 4223433..ec46097 100644
--- a/src/Frontend-GNOME/NotifyManager.cs
+++ b/src/Frontend-GNOME/NotifyManager.cs
@@ -1,6 +1,6 @@
 // Smuxi - Smart MUltipleXed Irc
 // 
-// Copyright (c) 2010 Mirco Bauer <meebey at meebey.net>
+// Copyright (c) 2010-2011 Mirco Bauer <meebey at meebey.net>
 // 
 // Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
 // 
@@ -35,7 +35,9 @@ namespace Smuxi.Frontend.Gnome
 #endif
         private static DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
         private static Gdk.Pixbuf PersonChatIconPixbuf { get; set; }
+        private static string     PersonChatIconName { get; set; }
         private static Gdk.Pixbuf GroupChatIconPixbuf { get; set; }
+        private static string     GroupChatIconName { get; set; }
         private static List<string> Capabilites { get; set; }
         private static string SoundFile { get; set; }
         private static Version SpecificationVersion { get; set; }
@@ -43,16 +45,19 @@ namespace Smuxi.Frontend.Gnome
         MainWindow MainWindow { get; set; }
         ChatViewManager ChatViewManager { get; set; }
         Dictionary<ChatView, MessageTextViewMessageHighlightedEventHandler> HighlightEventHandlers { get; set; }
+        bool IsInitialized { get; set; }
         bool IsEnabled { get; set; }
 
         static NotifyManager()
         {
-            // 128 pixels as per notify-osd guidelines:
+            // image size >= 128 pixels as per notify-osd guidelines:
             // https://wiki.ubuntu.com/NotificationDevelopmentGuidelines
-            PersonChatIconPixbuf = new Gdk.Pixbuf(null, "person-chat.svg",
-                                                  128, 128);
-            GroupChatIconPixbuf = new Gdk.Pixbuf(null, "group-chat.svg",
-                                                 128, 128);
+            PersonChatIconPixbuf = Frontend.LoadIcon(
+                "smuxi-person-chat", 256, "person-chat_256x256.png"
+            );
+            GroupChatIconPixbuf = Frontend.LoadIcon(
+                "smuxi-group-chat", 256, "group-chat_256x256.png"
+            );
 
             var partialPath = "share";
             partialPath = Path.Combine(partialPath, "sounds");
@@ -88,7 +93,13 @@ namespace Smuxi.Frontend.Gnome
                 <ChatView,
                  MessageTextViewMessageHighlightedEventHandler>();
 
-            Init();
+            try {
+                Init();
+            } catch (Exception ex) {
+#if LOG4NET
+                Logger.Error("NotifyManager(): initialization failed: ", ex);
+#endif
+            }
         }
         
         public void Dispose()
@@ -104,6 +115,10 @@ namespace Smuxi.Frontend.Gnome
                 throw new ArgumentNullException("userConfig");
             }
 
+            if (!IsInitialized) {
+                return;
+            }
+
             IsEnabled = (bool) userConfig["Interface/Notification/PopupsEnabled"];
         }
 
@@ -155,6 +170,8 @@ namespace Smuxi.Frontend.Gnome
 
             ChatViewManager.ChatAdded   += OnChatViewManagerChatAdded;
             ChatViewManager.ChatRemoved += OnChatViewManagerChatRemoved;
+
+            IsInitialized = true;
         }
 
         void OnChatViewManagerChatAdded(object sender, ChatViewManagerChatAddedEventArgs e)
@@ -190,18 +207,39 @@ namespace Smuxi.Frontend.Gnome
                                           MessageTextViewMessageHighlightedEventArgs e,
                                           ChatView chatView)
         {
+#if MSG_DEBUG
             Trace.Call(sender, e, chatView);
+#endif
 
-            if (MainWindow.HasToplevelFocus || !IsEnabled) {
+            if (!IsEnabled ||
+                e.Message.TimeStamp <= chatView.SyncedLastSeenHighlight ||
+                (MainWindow.HasToplevelFocus &&
+                 chatView.LabelWidget.IsDrawable)) {
+                // no need to show a notification for:
+                // - disabled chats
+                // - seen highlights
+                // - main window has focus and the chat tab is visible
                 return;
             }
 
+            try {
+                ShowNotification(chatView, e.Message);
+            } catch (Exception ex) {
+#if LOG4NET
+                Logger.Error("OnChatViewMessageHighlighted(): " +
+                             "ShowNotification() threw exception", ex);
+#endif
+            }
+        }
+
+        void ShowNotification(ChatView chatView, MessageModel msg)
+        {
             Notification notification;
             if (!Capabilites.Contains("append") &&
                 Notifications.TryGetValue(chatView, out notification)) {
                 // no support for append, update the existing notification
                 notification.Body = GLib.Markup.EscapeText(
-                    e.Message.ToString()
+                    msg.ToString()
                 );
                 return;
             }
@@ -213,7 +251,7 @@ namespace Smuxi.Frontend.Gnome
             if (Capabilites.Contains("body")) {
                 // notify-osd doesn't like unknown tags when appending
                 notification.Body = GLib.Markup.EscapeText(
-                    e.Message.ToString()
+                    msg.ToString()
                 );
             }
             //notification.IconName = "notification-message-im";
@@ -228,9 +266,7 @@ namespace Smuxi.Frontend.Gnome
             if (Capabilites.Contains("actions")) {
                 notification.AddAction("show", _("Show"), delegate {
                     try {
-                        MainWindow.PresentWithTime(
-                            (uint) (DateTime.UtcNow - UnixEpoch).TotalSeconds
-                        );
+                        MainWindow.Present();
                         MainWindow.Notebook.CurrentChatView = chatView;
                         notification.Close();
                     } catch (Exception ex) {
@@ -259,17 +295,22 @@ namespace Smuxi.Frontend.Gnome
                 }
             }
             notification.Closed += delegate {
-                Notifications.Remove(chatView);
-            };
-
-            try {
-                notification.Show();
-            } catch (Exception ex) {
+                try {
 #if LOG4NET
-                Logger.Error("OnChatViewMessageHighlighted(): " +
-                             " notification.Show() threw exception", ex);
+                    Logger.Debug("OnChatViewMessageHighlighted(): received " +
+                                 "notification.Closed signal for: " +
+                                 chatView.Name);
 #endif
-            }
+                    Notifications.Remove(chatView);
+                } catch (Exception ex) {
+#if LOG4NET
+                    Logger.Error("OnChatViewMessageHighlighted(): " +
+                                 "Exception in notification.Closed handler",
+                                 ex);
+#endif
+                }
+            };
+            notification.Show();
 
             if (!Notifications.ContainsKey(chatView)) {
                 Notifications.Add(chatView, notification);
@@ -278,13 +319,31 @@ namespace Smuxi.Frontend.Gnome
 
         void OnMainWindowFocusInEvent(object sender, Gtk.FocusInEventArgs e)
         {
+            Trace.Call(sender, e);
+
+            if (MainWindow.Notebook.IsBrowseModeEnabled) {
+                return;
+            }
+
             var currentChatView = MainWindow.Notebook.CurrentChatView;
+            if (currentChatView == null) {
+                return;
+            }
             DisposeNotification(currentChatView);
         }
 
         void OnMainWindowNotebookSwitchPage(object sender, Gtk.SwitchPageArgs e)
         {
+            Trace.Call(sender, e);
+
+            if (MainWindow.Notebook.IsBrowseModeEnabled) {
+                return;
+            }
+
             var currentChatView = MainWindow.Notebook.CurrentChatView;
+            if (currentChatView == null) {
+                return;
+            }
             DisposeNotification(currentChatView);
         }
 
@@ -299,7 +358,25 @@ namespace Smuxi.Frontend.Gnome
                          chatView.Name);
 #endif
 
-            notification.Close();
+            try {
+                // don't try to close already closed notifications (timeout)
+                if (notification.Id == 0) {
+#if LOG4NET
+                    Logger.Debug("DisposeNotification(): notification already " +
+                                 "closed for: " + chatView.Name);
+#endif
+                    return;
+                }
+
+                notification.Close();
+            } catch (Exception ex) {
+#if LOG4NET
+                Logger.Error("DisposeNotification(): " +
+                             "notification.Close() thew exception", ex);
+#endif
+            } finally {
+                Notifications.Remove(chatView);
+            }
         }
 
         private static string _(string msg)
diff --git a/src/Frontend-GNOME/PangoTools.cs b/src/Frontend-GNOME/PangoTools.cs
index 733df95..b9d808c 100644
--- a/src/Frontend-GNOME/PangoTools.cs
+++ b/src/Frontend-GNOME/PangoTools.cs
@@ -65,12 +65,13 @@ namespace Smuxi.Frontend.Gnome
                     
                     Gdk.Color gdkColor = Gdk.Color.Zero;
                     Gdk.Color.Parse("darkblue", ref gdkColor);
-                    TextColor urlColor = ColorTools.GetTextColor(gdkColor);
+                    TextColor urlColor = ColorConverter.GetTextColor(gdkColor);
                     if (bgColor != null) {
                         // we have a bg color so lets try to get a url color
                         // with a good contrast
-                        urlColor = ColorTools.GetBestTextColor(
-                            urlColor, ColorTools.GetTextColor(bgColor.Value));
+                        urlColor = TextColorTools.GetBestTextColor(
+                            urlColor, ColorConverter.GetTextColor(bgColor.Value)
+                        );
                     }
 
                     str = String.Format("<span color='#{0}'><u>{1}</u></span>",
@@ -87,9 +88,12 @@ namespace Smuxi.Frontend.Gnome
                         if (bgColor == null) {
                             fgColor = text.ForegroundColor;
                         } else {
-                            var bgTextColor = ColorTools.GetTextColor(bgColor.Value);
-                            fgColor = ColorTools.GetBestTextColor(
-                                text.ForegroundColor, bgTextColor);
+                            var bgTextColor = ColorConverter.GetTextColor(
+                                bgColor.Value
+                            );
+                            fgColor = TextColorTools.GetBestTextColor(
+                                text.ForegroundColor, bgTextColor
+                            );
                         }
                         tags.Add(String.Format("span color='#{0}'",
                                                 fgColor.HexCode));
diff --git a/src/Frontend-GNOME/Preferences/PreferencesDialog.cs b/src/Frontend-GNOME/Preferences/PreferencesDialog.cs
index cbeceee..20ee6d1 100644
--- a/src/Frontend-GNOME/Preferences/PreferencesDialog.cs
+++ b/src/Frontend-GNOME/Preferences/PreferencesDialog.cs
@@ -137,7 +137,7 @@ namespace Smuxi.Frontend.Gnome
             ((Gtk.CheckButton)_Glade["OverrideForegroundColorCheckButton"]).Toggled += OnOverrideForegroundColorCheckButtonToggled;
             ((Gtk.CheckButton)_Glade["OverrideBackgroundColorCheckButton"]).Toggled += OnOverrideBackgroundColorCheckButtonToggled;
             ((Gtk.CheckButton)_Glade["OverrideFontCheckButton"]).Toggled += OnOverrideFontCheckButtonToggled;
-
+            ((Gtk.FontButton)_Glade["FontButton"]).FontSet += _OnChanged;
             ((Gtk.CheckButton)_Glade["ShowAdvancedSettingsCheckButton"]).Toggled += delegate {
                 CheckShowAdvancedSettingsCheckButton();
             };
@@ -181,6 +181,30 @@ namespace Smuxi.Frontend.Gnome
             wrapModeComboBox.Model = store;
             wrapModeComboBox.Active = 0;
             
+            Gtk.ComboBox persistencyTypeComboBox =
+                (Gtk.ComboBox) _Glade["PersistencyTypeComboBox"];
+            // glade might initialize it already!
+            persistencyTypeComboBox.Clear();
+            persistencyTypeComboBox.Changed += _OnChanged;
+            cell = new Gtk.CellRendererText();
+            persistencyTypeComboBox.PackStart(cell, false);
+            persistencyTypeComboBox.AddAttribute(cell, "text", 1);
+            store = new Gtk.ListStore(
+                typeof(MessageBufferPersistencyType), typeof(string)
+            );
+            // fill ListStore
+            store.AppendValues(MessageBufferPersistencyType.Volatile,
+                               _("Volatile"));
+            store.AppendValues(MessageBufferPersistencyType.Persistent,
+                               _("Persistent"));
+            persistencyTypeComboBox.Model = store;
+            persistencyTypeComboBox.Active = 0;
+            if (Frontend.EngineVersion < new Version("0.8.1")) {
+                persistencyTypeComboBox.Sensitive = false;
+                ((Gtk.SpinButton) _Glade["VolatileMaxCapacitySpinButton"]).Sensitive = false;
+                ((Gtk.SpinButton) _Glade["PersistentMaxCapacitySpinButton"]).Sensitive = false;
+            }
+
             Gtk.ComboBox proxyTypeComboBox = (Gtk.ComboBox)_Glade["ProxyTypeComboBox"];
             // initialize wrap modes
             // glade might initialize it already!
@@ -196,6 +220,8 @@ namespace Smuxi.Frontend.Gnome
             // fill ListStore
             store.AppendValues(ProxyType.None,    String.Format("<{0}>",
                                                                 _("No Proxy")));
+            store.AppendValues(ProxyType.System,  String.Format("<{0}>",
+                                                                _("System Default")));
             store.AppendValues(ProxyType.Http,    "HTTP");
             store.AppendValues(ProxyType.Socks4,  "SOCK 4");
             store.AppendValues(ProxyType.Socks4a, "SOCK 4a");
@@ -285,7 +311,12 @@ namespace Smuxi.Frontend.Gnome
                 try {
                     Encoding enc = Encoding.GetEncoding(encInfo.CodePage);
                     string encodingName = enc.EncodingName.ToUpper();
-                    
+
+                    if (!enc.IsSingleByte && enc != Encoding.UTF8) {
+                        // ignore multi byte encodings except UTF-8
+                        continue;
+                    }
+
                     // filter noise and duplicates
                     if (encodingName.IndexOf("DOS") != -1 ||
                         encodingName.IndexOf("MAC") != -1 ||
@@ -350,6 +381,29 @@ namespace Smuxi.Frontend.Gnome
                 (string) Frontend.UserConfig["Connection/ProxyPassword"];
             CheckProxyShowPasswordCheckButton();
 
+            // MessageBuffer
+            if (Frontend.EngineVersion >= new Version("0.8.1")) {
+                // feature introduced in >= 0.8.1
+                Gtk.ComboBox persistencyTypeComboBox =
+                    ((Gtk.ComboBox)_Glade["PersistencyTypeComboBox"]);
+                var persistencyType = (MessageBufferPersistencyType) Enum.Parse(
+                    typeof(MessageBufferPersistencyType),
+                    (string) Frontend.UserConfig["MessageBuffer/PersistencyType"]
+                );
+                i = 0;
+                foreach (object[] row in (Gtk.ListStore) persistencyTypeComboBox.Model) {
+                    if (((MessageBufferPersistencyType) row[0]) == persistencyType) {
+                        persistencyTypeComboBox.Active = i;
+                        break;
+                    }
+                    i++;
+                }
+                ((Gtk.SpinButton)_Glade["VolatileMaxCapacitySpinButton"]).Value =
+                    (double)(int)Frontend.UserConfig["MessageBuffer/Volatile/MaxCapacity"];
+                ((Gtk.SpinButton)_Glade["PersistentMaxCapacitySpinButton"]).Value =
+                    (double)(int)Frontend.UserConfig["MessageBuffer/Persistent/MaxCapacity"];
+            }
+
             // Interface
             ((Gtk.CheckButton) _Glade["ShowAdvancedSettingsCheckButton"]).Active =
                 (bool) Frontend.UserConfig["Interface/ShowAdvancedSettings"];
@@ -416,19 +470,19 @@ namespace Smuxi.Frontend.Gnome
             
             colorButton = (Gtk.ColorButton)_Glade["NoActivityColorButton"];
             colorHexCode = (string)Frontend.UserConfig["Interface/Notebook/Tab/NoActivityColor"];
-            colorButton.Color = ColorTools.GetGdkColor(colorHexCode);
+            colorButton.Color = ColorConverter.GetGdkColor(colorHexCode);
 
             colorButton = (Gtk.ColorButton)_Glade["ActivityColorButton"];
             colorHexCode = (string)Frontend.UserConfig["Interface/Notebook/Tab/ActivityColor"];
-            colorButton.Color = ColorTools.GetGdkColor(colorHexCode);
+            colorButton.Color = ColorConverter.GetGdkColor(colorHexCode);
 
             colorButton = (Gtk.ColorButton)_Glade["ModeColorButton"];
             colorHexCode = (string)Frontend.UserConfig["Interface/Notebook/Tab/EventColor"];
-            colorButton.Color = ColorTools.GetGdkColor(colorHexCode);
+            colorButton.Color = ColorConverter.GetGdkColor(colorHexCode);
             
             colorButton = (Gtk.ColorButton)_Glade["HighlightColorButton"];
             colorHexCode = (string)Frontend.UserConfig["Interface/Notebook/Tab/HighlightColor"];
-            colorButton.Color = ColorTools.GetGdkColor(colorHexCode);
+            colorButton.Color = ColorConverter.GetGdkColor(colorHexCode);
             
             // Interface/Chat
             colorButton = (Gtk.ColorButton)_Glade["ForegroundColorButton"];
@@ -437,7 +491,7 @@ namespace Smuxi.Frontend.Gnome
                 ((Gtk.CheckButton)_Glade["OverrideForegroundColorCheckButton"]).Active = false;
             } else {
                 ((Gtk.CheckButton)_Glade["OverrideForegroundColorCheckButton"]).Active = true;
-                colorButton.Color = ColorTools.GetGdkColor(colorHexCode);
+                colorButton.Color = ColorConverter.GetGdkColor(colorHexCode);
             }
             
             colorButton = (Gtk.ColorButton)_Glade["BackgroundColorButton"];
@@ -446,7 +500,7 @@ namespace Smuxi.Frontend.Gnome
                 ((Gtk.CheckButton)_Glade["OverrideBackgroundColorCheckButton"]).Active = false;
             } else {
                 ((Gtk.CheckButton)_Glade["OverrideBackgroundColorCheckButton"]).Active = true;
-                colorButton.Color = ColorTools.GetGdkColor(colorHexCode);
+                colorButton.Color = ColorConverter.GetGdkColor(colorHexCode);
             }
             
             Gtk.FontButton fontButton = (Gtk.FontButton)_Glade["FontButton"];
@@ -624,6 +678,27 @@ namespace Smuxi.Frontend.Gnome
             Frontend.UserConfig["Connection/ProxyPassword"] =
                 ((Gtk.Entry) _Glade["ProxyPasswordEntry"]).Text;
 
+            int i;
+            // MessageBuffer
+            if (Frontend.EngineVersion >= new Version("0.8.1")) {
+                var persistencyTypeComboBox = (Gtk.ComboBox) _Glade["PersistencyTypeComboBox"];
+                var persistencyType = MessageBufferPersistencyType.Volatile;
+                i = 0;
+                foreach (object[] row in (Gtk.ListStore) persistencyTypeComboBox.Model) {
+                    if (persistencyTypeComboBox.Active == i) {
+                        persistencyType = (MessageBufferPersistencyType) row[0];
+                        break;
+                    }
+                    i++;
+                }
+                Frontend.UserConfig["MessageBuffer/PersistencyType"] =
+                    persistencyType.ToString();
+                Frontend.UserConfig["MessageBuffer/Volatile/MaxCapacity"] =
+                    (int)((Gtk.SpinButton)_Glade["VolatileMaxCapacitySpinButton"]).Value;
+                Frontend.UserConfig["MessageBuffer/Persistent/MaxCapacity"] =
+                    (int)((Gtk.SpinButton)_Glade["PersistentMaxCapacitySpinButton"]).Value;
+            }
+
             // Interface
             Frontend.UserConfig["Interface/ShowAdvancedSettings"] =
                 ((Gtk.CheckButton)_Glade["ShowAdvancedSettingsCheckButton"]).Active;
@@ -636,7 +711,7 @@ namespace Smuxi.Frontend.Gnome
                 (int)((Gtk.SpinButton)_Glade["EngineBufferLinesSpinButton"]).Value;
             Frontend.UserConfig["Interface/Notebook/StripColors"] =
                 ((Gtk.CheckButton)_Glade["StripColorsCheckButton"]).Active;
-            Frontend.UserConfig["Interface/Notebook/StripFormatting"] =
+            Frontend.UserConfig["Interface/Notebook/StripFormattings"] =
                 ((Gtk.CheckButton)_Glade["StripFormattingsCheckButton"]).Active;
                 
             string tab_position = null;
@@ -679,25 +754,25 @@ namespace Smuxi.Frontend.Gnome
             // Interface/Notebook/Tab
             prefix = "Interface/Notebook/Tab/";
             Frontend.UserConfig[prefix + "NoActivityColor"] =
-                ColorTools.GetHexCodeColor(((Gtk.ColorButton)_Glade["NoActivityColorButton"]).Color);
+                ColorConverter.GetHexCode(((Gtk.ColorButton)_Glade["NoActivityColorButton"]).Color);
             Frontend.UserConfig[prefix + "ActivityColor"] =
-                ColorTools.GetHexCodeColor(((Gtk.ColorButton)_Glade["ActivityColorButton"]).Color);
+                ColorConverter.GetHexCode(((Gtk.ColorButton)_Glade["ActivityColorButton"]).Color);
             Frontend.UserConfig[prefix + "EventColor"] =
-                ColorTools.GetHexCodeColor(((Gtk.ColorButton)_Glade["ModeColorButton"]).Color);
+                ColorConverter.GetHexCode(((Gtk.ColorButton)_Glade["ModeColorButton"]).Color);
             Frontend.UserConfig[prefix + "HighlightColor"] =
-                ColorTools.GetHexCodeColor(((Gtk.ColorButton)_Glade["HighlightColorButton"]).Color);
+                ColorConverter.GetHexCode(((Gtk.ColorButton)_Glade["HighlightColorButton"]).Color);
             
             // Interface/Chat
             prefix = "Interface/Chat/";
             if (((Gtk.CheckButton)_Glade["OverrideForegroundColorCheckButton"]).Active) {
                 Frontend.UserConfig[prefix + "ForegroundColor"] = 
-                    ColorTools.GetHexCodeColor(((Gtk.ColorButton)_Glade["ForegroundColorButton"]).Color);
+                    ColorConverter.GetHexCode(((Gtk.ColorButton)_Glade["ForegroundColorButton"]).Color);
             } else {
                 Frontend.UserConfig[prefix + "ForegroundColor"] = String.Empty;
             }
             if (((Gtk.CheckButton)_Glade["OverrideBackgroundColorCheckButton"]).Active) {
                 Frontend.UserConfig[prefix + "BackgroundColor"] = 
-                    ColorTools.GetHexCodeColor(((Gtk.ColorButton)_Glade["BackgroundColorButton"]).Color);
+                    ColorConverter.GetHexCode(((Gtk.ColorButton)_Glade["BackgroundColorButton"]).Color);
             } else {
                 Frontend.UserConfig[prefix + "BackgroundColor"] = String.Empty;
             }
@@ -715,7 +790,7 @@ namespace Smuxi.Frontend.Gnome
             
             Gtk.ComboBox wrapModeComboBox = (Gtk.ComboBox) _Glade["WrapModeComboBox"];
             Gtk.WrapMode wrapMode = Gtk.WrapMode.Char;
-            int i = 0;
+            i = 0;
             foreach (object[] row in (Gtk.ListStore) wrapModeComboBox.Model) {
                 if (wrapModeComboBox.Active == i) {
                     wrapMode = (Gtk.WrapMode) row[0];
@@ -807,7 +882,6 @@ namespace Smuxi.Frontend.Gnome
             try {
                 _Save();
                 Frontend.Config.Load();
-                Frontend.UserConfig.ClearCache();
                 Frontend.ApplyConfig(Frontend.UserConfig);
                 _Dialog.Destroy();
             } catch (ApplicationException ex) {
@@ -827,7 +901,6 @@ namespace Smuxi.Frontend.Gnome
             try {
                 _Save();
                 Frontend.Config.Load();
-                Frontend.UserConfig.ClearCache();
                 _Load();
                 Frontend.ApplyConfig(Frontend.UserConfig);
             } catch (ApplicationException ex) {
@@ -956,6 +1029,7 @@ namespace Smuxi.Frontend.Gnome
             var proxyType = (ProxyType) typoComboBox.Model.GetValue(iter, 0);
             switch (proxyType) {
                 case ProxyType.None:
+                case ProxyType.System:
                     hostEntry.Sensitive = false;
                     portSpinButton.Sensitive = false;
                     userEntry.Sensitive = false;
diff --git a/src/Frontend-GNOME/QuickConnectDialog.cs b/src/Frontend-GNOME/QuickConnectDialog.cs
index ffb2fb8..07a967f 100644
--- a/src/Frontend-GNOME/QuickConnectDialog.cs
+++ b/src/Frontend-GNOME/QuickConnectDialog.cs
@@ -1,10 +1,4 @@
 /*
- * $Id: PreferencesDialog.cs 73 2005-06-27 12:42:06Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-GtkGnome/PreferencesDialog.cs $
- * $Rev: 73 $
- * $Author: meebey $
- * $Date: 2005-06-27 14:42:06 +0200 (Mon, 27 Jun 2005) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
  * Copyright (c) 2008, 2010 Mirco Bauer <meebey at meebey.net>
@@ -208,7 +202,7 @@ namespace Smuxi.Frontend.Gnome
             Trace.Call();
             
             f_ConnectButton.Sensitive =
-                !f_Widget.HostnameEntry.Sensitive ||
+                !f_Widget.HostnameEntry.Visible ||
                 f_Widget.HostnameEntry.Text.Trim().Length > 0;
         }
         
diff --git a/src/Frontend-GNOME/StatusIconManager.cs b/src/Frontend-GNOME/StatusIconManager.cs
index bb423eb..372f0e1 100644
--- a/src/Frontend-GNOME/StatusIconManager.cs
+++ b/src/Frontend-GNOME/StatusIconManager.cs
@@ -1,6 +1,6 @@
 // Smuxi - Smart MUltipleXed Irc
 // 
-// Copyright (c) 2010 Mirco Bauer <meebey at meebey.net>
+// Copyright (c) 2010-2011 Mirco Bauer <meebey at meebey.net>
 // 
 // Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
 // 
@@ -79,7 +79,13 @@ namespace Smuxi.Frontend.Gnome
             if (f_NotificationAreaIconMode != NotificationAreaIconMode.Never &&
                 f_StatusIcon == null) {
                 f_StatusIcon = new Gtk.StatusIcon();
-                f_StatusIcon.Pixbuf = new Gdk.Pixbuf(null, "icon.svg");
+                if (Frontend.HasSystemIconTheme) {
+                    f_StatusIcon.IconName = Frontend.IconName;
+                } else {
+                    f_StatusIcon.Pixbuf = Frontend.LoadIcon(
+                        Frontend.IconName, 256, "icon_256x256.png"
+                    );
+                }
                 f_StatusIcon.Activate += OnStatusIconActivated;
                 f_StatusIcon.PopupMenu += OnStatusIconPopupMenu;
                 f_StatusIcon.Tooltip = "Smuxi";
@@ -195,17 +201,19 @@ namespace Smuxi.Frontend.Gnome
 
         protected void OnChatViewManagerChatAdded(object sender, ChatViewManagerChatAddedEventArgs e)
         {
-            e.ChatView.OutputMessageTextView.MessageHighlighted += OnChatViewMessageHighlighted;
+            e.ChatView.MessageHighlighted += OnChatViewMessageHighlighted;
         }
 
         protected void OnChatViewManagerChatRemoved(object sender, ChatViewManagerChatRemovedEventArgs e)
         {
-            e.ChatView.OutputMessageTextView.MessageHighlighted -= OnChatViewMessageHighlighted;
+            e.ChatView.MessageHighlighted -= OnChatViewMessageHighlighted;
         }
 
-        private void OnChatViewMessageHighlighted(object sender, MessageTextViewMessageHighlightedEventArgs e)
+        private void OnChatViewMessageHighlighted(object sender, ChatViewMessageHighlightedEventArgs e)
         {
+#if MSG_DEBUG
             Trace.Call(sender, e);
+#endif
 
             if (f_StatusIcon == null) {
                 return;
diff --git a/src/Frontend-GNOME/ThemeSettings.cs b/src/Frontend-GNOME/ThemeSettings.cs
index 400794e..662cc44 100644
--- a/src/Frontend-GNOME/ThemeSettings.cs
+++ b/src/Frontend-GNOME/ThemeSettings.cs
@@ -22,6 +22,7 @@
 
 using System;
 using System.IO;
+using System.Linq;
 using Smuxi.Engine;
 
 namespace Smuxi.Frontend.Gnome
@@ -142,13 +143,29 @@ namespace Smuxi.Frontend.Gnome
             }
             Pango.FontDescription fontDescription = new Pango.FontDescription();
             if (String.IsNullOrEmpty(fontFamily)) {
-                // HACK: use fixed-sys by default if present
-                if (File.Exists("Fixedsys500c.ttf")) {
-                    fontDescription.Family = "FixedsysTTF, monospace";
-                    // fixed-sys only looks good in size 11
-                    fontDescription.Size = 11 * 1024;
-                    fontDescription.Weight = Pango.Weight.Bold;
-                    fontDescription.Style = Pango.Style.Normal;
+                // HACK: use Consolas or Fixed-Sys on Windows by default
+                if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
+                    var osVersion = Environment.OSVersion.Version;
+                    var isWinXp = osVersion.Major == 5 && osVersion.Minor > 0;
+                    var context = Frontend.MainWindow.CreatePangoContext();
+                    if (context.Families.Any(family =>
+                                             family.Name == "Consolas") &&
+                        !isWinXp) {
+                        // this system has Consolas available and is not WinXP,
+                        // let's use it!
+                        fontDescription.Family = "Consolas, monospace";
+                        // Consolas only looks good in size 11
+                        fontDescription.Size = 11 * 1024;
+                        fontDescription.Weight = Pango.Weight.Normal;
+                        fontDescription.Style = Pango.Style.Normal;
+                    } else {
+                        // too bad, fallback to FixedSys then
+                        fontDescription.Family = "FixedsysTTF, monospace";
+                        // FixedSys only looks good in size 11
+                        fontDescription.Size = 11 * 1024;
+                        fontDescription.Weight = Pango.Weight.Bold;
+                        fontDescription.Style = Pango.Style.Normal;
+                    }
                 } else {
                     // use Monospace and Bold by default
                     fontDescription.Family = "monospace";
diff --git a/src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs b/src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs
index 21f5665..1c56fea 100644
--- a/src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs
+++ b/src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs
@@ -30,6 +30,7 @@ using System;
 using System.IO;
 using Smuxi.Common;
 using Smuxi.Engine;
+using IOPath = System.IO.Path;
 
 namespace Smuxi.Frontend.Gnome
 {
@@ -231,6 +232,24 @@ namespace Smuxi.Frontend.Gnome
                     f_Config["Engines/" + f_EngineName + "/SshUsername"];
                 f_CredentialsWidget.SshPasswordEntry.Text = (string)
                     f_Config["Engines/" + f_EngineName + "/SshPassword"];
+                var sshKeyfile = (string)
+                    f_Config["Engines/" + f_EngineName + "/SshKeyfile"];
+                if (!String.IsNullOrEmpty(sshKeyfile)) {
+                    f_CredentialsWidget.SshKeyfileChooserButton.SetFilename(
+                        sshKeyfile
+                    );
+                }
+                var sshPath = IOPath.Combine(
+                    Environment.GetFolderPath(
+                        Environment.SpecialFolder.Personal
+                    ),
+                    ".ssh"
+                );
+                if (Directory.Exists(sshPath)) {
+                    f_CredentialsWidget.SshKeyfileChooserButton.SetCurrentFolder(
+                        sshPath
+                    );
+                }
                 f_CredentialsWidget.UsernameEntry.Text = (string)
                     f_Config["Engines/" + f_EngineName + "/Username"];
                 f_CredentialsWidget.PasswordEntry.Text = (string)
@@ -332,6 +351,8 @@ namespace Smuxi.Frontend.Gnome
                 f_Config["Engines/"+engine+"/SshPassword"] =
                     f_CredentialsWidget.SshPasswordEntry.Text;
             }
+            f_Config["Engines/"+engine+"/SshKeyfile"] =
+                f_CredentialsWidget.SshKeyfileChooserButton.Filename ?? String.Empty;
             f_Config["Engines/"+engine+"/SshHostname"] =
                 f_ConnectionWidget.SshHostEntry.Text.Trim();
             f_Config["Engines/"+engine+"/SshPort"] =
diff --git a/src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistantCredentialsWidget.cs b/src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistantCredentialsWidget.cs
index feb494f..2379ced 100644
--- a/src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistantCredentialsWidget.cs
+++ b/src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistantCredentialsWidget.cs
@@ -62,6 +62,12 @@ namespace Smuxi.Frontend.Gnome
             }
         }
         
+        public Gtk.FileChooserButton SshKeyfileChooserButton {
+            get {
+                return f_SshKeyfileChooserButton;
+            }
+        }
+
         public EngineAssistantCredentialsWidget()
         {
             Build();
diff --git a/src/Frontend-GNOME/Views/Chats/ChatView.cs b/src/Frontend-GNOME/Views/Chats/ChatView.cs
index 6e2ba17..90f7328 100644
--- a/src/Frontend-GNOME/Views/Chats/ChatView.cs
+++ b/src/Frontend-GNOME/Views/Chats/ChatView.cs
@@ -1,13 +1,7 @@
 /*
- * $Id$
- * $URL$
- * $Rev$
- * $Author$
- * $Date$
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2010 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -28,6 +22,7 @@
 
 using System;
 using System.Drawing;
+using System.Threading;
 using System.Collections.Generic;
 using Smuxi.Common;
 using Smuxi.Engine;
@@ -36,15 +31,16 @@ using Smuxi.Frontend;
 namespace Smuxi.Frontend.Gnome
 {
     // TODO: use Gtk.Bin
-    public abstract class ChatView : Gtk.EventBox, IChatView, IDisposable
+    public abstract class ChatView : Gtk.EventBox, IChatView, IDisposable, ITraceable
     {
 #if LOG4NET
         private static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 #endif
-        public    string             ID { get; private set; }
-        private   string             _Name;
+        public    string             ID { get; internal set; }
+        public    int                Position { get; internal set; }
         private   ChatModel          _ChatModel;
         private   bool               _HasHighlight;
+        private   int                HighlightCount { get; set; }
         private   bool               _HasActivity;
         private   bool               _HasEvent;
         private   bool               _IsSynced;
@@ -56,15 +52,31 @@ namespace Smuxi.Frontend.Gnome
         private   Gtk.ScrolledWindow _OutputScrolledWindow;
         private   MessageTextView    _OutputMessageTextView;
         private   ThemeSettings      _ThemeSettings;
-        private   DateTime           _LastHighlight;
         private   TaskQueue          _LastSeenHighlightQueue;
-        
+        public    DateTime           SyncedLastSeenHighlight { get; private set; }
+        IList<MessageModel>          SyncedMessages { get; set; }
+        protected string             SyncedName { get; set; }
+        public    IProtocolManager   ProtocolManager { get; set; }
+        bool                         UseLowBandwidthMode { get; set; }
+        protected Gtk.Image          TabImage { get; set; }
+        bool                         IsAutoScrolling { get; set; }
+
         public ChatModel ChatModel {
             get {
                 return _ChatModel;
             }
         }
 
+        public new string Name {
+            get {
+                return base.Name;
+            }
+            set {
+                base.Name = value;
+                _TabLabel.Text = value;
+            }
+        }
+
         // this property is thread-safe
         public bool IsActive {
             get {
@@ -84,24 +96,37 @@ namespace Smuxi.Frontend.Gnome
             }
             set {
                 _HasHighlight = value;
-                
+                HighlightCount++;
+
                 if (!value) {
                     // clear highlight with "no activity"
                     HasActivity = false;
+                    HighlightCount = 0;
                     return;
                 }
 
-                var color = ColorTools.GetBestTextColor(
-                    ColorTools.GetTextColor(_ThemeSettings.HighlightColor),
-                    ColorTools.GetTextColor(
+                var color = TextColorTools.GetBestTextColor(
+                    ColorConverter.GetTextColor(_ThemeSettings.HighlightColor),
+                    ColorConverter.GetTextColor(
                         Gtk.Rc.GetStyle(_TabLabel).Base(Gtk.StateType.Normal)
-                    ), ColorContrast.High
-                );
-                _TabLabel.Markup = String.Format(
-                    "<span foreground=\"{0}\">{1}</span>",
-                    GLib.Markup.EscapeText(color.ToString()),
-                    GLib.Markup.EscapeText(_Name)
+                    ), TextColorContrast.High
                 );
+
+                if (HighlightCount > 1) {
+                    _TabLabel.Markup = String.Format(
+                        "<span foreground=\"{0}\">{1} ({2})</span>",
+                        GLib.Markup.EscapeText(color.ToString()),
+                        GLib.Markup.EscapeText(Name),
+                        GLib.Markup.EscapeText(HighlightCount.ToString())
+
+                    );
+                } else {
+                    _TabLabel.Markup = String.Format(
+                        "<span foreground=\"{0}\">{1}</span>",
+                        GLib.Markup.EscapeText(color.ToString()),
+                        GLib.Markup.EscapeText(Name)
+                    );
+                }
             }
         }
 
@@ -110,6 +135,10 @@ namespace Smuxi.Frontend.Gnome
                 return _HasActivity;
             }
             set {
+                if (value && _HasActivity == value) {
+                    // nothing to update
+                    return;
+                }
                 _HasActivity = value;
 
                 if (HasHighlight) {
@@ -123,16 +152,16 @@ namespace Smuxi.Frontend.Gnome
                 } else {
                     colorValue = _ThemeSettings.NoActivityColor;
                 }
-                var color = ColorTools.GetBestTextColor(
-                    ColorTools.GetTextColor(colorValue),
-                    ColorTools.GetTextColor(
+                var color = TextColorTools.GetBestTextColor(
+                    ColorConverter.GetTextColor(colorValue),
+                    ColorConverter.GetTextColor(
                         Gtk.Rc.GetStyle(_TabLabel).Base(Gtk.StateType.Normal)
-                    ), ColorContrast.High
+                    ), TextColorContrast.High
                 );
                 _TabLabel.Markup = String.Format(
                     "<span foreground=\"{0}\">{1}</span>",
                     GLib.Markup.EscapeText(color.ToString()),
-                    GLib.Markup.EscapeText(_Name)
+                    GLib.Markup.EscapeText(Name)
                 );
             }
         }
@@ -142,6 +171,8 @@ namespace Smuxi.Frontend.Gnome
                 return _HasEvent;
             }
             set {
+                _HasEvent = value;
+
                 if (HasHighlight) {
                     return;
                 }
@@ -155,16 +186,16 @@ namespace Smuxi.Frontend.Gnome
                     return;
                 }
 
-                var color = ColorTools.GetBestTextColor(
-                    ColorTools.GetTextColor(_ThemeSettings.EventColor),
-                    ColorTools.GetTextColor(
+                var color = TextColorTools.GetBestTextColor(
+                    ColorConverter.GetTextColor(_ThemeSettings.EventColor),
+                    ColorConverter.GetTextColor(
                         Gtk.Rc.GetStyle(_TabLabel).Base(Gtk.StateType.Normal)
-                    ), ColorContrast.High
+                    ), TextColorContrast.High
                 );
                 _TabLabel.Markup = String.Format(
                     "<span foreground=\"{0}\">{1}</span>",
                     GLib.Markup.EscapeText(color.ToString()),
-                    GLib.Markup.EscapeText(_Name)
+                    GLib.Markup.EscapeText(Name)
                 );
             }
         }
@@ -214,15 +245,19 @@ namespace Smuxi.Frontend.Gnome
             }
         }
 
+        protected abstract Gtk.Image DefaultTabImage {
+            get;
+        }
+
+        public event EventHandler<ChatViewMessageHighlightedEventArgs> MessageHighlighted;
+
         public ChatView(ChatModel chat)
         {
             Trace.Call(chat);
             
             _ChatModel = chat;
-            _Name = _ChatModel.Name;
-            ID = _ChatModel.ID;
-            Name = _Name;
-            
+
+            IsAutoScrolling = true;
             MessageTextView tv = new MessageTextView();
             _EndMark = tv.Buffer.CreateMark("end", tv.Buffer.EndIter, false); 
             tv.ShowTimestamps = true;
@@ -233,32 +268,40 @@ namespace Smuxi.Frontend.Gnome
             tv.MessageAdded += OnMessageTextViewMessageAdded;
             tv.MessageHighlighted += OnMessageTextViewMessageHighlighted;
             tv.PopulatePopup += OnMessageTextViewPopulatePopup;
+            tv.SizeRequested += delegate {
+                AutoScroll();
+            };
             _OutputMessageTextView = tv;
 
             Gtk.ScrolledWindow sw = new Gtk.ScrolledWindow();
+            _OutputScrolledWindow = sw;
             //sw.HscrollbarPolicy = Gtk.PolicyType.Never;
             sw.HscrollbarPolicy = Gtk.PolicyType.Automatic;
             sw.VscrollbarPolicy = Gtk.PolicyType.Always;
             sw.ShadowType = Gtk.ShadowType.In;
+            sw.Vadjustment.ValueChanged += delegate {
+                CheckAutoScroll();
+            };
             sw.Add(_OutputMessageTextView);
-            _OutputScrolledWindow = sw;
-            
+
             // popup menu
             _TabMenu = new Gtk.Menu();
             
             Gtk.ImageMenuItem close_item = new Gtk.ImageMenuItem(Gtk.Stock.Close, null);
             close_item.Activated += new EventHandler(OnTabMenuCloseActivated);  
             _TabMenu.Append(close_item);
+            _TabMenu.ShowAll();
             
             //FocusChild = _OutputTextView;
             //CanFocus = false;
             
             _TabLabel = new Gtk.Label();
-            _TabLabel.Text = _Name;
-            
+
+            TabImage = DefaultTabImage;
             _TabHBox = new Gtk.HBox();
             _TabHBox.PackEnd(new Gtk.Fixed(), true, true, 0);
             _TabHBox.PackEnd(_TabLabel, false, false, 0);
+            _TabHBox.PackStart(TabImage, false, false, 2);
             _TabHBox.ShowAll();
             
             _TabEventBox = new Gtk.EventBox();
@@ -270,7 +313,7 @@ namespace Smuxi.Frontend.Gnome
             _ThemeSettings = new ThemeSettings();
 
             // OPT-TODO: this should use a TaskStack instead of TaskQueue
-            _LastSeenHighlightQueue = new TaskQueue("LastSeenHighlightQueue("+_Name+")");
+            _LastSeenHighlightQueue = new TaskQueue("LastSeenHighlightQueue("+ID+")");
             _LastSeenHighlightQueue.AbortedEvent += OnLastSeenHighlightQueueAbortedEvent;
             _LastSeenHighlightQueue.ExceptionEvent += OnLastSeenHighlightQueueExceptionEvent;
         }
@@ -337,17 +380,18 @@ namespace Smuxi.Frontend.Gnome
         
         public virtual void ScrollToEnd()
         {
+#if SCROLL_DEBUG
             Trace.Call();
-            
-            Gtk.Adjustment adj = _OutputScrolledWindow.Vadjustment;
-#if LOG4NET
+#endif
+
+            // BUG? doesn't work always for some reason
+            // seems like GTK+ doesn't update the adjustment till we give back control
+            //Gtk.Adjustment adj = _OutputScrolledWindow.Vadjustment;
+#if LOG4NET && SCROLL_DEBUG
             _Logger.Debug("ScrollToEnd(): Vadjustment.Value: " + adj.Value +
                           " Vadjustment.Upper: " + adj.Upper +
                           " Vadjustment.PageSize: " + adj.PageSize);
 #endif
-            
-            // BUG? doesn't work always for some reason
-            // seems like GTK+ doesn't update the adjustment till we give back control
             //adj.Value = adj.Upper - adj.PageSize;
             
             //_OutputTextView.Buffer.MoveMark(_EndMark, _OutputTextView.Buffer.EndIter);
@@ -357,8 +401,10 @@ namespace Smuxi.Frontend.Gnome
             //_OutputTextView.ScrollMarkOnscreen(_OutputTextView.Buffer.InsertMark);
 
             //_OutputTextView.ScrollMarkOnscreen(_OutputTextView.Buffer.GetMark("tail"));
-            
+
+#if SCROLL_DEBUG
             System.Reflection.MethodBase mb = Trace.GetMethodBase();
+#endif
             // WORKAROUND1: scroll after one second delay
             /*
             GLib.Timeout.Add(1000, new GLib.TimeoutHandler(delegate {
@@ -370,13 +416,34 @@ namespace Smuxi.Frontend.Gnome
             */
             // WORKAROUND2: scroll when GTK+ mainloop is idle
             GLib.Idle.Add(new GLib.IdleHandler(delegate {
+#if SCROLL_DEBUG
                 Trace.Call(mb);
-                
+#endif
                 _OutputMessageTextView.ScrollMarkOnscreen(_EndMark);
                 return false;
             }));
         }
         
+        void CheckAutoScroll()
+        {
+            var vAdjustment = _OutputScrolledWindow.Vadjustment;
+            if (vAdjustment.Upper == (vAdjustment.Value + vAdjustment.PageSize)) {
+                // the scrollbar is way at the end, lets autoscroll
+                IsAutoScrolling = true;
+            } else {
+                IsAutoScrolling = false;
+            }
+        }
+
+        void AutoScroll()
+        {
+            if (!IsAutoScrolling) {
+                return;
+            }
+
+            ScrollToEnd();
+        }
+
         public virtual void Enable()
         {
             Trace.Call();
@@ -392,31 +459,83 @@ namespace Smuxi.Frontend.Gnome
         public virtual void Sync()
         {
             Trace.Call();
-            
+
+            GLib.Idle.Add(delegate {
+                TabImage.SetFromStock(Gtk.Stock.Refresh, Gtk.IconSize.Menu);
+                return false;
+            });
+
+            // REMOTING CALL
+            SyncedName = _ChatModel.Name;
+            // REMOTING CALL
+            ProtocolManager = _ChatModel.ProtocolManager;
+
+            if (!Frontend.IsLocalEngine && Frontend.UseLowBandwidthMode) {
+                // FIXME: set TabImage back to normal
+                return;
+            }
+
+            // REMOTING CALL
+            SyncedLastSeenHighlight = _ChatModel.LastSeenHighlight;
+
+            DateTime start, stop;
+            start = DateTime.UtcNow;
+            // REMOTING CALL
+            SyncedMessages = _ChatModel.Messages;
+            stop = DateTime.UtcNow;
 #if LOG4NET
-            _Logger.Debug("Sync() syncing messages");
+            _Logger.Debug(
+                String.Format(
+                    "Sync(): retrieving ChatModel.Messages took: {0:0.00} ms",
+                    (stop - start).TotalMilliseconds
+                )
+            );
 #endif
+        }
+
+        public virtual void Populate()
+        {
+            Trace.Call();
+
+            Name = SyncedName;
+
             // sync messages
             // cleanup, be sure the output is empty
             _OutputMessageTextView.Clear();
-            IList<MessageModel> messages = _ChatModel.Messages;
-            if (messages.Count > 0) {
-                foreach (MessageModel msg in messages) {
-                    AddMessage(msg);
+
+            if (!Frontend.IsLocalEngine && Frontend.UseLowBandwidthMode) {
+                var msg = new MessageBuilder();
+                msg.AppendEventPrefix();
+                msg.AppendMessage(_("Low Bandwidth Mode is active: no messages synced."));
+                AddMessage(msg.ToMessage());
+            } else {
+                if (SyncedMessages.Count > 0) {
+                    // TODO: push messages in batches and give back control to
+                    // GTK+ in between for blocking the GUI thread less
+                    foreach (MessageModel msg in SyncedMessages) {
+                        AddMessage(msg);
+                    }
                 }
             }
-            // REMOTING CALL
-            if (_LastHighlight > _ChatModel.LastSeenHighlight) {
-                HasHighlight = true;
+
+            // as we don't track which messages were already seen it would
+            // show all chats with message activity after the frontend connect
+            if (!HasHighlight) {
+                HasActivity = false;
             }
 
+            // let the user know at which position new messages start
+            _OutputMessageTextView.UpdateMarkerline();
+
+            // reset tab icon to normal
+            TabImage.Pixbuf = DefaultTabImage.Pixbuf;
+
+            SyncedMessages = null;
             _IsSynced = true;
         }
         
         public virtual void AddMessage(MessageModel msg)
         {
-            Trace.Call(msg);
-            
             _OutputMessageTextView.AddMessage(msg);
         }
         
@@ -444,35 +563,54 @@ namespace Smuxi.Frontend.Gnome
         {
             Trace.Call();
 
-            ChatModel.ProtocolManager.CloseChat(
-                Frontend.FrontendManager,
-                ChatModel
-            );
+            ThreadPool.QueueUserWorkItem(delegate {
+                try {
+                    ChatModel.ProtocolManager.CloseChat(
+                        Frontend.FrontendManager,
+                        ChatModel
+                    );
+                } catch (Exception ex) {
+                    Frontend.ShowException(ex);
+                }
+            });
+        }
+
+        public override string ToString()
+        {
+            return String.Format("<{0}>", ToTraceString());
+        }
+
+        public string ToTraceString()
+        {
+            return ID;
         }
 
         protected virtual void OnTabButtonPress(object sender, Gtk.ButtonPressEventArgs e)
         {
             Trace.Call(sender, e);
-            
-            if (e.Event.Button == 3) {
-                _TabMenu.Popup(null, null, null, e.Event.Button, e.Event.Time);
-                _TabMenu.ShowAll();
-            } else if (e.Event.Button == 2) {
-                Close();
+
+            try {
+                if (e.Event.Button == 3) {
+                    _TabMenu.Popup(null, null, null, e.Event.Button, e.Event.Time);
+                }
+            } catch (Exception ex) {
+                Frontend.ShowException(ex);
             }
         }
         
         protected virtual void OnTabMenuCloseActivated(object sender, EventArgs e)
         {
             Trace.Call(sender, e);
-            
-            Close();
+
+            try {
+                Close();
+            } catch (Exception ex) {
+                Frontend.ShowException(ex);
+            }
         }
         
         protected virtual void OnMessageTextViewMessageAdded(object sender, MessageTextViewMessageAddedEventArgs e)
         {
-            Trace.Call(sender, e);
-            
             // HACK: out of scope?
             // probably we should use the ChatViewManager instead?
             if (Frontend.MainWindow.Notebook.CurrentChatView != this) {
@@ -486,50 +624,22 @@ namespace Smuxi.Frontend.Gnome
                 }
             }
 
-            Gtk.ScrolledWindow sw = _OutputScrolledWindow;
-            Gtk.TextView tv = _OutputMessageTextView;
-
-            if (sw.Vadjustment.Upper == (sw.Vadjustment.Value + sw.Vadjustment.PageSize)) {
-                // the scrollbar is way at the end, lets autoscroll
-                Gtk.TextIter endit = tv.Buffer.EndIter;
-                tv.Buffer.PlaceCursor(endit);
-                tv.Buffer.MoveMark(tv.Buffer.InsertMark, endit);
-                tv.ScrollMarkOnscreen(tv.Buffer.InsertMark);
-            }
+            var buffer = _OutputMessageTextView.Buffer;
+            buffer.MoveMark(_EndMark, buffer.EndIter);
 
-            // update the end mark
-            tv.Buffer.MoveMark(_EndMark, tv.Buffer.EndIter);
+            AutoScroll();
         }
         
         protected virtual void OnMessageTextViewMessageHighlighted(object sender, MessageTextViewMessageHighlightedEventArgs e)
         {
-            Trace.Call(sender, e);
-            
-            // HACK: out of scope?
-            // only beep if the main windows has no focus (the user is
-            // elsewhere) and the chat is was already synced, as during sync we
-            // would get insane from all beeping caused by the old highlights
-            if (!Frontend.MainWindow.HasToplevelFocus &&
-                _IsSynced &&
-                Frontend.UserConfig["Sound/BeepOnHighlight"] != null &&
-                (bool) Frontend.UserConfig["Sound/BeepOnHighlight"]) {
-#if LOG4NET
-                _Logger.Debug("OnMessageTextViewMessageHighlighted(): BEEP!");
-#endif
-                try {
-                    if (Display != null) {
-                        Display.Beep();
-                    }
-                } catch (Exception ex) {
-#if LOG4NET
-                    _Logger.Error("OnMessageTextViewMessageHighlighted(): Exception", ex);
-#endif
-                }
-            }
-
             if (_IsSynced) {
                 bool isActiveChat = IsActive;
 
+                if (Frontend.UseLowBandwidthMode && !isActiveChat) {
+                    HasHighlight = true;
+                    return;
+                }
+
                 var method = Trace.GetMethodBase();
                 // update last seen highlight
                 // OPT-TODO: we should use a TaskStack here OR at least a
@@ -565,7 +675,39 @@ namespace Smuxi.Frontend.Gnome
                     }
                 });
             } else {
-                _LastHighlight = e.Message.TimeStamp;
+                if (e.Message.TimeStamp > SyncedLastSeenHighlight) {
+                    HasHighlight = true;
+                }
+            }
+
+            if (e.Message.TimeStamp > SyncedLastSeenHighlight) {
+                // unseen highlight
+
+                // HACK: out of scope?
+                // only beep if the main windows has no focus (the user is
+                // elsewhere) and the chat is was already synced, as during sync we
+                // would get insane from all beeping caused by the old highlights
+                if (!Frontend.MainWindow.HasToplevelFocus &&
+                    _IsSynced &&
+                    Frontend.UserConfig["Sound/BeepOnHighlight"] != null &&
+                    (bool) Frontend.UserConfig["Sound/BeepOnHighlight"]) {
+#if LOG4NET
+                    _Logger.Debug("OnMessageTextViewMessageHighlighted(): BEEP!");
+#endif
+                    try {
+                        if (Display != null) {
+                            Display.Beep();
+                        }
+                    } catch (Exception ex) {
+#if LOG4NET
+                        _Logger.Error("OnMessageTextViewMessageHighlighted(): Exception", ex);
+#endif
+                    }
+                }
+
+                if (MessageHighlighted != null) {
+                    MessageHighlighted(this, new ChatViewMessageHighlightedEventArgs(e.Message));
+                }
             }
         }
 
@@ -576,9 +718,6 @@ namespace Smuxi.Frontend.Gnome
             if (OutputMessageTextView.IsAtUrlTag) {
                 return;
             }
-            if (Frontend.MainWindow.ShowMenuBar) {
-                return;
-            }
 
             Gtk.Menu popup = e.Menu;
             popup.Prepend(new Gtk.SeparatorMenuItem());
@@ -587,7 +726,7 @@ namespace Smuxi.Frontend.Gnome
             item.Active = Frontend.MainWindow.ShowMenuBar;
             item.Activated += delegate {
                 try {
-                    Frontend.MainWindow.ShowMenuBar = true;
+                    Frontend.MainWindow.ShowMenuBar = !Frontend.MainWindow.ShowMenuBar;
                 } catch (Exception ex) {
                     Frontend.ShowException(ex);
                 }
@@ -621,4 +760,14 @@ namespace Smuxi.Frontend.Gnome
             return Mono.Unix.Catalog.GetString(msg);
         }
     }
+
+    public class ChatViewMessageHighlightedEventArgs : EventArgs
+    {
+        public MessageModel Message { get; set; }
+
+        public ChatViewMessageHighlightedEventArgs(MessageModel msg)
+        {
+            Message = msg;
+        }
+    }
 }
diff --git a/src/Frontend-GNOME/Views/Chats/GroupChatView.cs b/src/Frontend-GNOME/Views/Chats/GroupChatView.cs
index a6cb7e2..a7ce350 100644
--- a/src/Frontend-GNOME/Views/Chats/GroupChatView.cs
+++ b/src/Frontend-GNOME/Views/Chats/GroupChatView.cs
@@ -1,13 +1,7 @@
 /*
- * $Id$
- * $URL$
- * $Rev$
- * $Author$
- * $Date$
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2006, 2009-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -27,6 +21,7 @@
  */
 
 using System;
+using System.Threading;
 using System.Collections.Generic;
 using System.Globalization;
 using Mono.Unix;
@@ -55,6 +50,8 @@ namespace Smuxi.Frontend.Gnome
         private MessageTextView    _TopicTextView;
         private MessageModel       _Topic;
         private Gtk.TreeViewColumn _IdentityNameColumn;
+        IDictionary<string, PersonModel> SyncedPersons { get; set; }
+        MessageModel                     SyncedTopic  { get; set; }
 
         public override bool HasSelection {
             get {
@@ -103,10 +100,19 @@ namespace Smuxi.Frontend.Gnome
                 return _IdentityNameColumn;
             }
         }
-        
-        static GroupChatView() {
-            IconPixbuf = new Gdk.Pixbuf(null, "group-chat.svg", 16, 16);
-       }
+
+        protected override Gtk.Image DefaultTabImage {
+            get {
+                return new Gtk.Image(IconPixbuf);
+            }
+        }
+
+        static GroupChatView()
+        {
+            IconPixbuf = Frontend.LoadIcon(
+                "smuxi-group-chat", 16, "group-chat_256x256.png"
+            );
+        }
 
         public GroupChatView(GroupChatModel groupChat) : base(groupChat)
         {
@@ -183,22 +189,9 @@ namespace Smuxi.Frontend.Gnome
             _TopicScrolledWindow.Visible = false;
             _TopicScrolledWindow.NoShowAll = true;
 
-            // predict and set useful topic heigth
-            Pango.Layout layout = _TopicTextView.CreatePangoLayout("Test Topic");
-            int lineWidth, lineHeigth;
-            layout.GetPixelSize(out lineWidth, out lineHeigth);
-            // use 2 lines + a bit extra as the topic heigth
-            int bestHeigth = (lineHeigth * 2) + 5;
-            _TopicTextView.HeightRequest = bestHeigth;
-            _TopicScrolledWindow.HeightRequest = bestHeigth;
-            
             Add(_OutputHPaned);
             
-            ApplyConfig(Frontend.UserConfig);
-            
-            var tabImage = new Gtk.Image(IconPixbuf);
-            TabHBox.PackStart(tabImage, false, false, 2);
-            TabHBox.ShowAll();
+            //ApplyConfig(Frontend.UserConfig);
             
             ShowAll();
         }
@@ -218,54 +211,53 @@ namespace Smuxi.Frontend.Gnome
         {
             Trace.Call();
 
-            IDictionary<string, PersonModel> persons = _GroupChatModel.Persons;
-            if (persons == null) {
-                persons = new Dictionary<string, PersonModel>(0);
-            }
+            GLib.Idle.Add(delegate {
+                TabImage.SetFromStock(Gtk.Stock.Refresh, Gtk.IconSize.Menu);
+                return false;
+            });
+
 #if LOG4NET
             _Logger.Debug("Sync() syncing persons");
 #endif
+            // REMOTING CALL 1
+            SyncedPersons = _GroupChatModel.Persons;
+            if (SyncedPersons == null) {
+                SyncedPersons = new Dictionary<string, PersonModel>(0);
+            }
+
+#if LOG4NET
+            _Logger.Debug("Sync() syncing topic");
+#endif
+            // REMOTING CALL 2
+            SyncedTopic = _GroupChatModel.Topic;
+
+            base.Sync();
+        }
+
+        public override void Populate()
+        {
+            Trace.Call();
+
             // sync persons
             if (_PersonTreeView != null) {
-                int count = persons.Count;
-                /*
-                if (count > 1) {
-                    Frontend.MainWindow.ProgressBar.DiscreteBlocks = (uint)count;
-                } else {
-                    Frontend.MainWindow.ProgressBar.DiscreteBlocks = 2;
-                }
-                Frontend.MainWindow.ProgressBar.BarStyle = Gtk.ProgressBarStyle.Continuous;
-                */
-                
                 // HACK: out of scope
                 string status = String.Format(
                                     _("Retrieving user list for {0}..."),
-                                    ChatModel.Name);
-                Frontend.MainWindow.Statusbar.Push(0, status);
+                                    SyncedName);
+                Frontend.MainWindow.Status = status;
     
                 Gtk.ListStore ls = (Gtk.ListStore) _PersonTreeView.Model;
                 // cleanup, be sure the list is empty
                 ls.Clear();
                 // detach the model (less CPU load)
                 _PersonTreeView.Model = new Gtk.ListStore(typeof(PersonModel));
-                int i = 1;
                 string longestName = String.Empty;
-                foreach (PersonModel person in persons.Values) {
+                foreach (PersonModel person in SyncedPersons.Values) {
                     ls.AppendValues(person);
                     
                     if (person.IdentityName.Length > longestName.Length) {
                         longestName = person.IdentityName;
                     }
-                    
-                    //Frontend.MainWindow.ProgressBar.Fraction = (double)i++ / count;
-                    /*
-                    // this seems to break the sync when it's remote engine is used,
-                    // guess it does some other GUI processing, like removing users from
-                    // the userlist....
-                    while (Gtk.Application.EventsPending()) {
-                        Gtk.Application.RunIteration(false);
-                    }
-                    */
                 }
                 // attach the model again
                 // BUG? TreeView doesn't seem to recognize existing values in the model?!?
@@ -283,20 +275,14 @@ namespace Smuxi.Frontend.Gnome
                 
                 UpdatePersonCount(); 
                
-                // HACK: out of scope
-                Frontend.MainWindow.ProgressBar.Fraction = 0;
                 // TRANSLATOR: this string will be appended to the one above
                 status += String.Format(" {0}", _("done."));
-                Frontend.MainWindow.Statusbar.Push(0, status);
+                Frontend.MainWindow.Status = status;
             }
 
-#if LOG4NET
-            _Logger.Debug("Sync() syncing topic");
-#endif
-            // sync topic
-            Topic = _GroupChatModel.Topic;
+            Topic = SyncedTopic;
 
-            base.Sync();
+            base.Populate();
         }
         
         protected void UpdatePersonCount()
@@ -374,6 +360,90 @@ namespace Smuxi.Frontend.Gnome
             } while (_PersonListStore.IterNext(ref iter));
             UpdatePersonCount();
         }
+
+        /*Logic taken from the PersonLookup method of Engine/Chats/GroupChatModel.cs */
+        public PersonModel PersonLookup(string identityName)
+        {
+            Trace.Call(identityName);
+#if LOG4NET
+            _Logger.Debug("PersonLookup(): GroupChatModel.Name: " + Name);
+#endif
+            int identityNameLength = identityName.Length;
+            if (_PersonListStore == null) {
+                return null;
+            }
+            foreach (object[] row in _PersonListStore) {
+                PersonModel person = (PersonModel)row[0];
+                if ((person.IdentityName.Length >= identityNameLength) &&
+                    (person.IdentityName.Substring(0, identityNameLength).ToLower() == identityName.ToLower())) {
+#if LOG4NET
+                    _Logger.Debug("PersonLookup(): found: " + person.IdentityName);
+#endif
+                    return person;
+                }
+            }
+
+#if LOG4NET
+            _Logger.Debug("PersonLookup() no matching identityName found");
+#endif
+            return null;
+        }
+
+        /*Logic taken from the PersonLookupAll method of Engine/Chats/GroupChatModel.cs */
+        public IList<string> PersonLookupAll(string identityName)
+        {
+            Trace.Call(identityName);
+
+            IList<string> foundIdentityNames = new List<string>();
+            int identityNameLength = identityName.Length;
+            string longestIdentityName = String.Empty;
+            if (_PersonListStore == null) {
+                return foundIdentityNames;
+            }
+            foreach (object[] row in _PersonListStore) {
+                PersonModel person = (PersonModel)row[0];
+                if ((person.IdentityName.Length >= identityNameLength) &&
+                    (person.IdentityName.Substring(0, identityNameLength).ToLower() == identityName.ToLower())) {
+                    foundIdentityNames.Add(person.IdentityName);
+                    if (person.IdentityName.Length > longestIdentityName.Length) {
+                        longestIdentityName = person.IdentityName;
+                    }
+                }
+            }
+
+            // guess the common part of the found nicknames
+            string common_nick = identityName;
+            bool match = true;
+            while (match) {
+                if (common_nick.Length >= longestIdentityName.Length) {
+                    break;
+                }
+                common_nick += longestIdentityName[common_nick.Length];
+                foreach (string name in foundIdentityNames) {
+                    if (!name.ToLower().StartsWith(common_nick.ToLower())) {
+                        common_nick = common_nick.Substring(0, common_nick.Length - 1);
+                        match = false;
+                     }
+                }
+            }
+
+            if (foundIdentityNames.Count == 0) {
+#if LOG4NET
+                _Logger.Debug("PersonLookupAll(): no matching identityName found");
+#endif
+            } else if (foundIdentityNames.Count == 1) {
+#if LOG4NET
+                _Logger.Debug("PersonLookupAll(): found exact match: " + foundIdentityNames[0]);
+#endif
+            } else {
+#if LOG4NET
+                _Logger.Debug("PersonLookupAll(): found " + foundIdentityNames.Count + " matches");
+#endif
+                foundIdentityNames.Insert(0, common_nick);
+            }
+            return foundIdentityNames;
+        }
+
         
         public override void ApplyConfig(UserConfig config)
         {
@@ -387,6 +457,15 @@ namespace Smuxi.Frontend.Gnome
 
             // topic
             _TopicTextView.ApplyConfig(config);
+            // predict and set useful topic heigth
+            Pango.Layout layout = _TopicTextView.CreatePangoLayout("Test Topic");
+            int lineWidth, lineHeigth;
+            layout.GetPixelSize(out lineWidth, out lineHeigth);
+            // use 2 lines + a bit extra as the topic heigth
+            int bestHeigth = (lineHeigth * 2) + 5;
+            _TopicTextView.HeightRequest = bestHeigth;
+            _TopicScrolledWindow.HeightRequest = bestHeigth;
+
             string topic_pos = (string) config["Interface/Notebook/Channel/TopicPosition"];
             if (_TopicScrolledWindow.IsAncestor(_OutputVBox)) {
                 _OutputVBox.Remove(_TopicScrolledWindow);
@@ -474,20 +553,31 @@ namespace Smuxi.Frontend.Gnome
             
             PersonModel person1 = (PersonModel) liststore.GetValue(iter1, 0); 
             PersonModel person2 = (PersonModel) liststore.GetValue(iter2, 0); 
-            
-            return String.Compare(person1.IdentityName, person2.IdentityName,
-                                  true, CultureInfo.InvariantCulture);
+
+            return person1.CompareTo(person2);
         }
-        
+
         protected virtual void OnPersonsRowActivated(object sender, Gtk.RowActivatedArgs e)
         {
             Trace.Call(sender, e);
 
             IList<PersonModel> persons = GetSelectedPersons();
-            if (persons == null) {
+            if (persons == null || persons.Count == 0) {
                 return;
             }
 
+            // jump to person chat if available
+            foreach (var chatView in Frontend.MainWindow.ChatViewManager.Chats) {
+                if (!(chatView is PersonChatView)) {
+                    continue;
+                }
+                var personChatView = (PersonChatView) chatView;
+                if (personChatView.PersonModel == persons[0]) {
+                    Frontend.MainWindow.ChatViewManager.CurrentChatView = personChatView;
+                    return;
+                }
+            }
+
             // this is a generic implemention that should be able to open/create
             // a private chat in most cases, as it depends what OpenChat()
             // of the specific protocol actually expects/needs
@@ -496,12 +586,19 @@ namespace Smuxi.Frontend.Gnome
                     person,
                     person.ID,
                     person.IdentityName,
-                    ChatModel.ProtocolManager
-                );
-                ChatModel.ProtocolManager.OpenChat(
-                    Frontend.FrontendManager,
-                    personChat
+                    null
                 );
+
+                ThreadPool.QueueUserWorkItem(delegate {
+                    try {
+                        ChatModel.ProtocolManager.OpenChat(
+                            Frontend.FrontendManager,
+                            personChat
+                        );
+                    } catch (Exception ex) {
+                        Frontend.ShowException(ex);
+                    }
+                });
             }
         }
 
@@ -527,7 +624,6 @@ namespace Smuxi.Frontend.Gnome
             if (e.Event.Key == Gdk.Key.Menu &&
                 _PersonTreeView.Selection.CountSelectedRows() > 0) {
                 _PersonMenu.Popup(null, null, null, 0, e.Event.Time);
-                _PersonMenu.ShowAll();
             }
         }
 
@@ -546,7 +642,6 @@ namespace Smuxi.Frontend.Gnome
                 // 0 == left mouse button here
                 //_PersonMenu.Popup(null, null, null, e.Event.Button, e.Event.Time);
                 _PersonMenu.Popup(null, null, null, 0, e.Event.Time);
-                _PersonMenu.ShowAll();
             }
         }
         
diff --git a/src/Frontend-GNOME/Views/Chats/PersonChatView.cs b/src/Frontend-GNOME/Views/Chats/PersonChatView.cs
index 917558a..dcbe617 100644
--- a/src/Frontend-GNOME/Views/Chats/PersonChatView.cs
+++ b/src/Frontend-GNOME/Views/Chats/PersonChatView.cs
@@ -39,8 +39,17 @@ namespace Smuxi.Frontend.Gnome
         public  PersonChatModel PersonChatModel { get; private set; }
         public  PersonModel     PersonModel { get; private set; }
 
-        static PersonChatView() {
-            IconPixbuf = new Gdk.Pixbuf(null, "person-chat.svg", 16, 16);
+        protected override Gtk.Image DefaultTabImage {
+            get {
+                return new Gtk.Image(IconPixbuf);
+            }
+        }
+
+        static PersonChatView()
+        {
+            IconPixbuf = Frontend.LoadIcon(
+                "smuxi-person-chat", 16, "person-chat_256x256.png"
+            );
         }
 
         public PersonChatView(PersonChatModel chat) : base(chat)
@@ -49,10 +58,6 @@ namespace Smuxi.Frontend.Gnome
             
             PersonChatModel = chat;
 
-            var tabImage = new Gtk.Image(IconPixbuf);
-            TabHBox.PackStart(tabImage, false, false, 2);
-            TabHBox.ShowAll();
-            
             Add(OutputScrolledWindow);
         }
 
@@ -60,6 +65,12 @@ namespace Smuxi.Frontend.Gnome
         {
             Trace.Call();
 
+            GLib.Idle.Add(delegate {
+                TabImage.SetFromStock(Gtk.Stock.Refresh, Gtk.IconSize.Menu);
+                return false;
+            });
+
+            // REMOTING CALL 1
             PersonModel = PersonChatModel.Person;
 
             base.Sync();
diff --git a/src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs b/src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs
index d79ec64..61c3709 100644
--- a/src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs
+++ b/src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs
@@ -1,13 +1,7 @@
 /*
- * $Id$
- * $URL$
- * $Rev$
- * $Author$
- * $Date$
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2006, 2009-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -27,6 +21,7 @@
  */
 
 using System;
+using System.Threading;
 using Smuxi.Engine;
 using Smuxi.Common;
 
@@ -37,18 +32,23 @@ namespace Smuxi.Frontend.Gnome
     {
         public static Gdk.Pixbuf IconPixbuf { get; private set; }
         
-        static ProtocolChatView() {
-            IconPixbuf = new Gdk.Pixbuf(null, "protocol-chat.svg", 16, 16);
+        protected override Gtk.Image DefaultTabImage {
+            get {
+                return new Gtk.Image(IconPixbuf);
+            }
+        }
+
+        static ProtocolChatView()
+        {
+            IconPixbuf = Frontend.LoadIcon(
+                "smuxi-protocol-chat", 16, "protocol-chat_256x256.png"
+            );
         }
 
         public ProtocolChatView(ChatModel chat) : base(chat)
         {
             Trace.Call(chat);
             
-            var tabImage = new Gtk.Image(IconPixbuf);
-            TabHBox.PackStart(tabImage, false, false, 2);
-            TabHBox.ShowAll();
-            
             Add(OutputScrolledWindow);
             
             ShowAll();
@@ -59,6 +59,7 @@ namespace Smuxi.Frontend.Gnome
             Trace.Call();
             
             // show warning if there are open chats (besides protocol chat)
+            // FIXME: REMOTING CALL 1 + 2 + 3
             if (ChatModel.ProtocolManager.Chats.Count > 1) {
                 Gtk.MessageDialog md = new Gtk.MessageDialog(
                     Frontend.MainWindow,
@@ -73,16 +74,22 @@ namespace Smuxi.Frontend.Gnome
                     return;
                 }
             }
-            
-            base.Close();
-            
-            Frontend.Session.CommandNetwork(
-                new CommandModel(
-                    Frontend.FrontendManager,
-                    ChatModel,
-                    "close"
-                )
-            );
+
+            ThreadPool.QueueUserWorkItem(delegate {
+                try {
+                    // no need to call base.Close() as CommandNetwork() will
+                    // deal with it
+                    Frontend.Session.CommandNetwork(
+                        new CommandModel(
+                            Frontend.FrontendManager,
+                            ChatModel,
+                            "close"
+                        )
+                    );
+                } catch (Exception ex) {
+                    Frontend.ShowException(ex);
+                }
+            });
         }
         
         private static string _(string msg)
diff --git a/src/Frontend-GNOME/Views/Chats/SessionChatView.cs b/src/Frontend-GNOME/Views/Chats/SessionChatView.cs
index dd8d73d..6280083 100644
--- a/src/Frontend-GNOME/Views/Chats/SessionChatView.cs
+++ b/src/Frontend-GNOME/Views/Chats/SessionChatView.cs
@@ -37,8 +37,17 @@ namespace Smuxi.Frontend.Gnome
     {
         public static Gdk.Pixbuf IconPixbuf { get; private set; }
         
-        static SessionChatView() {
-            IconPixbuf = new Gdk.Pixbuf(null, "session-chat.svg", 16, 16);
+        protected override Gtk.Image DefaultTabImage {
+            get {
+                return new Gtk.Image(IconPixbuf);
+            }
+        }
+
+        static SessionChatView()
+        {
+            IconPixbuf = Frontend.LoadIcon(
+                "smuxi-session-chat", 16, "session-chat_256x256.png"
+            );
         }
 
         public SessionChatView(ChatModel chat) : base(chat)
@@ -46,11 +55,8 @@ namespace Smuxi.Frontend.Gnome
             Trace.Call(chat);
             
             OutputMessageTextView.ShowMarkerline = false;
+            OutputMessageTextView.ShowTimestamps = false;
 
-            var tabImage = new Gtk.Image(IconPixbuf);
-            TabHBox.PackStart(tabImage, false, false, 2);
-            TabHBox.ShowAll();
-            
             Add(OutputScrolledWindow);
         }
         
diff --git a/src/Frontend-GNOME/Views/MessageTextView.cs b/src/Frontend-GNOME/Views/MessageTextView.cs
index c0c92e3..9e9ce89 100644
--- a/src/Frontend-GNOME/Views/MessageTextView.cs
+++ b/src/Frontend-GNOME/Views/MessageTextView.cs
@@ -1,9 +1,7 @@
 /*
- * $Id$
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2009 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2009-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -45,8 +43,8 @@ namespace Smuxi.Frontend.Gnome
         private bool         _ShowTimestamps;
         private bool         _ShowHighlight;
         private bool         _ShowMarkerline;
-        private bool         _AtUrlTag;
-        private string       _Url;
+        private bool         _AtLinkTag;
+        private Uri          _ActiveLink;
         private UserConfig   _Config;
         private ThemeSettings _ThemeSettings;
         private Gdk.Color    _MarkerlineColor = new Gdk.Color(255, 0, 0);
@@ -109,7 +107,7 @@ namespace Smuxi.Frontend.Gnome
 
         public bool IsAtUrlTag {
             get {
-                return _AtUrlTag;
+                return _AtLinkTag;
             }
         }
 
@@ -176,36 +174,52 @@ namespace Smuxi.Frontend.Gnome
         
         public void AddMessage(MessageModel msg, bool addLinebreak)
         {
+#if MSG_DEBUG
             Trace.Call(msg, addLinebreak);
+#endif
 
             if (msg == null) {
                 throw new ArgumentNullException("msg");
             }
 
-            Gtk.TextIter iter = Buffer.EndIter;
+            var buffer = Buffer;
+            var iter = buffer.EndIter;
 
             Gdk.Color bgColor = DefaultAttributes.Appearance.BgColor;
             if (_ThemeSettings.BackgroundColor != null) {
                 bgColor = _ThemeSettings.BackgroundColor.Value;
             }
-            TextColor bgTextColor = ColorTools.GetTextColor(bgColor);
+            TextColor bgTextColor = ColorConverter.GetTextColor(bgColor);
 
             if (_ShowTimestamps) {
-                DateTime localTimestamp = msg.TimeStamp.ToLocalTime();
-                if (_LastMessage != null &&
-                    _LastMessage.TimeStamp.ToLocalTime().Date != localTimestamp.Date) {
-                    string dayLine = String.Format(
-                        "-!- " + _("Day changed to {0}"),
-                        localTimestamp.Date.ToLongDateString()
-                    );
-                    Buffer.Insert(ref iter, dayLine + "\n");
+                var msgTimeStamp = msg.TimeStamp.ToLocalTime();
+                if (_LastMessage != null) {
+                    var lastMsgTimeStamp = _LastMessage.TimeStamp.ToLocalTime();
+                    var span = msgTimeStamp.Date - lastMsgTimeStamp.Date;
+                    string dayLine = null;
+                    if (span.Days > 1) {
+                        dayLine = String.Format(
+                            "-!- " + _("Day changed from {0} to {1}"),
+                            lastMsgTimeStamp.ToShortDateString(),
+                            msgTimeStamp.ToShortDateString()
+                        );
+                    } else if (span.Days > 0) {
+                        dayLine = String.Format(
+                            "-!- " + _("Day changed to {0}"),
+                            msgTimeStamp.ToLongDateString()
+                        );
+                    }
+
+                    if (dayLine != null) {
+                        buffer.Insert(ref iter, dayLine + "\n");
+                    }
                 }
                 
                 string timestamp = null;
                 try {
                     string format = (string)Frontend.UserConfig["Interface/Notebook/TimestampFormat"];
                     if (!String.IsNullOrEmpty(format)) {
-                        timestamp = localTimestamp.ToString(format);
+                        timestamp = msgTimeStamp.ToString(format);
                     }
                 } catch (FormatException e) {
                     timestamp = "Timestamp Format ERROR: " + e.Message;
@@ -217,17 +231,17 @@ namespace Smuxi.Frontend.Gnome
                         // get best contrast for the event font color
                         Gtk.TextTag eventTag = _MessageTextTagTable.Lookup("event");
                         Gdk.Color eventColor = eventTag.ForegroundGdk;
-                        TextColor eventTextColor = ColorTools.GetBestTextColor(
-                            ColorTools.GetTextColor(eventColor),
+                        TextColor eventTextColor = TextColorTools.GetBestTextColor(
+                            ColorConverter.GetTextColor(eventColor),
                             bgTextColor,
-                            ColorContrast.High
+                            TextColorContrast.High
                         );
-                        eventTag.ForegroundGdk = ColorTools.GetGdkColor(
+                        eventTag.ForegroundGdk = ColorConverter.GetGdkColor(
                             eventTextColor
                         );
-                        Buffer.InsertWithTagsByName(ref iter, timestamp, "event");
+                        buffer.InsertWithTagsByName(ref iter, timestamp, "event");
                     } else {
-                        Buffer.Insert(ref iter, timestamp);
+                        buffer.Insert(ref iter, timestamp);
                     }
                 }
             }
@@ -241,16 +255,39 @@ namespace Smuxi.Frontend.Gnome
 
                 // TODO: implement all types
                 if (msgPart is UrlMessagePartModel) {
-                    UrlMessagePartModel fmsgui = (UrlMessagePartModel) msgPart;
+                    var urlPart = (UrlMessagePartModel) msgPart;
                     // HACK: the engine should set a color for us!
-                    Gtk.TextTag urlTag = _MessageTextTagTable.Lookup("url");
-                    Gdk.Color urlColor = urlTag.ForegroundGdk;
-                    //Console.WriteLine("urlColor: " + urlColor);
-                    TextColor urlTextColor = ColorTools.GetTextColor(urlColor);
-                    urlTextColor = ColorTools.GetBestTextColor(urlTextColor, bgTextColor);
-                    //Console.WriteLine("GetBestTextColor({0}, {1}): {2}",  urlColor, bgTextColor, urlTextColor);
-                    urlTag.ForegroundGdk = ColorTools.GetGdkColor(urlTextColor);
-                    Buffer.InsertWithTagsByName(ref iter, fmsgui.Url, "url");
+                    var linkStyleTag = _MessageTextTagTable.Lookup("link");
+                    var linkColor = ColorConverter.GetTextColor(
+                        linkStyleTag.ForegroundGdk
+                    );
+                    linkColor = TextColorTools.GetBestTextColor(
+                        linkColor, bgTextColor
+                    );
+                    var linkText = urlPart.Text ?? urlPart.Url;
+
+                    var url = urlPart.Url;
+                    // HACK: assume http if no protocol/scheme was specified
+                    if (urlPart.Protocol == UrlProtocol.None ||
+                        !Regex.IsMatch(url, @"^[a-zA-Z0-9\-]+:")) {
+                        url = String.Format("http://{0}", url);
+                    }
+                    Uri uri;
+                    try {
+                        uri = new Uri(url);
+                    } catch (UriFormatException ex) {
+#if LOG4NET
+                        _Logger.Error("AddMessage(): Invalid URL: " + url, ex);
+#endif
+                        buffer.Insert(ref iter, linkText);
+                        continue;
+                    }
+
+                    var linkTag = new LinkTag(uri);
+                    linkTag.ForegroundGdk = ColorConverter.GetGdkColor(linkColor);
+                    linkTag.TextEvent += OnLinkTagTextEvent;
+                    _MessageTextTagTable.Add(linkTag);
+                    buffer.InsertWithTags(ref iter, linkText, linkStyleTag, linkTag);
                 } else if (msgPart is TextMessagePartModel) {
                     TextMessagePartModel fmsgti = (TextMessagePartModel) msgPart;
                     List<string> tags = new List<string>();
@@ -259,7 +296,9 @@ namespace Smuxi.Frontend.Gnome
                         if (fmsgti.BackgroundColor != TextColor.None) {
                             bg = fmsgti.BackgroundColor;
                         }
-                        TextColor color = ColorTools.GetBestTextColor(fmsgti.ForegroundColor, bg);
+                        TextColor color = TextColorTools.GetBestTextColor(
+                            fmsgti.ForegroundColor, bg
+                        );
                         //Console.WriteLine("GetBestTextColor({0}, {1}): {2}",  fmsgti.ForegroundColor, bgTextColor, color);
                         string tagname = GetTextTagName(color, null);
                         //string tagname = _GetTextTagName(fmsgti.ForegroundColor, null);
@@ -271,19 +310,19 @@ namespace Smuxi.Frontend.Gnome
                         tags.Add(tagname);
                     }
                     if (fmsgti.Underline) {
-#if LOG4NET
+#if LOG4NET && MSG_DEBUG
                         _Logger.Debug("AddMessage(): fmsgti.Underline is true");
 #endif
                         tags.Add("underline");
                     }
                     if (fmsgti.Bold) {
-#if LOG4NET
+#if LOG4NET && MSG_DEBUG
                         _Logger.Debug("AddMessage(): fmsgti.Bold is true");
 #endif
                         tags.Add("bold");
                     }
                     if (fmsgti.Italic) {
-#if LOG4NET
+#if LOG4NET && MSG_DEBUG
                         _Logger.Debug("AddMessage(): fmsgti.Italic is true");
 #endif
                         tags.Add("italic");
@@ -295,14 +334,14 @@ namespace Smuxi.Frontend.Gnome
                     }
 
                     if (tags.Count > 0) {
-                        Buffer.InsertWithTagsByName(ref iter, fmsgti.Text, tags.ToArray());
+                        buffer.InsertWithTagsByName(ref iter, fmsgti.Text, tags.ToArray());
                     } else {
-                        Buffer.Insert(ref iter, fmsgti.Text);
+                        buffer.Insert(ref iter, fmsgti.Text);
                     }
                 }
             }
             if (addLinebreak) {
-                Buffer.Insert(ref iter, "\n");
+                buffer.Insert(ref iter, "\n");
             }
 
             CheckBufferSize();
@@ -364,10 +403,9 @@ namespace Smuxi.Frontend.Gnome
             tt.Underline = Pango.Underline.Single;
             ttt.Add(tt);
             
-            tt = new Gtk.TextTag("url");
+            tt = new Gtk.TextTag("link");
             tt.Underline = Pango.Underline.Single;
             tt.Foreground = "darkblue";
-            tt.TextEvent += OnTextTagUrlTextEvent;
             fd = new Pango.FontDescription();
             tt.FontDesc = fd;
             ttt.Add(tt);
@@ -396,15 +434,15 @@ namespace Smuxi.Frontend.Gnome
             Gtk.TextIter iter = GetIterAtLocation(bufferX, bufferY);
             bool atUrlTag = false;
             foreach (Gtk.TextTag tag in iter.Tags) {
-                if (tag.Name == "url") {
+                if (tag.Name == "link") {
                     atUrlTag = true;
                     break;
                 }
             }
             
             Gdk.Window window = GetWindow(Gtk.TextWindowType.Text); 
-            if (atUrlTag != _AtUrlTag) {
-                _AtUrlTag = atUrlTag;
+            if (atUrlTag != _AtLinkTag) {
+                _AtLinkTag = atUrlTag;
                 
                 if (atUrlTag) {
 #if LOG4NET
@@ -416,54 +454,46 @@ namespace Smuxi.Frontend.Gnome
                     _Logger.Debug("OnMotionNotifyEvent(): not at url tag");
 #endif
                     window.Cursor = _NormalCursor;
+                    _ActiveLink = null;
                 }
             }
         }
         
-        protected virtual void OnTextTagUrlTextEvent(object sender, Gtk.TextEventArgs e)
+        protected virtual void OnLinkTagTextEvent(object sender, Gtk.TextEventArgs e)
         {
             // logging noise
             //Trace.Call(sender, e);
             
-            Gtk.TextIter start = Gtk.TextIter.Zero;
-            Gtk.TextIter end = Gtk.TextIter.Zero;
-
             // if something in the textview is selected, bail out
             if (HasTextViewSelection) {
 #if LOG4NET
-                _Logger.Debug("OnTextTagUrlTextEvent(): active selection present, bailing out...");
+                _Logger.Debug("OnLinkTagTextEvent(): active selection present, bailing out...");
 #endif
                 return;
             }
             
-            // get URL via TextTag from TextIter
-            Gtk.TextTag tag = (Gtk.TextTag) sender;
-            
-            start = e.Iter;
-            start.BackwardToTagToggle(tag);
-            end = e.Iter;
-            end.ForwardToTagToggle(tag);
-            _Url = Buffer.GetText(start, end, false);
+            var tag = (LinkTag) sender;
+            _ActiveLink = tag.Link;
 
             if (e.Event.Type != Gdk.EventType.ButtonRelease) {
                 return;
             }
 
-            if (String.IsNullOrEmpty(_Url)) {
+            if (_ActiveLink == null) {
 #if LOG4NET
-                _Logger.Warn("OnTextTagUrlTextEvent(): url is empty, ignoring...");
+                _Logger.Warn("OnLinkTagTextEvent(): _ActiveLink is null, ignoring...");
 #endif
                 return;
             }
 
-            OpenLink(_Url);
+            OpenLink(_ActiveLink);
         }
 
         protected virtual void OnPopulatePopup(object sender, Gtk.PopulatePopupArgs e)
         {
             Trace.Call(sender, e);
 
-            if (!_AtUrlTag) {
+            if (!_AtLinkTag) {
                 return;
             }
 
@@ -475,8 +505,8 @@ namespace Smuxi.Frontend.Gnome
 
             Gtk.ImageMenuItem open_item = new Gtk.ImageMenuItem(Gtk.Stock.Open, null);
             open_item.Activated += delegate {
-                if (!String.IsNullOrEmpty(_Url)) {
-                    OpenLink(_Url);
+                if (_ActiveLink != null) {
+                    OpenLink(_ActiveLink);
                 }
             };
             popup.Append(open_item);
@@ -485,32 +515,38 @@ namespace Smuxi.Frontend.Gnome
             copy_item.Activated += delegate {
                 Gdk.Atom clipboardAtom = Gdk.Atom.Intern("CLIPBOARD", false);
                 Gtk.Clipboard clipboard = Gtk.Clipboard.Get(clipboardAtom);
-                clipboard.Text = _Url;
+                clipboard.Text = _ActiveLink.ToString();
             };
             popup.Append(copy_item);
 
             popup.ShowAll();
         }
 
-        private void OpenLink(string link)
+        private void OpenLink(Uri link)
         {
             Trace.Call(link);
 
-            if (!Regex.IsMatch(link, @"^[a-zA-Z0-9\-]+:\/\/")) {
-                // URL doesn't start with a protocol
-                link = "http://" + link;
+            if (link == null) {
+                throw new ArgumentNullException("link");
             }
-            
+
             // hopefully MS .NET / Mono finds some way to handle the URL
             ThreadPool.QueueUserWorkItem(delegate {
+                var url = link.ToString();
                 try {
-                    SysDiag.Process.Start(link);
+                    using (var process = SysDiag.Process.Start(url)) {
+                        // Start() might return null in case it re-used a
+                        // process instead of starting one
+                        if (process != null) {
+                            process.WaitForExit();
+                        }
+                    }
                 } catch (Exception ex) {
                     // exceptions in the thread pool would kill the process, see:
                     // http://msdn.microsoft.com/en-us/library/0ka9477y.aspx
                     // http://projects.qnetp.net/issues/show/194
 #if LOG4NET
-                    _Logger.Error("OpenLink(): opening URL: '" + link + "' failed", ex);
+                    _Logger.Error("OpenLink(): opening URL: '" + url + "' failed", ex);
 #endif
                 }
             });
@@ -541,9 +577,6 @@ namespace Smuxi.Frontend.Gnome
                  } else if (bgColor != null) {
                     tt.BackgroundGdk = c;
                  }
-#if LOG4NET
-                 _Logger.Debug("GetTextTagName(): adding: " + tagname + " to _OutputTextTagTable");
-#endif
                  _MessageTextTagTable.Add(tt);
              }
              return tagname;
diff --git a/src/Frontend-GNOME/Views/ServerWidget.cs b/src/Frontend-GNOME/Views/ServerWidget.cs
index 4443570..3336562 100644
--- a/src/Frontend-GNOME/Views/ServerWidget.cs
+++ b/src/Frontend-GNOME/Views/ServerWidget.cs
@@ -117,7 +117,6 @@ namespace Smuxi.Frontend.Gnome
             f_HostnameEntry.Sensitive = false;
             f_HostnameEntry.Text = server.Hostname;
 
-            f_PortSpinButton.Value = server.Port;
             f_NetworkComboBoxEntry.Entry.Text = server.Network;
             f_UsernameEntry.Text = server.Username;
             // HACK: Twitter username is part of the PKEY, not allowed to change
@@ -128,6 +127,7 @@ namespace Smuxi.Frontend.Gnome
             f_UseEncryptionCheckButton.Active = server.UseEncryption;
             f_ValidateServerCertificateCheckButton.Active =
                 server.ValidateServerCertificate;
+            f_PortSpinButton.Value = server.Port;
             OnStartupConnectCheckButton.Active = server.OnStartupConnect;
             if (server.OnConnectCommands == null ||
                 server.OnConnectCommands.Count == 0) {
@@ -290,9 +290,9 @@ namespace Smuxi.Frontend.Gnome
                     f_PortSpinButton.Value = 5222;
                     f_PortSpinButton.Sensitive = true;
                     f_UseEncryptionCheckButton.Active = false;
-                    f_UseEncryptionCheckButton.Sensitive = false;
+                    f_UseEncryptionCheckButton.Sensitive = true;
                     f_ValidateServerCertificateCheckButton.Active = false;
-                    f_ValidateServerCertificateCheckButton.Sensitive = false;
+                    f_ValidateServerCertificateCheckButton.Sensitive = true;
                     break;
                 // this protocols have static servers
                 case "AIM":
diff --git a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs
index 9d3d587..16e9594 100644
--- a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs
+++ b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs
@@ -5,27 +5,17 @@ namespace Smuxi.Frontend.Gnome
 	public partial class ChatFindDialog
 	{
 		private global::Gtk.VBox vbox2;
-
 		private global::Gtk.HBox hbox1;
-
 		private global::Gtk.Label label1;
-
 		private global::Gtk.Entry f_SearchForEntry;
-
 		private global::Gtk.VBox vbox3;
-
 		private global::Gtk.CheckButton f_MatchCaseCheckButton;
-
 		private global::Gtk.CheckButton f_SearchBackwardsCheckButton;
-
 		private global::Gtk.CheckButton f_WrapAroundCheckButton;
-
 		private global::Gtk.CheckButton f_UseRegularExpressionsCheckButton;
-
 		private global::Gtk.Button f_CloseButton;
-
 		private global::Gtk.Button f_FindButton;
-
+        
 		protected virtual void Build ()
 		{
 			global::Stetic.Gui.Initialize (this);
@@ -54,7 +44,7 @@ namespace Smuxi.Frontend.Gnome
 			this.label1.LabelProp = global::Mono.Unix.Catalog.GetString ("_Search for:");
 			this.label1.UseUnderline = true;
 			this.hbox1.Add (this.label1);
-			global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.label1]));
+			global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.label1]));
 			w2.Position = 0;
 			w2.Expand = false;
 			w2.Fill = false;
@@ -65,10 +55,10 @@ namespace Smuxi.Frontend.Gnome
 			this.f_SearchForEntry.IsEditable = true;
 			this.f_SearchForEntry.InvisibleChar = '●';
 			this.hbox1.Add (this.f_SearchForEntry);
-			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.f_SearchForEntry]));
+			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.f_SearchForEntry]));
 			w3.Position = 1;
 			this.vbox2.Add (this.hbox1);
-			global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.hbox1]));
+			global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.hbox1]));
 			w4.Position = 0;
 			w4.Expand = false;
 			w4.Fill = false;
@@ -84,7 +74,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_MatchCaseCheckButton.DrawIndicator = true;
 			this.f_MatchCaseCheckButton.UseUnderline = true;
 			this.vbox3.Add (this.f_MatchCaseCheckButton);
-			global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.vbox3[this.f_MatchCaseCheckButton]));
+			global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.vbox3 [this.f_MatchCaseCheckButton]));
 			w5.Position = 0;
 			w5.Expand = false;
 			w5.Fill = false;
@@ -96,7 +86,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_SearchBackwardsCheckButton.DrawIndicator = true;
 			this.f_SearchBackwardsCheckButton.UseUnderline = true;
 			this.vbox3.Add (this.f_SearchBackwardsCheckButton);
-			global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(this.vbox3[this.f_SearchBackwardsCheckButton]));
+			global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(this.vbox3 [this.f_SearchBackwardsCheckButton]));
 			w6.Position = 1;
 			w6.Expand = false;
 			w6.Fill = false;
@@ -109,7 +99,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_WrapAroundCheckButton.DrawIndicator = true;
 			this.f_WrapAroundCheckButton.UseUnderline = true;
 			this.vbox3.Add (this.f_WrapAroundCheckButton);
-			global::Gtk.Box.BoxChild w7 = ((global::Gtk.Box.BoxChild)(this.vbox3[this.f_WrapAroundCheckButton]));
+			global::Gtk.Box.BoxChild w7 = ((global::Gtk.Box.BoxChild)(this.vbox3 [this.f_WrapAroundCheckButton]));
 			w7.Position = 2;
 			w7.Expand = false;
 			w7.Fill = false;
@@ -121,18 +111,18 @@ namespace Smuxi.Frontend.Gnome
 			this.f_UseRegularExpressionsCheckButton.DrawIndicator = true;
 			this.f_UseRegularExpressionsCheckButton.UseUnderline = true;
 			this.vbox3.Add (this.f_UseRegularExpressionsCheckButton);
-			global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.vbox3[this.f_UseRegularExpressionsCheckButton]));
+			global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.vbox3 [this.f_UseRegularExpressionsCheckButton]));
 			w8.PackType = ((global::Gtk.PackType)(1));
 			w8.Position = 3;
 			w8.Expand = false;
 			w8.Fill = false;
 			this.vbox2.Add (this.vbox3);
-			global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.vbox3]));
+			global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.vbox3]));
 			w9.Position = 1;
 			w9.Expand = false;
 			w9.Fill = false;
 			w1.Add (this.vbox2);
-			global::Gtk.Box.BoxChild w10 = ((global::Gtk.Box.BoxChild)(w1[this.vbox2]));
+			global::Gtk.Box.BoxChild w10 = ((global::Gtk.Box.BoxChild)(w1 [this.vbox2]));
 			w10.Position = 0;
 			w10.Expand = false;
 			w10.Fill = false;
@@ -151,7 +141,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_CloseButton.UseUnderline = true;
 			this.f_CloseButton.Label = "gtk-close";
 			this.AddActionWidget (this.f_CloseButton, -7);
-			global::Gtk.ButtonBox.ButtonBoxChild w12 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w11[this.f_CloseButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w12 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w11 [this.f_CloseButton]));
 			w12.Expand = false;
 			w12.Fill = false;
 			// Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild
@@ -163,7 +153,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_FindButton.UseUnderline = true;
 			this.f_FindButton.Label = "gtk-find";
 			this.AddActionWidget (this.f_FindButton, 0);
-			global::Gtk.ButtonBox.ButtonBoxChild w13 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w11[this.f_FindButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w13 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w11 [this.f_FindButton]));
 			w13.Position = 1;
 			w13.Expand = false;
 			w13.Fill = false;
diff --git a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatTypeWidget.cs b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatTypeWidget.cs
index 155ef70..0d37bac 100644
--- a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatTypeWidget.cs
+++ b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatTypeWidget.cs
@@ -5,7 +5,7 @@ namespace Smuxi.Frontend.Gnome
 	public partial class ChatTypeWidget
 	{
 		private global::Gtk.ComboBox f_ComboBox;
-
+        
 		protected virtual void Build ()
 		{
 			global::Stetic.Gui.Initialize (this);
diff --git a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs
index 6552409..f240c5b 100644
--- a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs
+++ b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs
@@ -5,35 +5,21 @@ namespace Smuxi.Frontend.Gnome
 	public partial class EngineAssistantConnectionWidget
 	{
 		private global::Gtk.VBox vbox2;
-
 		private global::Gtk.VBox vbox4;
-
 		private global::Gtk.CheckButton f_UseSshTunnelCheckButton;
-
 		private global::Gtk.Label label6;
-
 		private global::Gtk.Table table1;
-
 		private global::Gtk.Entry f_HostEntry;
-
 		private global::Gtk.SpinButton f_PortSpinButton;
-
 		private global::Gtk.Entry f_SshHostEntry;
-
 		private global::Gtk.SpinButton f_SshPortSpinButton;
-
 		private global::Gtk.Label label1;
-
 		private global::Gtk.Label label10;
-
 		private global::Gtk.Label label11;
-
 		private global::Gtk.Label label5;
-
 		private global::Gtk.Label label7;
-
 		private global::Gtk.Label label9;
-
+        
 		protected virtual void Build ()
 		{
 			global::Stetic.Gui.Initialize (this);
@@ -58,7 +44,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_UseSshTunnelCheckButton.DrawIndicator = true;
 			this.f_UseSshTunnelCheckButton.UseUnderline = true;
 			this.vbox4.Add (this.f_UseSshTunnelCheckButton);
-			global::Gtk.Box.BoxChild w1 = ((global::Gtk.Box.BoxChild)(this.vbox4[this.f_UseSshTunnelCheckButton]));
+			global::Gtk.Box.BoxChild w1 = ((global::Gtk.Box.BoxChild)(this.vbox4 [this.f_UseSshTunnelCheckButton]));
 			w1.Position = 0;
 			w1.Expand = false;
 			w1.Fill = false;
@@ -66,17 +52,17 @@ namespace Smuxi.Frontend.Gnome
 			this.label6 = new global::Gtk.Label ();
 			this.label6.Name = "label6";
 			this.label6.Xpad = 50;
-			this.label6.Xalign = 0f;
+			this.label6.Xalign = 0F;
 			this.label6.LabelProp = global::Mono.Unix.Catalog.GetString ("<span size=\"small\">Enables the use of SSH for the connection.  This has a small performance impact, but is more secure and required when using NAT or port-based firewalls</span>");
 			this.label6.UseMarkup = true;
 			this.label6.Wrap = true;
 			this.vbox4.Add (this.label6);
-			global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.vbox4[this.label6]));
+			global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.vbox4 [this.label6]));
 			w2.Position = 1;
 			w2.Expand = false;
 			w2.Fill = false;
 			this.vbox2.Add (this.vbox4);
-			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.vbox4]));
+			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.vbox4]));
 			w3.Position = 0;
 			w3.Expand = false;
 			w3.Fill = false;
@@ -94,7 +80,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_HostEntry.IsEditable = true;
 			this.f_HostEntry.InvisibleChar = '●';
 			this.table1.Add (this.f_HostEntry);
-			global::Gtk.Table.TableChild w4 = ((global::Gtk.Table.TableChild)(this.table1[this.f_HostEntry]));
+			global::Gtk.Table.TableChild w4 = ((global::Gtk.Table.TableChild)(this.table1 [this.f_HostEntry]));
 			w4.TopAttach = ((uint)(2));
 			w4.BottomAttach = ((uint)(3));
 			w4.LeftAttach = ((uint)(1));
@@ -110,7 +96,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_PortSpinButton.Numeric = true;
 			this.f_PortSpinButton.Value = 7689;
 			this.table1.Add (this.f_PortSpinButton);
-			global::Gtk.Table.TableChild w5 = ((global::Gtk.Table.TableChild)(this.table1[this.f_PortSpinButton]));
+			global::Gtk.Table.TableChild w5 = ((global::Gtk.Table.TableChild)(this.table1 [this.f_PortSpinButton]));
 			w5.TopAttach = ((uint)(2));
 			w5.BottomAttach = ((uint)(3));
 			w5.LeftAttach = ((uint)(3));
@@ -124,7 +110,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_SshHostEntry.IsEditable = true;
 			this.f_SshHostEntry.InvisibleChar = '●';
 			this.table1.Add (this.f_SshHostEntry);
-			global::Gtk.Table.TableChild w6 = ((global::Gtk.Table.TableChild)(this.table1[this.f_SshHostEntry]));
+			global::Gtk.Table.TableChild w6 = ((global::Gtk.Table.TableChild)(this.table1 [this.f_SshHostEntry]));
 			w6.LeftAttach = ((uint)(1));
 			w6.RightAttach = ((uint)(2));
 			w6.YOptions = ((global::Gtk.AttachOptions)(4));
@@ -137,7 +123,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_SshPortSpinButton.Numeric = true;
 			this.f_SshPortSpinButton.Value = 22;
 			this.table1.Add (this.f_SshPortSpinButton);
-			global::Gtk.Table.TableChild w7 = ((global::Gtk.Table.TableChild)(this.table1[this.f_SshPortSpinButton]));
+			global::Gtk.Table.TableChild w7 = ((global::Gtk.Table.TableChild)(this.table1 [this.f_SshPortSpinButton]));
 			w7.LeftAttach = ((uint)(3));
 			w7.RightAttach = ((uint)(4));
 			w7.XOptions = ((global::Gtk.AttachOptions)(4));
@@ -145,22 +131,22 @@ namespace Smuxi.Frontend.Gnome
 			// Container child table1.Gtk.Table+TableChild
 			this.label1 = new global::Gtk.Label ();
 			this.label1.Name = "label1";
-			this.label1.Xalign = 0f;
+			this.label1.Xalign = 0F;
 			this.label1.LabelProp = global::Mono.Unix.Catalog.GetString ("SSH _Host:");
 			this.label1.UseUnderline = true;
 			this.table1.Add (this.label1);
-			global::Gtk.Table.TableChild w8 = ((global::Gtk.Table.TableChild)(this.table1[this.label1]));
+			global::Gtk.Table.TableChild w8 = ((global::Gtk.Table.TableChild)(this.table1 [this.label1]));
 			w8.XOptions = ((global::Gtk.AttachOptions)(4));
 			w8.YOptions = ((global::Gtk.AttachOptions)(4));
 			// Container child table1.Gtk.Table+TableChild
 			this.label10 = new global::Gtk.Label ();
 			this.label10.Name = "label10";
 			this.label10.Xpad = 50;
-			this.label10.Xalign = 0f;
+			this.label10.Xalign = 0F;
 			this.label10.LabelProp = global::Mono.Unix.Catalog.GetString ("<span size=\"small\">DNS or IP address and port of the SSH server</span>");
 			this.label10.UseMarkup = true;
 			this.table1.Add (this.label10);
-			global::Gtk.Table.TableChild w9 = ((global::Gtk.Table.TableChild)(this.table1[this.label10]));
+			global::Gtk.Table.TableChild w9 = ((global::Gtk.Table.TableChild)(this.table1 [this.label10]));
 			w9.TopAttach = ((uint)(1));
 			w9.BottomAttach = ((uint)(2));
 			w9.RightAttach = ((uint)(4));
@@ -169,11 +155,11 @@ namespace Smuxi.Frontend.Gnome
 			// Container child table1.Gtk.Table+TableChild
 			this.label11 = new global::Gtk.Label ();
 			this.label11.Name = "label11";
-			this.label11.Xalign = 0f;
+			this.label11.Xalign = 0F;
 			this.label11.LabelProp = global::Mono.Unix.Catalog.GetString ("_Port:");
 			this.label11.UseUnderline = true;
 			this.table1.Add (this.label11);
-			global::Gtk.Table.TableChild w10 = ((global::Gtk.Table.TableChild)(this.table1[this.label11]));
+			global::Gtk.Table.TableChild w10 = ((global::Gtk.Table.TableChild)(this.table1 [this.label11]));
 			w10.TopAttach = ((uint)(2));
 			w10.BottomAttach = ((uint)(3));
 			w10.LeftAttach = ((uint)(2));
@@ -183,11 +169,11 @@ namespace Smuxi.Frontend.Gnome
 			// Container child table1.Gtk.Table+TableChild
 			this.label5 = new global::Gtk.Label ();
 			this.label5.Name = "label5";
-			this.label5.Xalign = 0f;
+			this.label5.Xalign = 0F;
 			this.label5.LabelProp = global::Mono.Unix.Catalog.GetString ("_Port:");
 			this.label5.UseUnderline = true;
 			this.table1.Add (this.label5);
-			global::Gtk.Table.TableChild w11 = ((global::Gtk.Table.TableChild)(this.table1[this.label5]));
+			global::Gtk.Table.TableChild w11 = ((global::Gtk.Table.TableChild)(this.table1 [this.label5]));
 			w11.LeftAttach = ((uint)(2));
 			w11.RightAttach = ((uint)(3));
 			w11.XOptions = ((global::Gtk.AttachOptions)(4));
@@ -196,11 +182,11 @@ namespace Smuxi.Frontend.Gnome
 			this.label7 = new global::Gtk.Label ();
 			this.label7.Name = "label7";
 			this.label7.Xpad = 50;
-			this.label7.Xalign = 0f;
+			this.label7.Xalign = 0F;
 			this.label7.LabelProp = global::Mono.Unix.Catalog.GetString ("<span size=\"small\">DNS or IP address and port of the Smuxi server</span>");
 			this.label7.UseMarkup = true;
 			this.table1.Add (this.label7);
-			global::Gtk.Table.TableChild w12 = ((global::Gtk.Table.TableChild)(this.table1[this.label7]));
+			global::Gtk.Table.TableChild w12 = ((global::Gtk.Table.TableChild)(this.table1 [this.label7]));
 			w12.TopAttach = ((uint)(3));
 			w12.BottomAttach = ((uint)(4));
 			w12.RightAttach = ((uint)(4));
@@ -209,17 +195,17 @@ namespace Smuxi.Frontend.Gnome
 			// Container child table1.Gtk.Table+TableChild
 			this.label9 = new global::Gtk.Label ();
 			this.label9.Name = "label9";
-			this.label9.Xalign = 0f;
+			this.label9.Xalign = 0F;
 			this.label9.LabelProp = global::Mono.Unix.Catalog.GetString ("_Smuxi Host:");
 			this.label9.UseUnderline = true;
 			this.table1.Add (this.label9);
-			global::Gtk.Table.TableChild w13 = ((global::Gtk.Table.TableChild)(this.table1[this.label9]));
+			global::Gtk.Table.TableChild w13 = ((global::Gtk.Table.TableChild)(this.table1 [this.label9]));
 			w13.TopAttach = ((uint)(2));
 			w13.BottomAttach = ((uint)(3));
 			w13.XOptions = ((global::Gtk.AttachOptions)(4));
 			w13.YOptions = ((global::Gtk.AttachOptions)(4));
 			this.vbox2.Add (this.table1);
-			global::Gtk.Box.BoxChild w14 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.table1]));
+			global::Gtk.Box.BoxChild w14 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.table1]));
 			w14.Position = 1;
 			w14.Expand = false;
 			w14.Fill = false;
diff --git a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs
index 1c82db2..23b5755 100644
--- a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs
+++ b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs
@@ -5,47 +5,31 @@ namespace Smuxi.Frontend.Gnome
 	public partial class EngineAssistantCredentialsWidget
 	{
 		private global::Gtk.VBox vbox12;
-
 		private global::Gtk.VBox vbox13;
-
 		private global::Gtk.Label label6;
-
 		private global::Gtk.Entry f_SshUsernameEntry;
-
 		private global::Gtk.Label label9;
-
 		private global::Gtk.VBox f_SshPasswordVBox;
-
 		private global::Gtk.Label label14;
-
 		private global::Gtk.Entry f_SshPasswordEntry;
-
 		private global::Gtk.Label label15;
-
+		private global::Gtk.VBox vbox17;
+		private global::Gtk.Label label16;
+		private global::Gtk.FileChooserButton f_SshKeyfileChooserButton;
+		private global::Gtk.Label label17;
 		private global::Gtk.VBox vbox16;
-
 		private global::Gtk.Label label12;
-
 		private global::Gtk.Entry f_UsernameEntry;
-
 		private global::Gtk.Label label13;
-
 		private global::Gtk.VBox vbox14;
-
 		private global::Gtk.Label label7;
-
 		private global::Gtk.Entry f_PasswordEntry;
-
 		private global::Gtk.Label label10;
-
 		private global::Gtk.VBox vbox15;
-
 		private global::Gtk.Label label8;
-
 		private global::Gtk.Entry f_VerifyPasswordEntry;
-
 		private global::Gtk.Label label11;
-
+        
 		protected virtual void Build ()
 		{
 			global::Stetic.Gui.Initialize (this);
@@ -64,11 +48,11 @@ namespace Smuxi.Frontend.Gnome
 			// Container child vbox13.Gtk.Box+BoxChild
 			this.label6 = new global::Gtk.Label ();
 			this.label6.Name = "label6";
-			this.label6.Xalign = 0f;
+			this.label6.Xalign = 0F;
 			this.label6.LabelProp = global::Mono.Unix.Catalog.GetString ("_SSH Username: (optional)");
 			this.label6.UseUnderline = true;
 			this.vbox13.Add (this.label6);
-			global::Gtk.Box.BoxChild w1 = ((global::Gtk.Box.BoxChild)(this.vbox13[this.label6]));
+			global::Gtk.Box.BoxChild w1 = ((global::Gtk.Box.BoxChild)(this.vbox13 [this.label6]));
 			w1.Position = 0;
 			w1.Expand = false;
 			w1.Fill = false;
@@ -79,7 +63,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_SshUsernameEntry.IsEditable = true;
 			this.f_SshUsernameEntry.InvisibleChar = '●';
 			this.vbox13.Add (this.f_SshUsernameEntry);
-			global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.vbox13[this.f_SshUsernameEntry]));
+			global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.vbox13 [this.f_SshUsernameEntry]));
 			w2.Position = 1;
 			w2.Expand = false;
 			w2.Fill = false;
@@ -87,16 +71,16 @@ namespace Smuxi.Frontend.Gnome
 			this.label9 = new global::Gtk.Label ();
 			this.label9.Name = "label9";
 			this.label9.Xpad = 50;
-			this.label9.Xalign = 0f;
+			this.label9.Xalign = 0F;
 			this.label9.LabelProp = global::Mono.Unix.Catalog.GetString ("<span size=\"small\">Username which will be used to log into the SSH server</span>");
 			this.label9.UseMarkup = true;
 			this.vbox13.Add (this.label9);
-			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.vbox13[this.label9]));
+			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.vbox13 [this.label9]));
 			w3.Position = 2;
 			w3.Expand = false;
 			w3.Fill = false;
 			this.vbox12.Add (this.vbox13);
-			global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.vbox12[this.vbox13]));
+			global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.vbox12 [this.vbox13]));
 			w4.Position = 0;
 			w4.Expand = false;
 			w4.Fill = false;
@@ -107,11 +91,11 @@ namespace Smuxi.Frontend.Gnome
 			// Container child f_SshPasswordVBox.Gtk.Box+BoxChild
 			this.label14 = new global::Gtk.Label ();
 			this.label14.Name = "label14";
-			this.label14.Xalign = 0f;
+			this.label14.Xalign = 0F;
 			this.label14.LabelProp = global::Mono.Unix.Catalog.GetString ("_SSH Password: (optional)");
 			this.label14.UseUnderline = true;
 			this.f_SshPasswordVBox.Add (this.label14);
-			global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.f_SshPasswordVBox[this.label14]));
+			global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.f_SshPasswordVBox [this.label14]));
 			w5.Position = 0;
 			w5.Expand = false;
 			w5.Fill = false;
@@ -123,7 +107,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_SshPasswordEntry.Visibility = false;
 			this.f_SshPasswordEntry.InvisibleChar = '●';
 			this.f_SshPasswordVBox.Add (this.f_SshPasswordEntry);
-			global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(this.f_SshPasswordVBox[this.f_SshPasswordEntry]));
+			global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(this.f_SshPasswordVBox [this.f_SshPasswordEntry]));
 			w6.Position = 1;
 			w6.Expand = false;
 			w6.Fill = false;
@@ -131,35 +115,76 @@ namespace Smuxi.Frontend.Gnome
 			this.label15 = new global::Gtk.Label ();
 			this.label15.Name = "label15";
 			this.label15.Xpad = 50;
-			this.label15.Xalign = 0f;
-			this.label15.LabelProp = global::Mono.Unix.Catalog.GetString ("<span size=\"small\">Password which will be used to log into the SSH server. The password is optional if SSH key authorization is used (via Pageant from the PuTTY tools).</span>");
+			this.label15.Xalign = 0F;
+			this.label15.LabelProp = global::Mono.Unix.Catalog.GetString ("<span size=\"small\">Password which will be used to log into the SSH server. The password is optional if SSH key authorization is used (see below).</span>");
 			this.label15.UseMarkup = true;
 			this.label15.Wrap = true;
 			this.f_SshPasswordVBox.Add (this.label15);
-			global::Gtk.Box.BoxChild w7 = ((global::Gtk.Box.BoxChild)(this.f_SshPasswordVBox[this.label15]));
+			global::Gtk.Box.BoxChild w7 = ((global::Gtk.Box.BoxChild)(this.f_SshPasswordVBox [this.label15]));
 			w7.Position = 2;
 			w7.Expand = false;
 			w7.Fill = false;
 			this.vbox12.Add (this.f_SshPasswordVBox);
-			global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.vbox12[this.f_SshPasswordVBox]));
+			global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.vbox12 [this.f_SshPasswordVBox]));
 			w8.Position = 1;
 			w8.Expand = false;
 			w8.Fill = false;
 			// Container child vbox12.Gtk.Box+BoxChild
+			this.vbox17 = new global::Gtk.VBox ();
+			this.vbox17.Name = "vbox17";
+			this.vbox17.Spacing = 6;
+			// Container child vbox17.Gtk.Box+BoxChild
+			this.label16 = new global::Gtk.Label ();
+			this.label16.Name = "label16";
+			this.label16.Xalign = 0F;
+			this.label16.LabelProp = global::Mono.Unix.Catalog.GetString ("_SSH Keyfile: (optional)");
+			this.label16.UseUnderline = true;
+			this.vbox17.Add (this.label16);
+			global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(this.vbox17 [this.label16]));
+			w9.Position = 0;
+			w9.Expand = false;
+			w9.Fill = false;
+			// Container child vbox17.Gtk.Box+BoxChild
+			this.f_SshKeyfileChooserButton = new global::Gtk.FileChooserButton (global::Mono.Unix.Catalog.GetString ("Select a File"), ((global::Gtk.FileChooserAction)(0)));
+			this.f_SshKeyfileChooserButton.Name = "f_SshKeyfileChooserButton";
+			this.f_SshKeyfileChooserButton.ShowHidden = true;
+			this.vbox17.Add (this.f_SshKeyfileChooserButton);
+			global::Gtk.Box.BoxChild w10 = ((global::Gtk.Box.BoxChild)(this.vbox17 [this.f_SshKeyfileChooserButton]));
+			w10.Position = 1;
+			w10.Expand = false;
+			w10.Fill = false;
+			// Container child vbox17.Gtk.Box+BoxChild
+			this.label17 = new global::Gtk.Label ();
+			this.label17.Name = "label17";
+			this.label17.Xpad = 50;
+			this.label17.Xalign = 0F;
+			this.label17.LabelProp = global::Mono.Unix.Catalog.GetString ("<span size=\"small\">SSH private keyfile which will be used to log into the SSH server</span>");
+			this.label17.UseMarkup = true;
+			this.vbox17.Add (this.label17);
+			global::Gtk.Box.BoxChild w11 = ((global::Gtk.Box.BoxChild)(this.vbox17 [this.label17]));
+			w11.Position = 2;
+			w11.Expand = false;
+			w11.Fill = false;
+			this.vbox12.Add (this.vbox17);
+			global::Gtk.Box.BoxChild w12 = ((global::Gtk.Box.BoxChild)(this.vbox12 [this.vbox17]));
+			w12.Position = 2;
+			w12.Expand = false;
+			w12.Fill = false;
+			// Container child vbox12.Gtk.Box+BoxChild
 			this.vbox16 = new global::Gtk.VBox ();
 			this.vbox16.Name = "vbox16";
 			this.vbox16.Spacing = 6;
 			// Container child vbox16.Gtk.Box+BoxChild
 			this.label12 = new global::Gtk.Label ();
 			this.label12.Name = "label12";
-			this.label12.Xalign = 0f;
+			this.label12.Xalign = 0F;
 			this.label12.LabelProp = global::Mono.Unix.Catalog.GetString ("_Username:");
 			this.label12.UseUnderline = true;
 			this.vbox16.Add (this.label12);
-			global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(this.vbox16[this.label12]));
-			w9.Position = 0;
-			w9.Expand = false;
-			w9.Fill = false;
+			global::Gtk.Box.BoxChild w13 = ((global::Gtk.Box.BoxChild)(this.vbox16 [this.label12]));
+			w13.Position = 0;
+			w13.Expand = false;
+			w13.Fill = false;
 			// Container child vbox16.Gtk.Box+BoxChild
 			this.f_UsernameEntry = new global::Gtk.Entry ();
 			this.f_UsernameEntry.CanFocus = true;
@@ -167,27 +192,27 @@ namespace Smuxi.Frontend.Gnome
 			this.f_UsernameEntry.IsEditable = true;
 			this.f_UsernameEntry.InvisibleChar = '●';
 			this.vbox16.Add (this.f_UsernameEntry);
-			global::Gtk.Box.BoxChild w10 = ((global::Gtk.Box.BoxChild)(this.vbox16[this.f_UsernameEntry]));
-			w10.Position = 1;
-			w10.Expand = false;
-			w10.Fill = false;
+			global::Gtk.Box.BoxChild w14 = ((global::Gtk.Box.BoxChild)(this.vbox16 [this.f_UsernameEntry]));
+			w14.Position = 1;
+			w14.Expand = false;
+			w14.Fill = false;
 			// Container child vbox16.Gtk.Box+BoxChild
 			this.label13 = new global::Gtk.Label ();
 			this.label13.Name = "label13";
 			this.label13.Xpad = 50;
-			this.label13.Xalign = 0f;
+			this.label13.Xalign = 0F;
 			this.label13.LabelProp = global::Mono.Unix.Catalog.GetString ("<span size=\"small\">Username which will be used to log into the Smuxi server</span>");
 			this.label13.UseMarkup = true;
 			this.vbox16.Add (this.label13);
-			global::Gtk.Box.BoxChild w11 = ((global::Gtk.Box.BoxChild)(this.vbox16[this.label13]));
-			w11.Position = 2;
-			w11.Expand = false;
-			w11.Fill = false;
+			global::Gtk.Box.BoxChild w15 = ((global::Gtk.Box.BoxChild)(this.vbox16 [this.label13]));
+			w15.Position = 2;
+			w15.Expand = false;
+			w15.Fill = false;
 			this.vbox12.Add (this.vbox16);
-			global::Gtk.Box.BoxChild w12 = ((global::Gtk.Box.BoxChild)(this.vbox12[this.vbox16]));
-			w12.Position = 2;
-			w12.Expand = false;
-			w12.Fill = false;
+			global::Gtk.Box.BoxChild w16 = ((global::Gtk.Box.BoxChild)(this.vbox12 [this.vbox16]));
+			w16.Position = 3;
+			w16.Expand = false;
+			w16.Fill = false;
 			// Container child vbox12.Gtk.Box+BoxChild
 			this.vbox14 = new global::Gtk.VBox ();
 			this.vbox14.Name = "vbox14";
@@ -195,14 +220,14 @@ namespace Smuxi.Frontend.Gnome
 			// Container child vbox14.Gtk.Box+BoxChild
 			this.label7 = new global::Gtk.Label ();
 			this.label7.Name = "label7";
-			this.label7.Xalign = 0f;
+			this.label7.Xalign = 0F;
 			this.label7.LabelProp = global::Mono.Unix.Catalog.GetString ("_Password:");
 			this.label7.UseUnderline = true;
 			this.vbox14.Add (this.label7);
-			global::Gtk.Box.BoxChild w13 = ((global::Gtk.Box.BoxChild)(this.vbox14[this.label7]));
-			w13.Position = 0;
-			w13.Expand = false;
-			w13.Fill = false;
+			global::Gtk.Box.BoxChild w17 = ((global::Gtk.Box.BoxChild)(this.vbox14 [this.label7]));
+			w17.Position = 0;
+			w17.Expand = false;
+			w17.Fill = false;
 			// Container child vbox14.Gtk.Box+BoxChild
 			this.f_PasswordEntry = new global::Gtk.Entry ();
 			this.f_PasswordEntry.CanFocus = true;
@@ -211,27 +236,27 @@ namespace Smuxi.Frontend.Gnome
 			this.f_PasswordEntry.Visibility = false;
 			this.f_PasswordEntry.InvisibleChar = '●';
 			this.vbox14.Add (this.f_PasswordEntry);
-			global::Gtk.Box.BoxChild w14 = ((global::Gtk.Box.BoxChild)(this.vbox14[this.f_PasswordEntry]));
-			w14.Position = 1;
-			w14.Expand = false;
-			w14.Fill = false;
+			global::Gtk.Box.BoxChild w18 = ((global::Gtk.Box.BoxChild)(this.vbox14 [this.f_PasswordEntry]));
+			w18.Position = 1;
+			w18.Expand = false;
+			w18.Fill = false;
 			// Container child vbox14.Gtk.Box+BoxChild
 			this.label10 = new global::Gtk.Label ();
 			this.label10.Name = "label10";
 			this.label10.Xpad = 50;
-			this.label10.Xalign = 0f;
+			this.label10.Xalign = 0F;
 			this.label10.LabelProp = global::Mono.Unix.Catalog.GetString ("<span size=\"small\">Password of the user</span>");
 			this.label10.UseMarkup = true;
 			this.vbox14.Add (this.label10);
-			global::Gtk.Box.BoxChild w15 = ((global::Gtk.Box.BoxChild)(this.vbox14[this.label10]));
-			w15.Position = 2;
-			w15.Expand = false;
-			w15.Fill = false;
+			global::Gtk.Box.BoxChild w19 = ((global::Gtk.Box.BoxChild)(this.vbox14 [this.label10]));
+			w19.Position = 2;
+			w19.Expand = false;
+			w19.Fill = false;
 			this.vbox12.Add (this.vbox14);
-			global::Gtk.Box.BoxChild w16 = ((global::Gtk.Box.BoxChild)(this.vbox12[this.vbox14]));
-			w16.Position = 3;
-			w16.Expand = false;
-			w16.Fill = false;
+			global::Gtk.Box.BoxChild w20 = ((global::Gtk.Box.BoxChild)(this.vbox12 [this.vbox14]));
+			w20.Position = 4;
+			w20.Expand = false;
+			w20.Fill = false;
 			// Container child vbox12.Gtk.Box+BoxChild
 			this.vbox15 = new global::Gtk.VBox ();
 			this.vbox15.Name = "vbox15";
@@ -239,14 +264,14 @@ namespace Smuxi.Frontend.Gnome
 			// Container child vbox15.Gtk.Box+BoxChild
 			this.label8 = new global::Gtk.Label ();
 			this.label8.Name = "label8";
-			this.label8.Xalign = 0f;
+			this.label8.Xalign = 0F;
 			this.label8.LabelProp = global::Mono.Unix.Catalog.GetString ("_Verify Password:");
 			this.label8.UseUnderline = true;
 			this.vbox15.Add (this.label8);
-			global::Gtk.Box.BoxChild w17 = ((global::Gtk.Box.BoxChild)(this.vbox15[this.label8]));
-			w17.Position = 0;
-			w17.Expand = false;
-			w17.Fill = false;
+			global::Gtk.Box.BoxChild w21 = ((global::Gtk.Box.BoxChild)(this.vbox15 [this.label8]));
+			w21.Position = 0;
+			w21.Expand = false;
+			w21.Fill = false;
 			// Container child vbox15.Gtk.Box+BoxChild
 			this.f_VerifyPasswordEntry = new global::Gtk.Entry ();
 			this.f_VerifyPasswordEntry.CanFocus = true;
@@ -255,33 +280,34 @@ namespace Smuxi.Frontend.Gnome
 			this.f_VerifyPasswordEntry.Visibility = false;
 			this.f_VerifyPasswordEntry.InvisibleChar = '●';
 			this.vbox15.Add (this.f_VerifyPasswordEntry);
-			global::Gtk.Box.BoxChild w18 = ((global::Gtk.Box.BoxChild)(this.vbox15[this.f_VerifyPasswordEntry]));
-			w18.Position = 1;
-			w18.Expand = false;
-			w18.Fill = false;
+			global::Gtk.Box.BoxChild w22 = ((global::Gtk.Box.BoxChild)(this.vbox15 [this.f_VerifyPasswordEntry]));
+			w22.Position = 1;
+			w22.Expand = false;
+			w22.Fill = false;
 			// Container child vbox15.Gtk.Box+BoxChild
 			this.label11 = new global::Gtk.Label ();
 			this.label11.Name = "label11";
 			this.label11.Xpad = 50;
-			this.label11.Xalign = 0f;
+			this.label11.Xalign = 0F;
 			this.label11.LabelProp = global::Mono.Unix.Catalog.GetString ("<span size=\"small\">Repeat the password for verification</span>");
 			this.label11.UseMarkup = true;
 			this.vbox15.Add (this.label11);
-			global::Gtk.Box.BoxChild w19 = ((global::Gtk.Box.BoxChild)(this.vbox15[this.label11]));
-			w19.Position = 2;
-			w19.Expand = false;
-			w19.Fill = false;
+			global::Gtk.Box.BoxChild w23 = ((global::Gtk.Box.BoxChild)(this.vbox15 [this.label11]));
+			w23.Position = 2;
+			w23.Expand = false;
+			w23.Fill = false;
 			this.vbox12.Add (this.vbox15);
-			global::Gtk.Box.BoxChild w20 = ((global::Gtk.Box.BoxChild)(this.vbox12[this.vbox15]));
-			w20.Position = 4;
-			w20.Expand = false;
-			w20.Fill = false;
+			global::Gtk.Box.BoxChild w24 = ((global::Gtk.Box.BoxChild)(this.vbox12 [this.vbox15]));
+			w24.Position = 5;
+			w24.Expand = false;
+			w24.Fill = false;
 			this.Add (this.vbox12);
 			if ((this.Child != null)) {
 				this.Child.ShowAll ();
 			}
 			this.label6.MnemonicWidget = this.f_SshUsernameEntry;
 			this.label14.MnemonicWidget = this.f_SshUsernameEntry;
+			this.label16.MnemonicWidget = this.f_SshKeyfileChooserButton;
 			this.label12.MnemonicWidget = this.f_UsernameEntry;
 			this.label7.MnemonicWidget = this.f_PasswordEntry;
 			this.label8.MnemonicWidget = this.f_VerifyPasswordEntry;
diff --git a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs
index 39466ba..681644b 100644
--- a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs
+++ b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs
@@ -5,7 +5,7 @@ namespace Smuxi.Frontend.Gnome
 	public partial class EngineAssistantIntroWidget
 	{
 		private global::Gtk.Label label2;
-
+        
 		protected virtual void Build ()
 		{
 			global::Stetic.Gui.Initialize (this);
@@ -15,7 +15,7 @@ namespace Smuxi.Frontend.Gnome
 			// Container child Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.Gtk.Container+ContainerChild
 			this.label2 = new global::Gtk.Label ();
 			this.label2.Name = "label2";
-			this.label2.Xalign = 0f;
+			this.label2.Xalign = 0F;
 			this.label2.LabelProp = global::Mono.Unix.Catalog.GetString ("Welcome to the Smuxi Engine Configuration Assistant.\nYou need to enter some information before you can use the engine.\n\nClick \"Forward\" to begin.");
 			this.Add (this.label2);
 			if ((this.Child != null)) {
diff --git a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs
index acda009..2ebe52c 100644
--- a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs
+++ b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs
@@ -5,23 +5,15 @@ namespace Smuxi.Frontend.Gnome
 	public partial class EngineAssistantNameWidget
 	{
 		private global::Gtk.VBox vbox2;
-
 		private global::Gtk.VBox vbox3;
-
 		private global::Gtk.Label f_EngineNameLabel;
-
 		private global::Gtk.Entry f_EngineNameEntry;
-
 		private global::Gtk.Label label2;
-
 		private global::Gtk.VBox vbox4;
-
 		private global::Gtk.Label label7;
-
 		private global::Gtk.CheckButton f_MakeDefaultEngineCheckButton;
-
 		private global::Gtk.Label label8;
-
+        
 		protected virtual void Build ()
 		{
 			global::Stetic.Gui.Initialize (this);
@@ -40,11 +32,11 @@ namespace Smuxi.Frontend.Gnome
 			// Container child vbox3.Gtk.Box+BoxChild
 			this.f_EngineNameLabel = new global::Gtk.Label ();
 			this.f_EngineNameLabel.Name = "f_EngineNameLabel";
-			this.f_EngineNameLabel.Xalign = 0f;
+			this.f_EngineNameLabel.Xalign = 0F;
 			this.f_EngineNameLabel.LabelProp = global::Mono.Unix.Catalog.GetString ("_Engine Name:");
 			this.f_EngineNameLabel.UseUnderline = true;
 			this.vbox3.Add (this.f_EngineNameLabel);
-			global::Gtk.Box.BoxChild w1 = ((global::Gtk.Box.BoxChild)(this.vbox3[this.f_EngineNameLabel]));
+			global::Gtk.Box.BoxChild w1 = ((global::Gtk.Box.BoxChild)(this.vbox3 [this.f_EngineNameLabel]));
 			w1.Position = 0;
 			w1.Expand = false;
 			w1.Fill = false;
@@ -55,7 +47,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_EngineNameEntry.IsEditable = true;
 			this.f_EngineNameEntry.InvisibleChar = '●';
 			this.vbox3.Add (this.f_EngineNameEntry);
-			global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.vbox3[this.f_EngineNameEntry]));
+			global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.vbox3 [this.f_EngineNameEntry]));
 			w2.Position = 1;
 			w2.Expand = false;
 			w2.Fill = false;
@@ -63,16 +55,16 @@ namespace Smuxi.Frontend.Gnome
 			this.label2 = new global::Gtk.Label ();
 			this.label2.Name = "label2";
 			this.label2.Xpad = 50;
-			this.label2.Xalign = 0f;
+			this.label2.Xalign = 0F;
 			this.label2.LabelProp = global::Mono.Unix.Catalog.GetString ("<span size=\"small\">Profile name of the new engine</span>");
 			this.label2.UseMarkup = true;
 			this.vbox3.Add (this.label2);
-			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.vbox3[this.label2]));
+			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.vbox3 [this.label2]));
 			w3.Position = 2;
 			w3.Expand = false;
 			w3.Fill = false;
 			this.vbox2.Add (this.vbox3);
-			global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.vbox3]));
+			global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.vbox3]));
 			w4.Position = 0;
 			w4.Expand = false;
 			w4.Fill = false;
@@ -84,11 +76,11 @@ namespace Smuxi.Frontend.Gnome
 			// Container child vbox4.Gtk.Box+BoxChild
 			this.label7 = new global::Gtk.Label ();
 			this.label7.Name = "label7";
-			this.label7.Xalign = 0f;
+			this.label7.Xalign = 0F;
 			this.label7.LabelProp = global::Mono.Unix.Catalog.GetString ("_Default Engine:");
 			this.label7.UseUnderline = true;
 			this.vbox4.Add (this.label7);
-			global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.vbox4[this.label7]));
+			global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.vbox4 [this.label7]));
 			w5.Position = 0;
 			w5.Expand = false;
 			w5.Fill = false;
@@ -100,7 +92,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_MakeDefaultEngineCheckButton.DrawIndicator = true;
 			this.f_MakeDefaultEngineCheckButton.UseUnderline = true;
 			this.vbox4.Add (this.f_MakeDefaultEngineCheckButton);
-			global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(this.vbox4[this.f_MakeDefaultEngineCheckButton]));
+			global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(this.vbox4 [this.f_MakeDefaultEngineCheckButton]));
 			w6.Position = 1;
 			w6.Expand = false;
 			w6.Fill = false;
@@ -108,17 +100,17 @@ namespace Smuxi.Frontend.Gnome
 			this.label8 = new global::Gtk.Label ();
 			this.label8.Name = "label8";
 			this.label8.Xpad = 50;
-			this.label8.Xalign = 0f;
+			this.label8.Xalign = 0F;
 			this.label8.LabelProp = global::Mono.Unix.Catalog.GetString ("<span size=\"small\">If enabled, the current engine will be the default next time Smuxi is started</span>");
 			this.label8.UseMarkup = true;
 			this.label8.Wrap = true;
 			this.vbox4.Add (this.label8);
-			global::Gtk.Box.BoxChild w7 = ((global::Gtk.Box.BoxChild)(this.vbox4[this.label8]));
+			global::Gtk.Box.BoxChild w7 = ((global::Gtk.Box.BoxChild)(this.vbox4 [this.label8]));
 			w7.Position = 2;
 			w7.Expand = false;
 			w7.Fill = false;
 			this.vbox2.Add (this.vbox4);
-			global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.vbox4]));
+			global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.vbox4]));
 			w8.Position = 1;
 			w8.Expand = false;
 			w8.Fill = false;
diff --git a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FilterListWidget.cs b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FilterListWidget.cs
index 2ac0fa1..93d23ac 100644
--- a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FilterListWidget.cs
+++ b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FilterListWidget.cs
@@ -5,17 +5,12 @@ namespace Smuxi.Frontend.Gnome
 	public partial class FilterListWidget
 	{
 		private global::Gtk.HBox hbox1;
-
 		private global::Gtk.ScrolledWindow scrolledwindow1;
-
 		private global::Gtk.TreeView f_TreeView;
-
 		private global::Gtk.VButtonBox vbuttonbox1;
-
 		private global::Gtk.Button f_AddButton;
-
 		private global::Gtk.Button f_RemoveButton;
-
+        
 		protected virtual void Build ()
 		{
 			global::Stetic.Gui.Initialize (this);
@@ -36,7 +31,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_TreeView.Name = "f_TreeView";
 			this.scrolledwindow1.Add (this.f_TreeView);
 			this.hbox1.Add (this.scrolledwindow1);
-			global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.scrolledwindow1]));
+			global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.scrolledwindow1]));
 			w2.Position = 0;
 			// Container child hbox1.Gtk.Box+BoxChild
 			this.vbuttonbox1 = new global::Gtk.VButtonBox ();
@@ -51,7 +46,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_AddButton.UseUnderline = true;
 			this.f_AddButton.Label = "gtk-add";
 			this.vbuttonbox1.Add (this.f_AddButton);
-			global::Gtk.ButtonBox.ButtonBoxChild w3 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.vbuttonbox1[this.f_AddButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w3 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.vbuttonbox1 [this.f_AddButton]));
 			w3.Expand = false;
 			w3.Fill = false;
 			// Container child vbuttonbox1.Gtk.ButtonBox+ButtonBoxChild
@@ -62,12 +57,12 @@ namespace Smuxi.Frontend.Gnome
 			this.f_RemoveButton.UseUnderline = true;
 			this.f_RemoveButton.Label = "gtk-remove";
 			this.vbuttonbox1.Add (this.f_RemoveButton);
-			global::Gtk.ButtonBox.ButtonBoxChild w4 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.vbuttonbox1[this.f_RemoveButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w4 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.vbuttonbox1 [this.f_RemoveButton]));
 			w4.Position = 1;
 			w4.Expand = false;
 			w4.Fill = false;
 			this.hbox1.Add (this.vbuttonbox1);
-			global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.vbuttonbox1]));
+			global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.vbuttonbox1]));
 			w5.Position = 1;
 			w5.Expand = false;
 			w5.Fill = false;
diff --git a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs
index 49dad40..9cf9cab 100644
--- a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs
+++ b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs
@@ -5,25 +5,16 @@ namespace Smuxi.Frontend.Gnome
 	public partial class FindGroupChatDialog
 	{
 		private global::Gtk.VBox vbox2;
-
 		private global::Gtk.HBox hbox1;
-
 		private global::Gtk.HBox hbox2;
-
 		private global::Gtk.Label label1;
-
 		private global::Gtk.Entry f_NameEntry;
-
 		private global::Gtk.Button f_FindButton;
-
 		private global::Gtk.ScrolledWindow GtkScrolledWindow;
-
 		private global::Gtk.TreeView f_TreeView;
-
 		private global::Gtk.Button f_CancelButton;
-
 		private global::Gtk.Button f_OKButton;
-
+        
 		protected virtual void Build ()
 		{
 			global::Stetic.Gui.Initialize (this);
@@ -56,7 +47,7 @@ namespace Smuxi.Frontend.Gnome
 			this.label1.LabelProp = global::Mono.Unix.Catalog.GetString ("_Name:");
 			this.label1.UseUnderline = true;
 			this.hbox2.Add (this.label1);
-			global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.hbox2[this.label1]));
+			global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.hbox2 [this.label1]));
 			w2.Position = 0;
 			w2.Expand = false;
 			w2.Fill = false;
@@ -68,10 +59,10 @@ namespace Smuxi.Frontend.Gnome
 			this.f_NameEntry.IsEditable = true;
 			this.f_NameEntry.InvisibleChar = '●';
 			this.hbox2.Add (this.f_NameEntry);
-			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox2[this.f_NameEntry]));
+			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox2 [this.f_NameEntry]));
 			w3.Position = 1;
 			this.hbox1.Add (this.hbox2);
-			global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.hbox2]));
+			global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.hbox2]));
 			w4.Position = 0;
 			// Container child hbox1.Gtk.Box+BoxChild
 			this.f_FindButton = new global::Gtk.Button ();
@@ -81,12 +72,12 @@ namespace Smuxi.Frontend.Gnome
 			this.f_FindButton.UseUnderline = true;
 			this.f_FindButton.Label = "gtk-find";
 			this.hbox1.Add (this.f_FindButton);
-			global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.f_FindButton]));
+			global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.f_FindButton]));
 			w5.Position = 1;
 			w5.Expand = false;
 			w5.Fill = false;
 			this.vbox2.Add (this.hbox1);
-			global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.hbox1]));
+			global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.hbox1]));
 			w6.Position = 0;
 			w6.Expand = false;
 			w6.Fill = false;
@@ -100,10 +91,10 @@ namespace Smuxi.Frontend.Gnome
 			this.f_TreeView.Name = "f_TreeView";
 			this.GtkScrolledWindow.Add (this.f_TreeView);
 			this.vbox2.Add (this.GtkScrolledWindow);
-			global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.GtkScrolledWindow]));
+			global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.GtkScrolledWindow]));
 			w8.Position = 1;
 			w1.Add (this.vbox2);
-			global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(w1[this.vbox2]));
+			global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(w1 [this.vbox2]));
 			w9.Position = 0;
 			// Internal child Smuxi.Frontend.Gnome.FindGroupChatDialog.ActionArea
 			global::Gtk.HButtonBox w10 = this.ActionArea;
@@ -120,7 +111,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_CancelButton.UseUnderline = true;
 			this.f_CancelButton.Label = "gtk-cancel";
 			this.AddActionWidget (this.f_CancelButton, -6);
-			global::Gtk.ButtonBox.ButtonBoxChild w11 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w10[this.f_CancelButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w11 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w10 [this.f_CancelButton]));
 			w11.Expand = false;
 			w11.Fill = false;
 			// Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild
@@ -132,7 +123,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_OKButton.UseUnderline = true;
 			this.f_OKButton.Label = "gtk-ok";
 			this.AddActionWidget (this.f_OKButton, -5);
-			global::Gtk.ButtonBox.ButtonBoxChild w12 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w10[this.f_OKButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w12 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w10 [this.f_OKButton]));
 			w12.Position = 1;
 			w12.Expand = false;
 			w12.Fill = false;
diff --git a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs
index 3758431..4eb853d 100644
--- a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs
+++ b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs
@@ -5,19 +5,13 @@ namespace Smuxi.Frontend.Gnome
 	public partial class OpenChatDialog
 	{
 		private global::Gtk.Table table1;
-
 		private global::Smuxi.Frontend.Gnome.ChatTypeWidget f_ChatTypeWidget;
-
 		private global::Gtk.Entry f_NameEntry;
-
 		private global::Gtk.Label label1;
-
 		private global::Gtk.Label label2;
-
 		private global::Gtk.Button f_CancelButton;
-
 		private global::Gtk.Button f_OpenButton;
-
+        
 		protected virtual void Build ()
 		{
 			global::Stetic.Gui.Initialize (this);
@@ -42,7 +36,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_ChatTypeWidget.Events = ((global::Gdk.EventMask)(256));
 			this.f_ChatTypeWidget.Name = "f_ChatTypeWidget";
 			this.table1.Add (this.f_ChatTypeWidget);
-			global::Gtk.Table.TableChild w2 = ((global::Gtk.Table.TableChild)(this.table1[this.f_ChatTypeWidget]));
+			global::Gtk.Table.TableChild w2 = ((global::Gtk.Table.TableChild)(this.table1 [this.f_ChatTypeWidget]));
 			w2.LeftAttach = ((uint)(1));
 			w2.RightAttach = ((uint)(2));
 			w2.XOptions = ((global::Gtk.AttachOptions)(4));
@@ -55,7 +49,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_NameEntry.ActivatesDefault = true;
 			this.f_NameEntry.InvisibleChar = '●';
 			this.table1.Add (this.f_NameEntry);
-			global::Gtk.Table.TableChild w3 = ((global::Gtk.Table.TableChild)(this.table1[this.f_NameEntry]));
+			global::Gtk.Table.TableChild w3 = ((global::Gtk.Table.TableChild)(this.table1 [this.f_NameEntry]));
 			w3.TopAttach = ((uint)(1));
 			w3.BottomAttach = ((uint)(2));
 			w3.LeftAttach = ((uint)(1));
@@ -65,27 +59,27 @@ namespace Smuxi.Frontend.Gnome
 			// Container child table1.Gtk.Table+TableChild
 			this.label1 = new global::Gtk.Label ();
 			this.label1.Name = "label1";
-			this.label1.Xalign = 0f;
+			this.label1.Xalign = 0F;
 			this.label1.LabelProp = global::Mono.Unix.Catalog.GetString ("_Type:");
 			this.label1.UseUnderline = true;
 			this.table1.Add (this.label1);
-			global::Gtk.Table.TableChild w4 = ((global::Gtk.Table.TableChild)(this.table1[this.label1]));
+			global::Gtk.Table.TableChild w4 = ((global::Gtk.Table.TableChild)(this.table1 [this.label1]));
 			w4.XOptions = ((global::Gtk.AttachOptions)(4));
 			w4.YOptions = ((global::Gtk.AttachOptions)(4));
 			// Container child table1.Gtk.Table+TableChild
 			this.label2 = new global::Gtk.Label ();
 			this.label2.Name = "label2";
-			this.label2.Xalign = 0f;
+			this.label2.Xalign = 0F;
 			this.label2.LabelProp = global::Mono.Unix.Catalog.GetString ("_Name:");
 			this.label2.UseUnderline = true;
 			this.table1.Add (this.label2);
-			global::Gtk.Table.TableChild w5 = ((global::Gtk.Table.TableChild)(this.table1[this.label2]));
+			global::Gtk.Table.TableChild w5 = ((global::Gtk.Table.TableChild)(this.table1 [this.label2]));
 			w5.TopAttach = ((uint)(1));
 			w5.BottomAttach = ((uint)(2));
 			w5.XOptions = ((global::Gtk.AttachOptions)(4));
 			w5.YOptions = ((global::Gtk.AttachOptions)(4));
 			w1.Add (this.table1);
-			global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(w1[this.table1]));
+			global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(w1 [this.table1]));
 			w6.Position = 0;
 			w6.Expand = false;
 			w6.Fill = false;
@@ -103,7 +97,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_CancelButton.UseUnderline = true;
 			this.f_CancelButton.Label = "gtk-cancel";
 			this.AddActionWidget (this.f_CancelButton, -6);
-			global::Gtk.ButtonBox.ButtonBoxChild w8 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w7[this.f_CancelButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w8 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w7 [this.f_CancelButton]));
 			w8.Expand = false;
 			w8.Fill = false;
 			// Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild
@@ -116,7 +110,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_OpenButton.UseUnderline = true;
 			this.f_OpenButton.Label = "gtk-open";
 			this.AddActionWidget (this.f_OpenButton, -5);
-			global::Gtk.ButtonBox.ButtonBoxChild w9 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w7[this.f_OpenButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w9 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w7 [this.f_OpenButton]));
 			w9.Position = 1;
 			w9.Expand = false;
 			w9.Fill = false;
diff --git a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs
index 2a31248..1b9e030 100644
--- a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs
+++ b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs
@@ -5,17 +5,12 @@ namespace Smuxi.Frontend.Gnome
 	public partial class QuickConnectDialog
 	{
 		private global::Gtk.HBox hbox1;
-
 		private global::Gtk.ScrolledWindow f_ScrolledWindow;
-
 		private global::Gtk.TreeView f_TreeView;
-
 		private global::Smuxi.Frontend.Gnome.ServerWidget f_Widget;
-
 		private global::Gtk.Button f_CancelButton;
-
 		private global::Gtk.Button f_ConnectButton;
-
+        
 		protected virtual void Build ()
 		{
 			global::Stetic.Gui.Initialize (this);
@@ -45,19 +40,19 @@ namespace Smuxi.Frontend.Gnome
 			this.f_TreeView.Name = "f_TreeView";
 			this.f_ScrolledWindow.Add (this.f_TreeView);
 			this.hbox1.Add (this.f_ScrolledWindow);
-			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.f_ScrolledWindow]));
+			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.f_ScrolledWindow]));
 			w3.Position = 0;
 			// Container child hbox1.Gtk.Box+BoxChild
 			this.f_Widget = new global::Smuxi.Frontend.Gnome.ServerWidget ();
 			this.f_Widget.Events = ((global::Gdk.EventMask)(256));
 			this.f_Widget.Name = "f_Widget";
 			this.hbox1.Add (this.f_Widget);
-			global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.f_Widget]));
+			global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.f_Widget]));
 			w4.Position = 1;
 			w4.Expand = false;
 			w4.Fill = false;
 			w1.Add (this.hbox1);
-			global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(w1[this.hbox1]));
+			global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(w1 [this.hbox1]));
 			w5.Position = 0;
 			// Internal child Smuxi.Frontend.Gnome.QuickConnectDialog.ActionArea
 			global::Gtk.HButtonBox w6 = this.ActionArea;
@@ -72,7 +67,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_CancelButton.UseUnderline = true;
 			this.f_CancelButton.Label = "gtk-cancel";
 			this.AddActionWidget (this.f_CancelButton, -6);
-			global::Gtk.ButtonBox.ButtonBoxChild w7 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w6[this.f_CancelButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w7 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w6 [this.f_CancelButton]));
 			w7.Expand = false;
 			w7.Fill = false;
 			// Container child dialog-action_area2.Gtk.ButtonBox+ButtonBoxChild
@@ -82,7 +77,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_ConnectButton.UseUnderline = true;
 			this.f_ConnectButton.Label = "gtk-connect";
 			this.AddActionWidget (this.f_ConnectButton, -5);
-			global::Gtk.ButtonBox.ButtonBoxChild w8 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w6[this.f_ConnectButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w8 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w6 [this.f_ConnectButton]));
 			w8.Position = 1;
 			w8.Expand = false;
 			w8.Fill = false;
diff --git a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs
index ea1b73c..12049b9 100644
--- a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs
+++ b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs
@@ -5,11 +5,9 @@ namespace Smuxi.Frontend.Gnome
 	public partial class ServerDialog
 	{
 		private global::Smuxi.Frontend.Gnome.ServerWidget f_Widget;
-
 		private global::Gtk.Button buttonCancel;
-
 		private global::Gtk.Button buttonOk;
-
+        
 		protected virtual void Build ()
 		{
 			global::Stetic.Gui.Initialize (this);
@@ -26,7 +24,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_Widget.Events = ((global::Gdk.EventMask)(256));
 			this.f_Widget.Name = "f_Widget";
 			w1.Add (this.f_Widget);
-			global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(w1[this.f_Widget]));
+			global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(w1 [this.f_Widget]));
 			w2.Position = 0;
 			w2.Padding = ((uint)(5));
 			// Internal child Smuxi.Frontend.Gnome.ServerDialog.ActionArea
@@ -44,7 +42,7 @@ namespace Smuxi.Frontend.Gnome
 			this.buttonCancel.UseUnderline = true;
 			this.buttonCancel.Label = "gtk-cancel";
 			this.AddActionWidget (this.buttonCancel, -6);
-			global::Gtk.ButtonBox.ButtonBoxChild w4 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w3[this.buttonCancel]));
+			global::Gtk.ButtonBox.ButtonBoxChild w4 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w3 [this.buttonCancel]));
 			w4.Expand = false;
 			w4.Fill = false;
 			// Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild
@@ -56,7 +54,7 @@ namespace Smuxi.Frontend.Gnome
 			this.buttonOk.UseUnderline = true;
 			this.buttonOk.Label = "gtk-ok";
 			this.AddActionWidget (this.buttonOk, -5);
-			global::Gtk.ButtonBox.ButtonBoxChild w5 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w3[this.buttonOk]));
+			global::Gtk.ButtonBox.ButtonBoxChild w5 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w3 [this.buttonOk]));
 			w5.Position = 1;
 			w5.Expand = false;
 			w5.Fill = false;
diff --git a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs
index bb5ad25..887016f 100644
--- a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs
+++ b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs
@@ -5,59 +5,33 @@ namespace Smuxi.Frontend.Gnome
 	public partial class ServerWidget
 	{
 		private global::Gtk.VBox vbox16;
-
 		private global::Gtk.Table table2;
-
 		private global::Gtk.Label f_HostnameLabel;
-
 		private global::Gtk.ComboBoxEntry f_NetworkComboBoxEntry;
-
 		private global::Gtk.Label f_NetworkLabel;
-
 		private global::Gtk.Label f_PasswordLabel;
-
 		private global::Gtk.ComboBox f_ProtocolComboBox;
-
 		private global::Gtk.Entry f_UsernameEntry;
-
 		private global::Gtk.HBox hbox10;
-
 		private global::Gtk.Entry f_HostnameEntry;
-
 		private global::Gtk.HBox hbox11;
-
 		private global::Gtk.Label f_PortLabel;
-
 		private global::Gtk.SpinButton f_PortSpinButton;
-
 		private global::Gtk.HBox hbox2;
-
 		private global::Gtk.Entry f_PasswordEntry;
-
 		private global::Gtk.CheckButton f_ShowPasswordCheckButton;
-
 		private global::Gtk.Label label21;
-
 		private global::Gtk.Label label5;
-
 		private global::Gtk.CheckButton f_OnStartupConnectCheckButton;
-
 		private global::Gtk.CheckButton f_UseEncryptionCheckButton;
-
 		private global::Gtk.CheckButton f_ValidateServerCertificateCheckButton;
-
 		private global::Gtk.VBox vbox2;
-
 		private global::Gtk.HBox hbox3;
-
 		private global::Gtk.Label label37;
-
 		private global::Gtk.CheckButton f_IgnoreOnConnectCommandsCheckButton;
-
 		private global::Gtk.ScrolledWindow scrolledwindow1;
-
 		private global::Gtk.TextView f_OnConnectCommandsTextView;
-
+        
 		protected virtual void Build ()
 		{
 			global::Stetic.Gui.Initialize (this);
@@ -76,18 +50,18 @@ namespace Smuxi.Frontend.Gnome
 			// Container child table2.Gtk.Table+TableChild
 			this.f_HostnameLabel = new global::Gtk.Label ();
 			this.f_HostnameLabel.Name = "f_HostnameLabel";
-			this.f_HostnameLabel.Xalign = 0f;
+			this.f_HostnameLabel.Xalign = 0F;
 			this.f_HostnameLabel.LabelProp = global::Mono.Unix.Catalog.GetString ("_Hostname:");
 			this.f_HostnameLabel.UseUnderline = true;
 			this.table2.Add (this.f_HostnameLabel);
-			global::Gtk.Table.TableChild w1 = ((global::Gtk.Table.TableChild)(this.table2[this.f_HostnameLabel]));
+			global::Gtk.Table.TableChild w1 = ((global::Gtk.Table.TableChild)(this.table2 [this.f_HostnameLabel]));
 			w1.TopAttach = ((uint)(1));
 			w1.BottomAttach = ((uint)(2));
 			// Container child table2.Gtk.Table+TableChild
 			this.f_NetworkComboBoxEntry = global::Gtk.ComboBoxEntry.NewText ();
 			this.f_NetworkComboBoxEntry.Name = "f_NetworkComboBoxEntry";
 			this.table2.Add (this.f_NetworkComboBoxEntry);
-			global::Gtk.Table.TableChild w2 = ((global::Gtk.Table.TableChild)(this.table2[this.f_NetworkComboBoxEntry]));
+			global::Gtk.Table.TableChild w2 = ((global::Gtk.Table.TableChild)(this.table2 [this.f_NetworkComboBoxEntry]));
 			w2.TopAttach = ((uint)(2));
 			w2.BottomAttach = ((uint)(3));
 			w2.LeftAttach = ((uint)(1));
@@ -97,11 +71,11 @@ namespace Smuxi.Frontend.Gnome
 			// Container child table2.Gtk.Table+TableChild
 			this.f_NetworkLabel = new global::Gtk.Label ();
 			this.f_NetworkLabel.Name = "f_NetworkLabel";
-			this.f_NetworkLabel.Xalign = 0f;
+			this.f_NetworkLabel.Xalign = 0F;
 			this.f_NetworkLabel.LabelProp = global::Mono.Unix.Catalog.GetString ("_Network:");
 			this.f_NetworkLabel.UseUnderline = true;
 			this.table2.Add (this.f_NetworkLabel);
-			global::Gtk.Table.TableChild w3 = ((global::Gtk.Table.TableChild)(this.table2[this.f_NetworkLabel]));
+			global::Gtk.Table.TableChild w3 = ((global::Gtk.Table.TableChild)(this.table2 [this.f_NetworkLabel]));
 			w3.TopAttach = ((uint)(2));
 			w3.BottomAttach = ((uint)(3));
 			w3.XOptions = ((global::Gtk.AttachOptions)(4));
@@ -109,18 +83,18 @@ namespace Smuxi.Frontend.Gnome
 			// Container child table2.Gtk.Table+TableChild
 			this.f_PasswordLabel = new global::Gtk.Label ();
 			this.f_PasswordLabel.Name = "f_PasswordLabel";
-			this.f_PasswordLabel.Xalign = 0f;
+			this.f_PasswordLabel.Xalign = 0F;
 			this.f_PasswordLabel.LabelProp = global::Mono.Unix.Catalog.GetString ("_Password:");
 			this.f_PasswordLabel.UseUnderline = true;
 			this.table2.Add (this.f_PasswordLabel);
-			global::Gtk.Table.TableChild w4 = ((global::Gtk.Table.TableChild)(this.table2[this.f_PasswordLabel]));
+			global::Gtk.Table.TableChild w4 = ((global::Gtk.Table.TableChild)(this.table2 [this.f_PasswordLabel]));
 			w4.TopAttach = ((uint)(4));
 			w4.BottomAttach = ((uint)(5));
 			// Container child table2.Gtk.Table+TableChild
 			this.f_ProtocolComboBox = new global::Gtk.ComboBox ();
 			this.f_ProtocolComboBox.Name = "f_ProtocolComboBox";
 			this.table2.Add (this.f_ProtocolComboBox);
-			global::Gtk.Table.TableChild w5 = ((global::Gtk.Table.TableChild)(this.table2[this.f_ProtocolComboBox]));
+			global::Gtk.Table.TableChild w5 = ((global::Gtk.Table.TableChild)(this.table2 [this.f_ProtocolComboBox]));
 			w5.LeftAttach = ((uint)(1));
 			w5.RightAttach = ((uint)(2));
 			// Container child table2.Gtk.Table+TableChild
@@ -129,7 +103,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_UsernameEntry.IsEditable = true;
 			this.f_UsernameEntry.InvisibleChar = '●';
 			this.table2.Add (this.f_UsernameEntry);
-			global::Gtk.Table.TableChild w6 = ((global::Gtk.Table.TableChild)(this.table2[this.f_UsernameEntry]));
+			global::Gtk.Table.TableChild w6 = ((global::Gtk.Table.TableChild)(this.table2 [this.f_UsernameEntry]));
 			w6.TopAttach = ((uint)(3));
 			w6.BottomAttach = ((uint)(4));
 			w6.LeftAttach = ((uint)(1));
@@ -143,7 +117,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_HostnameEntry.IsEditable = true;
 			this.f_HostnameEntry.InvisibleChar = '●';
 			this.hbox10.Add (this.f_HostnameEntry);
-			global::Gtk.Box.BoxChild w7 = ((global::Gtk.Box.BoxChild)(this.hbox10[this.f_HostnameEntry]));
+			global::Gtk.Box.BoxChild w7 = ((global::Gtk.Box.BoxChild)(this.hbox10 [this.f_HostnameEntry]));
 			w7.Position = 0;
 			// Container child hbox10.Gtk.Box+BoxChild
 			this.hbox11 = new global::Gtk.HBox ();
@@ -155,7 +129,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_PortLabel.LabelProp = global::Mono.Unix.Catalog.GetString ("_Port:");
 			this.f_PortLabel.UseUnderline = true;
 			this.hbox11.Add (this.f_PortLabel);
-			global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.hbox11[this.f_PortLabel]));
+			global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.hbox11 [this.f_PortLabel]));
 			w8.Position = 0;
 			// Container child hbox11.Gtk.Box+BoxChild
 			this.f_PortSpinButton = new global::Gtk.SpinButton (0, 65535, 1);
@@ -165,13 +139,13 @@ namespace Smuxi.Frontend.Gnome
 			this.f_PortSpinButton.ClimbRate = 1;
 			this.f_PortSpinButton.Numeric = true;
 			this.hbox11.Add (this.f_PortSpinButton);
-			global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(this.hbox11[this.f_PortSpinButton]));
+			global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(this.hbox11 [this.f_PortSpinButton]));
 			w9.Position = 1;
 			this.hbox10.Add (this.hbox11);
-			global::Gtk.Box.BoxChild w10 = ((global::Gtk.Box.BoxChild)(this.hbox10[this.hbox11]));
+			global::Gtk.Box.BoxChild w10 = ((global::Gtk.Box.BoxChild)(this.hbox10 [this.hbox11]));
 			w10.Position = 1;
 			this.table2.Add (this.hbox10);
-			global::Gtk.Table.TableChild w11 = ((global::Gtk.Table.TableChild)(this.table2[this.hbox10]));
+			global::Gtk.Table.TableChild w11 = ((global::Gtk.Table.TableChild)(this.table2 [this.hbox10]));
 			w11.TopAttach = ((uint)(1));
 			w11.BottomAttach = ((uint)(2));
 			w11.LeftAttach = ((uint)(1));
@@ -187,7 +161,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_PasswordEntry.Visibility = false;
 			this.f_PasswordEntry.InvisibleChar = '●';
 			this.hbox2.Add (this.f_PasswordEntry);
-			global::Gtk.Box.BoxChild w12 = ((global::Gtk.Box.BoxChild)(this.hbox2[this.f_PasswordEntry]));
+			global::Gtk.Box.BoxChild w12 = ((global::Gtk.Box.BoxChild)(this.hbox2 [this.f_PasswordEntry]));
 			w12.Position = 0;
 			// Container child hbox2.Gtk.Box+BoxChild
 			this.f_ShowPasswordCheckButton = new global::Gtk.CheckButton ();
@@ -197,10 +171,10 @@ namespace Smuxi.Frontend.Gnome
 			this.f_ShowPasswordCheckButton.DrawIndicator = true;
 			this.f_ShowPasswordCheckButton.UseUnderline = true;
 			this.hbox2.Add (this.f_ShowPasswordCheckButton);
-			global::Gtk.Box.BoxChild w13 = ((global::Gtk.Box.BoxChild)(this.hbox2[this.f_ShowPasswordCheckButton]));
+			global::Gtk.Box.BoxChild w13 = ((global::Gtk.Box.BoxChild)(this.hbox2 [this.f_ShowPasswordCheckButton]));
 			w13.Position = 1;
 			this.table2.Add (this.hbox2);
-			global::Gtk.Table.TableChild w14 = ((global::Gtk.Table.TableChild)(this.table2[this.hbox2]));
+			global::Gtk.Table.TableChild w14 = ((global::Gtk.Table.TableChild)(this.table2 [this.hbox2]));
 			w14.TopAttach = ((uint)(4));
 			w14.BottomAttach = ((uint)(5));
 			w14.LeftAttach = ((uint)(1));
@@ -210,22 +184,22 @@ namespace Smuxi.Frontend.Gnome
 			// Container child table2.Gtk.Table+TableChild
 			this.label21 = new global::Gtk.Label ();
 			this.label21.Name = "label21";
-			this.label21.Xalign = 0f;
+			this.label21.Xalign = 0F;
 			this.label21.LabelProp = global::Mono.Unix.Catalog.GetString ("_Username:");
 			this.label21.UseUnderline = true;
 			this.table2.Add (this.label21);
-			global::Gtk.Table.TableChild w15 = ((global::Gtk.Table.TableChild)(this.table2[this.label21]));
+			global::Gtk.Table.TableChild w15 = ((global::Gtk.Table.TableChild)(this.table2 [this.label21]));
 			w15.TopAttach = ((uint)(3));
 			w15.BottomAttach = ((uint)(4));
 			// Container child table2.Gtk.Table+TableChild
 			this.label5 = new global::Gtk.Label ();
 			this.label5.Name = "label5";
-			this.label5.Xalign = 0f;
+			this.label5.Xalign = 0F;
 			this.label5.LabelProp = global::Mono.Unix.Catalog.GetString ("_Protocol:");
 			this.label5.UseUnderline = true;
 			this.table2.Add (this.label5);
 			this.vbox16.Add (this.table2);
-			global::Gtk.Box.BoxChild w17 = ((global::Gtk.Box.BoxChild)(this.vbox16[this.table2]));
+			global::Gtk.Box.BoxChild w17 = ((global::Gtk.Box.BoxChild)(this.vbox16 [this.table2]));
 			w17.Position = 0;
 			w17.Expand = false;
 			// Container child vbox16.Gtk.Box+BoxChild
@@ -235,9 +209,9 @@ namespace Smuxi.Frontend.Gnome
 			this.f_OnStartupConnectCheckButton.Label = global::Mono.Unix.Catalog.GetString ("Automatically connect to server at startup");
 			this.f_OnStartupConnectCheckButton.DrawIndicator = true;
 			this.f_OnStartupConnectCheckButton.UseUnderline = true;
-			this.f_OnStartupConnectCheckButton.Xalign = 0f;
+			this.f_OnStartupConnectCheckButton.Xalign = 0F;
 			this.vbox16.Add (this.f_OnStartupConnectCheckButton);
-			global::Gtk.Box.BoxChild w18 = ((global::Gtk.Box.BoxChild)(this.vbox16[this.f_OnStartupConnectCheckButton]));
+			global::Gtk.Box.BoxChild w18 = ((global::Gtk.Box.BoxChild)(this.vbox16 [this.f_OnStartupConnectCheckButton]));
 			w18.Position = 1;
 			w18.Expand = false;
 			w18.Fill = false;
@@ -249,7 +223,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_UseEncryptionCheckButton.DrawIndicator = true;
 			this.f_UseEncryptionCheckButton.UseUnderline = true;
 			this.vbox16.Add (this.f_UseEncryptionCheckButton);
-			global::Gtk.Box.BoxChild w19 = ((global::Gtk.Box.BoxChild)(this.vbox16[this.f_UseEncryptionCheckButton]));
+			global::Gtk.Box.BoxChild w19 = ((global::Gtk.Box.BoxChild)(this.vbox16 [this.f_UseEncryptionCheckButton]));
 			w19.Position = 2;
 			w19.Expand = false;
 			w19.Fill = false;
@@ -261,7 +235,7 @@ namespace Smuxi.Frontend.Gnome
 			this.f_ValidateServerCertificateCheckButton.DrawIndicator = true;
 			this.f_ValidateServerCertificateCheckButton.UseUnderline = true;
 			this.vbox16.Add (this.f_ValidateServerCertificateCheckButton);
-			global::Gtk.Box.BoxChild w20 = ((global::Gtk.Box.BoxChild)(this.vbox16[this.f_ValidateServerCertificateCheckButton]));
+			global::Gtk.Box.BoxChild w20 = ((global::Gtk.Box.BoxChild)(this.vbox16 [this.f_ValidateServerCertificateCheckButton]));
 			w20.Position = 3;
 			w20.Expand = false;
 			w20.Fill = false;
@@ -276,11 +250,11 @@ namespace Smuxi.Frontend.Gnome
 			// Container child hbox3.Gtk.Box+BoxChild
 			this.label37 = new global::Gtk.Label ();
 			this.label37.Name = "label37";
-			this.label37.Xalign = 0f;
+			this.label37.Xalign = 0F;
 			this.label37.LabelProp = global::Mono.Unix.Catalog.GetString ("_On Connect Commands:");
 			this.label37.UseUnderline = true;
 			this.hbox3.Add (this.label37);
-			global::Gtk.Box.BoxChild w21 = ((global::Gtk.Box.BoxChild)(this.hbox3[this.label37]));
+			global::Gtk.Box.BoxChild w21 = ((global::Gtk.Box.BoxChild)(this.hbox3 [this.label37]));
 			w21.Position = 0;
 			w21.Expand = false;
 			w21.Fill = false;
@@ -292,10 +266,10 @@ namespace Smuxi.Frontend.Gnome
 			this.f_IgnoreOnConnectCommandsCheckButton.DrawIndicator = true;
 			this.f_IgnoreOnConnectCommandsCheckButton.UseUnderline = true;
 			this.hbox3.Add (this.f_IgnoreOnConnectCommandsCheckButton);
-			global::Gtk.Box.BoxChild w22 = ((global::Gtk.Box.BoxChild)(this.hbox3[this.f_IgnoreOnConnectCommandsCheckButton]));
+			global::Gtk.Box.BoxChild w22 = ((global::Gtk.Box.BoxChild)(this.hbox3 [this.f_IgnoreOnConnectCommandsCheckButton]));
 			w22.Position = 1;
 			this.vbox2.Add (this.hbox3);
-			global::Gtk.Box.BoxChild w23 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.hbox3]));
+			global::Gtk.Box.BoxChild w23 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.hbox3]));
 			w23.Position = 0;
 			w23.Expand = false;
 			w23.Fill = false;
@@ -313,10 +287,10 @@ namespace Smuxi.Frontend.Gnome
 			this.f_OnConnectCommandsTextView.WrapMode = ((global::Gtk.WrapMode)(2));
 			this.scrolledwindow1.Add (this.f_OnConnectCommandsTextView);
 			this.vbox2.Add (this.scrolledwindow1);
-			global::Gtk.Box.BoxChild w25 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.scrolledwindow1]));
+			global::Gtk.Box.BoxChild w25 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.scrolledwindow1]));
 			w25.Position = 1;
 			this.vbox16.Add (this.vbox2);
-			global::Gtk.Box.BoxChild w26 = ((global::Gtk.Box.BoxChild)(this.vbox16[this.vbox2]));
+			global::Gtk.Box.BoxChild w26 = ((global::Gtk.Box.BoxChild)(this.vbox16 [this.vbox2]));
 			w26.Position = 4;
 			this.Add (this.vbox16);
 			if ((this.Child != null)) {
diff --git a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs
index 60a8503..8fe3b91 100644
--- a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs
+++ b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs
@@ -5,391 +5,199 @@ namespace Smuxi.Frontend.Gnome
 	public partial class SteticPreferencesDialog
 	{
 		private global::Gtk.HBox hbox1;
-
 		private global::Gtk.ScrolledWindow MenuScrolledWindow;
-
 		private global::Gtk.TreeView MenuTreeView;
-
 		private global::Gtk.Notebook Notebook;
-
 		private global::Gtk.VBox vbox1;
-
 		private global::Gtk.Table table1;
-
 		private global::Gtk.Entry ConnectionNicknamesEntry;
-
 		private global::Gtk.Entry ConnectionRealnameEntry;
-
 		private global::Gtk.Entry ConnectionUsernameEntry;
-
 		private global::Gtk.ComboBox EncodingComboBox;
-
 		private global::Gtk.HBox hbox13;
-
 		private global::Gtk.Label label6;
-
 		private global::Gtk.Fixed fixed31;
-
 		private global::Gtk.HBox hbox14;
-
 		private global::Gtk.Label label7;
-
 		private global::Gtk.Fixed fixed32;
-
 		private global::Gtk.HBox hbox15;
-
 		private global::Gtk.Label label8;
-
 		private global::Gtk.Fixed fixed33;
-
 		private global::Gtk.Label label58;
-
 		private global::Gtk.VBox vbox2;
-
 		private global::Gtk.VBox vbox3;
-
 		private global::Gtk.HBox hbox2;
-
 		private global::Gtk.Label label37;
-
 		private global::Gtk.Fixed fixed18;
-
 		private global::Gtk.ScrolledWindow scrolledwindow1;
-
 		private global::Gtk.TextView OnConnectCommandsTextView;
-
 		private global::Gtk.VBox vbox4;
-
 		private global::Gtk.HBox hbox3;
-
 		private global::Gtk.Label label43;
-
 		private global::Gtk.Fixed fixed19;
-
 		private global::Gtk.ScrolledWindow scrolledwindow2;
-
 		private global::Gtk.TextView OnStartupCommandsTextView;
-
 		private global::Gtk.Label label44;
-
 		private global::Gtk.Notebook InterfaceNotebook;
-
 		private global::Gtk.VBox vbox10;
-
 		private global::Gtk.Table table5;
-
 		private global::Gtk.SpinButton BufferLinesSpinButton;
-
 		private global::Gtk.SpinButton EngineBufferLinesSpinButton;
-
 		private global::Gtk.HBox hbox7;
-
 		private global::Gtk.Label label33;
-
 		private global::Gtk.Fixed fixed25;
-
 		private global::Gtk.HBox hbox8;
-
 		private global::Gtk.Label label39;
-
 		private global::Gtk.Fixed fixed26;
-
 		private global::Gtk.HBox hbox9;
-
 		private global::Gtk.Label label40;
-
 		private global::Gtk.Fixed fixed27;
-
 		private global::Gtk.Entry TimestampFormatEntry;
-
 		private global::Gtk.CheckButton StripColorsCheckButton;
-
 		private global::Gtk.Alignment alignment16;
-
 		private global::Gtk.HBox hbox17;
-
 		private global::Gtk.Image image5;
-
 		private global::Gtk.Label label47;
-
 		private global::Gtk.CheckButton StripFormattingsCheckButton;
-
 		private global::Gtk.Alignment alignment15;
-
 		private global::Gtk.HBox hbox16;
-
 		private global::Gtk.Image image6;
-
 		private global::Gtk.Label label46;
-
 		private global::Gtk.CheckButton checkbutton1;
-
 		private global::Gtk.Alignment alignment26;
-
 		private global::Gtk.HBox hbox28;
-
 		private global::Gtk.Image image7;
-
 		private global::Gtk.Label label60;
-
 		private global::Gtk.Label label1;
-
 		private global::Gtk.VBox vbox5;
-
 		private global::Gtk.Frame frame1;
-
 		private global::Gtk.Alignment alignment4;
-
 		private global::Gtk.VBox vbox6;
-
 		private global::Gtk.RadioButton TabPositionRadioButtonTop;
-
 		private global::Gtk.HBox hbox10;
-
 		private global::Gtk.Image image12;
-
 		private global::Gtk.Label label5;
-
 		private global::Gtk.RadioButton TabPositionRadioButtonBottom;
-
 		private global::Gtk.HBox hbox24;
-
 		private global::Gtk.Image image9;
-
 		private global::Gtk.Label label54;
-
 		private global::Gtk.RadioButton TabPositionRadioButtonLeft;
-
 		private global::Gtk.Alignment alignment24;
-
 		private global::Gtk.HBox hbox25;
-
 		private global::Gtk.Image image10;
-
 		private global::Gtk.Label label55;
-
 		private global::Gtk.RadioButton TabPositionRadioButtonRight;
-
 		private global::Gtk.Alignment alignment25;
-
 		private global::Gtk.HBox hbox26;
-
 		private global::Gtk.Image image11;
-
 		private global::Gtk.Label label56;
-
 		private global::Gtk.RadioButton TabPositionRadioButtonNone;
-
 		private global::Gtk.Label label9;
-
 		private global::Gtk.Frame frame4;
-
 		private global::Gtk.Alignment alignment8;
-
 		private global::Gtk.Table table3;
-
 		private global::Gtk.ColorButton ActivityColorButton;
-
 		private global::Gtk.ColorButton HighlightColorButton;
-
 		private global::Gtk.Label label16;
-
 		private global::Gtk.Label label17;
-
 		private global::Gtk.Label label18;
-
 		private global::Gtk.Label label59;
-
 		private global::Gtk.ColorButton ModeColorButton;
-
 		private global::Gtk.ColorButton NoActivityColorButton;
-
 		private global::Gtk.Label label15;
-
 		private global::Gtk.Label label2;
-
 		private global::Gtk.Frame frame3;
-
 		private global::Gtk.Alignment alignment7;
-
 		private global::Gtk.VBox vbox7;
-
 		private global::Gtk.Table table4;
-
 		private global::Gtk.Entry CommandCharacterEntry;
-
 		private global::Gtk.SpinButton CommandHistorySizeSpinButton;
-
 		private global::Gtk.Entry CompletionCharacterEntry;
-
 		private global::Gtk.HBox hbox4;
-
 		private global::Gtk.Label label13;
-
 		private global::Gtk.Fixed fixed22;
-
 		private global::Gtk.HBox hbox5;
-
 		private global::Gtk.Label label14;
-
 		private global::Gtk.Fixed fixed23;
-
 		private global::Gtk.HBox hbox6;
-
 		private global::Gtk.Label label42;
-
 		private global::Gtk.Fixed fixed24;
-
 		private global::Gtk.CheckButton BashStyleCompletionCheckButton;
-
 		private global::Gtk.Label label12;
-
 		private global::Gtk.Label label3;
-
 		private global::Gtk.VBox vbox8;
-
 		private global::Gtk.Frame frame2;
-
 		private global::Gtk.Alignment alignment5;
-
 		private global::Gtk.VBox vbox9;
-
 		private global::Gtk.CheckButton NickColorsCheckButton;
-
 		private global::Gtk.Frame frame10;
-
 		private global::Gtk.Alignment alignment14;
-
 		private global::Gtk.VBox vbox11;
-
 		private global::Gtk.RadioButton TopicPositionRadioButtonTop;
-
 		private global::Gtk.Alignment alignment21;
-
 		private global::Gtk.HBox hbox22;
-
 		private global::Gtk.Image image1;
-
 		private global::Gtk.Label label52;
-
 		private global::Gtk.RadioButton TopicPositionRadioButtonBottom;
-
 		private global::Gtk.Alignment alignment20;
-
 		private global::Gtk.HBox hbox21;
-
 		private global::Gtk.Image image2;
-
 		private global::Gtk.Label label51;
-
 		private global::Gtk.RadioButton TopicPositionRadioButtonNone;
-
 		private global::Gtk.Label label41;
-
 		private global::Gtk.Frame frame9;
-
 		private global::Gtk.Alignment alignment13;
-
 		private global::Gtk.VBox vbox12;
-
 		private global::Gtk.RadioButton UserListPositionRadioButtonLeft;
-
 		private global::Gtk.Alignment alignment17;
-
 		private global::Gtk.HBox hbox18;
-
 		private global::Gtk.Image image3;
-
 		private global::Gtk.Label label48;
-
 		private global::Gtk.RadioButton UserListPositionRadioButtonRight;
-
 		private global::Gtk.Alignment alignment18;
-
 		private global::Gtk.HBox hbox19;
-
 		private global::Gtk.Image image4;
-
 		private global::Gtk.Label label49;
-
 		private global::Gtk.RadioButton UserListPositionRadioButtonNone;
-
 		private global::Gtk.Label label38;
-
 		private global::Gtk.Label label10;
-
 		private global::Gtk.Frame frame11;
-
 		private global::Gtk.Alignment alignment27;
-
 		private global::Gtk.VBox vbox13;
-
 		private global::Gtk.VBox vbox14;
-
 		private global::Gtk.Label label62;
-
 		private global::Gtk.ScrolledWindow scrolledwindow4;
-
 		private global::Gtk.TextView HighlightWordsTextView;
-
 		private global::Gtk.CheckButton BeepOnHighlightCheckButton;
-
 		private global::Gtk.Label label61;
-
 		private global::Gtk.Label label4;
-
 		private global::Gtk.Label label45;
-
 		private global::Gtk.HBox hbox27;
-
 		private global::Gtk.ScrolledWindow scrolledwindow3;
-
 		private global::Gtk.TreeView ServersTreeView;
-
 		private global::Gtk.VButtonBox vbuttonbox1;
-
 		private global::Gtk.Button ServersAddButton;
-
 		private global::Gtk.Button ServersEditButton;
-
 		private global::Gtk.Button ServersRemoveButton;
-
 		private global::Gtk.Label label57;
-
 		private global::Gtk.VBox vbox15;
-
 		private global::Gtk.Frame frame12;
-
 		private global::Gtk.Alignment alignment28;
-
 		private global::Gtk.VBox vbox16;
-
 		private global::Gtk.ScrolledWindow scrolledwindow5;
-
 		private global::Gtk.TreeView ChannelFiltersTreeView;
-
 		private global::Gtk.HButtonBox hbuttonbox1;
-
 		private global::Gtk.Button ChannelFiltersAddButton;
-
 		private global::Gtk.Button ChannelFiltersRemoveButton;
-
 		private global::Gtk.Label label64;
-
 		private global::Gtk.Frame frame13;
-
 		private global::Gtk.Alignment alignment29;
-
 		private global::Gtk.Label label65;
-
 		private global::Gtk.Label label63;
-
 		private global::Gtk.Button CancelButton;
-
 		private global::Gtk.Button ApplyButton;
-
 		private global::Gtk.Button OKButton;
-
+        
 		protected virtual void Build ()
 		{
 			global::Stetic.Gui.Initialize (this);
@@ -417,7 +225,7 @@ namespace Smuxi.Frontend.Gnome
 			this.MenuTreeView.HeadersVisible = false;
 			this.MenuScrolledWindow.Add (this.MenuTreeView);
 			this.hbox1.Add (this.MenuScrolledWindow);
-			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.MenuScrolledWindow]));
+			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.MenuScrolledWindow]));
 			w3.Position = 0;
 			w3.Expand = false;
 			// Container child hbox1.Gtk.Box+BoxChild
@@ -441,7 +249,7 @@ namespace Smuxi.Frontend.Gnome
 			this.ConnectionNicknamesEntry.IsEditable = true;
 			this.ConnectionNicknamesEntry.InvisibleChar = '●';
 			this.table1.Add (this.ConnectionNicknamesEntry);
-			global::Gtk.Table.TableChild w4 = ((global::Gtk.Table.TableChild)(this.table1[this.ConnectionNicknamesEntry]));
+			global::Gtk.Table.TableChild w4 = ((global::Gtk.Table.TableChild)(this.table1 [this.ConnectionNicknamesEntry]));
 			w4.LeftAttach = ((uint)(1));
 			w4.RightAttach = ((uint)(2));
 			w4.YOptions = ((global::Gtk.AttachOptions)(0));
@@ -451,7 +259,7 @@ namespace Smuxi.Frontend.Gnome
 			this.ConnectionRealnameEntry.IsEditable = true;
 			this.ConnectionRealnameEntry.InvisibleChar = '●';
 			this.table1.Add (this.ConnectionRealnameEntry);
-			global::Gtk.Table.TableChild w5 = ((global::Gtk.Table.TableChild)(this.table1[this.ConnectionRealnameEntry]));
+			global::Gtk.Table.TableChild w5 = ((global::Gtk.Table.TableChild)(this.table1 [this.ConnectionRealnameEntry]));
 			w5.TopAttach = ((uint)(2));
 			w5.BottomAttach = ((uint)(3));
 			w5.LeftAttach = ((uint)(1));
@@ -463,7 +271,7 @@ namespace Smuxi.Frontend.Gnome
 			this.ConnectionUsernameEntry.IsEditable = true;
 			this.ConnectionUsernameEntry.InvisibleChar = '●';
 			this.table1.Add (this.ConnectionUsernameEntry);
-			global::Gtk.Table.TableChild w6 = ((global::Gtk.Table.TableChild)(this.table1[this.ConnectionUsernameEntry]));
+			global::Gtk.Table.TableChild w6 = ((global::Gtk.Table.TableChild)(this.table1 [this.ConnectionUsernameEntry]));
 			w6.TopAttach = ((uint)(1));
 			w6.BottomAttach = ((uint)(2));
 			w6.LeftAttach = ((uint)(1));
@@ -473,7 +281,7 @@ namespace Smuxi.Frontend.Gnome
 			this.EncodingComboBox = new global::Gtk.ComboBox ();
 			this.EncodingComboBox.Name = "EncodingComboBox";
 			this.table1.Add (this.EncodingComboBox);
-			global::Gtk.Table.TableChild w7 = ((global::Gtk.Table.TableChild)(this.table1[this.EncodingComboBox]));
+			global::Gtk.Table.TableChild w7 = ((global::Gtk.Table.TableChild)(this.table1 [this.EncodingComboBox]));
 			w7.TopAttach = ((uint)(3));
 			w7.BottomAttach = ((uint)(4));
 			w7.LeftAttach = ((uint)(1));
@@ -486,7 +294,7 @@ namespace Smuxi.Frontend.Gnome
 			this.label6.Name = "label6";
 			this.label6.LabelProp = global::Mono.Unix.Catalog.GetString ("Nicknames:");
 			this.hbox13.Add (this.label6);
-			global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.hbox13[this.label6]));
+			global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.hbox13 [this.label6]));
 			w8.Position = 0;
 			w8.Expand = false;
 			w8.Fill = false;
@@ -495,7 +303,7 @@ namespace Smuxi.Frontend.Gnome
 			this.fixed31.Name = "fixed31";
 			this.fixed31.HasWindow = false;
 			this.hbox13.Add (this.fixed31);
-			global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(this.hbox13[this.fixed31]));
+			global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(this.hbox13 [this.fixed31]));
 			w9.Position = 1;
 			this.table1.Add (this.hbox13);
 			// Container child table1.Gtk.Table+TableChild
@@ -506,7 +314,7 @@ namespace Smuxi.Frontend.Gnome
 			this.label7.Name = "label7";
 			this.label7.LabelProp = global::Mono.Unix.Catalog.GetString ("Username:");
 			this.hbox14.Add (this.label7);
-			global::Gtk.Box.BoxChild w11 = ((global::Gtk.Box.BoxChild)(this.hbox14[this.label7]));
+			global::Gtk.Box.BoxChild w11 = ((global::Gtk.Box.BoxChild)(this.hbox14 [this.label7]));
 			w11.Position = 0;
 			w11.Expand = false;
 			w11.Fill = false;
@@ -515,10 +323,10 @@ namespace Smuxi.Frontend.Gnome
 			this.fixed32.Name = "fixed32";
 			this.fixed32.HasWindow = false;
 			this.hbox14.Add (this.fixed32);
-			global::Gtk.Box.BoxChild w12 = ((global::Gtk.Box.BoxChild)(this.hbox14[this.fixed32]));
+			global::Gtk.Box.BoxChild w12 = ((global::Gtk.Box.BoxChild)(this.hbox14 [this.fixed32]));
 			w12.Position = 1;
 			this.table1.Add (this.hbox14);
-			global::Gtk.Table.TableChild w13 = ((global::Gtk.Table.TableChild)(this.table1[this.hbox14]));
+			global::Gtk.Table.TableChild w13 = ((global::Gtk.Table.TableChild)(this.table1 [this.hbox14]));
 			w13.TopAttach = ((uint)(1));
 			w13.BottomAttach = ((uint)(2));
 			// Container child table1.Gtk.Table+TableChild
@@ -529,7 +337,7 @@ namespace Smuxi.Frontend.Gnome
 			this.label8.Name = "label8";
 			this.label8.LabelProp = global::Mono.Unix.Catalog.GetString ("Realname:");
 			this.hbox15.Add (this.label8);
-			global::Gtk.Box.BoxChild w14 = ((global::Gtk.Box.BoxChild)(this.hbox15[this.label8]));
+			global::Gtk.Box.BoxChild w14 = ((global::Gtk.Box.BoxChild)(this.hbox15 [this.label8]));
 			w14.Position = 0;
 			w14.Expand = false;
 			w14.Fill = false;
@@ -538,24 +346,24 @@ namespace Smuxi.Frontend.Gnome
 			this.fixed33.Name = "fixed33";
 			this.fixed33.HasWindow = false;
 			this.hbox15.Add (this.fixed33);
-			global::Gtk.Box.BoxChild w15 = ((global::Gtk.Box.BoxChild)(this.hbox15[this.fixed33]));
+			global::Gtk.Box.BoxChild w15 = ((global::Gtk.Box.BoxChild)(this.hbox15 [this.fixed33]));
 			w15.Position = 1;
 			this.table1.Add (this.hbox15);
-			global::Gtk.Table.TableChild w16 = ((global::Gtk.Table.TableChild)(this.table1[this.hbox15]));
+			global::Gtk.Table.TableChild w16 = ((global::Gtk.Table.TableChild)(this.table1 [this.hbox15]));
 			w16.TopAttach = ((uint)(2));
 			w16.BottomAttach = ((uint)(3));
 			// Container child table1.Gtk.Table+TableChild
 			this.label58 = new global::Gtk.Label ();
 			this.label58.Name = "label58";
-			this.label58.Xalign = 0f;
+			this.label58.Xalign = 0F;
 			this.label58.LabelProp = global::Mono.Unix.Catalog.GetString ("Encoding:");
 			this.table1.Add (this.label58);
-			global::Gtk.Table.TableChild w17 = ((global::Gtk.Table.TableChild)(this.table1[this.label58]));
+			global::Gtk.Table.TableChild w17 = ((global::Gtk.Table.TableChild)(this.table1 [this.label58]));
 			w17.TopAttach = ((uint)(3));
 			w17.BottomAttach = ((uint)(4));
 			w17.YOptions = ((global::Gtk.AttachOptions)(0));
 			this.vbox1.Add (this.table1);
-			global::Gtk.Box.BoxChild w18 = ((global::Gtk.Box.BoxChild)(this.vbox1[this.table1]));
+			global::Gtk.Box.BoxChild w18 = ((global::Gtk.Box.BoxChild)(this.vbox1 [this.table1]));
 			w18.Position = 0;
 			w18.Expand = false;
 			// Container child vbox1.Gtk.Box+BoxChild
@@ -572,7 +380,7 @@ namespace Smuxi.Frontend.Gnome
 			this.label37.Name = "label37";
 			this.label37.LabelProp = global::Mono.Unix.Catalog.GetString ("On Connect Commands:");
 			this.hbox2.Add (this.label37);
-			global::Gtk.Box.BoxChild w19 = ((global::Gtk.Box.BoxChild)(this.hbox2[this.label37]));
+			global::Gtk.Box.BoxChild w19 = ((global::Gtk.Box.BoxChild)(this.hbox2 [this.label37]));
 			w19.Position = 0;
 			w19.Expand = false;
 			w19.Fill = false;
@@ -581,10 +389,10 @@ namespace Smuxi.Frontend.Gnome
 			this.fixed18.Name = "fixed18";
 			this.fixed18.HasWindow = false;
 			this.hbox2.Add (this.fixed18);
-			global::Gtk.Box.BoxChild w20 = ((global::Gtk.Box.BoxChild)(this.hbox2[this.fixed18]));
+			global::Gtk.Box.BoxChild w20 = ((global::Gtk.Box.BoxChild)(this.hbox2 [this.fixed18]));
 			w20.Position = 1;
 			this.vbox3.Add (this.hbox2);
-			global::Gtk.Box.BoxChild w21 = ((global::Gtk.Box.BoxChild)(this.vbox3[this.hbox2]));
+			global::Gtk.Box.BoxChild w21 = ((global::Gtk.Box.BoxChild)(this.vbox3 [this.hbox2]));
 			w21.Position = 0;
 			w21.Expand = false;
 			w21.Fill = false;
@@ -602,10 +410,10 @@ namespace Smuxi.Frontend.Gnome
 			this.OnConnectCommandsTextView.WrapMode = ((global::Gtk.WrapMode)(2));
 			this.scrolledwindow1.Add (this.OnConnectCommandsTextView);
 			this.vbox3.Add (this.scrolledwindow1);
-			global::Gtk.Box.BoxChild w23 = ((global::Gtk.Box.BoxChild)(this.vbox3[this.scrolledwindow1]));
+			global::Gtk.Box.BoxChild w23 = ((global::Gtk.Box.BoxChild)(this.vbox3 [this.scrolledwindow1]));
 			w23.Position = 1;
 			this.vbox2.Add (this.vbox3);
-			global::Gtk.Box.BoxChild w24 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.vbox3]));
+			global::Gtk.Box.BoxChild w24 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.vbox3]));
 			w24.Position = 0;
 			// Container child vbox2.Gtk.Box+BoxChild
 			this.vbox4 = new global::Gtk.VBox ();
@@ -618,7 +426,7 @@ namespace Smuxi.Frontend.Gnome
 			this.label43.Name = "label43";
 			this.label43.LabelProp = global::Mono.Unix.Catalog.GetString ("On Startup Commands:");
 			this.hbox3.Add (this.label43);
-			global::Gtk.Box.BoxChild w25 = ((global::Gtk.Box.BoxChild)(this.hbox3[this.label43]));
+			global::Gtk.Box.BoxChild w25 = ((global::Gtk.Box.BoxChild)(this.hbox3 [this.label43]));
 			w25.Position = 0;
 			w25.Expand = false;
 			w25.Fill = false;
@@ -627,10 +435,10 @@ namespace Smuxi.Frontend.Gnome
 			this.fixed19.Name = "fixed19";
 			this.fixed19.HasWindow = false;
 			this.hbox3.Add (this.fixed19);
-			global::Gtk.Box.BoxChild w26 = ((global::Gtk.Box.BoxChild)(this.hbox3[this.fixed19]));
+			global::Gtk.Box.BoxChild w26 = ((global::Gtk.Box.BoxChild)(this.hbox3 [this.fixed19]));
 			w26.Position = 1;
 			this.vbox4.Add (this.hbox3);
-			global::Gtk.Box.BoxChild w27 = ((global::Gtk.Box.BoxChild)(this.vbox4[this.hbox3]));
+			global::Gtk.Box.BoxChild w27 = ((global::Gtk.Box.BoxChild)(this.vbox4 [this.hbox3]));
 			w27.Position = 0;
 			w27.Expand = false;
 			w27.Fill = false;
@@ -648,13 +456,13 @@ namespace Smuxi.Frontend.Gnome
 			this.OnStartupCommandsTextView.WrapMode = ((global::Gtk.WrapMode)(2));
 			this.scrolledwindow2.Add (this.OnStartupCommandsTextView);
 			this.vbox4.Add (this.scrolledwindow2);
-			global::Gtk.Box.BoxChild w29 = ((global::Gtk.Box.BoxChild)(this.vbox4[this.scrolledwindow2]));
+			global::Gtk.Box.BoxChild w29 = ((global::Gtk.Box.BoxChild)(this.vbox4 [this.scrolledwindow2]));
 			w29.Position = 1;
 			this.vbox2.Add (this.vbox4);
-			global::Gtk.Box.BoxChild w30 = ((global::Gtk.Box.BoxChild)(this.vbox2[this.vbox4]));
+			global::Gtk.Box.BoxChild w30 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.vbox4]));
 			w30.Position = 1;
 			this.vbox1.Add (this.vbox2);
-			global::Gtk.Box.BoxChild w31 = ((global::Gtk.Box.BoxChild)(this.vbox1[this.vbox2]));
+			global::Gtk.Box.BoxChild w31 = ((global::Gtk.Box.BoxChild)(this.vbox1 [this.vbox2]));
 			w31.Position = 1;
 			this.Notebook.Add (this.vbox1);
 			// Notebook tab
@@ -687,7 +495,7 @@ namespace Smuxi.Frontend.Gnome
 			this.BufferLinesSpinButton.Numeric = true;
 			this.BufferLinesSpinButton.Value = 200;
 			this.table5.Add (this.BufferLinesSpinButton);
-			global::Gtk.Table.TableChild w33 = ((global::Gtk.Table.TableChild)(this.table5[this.BufferLinesSpinButton]));
+			global::Gtk.Table.TableChild w33 = ((global::Gtk.Table.TableChild)(this.table5 [this.BufferLinesSpinButton]));
 			w33.TopAttach = ((uint)(1));
 			w33.BottomAttach = ((uint)(2));
 			w33.LeftAttach = ((uint)(1));
@@ -703,7 +511,7 @@ namespace Smuxi.Frontend.Gnome
 			this.EngineBufferLinesSpinButton.Numeric = true;
 			this.EngineBufferLinesSpinButton.Value = 200;
 			this.table5.Add (this.EngineBufferLinesSpinButton);
-			global::Gtk.Table.TableChild w34 = ((global::Gtk.Table.TableChild)(this.table5[this.EngineBufferLinesSpinButton]));
+			global::Gtk.Table.TableChild w34 = ((global::Gtk.Table.TableChild)(this.table5 [this.EngineBufferLinesSpinButton]));
 			w34.TopAttach = ((uint)(2));
 			w34.BottomAttach = ((uint)(3));
 			w34.LeftAttach = ((uint)(1));
@@ -717,7 +525,7 @@ namespace Smuxi.Frontend.Gnome
 			this.label33.Name = "label33";
 			this.label33.LabelProp = global::Mono.Unix.Catalog.GetString ("Timestamp Format:");
 			this.hbox7.Add (this.label33);
-			global::Gtk.Box.BoxChild w35 = ((global::Gtk.Box.BoxChild)(this.hbox7[this.label33]));
+			global::Gtk.Box.BoxChild w35 = ((global::Gtk.Box.BoxChild)(this.hbox7 [this.label33]));
 			w35.Position = 0;
 			w35.Expand = false;
 			w35.Fill = false;
@@ -726,7 +534,7 @@ namespace Smuxi.Frontend.Gnome
 			this.fixed25.Name = "fixed25";
 			this.fixed25.HasWindow = false;
 			this.hbox7.Add (this.fixed25);
-			global::Gtk.Box.BoxChild w36 = ((global::Gtk.Box.BoxChild)(this.hbox7[this.fixed25]));
+			global::Gtk.Box.BoxChild w36 = ((global::Gtk.Box.BoxChild)(this.hbox7 [this.fixed25]));
 			w36.Position = 1;
 			this.table5.Add (this.hbox7);
 			// Container child table5.Gtk.Table+TableChild
@@ -737,7 +545,7 @@ namespace Smuxi.Frontend.Gnome
 			this.label39.Name = "label39";
 			this.label39.LabelProp = global::Mono.Unix.Catalog.GetString ("Buffer Lines:");
 			this.hbox8.Add (this.label39);
-			global::Gtk.Box.BoxChild w38 = ((global::Gtk.Box.BoxChild)(this.hbox8[this.label39]));
+			global::Gtk.Box.BoxChild w38 = ((global::Gtk.Box.BoxChild)(this.hbox8 [this.label39]));
 			w38.Position = 0;
 			w38.Expand = false;
 			w38.Fill = false;
@@ -746,10 +554,10 @@ namespace Smuxi.Frontend.Gnome
 			this.fixed26.Name = "fixed26";
 			this.fixed26.HasWindow = false;
 			this.hbox8.Add (this.fixed26);
-			global::Gtk.Box.BoxChild w39 = ((global::Gtk.Box.BoxChild)(this.hbox8[this.fixed26]));
+			global::Gtk.Box.BoxChild w39 = ((global::Gtk.Box.BoxChild)(this.hbox8 [this.fixed26]));
 			w39.Position = 1;
 			this.table5.Add (this.hbox8);
-			global::Gtk.Table.TableChild w40 = ((global::Gtk.Table.TableChild)(this.table5[this.hbox8]));
+			global::Gtk.Table.TableChild w40 = ((global::Gtk.Table.TableChild)(this.table5 [this.hbox8]));
 			w40.TopAttach = ((uint)(1));
 			w40.BottomAttach = ((uint)(2));
 			// Container child table5.Gtk.Table+TableChild
@@ -760,7 +568,7 @@ namespace Smuxi.Frontend.Gnome
 			this.label40.Name = "label40";
 			this.label40.LabelProp = global::Mono.Unix.Catalog.GetString ("Engine Buffer Lines:");
 			this.hbox9.Add (this.label40);
-			global::Gtk.Box.BoxChild w41 = ((global::Gtk.Box.BoxChild)(this.hbox9[this.label40]));
+			global::Gtk.Box.BoxChild w41 = ((global::Gtk.Box.BoxChild)(this.hbox9 [this.label40]));
 			w41.Position = 0;
 			w41.Expand = false;
 			w41.Fill = false;
@@ -769,10 +577,10 @@ namespace Smuxi.Frontend.Gnome
 			this.fixed27.Name = "fixed27";
 			this.fixed27.HasWindow = false;
 			this.hbox9.Add (this.fixed27);
-			global::Gtk.Box.BoxChild w42 = ((global::Gtk.Box.BoxChild)(this.hbox9[this.fixed27]));
+			global::Gtk.Box.BoxChild w42 = ((global::Gtk.Box.BoxChild)(this.hbox9 [this.fixed27]));
 			w42.Position = 1;
 			this.table5.Add (this.hbox9);
-			global::Gtk.Table.TableChild w43 = ((global::Gtk.Table.TableChild)(this.table5[this.hbox9]));
+			global::Gtk.Table.TableChild w43 = ((global::Gtk.Table.TableChild)(this.table5 [this.hbox9]));
 			w43.TopAttach = ((uint)(2));
 			w43.BottomAttach = ((uint)(3));
 			// Container child table5.Gtk.Table+TableChild
@@ -783,12 +591,12 @@ namespace Smuxi.Frontend.Gnome
 			this.TimestampFormatEntry.IsEditable = true;
 			this.TimestampFormatEntry.InvisibleChar = '●';
 			this.table5.Add (this.TimestampFormatEntry);
-			global::Gtk.Table.TableChild w44 = ((global::Gtk.Table.TableChild)(this.table5[this.TimestampFormatEntry]));
+			global::Gtk.Table.TableChild w44 = ((global::Gtk.Table.TableChild)(this.table5 [this.TimestampFormatEntry]));
 			w44.LeftAttach = ((uint)(1));
 			w44.RightAttach = ((uint)(2));
 			w44.YOptions = ((global::Gtk.AttachOptions)(0));
 			this.vbox10.Add (this.table5);
-			global::Gtk.Box.BoxChild w45 = ((global::Gtk.Box.BoxChild)(this.vbox10[this.table5]));
+			global::Gtk.Box.BoxChild w45 = ((global::Gtk.Box.BoxChild)(this.vbox10 [this.table5]));
 			w45.Position = 0;
 			w45.Expand = false;
 			w45.Fill = false;
@@ -799,7 +607,7 @@ namespace Smuxi.Frontend.Gnome
 			this.StripColorsCheckButton.UseUnderline = true;
 			this.StripColorsCheckButton.Remove (this.StripColorsCheckButton.Child);
 			// Container child StripColorsCheckButton.Gtk.Container+ContainerChild
-			this.alignment16 = new global::Gtk.Alignment (0.5f, 0.5f, 0f, 0f);
+			this.alignment16 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
 			this.alignment16.Name = "alignment16";
 			// Container child alignment16.Gtk.Container+ContainerChild
 			this.hbox17 = new global::Gtk.HBox ();
@@ -810,7 +618,7 @@ namespace Smuxi.Frontend.Gnome
 			this.image5.Name = "image5";
 			this.image5.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-cut", global::Gtk.IconSize.Menu);
 			this.hbox17.Add (this.image5);
-			global::Gtk.Box.BoxChild w46 = ((global::Gtk.Box.BoxChild)(this.hbox17[this.image5]));
+			global::Gtk.Box.BoxChild w46 = ((global::Gtk.Box.BoxChild)(this.hbox17 [this.image5]));
 			w46.Position = 0;
 			w46.Expand = false;
 			w46.Fill = false;
@@ -820,14 +628,14 @@ namespace Smuxi.Frontend.Gnome
 			this.label47.LabelProp = global::Mono.Unix.Catalog.GetString ("Strip Colors");
 			this.label47.UseUnderline = true;
 			this.hbox17.Add (this.label47);
-			global::Gtk.Box.BoxChild w47 = ((global::Gtk.Box.BoxChild)(this.hbox17[this.label47]));
+			global::Gtk.Box.BoxChild w47 = ((global::Gtk.Box.BoxChild)(this.hbox17 [this.label47]));
 			w47.Position = 1;
 			w47.Expand = false;
 			w47.Fill = false;
 			this.alignment16.Add (this.hbox17);
 			this.StripColorsCheckButton.Add (this.alignment16);
 			this.vbox10.Add (this.StripColorsCheckButton);
-			global::Gtk.Box.BoxChild w50 = ((global::Gtk.Box.BoxChild)(this.vbox10[this.StripColorsCheckButton]));
+			global::Gtk.Box.BoxChild w50 = ((global::Gtk.Box.BoxChild)(this.vbox10 [this.StripColorsCheckButton]));
 			w50.Position = 1;
 			w50.Expand = false;
 			w50.Fill = false;
@@ -838,7 +646,7 @@ namespace Smuxi.Frontend.Gnome
 			this.StripFormattingsCheckButton.UseUnderline = true;
 			this.StripFormattingsCheckButton.Remove (this.StripFormattingsCheckButton.Child);
 			// Container child StripFormattingsCheckButton.Gtk.Container+ContainerChild
-			this.alignment15 = new global::Gtk.Alignment (0.5f, 0.5f, 0f, 0f);
+			this.alignment15 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
 			this.alignment15.Name = "alignment15";
 			// Container child alignment15.Gtk.Container+ContainerChild
 			this.hbox16 = new global::Gtk.HBox ();
@@ -849,7 +657,7 @@ namespace Smuxi.Frontend.Gnome
 			this.image6.Name = "image6";
 			this.image6.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-cut", global::Gtk.IconSize.Menu);
 			this.hbox16.Add (this.image6);
-			global::Gtk.Box.BoxChild w51 = ((global::Gtk.Box.BoxChild)(this.hbox16[this.image6]));
+			global::Gtk.Box.BoxChild w51 = ((global::Gtk.Box.BoxChild)(this.hbox16 [this.image6]));
 			w51.Position = 0;
 			w51.Expand = false;
 			w51.Fill = false;
@@ -859,14 +667,14 @@ namespace Smuxi.Frontend.Gnome
 			this.label46.LabelProp = global::Mono.Unix.Catalog.GetString ("Strip Formattings");
 			this.label46.UseUnderline = true;
 			this.hbox16.Add (this.label46);
-			global::Gtk.Box.BoxChild w52 = ((global::Gtk.Box.BoxChild)(this.hbox16[this.label46]));
+			global::Gtk.Box.BoxChild w52 = ((global::Gtk.Box.BoxChild)(this.hbox16 [this.label46]));
 			w52.Position = 1;
 			w52.Expand = false;
 			w52.Fill = false;
 			this.alignment15.Add (this.hbox16);
 			this.StripFormattingsCheckButton.Add (this.alignment15);
 			this.vbox10.Add (this.StripFormattingsCheckButton);
-			global::Gtk.Box.BoxChild w55 = ((global::Gtk.Box.BoxChild)(this.vbox10[this.StripFormattingsCheckButton]));
+			global::Gtk.Box.BoxChild w55 = ((global::Gtk.Box.BoxChild)(this.vbox10 [this.StripFormattingsCheckButton]));
 			w55.Position = 2;
 			w55.Expand = false;
 			w55.Fill = false;
@@ -878,7 +686,7 @@ namespace Smuxi.Frontend.Gnome
 			this.checkbutton1.UseUnderline = true;
 			this.checkbutton1.Remove (this.checkbutton1.Child);
 			// Container child checkbutton1.Gtk.Container+ContainerChild
-			this.alignment26 = new global::Gtk.Alignment (0.5f, 0.5f, 0f, 0f);
+			this.alignment26 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
 			this.alignment26.Name = "alignment26";
 			// Container child alignment26.Gtk.Container+ContainerChild
 			this.hbox28 = new global::Gtk.HBox ();
@@ -889,7 +697,7 @@ namespace Smuxi.Frontend.Gnome
 			this.image7.Name = "image7";
 			this.image7.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-cut", global::Gtk.IconSize.Menu);
 			this.hbox28.Add (this.image7);
-			global::Gtk.Box.BoxChild w56 = ((global::Gtk.Box.BoxChild)(this.hbox28[this.image7]));
+			global::Gtk.Box.BoxChild w56 = ((global::Gtk.Box.BoxChild)(this.hbox28 [this.image7]));
 			w56.Position = 0;
 			w56.Expand = false;
 			w56.Fill = false;
@@ -899,14 +707,14 @@ namespace Smuxi.Frontend.Gnome
 			this.label60.LabelProp = global::Mono.Unix.Catalog.GetString ("Strip UTF-8");
 			this.label60.UseUnderline = true;
 			this.hbox28.Add (this.label60);
-			global::Gtk.Box.BoxChild w57 = ((global::Gtk.Box.BoxChild)(this.hbox28[this.label60]));
+			global::Gtk.Box.BoxChild w57 = ((global::Gtk.Box.BoxChild)(this.hbox28 [this.label60]));
 			w57.Position = 1;
 			w57.Expand = false;
 			w57.Fill = false;
 			this.alignment26.Add (this.hbox28);
 			this.checkbutton1.Add (this.alignment26);
 			this.vbox10.Add (this.checkbutton1);
-			global::Gtk.Box.BoxChild w60 = ((global::Gtk.Box.BoxChild)(this.vbox10[this.checkbutton1]));
+			global::Gtk.Box.BoxChild w60 = ((global::Gtk.Box.BoxChild)(this.vbox10 [this.checkbutton1]));
 			w60.Position = 3;
 			w60.Expand = false;
 			w60.Fill = false;
@@ -925,7 +733,7 @@ namespace Smuxi.Frontend.Gnome
 			this.frame1 = new global::Gtk.Frame ();
 			this.frame1.Name = "frame1";
 			// Container child frame1.Gtk.Container+ContainerChild
-			this.alignment4 = new global::Gtk.Alignment (0.5f, 0.5f, 1f, 1f);
+			this.alignment4 = new global::Gtk.Alignment (0.5F, 0.5F, 1F, 1F);
 			this.alignment4.Name = "alignment4";
 			this.alignment4.LeftPadding = ((uint)(12));
 			// Container child alignment4.Gtk.Container+ContainerChild
@@ -949,7 +757,7 @@ namespace Smuxi.Frontend.Gnome
 			this.image12.Name = "image12";
 			this.image12.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-goto-top", global::Gtk.IconSize.Menu);
 			this.hbox10.Add (this.image12);
-			global::Gtk.Box.BoxChild w62 = ((global::Gtk.Box.BoxChild)(this.hbox10[this.image12]));
+			global::Gtk.Box.BoxChild w62 = ((global::Gtk.Box.BoxChild)(this.hbox10 [this.image12]));
 			w62.Position = 0;
 			w62.Expand = false;
 			w62.Fill = false;
@@ -958,13 +766,13 @@ namespace Smuxi.Frontend.Gnome
 			this.label5.Name = "label5";
 			this.label5.LabelProp = global::Mono.Unix.Catalog.GetString ("Top");
 			this.hbox10.Add (this.label5);
-			global::Gtk.Box.BoxChild w63 = ((global::Gtk.Box.BoxChild)(this.hbox10[this.label5]));
+			global::Gtk.Box.BoxChild w63 = ((global::Gtk.Box.BoxChild)(this.hbox10 [this.label5]));
 			w63.Position = 1;
 			w63.Expand = false;
 			w63.Fill = false;
 			this.TabPositionRadioButtonTop.Add (this.hbox10);
 			this.vbox6.Add (this.TabPositionRadioButtonTop);
-			global::Gtk.Box.BoxChild w65 = ((global::Gtk.Box.BoxChild)(this.vbox6[this.TabPositionRadioButtonTop]));
+			global::Gtk.Box.BoxChild w65 = ((global::Gtk.Box.BoxChild)(this.vbox6 [this.TabPositionRadioButtonTop]));
 			w65.Position = 0;
 			w65.Expand = false;
 			w65.Fill = false;
@@ -984,7 +792,7 @@ namespace Smuxi.Frontend.Gnome
 			this.image9.Name = "image9";
 			this.image9.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-goto-bottom", global::Gtk.IconSize.Menu);
 			this.hbox24.Add (this.image9);
-			global::Gtk.Box.BoxChild w66 = ((global::Gtk.Box.BoxChild)(this.hbox24[this.image9]));
+			global::Gtk.Box.BoxChild w66 = ((global::Gtk.Box.BoxChild)(this.hbox24 [this.image9]));
 			w66.Position = 0;
 			w66.Expand = false;
 			w66.Fill = false;
@@ -994,13 +802,13 @@ namespace Smuxi.Frontend.Gnome
 			this.label54.LabelProp = global::Mono.Unix.Catalog.GetString ("Bottom");
 			this.label54.UseUnderline = true;
 			this.hbox24.Add (this.label54);
-			global::Gtk.Box.BoxChild w67 = ((global::Gtk.Box.BoxChild)(this.hbox24[this.label54]));
+			global::Gtk.Box.BoxChild w67 = ((global::Gtk.Box.BoxChild)(this.hbox24 [this.label54]));
 			w67.Position = 1;
 			w67.Expand = false;
 			w67.Fill = false;
 			this.TabPositionRadioButtonBottom.Add (this.hbox24);
 			this.vbox6.Add (this.TabPositionRadioButtonBottom);
-			global::Gtk.Box.BoxChild w69 = ((global::Gtk.Box.BoxChild)(this.vbox6[this.TabPositionRadioButtonBottom]));
+			global::Gtk.Box.BoxChild w69 = ((global::Gtk.Box.BoxChild)(this.vbox6 [this.TabPositionRadioButtonBottom]));
 			w69.Position = 1;
 			w69.Expand = false;
 			w69.Fill = false;
@@ -1012,7 +820,7 @@ namespace Smuxi.Frontend.Gnome
 			this.TabPositionRadioButtonLeft.Group = this.TabPositionRadioButtonTop.Group;
 			this.TabPositionRadioButtonLeft.Remove (this.TabPositionRadioButtonLeft.Child);
 			// Container child TabPositionRadioButtonLeft.Gtk.Container+ContainerChild
-			this.alignment24 = new global::Gtk.Alignment (0.5f, 0.5f, 0f, 0f);
+			this.alignment24 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
 			this.alignment24.Name = "alignment24";
 			// Container child alignment24.Gtk.Container+ContainerChild
 			this.hbox25 = new global::Gtk.HBox ();
@@ -1023,7 +831,7 @@ namespace Smuxi.Frontend.Gnome
 			this.image10.Name = "image10";
 			this.image10.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-goto-first", global::Gtk.IconSize.Menu);
 			this.hbox25.Add (this.image10);
-			global::Gtk.Box.BoxChild w70 = ((global::Gtk.Box.BoxChild)(this.hbox25[this.image10]));
+			global::Gtk.Box.BoxChild w70 = ((global::Gtk.Box.BoxChild)(this.hbox25 [this.image10]));
 			w70.Position = 0;
 			w70.Expand = false;
 			w70.Fill = false;
@@ -1033,14 +841,14 @@ namespace Smuxi.Frontend.Gnome
 			this.label55.LabelProp = global::Mono.Unix.Catalog.GetString ("Left");
 			this.label55.UseUnderline = true;
 			this.hbox25.Add (this.label55);
-			global::Gtk.Box.BoxChild w71 = ((global::Gtk.Box.BoxChild)(this.hbox25[this.label55]));
+			global::Gtk.Box.BoxChild w71 = ((global::Gtk.Box.BoxChild)(this.hbox25 [this.label55]));
 			w71.Position = 1;
 			w71.Expand = false;
 			w71.Fill = false;
 			this.alignment24.Add (this.hbox25);
 			this.TabPositionRadioButtonLeft.Add (this.alignment24);
 			this.vbox6.Add (this.TabPositionRadioButtonLeft);
-			global::Gtk.Box.BoxChild w74 = ((global::Gtk.Box.BoxChild)(this.vbox6[this.TabPositionRadioButtonLeft]));
+			global::Gtk.Box.BoxChild w74 = ((global::Gtk.Box.BoxChild)(this.vbox6 [this.TabPositionRadioButtonLeft]));
 			w74.Position = 2;
 			w74.Expand = false;
 			w74.Fill = false;
@@ -1052,7 +860,7 @@ namespace Smuxi.Frontend.Gnome
 			this.TabPositionRadioButtonRight.Group = this.TabPositionRadioButtonTop.Group;
 			this.TabPositionRadioButtonRight.Remove (this.TabPositionRadioButtonRight.Child);
 			// Container child TabPositionRadioButtonRight.Gtk.Container+ContainerChild
-			this.alignment25 = new global::Gtk.Alignment (0.5f, 0.5f, 0f, 0f);
+			this.alignment25 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
 			this.alignment25.Name = "alignment25";
 			// Container child alignment25.Gtk.Container+ContainerChild
 			this.hbox26 = new global::Gtk.HBox ();
@@ -1063,7 +871,7 @@ namespace Smuxi.Frontend.Gnome
 			this.image11.Name = "image11";
 			this.image11.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-goto-last", global::Gtk.IconSize.Menu);
 			this.hbox26.Add (this.image11);
-			global::Gtk.Box.BoxChild w75 = ((global::Gtk.Box.BoxChild)(this.hbox26[this.image11]));
+			global::Gtk.Box.BoxChild w75 = ((global::Gtk.Box.BoxChild)(this.hbox26 [this.image11]));
 			w75.Position = 0;
 			w75.Expand = false;
 			w75.Fill = false;
@@ -1073,14 +881,14 @@ namespace Smuxi.Frontend.Gnome
 			this.label56.LabelProp = global::Mono.Unix.Catalog.GetString ("Right");
 			this.label56.UseUnderline = true;
 			this.hbox26.Add (this.label56);
-			global::Gtk.Box.BoxChild w76 = ((global::Gtk.Box.BoxChild)(this.hbox26[this.label56]));
+			global::Gtk.Box.BoxChild w76 = ((global::Gtk.Box.BoxChild)(this.hbox26 [this.label56]));
 			w76.Position = 1;
 			w76.Expand = false;
 			w76.Fill = false;
 			this.alignment25.Add (this.hbox26);
 			this.TabPositionRadioButtonRight.Add (this.alignment25);
 			this.vbox6.Add (this.TabPositionRadioButtonRight);
-			global::Gtk.Box.BoxChild w79 = ((global::Gtk.Box.BoxChild)(this.vbox6[this.TabPositionRadioButtonRight]));
+			global::Gtk.Box.BoxChild w79 = ((global::Gtk.Box.BoxChild)(this.vbox6 [this.TabPositionRadioButtonRight]));
 			w79.Position = 3;
 			w79.Expand = false;
 			w79.Fill = false;
@@ -1091,7 +899,7 @@ namespace Smuxi.Frontend.Gnome
 			this.TabPositionRadioButtonNone.UseUnderline = true;
 			this.TabPositionRadioButtonNone.Group = this.TabPositionRadioButtonTop.Group;
 			this.vbox6.Add (this.TabPositionRadioButtonNone);
-			global::Gtk.Box.BoxChild w80 = ((global::Gtk.Box.BoxChild)(this.vbox6[this.TabPositionRadioButtonNone]));
+			global::Gtk.Box.BoxChild w80 = ((global::Gtk.Box.BoxChild)(this.vbox6 [this.TabPositionRadioButtonNone]));
 			w80.Position = 4;
 			w80.Expand = false;
 			w80.Fill = false;
@@ -1103,14 +911,14 @@ namespace Smuxi.Frontend.Gnome
 			this.label9.UseMarkup = true;
 			this.frame1.LabelWidget = this.label9;
 			this.vbox5.Add (this.frame1);
-			global::Gtk.Box.BoxChild w83 = ((global::Gtk.Box.BoxChild)(this.vbox5[this.frame1]));
+			global::Gtk.Box.BoxChild w83 = ((global::Gtk.Box.BoxChild)(this.vbox5 [this.frame1]));
 			w83.Position = 0;
 			w83.Expand = false;
 			// Container child vbox5.Gtk.Box+BoxChild
 			this.frame4 = new global::Gtk.Frame ();
 			this.frame4.Name = "frame4";
 			// Container child frame4.Gtk.Container+ContainerChild
-			this.alignment8 = new global::Gtk.Alignment (0.5f, 0.5f, 1f, 1f);
+			this.alignment8 = new global::Gtk.Alignment (0.5F, 0.5F, 1F, 1F);
 			this.alignment8.Name = "alignment8";
 			this.alignment8.LeftPadding = ((uint)(12));
 			// Container child alignment8.Gtk.Container+ContainerChild
@@ -1122,7 +930,7 @@ namespace Smuxi.Frontend.Gnome
 			this.ActivityColorButton = new global::Gtk.ColorButton ();
 			this.ActivityColorButton.Name = "ActivityColorButton";
 			this.table3.Add (this.ActivityColorButton);
-			global::Gtk.Table.TableChild w84 = ((global::Gtk.Table.TableChild)(this.table3[this.ActivityColorButton]));
+			global::Gtk.Table.TableChild w84 = ((global::Gtk.Table.TableChild)(this.table3 [this.ActivityColorButton]));
 			w84.TopAttach = ((uint)(1));
 			w84.BottomAttach = ((uint)(2));
 			w84.LeftAttach = ((uint)(1));
@@ -1132,7 +940,7 @@ namespace Smuxi.Frontend.Gnome
 			this.HighlightColorButton = new global::Gtk.ColorButton ();
 			this.HighlightColorButton.Name = "HighlightColorButton";
 			this.table3.Add (this.HighlightColorButton);
-			global::Gtk.Table.TableChild w85 = ((global::Gtk.Table.TableChild)(this.table3[this.HighlightColorButton]));
+			global::Gtk.Table.TableChild w85 = ((global::Gtk.Table.TableChild)(this.table3 [this.HighlightColorButton]));
 			w85.TopAttach = ((uint)(3));
 			w85.BottomAttach = ((uint)(4));
 			w85.LeftAttach = ((uint)(1));
@@ -1141,38 +949,38 @@ namespace Smuxi.Frontend.Gnome
 			// Container child table3.Gtk.Table+TableChild
 			this.label16 = new global::Gtk.Label ();
 			this.label16.Name = "label16";
-			this.label16.Xalign = 0f;
+			this.label16.Xalign = 0F;
 			this.label16.LabelProp = global::Mono.Unix.Catalog.GetString ("No Activity");
 			this.table3.Add (this.label16);
-			global::Gtk.Table.TableChild w86 = ((global::Gtk.Table.TableChild)(this.table3[this.label16]));
+			global::Gtk.Table.TableChild w86 = ((global::Gtk.Table.TableChild)(this.table3 [this.label16]));
 			w86.YOptions = ((global::Gtk.AttachOptions)(0));
 			// Container child table3.Gtk.Table+TableChild
 			this.label17 = new global::Gtk.Label ();
 			this.label17.Name = "label17";
-			this.label17.Xalign = 0f;
+			this.label17.Xalign = 0F;
 			this.label17.LabelProp = global::Mono.Unix.Catalog.GetString ("Activity");
 			this.table3.Add (this.label17);
-			global::Gtk.Table.TableChild w87 = ((global::Gtk.Table.TableChild)(this.table3[this.label17]));
+			global::Gtk.Table.TableChild w87 = ((global::Gtk.Table.TableChild)(this.table3 [this.label17]));
 			w87.TopAttach = ((uint)(1));
 			w87.BottomAttach = ((uint)(2));
 			w87.YOptions = ((global::Gtk.AttachOptions)(0));
 			// Container child table3.Gtk.Table+TableChild
 			this.label18 = new global::Gtk.Label ();
 			this.label18.Name = "label18";
-			this.label18.Xalign = 0f;
+			this.label18.Xalign = 0F;
 			this.label18.LabelProp = global::Mono.Unix.Catalog.GetString ("Join/Part/Mode");
 			this.table3.Add (this.label18);
-			global::Gtk.Table.TableChild w88 = ((global::Gtk.Table.TableChild)(this.table3[this.label18]));
+			global::Gtk.Table.TableChild w88 = ((global::Gtk.Table.TableChild)(this.table3 [this.label18]));
 			w88.TopAttach = ((uint)(2));
 			w88.BottomAttach = ((uint)(3));
 			w88.YOptions = ((global::Gtk.AttachOptions)(0));
 			// Container child table3.Gtk.Table+TableChild
 			this.label59 = new global::Gtk.Label ();
 			this.label59.Name = "label59";
-			this.label59.Xalign = 0f;
+			this.label59.Xalign = 0F;
 			this.label59.LabelProp = global::Mono.Unix.Catalog.GetString ("Highlight");
 			this.table3.Add (this.label59);
-			global::Gtk.Table.TableChild w89 = ((global::Gtk.Table.TableChild)(this.table3[this.label59]));
+			global::Gtk.Table.TableChild w89 = ((global::Gtk.Table.TableChild)(this.table3 [this.label59]));
 			w89.TopAttach = ((uint)(3));
 			w89.BottomAttach = ((uint)(4));
 			w89.YOptions = ((global::Gtk.AttachOptions)(0));
@@ -1180,7 +988,7 @@ namespace Smuxi.Frontend.Gnome
 			this.ModeColorButton = new global::Gtk.ColorButton ();
 			this.ModeColorButton.Name = "ModeColorButton";
 			this.table3.Add (this.ModeColorButton);
-			global::Gtk.Table.TableChild w90 = ((global::Gtk.Table.TableChild)(this.table3[this.ModeColorButton]));
+			global::Gtk.Table.TableChild w90 = ((global::Gtk.Table.TableChild)(this.table3 [this.ModeColorButton]));
 			w90.TopAttach = ((uint)(2));
 			w90.BottomAttach = ((uint)(3));
 			w90.LeftAttach = ((uint)(1));
@@ -1190,7 +998,7 @@ namespace Smuxi.Frontend.Gnome
 			this.NoActivityColorButton = new global::Gtk.ColorButton ();
 			this.NoActivityColorButton.Name = "NoActivityColorButton";
 			this.table3.Add (this.NoActivityColorButton);
-			global::Gtk.Table.TableChild w91 = ((global::Gtk.Table.TableChild)(this.table3[this.NoActivityColorButton]));
+			global::Gtk.Table.TableChild w91 = ((global::Gtk.Table.TableChild)(this.table3 [this.NoActivityColorButton]));
 			w91.LeftAttach = ((uint)(1));
 			w91.RightAttach = ((uint)(2));
 			w91.YOptions = ((global::Gtk.AttachOptions)(0));
@@ -1202,11 +1010,11 @@ namespace Smuxi.Frontend.Gnome
 			this.label15.UseMarkup = true;
 			this.frame4.LabelWidget = this.label15;
 			this.vbox5.Add (this.frame4);
-			global::Gtk.Box.BoxChild w94 = ((global::Gtk.Box.BoxChild)(this.vbox5[this.frame4]));
+			global::Gtk.Box.BoxChild w94 = ((global::Gtk.Box.BoxChild)(this.vbox5 [this.frame4]));
 			w94.Position = 1;
 			w94.Expand = false;
 			this.InterfaceNotebook.Add (this.vbox5);
-			global::Gtk.Notebook.NotebookChild w95 = ((global::Gtk.Notebook.NotebookChild)(this.InterfaceNotebook[this.vbox5]));
+			global::Gtk.Notebook.NotebookChild w95 = ((global::Gtk.Notebook.NotebookChild)(this.InterfaceNotebook [this.vbox5]));
 			w95.Position = 1;
 			// Notebook tab
 			this.label2 = new global::Gtk.Label ();
@@ -1218,7 +1026,7 @@ namespace Smuxi.Frontend.Gnome
 			this.frame3 = new global::Gtk.Frame ();
 			this.frame3.Name = "frame3";
 			// Container child frame3.Gtk.Container+ContainerChild
-			this.alignment7 = new global::Gtk.Alignment (0.5f, 0.5f, 1f, 1f);
+			this.alignment7 = new global::Gtk.Alignment (0.5F, 0.5F, 1F, 1F);
 			this.alignment7.Name = "alignment7";
 			this.alignment7.LeftPadding = ((uint)(12));
 			// Container child alignment7.Gtk.Container+ContainerChild
@@ -1240,7 +1048,7 @@ namespace Smuxi.Frontend.Gnome
 			this.CommandCharacterEntry.MaxLength = 1;
 			this.CommandCharacterEntry.InvisibleChar = '●';
 			this.table4.Add (this.CommandCharacterEntry);
-			global::Gtk.Table.TableChild w96 = ((global::Gtk.Table.TableChild)(this.table4[this.CommandCharacterEntry]));
+			global::Gtk.Table.TableChild w96 = ((global::Gtk.Table.TableChild)(this.table4 [this.CommandCharacterEntry]));
 			w96.TopAttach = ((uint)(1));
 			w96.BottomAttach = ((uint)(2));
 			w96.LeftAttach = ((uint)(1));
@@ -1256,7 +1064,7 @@ namespace Smuxi.Frontend.Gnome
 			this.CommandHistorySizeSpinButton.Numeric = true;
 			this.CommandHistorySizeSpinButton.Value = 30;
 			this.table4.Add (this.CommandHistorySizeSpinButton);
-			global::Gtk.Table.TableChild w97 = ((global::Gtk.Table.TableChild)(this.table4[this.CommandHistorySizeSpinButton]));
+			global::Gtk.Table.TableChild w97 = ((global::Gtk.Table.TableChild)(this.table4 [this.CommandHistorySizeSpinButton]));
 			w97.TopAttach = ((uint)(2));
 			w97.BottomAttach = ((uint)(3));
 			w97.LeftAttach = ((uint)(1));
@@ -1271,7 +1079,7 @@ namespace Smuxi.Frontend.Gnome
 			this.CompletionCharacterEntry.MaxLength = 1;
 			this.CompletionCharacterEntry.InvisibleChar = '●';
 			this.table4.Add (this.CompletionCharacterEntry);
-			global::Gtk.Table.TableChild w98 = ((global::Gtk.Table.TableChild)(this.table4[this.CompletionCharacterEntry]));
+			global::Gtk.Table.TableChild w98 = ((global::Gtk.Table.TableChild)(this.table4 [this.CompletionCharacterEntry]));
 			w98.LeftAttach = ((uint)(1));
 			w98.RightAttach = ((uint)(2));
 			w98.YOptions = ((global::Gtk.AttachOptions)(0));
@@ -1283,7 +1091,7 @@ namespace Smuxi.Frontend.Gnome
 			this.label13.Name = "label13";
 			this.label13.LabelProp = global::Mono.Unix.Catalog.GetString ("Completion Character:");
 			this.hbox4.Add (this.label13);
-			global::Gtk.Box.BoxChild w99 = ((global::Gtk.Box.BoxChild)(this.hbox4[this.label13]));
+			global::Gtk.Box.BoxChild w99 = ((global::Gtk.Box.BoxChild)(this.hbox4 [this.label13]));
 			w99.Position = 0;
 			w99.Expand = false;
 			w99.Fill = false;
@@ -1292,7 +1100,7 @@ namespace Smuxi.Frontend.Gnome
 			this.fixed22.Name = "fixed22";
 			this.fixed22.HasWindow = false;
 			this.hbox4.Add (this.fixed22);
-			global::Gtk.Box.BoxChild w100 = ((global::Gtk.Box.BoxChild)(this.hbox4[this.fixed22]));
+			global::Gtk.Box.BoxChild w100 = ((global::Gtk.Box.BoxChild)(this.hbox4 [this.fixed22]));
 			w100.Position = 1;
 			this.table4.Add (this.hbox4);
 			// Container child table4.Gtk.Table+TableChild
@@ -1303,7 +1111,7 @@ namespace Smuxi.Frontend.Gnome
 			this.label14.Name = "label14";
 			this.label14.LabelProp = global::Mono.Unix.Catalog.GetString ("Command Character:");
 			this.hbox5.Add (this.label14);
-			global::Gtk.Box.BoxChild w102 = ((global::Gtk.Box.BoxChild)(this.hbox5[this.label14]));
+			global::Gtk.Box.BoxChild w102 = ((global::Gtk.Box.BoxChild)(this.hbox5 [this.label14]));
 			w102.Position = 0;
 			w102.Expand = false;
 			w102.Fill = false;
@@ -1312,10 +1120,10 @@ namespace Smuxi.Frontend.Gnome
 			this.fixed23.Name = "fixed23";
 			this.fixed23.HasWindow = false;
 			this.hbox5.Add (this.fixed23);
-			global::Gtk.Box.BoxChild w103 = ((global::Gtk.Box.BoxChild)(this.hbox5[this.fixed23]));
+			global::Gtk.Box.BoxChild w103 = ((global::Gtk.Box.BoxChild)(this.hbox5 [this.fixed23]));
 			w103.Position = 1;
 			this.table4.Add (this.hbox5);
-			global::Gtk.Table.TableChild w104 = ((global::Gtk.Table.TableChild)(this.table4[this.hbox5]));
+			global::Gtk.Table.TableChild w104 = ((global::Gtk.Table.TableChild)(this.table4 [this.hbox5]));
 			w104.TopAttach = ((uint)(1));
 			w104.BottomAttach = ((uint)(2));
 			// Container child table4.Gtk.Table+TableChild
@@ -1326,7 +1134,7 @@ namespace Smuxi.Frontend.Gnome
 			this.label42.Name = "label42";
 			this.label42.LabelProp = global::Mono.Unix.Catalog.GetString ("Command History Size:");
 			this.hbox6.Add (this.label42);
-			global::Gtk.Box.BoxChild w105 = ((global::Gtk.Box.BoxChild)(this.hbox6[this.label42]));
+			global::Gtk.Box.BoxChild w105 = ((global::Gtk.Box.BoxChild)(this.hbox6 [this.label42]));
 			w105.Position = 0;
 			w105.Expand = false;
 			w105.Fill = false;
@@ -1335,14 +1143,14 @@ namespace Smuxi.Frontend.Gnome
 			this.fixed24.Name = "fixed24";
 			this.fixed24.HasWindow = false;
 			this.hbox6.Add (this.fixed24);
-			global::Gtk.Box.BoxChild w106 = ((global::Gtk.Box.BoxChild)(this.hbox6[this.fixed24]));
+			global::Gtk.Box.BoxChild w106 = ((global::Gtk.Box.BoxChild)(this.hbox6 [this.fixed24]));
 			w106.Position = 1;
 			this.table4.Add (this.hbox6);
-			global::Gtk.Table.TableChild w107 = ((global::Gtk.Table.TableChild)(this.table4[this.hbox6]));
+			global::Gtk.Table.TableChild w107 = ((global::Gtk.Table.TableChild)(this.table4 [this.hbox6]));
 			w107.TopAttach = ((uint)(2));
 			w107.BottomAttach = ((uint)(3));
 			this.vbox7.Add (this.table4);
-			global::Gtk.Box.BoxChild w108 = ((global::Gtk.Box.BoxChild)(this.vbox7[this.table4]));
+			global::Gtk.Box.BoxChild w108 = ((global::Gtk.Box.BoxChild)(this.vbox7 [this.table4]));
 			w108.Position = 0;
 			w108.Expand = false;
 			w108.Fill = false;
@@ -1353,7 +1161,7 @@ namespace Smuxi.Frontend.Gnome
 			this.BashStyleCompletionCheckButton.DrawIndicator = true;
 			this.BashStyleCompletionCheckButton.UseUnderline = true;
 			this.vbox7.Add (this.BashStyleCompletionCheckButton);
-			global::Gtk.Box.BoxChild w109 = ((global::Gtk.Box.BoxChild)(this.vbox7[this.BashStyleCompletionCheckButton]));
+			global::Gtk.Box.BoxChild w109 = ((global::Gtk.Box.BoxChild)(this.vbox7 [this.BashStyleCompletionCheckButton]));
 			w109.Position = 1;
 			w109.Expand = false;
 			w109.Fill = false;
@@ -1365,7 +1173,7 @@ namespace Smuxi.Frontend.Gnome
 			this.label12.UseMarkup = true;
 			this.frame3.LabelWidget = this.label12;
 			this.InterfaceNotebook.Add (this.frame3);
-			global::Gtk.Notebook.NotebookChild w112 = ((global::Gtk.Notebook.NotebookChild)(this.InterfaceNotebook[this.frame3]));
+			global::Gtk.Notebook.NotebookChild w112 = ((global::Gtk.Notebook.NotebookChild)(this.InterfaceNotebook [this.frame3]));
 			w112.Position = 2;
 			// Notebook tab
 			this.label3 = new global::Gtk.Label ();
@@ -1380,7 +1188,7 @@ namespace Smuxi.Frontend.Gnome
 			this.frame2 = new global::Gtk.Frame ();
 			this.frame2.Name = "frame2";
 			// Container child frame2.Gtk.Container+ContainerChild
-			this.alignment5 = new global::Gtk.Alignment (0.5f, 0.5f, 1f, 1f);
+			this.alignment5 = new global::Gtk.Alignment (0.5F, 0.5F, 1F, 1F);
 			this.alignment5.Name = "alignment5";
 			this.alignment5.LeftPadding = ((uint)(12));
 			// Container child alignment5.Gtk.Container+ContainerChild
@@ -1395,14 +1203,14 @@ namespace Smuxi.Frontend.Gnome
 			this.NickColorsCheckButton.DrawIndicator = true;
 			this.NickColorsCheckButton.UseUnderline = true;
 			this.vbox9.Add (this.NickColorsCheckButton);
-			global::Gtk.Box.BoxChild w113 = ((global::Gtk.Box.BoxChild)(this.vbox9[this.NickColorsCheckButton]));
+			global::Gtk.Box.BoxChild w113 = ((global::Gtk.Box.BoxChild)(this.vbox9 [this.NickColorsCheckButton]));
 			w113.Position = 0;
 			w113.Expand = false;
 			// Container child vbox9.Gtk.Box+BoxChild
 			this.frame10 = new global::Gtk.Frame ();
 			this.frame10.Name = "frame10";
 			// Container child frame10.Gtk.Container+ContainerChild
-			this.alignment14 = new global::Gtk.Alignment (0.5f, 0.5f, 1f, 1f);
+			this.alignment14 = new global::Gtk.Alignment (0.5F, 0.5F, 1F, 1F);
 			this.alignment14.Name = "alignment14";
 			this.alignment14.LeftPadding = ((uint)(12));
 			// Container child alignment14.Gtk.Container+ContainerChild
@@ -1417,7 +1225,7 @@ namespace Smuxi.Frontend.Gnome
 			this.TopicPositionRadioButtonTop.Group = new global::GLib.SList (global::System.IntPtr.Zero);
 			this.TopicPositionRadioButtonTop.Remove (this.TopicPositionRadioButtonTop.Child);
 			// Container child TopicPositionRadioButtonTop.Gtk.Container+ContainerChild
-			this.alignment21 = new global::Gtk.Alignment (0.5f, 0.5f, 0f, 0f);
+			this.alignment21 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
 			this.alignment21.Name = "alignment21";
 			// Container child alignment21.Gtk.Container+ContainerChild
 			this.hbox22 = new global::Gtk.HBox ();
@@ -1428,7 +1236,7 @@ namespace Smuxi.Frontend.Gnome
 			this.image1.Name = "image1";
 			this.image1.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-goto-top", global::Gtk.IconSize.Menu);
 			this.hbox22.Add (this.image1);
-			global::Gtk.Box.BoxChild w114 = ((global::Gtk.Box.BoxChild)(this.hbox22[this.image1]));
+			global::Gtk.Box.BoxChild w114 = ((global::Gtk.Box.BoxChild)(this.hbox22 [this.image1]));
 			w114.Position = 0;
 			w114.Expand = false;
 			w114.Fill = false;
@@ -1438,14 +1246,14 @@ namespace Smuxi.Frontend.Gnome
 			this.label52.LabelProp = global::Mono.Unix.Catalog.GetString ("Top");
 			this.label52.UseUnderline = true;
 			this.hbox22.Add (this.label52);
-			global::Gtk.Box.BoxChild w115 = ((global::Gtk.Box.BoxChild)(this.hbox22[this.label52]));
+			global::Gtk.Box.BoxChild w115 = ((global::Gtk.Box.BoxChild)(this.hbox22 [this.label52]));
 			w115.Position = 1;
 			w115.Expand = false;
 			w115.Fill = false;
 			this.alignment21.Add (this.hbox22);
 			this.TopicPositionRadioButtonTop.Add (this.alignment21);
 			this.vbox11.Add (this.TopicPositionRadioButtonTop);
-			global::Gtk.Box.BoxChild w118 = ((global::Gtk.Box.BoxChild)(this.vbox11[this.TopicPositionRadioButtonTop]));
+			global::Gtk.Box.BoxChild w118 = ((global::Gtk.Box.BoxChild)(this.vbox11 [this.TopicPositionRadioButtonTop]));
 			w118.Position = 0;
 			w118.Expand = false;
 			w118.Fill = false;
@@ -1457,7 +1265,7 @@ namespace Smuxi.Frontend.Gnome
 			this.TopicPositionRadioButtonBottom.Group = this.TopicPositionRadioButtonTop.Group;
 			this.TopicPositionRadioButtonBottom.Remove (this.TopicPositionRadioButtonBottom.Child);
 			// Container child TopicPositionRadioButtonBottom.Gtk.Container+ContainerChild
-			this.alignment20 = new global::Gtk.Alignment (0.5f, 0.5f, 0f, 0f);
+			this.alignment20 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
 			this.alignment20.Name = "alignment20";
 			// Container child alignment20.Gtk.Container+ContainerChild
 			this.hbox21 = new global::Gtk.HBox ();
@@ -1468,7 +1276,7 @@ namespace Smuxi.Frontend.Gnome
 			this.image2.Name = "image2";
 			this.image2.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-goto-bottom", global::Gtk.IconSize.Menu);
 			this.hbox21.Add (this.image2);
-			global::Gtk.Box.BoxChild w119 = ((global::Gtk.Box.BoxChild)(this.hbox21[this.image2]));
+			global::Gtk.Box.BoxChild w119 = ((global::Gtk.Box.BoxChild)(this.hbox21 [this.image2]));
 			w119.Position = 0;
 			w119.Expand = false;
 			w119.Fill = false;
@@ -1478,14 +1286,14 @@ namespace Smuxi.Frontend.Gnome
 			this.label51.LabelProp = global::Mono.Unix.Catalog.GetString ("Bottom");
 			this.label51.UseUnderline = true;
 			this.hbox21.Add (this.label51);
-			global::Gtk.Box.BoxChild w120 = ((global::Gtk.Box.BoxChild)(this.hbox21[this.label51]));
+			global::Gtk.Box.BoxChild w120 = ((global::Gtk.Box.BoxChild)(this.hbox21 [this.label51]));
 			w120.Position = 1;
 			w120.Expand = false;
 			w120.Fill = false;
 			this.alignment20.Add (this.hbox21);
 			this.TopicPositionRadioButtonBottom.Add (this.alignment20);
 			this.vbox11.Add (this.TopicPositionRadioButtonBottom);
-			global::Gtk.Box.BoxChild w123 = ((global::Gtk.Box.BoxChild)(this.vbox11[this.TopicPositionRadioButtonBottom]));
+			global::Gtk.Box.BoxChild w123 = ((global::Gtk.Box.BoxChild)(this.vbox11 [this.TopicPositionRadioButtonBottom]));
 			w123.Position = 1;
 			w123.Expand = false;
 			w123.Fill = false;
@@ -1496,7 +1304,7 @@ namespace Smuxi.Frontend.Gnome
 			this.TopicPositionRadioButtonNone.UseUnderline = true;
 			this.TopicPositionRadioButtonNone.Group = this.TopicPositionRadioButtonTop.Group;
 			this.vbox11.Add (this.TopicPositionRadioButtonNone);
-			global::Gtk.Box.BoxChild w124 = ((global::Gtk.Box.BoxChild)(this.vbox11[this.TopicPositionRadioButtonNone]));
+			global::Gtk.Box.BoxChild w124 = ((global::Gtk.Box.BoxChild)(this.vbox11 [this.TopicPositionRadioButtonNone]));
 			w124.Position = 2;
 			w124.Expand = false;
 			w124.Fill = false;
@@ -1508,7 +1316,7 @@ namespace Smuxi.Frontend.Gnome
 			this.label41.UseMarkup = true;
 			this.frame10.LabelWidget = this.label41;
 			this.vbox9.Add (this.frame10);
-			global::Gtk.Box.BoxChild w127 = ((global::Gtk.Box.BoxChild)(this.vbox9[this.frame10]));
+			global::Gtk.Box.BoxChild w127 = ((global::Gtk.Box.BoxChild)(this.vbox9 [this.frame10]));
 			w127.Position = 1;
 			w127.Expand = false;
 			// Container child vbox9.Gtk.Box+BoxChild
@@ -1517,7 +1325,7 @@ namespace Smuxi.Frontend.Gnome
 			this.frame9.HeightRequest = 96;
 			this.frame9.Name = "frame9";
 			// Container child frame9.Gtk.Container+ContainerChild
-			this.alignment13 = new global::Gtk.Alignment (0.5f, 0.5f, 1f, 1f);
+			this.alignment13 = new global::Gtk.Alignment (0.5F, 0.5F, 1F, 1F);
 			this.alignment13.Name = "alignment13";
 			this.alignment13.LeftPadding = ((uint)(12));
 			// Container child alignment13.Gtk.Container+ContainerChild
@@ -1532,7 +1340,7 @@ namespace Smuxi.Frontend.Gnome
 			this.UserListPositionRadioButtonLeft.Group = new global::GLib.SList (global::System.IntPtr.Zero);
 			this.UserListPositionRadioButtonLeft.Remove (this.UserListPositionRadioButtonLeft.Child);
 			// Container child UserListPositionRadioButtonLeft.Gtk.Container+ContainerChild
-			this.alignment17 = new global::Gtk.Alignment (0.5f, 0.5f, 0f, 0f);
+			this.alignment17 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
 			this.alignment17.Name = "alignment17";
 			// Container child alignment17.Gtk.Container+ContainerChild
 			this.hbox18 = new global::Gtk.HBox ();
@@ -1543,7 +1351,7 @@ namespace Smuxi.Frontend.Gnome
 			this.image3.Name = "image3";
 			this.image3.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-goto-first", global::Gtk.IconSize.Menu);
 			this.hbox18.Add (this.image3);
-			global::Gtk.Box.BoxChild w128 = ((global::Gtk.Box.BoxChild)(this.hbox18[this.image3]));
+			global::Gtk.Box.BoxChild w128 = ((global::Gtk.Box.BoxChild)(this.hbox18 [this.image3]));
 			w128.Position = 0;
 			w128.Expand = false;
 			w128.Fill = false;
@@ -1553,14 +1361,14 @@ namespace Smuxi.Frontend.Gnome
 			this.label48.LabelProp = global::Mono.Unix.Catalog.GetString ("Left");
 			this.label48.UseUnderline = true;
 			this.hbox18.Add (this.label48);
-			global::Gtk.Box.BoxChild w129 = ((global::Gtk.Box.BoxChild)(this.hbox18[this.label48]));
+			global::Gtk.Box.BoxChild w129 = ((global::Gtk.Box.BoxChild)(this.hbox18 [this.label48]));
 			w129.Position = 1;
 			w129.Expand = false;
 			w129.Fill = false;
 			this.alignment17.Add (this.hbox18);
 			this.UserListPositionRadioButtonLeft.Add (this.alignment17);
 			this.vbox12.Add (this.UserListPositionRadioButtonLeft);
-			global::Gtk.Box.BoxChild w132 = ((global::Gtk.Box.BoxChild)(this.vbox12[this.UserListPositionRadioButtonLeft]));
+			global::Gtk.Box.BoxChild w132 = ((global::Gtk.Box.BoxChild)(this.vbox12 [this.UserListPositionRadioButtonLeft]));
 			w132.Position = 0;
 			w132.Expand = false;
 			w132.Fill = false;
@@ -1572,7 +1380,7 @@ namespace Smuxi.Frontend.Gnome
 			this.UserListPositionRadioButtonRight.Group = this.UserListPositionRadioButtonLeft.Group;
 			this.UserListPositionRadioButtonRight.Remove (this.UserListPositionRadioButtonRight.Child);
 			// Container child UserListPositionRadioButtonRight.Gtk.Container+ContainerChild
-			this.alignment18 = new global::Gtk.Alignment (0.5f, 0.5f, 0f, 0f);
+			this.alignment18 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
 			this.alignment18.Name = "alignment18";
 			// Container child alignment18.Gtk.Container+ContainerChild
 			this.hbox19 = new global::Gtk.HBox ();
@@ -1583,7 +1391,7 @@ namespace Smuxi.Frontend.Gnome
 			this.image4.Name = "image4";
 			this.image4.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-goto-last", global::Gtk.IconSize.Menu);
 			this.hbox19.Add (this.image4);
-			global::Gtk.Box.BoxChild w133 = ((global::Gtk.Box.BoxChild)(this.hbox19[this.image4]));
+			global::Gtk.Box.BoxChild w133 = ((global::Gtk.Box.BoxChild)(this.hbox19 [this.image4]));
 			w133.Position = 0;
 			w133.Expand = false;
 			w133.Fill = false;
@@ -1593,14 +1401,14 @@ namespace Smuxi.Frontend.Gnome
 			this.label49.LabelProp = global::Mono.Unix.Catalog.GetString ("Right");
 			this.label49.UseUnderline = true;
 			this.hbox19.Add (this.label49);
-			global::Gtk.Box.BoxChild w134 = ((global::Gtk.Box.BoxChild)(this.hbox19[this.label49]));
+			global::Gtk.Box.BoxChild w134 = ((global::Gtk.Box.BoxChild)(this.hbox19 [this.label49]));
 			w134.Position = 1;
 			w134.Expand = false;
 			w134.Fill = false;
 			this.alignment18.Add (this.hbox19);
 			this.UserListPositionRadioButtonRight.Add (this.alignment18);
 			this.vbox12.Add (this.UserListPositionRadioButtonRight);
-			global::Gtk.Box.BoxChild w137 = ((global::Gtk.Box.BoxChild)(this.vbox12[this.UserListPositionRadioButtonRight]));
+			global::Gtk.Box.BoxChild w137 = ((global::Gtk.Box.BoxChild)(this.vbox12 [this.UserListPositionRadioButtonRight]));
 			w137.Position = 1;
 			w137.Expand = false;
 			w137.Fill = false;
@@ -1611,7 +1419,7 @@ namespace Smuxi.Frontend.Gnome
 			this.UserListPositionRadioButtonNone.UseUnderline = true;
 			this.UserListPositionRadioButtonNone.Group = this.UserListPositionRadioButtonLeft.Group;
 			this.vbox12.Add (this.UserListPositionRadioButtonNone);
-			global::Gtk.Box.BoxChild w138 = ((global::Gtk.Box.BoxChild)(this.vbox12[this.UserListPositionRadioButtonNone]));
+			global::Gtk.Box.BoxChild w138 = ((global::Gtk.Box.BoxChild)(this.vbox12 [this.UserListPositionRadioButtonNone]));
 			w138.Position = 2;
 			w138.Expand = false;
 			w138.Fill = false;
@@ -1623,7 +1431,7 @@ namespace Smuxi.Frontend.Gnome
 			this.label38.UseMarkup = true;
 			this.frame9.LabelWidget = this.label38;
 			this.vbox9.Add (this.frame9);
-			global::Gtk.Box.BoxChild w141 = ((global::Gtk.Box.BoxChild)(this.vbox9[this.frame9]));
+			global::Gtk.Box.BoxChild w141 = ((global::Gtk.Box.BoxChild)(this.vbox9 [this.frame9]));
 			w141.Position = 2;
 			w141.Expand = false;
 			this.alignment5.Add (this.vbox9);
@@ -1634,14 +1442,14 @@ namespace Smuxi.Frontend.Gnome
 			this.label10.UseMarkup = true;
 			this.frame2.LabelWidget = this.label10;
 			this.vbox8.Add (this.frame2);
-			global::Gtk.Box.BoxChild w144 = ((global::Gtk.Box.BoxChild)(this.vbox8[this.frame2]));
+			global::Gtk.Box.BoxChild w144 = ((global::Gtk.Box.BoxChild)(this.vbox8 [this.frame2]));
 			w144.Position = 0;
 			w144.Expand = false;
 			// Container child vbox8.Gtk.Box+BoxChild
 			this.frame11 = new global::Gtk.Frame ();
 			this.frame11.Name = "frame11";
 			// Container child frame11.Gtk.Container+ContainerChild
-			this.alignment27 = new global::Gtk.Alignment (0.5f, 0.5f, 1f, 1f);
+			this.alignment27 = new global::Gtk.Alignment (0.5F, 0.5F, 1F, 1F);
 			this.alignment27.Name = "alignment27";
 			this.alignment27.LeftPadding = ((uint)(12));
 			// Container child alignment27.Gtk.Container+ContainerChild
@@ -1654,10 +1462,10 @@ namespace Smuxi.Frontend.Gnome
 			// Container child vbox14.Gtk.Box+BoxChild
 			this.label62 = new global::Gtk.Label ();
 			this.label62.Name = "label62";
-			this.label62.Xalign = 0f;
+			this.label62.Xalign = 0F;
 			this.label62.LabelProp = global::Mono.Unix.Catalog.GetString ("Highlight words:");
 			this.vbox14.Add (this.label62);
-			global::Gtk.Box.BoxChild w145 = ((global::Gtk.Box.BoxChild)(this.vbox14[this.label62]));
+			global::Gtk.Box.BoxChild w145 = ((global::Gtk.Box.BoxChild)(this.vbox14 [this.label62]));
 			w145.Position = 0;
 			w145.Expand = false;
 			w145.Fill = false;
@@ -1671,10 +1479,10 @@ namespace Smuxi.Frontend.Gnome
 			this.HighlightWordsTextView.Name = "HighlightWordsTextView";
 			this.scrolledwindow4.Add (this.HighlightWordsTextView);
 			this.vbox14.Add (this.scrolledwindow4);
-			global::Gtk.Box.BoxChild w147 = ((global::Gtk.Box.BoxChild)(this.vbox14[this.scrolledwindow4]));
+			global::Gtk.Box.BoxChild w147 = ((global::Gtk.Box.BoxChild)(this.vbox14 [this.scrolledwindow4]));
 			w147.Position = 1;
 			this.vbox13.Add (this.vbox14);
-			global::Gtk.Box.BoxChild w148 = ((global::Gtk.Box.BoxChild)(this.vbox13[this.vbox14]));
+			global::Gtk.Box.BoxChild w148 = ((global::Gtk.Box.BoxChild)(this.vbox13 [this.vbox14]));
 			w148.Position = 0;
 			// Container child vbox13.Gtk.Box+BoxChild
 			this.BeepOnHighlightCheckButton = new global::Gtk.CheckButton ();
@@ -1683,7 +1491,7 @@ namespace Smuxi.Frontend.Gnome
 			this.BeepOnHighlightCheckButton.DrawIndicator = true;
 			this.BeepOnHighlightCheckButton.UseUnderline = true;
 			this.vbox13.Add (this.BeepOnHighlightCheckButton);
-			global::Gtk.Box.BoxChild w149 = ((global::Gtk.Box.BoxChild)(this.vbox13[this.BeepOnHighlightCheckButton]));
+			global::Gtk.Box.BoxChild w149 = ((global::Gtk.Box.BoxChild)(this.vbox13 [this.BeepOnHighlightCheckButton]));
 			w149.Position = 1;
 			w149.Expand = false;
 			w149.Fill = false;
@@ -1695,10 +1503,10 @@ namespace Smuxi.Frontend.Gnome
 			this.label61.UseMarkup = true;
 			this.frame11.LabelWidget = this.label61;
 			this.vbox8.Add (this.frame11);
-			global::Gtk.Box.BoxChild w152 = ((global::Gtk.Box.BoxChild)(this.vbox8[this.frame11]));
+			global::Gtk.Box.BoxChild w152 = ((global::Gtk.Box.BoxChild)(this.vbox8 [this.frame11]));
 			w152.Position = 1;
 			this.InterfaceNotebook.Add (this.vbox8);
-			global::Gtk.Notebook.NotebookChild w153 = ((global::Gtk.Notebook.NotebookChild)(this.InterfaceNotebook[this.vbox8]));
+			global::Gtk.Notebook.NotebookChild w153 = ((global::Gtk.Notebook.NotebookChild)(this.InterfaceNotebook [this.vbox8]));
 			w153.Position = 3;
 			// Notebook tab
 			this.label4 = new global::Gtk.Label ();
@@ -1707,7 +1515,7 @@ namespace Smuxi.Frontend.Gnome
 			this.InterfaceNotebook.SetTabLabel (this.vbox8, this.label4);
 			this.label4.ShowAll ();
 			this.Notebook.Add (this.InterfaceNotebook);
-			global::Gtk.Notebook.NotebookChild w154 = ((global::Gtk.Notebook.NotebookChild)(this.Notebook[this.InterfaceNotebook]));
+			global::Gtk.Notebook.NotebookChild w154 = ((global::Gtk.Notebook.NotebookChild)(this.Notebook [this.InterfaceNotebook]));
 			w154.Position = 1;
 			// Notebook tab
 			this.label45 = new global::Gtk.Label ();
@@ -1729,7 +1537,7 @@ namespace Smuxi.Frontend.Gnome
 			this.ServersTreeView.Name = "ServersTreeView";
 			this.scrolledwindow3.Add (this.ServersTreeView);
 			this.hbox27.Add (this.scrolledwindow3);
-			global::Gtk.Box.BoxChild w156 = ((global::Gtk.Box.BoxChild)(this.hbox27[this.scrolledwindow3]));
+			global::Gtk.Box.BoxChild w156 = ((global::Gtk.Box.BoxChild)(this.hbox27 [this.scrolledwindow3]));
 			w156.Position = 0;
 			// Container child hbox27.Gtk.Box+BoxChild
 			this.vbuttonbox1 = new global::Gtk.VButtonBox ();
@@ -1743,7 +1551,7 @@ namespace Smuxi.Frontend.Gnome
 			this.ServersAddButton.UseUnderline = true;
 			this.ServersAddButton.Label = "gtk-add";
 			this.vbuttonbox1.Add (this.ServersAddButton);
-			global::Gtk.ButtonBox.ButtonBoxChild w157 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.vbuttonbox1[this.ServersAddButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w157 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.vbuttonbox1 [this.ServersAddButton]));
 			w157.Expand = false;
 			w157.Fill = false;
 			// Container child vbuttonbox1.Gtk.ButtonBox+ButtonBoxChild
@@ -1753,7 +1561,7 @@ namespace Smuxi.Frontend.Gnome
 			this.ServersEditButton.UseUnderline = true;
 			this.ServersEditButton.Label = "gtk-edit";
 			this.vbuttonbox1.Add (this.ServersEditButton);
-			global::Gtk.ButtonBox.ButtonBoxChild w158 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.vbuttonbox1[this.ServersEditButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w158 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.vbuttonbox1 [this.ServersEditButton]));
 			w158.Position = 1;
 			w158.Expand = false;
 			w158.Fill = false;
@@ -1764,16 +1572,16 @@ namespace Smuxi.Frontend.Gnome
 			this.ServersRemoveButton.UseUnderline = true;
 			this.ServersRemoveButton.Label = "gtk-remove";
 			this.vbuttonbox1.Add (this.ServersRemoveButton);
-			global::Gtk.ButtonBox.ButtonBoxChild w159 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.vbuttonbox1[this.ServersRemoveButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w159 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.vbuttonbox1 [this.ServersRemoveButton]));
 			w159.Position = 2;
 			w159.Expand = false;
 			w159.Fill = false;
 			this.hbox27.Add (this.vbuttonbox1);
-			global::Gtk.Box.BoxChild w160 = ((global::Gtk.Box.BoxChild)(this.hbox27[this.vbuttonbox1]));
+			global::Gtk.Box.BoxChild w160 = ((global::Gtk.Box.BoxChild)(this.hbox27 [this.vbuttonbox1]));
 			w160.Position = 1;
 			w160.Expand = false;
 			this.Notebook.Add (this.hbox27);
-			global::Gtk.Notebook.NotebookChild w161 = ((global::Gtk.Notebook.NotebookChild)(this.Notebook[this.hbox27]));
+			global::Gtk.Notebook.NotebookChild w161 = ((global::Gtk.Notebook.NotebookChild)(this.Notebook [this.hbox27]));
 			w161.Position = 2;
 			// Notebook tab
 			this.label57 = new global::Gtk.Label ();
@@ -1790,7 +1598,7 @@ namespace Smuxi.Frontend.Gnome
 			this.frame12 = new global::Gtk.Frame ();
 			this.frame12.Name = "frame12";
 			// Container child frame12.Gtk.Container+ContainerChild
-			this.alignment28 = new global::Gtk.Alignment (0.5f, 0.5f, 1f, 1f);
+			this.alignment28 = new global::Gtk.Alignment (0.5F, 0.5F, 1F, 1F);
 			this.alignment28.Name = "alignment28";
 			this.alignment28.LeftPadding = ((uint)(12));
 			// Container child alignment28.Gtk.Container+ContainerChild
@@ -1805,7 +1613,7 @@ namespace Smuxi.Frontend.Gnome
 			this.ChannelFiltersTreeView.Name = "ChannelFiltersTreeView";
 			this.scrolledwindow5.Add (this.ChannelFiltersTreeView);
 			this.vbox16.Add (this.scrolledwindow5);
-			global::Gtk.Box.BoxChild w163 = ((global::Gtk.Box.BoxChild)(this.vbox16[this.scrolledwindow5]));
+			global::Gtk.Box.BoxChild w163 = ((global::Gtk.Box.BoxChild)(this.vbox16 [this.scrolledwindow5]));
 			w163.Position = 0;
 			// Container child vbox16.Gtk.Box+BoxChild
 			this.hbuttonbox1 = new global::Gtk.HButtonBox ();
@@ -1818,7 +1626,7 @@ namespace Smuxi.Frontend.Gnome
 			this.ChannelFiltersAddButton.UseUnderline = true;
 			this.ChannelFiltersAddButton.Label = "gtk-add";
 			this.hbuttonbox1.Add (this.ChannelFiltersAddButton);
-			global::Gtk.ButtonBox.ButtonBoxChild w164 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.hbuttonbox1[this.ChannelFiltersAddButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w164 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.hbuttonbox1 [this.ChannelFiltersAddButton]));
 			w164.Expand = false;
 			w164.Fill = false;
 			// Container child hbuttonbox1.Gtk.ButtonBox+ButtonBoxChild
@@ -1829,12 +1637,12 @@ namespace Smuxi.Frontend.Gnome
 			this.ChannelFiltersRemoveButton.UseUnderline = true;
 			this.ChannelFiltersRemoveButton.Label = "gtk-remove";
 			this.hbuttonbox1.Add (this.ChannelFiltersRemoveButton);
-			global::Gtk.ButtonBox.ButtonBoxChild w165 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.hbuttonbox1[this.ChannelFiltersRemoveButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w165 = ((global::Gtk.ButtonBox.ButtonBoxChild)(this.hbuttonbox1 [this.ChannelFiltersRemoveButton]));
 			w165.Position = 1;
 			w165.Expand = false;
 			w165.Fill = false;
 			this.vbox16.Add (this.hbuttonbox1);
-			global::Gtk.Box.BoxChild w166 = ((global::Gtk.Box.BoxChild)(this.vbox16[this.hbuttonbox1]));
+			global::Gtk.Box.BoxChild w166 = ((global::Gtk.Box.BoxChild)(this.vbox16 [this.hbuttonbox1]));
 			w166.Position = 1;
 			w166.Expand = false;
 			this.alignment28.Add (this.vbox16);
@@ -1845,14 +1653,14 @@ namespace Smuxi.Frontend.Gnome
 			this.label64.UseMarkup = true;
 			this.frame12.LabelWidget = this.label64;
 			this.vbox15.Add (this.frame12);
-			global::Gtk.Box.BoxChild w169 = ((global::Gtk.Box.BoxChild)(this.vbox15[this.frame12]));
+			global::Gtk.Box.BoxChild w169 = ((global::Gtk.Box.BoxChild)(this.vbox15 [this.frame12]));
 			w169.Position = 0;
 			// Container child vbox15.Gtk.Box+BoxChild
 			this.frame13 = new global::Gtk.Frame ();
 			this.frame13.Sensitive = false;
 			this.frame13.Name = "frame13";
 			// Container child frame13.Gtk.Container+ContainerChild
-			this.alignment29 = new global::Gtk.Alignment (0.5f, 0.5f, 1f, 1f);
+			this.alignment29 = new global::Gtk.Alignment (0.5F, 0.5F, 1F, 1F);
 			this.alignment29.Name = "alignment29";
 			this.alignment29.LeftPadding = ((uint)(12));
 			this.frame13.Add (this.alignment29);
@@ -1862,10 +1670,10 @@ namespace Smuxi.Frontend.Gnome
 			this.label65.UseMarkup = true;
 			this.frame13.LabelWidget = this.label65;
 			this.vbox15.Add (this.frame13);
-			global::Gtk.Box.BoxChild w171 = ((global::Gtk.Box.BoxChild)(this.vbox15[this.frame13]));
+			global::Gtk.Box.BoxChild w171 = ((global::Gtk.Box.BoxChild)(this.vbox15 [this.frame13]));
 			w171.Position = 1;
 			this.Notebook.Add (this.vbox15);
-			global::Gtk.Notebook.NotebookChild w172 = ((global::Gtk.Notebook.NotebookChild)(this.Notebook[this.vbox15]));
+			global::Gtk.Notebook.NotebookChild w172 = ((global::Gtk.Notebook.NotebookChild)(this.Notebook [this.vbox15]));
 			w172.Position = 3;
 			// Notebook tab
 			this.label63 = new global::Gtk.Label ();
@@ -1875,10 +1683,10 @@ namespace Smuxi.Frontend.Gnome
 			this.Notebook.SetTabLabel (this.vbox15, this.label63);
 			this.label63.ShowAll ();
 			this.hbox1.Add (this.Notebook);
-			global::Gtk.Box.BoxChild w173 = ((global::Gtk.Box.BoxChild)(this.hbox1[this.Notebook]));
+			global::Gtk.Box.BoxChild w173 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.Notebook]));
 			w173.Position = 1;
 			w1.Add (this.hbox1);
-			global::Gtk.Box.BoxChild w174 = ((global::Gtk.Box.BoxChild)(w1[this.hbox1]));
+			global::Gtk.Box.BoxChild w174 = ((global::Gtk.Box.BoxChild)(w1 [this.hbox1]));
 			w174.Position = 0;
 			// Internal child Smuxi.Frontend.Gnome.SteticPreferencesDialog.ActionArea
 			global::Gtk.HButtonBox w175 = this.ActionArea;
@@ -1893,7 +1701,7 @@ namespace Smuxi.Frontend.Gnome
 			this.CancelButton.UseUnderline = true;
 			this.CancelButton.Label = "gtk-cancel";
 			this.AddActionWidget (this.CancelButton, -6);
-			global::Gtk.ButtonBox.ButtonBoxChild w176 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w175[this.CancelButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w176 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w175 [this.CancelButton]));
 			w176.Expand = false;
 			w176.Fill = false;
 			// Container child dialog-action_area1.Gtk.ButtonBox+ButtonBoxChild
@@ -1904,7 +1712,7 @@ namespace Smuxi.Frontend.Gnome
 			this.ApplyButton.UseUnderline = true;
 			this.ApplyButton.Label = "gtk-apply";
 			this.AddActionWidget (this.ApplyButton, -10);
-			global::Gtk.ButtonBox.ButtonBoxChild w177 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w175[this.ApplyButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w177 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w175 [this.ApplyButton]));
 			w177.Position = 1;
 			w177.Expand = false;
 			w177.Fill = false;
@@ -1915,7 +1723,7 @@ namespace Smuxi.Frontend.Gnome
 			this.OKButton.UseUnderline = true;
 			this.OKButton.Label = "gtk-ok";
 			this.AddActionWidget (this.OKButton, -5);
-			global::Gtk.ButtonBox.ButtonBoxChild w178 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w175[this.OKButton]));
+			global::Gtk.ButtonBox.ButtonBoxChild w178 = ((global::Gtk.ButtonBox.ButtonBoxChild)(w175 [this.OKButton]));
 			w178.Position = 2;
 			w178.Expand = false;
 			w178.Fill = false;
diff --git a/src/Frontend-GNOME/gtk-gui/generated.cs b/src/Frontend-GNOME/gtk-gui/generated.cs
index 91cadc8..39f680b 100644
--- a/src/Frontend-GNOME/gtk-gui/generated.cs
+++ b/src/Frontend-GNOME/gtk-gui/generated.cs
@@ -5,15 +5,15 @@ namespace Stetic
 	internal class Gui
 	{
 		private static bool initialized;
-
-		static internal void Initialize (Gtk.Widget iconRenderer)
+        
+		internal static void Initialize (Gtk.Widget iconRenderer)
 		{
 			if ((Stetic.Gui.initialized == false)) {
 				Stetic.Gui.initialized = true;
 			}
 		}
 	}
-
+    
 	internal class IconLoader
 	{
 		public static Gdk.Pixbuf LoadIcon (Gtk.Widget widget, string name, Gtk.IconSize size)
@@ -24,7 +24,7 @@ namespace Stetic
 			} else {
 				int sz;
 				int sy;
-				global::Gtk.Icon.SizeLookup (size, out sz, out sy);
+				global::Gtk.Icon.SizeLookup (size, out  sz, out  sy);
 				try {
 					return Gtk.IconTheme.Default.LoadIcon (name, sz, 0);
 				} catch (System.Exception) {
@@ -47,13 +47,12 @@ namespace Stetic
 			}
 		}
 	}
-
+    
 	internal class BinContainer
 	{
 		private Gtk.Widget child;
-
 		private Gtk.UIManager uimanager;
-
+        
 		public static BinContainer Attach (Gtk.Bin bin)
 		{
 			BinContainer bc = new BinContainer ();
@@ -62,32 +61,32 @@ namespace Stetic
 			bin.Added += new Gtk.AddedHandler (bc.OnAdded);
 			return bc;
 		}
-
+        
 		private void OnSizeRequested (object sender, Gtk.SizeRequestedArgs args)
 		{
 			if ((this.child != null)) {
 				args.Requisition = this.child.SizeRequest ();
 			}
 		}
-
+        
 		private void OnSizeAllocated (object sender, Gtk.SizeAllocatedArgs args)
 		{
 			if ((this.child != null)) {
 				this.child.Allocation = args.Allocation;
 			}
 		}
-
+        
 		private void OnAdded (object sender, Gtk.AddedArgs args)
 		{
 			this.child = args.Widget;
 		}
-
+        
 		public void SetUiManager (Gtk.UIManager uim)
 		{
 			this.uimanager = uim;
 			this.child.Realized += new System.EventHandler (this.OnRealized);
 		}
-
+        
 		private void OnRealized (object sender, System.EventArgs args)
 		{
 			if ((this.uimanager != null)) {
@@ -100,14 +99,14 @@ namespace Stetic
 			}
 		}
 	}
-
+    
 	internal class ActionGroups
 	{
 		public static Gtk.ActionGroup GetActionGroup (System.Type type)
 		{
 			return Stetic.ActionGroups.GetActionGroup (type.FullName);
 		}
-
+        
 		public static Gtk.ActionGroup GetActionGroup (string name)
 		{
 			return null;
diff --git a/src/Frontend-GNOME/gtk-gui/gui.stetic b/src/Frontend-GNOME/gtk-gui/gui.stetic
index 1929faa..763905f 100644
--- a/src/Frontend-GNOME/gtk-gui/gui.stetic
+++ b/src/Frontend-GNOME/gtk-gui/gui.stetic
@@ -3357,7 +3357,7 @@ Click "Forward" to begin.</property>
       </widget>
     </child>
   </widget>
-  <widget class="Gtk.Bin" id="Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget" design-size="736 372">
+  <widget class="Gtk.Bin" id="Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget" design-size="736 674">
     <property name="MemberName" />
     <property name="Visible">False</property>
     <child>
@@ -3460,7 +3460,7 @@ Click "Forward" to begin.</property>
                 <property name="MemberName" />
                 <property name="Xpad">50</property>
                 <property name="Xalign">0</property>
-                <property name="LabelProp" translatable="yes"><span size="small">Password which will be used to log into the SSH server. The password is optional if SSH key authorization is used (via Pageant from the PuTTY tools).</span></property>
+                <property name="LabelProp" translatable="yes"><span size="small">Password which will be used to log into the SSH server. The password is optional if SSH key authorization is used (see below).</span></property>
                 <property name="UseMarkup">True</property>
                 <property name="Wrap">True</property>
               </widget>
@@ -3480,6 +3480,60 @@ Click "Forward" to begin.</property>
           </packing>
         </child>
         <child>
+          <widget class="Gtk.VBox" id="vbox17">
+            <property name="MemberName" />
+            <property name="Spacing">6</property>
+            <child>
+              <widget class="Gtk.Label" id="label16">
+                <property name="MemberName" />
+                <property name="Xalign">0</property>
+                <property name="LabelProp" translatable="yes">_SSH Keyfile: (optional)</property>
+                <property name="UseUnderline">True</property>
+                <property name="MnemonicWidget">f_SshKeyfileChooserButton</property>
+              </widget>
+              <packing>
+                <property name="Position">0</property>
+                <property name="AutoSize">True</property>
+                <property name="Expand">False</property>
+                <property name="Fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="Gtk.FileChooserButton" id="f_SshKeyfileChooserButton">
+                <property name="MemberName" />
+                <property name="ShowHidden">True</property>
+              </widget>
+              <packing>
+                <property name="Position">1</property>
+                <property name="AutoSize">True</property>
+                <property name="Expand">False</property>
+                <property name="Fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="Gtk.Label" id="label17">
+                <property name="MemberName" />
+                <property name="Xpad">50</property>
+                <property name="Xalign">0</property>
+                <property name="LabelProp" translatable="yes"><span size="small">SSH private keyfile which will be used to log into the SSH server</span></property>
+                <property name="UseMarkup">True</property>
+              </widget>
+              <packing>
+                <property name="Position">2</property>
+                <property name="AutoSize">True</property>
+                <property name="Expand">False</property>
+                <property name="Fill">False</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="Position">2</property>
+            <property name="AutoSize">True</property>
+            <property name="Expand">False</property>
+            <property name="Fill">False</property>
+          </packing>
+        </child>
+        <child>
           <widget class="Gtk.VBox" id="vbox16">
             <property name="MemberName" />
             <property name="Spacing">6</property>
@@ -3529,7 +3583,7 @@ Click "Forward" to begin.</property>
             </child>
           </widget>
           <packing>
-            <property name="Position">2</property>
+            <property name="Position">3</property>
             <property name="AutoSize">True</property>
             <property name="Expand">False</property>
             <property name="Fill">False</property>
@@ -3586,7 +3640,7 @@ Click "Forward" to begin.</property>
             </child>
           </widget>
           <packing>
-            <property name="Position">3</property>
+            <property name="Position">4</property>
             <property name="AutoSize">True</property>
             <property name="Expand">False</property>
             <property name="Fill">False</property>
@@ -3643,7 +3697,7 @@ Click "Forward" to begin.</property>
             </child>
           </widget>
           <packing>
-            <property name="Position">4</property>
+            <property name="Position">5</property>
             <property name="AutoSize">True</property>
             <property name="Expand">False</property>
             <property name="Fill">False</property>
diff --git a/src/Frontend-GNOME/smuxi-frontend-gnome.desktop b/src/Frontend-GNOME/smuxi-frontend-gnome.desktop
index a09f65c..932a129 100644
--- a/src/Frontend-GNOME/smuxi-frontend-gnome.desktop
+++ b/src/Frontend-GNOME/smuxi-frontend-gnome.desktop
@@ -1,20 +1,45 @@
 [Desktop Entry]
 Version=1.0
-Encoding=UTF-8
-Name=Smuxi IRC Client
-Name[da]=Smuxi - IRC-klient
-Name[de]=Smuxi - Chat Client
-Name[fr]=Client IRC Smuxi
+Name=Smuxi
+Name[da]=Smuxi
+Name[de]=Smuxi
+Name[fr]=Smuxi
+Name[sv]=Smuxi
 GenericName=IRC Chat
+GenericName[ca]=_Xat a l'IRC
 GenericName[da]=IRC-snak
 GenericName[de]=IRC Chat
+GenericName[es]=IRC Chat
 GenericName[fr]=Chat IRC
+GenericName[it]=Chat IRC
+GenericName[pt]=Conversação de IRC
+GenericName[ru]=IRC-чат
+GenericName[sv]=IRC chatt
+GenericName[zh_CN]=IRC 聊天
+X-GNOME-FullName=Smuxi IRC Client
+X-GNOME-FullName[ca]=Client d'IRC Smuxi
+X-GNOME-FullName[da]=Smuxi - IRC-klient
+X-GNOME-FullName[de]=Smuxi - Chat Client
+X-GNOME-FullName[es]=Cliente IRC Smuxi
+X-GNOME-FullName[fr]=Client IRC Smuxi
+X-GNOME-FullName[it]=Client di IRC Smuxi
+X-GNOME-FullName[pt]=Smuxi Cliente de IRC
+X-GNOME-FullName[ru]=IRC-клиент Smuxi
+X-GNOME-FullName[sv]=Smuxi IRC-klient
+X-GNOME-FullName[zh_CN]=Smuxi IRC 客户端
 Comment=Chat with other people on IRC
+Comment[ca]=Xategeu amb altres persones a l'IRC
 Comment[da]=Snak med andre via IRC
 Comment[de]=Kommuniziere mit anderen Leuten im IRC
+Comment[es]=Charla con otras personas en IRC
 Comment[fr]=Chatter sur IRC avec d'autres gens
+Comment[it]=Chiacchiera con altre persone su IRC
+Comment[pt]=Conversar com outra pessoa no IRC
+Comment[ru]=Разговор с людьми в сети IRC
+Comment[sv]=Chatta med andra människor på IRC
+Comment[zh_CN]=和 IRC 上的其他人聊天
 Exec=smuxi-frontend-gnome
 Terminal=false
 Type=Application
 Categories=Network;GNOME;GTK;Chat;InstantMessaging;IRCClient;
-Icon=smuxi-frontend-gnome.svg
+Icon=smuxi-frontend-gnome
diff --git a/src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in b/src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in
new file mode 100644
index 0000000..0cac68f
--- /dev/null
+++ b/src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Version=1.0
+_Name=Smuxi
+_GenericName=IRC Chat
+_X-GNOME-FullName=Smuxi IRC Client
+_Comment=Chat with other people on IRC
+Exec=smuxi-frontend-gnome
+Terminal=false
+Type=Application
+Categories=Network;GNOME;GTK;Chat;InstantMessaging;IRCClient;
+Icon=smuxi-frontend-gnome
diff --git a/src/Frontend-GNOME/smuxi-frontend-gnome.in b/src/Frontend-GNOME/smuxi-frontend-gnome.in
index 0e2b8ab..b0af2e9 100644
--- a/src/Frontend-GNOME/smuxi-frontend-gnome.in
+++ b/src/Frontend-GNOME/smuxi-frontend-gnome.in
@@ -1,3 +1,3 @@
 #!/bin/sh
 
-exec mono "@expanded_libdir@/@PACKAGE@/smuxi-frontend-gnome.exe" "$@"
+exec mono --debug "@expanded_libdir@/@PACKAGE@/smuxi-frontend-gnome.exe" "$@"
diff --git a/images/icon.svg b/src/Frontend-GNOME/smuxi-frontend-gnome.svg
similarity index 100%
rename from images/icon.svg
rename to src/Frontend-GNOME/smuxi-frontend-gnome.svg
diff --git a/src/Frontend-STFL/AssemblyInfo.cs b/src/Frontend-STFL/AssemblyInfo.cs
index a36fbec..b2cc841 100644
--- a/src/Frontend-STFL/AssemblyInfo.cs
+++ b/src/Frontend-STFL/AssemblyInfo.cs
@@ -1,10 +1,4 @@
 /*
- * $Id: AssemblyInfo.cs 197 2007-06-12 00:57:23Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-GNOME/AssemblyInfo.cs $
- * $Rev: 197 $
- * $Author: meebey $
- * $Date: 2007-06-12 02:57:23 +0200 (Tue, 12 Jun 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
  * Copyright (c) 2007 Mirco Bauer <meebey at meebey.net>
@@ -30,7 +24,12 @@ using System.Reflection;
 using System.Runtime.CompilerServices;
 
 [assembly: AssemblyTitle("Smuxi - STFL frontend")]
-[assembly: AssemblyCopyright("2007-2008 (C) Mirco Bauer <meebey at meebey.net>")]
+[assembly: AssemblyCopyright("2007-2011 (C) Mirco Bauer <meebey at meebey.net>, 2011 (C) Andrius Bentkus <andrius.bentkus at gmail.com>")]
 
 [assembly: AssemblyDelaySign(false)]
 [assembly: AssemblyKeyFile("")]
+
+#if LOG4NET
+// let log4net use .exe.config file
+[assembly: log4net.Config.XmlConfigurator]
+#endif
diff --git a/src/Frontend-STFL/ChatView.cs b/src/Frontend-STFL/ChatView.cs
index bb2d363..90a1949 100644
--- a/src/Frontend-STFL/ChatView.cs
+++ b/src/Frontend-STFL/ChatView.cs
@@ -1,13 +1,7 @@
 /*
- * $Id: ChatView.cs 200 2007-06-25 01:12:33Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-GNOME/ChatView.cs $
- * $Rev: 200 $
- * $Author: meebey $
- * $Date: 2007-06-25 03:12:33 +0200 (Mon, 25 Jun 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2007 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2007, 2010-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -27,46 +21,122 @@
  */
 
 using System;
+using System.Text;
 using System.Collections.Generic;
 using System.Globalization;
 using Smuxi.Common;
 using Smuxi.Engine;
 using Smuxi.Frontend;
-using STFL = Stfl;
+using Stfl;
 
 namespace Smuxi.Frontend.Stfl
 {
+    [ChatViewInfo(ChatType = ChatType.Session)]
     [ChatViewInfo(ChatType = ChatType.Protocol)]
     [ChatViewInfo(ChatType = ChatType.Person)]
     [ChatViewInfo(ChatType = ChatType.Group)]
-    public class ChatView : IChatView
+    public class ChatView : IChatView, IDisposable
     {
 #if LOG4NET
-        private static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+        static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 #endif
-        private ChatModel  _ChatModel;
-        private MainWindow _MainWindow;
-        
+        // HACK: STFL crashes if we use 0 in a widget name
+        static int f_NextID = 1;
+        int        f_WidgetID;
+        string     f_WidgetName;
+        ChatModel  f_ChatModel;
+        MainWindow f_MainWindow;
+        TextView   MessageTextView { get; set; }
+
         public ChatModel ChatModel {
             get {
-                return _ChatModel;
+                return f_ChatModel;
             }
         }
-        
-        public MainWindow MainWindow {
+
+        public string ID {
             get {
-                return _MainWindow;
+                return ChatModel.ID;
+            }
+        }
+
+        public int Position {
+            get {
+                return ChatModel.Position;
+            }
+        }
+
+        public bool IsVisible {
+            get {
+                return f_MainWindow[f_WidgetID + "d"] == "1";
             }
             set {
-                _MainWindow = value;
+                f_MainWindow[f_WidgetID + "d"] = value ?  "1" : "0";
+           }
+        }
+
+        public string WidgetName {
+            get {
+                return f_WidgetName;
             }
         }
-        
-        public ChatView(ChatModel chat)
+
+        public ChatView(ChatModel chat, MainWindow window)
         {
-            _ChatModel = chat;
+            Trace.Call(chat, window);
+
+            if (chat == null) {
+                throw new ArgumentNullException("chat");
+            }
+            if (window == null) {
+                throw new ArgumentNullException("window");
+            }
+
+            f_ChatModel = chat;
+            f_MainWindow = window;
+            f_WidgetID = f_NextID++;
+            f_WidgetName = "output_textview_" + f_WidgetID;
+
+            f_MainWindow.Modify("output_vbox", "append",
+                "{" +
+                    "textview[" + f_WidgetName + "] " +
+                        ".expand:vh " +
+                        ".display[" + f_WidgetID + "d]:0 " +
+                        "offset[" + f_WidgetID + "os]:0 " +
+                        "richtext:1 " +
+                        "style_red_normal:fg=red " +
+                        "style_url_normal:attr=underline " +
+                        "style_u_normal:attr=underline " +
+                        "style_b_normal:attr=bold " +
+                        "style_i_normal:attr=standout " +
+                "}"
+            );
+            MessageTextView = new TextView(f_MainWindow, f_WidgetName);
+            MessageTextView.OffsetVariableName = f_WidgetID + "os";
+            // HACK: as the chat is not always visible we can't extract the
+            // heigth and width information from the textview because it simply
+            // returns 0 when invisible, thus we need to abuse output_vbox
+            MessageTextView.HeigthVariableName = "output_vbox:h";
+            MessageTextView.WidthVariableName = "output_vbox:w";
+            MessageTextView.AutoLineWrap = true;
         }
         
+        ~ChatView()
+        {
+            Dispose(false);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            f_MainWindow.Modify(f_WidgetName, "delete", null);
+        }
+
+        public virtual void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
         public virtual void Enable()
         {
             Trace.Call();
@@ -84,9 +154,9 @@ namespace Smuxi.Frontend.Stfl
 #endif
             // sync messages
             // cleanup, be sure the output is empty
-            _MainWindow.Modify("output_textview", "replace_inner", "");
+            f_MainWindow.Modify("output_textview", "replace_inner", "");
             
-            IList<MessageModel> messages = _ChatModel.Messages;
+            IList<MessageModel> messages = f_ChatModel.Messages;
             if (messages.Count > 0) {
                 foreach (MessageModel msg in messages) {
                     AddMessage(msg);
@@ -94,53 +164,98 @@ namespace Smuxi.Frontend.Stfl
             }
         }
         
-    	public void AddMessage(MessageModel msg)
-    	{
-            string finalMsg = String.Empty;
+        public virtual void Populate()
+        {
+        }
+
+        public void AddMessage(MessageModel msg)
+        {
+            // OPT: typical message length
+            var line = new StringBuilder(512);
+            int msgLength = 0;
             foreach (MessagePartModel msgPart in msg.MessageParts) {
                 // TODO: implement other types
-                if (msgPart is TextMessagePartModel) {
-                    TextMessagePartModel fmsgti = (TextMessagePartModel) msgPart;
-                    finalMsg += fmsgti.Text;
-                } 
+                if (msgPart is UrlMessagePartModel) {
+                    var urlPart = (UrlMessagePartModel) msgPart;
+                    var escapedUrl = StflApi.EscapeRichText(urlPart.Url);
+                    line.Append(String.Format("<url>{0}</url>", escapedUrl));
+                    msgLength += urlPart.Url.Length;
+                } else if (msgPart is TextMessagePartModel) {
+                    var txtPart = (TextMessagePartModel) msgPart;
+                    if (String.IsNullOrEmpty(txtPart.Text)) {
+                        continue;
+                    }
+
+                    var tags = new List<string>();
+                    if (txtPart.ForegroundColor != TextColor.None) {
+                        // TODO: implement color mapping, see:
+                        // http://www.calmar.ws/vim/256-xterm-24bit-rgb-color-chart.html
+                        //tags.Add("red");
+                    }
+                    if (txtPart.Underline) {
+                        tags.Add("u");
+                    }
+                    if (txtPart.Bold) {
+                        tags.Add("b");
+                    }
+                    if (txtPart.Italic) {
+                        tags.Add("i");
+                    }
+
+                    string escapedText = StflApi.EscapeRichText(txtPart.Text);
+                    if (tags.Count > 0) {
+                        tags.Reverse();
+                        string markup = escapedText;
+                        foreach (string tag in tags) {
+                            markup = String.Format("<{0}>{1}</{2}>",
+                                                   tag, markup, tag);
+                        }
+                        line.Append(markup);
+                    } else {
+                        line.Append(escapedText);
+                    }
+                    msgLength += txtPart.Text.Length;
+                }
             }
-            
+
             string timestamp;
             try {
                 timestamp = msg.TimeStamp.ToLocalTime().ToString((string)Frontend.UserConfig["Interface/Notebook/TimestampFormat"]);
             } catch (FormatException e) {
                 timestamp = "Timestamp Format ERROR: " + e.Message;
             }
-            finalMsg = timestamp + " " + _ChatModel.Name + " " + finalMsg;
-            
-            _MainWindow.Modify("output_textview", "append", "{listitem text:" + STFL.quote(finalMsg) + "}"); 
-            
-            //ScrollToEnd();
-    	}
-    	
-    	public void ScrollUp()
+            var finalMsg = String.Format("{0} {1}", timestamp, line.ToString());
+            MessageTextView.AppendLine(finalMsg);
+
+            ScrollToEnd();
+        }
+
+        public void ScrollUp()
         {
             Trace.Call();
+
+            MessageTextView.ScrollUp();
         }
-        
-    	public void ScrollDown()
+
+        public void ScrollDown()
         {
             Trace.Call();
+
+            MessageTextView.ScrollDown();
         }
-        
-    	public void ScrollToStart()
+
+        public void ScrollToStart()
         {
             Trace.Call();
+
+            MessageTextView.ScrollToStart();
         }
-        
-    	public void ScrollToEnd()
+
+        public void ScrollToEnd()
         {
             Trace.Call();
-            
-            // let height refresh
-            //_MainWindow.Run(-1);
-            //_MainWindow.Modify("output_textview", "replace", "offset:-1");
-            //_MainWindow["output_textview_offset"] = (_ChatModel.Messages.Count - 1).ToString();
-        }     
+
+            MessageTextView.ScrollToEnd();
+        }
     }
 }
diff --git a/src/Frontend-STFL/ChatViewManager.cs b/src/Frontend-STFL/ChatViewManager.cs
index 1f5798d..3f9ff7d 100644
--- a/src/Frontend-STFL/ChatViewManager.cs
+++ b/src/Frontend-STFL/ChatViewManager.cs
@@ -1,13 +1,7 @@
 /*
- * $Id: ChannelPage.cs 138 2006-12-23 17:11:57Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-GNOME/ChannelPage.cs $
- * $Rev: 138 $
- * $Author: meebey $
- * $Date: 2006-12-23 18:11:57 +0100 (Sat, 23 Dec 2006) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2007 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2007, 2010-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -27,6 +21,7 @@
  */
 
 using System;
+using System.Text;
 using System.Globalization;
 using System.Collections.Generic;
 using Mono.Unix;
@@ -41,52 +36,142 @@ namespace Smuxi.Frontend.Stfl
 #if LOG4NET
         private static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 #endif
-        private MainWindow                      _MainWindow;
-        private ChatView                        _ActiveChat;
-        private Dictionary<ChatModel, ChatView> _ChatViews = new Dictionary<ChatModel, ChatView>();
-        
+        private MainWindow                      f_MainWindow;
+        private ChatView                        f_CurrentChat;
+        private Dictionary<ChatModel, ChatView> f_ChatViews = new Dictionary<ChatModel, ChatView>();
+        private List<ChatView>                  f_ChatViewList = new List<ChatView>();
+
+        public event ChatSwitchedEventHandler CurrentChatSwitched;
+
         public override IChatView ActiveChat {
             get {
-                return _ActiveChat;
+                return CurrentChat;
+            }
+        }
+        
+        public ChatView CurrentChat {
+            get {
+                return f_CurrentChat;
+            }
+            set {
+                if (f_CurrentChat != null) {
+                    f_CurrentChat.IsVisible = false;
+                }
+
+                f_CurrentChat = value;
+                if (f_CurrentChat != null) {
+#if LOG4NET
+                    _Logger.Debug("set_CurrentChat(): making " + value.ChatModel.ID + " visible");
+#endif
+                    f_CurrentChat.IsVisible = true;
+                }
+
+                if (CurrentChatSwitched != null) {
+                    CurrentChatSwitched(this, new ChatSwitchedEventArgs(f_CurrentChat));
+                }
+            }
+        }
+
+        public int CurrentChatNumber {
+            get {
+                if (CurrentChat == null) {
+                    return -1;
+                }
+                return f_ChatViewList.IndexOf(CurrentChat);
+            }
+            set {
+                if (value < 0 || value >= f_ChatViewList.Count) {
+                    return;
+                }
+
+                CurrentChat = f_ChatViewList[value];
             }
         }
 
         public ChatViewManager(MainWindow mainWindow)
         {
-            _MainWindow = mainWindow;
+           if (mainWindow == null) {
+                throw new ArgumentNullException("mainWindow");
+           }
+
+           f_MainWindow = mainWindow;
         }
         
         public override void AddChat(ChatModel chat)
         {
-            ChatView chatView = (ChatView) CreateChatView(chat);
-            chatView.MainWindow = _MainWindow;
-            _ChatViews.Add(chat, chatView);
-            
-            _ActiveChat = chatView;
+            ChatView chatView = (ChatView) CreateChatView(chat, f_MainWindow);
+            f_ChatViews.Add(chat, chatView);
+            f_ChatViewList.Add(chatView);
+
+            if (CurrentChat == null) {
+                CurrentChat = chatView;
+            }
+
+            UpdateNavigation();
         }
-        
+
         public override void RemoveChat(ChatModel chat)
         {
-            ChatView chatView = _ChatViews[chat];
-            _ChatViews.Remove(chat);
+            var chatView = GetChat(chat);
+            chatView.IsVisible = false;
+
+            if (CurrentChat == chatView) {
+                CurrentChatNumber--;
+            }
+
+            chatView.Dispose();
+            f_ChatViews.Remove(chat);
+            f_ChatViewList.Remove(chatView);
+
+            UpdateNavigation();
         }
         
         public override void EnableChat(ChatModel chat)
         {
-               ChatView chatView = _ChatViews[chat];
-               chatView.Enable();
+           ChatView chatView = f_ChatViews[chat];
+           chatView.Enable();
         }
         
         public override void DisableChat(ChatModel chat)
         {
-               ChatView chatView = _ChatViews[chat];
-               chatView.Disable();
+           ChatView chatView = f_ChatViews[chat];
+           chatView.Disable();
         }
         
         public ChatView GetChat(ChatModel chat)
         {
-            return _ChatViews[chat];
-            //return _ActiveChat;
+            return f_ChatViews[chat];
+        }
+        
+        public ChatView GetChat(int chat)
+        {
+            if (chat < 0 || chat >= f_ChatViewList.Count) {
+                return null;
+            }
+            return f_ChatViewList[chat];
+        }
+
+        private void UpdateNavigation()
+        {
+            var nav = new StringBuilder();
+            foreach (var chat in f_ChatViewList) {
+                nav.AppendFormat("[{0}] ", chat.ChatModel.Name);
+            }
+            nav.Remove(nav.Length - 1, 1);
+
+            f_MainWindow.NavigationLabel = nav.ToString();
+        }
+    }
+
+    public delegate void ChatSwitchedEventHandler(object sender, ChatSwitchedEventArgs e);
+    
+    public class ChatSwitchedEventArgs : EventArgs
+    {
+        public ChatView ChatView { get; set; }
+        
+        public ChatSwitchedEventArgs(ChatView chatView)
+        {
+            ChatView = chatView;
         }
-    }   
+    }
 }
diff --git a/src/Frontend-STFL/Entry.cs b/src/Frontend-STFL/Entry.cs
index 8dfea3a..d597a77 100644
--- a/src/Frontend-STFL/Entry.cs
+++ b/src/Frontend-STFL/Entry.cs
@@ -1,13 +1,8 @@
 /*
- * $Id: MainWindow.cs 192 2007-04-22 11:48:12Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-GNOME/MainWindow.cs $
- * $Rev: 192 $
- * $Author: meebey $
- * $Date: 2007-04-22 13:48:12 +0200 (Sun, 22 Apr 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2007 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2007, 2010-2011 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2011 Andrius Bentkus <andrius.bentkus at gmail.com>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -30,7 +25,7 @@ using System;
 using System.IO;
 using System.Reflection;
 using Mono.Unix;
-//using Stfl;
+using Stfl;
 using Smuxi.Common;
 using Smuxi.Engine;
 
@@ -41,45 +36,105 @@ namespace Smuxi.Frontend.Stfl
 #if LOG4NET
         private static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 #endif
-        private MainWindow _MainWindow;
-        
-        public event EventHandler Activated;
-        
+        MainWindow      f_MainWindow;
+        ChatViewManager f_ChatViewManager;
+
+        event EventHandler Activated;
+
         public string Text {
             get {
-                return _MainWindow["input_text"];
+                return f_MainWindow["input_text"];
+            }
+            set {
+                f_MainWindow["input_text"] = value;
+            }
+        }
+
+        public int Position {
+            get {
+                return Int32.Parse(f_MainWindow["input_pos"]);
             }
             set {
-                _MainWindow["input_text"] = value;
+                f_MainWindow["input_pos"] = value.ToString();
             }
         }
         
-        public Entry(MainWindow mainWindow)
+        public Entry(MainWindow mainWindow, ChatViewManager chatViewManager)
         {
-            _MainWindow = mainWindow;
-            _MainWindow.KeyPressed += new KeyPressedEventHandler(_OnKeyPressed);
+           if (mainWindow == null) {
+                throw new ArgumentNullException("mainWindow");
+           }
+           if (chatViewManager == null) {
+                throw new ArgumentNullException("chatViewManager");
+           }
+
+            f_MainWindow = mainWindow;
+            f_MainWindow.KeyPressed += OnKeyPressed;
+            
+            f_ChatViewManager = chatViewManager;
+            f_ChatViewManager.CurrentChatSwitched += OnChatSwitched;
         }
         
-        private void _OnKeyPressed(object sender, KeyPressedEventArgs e)
+        private void OnKeyPressed(object sender, KeyPressedEventArgs e)
         {
             Trace.Call(sender, e);
             
 #if LOG4NET
-            _Logger.Debug("_OnKeyPressed(): e.Key: " + e.Key + " e.Focus: " + e.Focus);
+            _Logger.Debug("_OnKeyPressed(): e.Key: '" + e.Key + "' e.Focus: '" + e.Focus + "'");
 #endif
             switch (e.Key) {
                 case "ENTER":
                     OnActivated(EventArgs.Empty);
                     break;
+                case "PPAGE":
+                    if (f_ChatViewManager.ActiveChat != null) {
+                        f_ChatViewManager.ActiveChat.ScrollUp();
+                    }
+                    break;
                 case "NPAGE":
-                    _MainWindow.ChatViewManager.ActiveChat.ScrollToEnd();
+                    if (f_ChatViewManager.ActiveChat != null) {
+                        f_ChatViewManager.ActiveChat.ScrollDown();
+                    }
+                    break;
+                case "kPRV5": // CTRL + PAGE UP
+                case "^P":
+                    f_ChatViewManager.CurrentChatNumber--;
+                    break;
+                case "kNXT5": // CTRL + PAGE DOWN
+                case "^N":
+                    f_ChatViewManager.CurrentChatNumber++;
                     break;
-            } 
+                case "^W":
+                    DeleteUntilSpace();
+                    break;
+                case "kRIT5":
+                    JumpWord(false);
+                    break;
+                case "kLFT5":
+                    JumpWord(true);
+                    break;
+                case "^D":
+                    DeleteChar();
+                    break;
+            }
+        }
+
+        private void OnChatSwitched(object sender, ChatSwitchedEventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            f_MainWindow.InputLabel = String.Format("[{0}]",
+                                                    e.ChatView.ChatModel.Name);
         }
 
         public virtual void OnActivated(EventArgs e)
         {
-            ExecuteCommand(Text);
+            var text = Text;
+            if (String.IsNullOrEmpty(text)) {
+                return;
+            }
+
+            ExecuteCommand(text);
             
             if (Activated != null) {
                 Activated(this, EventArgs.Empty);
@@ -90,16 +145,19 @@ namespace Smuxi.Frontend.Stfl
         
         public void ExecuteCommand(string cmd)
         {
-            if (!(cmd.Length > 0)) {
-                return;
+            if (cmd == null) {
+                throw new ArgumentNullException("cmd");
+            }
+
+            ChatModel chat = null;
+            if (f_MainWindow.ChatViewManager.ActiveChat != null) {
+                chat = f_MainWindow.ChatViewManager.ActiveChat.ChatModel;
             }
-            
             bool handled = false;
-            CommandModel cd = new CommandModel(Frontend.FrontendManager,
-                                               _MainWindow.ChatViewManager.ActiveChat.ChatModel,
+            CommandModel cd = new CommandModel(Frontend.FrontendManager, chat,
                                                (string)Frontend.UserConfig["Interface/Entry/CommandCharacter"],
                                                cmd);
-            //handled = _Command(cd);
+            handled = Command(cd);
             if (!handled) {
                 handled = Frontend.Session.Command(cd);
             }
@@ -117,6 +175,42 @@ namespace Smuxi.Frontend.Stfl
             }
         }
 
+        private bool Command(CommandModel cmd)
+        {
+            bool handled = false;
+            if (cmd.IsCommand) {
+                switch (cmd.Command.ToLower()) {
+                    case "window":
+                        CommandWindow(cmd);
+                        handled = true;
+                        break;
+                    case "gc":
+#if LOG4NET
+                        _Logger.Debug("GC.Collect()");
+#endif
+                        cmd.FrontendManager.AddTextToChat(cmd.Chat,
+                            "-!- GCing...");
+                        GC.Collect();
+                        handled = true;
+                        break;
+                }
+            }
+            return handled;
+        }
+
+        private void CommandWindow(CommandModel cmd)
+        {
+            int window;
+            if (!Int32.TryParse(cmd.Parameter, out window)) {
+                return;
+            }
+            ChatView chat = f_ChatViewManager.GetChat(window - 1);
+            if (chat == null) {
+                return;
+            }
+            f_ChatViewManager.CurrentChat = chat;
+        }
+
         private void _CommandUnknown(CommandModel cd)
         {
             cd.FrontendManager.AddTextToChat(cd.Chat, "-!- " +
@@ -124,5 +218,91 @@ namespace Smuxi.Frontend.Stfl
                                               "Unknown Command: {0}"),
                                               cd.Command));
         }
+
+        // gets the position of the first space left
+        private int GetLeftSpace(int end)
+        {
+            // we are already at the very beginning
+            if (end == 0) {
+                return 0;
+            }
+
+            int start;
+
+            // are the first characters spaces?
+            bool firstSpace = true;
+
+            for (start = end; start > 0; start--) {
+                if (start >= Text.Length) {
+                    continue;
+                } else if (Text[start] == ' ') {
+                    if (firstSpace) {
+                        continue;
+                    } else {
+                        start++; // don't cut the last char
+                        break;
+                    }
+                } else {
+                    firstSpace = false;
+                }
+            }
+
+            return start;
+        }
+
+        private int GetRightSpace(int start)
+        {
+            bool firstSpace = true;
+
+            int end;
+            for (end = start; end < Text.Length; end++) {
+                if (Text[end] == ' ') {
+                    if (firstSpace) {
+                        continue;
+                    } else {
+                        break;
+                    }
+                } else {
+                    firstSpace = false;
+                }
+            }
+
+            return end;
+        }
+
+        private void DeleteUntilSpace()
+        {
+            int end = Position;
+
+            // nothing to delete, if we are at the very beginning
+            if (end == 0) {
+                return;
+            }
+
+            int start = GetLeftSpace(end);
+
+            Text = Text.Substring(0, start) + Text.Substring(end);
+
+            Position = start;
+        }
+
+        private void JumpWord(bool left)
+        {
+            if (left) {
+                int pos = GetLeftSpace(Position);
+                if (pos > 0) {
+                    pos--;
+                }
+                Position = pos;
+            } else {
+                Position = GetRightSpace(Position);
+            }
+        }
+
+        private void DeleteChar()
+        {
+            Text = Text.Substring(0, Position) +
+                   Text.Substring(Math.Min(Position + 1, Text.Length));
+        }
     }
 }
diff --git a/src/Frontend-STFL/Frontend.cs b/src/Frontend-STFL/Frontend.cs
index 83f6d10..2fd4677 100644
--- a/src/Frontend-STFL/Frontend.cs
+++ b/src/Frontend-STFL/Frontend.cs
@@ -1,13 +1,7 @@
 /*
- * $Id: Frontend.cs 192 2007-04-22 11:48:12Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-GNOME/Frontend.cs $
- * $Rev: 192 $
- * $Author: meebey $
- * $Date: 2007-04-22 13:48:12 +0200 (Sun, 22 Apr 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2007 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2007, 2010-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -32,7 +26,7 @@ using System.Reflection;
 using System.Runtime.InteropServices;
 using Smuxi.Engine;
 using Smuxi.Common;
-using STFL = Stfl;
+using Stfl;
 
 namespace Smuxi.Frontend.Stfl
 {
@@ -128,10 +122,10 @@ namespace Smuxi.Frontend.Stfl
             }
         }
         
-        public static void Init(string[] args)
+        public static void Init(string engine)
         {
             System.Threading.Thread.CurrentThread.Name = "Main";
-            Trace.Call(args);
+            Trace.Call(engine);
            
             Assembly asm = Assembly.GetAssembly(typeof(Frontend));
             AssemblyName asm_name = asm.GetName(false);
@@ -141,7 +135,8 @@ namespace Smuxi.Frontend.Stfl
             _VersionNumber = asm_name.Version.ToString();
             _VersionString = pr.Product + " - " + _UIName + " frontend " + _Version;
 
-            //STFL.error_action("print");
+            // this always calls abort() :(((
+            //StflApi.stfl_error_action("print");
             
 #if LOG4NET
             _Logger.Info(_VersionString + " starting");
@@ -152,16 +147,14 @@ namespace Smuxi.Frontend.Stfl
             // loading and setting defaults
             _FrontendConfig.Load();
             _FrontendConfig.Save();
-           
+
             if (_FrontendConfig.IsCleanConfig) {
                 // first start assistant
             } else {
-                if (((string)FrontendConfig["Engines/Default"]).Length == 0) {
+                if (String.IsNullOrEmpty(engine) || engine == "local") {
                     InitLocalEngine();
                 } else {
-                    // there is a default engine set, means we want a remote engine
-                    //new EngineManagerDialog();
-                    InitLocalEngine();
+                    InitRemoteEngine(engine);
                 }
             }
             
@@ -187,6 +180,42 @@ namespace Smuxi.Frontend.Stfl
             ConnectEngineToGUI();
         }
         
+        public static void InitRemoteEngine(string engine)
+        {
+            var manager = new EngineManager(_FrontendConfig,
+                                            _MainWindow.UI);
+            try {
+                try {
+                    Console.WriteLine(
+                        _("Connecting to remote engine '{0}'..."), engine
+                    );
+                    manager.Connect(engine);
+                    Console.WriteLine(_("Connection established"));
+                } catch (Exception ex) {
+#if LOG4NET
+                    _Logger.Error(ex);
+#endif
+                    Console.WriteLine(
+                        _("Connection failed! Error: {1}"),
+                        engine,
+                        ex.Message
+                    );
+                    Environment.Exit(1);
+                }
+
+                _Session = manager.Session;
+                _UserConfig = manager.UserConfig;
+                _EngineVersion = manager.EngineVersion;
+                ConnectEngineToGUI();
+            } catch (Exception ex) {
+#if LOG4NET
+                _Logger.Error(ex);
+#endif
+                manager.Disconnect();
+                throw;
+            }
+        }
+
         public static void ConnectEngineToGUI()
         {
             _FrontendManager = _Session.GetFrontendManager(_MainWindow.UI);
@@ -233,5 +262,10 @@ namespace Smuxi.Frontend.Stfl
         {
             //Application.Error("Error occurred!", ex.ToString());
         }
+
+        static string _(string msg)
+        {
+            return Mono.Unix.Catalog.GetString(msg);
+        }
     }
 }
diff --git a/src/Frontend-STFL/Main.cs b/src/Frontend-STFL/Main.cs
index 466d27d..2e1a87d 100644
--- a/src/Frontend-STFL/Main.cs
+++ b/src/Frontend-STFL/Main.cs
@@ -1,13 +1,7 @@
 /*
- * $Id: Main.cs 183 2007-04-21 15:14:23Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-GNOME/Main.cs $
- * $Rev: 183 $
- * $Author: meebey $
- * $Date: 2007-04-21 17:14:23 +0200 (Sat, 21 Apr 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2007 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2007, 2010-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -28,6 +22,11 @@
 
 using System;
 using System.IO;
+using System.Reflection;
+using SysDiag = System.Diagnostics;
+using NDesk.Options;
+using Smuxi.Common;
+using Smuxi.Engine;
 
 namespace Smuxi.Frontend.Stfl
 { 
@@ -40,18 +39,120 @@ namespace Smuxi.Frontend.Stfl
         public static void Main(string[] args)
         {
 #if LOG4NET
-            //log4net.Config.BasicConfigurator.Configure();
-            FileInfo config = new FileInfo("smuxi-frontend-stfl.log.config");
-            log4net.Config.XmlConfigurator.Configure(config);
+            // initialize log level
+            log4net.Repository.ILoggerRepository repo = log4net.LogManager.GetRepository();
+            repo.Threshold = log4net.Core.Level.Error;
 #endif
+
+            bool debug = false;
+            bool listEngines = false;
+            string engine = "local";
+
+            InitLocale();
+
+            OptionSet parser = new OptionSet();
+
+            parser.Add(
+                "d|debug",
+                _("Enable debug output"),
+                delegate (string value) {
+                    debug = true;
+                }
+            );
+
+            parser.Add(
+                "e|engine=",
+                _("Engine to connect to"),
+                delegate (string value) {
+                    engine = value;
+                }
+            );
+
+            parser.Add(
+                "l|list-engines",
+                _("List available engines"),
+                delegate (string value) {
+                    listEngines = true;
+                }
+            );
+
+            parser.Add(
+                 "h|help",
+                 _("Show this help"),
+                 delegate(string value) {
+                    Console.WriteLine(_("Usage: smuxi-frontend-stfl [options]"));
+                    Console.WriteLine();
+                    Console.WriteLine(_("Options:"));
+                    parser.WriteOptionDescriptions(Console.Out);
+                    Environment.Exit(0);
+                 }
+            );
+
+            parser.Add(
+                 "<>",
+                delegate(string value) {
+                    throw new OptionException(
+                        String.Format(
+                            _("Unknown option: '{0}'"),
+                            value
+                        ),
+                        value
+                    );
+                }
+            );
+
             try {
-                Frontend.Init(args);
+                parser.Parse(args);
+#if LOG4NET
+                if (debug) {
+                    repo.Threshold = log4net.Core.Level.Debug;
+                }
+#endif
+            } catch (OptionException ex) {
+                Console.Error.WriteLine(_("Command line error: {0}"), ex.Message);
+                Environment.Exit(1);
+            }
+
+            if (listEngines) {
+                Console.WriteLine(_("Available Engines:"));
+                var config = new FrontendConfig(Frontend.UIName);
+                config.Load();
+                foreach (var entry in  (string[]) config["Engines/Engines"]) {
+                    Console.WriteLine("\t{0}", entry);
+                }
+                return;
+            }
+
+            try {
+                Frontend.Init(engine);
             } catch (Exception e) {
 #if LOG4NET
                 _Logger.Fatal(e);
 #endif
-                throw;
+                if (SysDiag.Debugger.IsAttached) {
+                    throw;
+                }
+            }
+        }
+
+        private static void InitLocale()
+        {
+            string appDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
+            string localeDir = Path.Combine(appDir, "locale");
+            if (!Directory.Exists(localeDir)) {
+                localeDir = Path.Combine(Defines.InstallPrefix, "share");
+                localeDir = Path.Combine(localeDir, "locale");
             }
+
+            LibraryCatalog.Init("smuxi-frontend-stfl", localeDir);
+#if LOG4NET
+            _Logger.Debug("Using locale data from: " + localeDir);
+#endif
+        }
+
+        static string _(string msg)
+        {
+            return Mono.Unix.Catalog.GetString(msg);
         }
     }
 }
diff --git a/src/Frontend-STFL/MainWindow.cs b/src/Frontend-STFL/MainWindow.cs
index 738bee2..b489290 100644
--- a/src/Frontend-STFL/MainWindow.cs
+++ b/src/Frontend-STFL/MainWindow.cs
@@ -1,13 +1,7 @@
 /*
- * $Id: MainWindow.cs 192 2007-04-22 11:48:12Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-GNOME/MainWindow.cs $
- * $Rev: 192 $
- * $Author: meebey $
- * $Date: 2007-04-22 13:48:12 +0200 (Sun, 22 Apr 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2007 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2007, 2010-2011 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -32,6 +26,7 @@ using System.Reflection;
 using Mono.Unix;
 using Smuxi.Common;
 using Smuxi.Engine;
+using Stfl;
 
 namespace Smuxi.Frontend.Stfl
 {
@@ -55,11 +50,29 @@ namespace Smuxi.Frontend.Stfl
                 return _UI;
             }
         }
-        
+
+        public string InputLabel {
+            get {
+                return this["input_label_text"];
+            }
+            set {
+                this["input_label_text"] = String.Format("{0} ", value);
+            }
+        }
+
+        public string NavigationLabel {
+            get {
+                return this["navigation_label_text"];
+            }
+            set {
+                this["navigation_label_text"] = value;
+            }
+        }
+
         public MainWindow() : base(null, "MainWindow.stfl")
         {
             _ChatViewManager = new ChatViewManager(this);
-            _Entry = new Entry(this);
+            _Entry = new Entry(this, _ChatViewManager);
             _UI = new StflUI(_ChatViewManager);
     	    Assembly asm = Assembly.GetExecutingAssembly();
     	    _ChatViewManager.Load(asm);
diff --git a/src/Frontend-STFL/MainWindow.stfl b/src/Frontend-STFL/MainWindow.stfl
index 2853fda..5ecc557 100644
--- a/src/Frontend-STFL/MainWindow.stfl
+++ b/src/Frontend-STFL/MainWindow.stfl
@@ -1,20 +1,45 @@
 vbox
   autobind:0
-  textview[output_textview]
-    .expand:vh
-    offset[output_textview_offset]:0
-    style_end:""
+  hbox[menu_hbox]
+    .expand:0 .height:1
+    @style_normal:fg=white,bg=blue
+    label
+      text:"Server"
+    label
+      text:"Chat"
+    label
+      text:"Engine"
+    label
+      text:"View"
+    label
+      text:"Help"
+  vbox[output_vbox]
   vbox[status]
     .expand:0 .height:1
     @style_normal:fg=white,bg=blue
     label
-      text:"Test"
+      text[navigation_label_text]:"Navigation"
   hbox[input_hbox]
     .expand:0 .height:1
-    label
+    label[input_label]
       .expand:0
-      text[input_label]:"[smuxi] "
+      text[input_label_text]:"[Chat] "
     !input[input]
       on_TAB:TAB
-      on_M4:alt4
+      on_^1:CTRL1
+      on_^2:CTRL2
+      on_^3:CTRL3
+      on_^4:CTRL4
+      on_^5:CTRL5
+      on_^6:CTRL6
+      on_^7:CTRL7
+      on_^8:CTRL8
+      on_^9:CTRL9
+      on_^0:CTRL0
+      on_^@:CTRL2
+      on_^]:CTRL5
+      on_^^:CTRL6
+      on_^_:CTRL7
+      on_^]:CTRL5
       text[input_text]:
+      pos[input_pos]:"0"
diff --git a/src/Frontend-STFL/Makefile.am b/src/Frontend-STFL/Makefile.am
index 7d72cf5..5eb8bc7 100644
--- a/src/Frontend-STFL/Makefile.am
+++ b/src/Frontend-STFL/Makefile.am
@@ -1,36 +1,11 @@
+SUBDIRS = STFL
 
 EXTRA_DIST =  
 
-# Warning: This is an automatically generated file, do not edit!
+ASSEMBLY_CONFIG_SOURCE = smuxi-frontend-stfl.exe.config
+ASSEMBLY_CONFIG = $(BUILD_DIR)/smuxi-frontend-stfl.exe.config
 
-if ENABLE_RELEASE
-ASSEMBLY_COMPILER_COMMAND = @MCS@
-ASSEMBLY_COMPILER_FLAGS =  -noconfig -codepage:utf8 -warn:4 -optimize+
-ASSEMBLY = ../../bin/release/smuxi-frontend-stfl.exe
-ASSEMBLY_MDB = 
-COMPILE_TARGET = exe
-PROJECT_REFERENCES =  \
-	../../bin/release/smuxi-engine.dll \
-	../../bin/release/smuxi-frontend.dll \
-	../../bin/release/smuxi-common.dll
-BUILD_DIR = ../../bin/release
-
-LOG4NET_DLL_SOURCE=../../lib/log4net.dll
-SMUXI_ENGINE_DLL_MDB=
-NINI_DLL_SOURCE=../../lib/Nini.dll
-SMUXI_ENGINE_DLL_SOURCE=../../bin/release/smuxi-engine.dll
-STFL_DLL_SOURCE=../../lib/Stfl.dll
-SMUXI_FRONTEND_DLL_MDB=
-SMUXI_FRONTEND_DLL_SOURCE=../../bin/release/smuxi-frontend.dll
-SMUXI_COMMON_DLL_SOURCE=../../bin/release/smuxi-common.dll
-
-endif
-
-if ENABLE_DEBUG
-ASSEMBLY_COMPILER_COMMAND = @MCS@
-ASSEMBLY_COMPILER_FLAGS =  -noconfig -codepage:utf8 -warn:4 -optimize+ -debug -define:DEBUG "-define:DEBUG,TRACE,LOG4NET"
-
-ASSEMBLY = ../../bin/debug/smuxi-frontend-stfl.exe
+ASSEMBLY = $(BUILD_DIR)/smuxi-frontend-stfl.exe
 ASSEMBLY_MDB = $(ASSEMBLY).mdb
 COMPILE_TARGET = exe
 PROJECT_REFERENCES =  \
@@ -50,26 +25,20 @@ SMUXI_FRONTEND_DLL_MDB=$(BUILD_DIR)/smuxi-frontend.dll.mdb
 SMUXI_FRONTEND_DLL_SOURCE=../../bin/debug/smuxi-frontend.dll
 SMUXI_COMMON_DLL_SOURCE=../../bin/debug/smuxi-common.dll
 
-endif
-
 AL=al2
 SATELLITE_ASSEMBLY_NAME=.resources.dll
 
 PROGRAMFILES = \
-	$(LOG4NET_DLL) \
 	$(SMUXI_ENGINE_DLL_MDB) \
-	$(NINI_DLL) \
 	$(SMUXI_ENGINE_DLL) \
-	$(STFL_DLL) \
 	$(SMUXI_FRONTEND_DLL_MDB) \
 	$(SMUXI_FRONTEND_DLL) \
-	$(SMUXI_COMMON_DLL)  
+	$(SMUXI_COMMON_DLL) \
+	$(ASSEMBLY_CONFIG)
 
 BINARIES = \
 	$(FRONTEND_STFL)  
 
-
-	
 all: $(ASSEMBLY) $(PROGRAMFILES) $(BINARIES) 
 
 FILES = \
@@ -81,7 +50,12 @@ FILES = \
 	StflUI.cs \
 	Entry.cs \
 	STFL/Form.cs \
+	STFL/EventReceivedEventArgs.cs \
 	STFL/KeyPressedEventArgs.cs \
+	STFL/NcursesApi.cs \
+	STFL/StflApi.cs \
+	STFL/TextView.cs \
+	STFL/Widget.cs \
 	ChatView.cs \
 	ChatViewManager.cs 
 
@@ -95,8 +69,7 @@ EXTRAS = \
 
 REFERENCES =  \
 	System \
-	Mono.Posix
-	$(STFL_LIBS) \
+	Mono.Posix \
 	$(LOG4NET_LIBS)
 
 DLL_REFERENCES = 
@@ -112,6 +85,15 @@ SMUXI_ENGINE_DLL = $(BUILD_DIR)/smuxi-engine.dll
 STFL_DLL = $(BUILD_DIR)/Stfl.dll
 SMUXI_FRONTEND_DLL = $(BUILD_DIR)/smuxi-frontend.dll
 SMUXI_COMMON_DLL = $(BUILD_DIR)/smuxi-common.dll
+LOG4NET_CONFIG = $(BUILD_DIR)/smuxi-frontend-stfl.exe.config
+LOG4NET_CONFIG_SOURCE = smuxi-frontend-stfl.exe.config
+build_datafiles = $(LOG4NET_CONFIG)
+
+if ENABLE_STATIC_STFL
+STFLSHARP_SO_SOURCE = $(builddir)/STFL/libstflsharp.so
+STFLSHARP_SO = $(BUILD_DIR)/libstflsharp.so
+build_datafiles += $(STFLSHARP_SO)
+endif
 
 $(eval $(call emit-deploy-wrapper,FRONTEND_STFL,smuxi-frontend-stfl,x))
 $(eval $(call emit-deploy-target,SMUXI_ENGINE_DLL_MDB))
@@ -119,7 +101,11 @@ $(eval $(call emit-deploy-target,SMUXI_ENGINE_DLL))
 $(eval $(call emit-deploy-target,SMUXI_FRONTEND_DLL_MDB))
 $(eval $(call emit-deploy-target,SMUXI_FRONTEND_DLL))
 $(eval $(call emit-deploy-target,SMUXI_COMMON_DLL))
-
+$(eval $(call emit-deploy-target,LOG4NET_CONFIG))
+$(eval $(call emit-deploy-target,ASSEMBLY_CONFIG))
+if ENABLE_STATIC_STFL
+$(eval $(call emit-deploy-target,STFLSHARP_SO))
+endif
 
 $(build_xamlg_list): %.xaml.g.cs: %.xaml
 	xamlg '$<'
@@ -129,4 +115,4 @@ $(build_resx_resources) : %.resources: %.resx
 
 $(ASSEMBLY) $(ASSEMBLY_MDB): $(build_sources) $(build_resources) $(build_datafiles) $(DLL_REFERENCES) $(PROJECT_REFERENCES) $(build_xamlg_list) $(build_satellite_assembly_list)
 	mkdir -p $(dir $(ASSEMBLY))
-	$(ASSEMBLY_COMPILER_COMMAND) $(ASSEMBLY_COMPILER_FLAGS) -out:$(ASSEMBLY) -target:$(COMPILE_TARGET) $(build_sources_embed) $(build_resources_embed) $(build_references_ref)
+	$(CSC) $(CSC_FLAGS) -out:$(ASSEMBLY) -target:$(COMPILE_TARGET) $(build_sources_embed) $(build_resources_embed) $(build_references_ref)
diff --git a/src/Frontend-STFL/Makefile.in b/src/Frontend-STFL/Makefile.in
index fd0503d..d83c919 100644
--- a/src/Frontend-STFL/Makefile.in
+++ b/src/Frontend-STFL/Makefile.in
@@ -38,11 +38,15 @@ host_triplet = @host@
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 	$(srcdir)/smuxi-frontend-stfl.in \
 	$(top_srcdir)/Makefile.include ChangeLog
+ at ENABLE_STATIC_STFL_TRUE@am__append_1 = $(STFLSHARP_SO)
 subdir = src/Frontend-STFL
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -77,12 +81,53 @@ am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibdir)" \
 SCRIPTS = $(bin_SCRIPTS) $(pkglib_SCRIPTS)
 SOURCES =
 DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-dvi-recursive install-exec-recursive \
+	install-html-recursive install-info-recursive \
+	install-pdf-recursive install-ps-recursive install-recursive \
+	installcheck-recursive installdirs-recursive pdf-recursive \
+	ps-recursive uninstall-recursive
 DATA = $(linuxdesktopapplications_DATA) $(linuxpkgconfig_DATA) \
 	$(programfiles_DATA) $(programfilesicons_DATA)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+	$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+	distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -96,13 +141,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -143,13 +201,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -157,6 +217,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -167,13 +228,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -187,13 +257,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -201,7 +277,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -216,10 +294,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -250,62 +331,40 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 twitter_api_key = @twitter_api_key@
+SUBDIRS = STFL
 EXTRA_DIST = $(build_sources) $(build_resx_files) \
 	$(build_others_files) $(ASSEMBLY_WRAPPER_IN) $(EXTRAS) \
 	$(DATA_FILES) $(build_culture_res_files)
- at ENABLE_DEBUG_TRUE@ASSEMBLY_COMPILER_COMMAND = @MCS@
-
-# Warning: This is an automatically generated file, do not edit!
- at ENABLE_RELEASE_TRUE@ASSEMBLY_COMPILER_COMMAND = @MCS@
- at ENABLE_DEBUG_TRUE@ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+ -debug -define:DEBUG "-define:DEBUG,TRACE,LOG4NET"
- at ENABLE_RELEASE_TRUE@ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+
- at ENABLE_DEBUG_TRUE@ASSEMBLY = ../../bin/debug/smuxi-frontend-stfl.exe
- at ENABLE_RELEASE_TRUE@ASSEMBLY = ../../bin/release/smuxi-frontend-stfl.exe
- at ENABLE_DEBUG_TRUE@ASSEMBLY_MDB = $(ASSEMBLY).mdb
- at ENABLE_RELEASE_TRUE@ASSEMBLY_MDB = 
- at ENABLE_DEBUG_TRUE@COMPILE_TARGET = exe
- at ENABLE_RELEASE_TRUE@COMPILE_TARGET = exe
- at ENABLE_DEBUG_TRUE@PROJECT_REFERENCES = \
- at ENABLE_DEBUG_TRUE@	../../bin/debug/smuxi-engine.dll \
- at ENABLE_DEBUG_TRUE@	../../bin/debug/smuxi-frontend.dll \
- at ENABLE_DEBUG_TRUE@	../../bin/debug/smuxi-common.dll
-
- at ENABLE_RELEASE_TRUE@PROJECT_REFERENCES = \
- at ENABLE_RELEASE_TRUE@	../../bin/release/smuxi-engine.dll \
- at ENABLE_RELEASE_TRUE@	../../bin/release/smuxi-frontend.dll \
- at ENABLE_RELEASE_TRUE@	../../bin/release/smuxi-common.dll
-
- at ENABLE_DEBUG_TRUE@BUILD_DIR = ../../bin/debug
- at ENABLE_RELEASE_TRUE@BUILD_DIR = ../../bin/release
- at ENABLE_DEBUG_TRUE@LOG4NET_DLL_SOURCE = ../../lib/log4net.dll
- at ENABLE_RELEASE_TRUE@LOG4NET_DLL_SOURCE = ../../lib/log4net.dll
- at ENABLE_DEBUG_TRUE@SMUXI_ENGINE_DLL_MDB = $(BUILD_DIR)/smuxi-engine.dll.mdb
- at ENABLE_RELEASE_TRUE@SMUXI_ENGINE_DLL_MDB = 
- at ENABLE_DEBUG_TRUE@NINI_DLL_SOURCE = ../../lib/Nini.dll
- at ENABLE_RELEASE_TRUE@NINI_DLL_SOURCE = ../../lib/Nini.dll
- at ENABLE_DEBUG_TRUE@SMUXI_ENGINE_DLL_SOURCE = ../../bin/debug/smuxi-engine.dll
- at ENABLE_RELEASE_TRUE@SMUXI_ENGINE_DLL_SOURCE = ../../bin/release/smuxi-engine.dll
- at ENABLE_DEBUG_TRUE@STFL_DLL_SOURCE = ../../lib/Stfl.dll
- at ENABLE_RELEASE_TRUE@STFL_DLL_SOURCE = ../../lib/Stfl.dll
- at ENABLE_DEBUG_TRUE@SMUXI_FRONTEND_DLL_MDB = $(BUILD_DIR)/smuxi-frontend.dll.mdb
- at ENABLE_RELEASE_TRUE@SMUXI_FRONTEND_DLL_MDB = 
- at ENABLE_DEBUG_TRUE@SMUXI_FRONTEND_DLL_SOURCE = ../../bin/debug/smuxi-frontend.dll
- at ENABLE_RELEASE_TRUE@SMUXI_FRONTEND_DLL_SOURCE = ../../bin/release/smuxi-frontend.dll
- at ENABLE_DEBUG_TRUE@SMUXI_COMMON_DLL_SOURCE = ../../bin/debug/smuxi-common.dll
- at ENABLE_RELEASE_TRUE@SMUXI_COMMON_DLL_SOURCE = ../../bin/release/smuxi-common.dll
- at ENABLE_DEBUG_TRUE@SMUXI_ENGINE_DLL_MDB_SOURCE = ../../bin/debug/smuxi-engine.dll.mdb
- at ENABLE_DEBUG_TRUE@SMUXI_FRONTEND_DLL_MDB_SOURCE = ../../bin/debug/smuxi-frontend.dll.mdb
+ASSEMBLY_CONFIG_SOURCE = smuxi-frontend-stfl.exe.config
+ASSEMBLY_CONFIG = $(BUILD_DIR)/smuxi-frontend-stfl.exe.config
+ASSEMBLY = $(BUILD_DIR)/smuxi-frontend-stfl.exe
+ASSEMBLY_MDB = $(ASSEMBLY).mdb
+COMPILE_TARGET = exe
+PROJECT_REFERENCES = \
+	../../bin/debug/smuxi-engine.dll \
+	../../bin/debug/smuxi-frontend.dll \
+	../../bin/debug/smuxi-common.dll
+
+BUILD_DIR = ../../bin/debug
+LOG4NET_DLL_SOURCE = ../../lib/log4net.dll
+SMUXI_ENGINE_DLL_MDB_SOURCE = ../../bin/debug/smuxi-engine.dll.mdb
+SMUXI_ENGINE_DLL_MDB = $(BUILD_DIR)/smuxi-engine.dll.mdb
+NINI_DLL_SOURCE = ../../lib/Nini.dll
+SMUXI_ENGINE_DLL_SOURCE = ../../bin/debug/smuxi-engine.dll
+STFL_DLL_SOURCE = ../../lib/Stfl.dll
+SMUXI_FRONTEND_DLL_MDB_SOURCE = ../../bin/debug/smuxi-frontend.dll.mdb
+SMUXI_FRONTEND_DLL_MDB = $(BUILD_DIR)/smuxi-frontend.dll.mdb
+SMUXI_FRONTEND_DLL_SOURCE = ../../bin/debug/smuxi-frontend.dll
+SMUXI_COMMON_DLL_SOURCE = ../../bin/debug/smuxi-common.dll
 AL = al2
 SATELLITE_ASSEMBLY_NAME = .resources.dll
 PROGRAMFILES = \
-	$(LOG4NET_DLL) \
 	$(SMUXI_ENGINE_DLL_MDB) \
-	$(NINI_DLL) \
 	$(SMUXI_ENGINE_DLL) \
-	$(STFL_DLL) \
 	$(SMUXI_FRONTEND_DLL_MDB) \
 	$(SMUXI_FRONTEND_DLL) \
-	$(SMUXI_COMMON_DLL)  
+	$(SMUXI_COMMON_DLL) \
+	$(ASSEMBLY_CONFIG)
 
 BINARIES = \
 	$(FRONTEND_STFL)  
@@ -319,7 +378,12 @@ FILES = \
 	StflUI.cs \
 	Entry.cs \
 	STFL/Form.cs \
+	STFL/EventReceivedEventArgs.cs \
 	STFL/KeyPressedEventArgs.cs \
+	STFL/NcursesApi.cs \
+	STFL/StflApi.cs \
+	STFL/TextView.cs \
+	STFL/Widget.cs \
 	ChatView.cs \
 	ChatViewManager.cs 
 
@@ -332,7 +396,8 @@ EXTRAS = \
 
 REFERENCES = \
 	System \
-	Mono.Posix
+	Mono.Posix \
+	$(LOG4NET_LIBS)
 
 DLL_REFERENCES = 
 CLEANFILES = $(PROGRAMFILES) $(BINARIES) $(ASSEMBLY) $(ASSEMBLY).mdb \
@@ -367,7 +432,7 @@ build_references_ref = $(foreach ref, $(REFERENCES), $(if $(filter \
 	-pkg:%, $(ref)), $(ref), $(if $(filter -r:%, $(ref)), $(ref), \
 	-r:$(ref)))) $(foreach ref, $(DLL_REFERENCES), -r:$(ref)) \
 	$(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
 programfilesdir = @libdir@/@PACKAGE@
@@ -393,7 +458,12 @@ SMUXI_ENGINE_DLL = $(BUILD_DIR)/smuxi-engine.dll
 STFL_DLL = $(BUILD_DIR)/Stfl.dll
 SMUXI_FRONTEND_DLL = $(BUILD_DIR)/smuxi-frontend.dll
 SMUXI_COMMON_DLL = $(BUILD_DIR)/smuxi-common.dll
-all: all-am
+LOG4NET_CONFIG = $(BUILD_DIR)/smuxi-frontend-stfl.exe.config
+LOG4NET_CONFIG_SOURCE = smuxi-frontend-stfl.exe.config
+build_datafiles = $(LOG4NET_CONFIG) $(am__append_1)
+ at ENABLE_STATIC_STFL_TRUE@STFLSHARP_SO_SOURCE = $(builddir)/STFL/libstflsharp.so
+ at ENABLE_STATIC_STFL_TRUE@STFLSHARP_SO = $(BUILD_DIR)/libstflsharp.so
+all: all-recursive
 
 .SUFFIXES:
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/Makefile.include $(am__configure_deps)
@@ -496,6 +566,12 @@ uninstall-pkglibSCRIPTS:
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(linuxdesktopapplicationsdir)" || $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)"
@@ -576,12 +652,141 @@ uninstall-programfilesiconsDATA:
 	test -n "$$files" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(programfilesiconsdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(programfilesiconsdir)" && rm -f $$files
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@fail= failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+	@fail= failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
 tags: TAGS
-TAGS:
 
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
 ctags: CTAGS
-CTAGS:
-
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
 distdir: $(DISTFILES)
 	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@@ -613,22 +818,51 @@ distdir: $(DISTFILES)
 	    || exit 1; \
 	  fi; \
 	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(MKDIR_P) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
 check-am: all-am
-check: check-am
+check: check-recursive
 all-am: Makefile $(SCRIPTS) $(DATA)
-installdirs:
+installdirs: installdirs-recursive
+installdirs-am:
 	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(linuxdesktopapplicationsdir)" "$(DESTDIR)$(linuxpkgconfigdir)" "$(DESTDIR)$(programfilesdir)" "$(DESTDIR)$(programfilesiconsdir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
 
 install-am: all-am
 	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
 
-installcheck: installcheck-am
+installcheck: installcheck-recursive
 install-strip:
 	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
 	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
@@ -647,23 +881,23 @@ distclean-generic:
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
+clean: clean-recursive
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
-distclean: distclean-am
+distclean: distclean-recursive
 	-rm -f Makefile
-distclean-am: clean-am distclean-generic
+distclean-am: clean-am distclean-generic distclean-tags
 
-dvi: dvi-am
+dvi: dvi-recursive
 
 dvi-am:
 
-html: html-am
+html: html-recursive
 
 html-am:
 
-info: info-am
+info: info-recursive
 
 info-am:
 
@@ -671,45 +905,45 @@ install-data-am: install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-programfilesDATA \
 	install-programfilesiconsDATA
 
-install-dvi: install-dvi-am
+install-dvi: install-dvi-recursive
 
 install-dvi-am:
 
 install-exec-am: install-binSCRIPTS install-pkglibSCRIPTS
 
-install-html: install-html-am
+install-html: install-html-recursive
 
 install-html-am:
 
-install-info: install-info-am
+install-info: install-info-recursive
 
 install-info-am:
 
 install-man:
 
-install-pdf: install-pdf-am
+install-pdf: install-pdf-recursive
 
 install-pdf-am:
 
-install-ps: install-ps-am
+install-ps: install-ps-recursive
 
 install-ps-am:
 
 installcheck-am:
 
-maintainer-clean: maintainer-clean-am
+maintainer-clean: maintainer-clean-recursive
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
-mostlyclean: mostlyclean-am
+mostlyclean: mostlyclean-recursive
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
-pdf: pdf-am
+pdf: pdf-recursive
 
 pdf-am:
 
-ps: ps-am
+ps: ps-recursive
 
 ps-am:
 
@@ -718,28 +952,31 @@ uninstall-am: uninstall-binSCRIPTS \
 	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
 	uninstall-programfilesDATA uninstall-programfilesiconsDATA
 
-.MAKE: install-am install-strip
-
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binSCRIPTS install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-linuxdesktopapplicationsDATA \
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+	install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+	all all-am check check-am clean clean-generic clean-libtool \
+	ctags ctags-recursive distclean distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-binSCRIPTS \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am \
+	install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-man install-pdf \
 	install-pdf-am install-pkglibSCRIPTS install-programfilesDATA \
 	install-programfilesiconsDATA install-ps install-ps-am \
 	install-strip installcheck installcheck-am installdirs \
-	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am tags tags-recursive uninstall uninstall-am \
 	uninstall-binSCRIPTS uninstall-linuxdesktopapplicationsDATA \
 	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
 	uninstall-programfilesDATA uninstall-programfilesiconsDATA
 
 
 all: $(ASSEMBLY) $(PROGRAMFILES) $(BINARIES) 
-	$(STFL_LIBS) \
-	$(LOG4NET_LIBS)
 
 # macros
 
@@ -774,6 +1011,9 @@ $(eval $(call emit-deploy-target,SMUXI_ENGINE_DLL))
 $(eval $(call emit-deploy-target,SMUXI_FRONTEND_DLL_MDB))
 $(eval $(call emit-deploy-target,SMUXI_FRONTEND_DLL))
 $(eval $(call emit-deploy-target,SMUXI_COMMON_DLL))
+$(eval $(call emit-deploy-target,LOG4NET_CONFIG))
+$(eval $(call emit-deploy-target,ASSEMBLY_CONFIG))
+ at ENABLE_STATIC_STFL_TRUE@$(eval $(call emit-deploy-target,STFLSHARP_SO))
 
 $(build_xamlg_list): %.xaml.g.cs: %.xaml
 	xamlg '$<'
@@ -783,7 +1023,7 @@ $(build_resx_resources) : %.resources: %.resx
 
 $(ASSEMBLY) $(ASSEMBLY_MDB): $(build_sources) $(build_resources) $(build_datafiles) $(DLL_REFERENCES) $(PROJECT_REFERENCES) $(build_xamlg_list) $(build_satellite_assembly_list)
 	mkdir -p $(dir $(ASSEMBLY))
-	$(ASSEMBLY_COMPILER_COMMAND) $(ASSEMBLY_COMPILER_FLAGS) -out:$(ASSEMBLY) -target:$(COMPILE_TARGET) $(build_sources_embed) $(build_resources_embed) $(build_references_ref)
+	$(CSC) $(CSC_FLAGS) -out:$(ASSEMBLY) -target:$(COMPILE_TARGET) $(build_sources_embed) $(build_resources_embed) $(build_references_ref)
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/Frontend-STFL/STFL/EventReceivedEventArgs.cs b/src/Frontend-STFL/STFL/EventReceivedEventArgs.cs
new file mode 100644
index 0000000..c243229
--- /dev/null
+++ b/src/Frontend-STFL/STFL/EventReceivedEventArgs.cs
@@ -0,0 +1,34 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2011 Mirco Bauer
+// 
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+// 
+// 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
+
+using System;
+
+namespace Stfl
+{
+    public class EventReceivedEventArgs : EventArgs
+    {
+        public string Event { get; set; }
+
+        public EventReceivedEventArgs(string @event)
+        {
+            Event = @event;
+        }
+    }
+}
diff --git a/src/Frontend-STFL/STFL/Form.cs b/src/Frontend-STFL/STFL/Form.cs
index 802f305..4b38744 100644
--- a/src/Frontend-STFL/STFL/Form.cs
+++ b/src/Frontend-STFL/STFL/Form.cs
@@ -28,67 +28,78 @@
 
 using System;
 using System.IO;
+using System.Text;
+using System.Runtime.InteropServices;
 using System.Reflection;
-//using Stfl;
-using Smuxi.Common;
 
-namespace Smuxi.Frontend.Stfl
+namespace Stfl
 {
     public class Form : IDisposable
     {
-        private stfl_form _StflForm;
+        IntPtr f_Handle;
         
         public event KeyPressedEventHandler KeyPressed;
+        public event EventHandler<EventReceivedEventArgs> EventReceived;
         
         public string this[string name] {
             get {
-                return _StflForm.get(name);
+                return StflApi.stfl_get(f_Handle, name);
             }
             set {
-                _StflForm.set(name, value);
+                StflApi.stfl_set(f_Handle, name, value);
             }
         }
-        
+
         public Form(string text)
         {
-            _CreateForm(text);
+            f_Handle = StflApi.stfl_create(text);
+
+            // initialize ncurses
+            StflApi.stfl_run(f_Handle, -3);
+            //StflApi.raw();
+            NcursesApi.nocbreak();
         }
-        
+
         public Form(Assembly assembly, string resourceName)
         {
             if (assembly == null) {
                 assembly = Assembly.GetCallingAssembly();
             }
 
-            using (Stream str = assembly.GetManifestResourceStream(resourceName)) {
-                if (str == null) {
+            using (Stream stream = assembly.GetManifestResourceStream(resourceName))
+            using (StreamReader reader = new StreamReader(stream)) {
+                if (stream == null) {
                     throw new ArgumentException(resourceName + " could not be found in assembly", "resourceName");
                 }
-                StreamReader reader = new StreamReader(str);
                 string text = reader.ReadToEnd();
-                reader.Dispose();
-                _CreateForm(text);
+                if (String.IsNullOrEmpty(text)) {
+                    throw new ArgumentException(resourceName + " in assembly is missing or empty.", "resourceName");
+                }
+                f_Handle = StflApi.stfl_create(text);
             }
         }
-        
-        private void _CreateForm(string text)
+
+        ~Form()
         {
-            _StflForm = new stfl_form(text);
+            Dispose(false);
         }
 
-        private void _DestroyForm()
+        protected virtual void Dispose(bool disposing)
         {
-            _StflForm.Dispose();
+            if (f_Handle != IntPtr.Zero) {
+                StflApi.stfl_free(f_Handle);
+            }
         }
-        
+
         public virtual void Dispose()
         {
-            _DestroyForm();
+            Dispose(true);
+            GC.SuppressFinalize(this);
         }
-        
+
         public virtual void Run(int timeout)
         {
-            string @event = _StflForm.run(timeout);
+            string @event = StflApi.stfl_run(f_Handle, timeout);
             ProcessEvent(@event);
         }
 
@@ -96,27 +107,38 @@ namespace Smuxi.Frontend.Stfl
         {
             Run(0);
         }
-        
+
         public void Modify(string name, string mode, string text)
         {
-            _StflForm.modify(name, mode, text);
+            StflApi.stfl_modify(f_Handle, name, mode, text);
         }
-        
-        protected virtual void ProcessEvent(string key)
+
+        public string Dump(string name, string prefix, int focus)
         {
-            if (key != null && key != "TIMEOUT") {
-                ProcessKey(key);
+            return StflApi.stfl_dump(f_Handle, name, prefix, focus);
+        }
+
+        protected virtual void ProcessEvent(string @event)
+        {
+            OnEventReceived(new EventReceivedEventArgs(@event));
+            if (@event != null && @event != "TIMEOUT") {
+                ProcessKey(@event);
             }
         }
-        
+
+        protected virtual void OnEventReceived(EventReceivedEventArgs e)
+        {
+            if (EventReceived != null) {
+                EventReceived(this, e);
+            }
+        }
+
         protected virtual void ProcessKey(string key)
         {
-            Trace.Call(key);
-            
-            string focus = _StflForm.get_focus();
+            string focus = StflApi.stfl_get_focus(f_Handle);
             OnKeyPressed(new KeyPressedEventArgs(key, focus));
         }
-        
+
         protected virtual void OnKeyPressed(KeyPressedEventArgs e)
         {
             if (KeyPressed != null) {
diff --git a/src/Frontend-STFL/STFL/KeyPressedEventArgs.cs b/src/Frontend-STFL/STFL/KeyPressedEventArgs.cs
index e5c448a..cd2b23c 100644
--- a/src/Frontend-STFL/STFL/KeyPressedEventArgs.cs
+++ b/src/Frontend-STFL/STFL/KeyPressedEventArgs.cs
@@ -28,7 +28,7 @@
 
 using System;
 
-namespace Smuxi.Frontend.Stfl
+namespace Stfl
 {
     public delegate void KeyPressedEventHandler(object sender, KeyPressedEventArgs e);
     
diff --git a/src/Frontend-STFL/STFL/Makefile.am b/src/Frontend-STFL/STFL/Makefile.am
new file mode 100644
index 0000000..0fddfab
--- /dev/null
+++ b/src/Frontend-STFL/STFL/Makefile.am
@@ -0,0 +1,12 @@
+if ENABLE_STATIC_STFL
+STFL_STATIC_LIB = /usr/lib/libstfl.a
+LIB_FILE = libstflsharp.so
+OBJ_FILES = $(wildcard *.o)
+CLEANFILES =  $(LIB_FILE) $(OBJ_FILES)
+
+all: $(LIB_FILE)
+
+$(LIB_FILE): $(OBJ_FILES) 
+	$(AR) -x $(STFL_STATIC_LIB)
+	$(LD) -o $(LIB_FILE) -shared -lncursesw -lpthread $(OBJ_FILES)
+endif
diff --git a/src/Frontend-STFL/STFL/Makefile.in b/src/Frontend-STFL/STFL/Makefile.in
new file mode 100644
index 0000000..fa56b03
--- /dev/null
+++ b/src/Frontend-STFL/STFL/Makefile.in
@@ -0,0 +1,458 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/Frontend-STFL/STFL
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CSC = @CSC@
+CSC_FLAGS = @CSC_FLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GETTEXT_PACKAGE_ENGINE = @GETTEXT_PACKAGE_ENGINE@
+GETTEXT_PACKAGE_ENGINE_IRC = @GETTEXT_PACKAGE_ENGINE_IRC@
+GETTEXT_PACKAGE_ENGINE_MNSP = @GETTEXT_PACKAGE_ENGINE_MNSP@
+GETTEXT_PACKAGE_ENGINE_OSCAR = @GETTEXT_PACKAGE_ENGINE_OSCAR@
+GETTEXT_PACKAGE_ENGINE_TWITTER = @GETTEXT_PACKAGE_ENGINE_TWITTER@
+GETTEXT_PACKAGE_ENGINE_XMPP = @GETTEXT_PACKAGE_ENGINE_XMPP@
+GETTEXT_PACKAGE_FRONTEND = @GETTEXT_PACKAGE_FRONTEND@
+GETTEXT_PACKAGE_FRONTEND_CURSES = @GETTEXT_PACKAGE_FRONTEND_CURSES@
+GETTEXT_PACKAGE_FRONTEND_GNOME = @GETTEXT_PACKAGE_FRONTEND_GNOME@
+GETTEXT_PACKAGE_FRONTEND_GNOME_IRC = @GETTEXT_PACKAGE_FRONTEND_GNOME_IRC@
+GETTEXT_PACKAGE_FRONTEND_GNOME_XMPP = @GETTEXT_PACKAGE_FRONTEND_GNOME_XMPP@
+GETTEXT_PACKAGE_FRONTEND_STFL = @GETTEXT_PACKAGE_FRONTEND_STFL@
+GETTEXT_PACKAGE_FRONTEND_SWF = @GETTEXT_PACKAGE_FRONTEND_SWF@
+GETTEXT_PACKAGE_FRONTEND_WPF = @GETTEXT_PACKAGE_FRONTEND_WPF@
+GETTEXT_PACKAGE_SERVER = @GETTEXT_PACKAGE_SERVER@
+GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
+GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
+GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
+GLIB_SHARP_20_LIBS = @GLIB_SHARP_20_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+GTK_SHARP_20_CFLAGS = @GTK_SHARP_20_CFLAGS@
+GTK_SHARP_20_LIBS = @GTK_SHARP_20_LIBS@
+INDICATE_SHARP_CFLAGS = @INDICATE_SHARP_CFLAGS@
+INDICATE_SHARP_LIBS = @INDICATE_SHARP_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
+LOG4NET_LIBS = @LOG4NET_LIBS@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MCS = @MCS@
+MKDIR_P = @MKDIR_P@
+MONO = @MONO@
+MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
+MONO_MODULE_LIBS = @MONO_MODULE_LIBS@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
+MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
+NINI_CFLAGS = @NINI_CFLAGS@
+NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
+NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
+OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dist_version = @dist_version@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+twitter_api_key = @twitter_api_key@
+ at ENABLE_STATIC_STFL_TRUE@STFL_STATIC_LIB = /usr/lib/libstfl.a
+ at ENABLE_STATIC_STFL_TRUE@LIB_FILE = libstflsharp.so
+ at ENABLE_STATIC_STFL_TRUE@OBJ_FILES = $(wildcard *.o)
+ at ENABLE_STATIC_STFL_TRUE@CLEANFILES = $(LIB_FILE) $(OBJ_FILES)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Frontend-STFL/STFL/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign src/Frontend-STFL/STFL/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am
+
+
+ at ENABLE_STATIC_STFL_TRUE@all: $(LIB_FILE)
+
+ at ENABLE_STATIC_STFL_TRUE@$(LIB_FILE): $(OBJ_FILES) 
+ at ENABLE_STATIC_STFL_TRUE@	$(AR) -x $(STFL_STATIC_LIB)
+ at ENABLE_STATIC_STFL_TRUE@	$(LD) -o $(LIB_FILE) -shared -lncursesw -lpthread $(OBJ_FILES)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/Frontend-STFL/STFL/NcursesApi.cs b/src/Frontend-STFL/STFL/NcursesApi.cs
new file mode 100644
index 0000000..4a9e0f1
--- /dev/null
+++ b/src/Frontend-STFL/STFL/NcursesApi.cs
@@ -0,0 +1,36 @@
+// $Id$
+// 
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2010 Mirco Bauer <meebey at meebey.net>
+// 
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+// 
+// 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
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Stfl
+{
+    internal static class NcursesApi
+    {
+        [DllImport("ncurses")]
+        public static extern void raw();
+
+        [DllImport("ncurses")]
+        public static extern void nocbreak();
+    }
+}
diff --git a/src/Frontend-STFL/STFL/StflApi.cs b/src/Frontend-STFL/STFL/StflApi.cs
new file mode 100644
index 0000000..4522e7c
--- /dev/null
+++ b/src/Frontend-STFL/STFL/StflApi.cs
@@ -0,0 +1,216 @@
+/*
+ * Smuxi - Smart MUltipleXed Irc
+ *
+ * Copyright (c) 2010 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2010 Andrius Bentkus <Andrius.Bentkus at rwth-aachen.de>
+ *
+ * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+ *
+ * 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
+ */
+
+using System;
+using System.Text;
+using System.Runtime.InteropServices;
+using Mono.Unix;
+
+namespace Stfl
+{
+    internal class StflApi
+    {
+#if LOG4NET
+        private static readonly log4net.ILog f_Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+#endif
+        static bool IsXterm { get; set; }
+        static bool IsUtf8Locale { get; set; }
+        static string EscapeLessThanCharacter  { get; set; }
+        static string EscapeGreaterThanCharacter { get; set; }
+
+        static StflApi()
+        {
+            IsXterm = Environment.GetEnvironmentVariable("TERM") == "xterm";
+            // detect UTF-8 locale according to:
+            // http://www.cl.cam.ac.uk/~mgk25/unicode.html#activate
+            var locale = Environment.GetEnvironmentVariable("LC_ALL") ??
+                         Environment.GetEnvironmentVariable("LC_LCTYPE") ??
+                         Environment.GetEnvironmentVariable("LANG") ??
+                         String.Empty;
+            locale = locale.ToUpperInvariant();
+            IsUtf8Locale = locale.Contains("UTF-8") || locale.Contains("UTF8");
+
+            EscapeLessThanCharacter = "<>";
+            EscapeGreaterThanCharacter = ">";
+        }
+
+        public static IntPtr ToUnixWideCharacters(string text)
+        {
+            if (text == null) {
+                return IntPtr.Zero;
+            }
+            return UnixMarshal.StringToHeap(text, Encoding.UTF32);
+        }
+
+        public static string FromUnixWideCharacters(IntPtr text)
+        {
+            if (text == IntPtr.Zero) {
+                return null;
+            }
+            return UnixMarshal.PtrToString(text, Encoding.UTF32);
+        }
+
+        public static string EscapeRichText(string text)
+        {
+            text = text.Replace("<", EscapeLessThanCharacter);
+            text = text.Replace(">", EscapeGreaterThanCharacter);
+            return text;
+        }
+
+        [DllImport("stfl")]
+        static extern IntPtr stfl_create(IntPtr text);
+        internal static IntPtr stfl_create(string text)
+        {
+            return stfl_create(ToUnixWideCharacters(text));
+        }
+
+        [DllImport("stfl")]
+        internal static extern void stfl_free(IntPtr form);
+
+        [DllImport("stfl", EntryPoint = "stfl_run")]
+        static extern IntPtr stfl_run_native(IntPtr form, int timeout);
+        internal static string stfl_run(IntPtr form, int timeout)
+        {
+            IntPtr res = stfl_run_native(form, timeout);
+            if (res == IntPtr.Zero) {
+                return null;
+            }
+            return UnixMarshal.PtrToString(res, Encoding.UTF32);
+        }
+
+        [DllImport("stfl")]
+        internal static extern void stfl_reset();
+
+        [DllImport("stfl")]
+        static extern IntPtr stfl_get(IntPtr form, IntPtr name);
+        internal static string stfl_get(IntPtr form, string text)
+        {
+            return FromUnixWideCharacters(
+                stfl_get(form, ToUnixWideCharacters(text))
+            );
+        }
+
+        [DllImport("stfl")]
+        static extern void stfl_set(IntPtr form, IntPtr name, IntPtr value);
+        internal static void stfl_set(IntPtr form, string name, string value)
+        {
+            stfl_set(form, ToUnixWideCharacters(name),
+                     ToUnixWideCharacters(value));
+        }
+        
+        [DllImport("stfl", EntryPoint = "stfl_get_focus")]
+        static extern IntPtr stfl_get_focus_native(IntPtr form);
+        internal static string stfl_get_focus(IntPtr form)
+        {
+            IntPtr res = stfl_get_focus_native(form);
+            if (res == IntPtr.Zero) {
+                return null;
+            }
+            return UnixMarshal.PtrToString(res, Encoding.UTF32);
+        }
+        
+        [DllImport("stfl")]
+        static extern void stfl_set_focus(IntPtr form, IntPtr name);
+        internal static void stfl_set_focus(IntPtr form, string name)
+        {
+            stfl_set_focus(form, ToUnixWideCharacters(name));
+        }
+
+        [DllImport("stfl")]
+        static extern IntPtr stfl_quote(IntPtr text);
+        internal static string stfl_quote(string text) {
+            return FromUnixWideCharacters(
+                stfl_quote(ToUnixWideCharacters(text))
+            );
+        }
+
+        [DllImport("stfl")]
+        static extern IntPtr stfl_dump(IntPtr form, IntPtr name, IntPtr prefix,
+                                       int focus);
+        internal static string stfl_dump(IntPtr form, string name,
+                                         string prefix, int focus)
+        {
+            return FromUnixWideCharacters(
+                    stfl_dump(form, ToUnixWideCharacters(name),
+                              ToUnixWideCharacters(prefix), focus)
+            );
+        }
+
+        [DllImport("stfl")]
+        static extern void stfl_modify(IntPtr form, IntPtr name, IntPtr mode,
+                                       IntPtr text);
+        internal static void stfl_modify(IntPtr form, string name, string mode,
+                                         string text)
+        {
+            stfl_modify(form, ToUnixWideCharacters(name),
+                        ToUnixWideCharacters(mode),
+                        ToUnixWideCharacters(text));
+        }
+
+        [DllImport("stfl")]
+        static extern IntPtr stfl_lookup(IntPtr form, IntPtr path,
+                                         IntPtr newname);
+        internal static string stfl_lookup(IntPtr form, string path,
+                                           string newname)
+        {
+            return FromUnixWideCharacters(
+                stfl_lookup(form, ToUnixWideCharacters(path),
+                            ToUnixWideCharacters(newname))
+            );
+        }
+
+        [DllImport("stfl", EntryPoint = "stfl_error")]
+        static extern IntPtr stfl_error_native();
+        internal static string stfl_error()
+        {
+            return FromUnixWideCharacters(stfl_error_native());
+        }
+
+        [DllImport("stfl")]
+        static extern void stfl_error_action(IntPtr mode);
+        internal static void stfl_error_action(string mode)
+        {
+            stfl_error_action(ToUnixWideCharacters(mode));
+        }
+
+        /*
+        [DllImport("stfl")]
+        internal static extern IntPtr stfl_ipool_create(IntPtr code);
+
+        [DllImport("stfl")]
+        internal static extern IntPtr stfl_ipool_add(IntPtr pool, IntPtr data);
+
+        [DllImport("stfl")]
+        internal static extern IntPtr stfl_ipool_towc(IntPtr pool, IntPtr buf);
+
+        [DllImport("stfl")]
+        internal static extern IntPtr stfl_ipool_fromwc(IntPtr pool, IntPtr buf);
+
+        [DllImport("stfl")]
+        internal static extern void stfl_ipool_flush(IntPtr pool);
+
+        [DllImport("stfl")]
+        internal static extern void stfl_ipool_destroy(IntPtr pool);
+        */
+    }       
+}
diff --git a/src/Frontend-STFL/STFL/TextView.cs b/src/Frontend-STFL/STFL/TextView.cs
new file mode 100644
index 0000000..3590f8f
--- /dev/null
+++ b/src/Frontend-STFL/STFL/TextView.cs
@@ -0,0 +1,230 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2011 Mirco Bauer
+// 
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+// 
+// 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
+
+using System;
+using System.Text;
+using System.Collections.Generic;
+
+namespace Stfl
+{
+    public class TextView : Widget
+    {
+        public string OffsetVariableName { get; set; }
+        public bool AutoLineWrap { get; set; }
+        List<string> Lines { get; set; }
+        int WrappedLineCount { get; set; }
+
+        public int Offset {
+            get {
+                var offset = Form[OffsetVariableName];
+                if (String.IsNullOrEmpty(offset)) {
+                    return -1;
+                }
+                return Int32.Parse(offset);
+            }
+            set {
+                var minOffset = OffsetStart;
+                var maxOffset = OffsetEnd;
+                if (value == -1) {
+                    value = maxOffset;
+                 } else if (value > maxOffset) {
+                    value = maxOffset;
+                } else if (value < minOffset) {
+                    value = minOffset;
+                }
+                Form[OffsetVariableName] = value.ToString();
+            }
+        }
+
+        public int OffsetStart {
+            get {
+                return 0;
+            }
+        }
+
+        public int OffsetEnd {
+            get {
+                int heigth = Heigth;
+                if (WrappedLineCount <= heigth) {
+                    return 0;
+                }
+                return WrappedLineCount - heigth;
+            }
+        }
+
+        public TextView(Form form, string widgetId) :
+                   base(form, widgetId)
+        {
+            Lines = new List<string>();
+            Form.EventReceived += OnEventReceived;
+        }
+
+        public void AppendWrappedLine(string line)
+        {
+            WrappedLineCount++;
+            Form.Modify(
+                WidgetName,
+                "append",
+                String.Format("{{listitem text:{0}}}",
+                              StflApi.stfl_quote(line))
+            );
+        }
+
+        public void AppendWrappedLines(IEnumerable<string> lines)
+        {
+            foreach (var line in lines) {
+                AppendWrappedLine(line);
+            }
+        }
+
+        public void AppendLine(string line)
+        {
+            var width = Width;
+            if (!AutoLineWrap || width <= 0) {
+                // we don't know our width for whatever reason thus we can't
+                // apply any line wrapping
+                Lines.Add(line);
+                AppendWrappedLine(line);
+                return;
+            }
+
+            Lines.Add(line);
+            AppendWrappedLines(WrapLine(line, width));
+        }
+
+        public void AppendLines(IEnumerable<string> lines)
+        {
+            var width = Width;
+            if (!AutoLineWrap || width <= 0) {
+                // we don't know our width for whatever reason thus we can't
+                // apply any line wrapping
+                Lines.AddRange(lines);
+                AppendWrappedLines(lines);
+                return;
+            }
+
+            Lines.AddRange(lines);
+            var wrappedLines = new List<string>(lines);
+            foreach (var line in lines) {
+                wrappedLines.AddRange(WrapLine(line, width));
+            }
+            AppendWrappedLines(wrappedLines);
+        }
+
+        public void ScrollUp()
+        {
+            Scroll(-0.9);
+        }
+
+        public void ScrollDown()
+        {
+            Scroll(0.9);
+        }
+
+        protected void Scroll(double scrollFactor)
+        {
+            int currentOffset = Offset;
+            int newOffset = (int) (currentOffset + (Heigth * scrollFactor));
+            if (newOffset < 0) {
+                newOffset = 0;
+            } else if (newOffset > OffsetEnd) {
+                newOffset = OffsetEnd;
+            }
+            Offset = newOffset;
+        }
+
+        public void ScrollToStart()
+        {
+            Offset = OffsetStart;
+        }
+
+        public void ScrollToEnd()
+        {
+            Offset = OffsetEnd;
+        }
+
+        public void Clear()
+        {
+            Lines.Clear();
+            WrappedLineCount = 0;
+            Form.Modify(WidgetName, "replace_inner", "{list}");
+            ScrollToStart();
+        }
+
+        public static List<string> WrapLine(string line, int wrapWidth)
+        {
+            if (line == null) {
+                throw new ArgumentNullException("line");
+            }
+            if (wrapWidth <= 0) {
+                throw new ArgumentException("Wrap width must bigger than 0",
+                                            "wrapWidth");
+            }
+
+            var wrappedLine = new List<string>();
+            if (line.Length <= wrapWidth) {
+                wrappedLine.Add(line);
+                return wrappedLine;
+            }
+
+            var tags = new List<string>();
+            for (int i = 0; i < line.Length; i += wrapWidth) {
+                var chunkSize = Math.Min(line.Length - i, wrapWidth);
+                // FIXME: don't break style tags
+                // TODO: word wrapping
+                var chunk = line.Substring(i, chunkSize);
+                wrappedLine.Add(chunk);
+            }
+
+            return wrappedLine;
+        }
+
+        void Resize()
+        {
+            var width = Width;
+            if (!AutoLineWrap || width <= 0) {
+                // nothing to do
+                return;
+            }
+
+            // re-wrap all lines and re-apply offset
+            WrappedLineCount = 0;
+            var offset = Offset;
+            var items = new StringBuilder("{list", Lines.Count + 2);
+            foreach (var line in Lines) {
+                foreach (var wrappedLine in WrapLine(line, width)) {
+                    WrappedLineCount++;
+                    items.AppendFormat("{{listitem text:{0}}}",
+                                       StflApi.stfl_quote(wrappedLine));
+                }
+            }
+            items.Append("}");
+            Form.Modify(WidgetName, "replace_inner", items.ToString());
+            Offset = offset;
+        }
+
+        void OnEventReceived(object sender, EventReceivedEventArgs e)
+        {
+            if (e.Event == "RESIZE") {
+                Resize();
+            }
+        }
+    }
+}
diff --git a/src/Frontend-STFL/STFL/Widget.cs b/src/Frontend-STFL/STFL/Widget.cs
new file mode 100644
index 0000000..5557607
--- /dev/null
+++ b/src/Frontend-STFL/STFL/Widget.cs
@@ -0,0 +1,121 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2011 Mirco Bauer
+// 
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+// 
+// 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
+
+using System;
+
+namespace Stfl
+{
+    public abstract class Widget
+    {
+        public string HeigthVariableName { get; set; }
+        public string WidthVariableName { get; set; }
+        protected Form Form { get; private set; }
+        protected string WidgetName { get; set; }
+
+        public int Heigth {
+            get {
+                Render();
+                var variableName = HeigthVariableName;
+                if (variableName == null) {
+                    variableName = String.Format("{0}:w", WidgetName);
+                }
+                return Int32.Parse(Form[variableName]);
+            }
+        }
+
+        public int Width {
+            get {
+                Render();
+                var variableName = WidthVariableName;
+                if (variableName == null) {
+                    variableName = String.Format("{0}:w", WidgetName);
+                }
+                return Int32.Parse(Form[variableName]);
+            }
+        }
+
+        public int MinHeigth {
+            get {
+                Render();
+                return Int32.Parse(Form[String.Format("{0}:minh", WidgetName)]);
+            }
+        }
+
+        public int MinWidth {
+            get {
+                Render();
+                return Int32.Parse(Form[String.Format("{0}:minw", WidgetName)]);
+            }
+        }
+
+        public int XPosition {
+            get {
+                return Int32.Parse(Form[String.Format("{0}:x", WidgetName)]);
+                Render();
+            }
+        }
+
+        public int YPosition {
+            get {
+                Render();
+                return Int32.Parse(Form[String.Format("{0}:y", WidgetName)]);
+            }
+        }
+
+        protected Widget(Form form, string widgetName)
+        {
+            if (form == null) {
+                throw new ArgumentNullException("form");
+            }
+            if (widgetName == null) {
+                throw new ArgumentNullException("widgetName");
+            }
+
+            Form = form;
+            WidgetName = widgetName;
+        }
+
+        public void Bind()
+        {
+            CheckWidget();
+        }
+
+        protected void Render()
+        {
+            Form.Run(-3);
+        }
+
+        protected bool WidgetExists()
+        {
+            return String.IsNullOrEmpty(Form.Dump(WidgetName, null, 0));
+        }
+
+        protected void CheckWidget()
+        {
+            if (!WidgetExists()) {
+                return;
+            }
+
+            throw new ArgumentException(
+                String.Format("Widget name: '{0}' is already used.", WidgetName)
+            );
+        }
+    }
+}
diff --git a/src/Frontend-STFL/StflUI.cs b/src/Frontend-STFL/StflUI.cs
index cd51fc6..9a5ac7a 100644
--- a/src/Frontend-STFL/StflUI.cs
+++ b/src/Frontend-STFL/StflUI.cs
@@ -55,47 +55,94 @@ namespace Smuxi.Frontend.Stfl
         {
             Trace.Call(chat);
             
-            _ChatViewManager.AddChat(chat);
+            try {
+                _ChatViewManager.AddChat(chat);
+            } catch (Exception ex) {
+#if LOG4NET
+                _Logger.Fatal(ex);
+#endif
+            }
         }
-        
+
         public void AddMessageToChat(ChatModel chat, MessageModel msg)
         {
             Trace.Call(chat, msg);
 
-            ChatView chatView = _ChatViewManager.GetChat(chat);
+            try {
+                ChatView chatView = _ChatViewManager.GetChat(chat);
 #if LOG4NET
-            if (chatView == null) {
-                _Logger.Fatal(String.Format("AddMessageToChat(): _ChatViewManager.GetChat(chat) chat.Name: {0} returned null!", chat.Name));
-                return;
-            }
+                if (chatView == null) {
+                    _Logger.Fatal(String.Format("AddMessageToChat(): _ChatViewManager.GetChat(chat) chat.Name: {0} returned null!", chat.Name));
+                    return;
+                }
 #endif
-            chatView.AddMessage(msg);
+                chatView.AddMessage(msg);
+            } catch (Exception ex) {
+#if LOG4NET
+                _Logger.Fatal(ex);
+#endif
+            }
         }
         
         public void RemoveChat(ChatModel chat)
         {
             Trace.Call(chat);
             
-            //Console.WriteLine("Removed page: "+page.Name+" type: "+page.ChatType);
+            try {
+                _ChatViewManager.RemoveChat(chat);
+            } catch (Exception ex) {
+#if LOG4NET
+                _Logger.Fatal(ex);
+#endif
+            }
         }
         
         public void EnableChat(ChatModel chat)
         {
             Trace.Call(chat);
+
+            try {
+                _ChatViewManager.EnableChat(chat);
+            } catch (Exception ex) {
+#if LOG4NET
+                _Logger.Fatal(ex);
+#endif
+            }
         }
         
         public void DisableChat(ChatModel chat)
         {
             Trace.Call(chat);
+
+            try {
+                _ChatViewManager.DisableChat(chat);
+            } catch (Exception ex) {
+#if LOG4NET
+                _Logger.Fatal(ex);
+#endif
+            }
         }
         
         public void SyncChat(ChatModel chat)
         {
             Trace.Call(chat);
             
-            //Console.WriteLine("Synced page: "+page.Name+" type: "+page.ChatType);
-            // HACK: fake that we synced the chat, else we get no messages
-            Frontend.FrontendManager.AddSyncedChat(chat);
+            try {
+                var chatView = _ChatViewManager.GetChat(chat);
+#if LOG4NET
+                if (chatView == null) {
+                    _Logger.Fatal(String.Format("SyncChat(): _ChatViewManager.GetChat(chat) chat.Name: {0} returned null!", chat.Name));
+                    return;
+                }
+#endif
+                chatView.Sync();
+
+                Frontend.FrontendManager.AddSyncedChat(chat);
+            } catch (Exception ex) {
+#if LOG4NET
+                _Logger.Fatal(ex);
+#endif
+            }
         }
         
         public void AddPersonToGroupChat(GroupChatModel groupChat, PersonModel person)
diff --git a/src/Frontend-SWF/Chats/ChatView.cs b/src/Frontend-SWF/Chats/ChatView.cs
index 35078ae..85cd5fd 100644
--- a/src/Frontend-SWF/Chats/ChatView.cs
+++ b/src/Frontend-SWF/Chats/ChatView.cs
@@ -38,6 +38,18 @@ namespace Smuxi.Frontend.Swf
             }
         }
 
+        public string ID {
+            get {
+                return ChatModel.ID;
+            }
+        }
+
+        public int Position {
+            get {
+                return ChatModel.Position;
+            }
+        }
+
         public RichTextBox OutputTextView {
             get {
                 return _OutputTextView;
@@ -171,6 +183,10 @@ namespace Smuxi.Frontend.Swf
             }
         }
 
+        public virtual void Populate()
+        {
+        }
+
         public virtual void ApplyConfig(UserConfig config)
         {
             Trace.Call(config);
diff --git a/src/Frontend-SWF/Makefile.in b/src/Frontend-SWF/Makefile.in
index affe0cd..ce18da4 100644
--- a/src/Frontend-SWF/Makefile.in
+++ b/src/Frontend-SWF/Makefile.in
@@ -41,8 +41,11 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 subdir = src/Frontend-SWF
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -83,6 +86,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -96,13 +100,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -143,13 +160,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -157,6 +176,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -167,13 +187,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -187,13 +216,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -201,7 +236,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -216,10 +253,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -372,7 +412,7 @@ build_references_ref = $(foreach ref, $(REFERENCES), $(if $(filter \
 	-pkg:%, $(ref)), $(ref), $(if $(filter -r:%, $(ref)), $(ref), \
 	-r:$(ref)))) $(foreach ref, $(DLL_REFERENCES), -r:$(ref)) \
 	$(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
 programfilesdir = @libdir@/@PACKAGE@
@@ -500,6 +540,12 @@ uninstall-pkglibSCRIPTS:
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(linuxdesktopapplicationsdir)" || $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)"
@@ -653,7 +699,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -707,7 +753,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-am
 
@@ -724,19 +770,21 @@ uninstall-am: uninstall-binSCRIPTS \
 
 .MAKE: install-am install-strip
 
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binSCRIPTS install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-linuxdesktopapplicationsDATA \
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binSCRIPTS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-man install-pdf \
 	install-pdf-am install-pkglibSCRIPTS install-programfilesDATA \
 	install-programfilesiconsDATA install-ps install-ps-am \
 	install-strip installcheck installcheck-am installdirs \
 	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
-	uninstall-binSCRIPTS uninstall-linuxdesktopapplicationsDATA \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am uninstall-binSCRIPTS \
+	uninstall-linuxdesktopapplicationsDATA \
 	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
 	uninstall-programfilesDATA uninstall-programfilesiconsDATA
 
diff --git a/src/Frontend-Test/Makefile.in b/src/Frontend-Test/Makefile.in
index 4ded6df..0b0fc9c 100644
--- a/src/Frontend-Test/Makefile.in
+++ b/src/Frontend-Test/Makefile.in
@@ -41,8 +41,11 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 subdir = src/Frontend-Test
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -83,6 +86,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -96,13 +100,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -143,13 +160,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -157,6 +176,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -167,13 +187,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -187,13 +216,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -201,7 +236,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -216,10 +253,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -347,7 +387,7 @@ build_references_ref = $(foreach ref, $(REFERENCES), $(if $(filter \
 	-pkg:%, $(ref)), $(ref), $(if $(filter -r:%, $(ref)), $(ref), \
 	-r:$(ref)))) $(foreach ref, $(DLL_REFERENCES), -r:$(ref)) \
 	$(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
 programfilesdir = @libdir@/@PACKAGE@
@@ -474,6 +514,12 @@ uninstall-pkglibSCRIPTS:
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(linuxdesktopapplicationsdir)" || $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)"
@@ -627,7 +673,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -681,7 +727,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-am
 
@@ -698,19 +744,21 @@ uninstall-am: uninstall-binSCRIPTS \
 
 .MAKE: install-am install-strip
 
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binSCRIPTS install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-linuxdesktopapplicationsDATA \
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binSCRIPTS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-man install-pdf \
 	install-pdf-am install-pkglibSCRIPTS install-programfilesDATA \
 	install-programfilesiconsDATA install-ps install-ps-am \
 	install-strip installcheck installcheck-am installdirs \
 	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
-	uninstall-binSCRIPTS uninstall-linuxdesktopapplicationsDATA \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am uninstall-binSCRIPTS \
+	uninstall-linuxdesktopapplicationsDATA \
 	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
 	uninstall-programfilesDATA uninstall-programfilesiconsDATA
 
diff --git a/src/Frontend/ChatViewManagerBase.cs b/src/Frontend/ChatViewManagerBase.cs
index 7cdb7e4..45d2fba 100644
--- a/src/Frontend/ChatViewManagerBase.cs
+++ b/src/Frontend/ChatViewManagerBase.cs
@@ -65,23 +65,45 @@ namespace Smuxi.Frontend
             }
             return null;
         }
-        
-        protected IChatView CreateChatView(ChatModel chat)
+
+        [Obsolete("Use CreateChatView(ChatModel, ChatType, Type) instead.")]
+        protected IChatView CreateChatView(ChatModel chat,
+                                           params object[] parameters)
         {
-            Trace.Call(chat);
-            
+            Trace.Call(chat, parameters);
+
+            // REMOTING CALL 1 + 2
+            return CreateChatView(chat, chat.ChatType,
+                                  chat.ProtocolManager.GetType(), parameters);
+        }
+
+        protected IChatView CreateChatView(ChatModel chat,
+                                           ChatType chatType,
+                                           Type protocolManagerType,
+                                           params object[] parameters)
+        {
+            Trace.Call(chat, chatType, protocolManagerType, parameters);
+
             Type type;
-            type = _GetChatViewType(chat.ChatType, chat.ProtocolManager != null ?
-                                                   chat.ProtocolManager.GetType() : null);
+            type = _GetChatViewType(chatType, protocolManagerType);
             if (type == null) {
-                type = _GetChatViewType(chat.ChatType, null);
+                type = _GetChatViewType(chatType, null);
             }
             
             if (type == null) {
                 throw new ApplicationException("Unsupported ChatModel type: " + chat.GetType());
             }
             
-            return (IChatView) Activator.CreateInstance(type, chat);
+            object[] ctorParams;
+            if (parameters != null && parameters.Length > 0) {
+                ctorParams = new object[parameters.Length + 1];
+                ctorParams[0] = chat;
+                parameters.CopyTo(ctorParams, 1);
+            } else {
+                ctorParams = new object[] {chat};
+            }
+
+            return (IChatView) Activator.CreateInstance(type, ctorParams);
         }
         
         public void LoadAll(string path, string pattern)
diff --git a/src/Frontend/ChatViewSyncManager.cs b/src/Frontend/ChatViewSyncManager.cs
new file mode 100644
index 0000000..034292b
--- /dev/null
+++ b/src/Frontend/ChatViewSyncManager.cs
@@ -0,0 +1,331 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2011 Mirco Bauer <meebey at meebey.net>
+//
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+//
+// 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
+
+using System;
+using System.Threading;
+using System.Runtime.Remoting;
+using System.Collections.Generic;
+using Smuxi.Common;
+using Smuxi.Engine;
+
+namespace Smuxi.Frontend
+{
+    public class ChatViewSyncManager
+    {
+#if LOG4NET
+        private static readonly log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+#endif
+        ThreadPoolQueue WorkerQueue { set; get; }
+        Dictionary<object, AutoResetEvent> SyncWaitQueue { set; get; }
+        Dictionary<object, IChatView> SyncReleaseQueue { set; get; }
+
+        public event EventHandler<ChatViewAddedEventArgs>  ChatAdded;
+        public event EventHandler<ChatViewSyncedEventArgs> ChatSynced;
+        public event EventHandler<WorkerExceptionEventArgs> WorkerException;
+
+        public ChatViewSyncManager()
+        {
+            WorkerQueue = new ThreadPoolQueue() {
+                MaxWorkers = 4
+            };
+            SyncWaitQueue = new Dictionary<object, AutoResetEvent>();
+            SyncReleaseQueue = new Dictionary<object, IChatView>();
+        }
+
+        public void Add(ChatModel chatModel)
+        {
+            Trace.Call(chatModel);
+
+            if (chatModel == null) {
+                throw new ArgumentNullException("chatModel");
+            }
+
+#if LOG4NET
+            DateTime start = DateTime.UtcNow;
+#endif
+            // REMOTING CALL 1
+            var chatId = chatModel.ID;
+            // REMOTING CALL 2
+            var chatType = chatModel.ChatType;
+            // REMOTING CALL 3
+            var chatPosition = chatModel.Position;
+            // REMOTING CALL 4
+            IProtocolManager protocolManager = chatModel.ProtocolManager;
+            Type protocolManagerType = null;
+            if (protocolManager != null) {
+                protocolManagerType = chatModel.ProtocolManager.GetType();
+            }
+#if LOG4NET
+            DateTime stop = DateTime.UtcNow;
+            double duration = stop.Subtract(start).TotalMilliseconds;
+            Logger.Debug("Add() done, syncing took: " +
+                         Math.Round(duration) + " ms");
+#endif
+
+            OnChatAdded(chatModel, chatId, chatType, chatPosition,
+                        protocolManagerType);
+        }
+
+        public void Sync(IChatView chatView)
+        {
+            Trace.Call(chatView);
+
+            if (chatView == null) {
+                throw new ArgumentNullException("chatView");
+            }
+
+#if LOG4NET
+            DateTime start = DateTime.UtcNow;
+#endif
+            chatView.Sync();
+#if LOG4NET
+            DateTime stop = DateTime.UtcNow;
+            double duration = stop.Subtract(start).TotalMilliseconds;
+            Logger.Debug("Sync() <" + chatView.ID + ">.Sync() done, " +
+                         " syncing took: " + Math.Round(duration) + " ms");
+#endif
+
+            OnChatSynced(chatView);
+        }
+
+        /// <remarks>
+        /// This method is thread safe.
+        /// </remarks>
+        public void QueueAdd(ChatModel chatModel)
+        {
+            Trace.Call(chatModel);
+
+            if (chatModel == null) {
+                throw new ArgumentNullException("chatModel");
+            }
+
+            var chatKey = GetChatKey(chatModel);
+            lock (SyncWaitQueue) {
+                SyncWaitQueue.Add(chatKey, new AutoResetEvent(false));
+#if LOG4NET
+                Logger.Debug("QueueAdd() <" + chatKey + "> created sync lock");
+#endif
+            }
+            WorkerQueue.Enqueue(delegate {
+                AddWorker(chatModel);
+            });
+        }
+
+        /// <remarks>
+        /// This method is thread safe.
+        /// </remarks>
+        public void QueueSync(ChatModel chatModel)
+        {
+            Trace.Call(chatModel);
+
+            if (chatModel == null) {
+                throw new ArgumentNullException("chatModel");
+            }
+
+            WorkerQueue.Enqueue(delegate {
+                SyncWorker(chatModel);
+            });
+        }
+
+        /// <remarks>
+        /// This method is thread safe.
+        /// </remarks>
+        public void ReleaseSync(IChatView chatView)
+        {
+            Trace.Call(chatView);
+
+            if (chatView == null) {
+                throw new ArgumentNullException("chatView");
+            }
+
+            var chatKey = GetChatKey(chatView.ChatModel);
+#if LOG4NET
+            Logger.Debug("ReleaseSync() <" + chatKey + "> releasing " +
+                         "<" + chatView.ID + ">");
+#endif
+            lock (SyncReleaseQueue) {
+                SyncReleaseQueue.Add(chatKey, chatView);
+            }
+            AutoResetEvent syncWait = null;
+            lock (SyncWaitQueue) {
+                SyncWaitQueue.TryGetValue(chatKey, out syncWait);
+            }
+            // release the sync worker
+            syncWait.Set();
+        }
+
+        public void Clear()
+        {
+            Trace.Call();
+
+            lock (SyncWaitQueue)
+            lock (SyncReleaseQueue) {
+                SyncWaitQueue.Clear();
+                SyncReleaseQueue.Clear();
+            }
+        }
+
+        object GetChatKey(ChatModel chatModel)
+        {
+            if (RemotingServices.IsTransparentProxy(chatModel)) {
+                // HACK: we can't use ChatModel as Dictionary as it is
+                // a remoting object
+                return RemotingServices.GetObjectUri(chatModel);
+            }
+            return chatModel;
+        }
+
+        void AddWorker(ChatModel chatModel)
+        {
+            try {
+                Add(chatModel);
+            } catch (Exception ex) {
+#if LOG4NET
+                Logger.Error("AddWorker(): Add() threw exception!" , ex);
+#endif
+                if (WorkerException != null) {
+                    WorkerException(
+                        this,
+                        new WorkerExceptionEventArgs(chatModel, ex)
+                    );
+                }
+                OnWorkerException(chatModel, ex);
+            }
+        }
+
+        void SyncWorker(ChatModel chatModel)
+        {
+            try {
+                var chatKey = GetChatKey(chatModel);
+                AutoResetEvent syncWait = null;
+                lock (SyncWaitQueue) {
+                    SyncWaitQueue.TryGetValue(chatKey, out syncWait);
+                }
+                if (syncWait != null) {
+#if LOG4NET
+                    Logger.Debug("SyncWorker() <" + chatKey + "> waiting for " +
+                                "sync lock release...");
+#endif
+                    // This chat was queued by QueueAdd() thus we need to wait
+                    // till the ChatView is created and ready to be synced
+                    syncWait.WaitOne();
+#if LOG4NET
+                    Logger.Debug("SyncWorker() <" + chatKey + "> " +
+                                 "sync lock released");
+#endif
+
+                    // no longer need the sync lock
+                    lock (SyncWaitQueue) {
+                        SyncWaitQueue.Remove(chatKey);
+                    }
+                }
+
+                IChatView chatView = null;
+                lock (SyncReleaseQueue) {
+                    if (!SyncReleaseQueue.TryGetValue(chatKey, out chatView)) {
+#if LOG4NET
+                        Logger.Warn("SyncWorker(): chatView is null! " +
+                                    "probably a reconnect, bailing out...");
+#endif
+                        return;
+                    }
+                }
+
+                Sync(chatView);
+            } catch (Exception ex) {
+#if LOG4NET
+                Logger.Error("SyncWorker(): Exception!", ex);
+#endif
+                OnWorkerException(chatModel, ex);
+            }
+        }
+
+        void OnChatAdded(ChatModel chatModel, string chatId,
+                         ChatType chatType, int chatPosition,
+                         Type protocolManagerType)
+        {
+            if (ChatAdded != null) {
+                ChatAdded(this,
+                          new ChatViewAddedEventArgs(chatModel, chatId,
+                                                     chatType, chatPosition,
+                                                     protocolManagerType));
+            }
+        }
+
+        void OnChatSynced(IChatView chatView)
+        {
+            if (ChatSynced != null) {
+                ChatSynced(this, new ChatViewSyncedEventArgs(chatView));
+            }
+        }
+
+        void OnWorkerException(ChatModel chatModel, Exception ex)
+        {
+            if (WorkerException != null) {
+                WorkerException(
+                    this,
+                    new WorkerExceptionEventArgs(chatModel, ex)
+                );
+            }
+        }
+    }
+
+    public class ChatViewAddedEventArgs : EventArgs
+    {
+        public ChatModel ChatModel { get; private set; }
+        public string ChatID { get; private set; }
+        public ChatType ChatType { get; private set; }
+        public int ChatPosition { get; private set; }
+        public Type ProtocolManagerType { get; private set; }
+
+        public ChatViewAddedEventArgs(ChatModel chatModel, string chatId,
+                                      ChatType chatType, int chatPosition,
+                                      Type protocolManagerType)
+        {
+            ChatModel = chatModel;
+            ChatID = chatId;
+            ChatType = chatType;
+            ChatPosition = chatPosition;
+            ProtocolManagerType = protocolManagerType;
+        }
+    }
+
+    public class ChatViewSyncedEventArgs : EventArgs
+    {
+        public IChatView ChatView { get; private set; }
+
+        public ChatViewSyncedEventArgs(IChatView chatView)
+        {
+            ChatView = chatView;
+        }
+    }
+
+    public class WorkerExceptionEventArgs : EventArgs
+    {
+        public ChatModel ChatModel { get; private set; }
+        public Exception Exception { get; private set; }
+
+        public WorkerExceptionEventArgs(ChatModel chat, Exception ex)
+        {
+            ChatModel = chat;
+            Exception = ex;
+        }
+    }
+}
diff --git a/src/Frontend/EngineManager.cs b/src/Frontend/EngineManager.cs
index dc2f6be..0e8242c 100644
--- a/src/Frontend/EngineManager.cs
+++ b/src/Frontend/EngineManager.cs
@@ -114,7 +114,25 @@ namespace Smuxi.Frontend
         public void Connect(string engine)
         {
             Trace.Call(engine);
-            
+
+            if (engine == null) {
+                throw new ArgumentNullException("engine");
+            }
+            if (engine.Length == 0) {
+                throw new ArgumentException(_("Engine must not be empty."), "engine");
+            }
+
+            bool engineFound = false;
+            foreach (var entry in (string[]) f_FrontendConfig["Engines/Engines"]) {
+                if (entry == engine) {
+                    engineFound = true;
+                    break;
+                }
+            }
+            if (!engineFound) {
+                throw new ArgumentException(_("Engine does not exist."), "engine");
+            }
+
             f_Engine = engine;
             string username = (string) f_FrontendConfig["Engines/"+engine+"/Username"];
             string password = (string) f_FrontendConfig["Engines/"+engine+"/Password"];
@@ -138,7 +156,15 @@ namespace Smuxi.Frontend
             }
             string sshUsername = (string) f_FrontendConfig["Engines/"+engine+"/SshUsername"];
             string sshPassword = (string) f_FrontendConfig["Engines/"+engine+"/SshPassword"];
-            
+            var sshKeyfile = (string) f_FrontendConfig["Engines/"+engine+"/SshKeyfile"];
+
+            // OPT: always use SSH compression (both openssh and plink support it)
+            // this reduces the .NET remoting traffic by about 75%
+            if (String.IsNullOrEmpty(sshParameters) ||
+                !sshParameters.Contains(" -C")) {
+                sshParameters += " -C";
+            }
+
             int remotingPort = 0;
             if (useSshTunnel) {
                 // find free remoting back-channel port
@@ -165,8 +191,8 @@ namespace Smuxi.Frontend
                 // thus the client will try to reach it using the original
                 // server port :(
                 f_SshTunnelManager = new SshTunnelManager(
-                    sshProgram, sshParameters, sshUsername, sshPassword, null,
-                    sshHostname, sshPort,
+                    sshProgram, sshParameters, sshUsername, sshPassword,
+                    sshKeyfile, sshHostname, sshPort,
                     //"127.0.0.1", localForwardPort, "127.0.0.1", port,
                     "127.0.0.1", port, "127.0.0.1", port,
                     "127.0.0.1", remotingPort, "127.0.0.1", remotingPort
diff --git a/src/Frontend/IChatView.cs b/src/Frontend/IChatView.cs
index 94ac878..1711ac5 100644
--- a/src/Frontend/IChatView.cs
+++ b/src/Frontend/IChatView.cs
@@ -33,13 +33,15 @@ namespace Smuxi.Frontend
 {
     public interface IChatView
     {
-        ChatModel ChatModel {
-            get;
-        }
-        
+        ChatModel ChatModel { get; }
+        string    ID { get; }
+        int       Position { get; }
+
         void Enable();
         void Disable();
-        
+        void Sync();
+        void Populate();
+
         void ScrollUp();
         void ScrollDown();
         void ScrollToStart();
diff --git a/src/Frontend/Makefile.am b/src/Frontend/Makefile.am
index 4f3b701..96db2ec 100644
--- a/src/Frontend/Makefile.am
+++ b/src/Frontend/Makefile.am
@@ -64,6 +64,7 @@ FILES = \
 	EntryController.cs \
 	EntryHistoryModel.cs \
 	ChatViewManagerBase.cs \
+	ChatViewSyncManager.cs \
 	IChatView.cs \
 	ChatViewInfoAttribute.cs \
 	IEntryView.cs \
@@ -80,6 +81,7 @@ EXTRAS = \
 
 REFERENCES =  \
 	System \
+	System.Core \
 	System.Runtime.Remoting \
 	Mono.Posix
 
diff --git a/src/Frontend/Makefile.in b/src/Frontend/Makefile.in
index 6a31d72..2e5db25 100644
--- a/src/Frontend/Makefile.in
+++ b/src/Frontend/Makefile.in
@@ -41,8 +41,11 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 subdir = src/Frontend
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -83,6 +86,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -96,13 +100,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -143,13 +160,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -157,6 +176,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -167,13 +187,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -187,13 +216,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -201,7 +236,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -216,10 +253,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -302,6 +342,7 @@ FILES = \
 	EntryController.cs \
 	EntryHistoryModel.cs \
 	ChatViewManagerBase.cs \
+	ChatViewSyncManager.cs \
 	IChatView.cs \
 	ChatViewInfoAttribute.cs \
 	IEntryView.cs \
@@ -316,6 +357,7 @@ EXTRAS = \
 
 REFERENCES = \
 	System \
+	System.Core \
 	System.Runtime.Remoting \
 	Mono.Posix
 
@@ -352,7 +394,7 @@ build_references_ref = $(foreach ref, $(REFERENCES), $(if $(filter \
 	-pkg:%, $(ref)), $(ref), $(if $(filter -r:%, $(ref)), $(ref), \
 	-r:$(ref)))) $(foreach ref, $(DLL_REFERENCES), -r:$(ref)) \
 	$(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
 programfilesdir = @libdir@/@PACKAGE@
@@ -479,6 +521,12 @@ uninstall-pkglibSCRIPTS:
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(linuxdesktopapplicationsdir)" || $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)"
@@ -632,7 +680,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -686,7 +734,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-am
 
@@ -703,19 +751,21 @@ uninstall-am: uninstall-binSCRIPTS \
 
 .MAKE: install-am install-strip
 
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binSCRIPTS install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-linuxdesktopapplicationsDATA \
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binSCRIPTS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-man install-pdf \
 	install-pdf-am install-pkglibSCRIPTS install-programfilesDATA \
 	install-programfilesiconsDATA install-ps install-ps-am \
 	install-strip installcheck installcheck-am installdirs \
 	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
-	uninstall-binSCRIPTS uninstall-linuxdesktopapplicationsDATA \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am uninstall-binSCRIPTS \
+	uninstall-linuxdesktopapplicationsDATA \
 	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
 	uninstall-programfilesDATA uninstall-programfilesiconsDATA
 
diff --git a/src/Frontend/SshTunnelManager.cs b/src/Frontend/SshTunnelManager.cs
index aa8cc43..766e026 100644
--- a/src/Frontend/SshTunnelManager.cs
+++ b/src/Frontend/SshTunnelManager.cs
@@ -89,6 +89,7 @@ namespace Smuxi.Frontend
             f_Parameters = parameters;
             f_Username = username;
             f_Password = password;
+            f_Keyfile = keyfile;
             f_Hostname = hostname;
             f_Port = port;
             
@@ -122,10 +123,8 @@ namespace Smuxi.Frontend
         {
             Trace.Call(disposing);
             
-            if (disposing) {
-                if (f_Process != null) {
-                    f_Process.Dispose();
-                }
+            if (f_Process != null) {
+                f_Process.Dispose();
             }
         }
         
@@ -326,6 +325,19 @@ namespace Smuxi.Frontend
             if (!String.IsNullOrEmpty(f_Password)) {
                 // TODO: pass password,  but how?
             }
+            if (!String.IsNullOrEmpty(f_Keyfile)) {
+                if (!File.Exists(f_Keyfile)) {
+                    throw new ApplicationException(_("SSH keyfile not found."));
+                }
+                try {
+                    using (File.OpenRead(f_Keyfile)) {}
+                } catch (Exception ex) {
+                    throw new ApplicationException(
+                        _("SSH keyfile could not be read."), ex
+                    );
+                }
+                sshArguments += String.Format(" -i \"{0}\"", f_Keyfile);
+            }
             if (f_Port != -1) {
                 sshArguments += String.Format(" -p {0}", f_Port);
             }
@@ -372,9 +384,16 @@ namespace Smuxi.Frontend
             psi.RedirectStandardOutput = true;
             psi.RedirectStandardError = true;
 
-            SysDiag.Process process = SysDiag.Process.Start(psi);
-            string error = process.StandardError.ReadToEnd();
-            string output = process.StandardOutput.ReadToEnd();
+            string error;
+            string output;
+            int exitCode;
+            using (var process = SysDiag.Process.Start(psi)) {
+                error = process.StandardError.ReadToEnd();
+                output = process.StandardOutput.ReadToEnd();
+                process.WaitForExit();
+                exitCode = process.ExitCode;
+            }
+
             string haystack;
             // we expect the version output on stderr
             if (error.Length > 0) {
@@ -408,7 +427,7 @@ namespace Smuxi.Frontend
                   "{2}\n" +
                   "Program Output:\n" +
                   "{3}\n"),
-                f_Process.ExitCode,
+                exitCode,
                 f_Program,
                 error,
                 output
@@ -423,11 +442,18 @@ namespace Smuxi.Frontend
         {
             string sshArguments = String.Empty;
             
-            // HACK: don't ask for SSH key fingerprints
-            // this is nasty but plink.exe can't ask for fingerprint
-            // confirmation and thus the connect would always fail
-            sshArguments += " -auto_store_key_in_cache";
-            
+            var sshVersion = GetPlinkVersionString();
+            // Smuxi by default ships Plink of Quest PuTTY which allows to
+            // accept any fingerprint but does _not_ work with pagent thus we
+            // need to also support the regular plink if the user wants
+            // ssh key authentication instead
+            if (sshVersion.EndsWith("_q1.129")) {
+                // HACK: don't ask for SSH key fingerprints
+                // this is nasty but plink.exe can't ask for fingerprint
+                // confirmation and thus the connect would always fail
+                sshArguments += " -auto_store_key_in_cache";
+            }
+
             // no interactive mode please
             sshArguments += " -batch";
             // don't execute a remote command
@@ -445,7 +471,19 @@ namespace Smuxi.Frontend
             if (!String.IsNullOrEmpty(f_Password)) {
                 sshArguments += String.Format(" -pw {0}", f_Password);
             }
-            
+            if (!String.IsNullOrEmpty(f_Keyfile)) {
+                if (!File.Exists(f_Keyfile)) {
+                    throw new ApplicationException(_("SSH keyfile not found."));
+                }
+                try {
+                    using (File.OpenRead(f_Keyfile)) {}
+                } catch (Exception ex) {
+                    throw new ApplicationException(
+                        _("SSH keyfile could not be read."), ex
+                    );
+                }
+                sshArguments += String.Format(" -i \"{0}\"", f_Keyfile);
+            }
             if (f_Port != -1) {
                 sshArguments += String.Format(" -P {0}", f_Port);
             }
@@ -484,6 +522,53 @@ namespace Smuxi.Frontend
             return psi;
         }
 
+        private string GetPlinkVersionString()
+        {
+            var startInfo = new SysDiag.ProcessStartInfo() {
+                FileName = f_Program,
+                Arguments = "-V",
+                UseShellExecute = false,
+                RedirectStandardOutput = true,
+                RedirectStandardError = true,
+                CreateNoWindow = true
+            };
+            string error;
+            string output;
+            int exitCode;
+            using (var process = SysDiag.Process.Start(startInfo)) {
+                error = process.StandardError.ReadToEnd();
+                output = process.StandardOutput.ReadToEnd();
+                process.WaitForExit();
+                exitCode = process.ExitCode;
+            }
+
+            Match match = Regex.Match(output, @"[0-9]+\.[0-9a-zA-Z_]+");
+            if (match.Success) {
+                var version = match.Value;
+#if LOG4NET
+                f_Logger.Debug("GetPlinkVersionString(): found version: " + version);
+#endif
+                return version;
+            }
+
+            string msg = String.Format(
+                _("Plink version number not found (exit code: {0})\n\n" +
+                  "SSH program: {1}\n\n" +
+                  "Program Error:\n" +
+                  "{2}\n" +
+                  "Program Output:\n" +
+                  "{3}\n"),
+                exitCode,
+                f_Program,
+                error,
+                output
+            );
+#if LOG4NET
+            f_Logger.Error("GetPlinkVersionString(): " + msg);
+#endif
+            throw new ApplicationException(msg);
+        }
+
         private static string _(string msg)
         {
             return LibraryCatalog.GetString(msg, f_LibraryTextDomain);
diff --git a/src/Makefile.in b/src/Makefile.in
index 005f33c..838d548 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -38,8 +38,11 @@ DIST_COMMON = $(srcdir)/AssemblyVersion.cs.in $(srcdir)/Makefile.am \
 	$(srcdir)/Makefile.in $(srcdir)/smuxi-win32.nsis.in ChangeLog
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -94,6 +97,7 @@ am__relativize = \
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -107,13 +111,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -154,13 +171,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -168,6 +187,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -178,13 +198,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -198,13 +227,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -212,7 +247,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -227,10 +264,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -335,6 +375,12 @@ AssemblyVersion.cs: $(top_builddir)/config.status $(srcdir)/AssemblyVersion.cs.i
 smuxi-win32.nsis: $(top_builddir)/config.status $(srcdir)/smuxi-win32.nsis.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
 # This directory's subdirectories are mostly independent; you can cd
 # into them and run `make' without going through this Makefile.
 # To change the values of `make' variables: instead of editing Makefiles,
@@ -560,7 +606,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-recursive
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-recursive
 	-rm -f Makefile
@@ -612,7 +658,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-recursive
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-recursive
 
@@ -628,17 +674,18 @@ uninstall-am:
 	install-am install-strip tags-recursive
 
 .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
-	all all-am check check-am clean clean-generic ctags \
-	ctags-recursive distclean distclean-generic distclean-tags \
-	distdir dvi dvi-am html html-am info info-am install \
-	install-am install-data install-data-am install-dvi \
-	install-dvi-am install-exec install-exec-am install-html \
-	install-html-am install-info install-info-am install-man \
-	install-pdf install-pdf-am install-ps install-ps-am \
-	install-strip installcheck installcheck-am installdirs \
-	installdirs-am maintainer-clean maintainer-clean-generic \
-	mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \
-	tags-recursive uninstall uninstall-am
+	all all-am check check-am clean clean-generic clean-libtool \
+	ctags ctags-recursive distclean distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+	uninstall uninstall-am
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/src/Server/Main.cs b/src/Server/Main.cs
index 90a67c1..b4f36cf 100644
--- a/src/Server/Main.cs
+++ b/src/Server/Main.cs
@@ -45,6 +45,7 @@ namespace Smuxi.Server
 
         public static void Main(string[] args)
         {
+            System.Threading.Thread.CurrentThread.Name = "Main";
 #if LOG4NET
             // initialize log level
             log4net.Repository.ILoggerRepository repo = log4net.LogManager.GetRepository();
@@ -56,6 +57,7 @@ namespace Smuxi.Server
             bool modUser    = false;
             bool listUsers  = false;
             bool debug      = false;
+            string optBuffers = null;
 
             string username = null;
             string password = null;
@@ -127,6 +129,19 @@ namespace Smuxi.Server
             );
 
             parser.Add(
+                "optimize-message-buffers=",
+                _("Optimize message buffers and exit " +
+                  "(valid values: none, defrag, index, all)"),
+                delegate (string val) {
+                    if (String.IsNullOrEmpty(val)) {
+                        val = "all";
+                    }
+                    CheckOptimizeMessageBuffersParameter(val);
+                    optBuffers = val;
+                }
+            );
+
+            parser.Add(
                  "h|help",
                  _("Show this help"),
                  delegate(string val) {
@@ -158,6 +173,9 @@ namespace Smuxi.Server
                     repo.Threshold = log4net.Core.Level.Debug;
                 }
 #endif
+                if (optBuffers != null) {
+                    OptimizeMessageBuffers(optBuffers);
+                }
                 if (addUser || modUser) {
                     CheckUsernameParameter(username);
                     CheckPasswordParameter(password);
@@ -249,6 +267,28 @@ namespace Smuxi.Server
             }
         }
 
+        private static void CheckOptimizeMessageBuffersParameter(string opts)
+        {
+            try {
+                ParseBufferOptimizationTypes(opts);
+            } catch (Exception) {
+                var validOpts = Enum.GetNames(typeof(Db4oMessageBufferOptimizationTypes));
+                // lower-case values
+                for (int i = 0; i < validOpts.Length; i++) {
+                    validOpts[i] = validOpts[i].ToLower();
+                }
+                var validValues = String.Join(", ", validOpts);
+                throw new OptionException(
+                    String.Format(
+                        _("Invalid optimization value passed to " +
+                          "--optimize-message-buffer, valid values are: {0}"),
+                        validValues
+                    ),
+                    String.Empty
+                );
+            }
+        }
+
         private static void ManageUser(bool addUser, bool delUser, bool modUser,
                                        bool listUsers,
                                        string username, string password)
@@ -297,6 +337,63 @@ namespace Smuxi.Server
             }
         }
 
+        private static Db4oMessageBufferOptimizationTypes ParseBufferOptimizationTypes(string optString)
+        {
+            if (optString == null) {
+                throw new ArgumentNullException("optString");
+            }
+
+            var optList = optString.Split(' ', ',');
+            var opts = Db4oMessageBufferOptimizationTypes.None;
+            foreach (var optItem in optList) {
+                var optEnum = (Db4oMessageBufferOptimizationTypes) Enum.Parse(
+                    typeof(Db4oMessageBufferOptimizationTypes),
+                    optItem,
+                    true
+                );
+                opts |= optEnum;
+            }
+            return opts;
+        }
+
+        private static void OptimizeMessageBuffers(string optString)
+        {
+            var logRepo = log4net.LogManager.GetRepository();
+            var origThreshold = logRepo.Threshold;
+            // don't spew errors of Db4oMessageBuffer
+            if (origThreshold == log4net.Core.Level.Error) {
+                logRepo.Threshold = log4net.Core.Level.Fatal;
+            }
+            try {
+                var opts = ParseBufferOptimizationTypes(optString);
+                if (opts == Db4oMessageBufferOptimizationTypes.None) {
+                    Environment.Exit(0);
+                    return;
+                }
+                var bufferCount = Db4oMessageBuffer.OptimizeAllBuffers(opts);
+                Console.WriteLine(
+                    String.Format(
+                        _("Successfully optimized {0} message buffers."),
+                        bufferCount
+                    )
+                );
+                Environment.Exit(0);
+            } catch (Exception ex) {
+                string error = ex.Message;
+                if (ex.InnerException != null) {
+                    // inner-exceptio is more useful for some reason...
+                    error = ex.InnerException.Message;
+                }
+                Console.WriteLine(
+                    String.Format(
+                        _("Failed to optimize message buffers: {0}"), error
+                    )
+                );
+                Environment.Exit(1);
+            }
+            logRepo.Threshold = origThreshold;
+        }
+
         private static string _(string msg)
         {
             return LibraryCatalog.GetString(msg, _LibraryTextDomain);
diff --git a/src/Server/Makefile.am b/src/Server/Makefile.am
index 9b96d22..359f817 100644
--- a/src/Server/Makefile.am
+++ b/src/Server/Makefile.am
@@ -3,12 +3,13 @@ EXTRA_DIST =
 
 SERVER_EXE_CONFIG_SOURCE = smuxi-server.exe.config
 SERVER_EXE_CONFIG = $(BUILD_DIR)/smuxi-server.exe.config
+ASSEMBLY_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 
 # Warning: This is an automatically generated file, do not edit!
 
 if ENABLE_RELEASE
 ASSEMBLY_COMPILER_COMMAND = @MCS@
-ASSEMBLY_COMPILER_FLAGS =  -noconfig -codepage:utf8 -warn:4 -optimize+
+ASSEMBLY_COMPILER_FLAGS +=  -noconfig -codepage:utf8 -warn:4 -optimize+
 ASSEMBLY = ../../bin/release/smuxi-server.exe
 ASSEMBLY_MDB = 
 COMPILE_TARGET = exe
@@ -28,7 +29,7 @@ endif
 
 if ENABLE_DEBUG
 ASSEMBLY_COMPILER_COMMAND = @MCS@
-ASSEMBLY_COMPILER_FLAGS =  -noconfig -codepage:utf8 -warn:4 -optimize- -debug -define:DEBUG "-define:TRACE,DEBUG,LOG4NET"
+ASSEMBLY_COMPILER_FLAGS +=  -noconfig -codepage:utf8 -warn:4 -optimize- -debug -define:DEBUG "-define:TRACE,DEBUG,LOG4NET"
 
 ASSEMBLY = ../../bin/debug/smuxi-server.exe
 ASSEMBLY_MDB = $(ASSEMBLY).mdb
diff --git a/src/Server/Makefile.in b/src/Server/Makefile.in
index 43b16bc..13509c2 100644
--- a/src/Server/Makefile.in
+++ b/src/Server/Makefile.in
@@ -35,14 +35,19 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
+ at ENABLE_RELEASE_TRUE@am__append_1 = -noconfig -codepage:utf8 -warn:4 -optimize+
+ at ENABLE_DEBUG_TRUE@am__append_2 = -noconfig -codepage:utf8 -warn:4 -optimize- -debug -define:DEBUG "-define:TRACE,DEBUG,LOG4NET"
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 	$(srcdir)/smuxi-server.in $(top_srcdir)/Makefile.include \
 	ChangeLog
 subdir = src/Server
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/expansions.m4 \
-	$(top_srcdir)/intltool.m4 $(top_srcdir)/mono.m4 \
-	$(top_srcdir)/programs.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/intltool.m4 $(top_srcdir)/libtool.m4 \
+	$(top_srcdir)/ltoptions.m4 $(top_srcdir)/ltsugar.m4 \
+	$(top_srcdir)/ltversion.m4 $(top_srcdir)/lt~obsolete.m4 \
+	$(top_srcdir)/mono.m4 $(top_srcdir)/programs.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -83,6 +88,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
+AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -96,13 +102,26 @@ CSC = @CSC@
 CSC_FLAGS = @CSC_FLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DB4O_CFLAGS = @DB4O_CFLAGS@
+DB4O_FILES = @DB4O_FILES@
+DB4O_LIBS = @DB4O_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SHARP_CFLAGS = @DBUS_SHARP_CFLAGS@
+DBUS_SHARP_GLIB_CFLAGS = @DBUS_SHARP_GLIB_CFLAGS@
+DBUS_SHARP_GLIB_LIBS = @DBUS_SHARP_GLIB_LIBS@
+DBUS_SHARP_LIBS = @DBUS_SHARP_LIBS@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DEV_VERSION_SUFFIX = @DEV_VERSION_SUFFIX@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FGREP = @FGREP@
 FRONTEND_GNOME_COMPILER_FLAGS = @FRONTEND_GNOME_COMPILER_FLAGS@
 GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -143,13 +162,15 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-JABBER_NET_CFLAGS = @JABBER_NET_CFLAGS@
-JABBER_NET_LIBS = @JABBER_NET_LIBS@
+LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
 LOG4NET_CFLAGS = @LOG4NET_CFLAGS@
 LOG4NET_LIBS = @LOG4NET_LIBS@
 LTLIBICONV = @LTLIBICONV@
@@ -157,6 +178,7 @@ LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
@@ -167,13 +189,22 @@ MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
 MSNPSHARP_CFLAGS = @MSNPSHARP_CFLAGS@
 MSNPSHARP_LIBS = @MSNPSHARP_LIBS@
+NDESK_DBUS_CFLAGS = @NDESK_DBUS_CFLAGS@
+NDESK_DBUS_GLIB_CFLAGS = @NDESK_DBUS_GLIB_CFLAGS@
+NDESK_DBUS_GLIB_LIBS = @NDESK_DBUS_GLIB_LIBS@
+NDESK_DBUS_LIBS = @NDESK_DBUS_LIBS@
 NINI_CFLAGS = @NINI_CFLAGS@
 NINI_LIBS = @NINI_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
 NOTIFY_SHARP_CFLAGS = @NOTIFY_SHARP_CFLAGS@
 NOTIFY_SHARP_LIBS = @NOTIFY_SHARP_LIBS@
+OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OSCARLIB_CFLAGS = @OSCARLIB_CFLAGS@
 OSCARLIB_LIBS = @OSCARLIB_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
@@ -187,13 +218,19 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 PROFILE = @PROFILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SERVER_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SMARTIRC4NET_FILES = @SMARTIRC4NET_FILES@
+STFL_CFLAGS = @STFL_CFLAGS@
+STFL_LIBS = @STFL_LIBS@
 STRIP = @STRIP@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
+XBUILD_FLAGS = @XBUILD_FLAGS@
 XGETTEXT = @XGETTEXT@
 XGETTEXT_015 = @XGETTEXT_015@
 XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
@@ -201,7 +238,9 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -216,10 +255,13 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
+dist_version = @dist_version@
 docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 expanded_libdir = @expanded_libdir@
+git_branch = @git_branch@
+git_commit_hash = @git_commit_hash@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
@@ -255,12 +297,12 @@ EXTRA_DIST = $(build_sources) $(build_resx_files) \
 	$(DATA_FILES) $(build_culture_res_files)
 SERVER_EXE_CONFIG_SOURCE = smuxi-server.exe.config
 SERVER_EXE_CONFIG = $(BUILD_DIR)/smuxi-server.exe.config
+ASSEMBLY_COMPILER_FLAGS = @SERVER_COMPILER_FLAGS@ $(am__append_1) \
+	$(am__append_2)
 @ENABLE_DEBUG_TRUE at ASSEMBLY_COMPILER_COMMAND = @MCS@
 
 # Warning: This is an automatically generated file, do not edit!
 @ENABLE_RELEASE_TRUE at ASSEMBLY_COMPILER_COMMAND = @MCS@
- at ENABLE_DEBUG_TRUE@ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize- -debug -define:DEBUG "-define:TRACE,DEBUG,LOG4NET"
- at ENABLE_RELEASE_TRUE@ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+
 @ENABLE_DEBUG_TRUE at ASSEMBLY = ../../bin/debug/smuxi-server.exe
 @ENABLE_RELEASE_TRUE at ASSEMBLY = ../../bin/release/smuxi-server.exe
 @ENABLE_DEBUG_TRUE at ASSEMBLY_MDB = $(ASSEMBLY).mdb
@@ -350,7 +392,7 @@ build_references_ref = $(foreach ref, $(REFERENCES), $(if $(filter \
 	-pkg:%, $(ref)), $(ref), $(if $(filter -r:%, $(ref)), $(ref), \
 	-r:$(ref)))) $(foreach ref, $(DLL_REFERENCES), -r:$(ref)) \
 	$(foreach ref, $(PROJECT_REFERENCES), -r:$(ref))
-DISTCLEANFILES = $(GENERATED_FILES) $(pc_files) $(BUILD_DIR)/*
+DISTCLEANFILES = $(GENERATED_FILES) $(pc_files)
 pkglib_SCRIPTS = $(ASSEMBLY)
 bin_SCRIPTS = $(BINARIES)
 programfilesdir = @libdir@/@PACKAGE@
@@ -478,6 +520,12 @@ uninstall-pkglibSCRIPTS:
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
 install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(linuxdesktopapplicationsdir)" || $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)"
@@ -631,7 +679,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -685,7 +733,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-am
 
@@ -702,19 +750,21 @@ uninstall-am: uninstall-binSCRIPTS \
 
 .MAKE: install-am install-strip
 
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binSCRIPTS install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-linuxdesktopapplicationsDATA \
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binSCRIPTS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-linuxdesktopapplicationsDATA \
 	install-linuxpkgconfigDATA install-man install-pdf \
 	install-pdf-am install-pkglibSCRIPTS install-programfilesDATA \
 	install-programfilesiconsDATA install-ps install-ps-am \
 	install-strip installcheck installcheck-am installdirs \
 	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
-	uninstall-binSCRIPTS uninstall-linuxdesktopapplicationsDATA \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am uninstall-binSCRIPTS \
+	uninstall-linuxdesktopapplicationsDATA \
 	uninstall-linuxpkgconfigDATA uninstall-pkglibSCRIPTS \
 	uninstall-programfilesDATA uninstall-programfilesiconsDATA
 
diff --git a/src/Server/Server.cs b/src/Server/Server.cs
index b0899d8..da30c00 100644
--- a/src/Server/Server.cs
+++ b/src/Server/Server.cs
@@ -51,8 +51,6 @@ namespace Smuxi.Server
 
         public static void Init(string[] args)
         {
-            Thread.CurrentThread.Name = "Main";
-            
             Engine.Engine.Init();
             string channel = (string)Engine.Engine.Config["Server/Channel"];
             string formatter = (string)Engine.Engine.Config["Server/Formatter"];
@@ -118,7 +116,10 @@ namespace Smuxi.Server
             _Logger.Info("Spawned remoting server with channel: "+channel+" formatter: "+formatter+" port: "+port);
 #endif            
             
-            Thread.Sleep(Timeout.Infinite);
+            Thread.CurrentThread.Join();
+#if LOG4NET
+            _Logger.Info("Shutting down remoting server...");
+#endif
         }
     }
 }
diff --git a/src/smuxi-win32.nsis.in b/src/smuxi-win32.nsis.in
index a22d64c..c3eca9e 100644
--- a/src/smuxi-win32.nsis.in
+++ b/src/smuxi-win32.nsis.in
@@ -27,14 +27,15 @@
 SetCompressor lzma
 
 !define PRODUCT_NAME "Smuxi"
-!define PRODUCT_VERSION "@VERSION@"
+!define PRODUCT_VERSION "@VERSION@@DEV_VERSION_SUFFIX@"
 !define PRODUCT_PUBLISHER "Mirco Bauer <meebey at meebey.net>"
 !define PRODUCT_WEB_SITE "http://www.smuxi.org"
 !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\smuxi-frontend-gnome.exe"
 !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
 !define PRODUCT_UNINST_ROOT_KEY "HKLM"
-!define DOTNET_VERSION "3.5"
-!define GTKSHARP_VERSION "2.12.9"
+!define DOTNET_VERSION "3.5 SP1"
+!define GTKSHARP_PRODUCT_GUID "{3CB70B01-4BC8-4C0F-B28F-7C6E33F913CC}"
+!define GTKSHARP_VERSION "2.12.10"
 
 ############################
 # MUI 1.67 compatible mode #
@@ -45,8 +46,8 @@ SetCompressor lzma
 
 ; MUI Settings [please make the path relative]
 !define MUI_ABORTWARNING
-!define MUI_ICON "../images/icon_32x32.ico"
-!define MUI_UNICON "../images/icon_32x32.ico"
+!define MUI_ICON "../images/icon.ico"
+!define MUI_UNICON "../images/icon.ico"
 
 ######################
 # Language Selection #
@@ -130,8 +131,8 @@ FunctionEnd
 !macroend
 
 !macro CheckGtkSharp GTKSHARP_REQ
-    !define GTKSHARP_FILE         "gtk-sharp-2.12.9-2.win32.msi"
-    !define GTKSHARP_BASE_URL     "http://ftp.novell.com/pub/mono/gtk-sharp/"
+    !define GTKSHARP_FILE         "gtk-sharp-2.12.10.win32.msi"
+    !define GTKSHARP_BASE_URL     "http://download.mono-project.com/gtk-sharp/"
     !define GTKSHARP_DOWNLOAD_URL "${GTKSHARP_BASE_URL}${GTKSHARP_FILE}"
     !define GTKSHARP_TEMP_FILE "$TEMP\${GTKSHARP_FILE}"
 
@@ -157,7 +158,7 @@ FunctionEnd
 
     InstallGtkSharpConfirmation:
         MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION \
-            "Your GTK# version: $GTKSHARP_FOUND_VERSION $\nRequired Version: ${GTKSHARP_REQ} or greater.$\n$\nDownload GTK# from ftp.novell.com?" \
+            "Your GTK# version: $GTKSHARP_FOUND_VERSION $\nRequired Version: ${GTKSHARP_REQ} or greater.$\n$\nDownload GTK# from download.mono-project.com?" \
             /SD IDYES IDYES InstallGtkSharp IDNO End
         goto GiveUp ;IDCANCEL
 
@@ -181,6 +182,11 @@ FunctionEnd
         ${EndIf}
         DetailPrint "Download completed."
         DetailPrint "Pausing installation while downloaded GTK# installer runs."
+        ${If} $GTKSHARP_FOUND_VERSION != ""
+            DetailPrint "Beginning uninstall of old GTK#..."
+            ExecWait 'msiexec /x "${GTKSHARP_PRODUCT_GUID}" /passive' $0
+            DetailPrint "Uninstall completed. Exit code = '$0'"
+        ${EndIf}
         ExecWait 'msiexec /i "${GTKSHARP_TEMP_FILE}" /passive' $0
         DetailPrint "Completed GTK# install. Exit code = '$0'. Removing GTK# installer."
         Delete "${GTKSHARP_TEMP_FILE}"
@@ -227,14 +233,14 @@ FunctionEnd
 # http://go.microsoft.com/fwlink/?LinkId=70848
 # .NET 3.5 - 197 MB
 # http://download.microsoft.com/download/6/0/f/60fc5854-3cb8-4892-b6db-bd4f42510f28/dotnetfx35.exe
+# .NET 3.5 Web Installer - 2.4 MB
+# http://download.microsoft.com/download/7/0/3/703455ee-a747-4cc8-bd3e-98a615c3aedb/dotNetFx35setup.exe
 # .NET 3.5 SP1 - 231 MB
 # http://download.microsoft.com/download/2/0/e/20e90413-712f-438c-988e-fdaa79a8ac3d/dotnetfx35.exe
-# .NET 3.5 SP1 Installer - 3 MB
+# .NET 3.5 SP1 Web Installer - 3 MB  .NET 2.0 -> 3.5: 52 MB
 # http://download.microsoft.com/download/0/6/1/061F001C-8752-4600-A198-53214C69B51F/dotnetfx35setup.exe
-# .NET 3.5 Web Installer - 2.4 MB
-# http://download.microsoft.com/download/7/0/3/703455ee-a747-4cc8-bd3e-98a615c3aedb/dotNetFx35setup.exe
 
-  !define DOTNET_URL "http://download.microsoft.com/download/7/0/3/703455ee-a747-4cc8-bd3e-98a615c3aedb/dotNetFx35setup.exe"
+  !define DOTNET_URL "http://download.microsoft.com/download/0/6/1/061F001C-8752-4600-A198-53214C69B51F/dotnetfx35setup.exe"
   !define MSI31_URL "http://download.microsoft.com/download/1/4/7/147ded26-931c-4daf-9095-ec7baf996f46/WindowsInstaller-KB893803-v2-x86.exe"
  
   DetailPrint "Checking your .NET Framework version..."
@@ -302,7 +308,7 @@ NewMSI:
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;                                  NetFX                                     ;
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-  StrCpy $7 ${DotNetReqVer}
+  StrCpy $7 "${DotNetReqVer}"
  
   System::Call "mscoree::GetCORVersion(w .r0, i ${NSIS_MAX_STRLEN}, *i r2r2) i .r1 ?u"
  
@@ -311,86 +317,29 @@ NewMSI:
     Goto NoDotNET
   ${EndIf}
  
-  ;at this point, $0 has maybe v2.345.678.
-  StrCpy $0 $0 $2 1 ;remove the starting "v", $0 has the installed version num as a string
-  StrCpy $6 $0
-  StrCpy $1 $7 ;$1 has the requested verison num as a string
- 
-  ;MessageBox MB_OKCANCEL "found $0" IDCANCEL GiveUpDotNET
- 
-  ;MessageBox MB_OKCANCEL "looking for $1" IDCANCEL GiveUpDotNET
- 
-  ;now let's compare the versions, installed against required <part0>.<part1>.<part2>.
-  ${Do}
-    StrCpy $2 "" ;clear out the installed part
-    StrCpy $3 "" ;clear out the required part
- 
-    ${Do}
-      ${If} $0 == "" ;if there are no more characters in the version
-        StrCpy $4 "." ;fake the end of the version string
-      ${Else}
-        StrCpy $4 $0 1 0 ;$4 = character from the installed ver
-        ${If} $4 != "."
-          StrCpy $0 $0 ${NSIS_MAX_STRLEN} 1 ;remove that first character from the remaining
-        ${EndIf}
-      ${EndIf}
- 
-      ${If} $1 == ""  ;if there are no more characters in the version
-        StrCpy $5 "." ;fake the end of the version string
-      ${Else}
-        StrCpy $5 $1 1 0 ;$5 = character from the required ver
-        ${If} $5 != "."
-          StrCpy $1 $1 ${NSIS_MAX_STRLEN} 1 ;remove that first character from the remaining
-        ${EndIf}
-      ${EndIf}
-      ;MessageBox MB_OKCANCEL "installed $2,$4,$0 required $3,$5,$1" IDCANCEL GiveUpDotNET
-      ${If} $4 == "."
-      ${AndIf} $5 == "."
-        ${ExitDo} ;we're at the end of the part
-      ${EndIf}
- 
-      ${If} $4 == "." ;if we're at the end of the current installed part
-        StrCpy $2 "0$2" ;put a zero on the front
-      ${Else} ;we have another character
-        StrCpy $2 "$2$4" ;put the next character on the back
-      ${EndIf}
-      ${If} $5 == "." ;if we're at the end of the current required part
-        StrCpy $3 "0$3" ;put a zero on the front
-      ${Else} ;we have another character
-        StrCpy $3 "$3$5" ;put the next character on the back
-      ${EndIf}
-    ${Loop}
-    ;MessageBox MB_OKCANCEL "finished parts: installed $2,$4,$0 required $3,$5,$1" IDCANCEL GiveUpDotNET
- 
-    ${If} $0 != "" ;let's remove the leading period on installed part if it exists
-      StrCpy $0 $0 ${NSIS_MAX_STRLEN} 1
-    ${EndIf}
-    ${If} $1 != "" ;let's remove the leading period on required part if it exists
-      StrCpy $1 $1 ${NSIS_MAX_STRLEN} 1
-    ${EndIf}
- 
-    ;$2 has the installed part, $3 has the required part
-    ${If} $2 S< $3
-      IntOp $0 0 - 1 ;$0 = -1, installed less than required
-      ${ExitDo}
-    ${ElseIf} $2 S> $3
-      IntOp $0 0 + 1 ;$0 = 1, installed greater than required
-      ${ExitDo}
-    ${ElseIf} $2 == ""
-    ${AndIf} $3 == ""
-      IntOp $0 0 + 0 ;$0 = 0, the versions are identical
-      ${ExitDo}
-    ${EndIf} ;otherwise we just keep looping through the parts
-  ${Loop}
- 
-  ${If} $0 < 0
-    DetailPrint ".NET Framework Version found: $6, but is older than the required version: $7"
-    Goto OldDotNET
+  Var /GLOBAL NET35_INSTALL
+  Var /GLOBAL NET35_SP
+  ReadRegStr $NET35_INSTALL HKLM \
+          "SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5" "Install"
+  ReadRegStr $NET35_SP HKLM \
+          "SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5" "SP"
+
+  ${If} $NET35_INSTALL == ""
+      StrCpy $6 "$0"
+      DetailPrint ".NET Framework Version found: $6, but is older than the required version: $7"
+      goto OldDotNET
+  ${ElseIf} $NET35_INSTALL == "1"
+  ${AndIf} $NET35_SP == "1"
+      DetailPrint ".NET Framework Version 3.5 SP1 found"
+      goto NewDotNET
+  ${ElseIf} $NET35_INSTALL == "1"
+      DetailPrint ".NET Framework Version 3.5 found but without SP1"
+      StrCpy $6 "3.5"
+      goto OldDotNET
   ${Else}
-    DetailPrint ".NET Framework Version found: $6, equal or newer to required version: $7."
-    Goto NewDotNET
+      goto NoDotNET
   ${EndIf}
- 
+
 NoDotNET:
     MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION \
     ".NET Framework not installed.$\nRequired Version: $7 or greater.$\n$\nDownload .NET Framework version from www.microsoft.com?" \
@@ -418,8 +367,10 @@ DownloadDotNET:
     IDYES NewDotNET IDNO GiveUpDotNET
   ${EndIf}
   DetailPrint "Pausing installation while downloaded .NET Framework installer runs."
-  DetailPrint "Depending on your internet bandwidth and computer performance, this can take a while. Please be patient!"
-  ExecWait '$TEMP\dotnetfx.exe /quiet /norestart'
+  DetailPrint ""
+  DetailPrint "!!! Depending on your internet bandwidth and computer performance"
+  DetailPrint "!!! this can take a while (up to 10 minutes). Please be patient!"
+  ExecWait '$TEMP\dotnetfx.exe /passive /norestart'
   DetailPrint "Completed .NET Framework install/update. Removing .NET Framework installer."
   Delete "$TEMP\dotnetfx.exe"
   DetailPrint ".NET Framework installer removed."
@@ -535,9 +486,10 @@ FunctionEnd
 
 Section "Main" SEC01
   !insertmacro CheckXPServicePack
-  !insertmacro CheckDotNET ${DOTNET_VERSION}
+  !insertmacro CheckDotNET "${DOTNET_VERSION}"
   !insertmacro CheckGtkSharp ${GTKSHARP_VERSION}
 
+  SetShellVarContext all
   SetOutPath "$INSTDIR"
 
   CreateDirectory "$SMPROGRAMS\Smuxi"
@@ -550,10 +502,14 @@ Section "Main" SEC01
   File "../bin-win32/Mono.Posix.dll"
   File "../bin-win32/MonoPosixHelper.dll"
   File "../bin-win32/Nini.dll"
-  File "../bin-win32/Twitterizer.Framework.dll"
+  File "../bin-win32/Twitterizer2.dll"
+  File "../bin-win32/Newtonsoft.Json.dll"
+  File "../bin-win32/jabber-net.dll"
+  File "../bin-win32/Db4objects.Db4o.dll"
   File "../bin-win32/smuxi-common.dll"
   File "../bin-win32/smuxi-engine-irc.dll"
   File "../bin-win32/smuxi-engine-twitter.dll"
+  File "../bin-win32/smuxi-engine-xmpp.dll"
   File "../bin-win32/smuxi-engine.dll"
   File "../bin-win32/smuxi-frontend-gnome-irc.dll"
   File "../bin-win32/smuxi-frontend-gnome.exe"
@@ -564,7 +520,7 @@ Section "Main" SEC01
   File "../bin-win32/zlib1.dll"
   File "../bin-win32/plink.exe"
   File "../bin-win32/Fixedsys500c.ttf"
-  File /r "../bin-win32/locale"
+  File /nonfatal /r "../bin-win32/locale"
 
   IfFileExists "$FONTS/Fixedsys500c.ttf" SkipFont InstallFont
 
@@ -614,6 +570,7 @@ Function un.onInit
 FunctionEnd
 
 Section Uninstall
+  SetShellVarContext all
   Delete "$INSTDIR\${PRODUCT_NAME}.url"
   Delete "$INSTDIR\uninst.exe"
   Delete "$INSTDIR\zlib1.dll"
@@ -628,6 +585,7 @@ Section Uninstall
   Delete "$INSTDIR\smuxi-engine.dll"
   Delete "$INSTDIR\smuxi-engine-irc.dll"
   Delete "$INSTDIR\smuxi-engine-twitter.dll"
+  Delete "$INSTDIR\smuxi-engine-xmpp.dll"
   Delete "$INSTDIR\smuxi-common.dll"
   Delete "$INSTDIR\Twitterizer.Framework.dll"
   Delete "$INSTDIR\Nini.dll"

-- 
smuxi



More information about the Pkg-cli-apps-commits mailing list